K64F: Update to the latest SDK drivers

Signed-off-by: Mahadevan Mahesh <Mahesh.Mahadevan@nxp.com>
pull/3290/head
Mahadevan Mahesh 2016-10-31 11:07:18 -05:00 committed by Anna Bridge
parent 2bc01394ea
commit 6c9715b738
83 changed files with 6154 additions and 3773 deletions

View File

@ -1,6 +1,7 @@
/* /*
** ################################################################### ** ###################################################################
** Processors: MK64FN1M0VDC12 ** Processors: MK64FN1M0CAJ12
** MK64FN1M0VDC12
** MK64FN1M0VLL12 ** MK64FN1M0VLL12
** MK64FN1M0VLQ12 ** MK64FN1M0VLQ12
** MK64FN1M0VMD12 ** MK64FN1M0VMD12
@ -15,13 +16,13 @@
** IAR ANSI C/C++ Compiler for ARM ** IAR ANSI C/C++ Compiler for ARM
** **
** Reference manual: K64P144M120SF5RM, Rev.2, January 2014 ** Reference manual: K64P144M120SF5RM, Rev.2, January 2014
** Version: rev. 2.8, 2015-02-19 ** Version: rev. 2.9, 2016-03-21
** Build: b151218 ** Build: b160321
** **
** Abstract: ** Abstract:
** CMSIS Peripheral Access Layer for MK64F12 ** CMSIS Peripheral Access Layer for MK64F12
** **
** Copyright (c) 1997 - 2015 Freescale Semiconductor, Inc. ** Copyright (c) 1997 - 2016 Freescale Semiconductor, Inc.
** All rights reserved. ** All rights reserved.
** **
** Redistribution and use in source and binary forms, with or without modification, ** Redistribution and use in source and binary forms, with or without modification,
@ -84,14 +85,17 @@
** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM. ** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM.
** - rev. 2.8 (2015-02-19) ** - rev. 2.8 (2015-02-19)
** Renamed interrupt vector LLW to LLWU. ** Renamed interrupt vector LLW to LLWU.
** - rev. 2.9 (2016-03-21)
** Added MK64FN1M0CAJ12 part.
** GPIO - renamed port instances: PTx -> GPIOx.
** **
** ################################################################### ** ###################################################################
*/ */
/*! /*!
* @file MK64F12.h * @file MK64F12.h
* @version 2.8 * @version 2.9
* @date 2015-02-19 * @date 2016-03-21
* @brief CMSIS Peripheral Access Layer for MK64F12 * @brief CMSIS Peripheral Access Layer for MK64F12
* *
* CMSIS Peripheral Access Layer for MK64F12 * CMSIS Peripheral Access Layer for MK64F12
@ -104,7 +108,7 @@
* compatible) */ * compatible) */
#define MCU_MEM_MAP_VERSION 0x0200U #define MCU_MEM_MAP_VERSION 0x0200U
/** Memory map minor version */ /** Memory map minor version */
#define MCU_MEM_MAP_VERSION_MINOR 0x0008U #define MCU_MEM_MAP_VERSION_MINOR 0x0009U
/** /**
* @brief Macro to calculate address of an aliased word in the peripheral * @brief Macro to calculate address of an aliased word in the peripheral
@ -6926,30 +6930,30 @@ typedef struct {
/* GPIO - Peripheral instance base addresses */ /* GPIO - Peripheral instance base addresses */
/** Peripheral PTA base address */ /** Peripheral GPIOA base address */
#define PTA_BASE (0x400FF000u) #define GPIOA_BASE (0x400FF000u)
/** Peripheral PTA base pointer */ /** Peripheral GPIOA base pointer */
#define PTA ((GPIO_Type *)PTA_BASE) #define GPIOA ((GPIO_Type *)GPIOA_BASE)
/** Peripheral PTB base address */ /** Peripheral GPIOB base address */
#define PTB_BASE (0x400FF040u) #define GPIOB_BASE (0x400FF040u)
/** Peripheral PTB base pointer */ /** Peripheral GPIOB base pointer */
#define PTB ((GPIO_Type *)PTB_BASE) #define GPIOB ((GPIO_Type *)GPIOB_BASE)
/** Peripheral PTC base address */ /** Peripheral GPIOC base address */
#define PTC_BASE (0x400FF080u) #define GPIOC_BASE (0x400FF080u)
/** Peripheral PTC base pointer */ /** Peripheral GPIOC base pointer */
#define PTC ((GPIO_Type *)PTC_BASE) #define GPIOC ((GPIO_Type *)GPIOC_BASE)
/** Peripheral PTD base address */ /** Peripheral GPIOD base address */
#define PTD_BASE (0x400FF0C0u) #define GPIOD_BASE (0x400FF0C0u)
/** Peripheral PTD base pointer */ /** Peripheral GPIOD base pointer */
#define PTD ((GPIO_Type *)PTD_BASE) #define GPIOD ((GPIO_Type *)GPIOD_BASE)
/** Peripheral PTE base address */ /** Peripheral GPIOE base address */
#define PTE_BASE (0x400FF100u) #define GPIOE_BASE (0x400FF100u)
/** Peripheral PTE base pointer */ /** Peripheral GPIOE base pointer */
#define PTE ((GPIO_Type *)PTE_BASE) #define GPIOE ((GPIO_Type *)GPIOE_BASE)
/** Array initializer of GPIO peripheral base addresses */ /** Array initializer of GPIO peripheral base addresses */
#define GPIO_BASE_ADDRS { PTA_BASE, PTB_BASE, PTC_BASE, PTD_BASE, PTE_BASE } #define GPIO_BASE_ADDRS { GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, GPIOD_BASE, GPIOE_BASE }
/** Array initializer of GPIO peripheral base pointers */ /** Array initializer of GPIO peripheral base pointers */
#define GPIO_BASE_PTRS { PTA, PTB, PTC, PTD, PTE } #define GPIO_BASE_PTRS { GPIOA, GPIOB, GPIOC, GPIOD, GPIOE }
/*! /*!
* @} * @}
@ -12677,16 +12681,16 @@ typedef struct {
#define DSPI1 SPI1 #define DSPI1 SPI1
#define DSPI2 SPI2 #define DSPI2 SPI2
#define FLEXCAN0 CAN0 #define FLEXCAN0 CAN0
#define GPIOA_BASE PTA_BASE #define PTA_BASE GPIOA_BASE
#define GPIOA PTA #define PTA GPIOA
#define GPIOB_BASE PTB_BASE #define PTB_BASE GPIOB_BASE
#define GPIOB PTB #define PTB GPIOB
#define GPIOC_BASE PTC_BASE #define PTC_BASE GPIOC_BASE
#define GPIOC PTC #define PTC GPIOC
#define GPIOD_BASE PTD_BASE #define PTD_BASE GPIOD_BASE
#define GPIOD PTD #define PTD GPIOD
#define GPIOE_BASE PTE_BASE #define PTE_BASE GPIOE_BASE
#define GPIOE PTE #define PTE GPIOE
#define UART_WP7816_T_TYPE0_REG(base) UART_WP7816T0_REG(base) #define UART_WP7816_T_TYPE0_REG(base) UART_WP7816T0_REG(base)
#define UART_WP7816_T_TYPE1_REG(base) UART_WP7816T1_REG(base) #define UART_WP7816_T_TYPE1_REG(base) UART_WP7816T1_REG(base)
#define UART_WP7816_T_TYPE0_WI_MASK UART_WP7816T0_WI_MASK #define UART_WP7816_T_TYPE0_WI_MASK UART_WP7816T0_WI_MASK

View File

@ -1,12 +1,12 @@
/* /*
** ################################################################### ** ###################################################################
** Version: rev. 2.14, 2015-06-08 ** Version: rev. 2.15, 2016-03-21
** Build: b151217 ** Build: b160829
** **
** Abstract: ** Abstract:
** Chip specific module features. ** Chip specific module features.
** **
** Copyright (c) 2015 Freescale Semiconductor, Inc. ** Copyright (c) 2016 Freescale Semiconductor, Inc.
** All rights reserved. ** All rights reserved.
** **
** Redistribution and use in source and binary forms, with or without modification, ** Redistribution and use in source and binary forms, with or without modification,
@ -83,6 +83,8 @@
** Several USB features added. ** Several USB features added.
** - rev. 2.14 (2015-06-08) ** - rev. 2.14 (2015-06-08)
** FTM features BUS_CLOCK and FAST_CLOCK removed. ** FTM features BUS_CLOCK and FAST_CLOCK removed.
** - rev. 2.15 (2016-03-21)
** Added MK64FN1M0CAJ12 part.
** **
** ################################################################### ** ###################################################################
*/ */
@ -92,8 +94,8 @@
/* SOC module features */ /* SOC module features */
#if defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLQ12) || defined(CPU_MK64FN1M0VMD12) || defined(CPU_MK64FX512VDC12) || \ #if defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLQ12) || defined(CPU_MK64FN1M0VMD12) || \
defined(CPU_MK64FX512VLQ12) || defined(CPU_MK64FX512VMD12) defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FX512VLQ12) || defined(CPU_MK64FX512VMD12)
/* @brief ACMP availability on the SoC. */ /* @brief ACMP availability on the SoC. */
#define FSL_FEATURE_SOC_ACMP_COUNT (0) #define FSL_FEATURE_SOC_ACMP_COUNT (0)
/* @brief ADC16 availability on the SoC. */ /* @brief ADC16 availability on the SoC. */
@ -640,6 +642,8 @@
#define FSL_FEATURE_FLEXCAN_HAS_BUF31TO0M (0) #define FSL_FEATURE_FLEXCAN_HAS_BUF31TO0M (0)
/* @brief Number of interrupt vectors. */ /* @brief Number of interrupt vectors. */
#define FSL_FEATURE_FLEXCAN_INTERRUPT_COUNT (6) #define FSL_FEATURE_FLEXCAN_INTERRUPT_COUNT (6)
/* @brief Is affected by errata with ID 5641 (Module does not transmit a message that is enabled to be transmitted at a specific moment during the arbitration process). */
#define FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641 (0)
/* CMP module features */ /* CMP module features */
@ -701,7 +705,7 @@
#define FSL_FEATURE_DMAMUX_MODULE_CHANNEL (16) #define FSL_FEATURE_DMAMUX_MODULE_CHANNEL (16)
/* @brief Total number of DMA channels on all modules. */ /* @brief Total number of DMA channels on all modules. */
#define FSL_FEATURE_DMAMUX_DMAMUX_CHANNELS (FSL_FEATURE_SOC_DMAMUX_COUNT * 16) #define FSL_FEATURE_DMAMUX_DMAMUX_CHANNELS (FSL_FEATURE_SOC_DMAMUX_COUNT * 16)
/* @brief Has the periodic trigger capability for the triggered DMA channel 0 (register bit CHCFG0[TRIG]). */ /* @brief Has the periodic trigger capability for the triggered DMA channel (register bit CHCFG0[TRIG]). */
#define FSL_FEATURE_DMAMUX_HAS_TRIG (1) #define FSL_FEATURE_DMAMUX_HAS_TRIG (1)
/* ENET module features */ /* ENET module features */
@ -728,7 +732,8 @@
/* FLASH module features */ /* FLASH module features */
#if defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FN1M0VLQ12) || defined(CPU_MK64FN1M0VMD12) #if defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FN1M0VLQ12) || \
defined(CPU_MK64FN1M0VMD12)
/* @brief Is of type FTFA. */ /* @brief Is of type FTFA. */
#define FSL_FEATURE_FLASH_IS_FTFA (0) #define FSL_FEATURE_FLASH_IS_FTFA (0)
/* @brief Is of type FTFE. */ /* @brief Is of type FTFE. */
@ -749,6 +754,8 @@
#define FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS (1) #define FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS (1)
/* @brief Has flash cache control in MCM module. */ /* @brief Has flash cache control in MCM module. */
#define FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS (0) #define FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS (0)
/* @brief Has flash cache control in MSCM module. */
#define FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS (0)
/* @brief P-Flash start address. */ /* @brief P-Flash start address. */
#define FSL_FEATURE_FLASH_PFLASH_START_ADDRESS (0x00000000) #define FSL_FEATURE_FLASH_PFLASH_START_ADDRESS (0x00000000)
/* @brief P-Flash block count. */ /* @brief P-Flash block count. */
@ -763,6 +770,8 @@
#define FSL_FEATURE_FLASH_PFLASH_BLOCK_DATA_PATH_WIDTH (16) #define FSL_FEATURE_FLASH_PFLASH_BLOCK_DATA_PATH_WIDTH (16)
/* @brief P-Flash block swap feature. */ /* @brief P-Flash block swap feature. */
#define FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP (1) #define FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP (1)
/* @brief P-Flash protection region count. */
#define FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT (32)
/* @brief Has FlexNVM memory. */ /* @brief Has FlexNVM memory. */
#define FSL_FEATURE_FLASH_HAS_FLEX_NVM (0) #define FSL_FEATURE_FLASH_HAS_FLEX_NVM (0)
/* @brief FlexNVM start address. (Valid only if FlexNVM is available.) */ /* @brief FlexNVM start address. (Valid only if FlexNVM is available.) */
@ -815,6 +824,10 @@
#define FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD (1) #define FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD (1)
/* @brief Has 0x49 Erase All Blocks Unsecure command. */ /* @brief Has 0x49 Erase All Blocks Unsecure command. */
#define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD (0) #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD (0)
/* @brief Has 0x4A Read 1s All Execute-only Segments command. */
#define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0)
/* @brief Has 0x4B Erase All Execute-only Segments command. */
#define FSL_FEATURE_FLASH_HAS_ERASE_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0)
/* @brief Has 0x80 Program Partition command. */ /* @brief Has 0x80 Program Partition command. */
#define FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD (0) #define FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD (0)
/* @brief Has 0x81 Set FlexRAM Function command. */ /* @brief Has 0x81 Set FlexRAM Function command. */
@ -926,6 +939,8 @@
#define FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS (1) #define FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS (1)
/* @brief Has flash cache control in MCM module. */ /* @brief Has flash cache control in MCM module. */
#define FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS (0) #define FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS (0)
/* @brief Has flash cache control in MSCM module. */
#define FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS (0)
/* @brief P-Flash start address. */ /* @brief P-Flash start address. */
#define FSL_FEATURE_FLASH_PFLASH_START_ADDRESS (0x00000000) #define FSL_FEATURE_FLASH_PFLASH_START_ADDRESS (0x00000000)
/* @brief P-Flash block count. */ /* @brief P-Flash block count. */
@ -940,6 +955,8 @@
#define FSL_FEATURE_FLASH_PFLASH_BLOCK_DATA_PATH_WIDTH (16) #define FSL_FEATURE_FLASH_PFLASH_BLOCK_DATA_PATH_WIDTH (16)
/* @brief P-Flash block swap feature. */ /* @brief P-Flash block swap feature. */
#define FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP (0) #define FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP (0)
/* @brief P-Flash protection region count. */
#define FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT (32)
/* @brief Has FlexNVM memory. */ /* @brief Has FlexNVM memory. */
#define FSL_FEATURE_FLASH_HAS_FLEX_NVM (1) #define FSL_FEATURE_FLASH_HAS_FLEX_NVM (1)
/* @brief FlexNVM start address. (Valid only if FlexNVM is available.) */ /* @brief FlexNVM start address. (Valid only if FlexNVM is available.) */
@ -979,19 +996,23 @@
/* @brief Has 0x0B Program Section command. */ /* @brief Has 0x0B Program Section command. */
#define FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD (1) #define FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD (1)
/* @brief Has 0x40 Read 1s All Blocks command. */ /* @brief Has 0x40 Read 1s All Blocks command. */
#define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_BLOCKS_CMD (0) #define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_BLOCKS_CMD (1)
/* @brief Has 0x41 Read Once command. */ /* @brief Has 0x41 Read Once command. */
#define FSL_FEATURE_FLASH_HAS_READ_ONCE_CMD (1) #define FSL_FEATURE_FLASH_HAS_READ_ONCE_CMD (1)
/* @brief Has 0x43 Program Once command. */ /* @brief Has 0x43 Program Once command. */
#define FSL_FEATURE_FLASH_HAS_PROGRAM_ONCE_CMD (1) #define FSL_FEATURE_FLASH_HAS_PROGRAM_ONCE_CMD (1)
/* @brief Has 0x44 Erase All Blocks command. */ /* @brief Has 0x44 Erase All Blocks command. */
#define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_CMD (0) #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_CMD (1)
/* @brief Has 0x45 Verify Backdoor Access Key command. */ /* @brief Has 0x45 Verify Backdoor Access Key command. */
#define FSL_FEATURE_FLASH_HAS_VERIFY_BACKDOOR_ACCESS_KEY_CMD (1) #define FSL_FEATURE_FLASH_HAS_VERIFY_BACKDOOR_ACCESS_KEY_CMD (1)
/* @brief Has 0x46 Swap Control command. */ /* @brief Has 0x46 Swap Control command. */
#define FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD (0) #define FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD (0)
/* @brief Has 0x49 Erase All Blocks Unsecure command. */ /* @brief Has 0x49 Erase All Blocks Unsecure command. */
#define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD (0) #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD (0)
/* @brief Has 0x4A Read 1s All Execute-only Segments command. */
#define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0)
/* @brief Has 0x4B Erase All Execute-only Segments command. */
#define FSL_FEATURE_FLASH_HAS_ERASE_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0)
/* @brief Has 0x80 Program Partition command. */ /* @brief Has 0x80 Program Partition command. */
#define FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD (1) #define FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD (1)
/* @brief Has 0x81 Set FlexRAM Function command. */ /* @brief Has 0x81 Set FlexRAM Function command. */
@ -1082,7 +1103,8 @@
#define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110 (0xFFFF) #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). */ /* @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 (0x0000) #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111 (0x0000)
#endif /* defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FN1M0VLQ12) || defined(CPU_MK64FN1M0VMD12) */ #endif /* defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FN1M0VLQ12) || \
defined(CPU_MK64FN1M0VMD12) */
/* FTM module features */ /* FTM module features */
@ -1094,6 +1116,8 @@
((x) == FTM3 ? (8) : (-1))))) ((x) == FTM3 ? (8) : (-1)))))
/* @brief Has counter reset by the selected input capture event (register bits C0SC[ICRST], C1SC[ICRST], ...). */ /* @brief Has counter reset by the selected input capture event (register bits C0SC[ICRST], C1SC[ICRST], ...). */
#define FSL_FEATURE_FTM_HAS_COUNTER_RESET_BY_CAPTURE_EVENT (0) #define FSL_FEATURE_FTM_HAS_COUNTER_RESET_BY_CAPTURE_EVENT (0)
/* @brief Has extended deadtime value. */
#define FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE (0)
/* @brief Enable pwm output for the module. */ /* @brief Enable pwm output for the module. */
#define FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT (0) #define FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT (0)
/* @brief Has half-cycle reload for the module. */ /* @brief Has half-cycle reload for the module. */
@ -1103,6 +1127,15 @@
/* @brief Has reload initialization trigger. */ /* @brief Has reload initialization trigger. */
#define FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER (0) #define FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER (0)
/* 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 */ /* I2C module features */
/* @brief Has System Management Bus support (registers SMB, A2, SLTL and SLTH). */ /* @brief Has System Management Bus support (registers SMB, A2, SLTL and SLTH). */
@ -1125,6 +1158,8 @@
#define FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION (1) #define FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION (1)
/* @brief Has double buffering support (register S2). */ /* @brief Has double buffering support (register S2). */
#define FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING (0) #define FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING (0)
/* @brief Has double buffer enable. */
#define FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE (0)
/* SAI module features */ /* SAI module features */
@ -1163,7 +1198,7 @@
#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE (8) #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE (8)
/* @brief Number of digital filters. */ /* @brief Number of digital filters. */
#define FSL_FEATURE_LLWU_HAS_PIN_FILTER (2) #define FSL_FEATURE_LLWU_HAS_PIN_FILTER (2)
/* @brief Has MF5 register. */ /* @brief Has MF register. */
#define FSL_FEATURE_LLWU_HAS_MF (0) #define FSL_FEATURE_LLWU_HAS_MF (0)
/* @brief Has PF register. */ /* @brief Has PF register. */
#define FSL_FEATURE_LLWU_HAS_PF (0) #define FSL_FEATURE_LLWU_HAS_PF (0)
@ -1390,6 +1425,8 @@
/* @brief Has shared interrupt handler with another LPTMR module. */ /* @brief Has shared interrupt handler with another LPTMR module. */
#define FSL_FEATURE_LPTMR_HAS_SHARED_IRQ_HANDLER (0) #define FSL_FEATURE_LPTMR_HAS_SHARED_IRQ_HANDLER (0)
/* @brief Whether LPTMR counter is 32 bits width. */
#define FSL_FEATURE_LPTMR_CNR_WIDTH_IS_32B (0)
/* MCG module features */ /* MCG module features */
@ -1468,22 +1505,14 @@
#define FSL_FEATURE_MPU_DESCRIPTOR_COUNT (12) #define FSL_FEATURE_MPU_DESCRIPTOR_COUNT (12)
/* @brief Has process identifier support. */ /* @brief Has process identifier support. */
#define FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER (1) #define FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER (1)
/* @brief Has master 0. */ /* @brief Total number of MPU master. */
#define FSL_FEATURE_MPU_HAS_MASTER0 (1) #define FSL_FEATURE_MPU_MASTER_COUNT (8)
/* @brief Has master 1. */ /* @brief Total number of MPU master with privileged rights */
#define FSL_FEATURE_MPU_HAS_MASTER1 (1) #define FSL_FEATURE_MPU_PRIVILEGED_RIGHTS_MASTER_COUNT (4)
/* @brief Has master 2. */ /* @brief Max index of used MPU master. */
#define FSL_FEATURE_MPU_HAS_MASTER2 (1) #define FSL_FEATURE_MPU_MASTER_MAX_INDEX (5)
/* @brief Has master 3. */ /* @brief Has master 4 or 5 or 6 or 7. */
#define FSL_FEATURE_MPU_HAS_MASTER3 (1) #define FSL_FEATURE_MPU_HAS_MASTER_4_7 (1)
/* @brief Has master 4. */
#define FSL_FEATURE_MPU_HAS_MASTER4 (1)
/* @brief Has master 5. */
#define FSL_FEATURE_MPU_HAS_MASTER5 (1)
/* @brief Has master 6. */
#define FSL_FEATURE_MPU_HAS_MASTER6 (0)
/* @brief Has master 7. */
#define FSL_FEATURE_MPU_HAS_MASTER7 (0)
/* interrupt module features */ /* interrupt module features */
@ -1587,15 +1616,6 @@
/* @brief Defines whether PCR[IRQC] bit-field has trigger states. */ /* @brief Defines whether PCR[IRQC] bit-field has trigger states. */
#define FSL_FEATURE_PORT_HAS_IRQC_TRIGGER (0) #define FSL_FEATURE_PORT_HAS_IRQC_TRIGGER (0)
/* 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)
/* RCM module features */ /* RCM module features */
/* @brief Has Loss-of-Lock Reset support. */ /* @brief Has Loss-of-Lock Reset support. */
@ -1629,8 +1649,8 @@
/* RTC module features */ /* RTC module features */
#if defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FN1M0VLQ12) || defined(CPU_MK64FX512VDC12) || \ #if defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FN1M0VLQ12) || \
defined(CPU_MK64FX512VLL12) || defined(CPU_MK64FX512VLQ12) defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FX512VLL12) || defined(CPU_MK64FX512VLQ12)
/* @brief Has wakeup pin. */ /* @brief Has wakeup pin. */
#define FSL_FEATURE_RTC_HAS_WAKEUP_PIN (1) #define FSL_FEATURE_RTC_HAS_WAKEUP_PIN (1)
/* @brief Has wakeup pin selection (bit field CR[WPS]). */ /* @brief Has wakeup pin selection (bit field CR[WPS]). */
@ -1672,8 +1692,8 @@
#define FSL_FEATURE_RTC_HAS_TSIC (0) #define FSL_FEATURE_RTC_HAS_TSIC (0)
/* @brief Has OSC capacitor setting RTC_CR[SC2P ~ SC16P] */ /* @brief Has OSC capacitor setting RTC_CR[SC2P ~ SC16P] */
#define FSL_FEATURE_RTC_HAS_OSC_SCXP (1) #define FSL_FEATURE_RTC_HAS_OSC_SCXP (1)
#endif /* defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FN1M0VLQ12) || defined(CPU_MK64FX512VDC12) || \ #endif /* defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FN1M0VLQ12) || \
defined(CPU_MK64FX512VLL12) || defined(CPU_MK64FX512VLQ12) */ defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FX512VLL12) || defined(CPU_MK64FX512VLQ12) */
/* SDHC module features */ /* SDHC module features */
@ -2012,8 +2032,8 @@
#define FSL_FEATURE_UART_HAS_IR_SUPPORT (1) #define FSL_FEATURE_UART_HAS_IR_SUPPORT (1)
/* @brief 2 bits long stop bit is available. */ /* @brief 2 bits long stop bit is available. */
#define FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT (1) #define FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT (1)
/* @brief Maximal data width without parity bit. */ /* @brief If 10-bit mode is supported. */
#define FSL_FEATURE_UART_HAS_10BIT_DATA_SUPPORT (0) #define FSL_FEATURE_UART_HAS_10BIT_DATA_SUPPORT (1)
/* @brief Baud rate fine adjustment is available. */ /* @brief Baud rate fine adjustment is available. */
#define FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT (1) #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). */ /* @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). */
@ -2090,7 +2110,7 @@
#define FSL_FEATURE_VREF_HAS_CHOP_OSC (1) #define FSL_FEATURE_VREF_HAS_CHOP_OSC (1)
/* @brief Has second order curvature compensation (bit SC[ICOMPEN]) */ /* @brief Has second order curvature compensation (bit SC[ICOMPEN]) */
#define FSL_FEATURE_VREF_HAS_COMPENSATION (1) #define FSL_FEATURE_VREF_HAS_COMPENSATION (1)
/* @brief Describes the set of SC[MODE_LV] bitfield values */ /* @brief If high/low buffer mode supported */
#define FSL_FEATURE_VREF_MODE_LV_TYPE (1) #define FSL_FEATURE_VREF_MODE_LV_TYPE (1)
/* @brief Module has also low reference (registers VREFL/VREFH) */ /* @brief Module has also low reference (registers VREFL/VREFH) */
#define FSL_FEATURE_VREF_HAS_LOW_REFERENCE (0) #define FSL_FEATURE_VREF_HAS_LOW_REFERENCE (0)

View File

@ -2,12 +2,12 @@
; * @file: startup_MK64F12.s ; * @file: startup_MK64F12.s
; * @purpose: CMSIS Cortex-M4 Core Device Startup File ; * @purpose: CMSIS Cortex-M4 Core Device Startup File
; * MK64F12 ; * MK64F12
; * @version: 2.8 ; * @version: 2.9
; * @date: 2015-2-19 ; * @date: 2016-3-21
; * @build: b151210 ; * @build: b160321
; * --------------------------------------------------------------------------------------- ; * ---------------------------------------------------------------------------------------
; * ; *
; * Copyright (c) 1997 - 2015 , Freescale Semiconductor, Inc. ; * Copyright (c) 1997 - 2016 , Freescale Semiconductor, Inc.
; * All rights reserved. ; * All rights reserved.
; * ; *
; * Redistribution and use in source and binary forms, with or without modification, ; * Redistribution and use in source and binary forms, with or without modification,

View File

@ -1,19 +1,20 @@
/* /*
** ################################################################### ** ###################################################################
** Processors: MK64FN1M0VDC12 ** Processors: MK64FN1M0CAJ12
** MK64FN1M0VDC12
** MK64FN1M0VLL12 ** MK64FN1M0VLL12
** MK64FN1M0VLQ12 ** MK64FN1M0VLQ12
** MK64FN1M0VMD12 ** MK64FN1M0VMD12
** **
** Compiler: GNU C Compiler ** Compiler: GNU C Compiler
** Reference manual: K64P144M120SF5RM, Rev.2, January 2014 ** Reference manual: K64P144M120SF5RM, Rev.2, January 2014
** Version: rev. 2.8, 2015-02-19 ** Version: rev. 2.9, 2016-03-21
** Build: b151217 ** Build: b160613
** **
** Abstract: ** Abstract:
** Linker file for the GNU C Compiler ** Linker file for the GNU C Compiler
** **
** Copyright (c) 2015 Freescale Semiconductor, Inc. ** Copyright (c) 2016 Freescale Semiconductor, Inc.
** All rights reserved. ** All rights reserved.
** **
** Redistribution and use in source and binary forms, with or without modification, ** Redistribution and use in source and binary forms, with or without modification,

View File

@ -2,12 +2,12 @@
/* @file: startup_MK64F12.s */ /* @file: startup_MK64F12.s */
/* @purpose: CMSIS Cortex-M4 Core Device Startup File */ /* @purpose: CMSIS Cortex-M4 Core Device Startup File */
/* MK64F12 */ /* MK64F12 */
/* @version: 2.8 */ /* @version: 2.9 */
/* @date: 2015-2-19 */ /* @date: 2016-3-21 */
/* @build: b151210 */ /* @build: b160321 */
/* ---------------------------------------------------------------------------------------*/ /* ---------------------------------------------------------------------------------------*/
/* */ /* */
/* Copyright (c) 1997 - 2015 , Freescale Semiconductor, Inc. */ /* Copyright (c) 1997 - 2016 , Freescale Semiconductor, Inc. */
/* All rights reserved. */ /* All rights reserved. */
/* */ /* */
/* Redistribution and use in source and binary forms, with or without modification, */ /* Redistribution and use in source and binary forms, with or without modification, */

View File

@ -1,19 +1,20 @@
/* /*
** ################################################################### ** ###################################################################
** Processors: MK64FN1M0VDC12 ** Processors: MK64FN1M0CAJ12
** MK64FN1M0VDC12
** MK64FN1M0VLL12 ** MK64FN1M0VLL12
** MK64FN1M0VLQ12 ** MK64FN1M0VLQ12
** MK64FN1M0VMD12 ** MK64FN1M0VMD12
** **
** Compiler: IAR ANSI C/C++ Compiler for ARM ** Compiler: IAR ANSI C/C++ Compiler for ARM
** Reference manual: K64P144M120SF5RM, Rev.2, January 2014 ** Reference manual: K64P144M120SF5RM, Rev.2, January 2014
** Version: rev. 2.8, 2015-02-19 ** Version: rev. 2.9, 2016-03-21
** Build: b151009 ** Build: b160406
** **
** Abstract: ** Abstract:
** Linker file for the IAR ANSI C/C++ Compiler for ARM ** Linker file for the IAR ANSI C/C++ Compiler for ARM
** **
** Copyright (c) 2015 Freescale Semiconductor, Inc. ** Copyright (c) 2016 Freescale Semiconductor, Inc.
** All rights reserved. ** All rights reserved.
** **
** Redistribution and use in source and binary forms, with or without modification, ** Redistribution and use in source and binary forms, with or without modification,

View File

@ -2,12 +2,12 @@
; @file: startup_MK64F12.s ; @file: startup_MK64F12.s
; @purpose: CMSIS Cortex-M4 Core Device Startup File ; @purpose: CMSIS Cortex-M4 Core Device Startup File
; MK64F12 ; MK64F12
; @version: 2.8 ; @version: 2.9
; @date: 2015-2-19 ; @date: 2016-3-21
; @build: b151210 ; @build: b160321
; --------------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------------
; ;
; Copyright (c) 1997 - 2015 , Freescale Semiconductor, Inc. ; Copyright (c) 1997 - 2016 , Freescale Semiconductor, Inc.
; All rights reserved. ; All rights reserved.
; ;
; Redistribution and use in source and binary forms, with or without modification, ; Redistribution and use in source and binary forms, with or without modification,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc. * Copyright (c) 2014 - 2016, Freescale Semiconductor, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -36,9 +36,9 @@
* *
* The CPU macro should be declared in the project or makefile. * The CPU macro should be declared in the project or makefile.
*/ */
#if (defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FX512VLL12) || \ #if (defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || \
defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FX512VLQ12) || defined(CPU_MK64FN1M0VLQ12) || \ defined(CPU_MK64FN1M0VLQ12) || defined(CPU_MK64FN1M0VMD12) || defined(CPU_MK64FX512VDC12) || \
defined(CPU_MK64FX512VMD12) || defined(CPU_MK64FN1M0VMD12)) defined(CPU_MK64FX512VLL12) || defined(CPU_MK64FX512VLQ12) || defined(CPU_MK64FX512VMD12))
#define K64F12_SERIES #define K64F12_SERIES

View File

@ -1,6 +1,7 @@
/* /*
** ################################################################### ** ###################################################################
** Processors: MK64FN1M0VDC12 ** Processors: MK64FN1M0CAJ12
** MK64FN1M0VDC12
** MK64FN1M0VLL12 ** MK64FN1M0VLL12
** MK64FN1M0VLQ12 ** MK64FN1M0VLQ12
** MK64FN1M0VMD12 ** MK64FN1M0VMD12
@ -15,15 +16,15 @@
** IAR ANSI C/C++ Compiler for ARM ** IAR ANSI C/C++ Compiler for ARM
** **
** Reference manual: K64P144M120SF5RM, Rev.2, January 2014 ** Reference manual: K64P144M120SF5RM, Rev.2, January 2014
** Version: rev. 2.8, 2015-02-19 ** Version: rev. 2.9, 2016-03-21
** Build: b151216 ** Build: b160321
** **
** Abstract: ** Abstract:
** Provides a system configuration function and a global variable that ** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes ** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device. ** the oscillator (PLL) that is part of the microcontroller device.
** **
** Copyright (c) 2015 Freescale Semiconductor, Inc. ** Copyright (c) 2016 Freescale Semiconductor, Inc.
** All rights reserved. ** All rights reserved.
** **
** Redistribution and use in source and binary forms, with or without modification, ** Redistribution and use in source and binary forms, with or without modification,
@ -86,14 +87,17 @@
** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM. ** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM.
** - rev. 2.8 (2015-02-19) ** - rev. 2.8 (2015-02-19)
** Renamed interrupt vector LLW to LLWU. ** Renamed interrupt vector LLW to LLWU.
** - rev. 2.9 (2016-03-21)
** Added MK64FN1M0CAJ12 part.
** GPIO - renamed port instances: PTx -> GPIOx.
** **
** ################################################################### ** ###################################################################
*/ */
/*! /*!
* @file MK64F12 * @file MK64F12
* @version 2.8 * @version 2.9
* @date 2015-02-19 * @date 2016-03-21
* @brief Device specific configuration file for MK64F12 (implementation file) * @brief Device specific configuration file for MK64F12 (implementation file)
* *
* Provides a system configuration function and a global variable that contains * Provides a system configuration function and a global variable that contains

View File

@ -1,6 +1,7 @@
/* /*
** ################################################################### ** ###################################################################
** Processors: MK64FN1M0VDC12 ** Processors: MK64FN1M0CAJ12
** MK64FN1M0VDC12
** MK64FN1M0VLL12 ** MK64FN1M0VLL12
** MK64FN1M0VLQ12 ** MK64FN1M0VLQ12
** MK64FN1M0VMD12 ** MK64FN1M0VMD12
@ -15,15 +16,15 @@
** IAR ANSI C/C++ Compiler for ARM ** IAR ANSI C/C++ Compiler for ARM
** **
** Reference manual: K64P144M120SF5RM, Rev.2, January 2014 ** Reference manual: K64P144M120SF5RM, Rev.2, January 2014
** Version: rev. 2.8, 2015-02-19 ** Version: rev. 2.9, 2016-03-21
** Build: b151216 ** Build: b160321
** **
** Abstract: ** Abstract:
** Provides a system configuration function and a global variable that ** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes ** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device. ** the oscillator (PLL) that is part of the microcontroller device.
** **
** Copyright (c) 2015 Freescale Semiconductor, Inc. ** Copyright (c) 2016 Freescale Semiconductor, Inc.
** All rights reserved. ** All rights reserved.
** **
** Redistribution and use in source and binary forms, with or without modification, ** Redistribution and use in source and binary forms, with or without modification,
@ -86,14 +87,17 @@
** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM. ** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM.
** - rev. 2.8 (2015-02-19) ** - rev. 2.8 (2015-02-19)
** Renamed interrupt vector LLW to LLWU. ** Renamed interrupt vector LLW to LLWU.
** - rev. 2.9 (2016-03-21)
** Added MK64FN1M0CAJ12 part.
** GPIO - renamed port instances: PTx -> GPIOx.
** **
** ################################################################### ** ###################################################################
*/ */
/*! /*!
* @file MK64F12 * @file MK64F12
* @version 2.8 * @version 2.9
* @date 2015-02-19 * @date 2016-03-21
* @brief Device specific configuration file for MK64F12 (header file) * @brief Device specific configuration file for MK64F12 (header file)
* *
* Provides a system configuration function and a global variable that contains * Provides a system configuration function and a global variable that contains
@ -115,6 +119,8 @@ extern "C" {
#define DISABLE_WDOG 1 #define DISABLE_WDOG 1
#endif #endif
/* Define clock source values */
#define CPU_XTAL_CLK_HZ 50000000u /* Value of the external crystal or oscillator clock frequency in Hz */ #define CPU_XTAL_CLK_HZ 50000000u /* Value of the external crystal or oscillator clock frequency in Hz */
#define CPU_XTAL32k_CLK_HZ 32768u /* Value of the external 32k crystal or oscillator clock frequency in Hz */ #define CPU_XTAL32k_CLK_HZ 32768u /* Value of the external 32k crystal or oscillator clock frequency in Hz */
#define CPU_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */ #define CPU_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */

View File

@ -46,8 +46,10 @@ static uint32_t ADC16_GetInstance(ADC_Type *base);
/*! @brief Pointers to ADC16 bases for each instance. */ /*! @brief Pointers to ADC16 bases for each instance. */
static ADC_Type *const s_adc16Bases[] = ADC_BASE_PTRS; static ADC_Type *const s_adc16Bases[] = ADC_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to ADC16 clocks for each instance. */ /*! @brief Pointers to ADC16 clocks for each instance. */
const clock_ip_name_t s_adc16Clocks[] = ADC16_CLOCKS; static const clock_ip_name_t s_adc16Clocks[] = ADC16_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/******************************************************************************* /*******************************************************************************
* Code * Code
@ -76,8 +78,10 @@ void ADC16_Init(ADC_Type *base, const adc16_config_t *config)
uint32_t tmp32; uint32_t tmp32;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock. */ /* Enable the clock. */
CLOCK_EnableClock(s_adc16Clocks[ADC16_GetInstance(base)]); CLOCK_EnableClock(s_adc16Clocks[ADC16_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* ADCx_CFG1. */ /* ADCx_CFG1. */
tmp32 = ADC_CFG1_ADICLK(config->clockSource) | ADC_CFG1_MODE(config->resolution); tmp32 = ADC_CFG1_ADICLK(config->clockSource) | ADC_CFG1_MODE(config->resolution);
@ -126,8 +130,10 @@ void ADC16_Init(ADC_Type *base, const adc16_config_t *config)
void ADC16_Deinit(ADC_Type *base) void ADC16_Deinit(ADC_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock. */ /* Disable the clock. */
CLOCK_DisableClock(s_adc16Clocks[ADC16_GetInstance(base)]); CLOCK_DisableClock(s_adc16Clocks[ADC16_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void ADC16_GetDefaultConfig(adc16_config_t *config) void ADC16_GetDefaultConfig(adc16_config_t *config)
@ -149,7 +155,7 @@ void ADC16_GetDefaultConfig(adc16_config_t *config)
status_t ADC16_DoAutoCalibration(ADC_Type *base) status_t ADC16_DoAutoCalibration(ADC_Type *base)
{ {
bool bHWTrigger = false; bool bHWTrigger = false;
uint32_t tmp32; volatile uint32_t tmp32; /* 'volatile' here is for the dummy read of ADCx_R[0] register. */
status_t status = kStatus_Success; status_t status = kStatus_Success;
/* The calibration would be failed when in hardwar mode. /* The calibration would be failed when in hardwar mode.
@ -171,6 +177,7 @@ status_t ADC16_DoAutoCalibration(ADC_Type *base)
break; break;
} }
} }
tmp32 = base->R[0]; /* Dummy read to clear COCO caused by calibration. */
/* Restore the hardware trigger setting if it was enabled before. */ /* Restore the hardware trigger setting if it was enabled before. */
if (bHWTrigger) if (bHWTrigger)

View File

@ -38,7 +38,6 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -74,7 +73,7 @@ enum _adc16_status_flags
* @brief Channel multiplexer mode for each channel. * @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 * 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. * are the different channels that share the same channel number.
*/ */
typedef enum _adc_channel_mux_mode typedef enum _adc_channel_mux_mode
{ {
@ -104,7 +103,7 @@ typedef enum _adc16_resolution
kADC16_Resolution12or13Bit = 1U, /*!< Single End 12-bit or Differential Sample 13-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. */ kADC16_Resolution10or11Bit = 2U, /*!< Single End 10-bit or Differential Sample 11-bit. */
/* This group of enumeration is for public user. */ /* This group of enumeration is for a public user. */
kADC16_ResolutionSE8Bit = kADC16_Resolution8or9Bit, /*!< Single End 8-bit. */ kADC16_ResolutionSE8Bit = kADC16_Resolution8or9Bit, /*!< Single End 8-bit. */
kADC16_ResolutionSE12Bit = kADC16_Resolution12or13Bit, /*!< Single End 12-bit. */ kADC16_ResolutionSE12Bit = kADC16_Resolution12or13Bit, /*!< Single End 12-bit. */
kADC16_ResolutionSE10Bit = kADC16_Resolution10or11Bit, /*!< Single End 10-bit. */ kADC16_ResolutionSE10Bit = kADC16_Resolution10or11Bit, /*!< Single End 10-bit. */
@ -203,7 +202,7 @@ typedef enum _adc16_pga_gain
#endif /* FSL_FEATURE_ADC16_HAS_PGA */ #endif /* FSL_FEATURE_ADC16_HAS_PGA */
/*! /*!
* @brief ADC16 converter configuration . * @brief ADC16 converter configuration.
*/ */
typedef struct _adc16_config typedef struct _adc16_config
{ {
@ -219,7 +218,7 @@ typedef struct _adc16_config
} adc16_config_t; } adc16_config_t;
/*! /*!
* @brief ADC16 Hardware compare configuration. * @brief ADC16 Hardware comparison configuration.
*/ */
typedef struct _adc16_hardware_compare_config typedef struct _adc16_hardware_compare_config
{ {
@ -237,7 +236,7 @@ typedef struct _adc16_channel_config
uint32_t channelNumber; /*!< Setting the conversion channel number. The available range is 0-31. uint32_t channelNumber; /*!< Setting the conversion channel number. The available range is 0-31.
See channel connection information for each chip in Reference See channel connection information for each chip in Reference
Manual document. */ Manual document. */
bool enableInterruptOnConversionCompleted; /*!< Generate a interrupt request once the conversion is completed. */ bool enableInterruptOnConversionCompleted; /*!< Generate an interrupt request once the conversion is completed. */
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
bool enableDifferentialConversion; /*!< Using Differential sample mode. */ bool enableDifferentialConversion; /*!< Using Differential sample mode. */
#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
@ -296,9 +295,9 @@ void ADC16_Init(ADC_Type *base, const adc16_config_t *config);
void ADC16_Deinit(ADC_Type *base); void ADC16_Deinit(ADC_Type *base);
/*! /*!
* @brief Gets an available pre-defined settings for converter's configuration. * @brief Gets an available pre-defined settings for the converter's configuration.
* *
* This function initializes the converter configuration structure with an available settings. The default values are: * This function initializes the converter configuration structure with available settings. The default values are as follows.
* @code * @code
* config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; * config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref;
* config->clockSource = kADC16_ClockSourceAsynchronousClock; * config->clockSource = kADC16_ClockSourceAsynchronousClock;
@ -310,7 +309,7 @@ void ADC16_Deinit(ADC_Type *base);
* config->enableLowPower = false; * config->enableLowPower = false;
* config->enableContinuousConversion = false; * config->enableContinuousConversion = false;
* @endcode * @endcode
* @param config Pointer to configuration structure. * @param config Pointer to the configuration structure.
*/ */
void ADC16_GetDefaultConfig(adc16_config_t *config); void ADC16_GetDefaultConfig(adc16_config_t *config);
@ -318,15 +317,15 @@ void ADC16_GetDefaultConfig(adc16_config_t *config);
/*! /*!
* @brief Automates the hardware calibration. * @brief Automates the hardware calibration.
* *
* This auto calibration helps to adjust the plus/minus side gain automatically on the converter's working situation. * This auto calibration helps to adjust the plus/minus side gain automatically.
* Execute the calibration before using the converter. Note that the hardware trigger should be used * Execute the calibration before using the converter. Note that the hardware trigger should be used
* during calibration. * during the calibration.
* *
* @param base ADC16 peripheral base address. * @param base ADC16 peripheral base address.
* *
* @return Execution status. * @return Execution status.
* @retval kStatus_Success Calibration is done successfully. * @retval kStatus_Success Calibration is done successfully.
* @retval kStatus_Fail Calibration is failed. * @retval kStatus_Fail Calibration has failed.
*/ */
status_t ADC16_DoAutoCalibration(ADC_Type *base); status_t ADC16_DoAutoCalibration(ADC_Type *base);
#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
@ -350,16 +349,16 @@ static inline void ADC16_SetOffsetValue(ADC_Type *base, int16_t value)
/* @} */ /* @} */
/*! /*!
* @name Advanced Feature * @name Advanced Features
* @{ * @{
*/ */
#if defined(FSL_FEATURE_ADC16_HAS_DMA) && FSL_FEATURE_ADC16_HAS_DMA #if defined(FSL_FEATURE_ADC16_HAS_DMA) && FSL_FEATURE_ADC16_HAS_DMA
/*! /*!
* @brief Enables generating the DMA trigger when conversion is completed. * @brief Enables generating the DMA trigger when the conversion is complete.
* *
* @param base ADC16 peripheral base address. * @param base ADC16 peripheral base address.
* @param enable Switcher of DMA feature. "true" means to enable, "false" means not. * @param enable Switcher of the DMA feature. "true" means enabled, "false" means not enabled.
*/ */
static inline void ADC16_EnableDMA(ADC_Type *base, bool enable) static inline void ADC16_EnableDMA(ADC_Type *base, bool enable)
{ {
@ -378,7 +377,7 @@ static inline void ADC16_EnableDMA(ADC_Type *base, bool enable)
* @brief Enables the hardware trigger mode. * @brief Enables the hardware trigger mode.
* *
* @param base ADC16 peripheral base address. * @param base ADC16 peripheral base address.
* @param enable Switcher of hardware trigger feature. "true" means to enable, "false" means not. * @param enable Switcher of the hardware trigger feature. "true" means enabled, "false" means not enabled.
*/ */
static inline void ADC16_EnableHardwareTrigger(ADC_Type *base, bool enable) static inline void ADC16_EnableHardwareTrigger(ADC_Type *base, bool enable)
{ {
@ -408,13 +407,12 @@ void ADC16_SetChannelMuxMode(ADC_Type *base, adc16_channel_mux_mode_t mode);
/*! /*!
* @brief Configures the hardware compare mode. * @brief Configures the hardware compare mode.
* *
* The hardware compare mode provides a way to process the conversion result automatically by hardware. Only the result * The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the result
* in * in the compare range is available. To compare the range, see "adc16_hardware_compare_mode_t" or the appopriate reference
* compare range is available. To compare the range, see "adc16_hardware_compare_mode_t", or the reference * manual for more information.
* manual document for more detailed information.
* *
* @param base ADC16 peripheral base address. * @param base ADC16 peripheral base address.
* @param config Pointer to "adc16_hardware_compare_config_t" structure. Passing "NULL" is to disable the feature. * @param config Pointer to the "adc16_hardware_compare_config_t" structure. Passing "NULL" disables the feature.
*/ */
void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config); void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config);
@ -422,21 +420,21 @@ void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare
/*! /*!
* @brief Sets the hardware average mode. * @brief Sets the hardware average mode.
* *
* Hardware average mode provides a way to process the conversion result automatically by hardware. The multiple * The hardware average mode provides a way to process the conversion result automatically by using hardware. The multiple
* conversion results are accumulated and averaged internally. This aids reading results. * conversion results are accumulated and averaged internally making them easier to read.
* *
* @param base ADC16 peripheral base address. * @param base ADC16 peripheral base address.
* @param mode Setting hardware average mode. See "adc16_hardware_average_mode_t". * @param mode Setting the hardware average mode. See "adc16_hardware_average_mode_t".
*/ */
void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode); void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode);
#endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ #endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */
#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA #if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA
/*! /*!
* @brief Configures the PGA for converter's front end. * @brief Configures the PGA for the converter's front end.
* *
* @param base ADC16 peripheral base address. * @param base ADC16 peripheral base address.
* @param config Pointer to "adc16_pga_config_t" structure. Passing "NULL" is to disable the feature. * @param config Pointer to the "adc16_pga_config_t" structure. Passing "NULL" disables the feature.
*/ */
void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config); void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config);
#endif /* FSL_FEATURE_ADC16_HAS_PGA */ #endif /* FSL_FEATURE_ADC16_HAS_PGA */
@ -468,26 +466,26 @@ void ADC16_ClearStatusFlags(ADC_Type *base, uint32_t mask);
/*! /*!
* @brief Configures the conversion channel. * @brief Configures the conversion channel.
* *
* This operation triggers the conversion if in software trigger mode. When in hardware trigger mode, this API * This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API
* configures the channel while the external trigger source helps to trigger the conversion. * configures the channel while the external trigger source helps to trigger the conversion.
* *
* Note that the "Channel Group" has a detailed description. * 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 * To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one
* group of status and control register, one for each conversion. The channel group parameter indicates which group of * group of status and control registers, 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 * registers are used, for example, 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 * 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 * the channel groups is actively controlling ADC conversions. The 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 * trigger modes. Channel group 1 and greater indicates multiple channel group registers for
* use only in hardware trigger mode. See the chip configuration information in the MCU reference manual about the * use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual for the
* number of SC1n registers (channel groups) specific to this device. None of the channel groups 1 or greater are used * number of SC1n registers (channel groups) specific to this device. Channel group 1 or greater are not used
* for software trigger operation and therefore writes to these channel groups do not initiate a new conversion. * for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion.
* Updating channel group 0 while a different channel group is actively controlling a conversion is allowed and * Updating the 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 * vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a
* conversion aborts the current conversion. * conversion aborts the current conversion.
* *
* @param base ADC16 peripheral base address. * @param base ADC16 peripheral base address.
* @param channelGroup Channel group index. * @param channelGroup Channel group index.
* @param config Pointer to "adc16_channel_config_t" structure for conversion channel. * @param config Pointer to the "adc16_channel_config_t" structure for the conversion channel.
*/ */
void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config); void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config);

View File

@ -28,7 +28,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "fsl_common.h"
#include "fsl_clock.h" #include "fsl_clock.h"
/******************************************************************************* /*******************************************************************************
@ -68,30 +67,30 @@
#define MCG_S_CLKST_VAL ((MCG->S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) #define MCG_S_CLKST_VAL ((MCG->S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT)
#define MCG_S_IREFST_VAL ((MCG->S & MCG_S_IREFST_MASK) >> MCG_S_IREFST_SHIFT) #define MCG_S_IREFST_VAL ((MCG->S & MCG_S_IREFST_MASK) >> MCG_S_IREFST_SHIFT)
#define MCG_S_PLLST_VAL ((MCG->S & MCG_S_PLLST_MASK) >> MCG_S_PLLST_SHIFT) #define MCG_S_PLLST_VAL ((MCG->S & MCG_S_PLLST_MASK) >> MCG_S_PLLST_SHIFT)
#define MCG_C1_FRDIV_VAL ((__FSL_CLOCK_SECURE_READ(&MCG->C1) & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT) #define MCG_C1_FRDIV_VAL ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT)
#define MCG_C2_LP_VAL ((__FSL_CLOCK_SECURE_READ(&MCG->C2) & MCG_C2_LP_MASK) >> MCG_C2_LP_SHIFT) #define MCG_C2_LP_VAL ((MCG->C2 & MCG_C2_LP_MASK) >> MCG_C2_LP_SHIFT)
#define MCG_C2_RANGE_VAL ((__FSL_CLOCK_SECURE_READ(&MCG->C2) & MCG_C2_RANGE_MASK) >> MCG_C2_RANGE_SHIFT) #define MCG_C2_RANGE_VAL ((MCG->C2 & MCG_C2_RANGE_MASK) >> MCG_C2_RANGE_SHIFT)
#define MCG_SC_FCRDIV_VAL ((__FSL_CLOCK_SECURE_READ(&MCG->SC) & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT) #define MCG_SC_FCRDIV_VAL ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT)
#define MCG_S2_PLLCST_VAL ((MCG->S2 & MCG_S2_PLLCST_MASK) >> MCG_S2_PLLCST_SHIFT) #define MCG_S2_PLLCST_VAL ((MCG->S2 & MCG_S2_PLLCST_MASK) >> MCG_S2_PLLCST_SHIFT)
#define MCG_C7_OSCSEL_VAL ((__FSL_CLOCK_SECURE_READ(&MCG->C7) & MCG_C7_OSCSEL_MASK) >> MCG_C7_OSCSEL_SHIFT) #define MCG_C7_OSCSEL_VAL ((MCG->C7 & MCG_C7_OSCSEL_MASK) >> MCG_C7_OSCSEL_SHIFT)
#define MCG_C4_DMX32_VAL ((MCG->C4 & MCG_C4_DMX32_MASK) >> MCG_C4_DMX32_SHIFT) #define MCG_C4_DMX32_VAL ((MCG->C4 & MCG_C4_DMX32_MASK) >> MCG_C4_DMX32_SHIFT)
#define MCG_C4_DRST_DRS_VAL ((MCG->C4 & MCG_C4_DRST_DRS_MASK) >> MCG_C4_DRST_DRS_SHIFT) #define MCG_C4_DRST_DRS_VAL ((MCG->C4 & MCG_C4_DRST_DRS_MASK) >> MCG_C4_DRST_DRS_SHIFT)
#define MCG_C7_PLL32KREFSEL_VAL ((__FSL_CLOCK_SECURE_READ(&MCG->C7) & MCG_C7_PLL32KREFSEL_MASK) >> MCG_C7_PLL32KREFSEL_SHIFT) #define MCG_C7_PLL32KREFSEL_VAL ((MCG->C7 & MCG_C7_PLL32KREFSEL_MASK) >> MCG_C7_PLL32KREFSEL_SHIFT)
#define MCG_C5_PLLREFSEL0_VAL ((__FSL_CLOCK_SECURE_READ(&MCG->C5) & MCG_C5_PLLREFSEL0_MASK) >> MCG_C5_PLLREFSEL0_SHIFT) #define MCG_C5_PLLREFSEL0_VAL ((MCG->C5 & MCG_C5_PLLREFSEL0_MASK) >> MCG_C5_PLLREFSEL0_SHIFT)
#define MCG_C11_PLLREFSEL1_VAL ((MCG->C11 & MCG_C11_PLLREFSEL1_MASK) >> MCG_C11_PLLREFSEL1_SHIFT) #define MCG_C11_PLLREFSEL1_VAL ((MCG->C11 & MCG_C11_PLLREFSEL1_MASK) >> MCG_C11_PLLREFSEL1_SHIFT)
#define MCG_C11_PRDIV1_VAL ((MCG->C11 & MCG_C11_PRDIV1_MASK) >> MCG_C11_PRDIV1_SHIFT) #define MCG_C11_PRDIV1_VAL ((MCG->C11 & MCG_C11_PRDIV1_MASK) >> MCG_C11_PRDIV1_SHIFT)
#define MCG_C12_VDIV1_VAL ((MCG->C12 & MCG_C12_VDIV1_MASK) >> MCG_C12_VDIV1_SHIFT) #define MCG_C12_VDIV1_VAL ((MCG->C12 & MCG_C12_VDIV1_MASK) >> MCG_C12_VDIV1_SHIFT)
#define MCG_C5_PRDIV0_VAL ((__FSL_CLOCK_SECURE_READ(&MCG->C5) & MCG_C5_PRDIV0_MASK) >> MCG_C5_PRDIV0_SHIFT) #define MCG_C5_PRDIV0_VAL ((MCG->C5 & MCG_C5_PRDIV0_MASK) >> MCG_C5_PRDIV0_SHIFT)
#define MCG_C6_VDIV0_VAL ((__FSL_CLOCK_SECURE_READ(&MCG->C6) & MCG_C6_VDIV0_MASK) >> MCG_C6_VDIV0_SHIFT) #define MCG_C6_VDIV0_VAL ((MCG->C6 & MCG_C6_VDIV0_MASK) >> MCG_C6_VDIV0_SHIFT)
#define OSC_MODE_MASK (MCG_C2_EREFS0_MASK | MCG_C2_HGO0_MASK | MCG_C2_RANGE0_MASK) #define OSC_MODE_MASK (MCG_C2_EREFS0_MASK | MCG_C2_HGO0_MASK | MCG_C2_RANGE0_MASK)
#define SIM_CLKDIV1_OUTDIV1_VAL ((__FSL_CLOCK_SECURE_READ(&SIM->CLKDIV1) & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT) #define SIM_CLKDIV1_OUTDIV1_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT)
#define SIM_CLKDIV1_OUTDIV2_VAL ((__FSL_CLOCK_SECURE_READ(&SIM->CLKDIV1) & SIM_CLKDIV1_OUTDIV2_MASK) >> SIM_CLKDIV1_OUTDIV2_SHIFT) #define SIM_CLKDIV1_OUTDIV2_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV2_MASK) >> SIM_CLKDIV1_OUTDIV2_SHIFT)
#define SIM_CLKDIV1_OUTDIV3_VAL ((__FSL_CLOCK_SECURE_READ(&SIM->CLKDIV1) & SIM_CLKDIV1_OUTDIV3_MASK) >> SIM_CLKDIV1_OUTDIV3_SHIFT) #define SIM_CLKDIV1_OUTDIV3_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV3_MASK) >> SIM_CLKDIV1_OUTDIV3_SHIFT)
#define SIM_CLKDIV1_OUTDIV4_VAL ((__FSL_CLOCK_SECURE_READ(&SIM->CLKDIV1) & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) #define SIM_CLKDIV1_OUTDIV4_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT)
#define SIM_SOPT1_OSC32KSEL_VAL ((__FSL_CLOCK_SECURE_READ(&SIM->SOPT1) & SIM_SOPT1_OSC32KSEL_MASK) >> SIM_SOPT1_OSC32KSEL_SHIFT) #define SIM_SOPT1_OSC32KSEL_VAL ((SIM->SOPT1 & SIM_SOPT1_OSC32KSEL_MASK) >> SIM_SOPT1_OSC32KSEL_SHIFT)
#define SIM_SOPT2_PLLFLLSEL_VAL ((__FSL_CLOCK_SECURE_READ(&SIM->SOPT2) & SIM_SOPT2_PLLFLLSEL_MASK) >> SIM_SOPT2_PLLFLLSEL_SHIFT) #define SIM_SOPT2_PLLFLLSEL_VAL ((SIM->SOPT2 & SIM_SOPT2_PLLFLLSEL_MASK) >> SIM_SOPT2_PLLFLLSEL_SHIFT)
/* MCG_S_CLKST definition. */ /* MCG_S_CLKST definition. */
enum _mcg_clkout_stat enum _mcg_clkout_stat
@ -120,7 +119,6 @@ static uint32_t s_fastIrcFreq = 4000000U;
/* External XTAL0 (OSC0) clock frequency. */ /* External XTAL0 (OSC0) clock frequency. */
uint32_t g_xtal0Freq; uint32_t g_xtal0Freq;
/* External XTAL32K clock frequency. */ /* External XTAL32K clock frequency. */
uint32_t g_xtal32Freq; uint32_t g_xtal32Freq;
@ -493,8 +491,7 @@ uint32_t CLOCK_GetFreq(clock_name_t clockName)
void CLOCK_SetSimConfig(sim_clock_config_t const *config) void CLOCK_SetSimConfig(sim_clock_config_t const *config)
{ {
__FSL_CLOCK_SECURE_WRITE(&SIM->CLKDIV1, config->clkdiv1); SIM->CLKDIV1 = config->clkdiv1;
CLOCK_SetPllFllSelClock(config->pllFllSel); CLOCK_SetPllFllSelClock(config->pllFllSel);
CLOCK_SetEr32kClock(config->er32kSrc); CLOCK_SetEr32kClock(config->er32kSrc);
} }
@ -507,30 +504,30 @@ bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq)
if (kCLOCK_UsbSrcExt == src) if (kCLOCK_UsbSrcExt == src)
{ {
__FSL_CLOCK_SECURE_BITS_CLEAR(&SIM->SOPT2, SIM_SOPT2_USBSRC_MASK); SIM->SOPT2 &= ~SIM_SOPT2_USBSRC_MASK;
} }
else else
{ {
switch (freq) switch (freq)
{ {
case 120000000U: case 120000000U:
__FSL_CLOCK_SECURE_WRITE(&SIM->CLKDIV2, SIM_CLKDIV2_USBDIV(4) | SIM_CLKDIV2_USBFRAC(1)); SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(4) | SIM_CLKDIV2_USBFRAC(1);
break; break;
case 96000000U: case 96000000U:
__FSL_CLOCK_SECURE_WRITE(&SIM->CLKDIV2, SIM_CLKDIV2_USBDIV(1) | SIM_CLKDIV2_USBFRAC(0)); SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(1) | SIM_CLKDIV2_USBFRAC(0);
break; break;
case 72000000U: case 72000000U:
__FSL_CLOCK_SECURE_WRITE(&SIM->CLKDIV2, SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC(1)); SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC(1);
break; break;
case 48000000U: case 48000000U:
__FSL_CLOCK_SECURE_WRITE(&SIM->CLKDIV2, SIM_CLKDIV2_USBDIV(0) | SIM_CLKDIV2_USBFRAC(0)); SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0) | SIM_CLKDIV2_USBFRAC(0);
break; break;
default: default:
ret = false; ret = false;
break; break;
} }
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&SIM->SOPT2, SIM_SOPT2_PLLFLLSEL_MASK | SIM_SOPT2_USBSRC_MASK, (uint32_t)src); SIM->SOPT2 = ((SIM->SOPT2 & ~(SIM_SOPT2_PLLFLLSEL_MASK | SIM_SOPT2_USBSRC_MASK)) | (uint32_t)src);
} }
CLOCK_EnableClock(kCLOCK_Usbfs0); CLOCK_EnableClock(kCLOCK_Usbfs0);
@ -577,7 +574,7 @@ uint32_t CLOCK_GetFllFreq(void)
uint32_t freq; uint32_t freq;
/* If FLL is not enabled currently, then return 0U. */ /* If FLL is not enabled currently, then return 0U. */
if ((__FSL_CLOCK_SECURE_READ(&MCG->C2) & MCG_C2_LP_MASK) || (MCG->S & MCG_S_PLLST_MASK)) if ((MCG->C2 & MCG_C2_LP_MASK) || (MCG->S & MCG_S_PLLST_MASK))
{ {
return 0U; return 0U;
} }
@ -598,7 +595,7 @@ uint32_t CLOCK_GetFllFreq(void)
uint32_t CLOCK_GetInternalRefClkFreq(void) uint32_t CLOCK_GetInternalRefClkFreq(void)
{ {
/* If MCGIRCLK is gated. */ /* If MCGIRCLK is gated. */
if (!(__FSL_CLOCK_SECURE_READ(&MCG->C1) & MCG_C1_IRCLKEN_MASK)) if (!(MCG->C1 & MCG_C1_IRCLKEN_MASK))
{ {
return 0U; return 0U;
} }
@ -633,6 +630,12 @@ uint32_t CLOCK_GetPll0Freq(void)
mcgpll0clk = CLOCK_GetPll0RefFreq(); mcgpll0clk = CLOCK_GetPll0RefFreq();
/*
* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock.
* Please call CLOCK_SetXtal1Freq base on board setting before using OSC1 clock.
*/
assert(mcgpll0clk);
mcgpll0clk /= (FSL_FEATURE_MCG_PLL_PRDIV_BASE + MCG_C5_PRDIV0_VAL); mcgpll0clk /= (FSL_FEATURE_MCG_PLL_PRDIV_BASE + MCG_C5_PRDIV0_VAL);
mcgpll0clk *= (FSL_FEATURE_MCG_PLL_VDIV_BASE + MCG_C6_VDIV0_VAL); mcgpll0clk *= (FSL_FEATURE_MCG_PLL_VDIV_BASE + MCG_C6_VDIV0_VAL);
@ -662,10 +665,10 @@ status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel)
needDelay = false; needDelay = false;
} }
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C7, MCG_C7_OSCSEL_MASK, MCG_C7_OSCSEL(oscsel)); MCG->C7 = (MCG->C7 & ~MCG_C7_OSCSEL_MASK) | MCG_C7_OSCSEL(oscsel);
if (kMCG_OscselOsc == oscsel) if (kMCG_OscselOsc == oscsel)
{ {
if (__FSL_CLOCK_SECURE_READ(&MCG->C2) & MCG_C2_EREFS_MASK) if (MCG->C2 & MCG_C2_EREFS_MASK)
{ {
while (!(MCG->S & MCG_S_OSCINIT0_MASK)) while (!(MCG->S & MCG_S_OSCINIT0_MASK))
{ {
@ -708,20 +711,20 @@ status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs,
if (fcrdiv != curFcrdiv) if (fcrdiv != curFcrdiv)
{ {
/* If fast IRC is in use currently, change to slow IRC. */ /* If fast IRC is in use currently, change to slow IRC. */
if ((kMCG_IrcFast == curIrcs) && ((mcgOutClkState == kMCG_ClkOutStatInt) || (__FSL_CLOCK_SECURE_READ(&MCG->C1) & MCG_C1_IRCLKEN_MASK))) if ((kMCG_IrcFast == curIrcs) && ((mcgOutClkState == kMCG_ClkOutStatInt) || (MCG->C1 & MCG_C1_IRCLKEN_MASK)))
{ {
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C2, MCG_C2_IRCS_MASK, MCG_C2_IRCS(kMCG_IrcSlow)); MCG->C2 = ((MCG->C2 & ~MCG_C2_IRCS_MASK) | (MCG_C2_IRCS(kMCG_IrcSlow)));
while (MCG_S_IRCST_VAL != kMCG_IrcSlow) while (MCG_S_IRCST_VAL != kMCG_IrcSlow)
{ {
} }
} }
/* Update FCRDIV. */ /* Update FCRDIV. */
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->SC, MCG_SC_FCRDIV_MASK | MCG_SC_ATMF_MASK | MCG_SC_LOCS0_MASK, MCG_SC_FCRDIV(fcrdiv)); MCG->SC = (MCG->SC & ~(MCG_SC_FCRDIV_MASK | MCG_SC_ATMF_MASK | MCG_SC_LOCS0_MASK)) | MCG_SC_FCRDIV(fcrdiv);
} }
/* Set internal reference clock selection. */ /* Set internal reference clock selection. */
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C2, MCG_C2_IRCS_MASK, MCG_C2_IRCS(ircs)); MCG->C2 = (MCG->C2 & ~MCG_C2_IRCS_MASK) | (MCG_C2_IRCS(ircs));
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C1, MCG_C1_IRCLKEN_MASK | MCG_C1_IREFSTEN_MASK, (uint8_t)enableMode); MCG->C1 = (MCG->C1 & ~(MCG_C1_IRCLKEN_MASK | MCG_C1_IREFSTEN_MASK)) | (uint8_t)enableMode;
/* If MCGIRCLK is used, need to wait for MCG_S_IRCST. */ /* If MCGIRCLK is used, need to wait for MCG_S_IRCST. */
if ((mcgOutClkState == kMCG_ClkOutStatInt) || (enableMode & kMCG_IrclkEnable)) if ((mcgOutClkState == kMCG_ClkOutStatInt) || (enableMode & kMCG_IrclkEnable))
@ -838,12 +841,12 @@ void CLOCK_EnablePll0(mcg_pll_config_t const *config)
uint8_t mcg_c5 = 0U; uint8_t mcg_c5 = 0U;
mcg_c5 |= MCG_C5_PRDIV0(config->prdiv); mcg_c5 |= MCG_C5_PRDIV0(config->prdiv);
__FSL_CLOCK_SECURE_WRITE(&MCG->C5, mcg_c5); /* Disable the PLL first. */ MCG->C5 = mcg_c5; /* Disable the PLL first. */
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C6, MCG_C6_VDIV0_MASK, MCG_C6_VDIV0(config->vdiv)); MCG->C6 = (MCG->C6 & ~MCG_C6_VDIV0_MASK) | MCG_C6_VDIV0(config->vdiv);
/* Set enable mode. */ /* Set enable mode. */
__FSL_CLOCK_SECURE_BITS_SET(&MCG->C5, ((uint32_t)kMCG_PllEnableIndependent | (uint32_t)config->enableMode)); MCG->C5 |= ((uint32_t)kMCG_PllEnableIndependent | (uint32_t)config->enableMode);
/* Wait for PLL lock. */ /* Wait for PLL lock. */
while (!(MCG->S & MCG_S_LOCK0_MASK)) while (!(MCG->S & MCG_S_LOCK0_MASK))
@ -858,25 +861,25 @@ void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode)
if (kMCG_MonitorNone == mode) if (kMCG_MonitorNone == mode)
{ {
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C6, MCG_C6_CME0_MASK); MCG->C6 &= ~MCG_C6_CME0_MASK;
} }
else else
{ {
if (kMCG_MonitorInt == mode) if (kMCG_MonitorInt == mode)
{ {
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C2, MCG_C2_LOCRE0_MASK); MCG->C2 &= ~MCG_C2_LOCRE0_MASK;
} }
else else
{ {
__FSL_CLOCK_SECURE_BITS_SET(&MCG->C2, MCG_C2_LOCRE0_MASK); MCG->C2 |= MCG_C2_LOCRE0_MASK;
} }
__FSL_CLOCK_SECURE_BITS_SET(&MCG->C6, MCG_C6_CME0_MASK); MCG->C6 |= MCG_C6_CME0_MASK;
} }
} }
void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode) void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode)
{ {
uint8_t mcg_c8 = __FSL_CLOCK_SECURE_READ(&MCG->C8); uint8_t mcg_c8 = MCG->C8;
mcg_c8 &= ~(MCG_C8_CME1_MASK | MCG_C8_LOCRE1_MASK); mcg_c8 &= ~(MCG_C8_CME1_MASK | MCG_C8_LOCRE1_MASK);
@ -888,7 +891,7 @@ void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode)
} }
mcg_c8 |= MCG_C8_CME1_MASK; mcg_c8 |= MCG_C8_CME1_MASK;
} }
__FSL_CLOCK_SECURE_WRITE(&MCG->C8, mcg_c8); MCG->C8 = mcg_c8;
} }
void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode) void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode)
@ -900,11 +903,11 @@ void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode)
if (kMCG_MonitorNone == mode) if (kMCG_MonitorNone == mode)
{ {
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C6, MCG_C6_LOLIE0_MASK); MCG->C6 &= ~MCG_C6_LOLIE0_MASK;
} }
else else
{ {
mcg_c8 = __FSL_CLOCK_SECURE_READ(&MCG->C8); mcg_c8 = MCG->C8;
mcg_c8 &= ~MCG_C8_LOCS1_MASK; mcg_c8 &= ~MCG_C8_LOCS1_MASK;
@ -916,8 +919,8 @@ void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode)
{ {
mcg_c8 |= MCG_C8_LOLRE_MASK; mcg_c8 |= MCG_C8_LOLRE_MASK;
} }
__FSL_CLOCK_SECURE_WRITE(&MCG->C8, mcg_c8); MCG->C8 = mcg_c8;
__FSL_CLOCK_SECURE_BITS_SET(&MCG->C6, MCG_C6_LOLIE0_MASK); MCG->C6 |= MCG_C6_LOLIE0_MASK;
} }
} }
@ -926,7 +929,7 @@ uint32_t CLOCK_GetStatusFlags(void)
uint32_t ret = 0U; uint32_t ret = 0U;
uint8_t mcg_s = MCG->S; uint8_t mcg_s = MCG->S;
if (__FSL_CLOCK_SECURE_READ(&MCG->SC) & MCG_SC_LOCS0_MASK) if (MCG->SC & MCG_SC_LOCS0_MASK)
{ {
ret |= kMCG_Osc0LostFlag; ret |= kMCG_Osc0LostFlag;
} }
@ -934,7 +937,7 @@ uint32_t CLOCK_GetStatusFlags(void)
{ {
ret |= kMCG_Osc0InitFlag; ret |= kMCG_Osc0InitFlag;
} }
if (__FSL_CLOCK_SECURE_READ(&MCG->C8) & MCG_C8_LOCS1_MASK) if (MCG->C8 & MCG_C8_LOCS1_MASK)
{ {
ret |= kMCG_RtcOscLostFlag; ret |= kMCG_RtcOscLostFlag;
} }
@ -959,8 +962,8 @@ void CLOCK_ClearStatusFlags(uint32_t mask)
} }
if (mask & kMCG_RtcOscLostFlag) if (mask & kMCG_RtcOscLostFlag)
{ {
reg = __FSL_CLOCK_SECURE_READ(&MCG->C8); reg = MCG->C8;
__FSL_CLOCK_SECURE_WRITE(&MCG->C8, reg); MCG->C8 = reg;
} }
if (mask & kMCG_Pll0LostFlag) if (mask & kMCG_Pll0LostFlag)
{ {
@ -975,7 +978,7 @@ void CLOCK_InitOsc0(osc_config_t const *config)
OSC_SetCapLoad(OSC0, config->capLoad); OSC_SetCapLoad(OSC0, config->capLoad);
OSC_SetExtRefClkConfig(OSC0, &config->oscerConfig); OSC_SetExtRefClkConfig(OSC0, &config->oscerConfig);
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C2, OSC_MODE_MASK, MCG_C2_RANGE(range) | (uint8_t)config->workMode); MCG->C2 = ((MCG->C2 & ~OSC_MODE_MASK) | MCG_C2_RANGE(range) | (uint8_t)config->workMode);
if ((kOSC_ModeExt != config->workMode) && (OSC0->CR & OSC_CR_ERCLKEN_MASK)) if ((kOSC_ModeExt != config->workMode) && (OSC0->CR & OSC_CR_ERCLKEN_MASK))
{ {
@ -989,7 +992,7 @@ void CLOCK_InitOsc0(osc_config_t const *config)
void CLOCK_DeinitOsc0(void) void CLOCK_DeinitOsc0(void)
{ {
OSC0->CR = 0U; OSC0->CR = 0U;
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C2, OSC_MODE_MASK); MCG->C2 &= ~OSC_MODE_MASK;
} }
status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_t *actualFreq, mcg_atm_select_t atms) status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_t *actualFreq, mcg_atm_select_t atms)
@ -1036,21 +1039,21 @@ status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_
MCG->ATCVL = (uint8_t)actv; MCG->ATCVL = (uint8_t)actv;
MCG->ATCVH = (uint8_t)(actv >> 8U); MCG->ATCVH = (uint8_t)(actv >> 8U);
mcg_sc = __FSL_CLOCK_SECURE_READ(&MCG->SC); mcg_sc = MCG->SC;
mcg_sc &= ~(MCG_SC_ATMS_MASK | MCG_SC_LOCS0_MASK); mcg_sc &= ~(MCG_SC_ATMS_MASK | MCG_SC_LOCS0_MASK);
mcg_sc |= (MCG_SC_ATMF_MASK | MCG_SC_ATMS(atms)); mcg_sc |= (MCG_SC_ATMF_MASK | MCG_SC_ATMS(atms));
__FSL_CLOCK_SECURE_WRITE(&MCG->SC, (mcg_sc | MCG_SC_ATME_MASK)); MCG->SC = (mcg_sc | MCG_SC_ATME_MASK);
/* Wait for finished. */ /* Wait for finished. */
while (__FSL_CLOCK_SECURE_READ(&MCG->SC) & MCG_SC_ATME_MASK) while (MCG->SC & MCG_SC_ATME_MASK)
{ {
} }
/* Error occurs? */ /* Error occurs? */
if (__FSL_CLOCK_SECURE_READ(&MCG->SC) & MCG_SC_ATMF_MASK) if (MCG->SC & MCG_SC_ATMF_MASK)
{ {
/* Clear the failed flag. */ /* Clear the failed flag. */
__FSL_CLOCK_SECURE_WRITE(&MCG->SC, mcg_sc); MCG->SC = mcg_sc;
return kStatus_MCG_AtmHardwareFail; return kStatus_MCG_AtmHardwareFail;
} }
@ -1168,7 +1171,7 @@ mcg_mode_t CLOCK_GetMode(void)
return mode; return mode;
} }
status_t CLOCK_SetFeiMode(mcg_drs_t drs, void (*fllStableDelay)(void)) status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void))
{ {
uint8_t mcg_c4; uint8_t mcg_c4;
bool change_drs = false; bool change_drs = false;
@ -1197,7 +1200,7 @@ status_t CLOCK_SetFeiMode(mcg_drs_t drs, void (*fllStableDelay)(void))
/* Set CLKS and IREFS. */ /* Set CLKS and IREFS. */
MCG->C1 = MCG->C1 =
((__FSL_CLOCK_SECURE_READ(&MCG->C1) & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK))) | (MCG_C1_CLKS(kMCG_ClkOutSrcOut) /* CLKS = 0 */ ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK))) | (MCG_C1_CLKS(kMCG_ClkOutSrcOut) /* CLKS = 0 */
| MCG_C1_IREFS(kMCG_FllSrcInternal)); /* IREFS = 1 */ | MCG_C1_IREFS(kMCG_FllSrcInternal)); /* IREFS = 1 */
/* Wait and check status. */ /* Wait and check status. */
@ -1212,7 +1215,7 @@ status_t CLOCK_SetFeiMode(mcg_drs_t drs, void (*fllStableDelay)(void))
} }
/* In FEI mode, the MCG_C4[DMX32] is set to 0U. */ /* In FEI mode, the MCG_C4[DMX32] is set to 0U. */
MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DRST_DRS(drs)); MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs));
/* Check MCG_S[CLKST] */ /* Check MCG_S[CLKST] */
while (kMCG_ClkOutStatFll != MCG_S_CLKST_VAL) while (kMCG_ClkOutStatFll != MCG_S_CLKST_VAL)
@ -1256,7 +1259,7 @@ status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void
} }
/* Set CLKS and IREFS. */ /* Set CLKS and IREFS. */
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C1, MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK, MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK)) |
(MCG_C1_CLKS(kMCG_ClkOutSrcOut) /* CLKS = 0 */ (MCG_C1_CLKS(kMCG_ClkOutSrcOut) /* CLKS = 0 */
| MCG_C1_FRDIV(frdiv) /* FRDIV */ | MCG_C1_FRDIV(frdiv) /* FRDIV */
| MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */
@ -1295,7 +1298,7 @@ status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void
return kStatus_Success; return kStatus_Success;
} }
status_t CLOCK_SetFbiMode(mcg_drs_t drs, void (*fllStableDelay)(void)) status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void))
{ {
uint8_t mcg_c4; uint8_t mcg_c4;
bool change_drs = false; bool change_drs = false;
@ -1313,7 +1316,7 @@ status_t CLOCK_SetFbiMode(mcg_drs_t drs, void (*fllStableDelay)(void))
mcg_c4 = MCG->C4; mcg_c4 = MCG->C4;
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C2, MCG_C2_LP_MASK); /* Disable lowpower. */ MCG->C2 &= ~MCG_C2_LP_MASK; /* Disable lowpower. */
/* /*
Errata: ERR007993 Errata: ERR007993
@ -1329,9 +1332,9 @@ status_t CLOCK_SetFbiMode(mcg_drs_t drs, void (*fllStableDelay)(void))
} }
/* Set CLKS and IREFS. */ /* Set CLKS and IREFS. */
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C1, MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK, MCG->C1 =
(MCG_C1_CLKS(kMCG_ClkOutSrcInternal) /* CLKS = 1 */ ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | (MCG_C1_CLKS(kMCG_ClkOutSrcInternal) /* CLKS = 1 */
| MCG_C1_IREFS(kMCG_FllSrcInternal))); /* IREFS = 1 */ | MCG_C1_IREFS(kMCG_FllSrcInternal))); /* IREFS = 1 */
/* Wait and check status. */ /* Wait and check status. */
while (kMCG_FllSrcInternal != MCG_S_IREFST_VAL) while (kMCG_FllSrcInternal != MCG_S_IREFST_VAL)
@ -1348,7 +1351,7 @@ status_t CLOCK_SetFbiMode(mcg_drs_t drs, void (*fllStableDelay)(void))
{ {
} }
MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DRST_DRS(drs)); MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs));
/* Wait for FLL stable time. */ /* Wait for FLL stable time. */
if (fllStableDelay) if (fllStableDelay)
@ -1374,13 +1377,13 @@ status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void
#endif #endif
/* Change to FLL mode. */ /* Change to FLL mode. */
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C6, MCG_C6_PLLS_MASK); MCG->C6 &= ~MCG_C6_PLLS_MASK;
while (MCG->S & MCG_S_PLLST_MASK) while (MCG->S & MCG_S_PLLST_MASK)
{ {
} }
/* Set LP bit to enable the FLL */ /* Set LP bit to enable the FLL */
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C2, MCG_C2_LP_MASK); MCG->C2 &= ~MCG_C2_LP_MASK;
mcg_c4 = MCG->C4; mcg_c4 = MCG->C4;
@ -1398,7 +1401,7 @@ status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void
} }
/* Set CLKS and IREFS. */ /* Set CLKS and IREFS. */
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C1, MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK, MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK)) |
(MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */ (MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */
| MCG_C1_FRDIV(frdiv) /* FRDIV = frdiv */ | MCG_C1_FRDIV(frdiv) /* FRDIV = frdiv */
| MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */
@ -1441,7 +1444,7 @@ status_t CLOCK_SetBlpiMode(void)
#endif /* MCG_CONFIG_CHECK_PARAM */ #endif /* MCG_CONFIG_CHECK_PARAM */
/* Set LP. */ /* Set LP. */
__FSL_CLOCK_SECURE_BITS_SET(&MCG->C2, MCG_C2_LP_MASK); MCG->C2 |= MCG_C2_LP_MASK;
return kStatus_Success; return kStatus_Success;
} }
@ -1456,21 +1459,23 @@ status_t CLOCK_SetBlpeMode(void)
#endif #endif
/* Set LP bit to enter BLPE mode. */ /* Set LP bit to enter BLPE mode. */
__FSL_CLOCK_SECURE_BITS_SET(&MCG->C2, MCG_C2_LP_MASK); MCG->C2 |= MCG_C2_LP_MASK;
return kStatus_Success; return kStatus_Success;
} }
status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config) status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config)
{ {
assert(config);
/* /*
This function is designed to change MCG to PBE mode from PEE/BLPE/FBE, This function is designed to change MCG to PBE mode from PEE/BLPE/FBE,
but with this workflow, the source mode could be all modes except PEI/PBI. but with this workflow, the source mode could be all modes except PEI/PBI.
*/ */
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C2, MCG_C2_LP_MASK); /* Disable lowpower. */ MCG->C2 &= ~MCG_C2_LP_MASK; /* Disable lowpower. */
/* Change to use external clock first. */ /* Change to use external clock first. */
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C1, MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK, MCG_C1_CLKS(kMCG_ClkOutSrcExternal)); MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | MCG_C1_CLKS(kMCG_ClkOutSrcExternal));
/* Wait for CLKST clock status bits to show clock source is ext ref clk */ /* Wait for CLKST clock status bits to show clock source is ext ref clk */
while ((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) != while ((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) !=
@ -1479,7 +1484,7 @@ status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *co
} }
/* Disable PLL first, then configure PLL. */ /* Disable PLL first, then configure PLL. */
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C6, MCG_C6_PLLS_MASK); MCG->C6 &= ~MCG_C6_PLLS_MASK;
while (MCG->S & MCG_S_PLLST_MASK) while (MCG->S & MCG_S_PLLST_MASK)
{ {
} }
@ -1490,7 +1495,9 @@ status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *co
} }
/* Change to PLL mode. */ /* Change to PLL mode. */
__FSL_CLOCK_SECURE_BITS_SET(&MCG->C6, MCG_C6_PLLS_MASK); MCG->C6 |= MCG_C6_PLLS_MASK;
/* Wait for PLL mode changed. */
while (!(MCG->S & MCG_S_PLLST_MASK)) while (!(MCG->S & MCG_S_PLLST_MASK))
{ {
} }
@ -1509,7 +1516,7 @@ status_t CLOCK_SetPeeMode(void)
#endif #endif
/* Change to use PLL/FLL output clock first. */ /* Change to use PLL/FLL output clock first. */
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C1, MCG_C1_CLKS_MASK, MCG_C1_CLKS(kMCG_ClkOutSrcOut)); MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcOut);
/* Wait for clock status bits to update */ /* Wait for clock status bits to update */
while (MCG_S_CLKST_VAL != kMCG_ClkOutStatPll) while (MCG_S_CLKST_VAL != kMCG_ClkOutStatPll)
@ -1529,15 +1536,15 @@ status_t CLOCK_ExternalModeToFbeModeQuick(void)
#endif /* MCG_CONFIG_CHECK_PARAM */ #endif /* MCG_CONFIG_CHECK_PARAM */
/* Disable low power */ /* Disable low power */
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C2, MCG_C2_LP_MASK); MCG->C2 &= ~MCG_C2_LP_MASK;
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C1, MCG_C1_CLKS_MASK, MCG_C1_CLKS(kMCG_ClkOutSrcExternal)); MCG->C1 = ((MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcExternal));
while (MCG_S_CLKST_VAL != kMCG_ClkOutStatExt) while (MCG_S_CLKST_VAL != kMCG_ClkOutStatExt)
{ {
} }
/* Disable PLL. */ /* Disable PLL. */
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C6, MCG_C6_PLLS_MASK); MCG->C6 &= ~MCG_C6_PLLS_MASK;
while (MCG->S & MCG_S_PLLST_MASK) while (MCG->S & MCG_S_PLLST_MASK)
{ {
} }
@ -1555,9 +1562,9 @@ status_t CLOCK_InternalModeToFbiModeQuick(void)
#endif #endif
/* Disable low power */ /* Disable low power */
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C2, MCG_C2_LP_MASK); MCG->C2 &= ~MCG_C2_LP_MASK;
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C1, MCG_C1_CLKS_MASK, MCG_C1_CLKS(kMCG_ClkOutSrcInternal)); MCG->C1 = ((MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcInternal));
while (MCG_S_CLKST_VAL != kMCG_ClkOutStatInt) while (MCG_S_CLKST_VAL != kMCG_ClkOutStatInt)
{ {
} }
@ -1565,9 +1572,9 @@ status_t CLOCK_InternalModeToFbiModeQuick(void)
return kStatus_Success; return kStatus_Success;
} }
status_t CLOCK_BootToFeiMode(mcg_drs_t drs, void (*fllStableDelay)(void)) status_t CLOCK_BootToFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void))
{ {
return CLOCK_SetFeiMode(drs, fllStableDelay); return CLOCK_SetFeiMode(dmx32, drs, fllStableDelay);
} }
status_t CLOCK_BootToFeeMode( status_t CLOCK_BootToFeeMode(
@ -1584,13 +1591,13 @@ status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEn
CLOCK_SetInternalRefClkConfig(ircEnableMode, ircs, fcrdiv); CLOCK_SetInternalRefClkConfig(ircEnableMode, ircs, fcrdiv);
/* If reset mode is not BLPI, first enter FBI mode. */ /* If reset mode is not BLPI, first enter FBI mode. */
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C1, MCG_C1_CLKS_MASK, MCG_C1_CLKS(kMCG_ClkOutSrcInternal)); MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcInternal);
while (MCG_S_CLKST_VAL != kMCG_ClkOutStatInt) while (MCG_S_CLKST_VAL != kMCG_ClkOutStatInt)
{ {
} }
/* Enter BLPI mode. */ /* Enter BLPI mode. */
__FSL_CLOCK_SECURE_BITS_SET(&MCG->C2, MCG_C2_LP_MASK); MCG->C2 |= MCG_C2_LP_MASK;
return kStatus_Success; return kStatus_Success;
} }
@ -1600,9 +1607,9 @@ status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel)
CLOCK_SetExternalRefClkConfig(oscsel); CLOCK_SetExternalRefClkConfig(oscsel);
/* Set to FBE mode. */ /* Set to FBE mode. */
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C1, MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK, MCG->C1 =
(MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */ ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | (MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */
| MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */
/* Wait for MCG_S[CLKST] and MCG_S[IREFST]. */ /* Wait for MCG_S[CLKST] and MCG_S[IREFST]. */
while ((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) != while ((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) !=
@ -1611,7 +1618,7 @@ status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel)
} }
/* In FBE now, start to enter BLPE. */ /* In FBE now, start to enter BLPE. */
__FSL_CLOCK_SECURE_BITS_SET(&MCG->C2, MCG_C2_LP_MASK); MCG->C2 |= MCG_C2_LP_MASK;
return kStatus_Success; return kStatus_Success;
} }
@ -1625,7 +1632,7 @@ status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mc
CLOCK_SetPbeMode(pllcs, config); CLOCK_SetPbeMode(pllcs, config);
/* Change to use PLL output clock. */ /* Change to use PLL output clock. */
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C1, MCG_C1_CLKS_MASK, MCG_C1_CLKS(kMCG_ClkOutSrcOut)); MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcOut);
while (MCG_S_CLKST_VAL != kMCG_ClkOutStatPll) while (MCG_S_CLKST_VAL != kMCG_ClkOutStatPll)
{ {
} }
@ -1676,7 +1683,7 @@ status_t CLOCK_SetMcgConfig(const mcg_config_t *config)
if (!(MCG->S & MCG_S_IRCST_MASK)) if (!(MCG->S & MCG_S_IRCST_MASK))
{ {
CLOCK_ExternalModeToFbeModeQuick(); CLOCK_ExternalModeToFbeModeQuick();
CLOCK_SetFeiMode(config->drs, (void (*)(void))0); CLOCK_SetFeiMode(config->dmx32, config->drs, (void (*)(void))0);
} }
CLOCK_SetExternalRefClkConfig(config->oscsel); CLOCK_SetExternalRefClkConfig(config->oscsel);
@ -1685,10 +1692,10 @@ status_t CLOCK_SetMcgConfig(const mcg_config_t *config)
/* Re-configure MCGIRCLK, if MCGIRCLK is used as system clock source, then change to FEI/PEI first. */ /* Re-configure MCGIRCLK, if MCGIRCLK is used as system clock source, then change to FEI/PEI first. */
if (MCG_S_CLKST_VAL == kMCG_ClkOutStatInt) if (MCG_S_CLKST_VAL == kMCG_ClkOutStatInt)
{ {
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C2, MCG_C2_LP_MASK); /* Disable lowpower. */ MCG->C2 &= ~MCG_C2_LP_MASK; /* Disable lowpower. */
{ {
CLOCK_SetFeiMode(config->drs, CLOCK_FllStableDelay); CLOCK_SetFeiMode(config->dmx32, config->drs, CLOCK_FllStableDelay);
} }
} }
@ -1704,13 +1711,13 @@ status_t CLOCK_SetMcgConfig(const mcg_config_t *config)
switch (next_mode) switch (next_mode)
{ {
case kMCG_ModeFEI: case kMCG_ModeFEI:
status = CLOCK_SetFeiMode(config->drs, CLOCK_FllStableDelay); status = CLOCK_SetFeiMode(config->dmx32, config->drs, CLOCK_FllStableDelay);
break; break;
case kMCG_ModeFEE: case kMCG_ModeFEE:
status = CLOCK_SetFeeMode(config->frdiv, config->dmx32, config->drs, CLOCK_FllStableDelay); status = CLOCK_SetFeeMode(config->frdiv, config->dmx32, config->drs, CLOCK_FllStableDelay);
break; break;
case kMCG_ModeFBI: case kMCG_ModeFBI:
status = CLOCK_SetFbiMode(config->drs, (void (*)(void))0); status = CLOCK_SetFbiMode(config->dmx32, config->drs, (void (*)(void))0);
break; break;
case kMCG_ModeFBE: case kMCG_ModeFBE:
status = CLOCK_SetFbeMode(config->frdiv, config->dmx32, config->drs, (void (*)(void))0); status = CLOCK_SetFbeMode(config->frdiv, config->dmx32, config->drs, (void (*)(void))0);
@ -1731,7 +1738,7 @@ status_t CLOCK_SetMcgConfig(const mcg_config_t *config)
} }
else else
{ {
__FSL_CLOCK_SECURE_BITS_SET_VALUE(&MCG->C1, MCG_C1_CLKS_MASK, MCG_C1_CLKS(kMCG_ClkOutSrcExternal)); MCG->C1 = ((MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcExternal));
while (MCG_S_CLKST_VAL != kMCG_ClkOutStatExt) while (MCG_S_CLKST_VAL != kMCG_ClkOutStatExt)
{ {
} }
@ -1755,7 +1762,7 @@ status_t CLOCK_SetMcgConfig(const mcg_config_t *config)
} }
else else
{ {
__FSL_CLOCK_SECURE_BITS_CLEAR(&MCG->C5, (uint32_t)kMCG_PllEnableIndependent); MCG->C5 &= ~(uint32_t)kMCG_PllEnableIndependent;
} }
return kStatus_Success; return kStatus_Success;
} }

View File

@ -45,8 +45,10 @@ static uint32_t CMP_GetInstance(CMP_Type *base);
******************************************************************************/ ******************************************************************************/
/*! @brief Pointers to CMP bases for each instance. */ /*! @brief Pointers to CMP bases for each instance. */
static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS; static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to CMP clocks for each instance. */ /*! @brief Pointers to CMP clocks for each instance. */
const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS; static const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/******************************************************************************* /*******************************************************************************
* Codes * Codes
@ -75,8 +77,10 @@ void CMP_Init(CMP_Type *base, const cmp_config_t *config)
uint8_t tmp8; uint8_t tmp8;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock. */ /* Enable the clock. */
CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]); CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure. */ /* Configure. */
CMP_Enable(base, false); /* Disable the CMP module during configuring. */ CMP_Enable(base, false); /* Disable the CMP module during configuring. */
@ -123,8 +127,10 @@ void CMP_Deinit(CMP_Type *base)
/* Disable the CMP module. */ /* Disable the CMP module. */
CMP_Enable(base, false); CMP_Enable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock. */ /* Disable the clock. */
CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]); CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void CMP_GetDefaultConfig(cmp_config_t *config) void CMP_GetDefaultConfig(cmp_config_t *config)

View File

@ -38,7 +38,6 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -64,8 +63,8 @@ enum _cmp_interrupt_enable
*/ */
enum _cmp_status_flags enum _cmp_status_flags
{ {
kCMP_OutputRisingEventFlag = CMP_SCR_CFR_MASK, /*!< Rising-edge on compare output has occurred. */ kCMP_OutputRisingEventFlag = CMP_SCR_CFR_MASK, /*!< Rising-edge on the comparison output has occurred. */
kCMP_OutputFallingEventFlag = CMP_SCR_CFF_MASK, /*!< Falling-edge on compare output has occurred. */ kCMP_OutputFallingEventFlag = CMP_SCR_CFF_MASK, /*!< Falling-edge on the comparison output has occurred. */
kCMP_OutputAssertEventFlag = CMP_SCR_COUT_MASK, /*!< Return the current value of the analog comparator output. */ kCMP_OutputAssertEventFlag = CMP_SCR_COUT_MASK, /*!< Return the current value of the analog comparator output. */
}; };
@ -85,20 +84,20 @@ typedef enum _cmp_hysteresis_mode
*/ */
typedef enum _cmp_reference_voltage_source typedef enum _cmp_reference_voltage_source
{ {
kCMP_VrefSourceVin1 = 0U, /*!< Vin1 is selected as resistor ladder network supply reference Vin. */ kCMP_VrefSourceVin1 = 0U, /*!< Vin1 is selected as a resistor ladder network supply reference Vin. */
kCMP_VrefSourceVin2 = 1U, /*!< Vin2 is selected as resistor ladder network supply reference Vin. */ kCMP_VrefSourceVin2 = 1U, /*!< Vin2 is selected as a resistor ladder network supply reference Vin. */
} cmp_reference_voltage_source_t; } cmp_reference_voltage_source_t;
/*! /*!
* @brief Configure the comparator. * @brief Configures the comparator.
*/ */
typedef struct _cmp_config typedef struct _cmp_config
{ {
bool enableCmp; /*!< Enable the CMP module. */ bool enableCmp; /*!< Enable the CMP module. */
cmp_hysteresis_mode_t hysteresisMode; /*!< CMP Hysteresis mode. */ cmp_hysteresis_mode_t hysteresisMode; /*!< CMP Hysteresis mode. */
bool enableHighSpeed; /*!< Enable High Speed (HS) comparison mode. */ bool enableHighSpeed; /*!< Enable High-speed (HS) comparison mode. */
bool enableInvertOutput; /*!< Enable inverted comparator output. */ bool enableInvertOutput; /*!< Enable the inverted comparator output. */
bool useUnfilteredOutput; /*!< Set compare output(COUT) to equal COUTA(true) or COUT(false). */ bool useUnfilteredOutput; /*!< Set the compare output(COUT) to equal COUTA(true) or COUT(false). */
bool enablePinOut; /*!< The comparator output is available on the associated pin. */ 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 #if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
bool enableTriggerMode; /*!< Enable the trigger mode. */ bool enableTriggerMode; /*!< Enable the trigger mode. */
@ -106,24 +105,24 @@ typedef struct _cmp_config
} cmp_config_t; } cmp_config_t;
/*! /*!
* @brief Configure the filter. * @brief Configures the filter.
*/ */
typedef struct _cmp_filter_config typedef struct _cmp_filter_config
{ {
#if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT #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. */ bool enableSample; /*!< Using the external SAMPLE as a sampling clock input or using a divided bus clock. */
#endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */ #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 filterCount; /*!< Filter Sample Count. Available range is 1-7; 0 disables the filter.*/
uint8_t filterPeriod; /*!< Filter Sample Period. The divider to bus clock. Available range is 0-255. */ uint8_t filterPeriod; /*!< Filter Sample Period. The divider to the bus clock. Available range is 0-255. */
} cmp_filter_config_t; } cmp_filter_config_t;
/*! /*!
* @brief Configure the internal DAC. * @brief Configures the internal DAC.
*/ */
typedef struct _cmp_dac_config typedef struct _cmp_dac_config
{ {
cmp_reference_voltage_source_t referenceVoltageSource; /*!< Supply voltage reference source. */ cmp_reference_voltage_source_t referenceVoltageSource; /*!< Supply voltage reference source. */
uint8_t DACValue; /*!< Value for DAC Output Voltage. Available range is 0-63.*/ uint8_t DACValue; /*!< Value for the DAC Output Voltage. Available range is 0-63.*/
} cmp_dac_config_t; } cmp_dac_config_t;
#if defined(__cplusplus) #if defined(__cplusplus)
@ -142,28 +141,28 @@ extern "C" {
/*! /*!
* @brief Initializes the CMP. * @brief Initializes the CMP.
* *
* This function initializes the CMP module. The operations included are: * This function initializes the CMP module. The operations included are as follows.
* - Enabling the clock for CMP module. * - Enabling the clock for CMP module.
* - Configuring the comparator. * - Configuring the comparator.
* - Enabling the CMP module. * - Enabling the CMP module.
* Note: For some devices, multiple CMP instance share the same clock gate. In this case, to enable the clock for * Note that for some devices, multiple CMP instances 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. * any instance enables all CMPs. See the appropriate MCU reference manual for the clock assignment of the CMP.
* *
* @param base CMP peripheral base address. * @param base CMP peripheral base address.
* @param config Pointer to configuration structure. * @param config Pointer to the configuration structure.
*/ */
void CMP_Init(CMP_Type *base, const cmp_config_t *config); void CMP_Init(CMP_Type *base, const cmp_config_t *config);
/*! /*!
* @brief De-initializes the CMP module. * @brief De-initializes the CMP module.
* *
* This function de-initializes the CMP module. The operations included are: * This function de-initializes the CMP module. The operations included are as follows.
* - Disabling the CMP module. * - Disabling the CMP module.
* - Disabling the clock for CMP module. * - Disabling the clock for CMP module.
* *
* This function disables the clock for the CMP. * 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 * Note that for some devices, multiple CMP instances share the same clock gate. In this case, before disabling the
* clock for the CMP, ensure that all the CMP instances are not used. * clock for the CMP, ensure that all the CMP instances are not used.
* *
* @param base CMP peripheral base address. * @param base CMP peripheral base address.
*/ */
@ -173,7 +172,7 @@ void CMP_Deinit(CMP_Type *base);
* @brief Enables/disables the CMP module. * @brief Enables/disables the CMP module.
* *
* @param base CMP peripheral base address. * @param base CMP peripheral base address.
* @param enable Enable the module or not. * @param enable Enables or disables the module.
*/ */
static inline void CMP_Enable(CMP_Type *base, bool enable) static inline void CMP_Enable(CMP_Type *base, bool enable)
{ {
@ -190,7 +189,7 @@ static inline void CMP_Enable(CMP_Type *base, bool enable)
/*! /*!
* @brief Initializes the CMP user configuration structure. * @brief Initializes the CMP user configuration structure.
* *
* This function initializes the user configure structure to these default values: * This function initializes the user configuration structure to these default values.
* @code * @code
* config->enableCmp = true; * config->enableCmp = true;
* config->hysteresisMode = kCMP_HysteresisLevel0; * config->hysteresisMode = kCMP_HysteresisLevel0;
@ -208,7 +207,7 @@ void CMP_GetDefaultConfig(cmp_config_t *config);
* @brief Sets the input channels for the comparator. * @brief Sets the input channels for the comparator.
* *
* This function 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 * Note that two input channels cannot be set the same way 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. * from the analog mux to the positive and negative port, the comparator is disabled automatically.
* *
* @param base CMP peripheral base address. * @param base CMP peripheral base address.
@ -229,13 +228,11 @@ void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negat
* @brief Enables/disables the DMA request for rising/falling events. * @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 * This function enables/disables the DMA request for rising/falling events. Either event triggers the generation of
* the DMA * the DMA request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from the CMP
* 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.
* if the
* DMA is disabled.
* *
* @param base CMP peripheral base address. * @param base CMP peripheral base address.
* @param enable Enable the feature or not. * @param enable Enables or disables the feature.
*/ */
void CMP_EnableDMA(CMP_Type *base, bool enable); void CMP_EnableDMA(CMP_Type *base, bool enable);
#endif /* FSL_FEATURE_CMP_HAS_DMA */ #endif /* FSL_FEATURE_CMP_HAS_DMA */
@ -245,7 +242,7 @@ void CMP_EnableDMA(CMP_Type *base, bool enable);
* @brief Enables/disables the window mode. * @brief Enables/disables the window mode.
* *
* @param base CMP peripheral base address. * @param base CMP peripheral base address.
* @param enable Enable the feature or not. * @param enable Enables or disables the feature.
*/ */
static inline void CMP_EnableWindowMode(CMP_Type *base, bool enable) static inline void CMP_EnableWindowMode(CMP_Type *base, bool enable)
{ {
@ -265,7 +262,7 @@ static inline void CMP_EnableWindowMode(CMP_Type *base, bool enable)
* @brief Enables/disables the pass through mode. * @brief Enables/disables the pass through mode.
* *
* @param base CMP peripheral base address. * @param base CMP peripheral base address.
* @param enable Enable the feature or not. * @param enable Enables or disables the feature.
*/ */
static inline void CMP_EnablePassThroughMode(CMP_Type *base, bool enable) static inline void CMP_EnablePassThroughMode(CMP_Type *base, bool enable)
{ {
@ -284,7 +281,7 @@ static inline void CMP_EnablePassThroughMode(CMP_Type *base, bool enable)
* @brief Configures the filter. * @brief Configures the filter.
* *
* @param base CMP peripheral base address. * @param base CMP peripheral base address.
* @param config Pointer to configuration structure. * @param config Pointer to the configuration structure.
*/ */
void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config); void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config);
@ -292,7 +289,7 @@ void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config);
* @brief Configures the internal DAC. * @brief Configures the internal DAC.
* *
* @param base CMP peripheral base address. * @param base CMP peripheral base address.
* @param config Pointer to configuration structure. "NULL" is for disabling the feature. * @param config Pointer to the configuration structure. "NULL" disables the feature.
*/ */
void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config); void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2016, Freescale Semiconductor, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -46,8 +46,6 @@
#define CMT_CMTDIV_FOUR (4) #define CMT_CMTDIV_FOUR (4)
/* CMT diver 8. */ /* CMT diver 8. */
#define CMT_CMTDIV_EIGHT (8) #define CMT_CMTDIV_EIGHT (8)
/* CMT mode bit mask. */
#define CMT_MODE_BIT_MASK (CMT_MSC_MCGEN_MASK | CMT_MSC_FSK_MASK | CMT_MSC_BASE_MASK)
/******************************************************************************* /*******************************************************************************
* Prototypes * Prototypes
@ -64,14 +62,16 @@ static uint32_t CMT_GetInstance(CMT_Type *base);
* Variables * Variables
******************************************************************************/ ******************************************************************************/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to cmt clocks for each instance. */ /*! @brief Pointers to cmt clocks for each instance. */
const clock_ip_name_t s_cmtClock[FSL_FEATURE_SOC_CMT_COUNT] = CMT_CLOCKS; static const clock_ip_name_t s_cmtClock[FSL_FEATURE_SOC_CMT_COUNT] = CMT_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*! @brief Pointers to cmt bases for each instance. */ /*! @brief Pointers to cmt bases for each instance. */
static CMT_Type *const s_cmtBases[] = CMT_BASE_PTRS; static CMT_Type *const s_cmtBases[] = CMT_BASE_PTRS;
/*! @brief Pointers to cmt IRQ number for each instance. */ /*! @brief Pointers to cmt IRQ number for each instance. */
const IRQn_Type s_cmtIrqs[] = CMT_IRQS; static const IRQn_Type s_cmtIrqs[] = CMT_IRQS;
/******************************************************************************* /*******************************************************************************
* Codes * Codes
@ -113,8 +113,10 @@ void CMT_Init(CMT_Type *base, const cmt_config_t *config, uint32_t busClock_Hz)
uint8_t divider; uint8_t divider;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate clock. */ /* Ungate clock. */
CLOCK_EnableClock(s_cmtClock[CMT_GetInstance(base)]); CLOCK_EnableClock(s_cmtClock[CMT_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Sets clock divider. The divider set in pps should be set /* Sets clock divider. The divider set in pps should be set
to make sycClock_Hz/divder = 8MHz */ to make sycClock_Hz/divder = 8MHz */
@ -144,15 +146,17 @@ void CMT_Deinit(CMT_Type *base)
CMT_DisableInterrupts(base, kCMT_EndOfCycleInterruptEnable); CMT_DisableInterrupts(base, kCMT_EndOfCycleInterruptEnable);
DisableIRQ(s_cmtIrqs[CMT_GetInstance(base)]); DisableIRQ(s_cmtIrqs[CMT_GetInstance(base)]);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate the clock. */ /* Gate the clock. */
CLOCK_DisableClock(s_cmtClock[CMT_GetInstance(base)]); CLOCK_DisableClock(s_cmtClock[CMT_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void CMT_SetMode(CMT_Type *base, cmt_mode_t mode, cmt_modulate_config_t *modulateConfig) void CMT_SetMode(CMT_Type *base, cmt_mode_t mode, cmt_modulate_config_t *modulateConfig)
{ {
uint8_t mscReg; uint8_t mscReg = base->MSC;
/* Set the mode. */ /* Judge the mode. */
if (mode != kCMT_DirectIROCtl) if (mode != kCMT_DirectIROCtl)
{ {
assert(modulateConfig); assert(modulateConfig);
@ -166,13 +170,14 @@ void CMT_SetMode(CMT_Type *base, cmt_mode_t mode, cmt_modulate_config_t *modulat
/* Set carrier modulator. */ /* Set carrier modulator. */
CMT_SetModulateMarkSpace(base, modulateConfig->markCount, modulateConfig->spaceCount); CMT_SetModulateMarkSpace(base, modulateConfig->markCount, modulateConfig->spaceCount);
mscReg &= ~ (CMT_MSC_FSK_MASK | CMT_MSC_BASE_MASK);
mscReg |= mode;
}
else
{
mscReg &= ~CMT_MSC_MCGEN_MASK;
} }
/* Set the CMT mode. */ /* Set the CMT mode. */
mscReg = base->MSC;
mscReg &= ~CMT_MODE_BIT_MASK;
mscReg |= mode;
base->MSC = mscReg; base->MSC = mscReg;
} }

View File

@ -37,7 +37,6 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -45,8 +44,8 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief CMT driver version 2.0.0. */ /*! @brief CMT driver version 2.0.1. */
#define FSL_CMT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) #define FSL_CMT_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
/*@}*/ /*@}*/
/*! /*!
@ -128,15 +127,15 @@ enum _cmt_interrupt_enable
}; };
/*! /*!
* @brief CMT carrier generator and modulator configure structure * @brief CMT carrier generator and modulator configuration structure
* *
*/ */
typedef struct _cmt_modulate_config typedef struct _cmt_modulate_config
{ {
uint8_t highCount1; /*!< The high time for carrier generator first register. */ uint8_t highCount1; /*!< The high-time for carrier generator first register. */
uint8_t lowCount1; /*!< The low time for carrier generator first register. */ uint8_t lowCount1; /*!< The low-time for carrier generator first register. */
uint8_t highCount2; /*!< The high time for carrier generator second register for FSK mode. */ uint8_t highCount2; /*!< The high-time for carrier generator second register for FSK mode. */
uint8_t lowCount2; /*!< The low time for carrier generator second register for FSK mode. */ uint8_t lowCount2; /*!< The low-time for carrier generator second register for FSK mode. */
uint16_t markCount; /*!< The mark time for the modulator gate. */ uint16_t markCount; /*!< The mark time for the modulator gate. */
uint16_t spaceCount; /*!< The space time for the modulator gate. */ uint16_t spaceCount; /*!< The space time for the modulator gate. */
} cmt_modulate_config_t; } cmt_modulate_config_t;
@ -164,10 +163,10 @@ extern "C" {
*/ */
/*! /*!
* @brief Gets the CMT default configuration structure. The purpose * @brief Gets the CMT default configuration structure. This API
* of this API is to get the default configuration structure for the CMT_Init(). * gets the default configuration structure for the CMT_Init().
* Use the initialized structure unchanged in CMT_Init(), or modify * Use the initialized structure unchanged in CMT_Init() or modify
* some fields of the structure before calling the CMT_Init(). * fields of the structure before calling the CMT_Init().
* *
* @param config The CMT configuration structure pointer. * @param config The CMT configuration structure pointer.
*/ */
@ -216,7 +215,7 @@ void CMT_SetMode(CMT_Type *base, cmt_mode_t mode, cmt_modulate_config_t *modulat
* *
* @param base CMT peripheral base address. * @param base CMT peripheral base address.
* @return The CMT mode. * @return The CMT mode.
* kCMT_DirectIROCtl Carrier modulator is disabled, the IRO signal is directly in software control. * kCMT_DirectIROCtl Carrier modulator is disabled; the IRO signal is directly in software control.
* kCMT_TimeMode Carrier modulator is enabled in time mode. * kCMT_TimeMode Carrier modulator is enabled in time mode.
* kCMT_FSKMode Carrier modulator is enabled in FSK mode. * kCMT_FSKMode Carrier modulator is enabled in FSK mode.
* kCMT_BasebandMode Carrier modulator is enabled in baseband mode. * kCMT_BasebandMode Carrier modulator is enabled in baseband mode.
@ -235,11 +234,11 @@ uint32_t CMT_GetCMTFrequency(CMT_Type *base, uint32_t busClock_Hz);
/*! /*!
* @brief Sets the primary data set for the CMT carrier generator counter. * @brief Sets the primary data set for the CMT carrier generator counter.
* *
* This function sets the high time and low time of the primary data set for the * This function sets the high-time and low-time of the primary data set for the
* CMT carrier generator counter to control the period and the duty cycle of the * CMT carrier generator counter to control the period and the duty cycle of the
* output carrier signal. * output carrier signal.
* If the CMT clock period is Tcmt, The period of the carrier generator signal equals * If the CMT clock period is Tcmt, the period of the carrier generator signal equals
* (highCount + lowCount) * Tcmt. The duty cycle equals highCount / (highCount + lowCount). * (highCount + lowCount) * Tcmt. The duty cycle equals to highCount / (highCount + lowCount).
* *
* @param base CMT peripheral base address. * @param base CMT peripheral base address.
* @param highCount The number of CMT clocks for carrier generator signal high time, * @param highCount The number of CMT clocks for carrier generator signal high time,
@ -261,10 +260,10 @@ static inline void CMT_SetCarrirGenerateCountOne(CMT_Type *base, uint32_t highCo
/*! /*!
* @brief Sets the secondary data set for the CMT carrier generator counter. * @brief Sets the secondary data set for the CMT carrier generator counter.
* *
* This function is used for FSK mode setting the high time and low time of the secondary * This function is used for FSK mode setting the high-time and low-time of the secondary
* data set CMT carrier generator counter to control the period and the duty cycle * data set CMT carrier generator counter to control the period and the duty cycle
* of the output carrier signal. * of the output carrier signal.
* If the CMT clock period is Tcmt, The period of the carrier generator signal equals * If the CMT clock period is Tcmt, the period of the carrier generator signal equals
* (highCount + lowCount) * Tcmt. The duty cycle equals highCount / (highCount + lowCount). * (highCount + lowCount) * Tcmt. The duty cycle equals highCount / (highCount + lowCount).
* *
* @param base CMT peripheral base address. * @param base CMT peripheral base address.
@ -325,7 +324,7 @@ static inline void CMT_EnableExtendedSpace(CMT_Type *base, bool enable)
} }
/*! /*!
* @brief Sets IRO - infrared output signal state. * @brief Sets the IRO (infrared output) signal state.
* *
* Changes the states of the IRO signal when the kCMT_DirectIROMode mode is set * Changes the states of the IRO signal when the kCMT_DirectIROMode mode is set
* and the IRO signal is enabled. * and the IRO signal is enabled.
@ -338,12 +337,12 @@ void CMT_SetIroState(CMT_Type *base, cmt_infrared_output_state_t state);
/*! /*!
* @brief Enables the CMT interrupt. * @brief Enables the CMT interrupt.
* *
* This function enables the CMT interrupts according to the provided maskIf enabled. * This function enables the CMT interrupts according to the provided mask if enabled.
* The CMT only has the end of the cycle interrupt - an interrupt occurs at the end * The CMT only has the end of the cycle interrupt - an interrupt occurs at the end
* of the modulator cycle. This interrupt provides a means for the user * of the modulator cycle. This interrupt provides a means for the user
* to reload the new mark/space values into the CMT modulator data registers * to reload the new mark/space values into the CMT modulator data registers
* and verify the modulator mark and space. * and verify the modulator mark and space.
* For example, to enable the end of cycle, do the following: * For example, to enable the end of cycle, do the following.
* @code * @code
* CMT_EnableInterrupts(CMT, kCMT_EndOfCycleInterruptEnable); * CMT_EnableInterrupts(CMT, kCMT_EndOfCycleInterruptEnable);
* @endcode * @endcode
@ -360,7 +359,7 @@ static inline void CMT_EnableInterrupts(CMT_Type *base, uint32_t mask)
* *
* This function disables the CMT interrupts according to the provided maskIf enabled. * This function disables the CMT interrupts according to the provided maskIf enabled.
* The CMT only has the end of the cycle interrupt. * The CMT only has the end of the cycle interrupt.
* For example, to disable the end of cycle, do the following: * For example, to disable the end of cycle, do the following.
* @code * @code
* CMT_DisableInterrupts(CMT, kCMT_EndOfCycleInterruptEnable); * CMT_DisableInterrupts(CMT, kCMT_EndOfCycleInterruptEnable);
* @endcode * @endcode

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -99,3 +99,63 @@ void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler)
__enable_irq(); __enable_irq();
} }
} }
#ifndef CPU_QN908X
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
void EnableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t index = 0;
uint32_t intNumber = (uint32_t)interrupt;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
SYSCON->STARTERSET[index] = 1u << intNumber;
EnableIRQ(interrupt); /* also enable interrupt at NVIC */
}
void DisableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t index = 0;
uint32_t intNumber = (uint32_t)interrupt;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
DisableIRQ(interrupt); /* also disable interrupt at NVIC */
SYSCON->STARTERCLR[index] = 1u << intNumber;
}
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
#else
void EnableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t index = 0;
uint32_t intNumber = (uint32_t)interrupt;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
/* SYSCON->STARTERSET[index] = 1u << intNumber; */
EnableIRQ(interrupt); /* also enable interrupt at NVIC */
}
void DisableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t index = 0;
uint32_t intNumber = (uint32_t)interrupt;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
DisableIRQ(interrupt); /* also disable interrupt at NVIC */
/* SYSCON->STARTERCLR[index] = 1u << intNumber; */
}
#endif /*CPU_QN908X */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -42,8 +42,6 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
@ -55,11 +53,12 @@
#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) #define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
/* Debug console type definition. */ /* Debug console type definition. */
#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */ #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_UART 1U /*!< Debug console base on UART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console base on LPUART. */ #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_LPSCI 3U /*!< Debug console base on LPSCI. */
#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console base on USBCDC. */ #define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console base on USBCDC. */
#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console base on USBCDC. */
/*! @brief Status group numbers. */ /*! @brief Status group numbers. */
enum _status_groups enum _status_groups
@ -86,6 +85,9 @@ enum _status_groups
kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */ kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */
kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */ kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */
kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */ kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */
kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */
kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */
kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */
kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */ kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */
kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */ kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */
kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */ kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */
@ -100,6 +102,8 @@ enum _status_groups
kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */ kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */
kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */ kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */
kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */ kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */
kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */
kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */
kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */ kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */
kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */ kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */
kStatusGroup_ApplicationRangeStart = 100, /*!< Starting number for application groups. */ kStatusGroup_ApplicationRangeStart = 100, /*!< Starting number for application groups. */
@ -126,6 +130,14 @@ typedef int32_t status_t;
*/ */
#include "fsl_clock.h" #include "fsl_clock.h"
/*
* Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral
*/
#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
(defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
#include "fsl_reset.h"
#endif
/*! @name Min/max macros */ /*! @name Min/max macros */
/* @{ */ /* @{ */
#if !defined(MIN) #if !defined(MIN)
@ -181,6 +193,11 @@ extern "C" {
*/ */
static inline void EnableIRQ(IRQn_Type interrupt) static inline void EnableIRQ(IRQn_Type interrupt)
{ {
if (NotAvail_IRQn == interrupt)
{
return;
}
#if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0) #if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0)
if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX) if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX)
#endif #endif
@ -198,6 +215,11 @@ static inline void EnableIRQ(IRQn_Type interrupt)
*/ */
static inline void DisableIRQ(IRQn_Type interrupt) static inline void DisableIRQ(IRQn_Type interrupt)
{ {
if (NotAvail_IRQn == interrupt)
{
return;
}
#if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0) #if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0)
if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX) if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX)
#endif #endif
@ -246,6 +268,38 @@ static inline void EnableGlobalIRQ(uint32_t primask)
*/ */
void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
/*!
* @brief Enable specific interrupt for wake-up from deep-sleep mode.
*
* Enable the interrupt for wake-up from deep sleep mode.
* Some interrupts are typically used in sleep mode only and will not occur during
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
* those clocks (significantly increasing power consumption in the reduced power mode),
* making these wake-ups possible.
*
* @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internally).
*
* @param interrupt The IRQ number.
*/
void EnableDeepSleepIRQ(IRQn_Type interrupt);
/*!
* @brief Disable specific interrupt for wake-up from deep-sleep mode.
*
* Disable the interrupt for wake-up from deep sleep mode.
* Some interrupts are typically used in sleep mode only and will not occur during
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
* those clocks (significantly increasing power consumption in the reduced power mode),
* making these wake-ups possible.
*
* @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internally).
*
* @param interrupt The IRQ number.
*/
void DisableDeepSleepIRQ(IRQn_Type interrupt);
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -32,6 +32,11 @@
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/*! @internal @brief Has data register with name CRC. */
#if defined(FSL_FEATURE_CRC_HAS_CRC_REG) && FSL_FEATURE_CRC_HAS_CRC_REG
#define DATA CRC
#define DATALL CRCLL
#endif
#if defined(CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT) && CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT #if defined(CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT) && CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT
/* @brief Default user configuration structure for CRC-16-CCITT */ /* @brief Default user configuration structure for CRC-16-CCITT */
@ -87,7 +92,7 @@ typedef struct _crc_module_config
* *
* @param enable True or false for the selected CRC protocol Reflect In (refin) parameter. * @param enable True or false for the selected CRC protocol Reflect In (refin) parameter.
*/ */
static inline crc_transpose_type_t crc_GetTransposeTypeFromReflectIn(bool enable) static inline crc_transpose_type_t CRC_GetTransposeTypeFromReflectIn(bool enable)
{ {
return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeBytes); return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeBytes);
} }
@ -99,7 +104,7 @@ static inline crc_transpose_type_t crc_GetTransposeTypeFromReflectIn(bool enable
* *
* @param enable True or false for the selected CRC protocol Reflect Out (refout) parameter. * @param enable True or false for the selected CRC protocol Reflect Out (refout) parameter.
*/ */
static inline crc_transpose_type_t crc_GetTransposeTypeFromReflectOut(bool enable) static inline crc_transpose_type_t CRC_GetTransposeTypeFromReflectOut(bool enable)
{ {
return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeNone); return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeNone);
} }
@ -113,7 +118,7 @@ static inline crc_transpose_type_t crc_GetTransposeTypeFromReflectOut(bool enabl
* @param base CRC peripheral address. * @param base CRC peripheral address.
* @param config Pointer to protocol configuration structure. * @param config Pointer to protocol configuration structure.
*/ */
static void crc_ConfigureAndStart(CRC_Type *base, const crc_module_config_t *config) static void CRC_ConfigureAndStart(CRC_Type *base, const crc_module_config_t *config)
{ {
uint32_t crcControl; uint32_t crcControl;
@ -148,18 +153,18 @@ static void crc_ConfigureAndStart(CRC_Type *base, const crc_module_config_t *con
* @param base CRC peripheral address. * @param base CRC peripheral address.
* @param protocolConfig Pointer to protocol configuration structure. * @param protocolConfig Pointer to protocol configuration structure.
*/ */
static void crc_SetProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig) static void CRC_SetProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig)
{ {
crc_module_config_t moduleConfig; crc_module_config_t moduleConfig;
/* convert protocol to CRC peripheral module configuration, prepare for final checksum */ /* convert protocol to CRC peripheral module configuration, prepare for final checksum */
moduleConfig.polynomial = protocolConfig->polynomial; moduleConfig.polynomial = protocolConfig->polynomial;
moduleConfig.seed = protocolConfig->seed; moduleConfig.seed = protocolConfig->seed;
moduleConfig.readTranspose = crc_GetTransposeTypeFromReflectOut(protocolConfig->reflectOut); moduleConfig.readTranspose = CRC_GetTransposeTypeFromReflectOut(protocolConfig->reflectOut);
moduleConfig.writeTranspose = crc_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn); moduleConfig.writeTranspose = CRC_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn);
moduleConfig.complementChecksum = protocolConfig->complementChecksum; moduleConfig.complementChecksum = protocolConfig->complementChecksum;
moduleConfig.crcBits = protocolConfig->crcBits; moduleConfig.crcBits = protocolConfig->crcBits;
crc_ConfigureAndStart(base, &moduleConfig); CRC_ConfigureAndStart(base, &moduleConfig);
} }
/*! /*!
@ -172,7 +177,7 @@ static void crc_SetProtocolConfig(CRC_Type *base, const crc_config_t *protocolCo
* @param base CRC peripheral address. * @param base CRC peripheral address.
* @param protocolConfig Pointer to protocol configuration structure. * @param protocolConfig Pointer to protocol configuration structure.
*/ */
static void crc_SetRawProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig) static void CRC_SetRawProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig)
{ {
crc_module_config_t moduleConfig; crc_module_config_t moduleConfig;
/* convert protocol to CRC peripheral module configuration, prepare for intermediate checksum */ /* convert protocol to CRC peripheral module configuration, prepare for intermediate checksum */
@ -180,25 +185,27 @@ static void crc_SetRawProtocolConfig(CRC_Type *base, const crc_config_t *protoco
moduleConfig.seed = protocolConfig->seed; moduleConfig.seed = protocolConfig->seed;
moduleConfig.readTranspose = moduleConfig.readTranspose =
kCrcTransposeNone; /* intermediate checksum does no transpose of data register read value */ kCrcTransposeNone; /* intermediate checksum does no transpose of data register read value */
moduleConfig.writeTranspose = crc_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn); moduleConfig.writeTranspose = CRC_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn);
moduleConfig.complementChecksum = false; /* intermediate checksum does no xor of data register read value */ moduleConfig.complementChecksum = false; /* intermediate checksum does no xor of data register read value */
moduleConfig.crcBits = protocolConfig->crcBits; moduleConfig.crcBits = protocolConfig->crcBits;
crc_ConfigureAndStart(base, &moduleConfig); CRC_ConfigureAndStart(base, &moduleConfig);
} }
void CRC_Init(CRC_Type *base, const crc_config_t *config) void CRC_Init(CRC_Type *base, const crc_config_t *config)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* ungate clock */ /* ungate clock */
CLOCK_EnableClock(kCLOCK_Crc0); CLOCK_EnableClock(kCLOCK_Crc0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* configure CRC module and write the seed */ /* configure CRC module and write the seed */
if (config->crcResult == kCrcFinalChecksum) if (config->crcResult == kCrcFinalChecksum)
{ {
crc_SetProtocolConfig(base, config); CRC_SetProtocolConfig(base, config);
} }
else else
{ {
crc_SetRawProtocolConfig(base, config); CRC_SetRawProtocolConfig(base, config);
} }
} }
@ -246,6 +253,11 @@ void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize)
} }
} }
uint32_t CRC_Get32bitResult(CRC_Type *base)
{
return base->DATA;
}
uint16_t CRC_Get16bitResult(CRC_Type *base) uint16_t CRC_Get16bitResult(CRC_Type *base)
{ {
uint32_t retval; uint32_t retval;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -34,11 +34,10 @@
#include "fsl_common.h" #include "fsl_common.h"
/*! /*!
* @addtogroup crc_driver * @addtogroup crc
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -46,16 +45,17 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief CRC driver version. Version 2.0.0. */ /*! @brief CRC driver version. Version 2.0.1.
#define FSL_CRC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) *
* Current version: 2.0.1
*
* Change log:
* - Version 2.0.1
* - move DATA and DATALL macro definition from header file to source file
*/
#define FSL_CRC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
/*@}*/ /*@}*/
/*! @internal @brief Has data register with name CRC. */
#if defined(FSL_FEATURE_CRC_HAS_CRC_REG) && FSL_FEATURE_CRC_HAS_CRC_REG
#define DATA CRC
#define DATALL CRCLL
#endif
#ifndef CRC_DRIVER_CUSTOM_DEFAULTS #ifndef CRC_DRIVER_CUSTOM_DEFAULTS
/*! @brief Default configuration structure filled by CRC_GetDefaultConfig(). Use CRC16-CCIT-FALSE as defeault. */ /*! @brief Default configuration structure filled by CRC_GetDefaultConfig(). Use CRC16-CCIT-FALSE as defeault. */
#define CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT 1 #define CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT 1
@ -108,31 +108,33 @@ extern "C" {
/*! /*!
* @brief Enables and configures the CRC peripheral module. * @brief Enables and configures the CRC peripheral module.
* *
* This functions enables the clock gate in the Kinetis SIM module for the CRC peripheral. * This function enables the clock gate in the Kinetis SIM module for the CRC peripheral.
* It also configures the CRC module and starts checksum computation by writing the seed. * It also configures the CRC module and starts a checksum computation by writing the seed.
* *
* @param base CRC peripheral address. * @param base CRC peripheral address.
* @param config CRC module configuration structure * @param config CRC module configuration structure.
*/ */
void CRC_Init(CRC_Type *base, const crc_config_t *config); void CRC_Init(CRC_Type *base, const crc_config_t *config);
/*! /*!
* @brief Disables the CRC peripheral module. * @brief Disables the CRC peripheral module.
* *
* This functions disables the clock gate in the Kinetis SIM module for the CRC peripheral. * This function disables the clock gate in the Kinetis SIM module for the CRC peripheral.
* *
* @param base CRC peripheral address. * @param base CRC peripheral address.
*/ */
static inline void CRC_Deinit(CRC_Type *base) static inline void CRC_Deinit(CRC_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* gate clock */ /* gate clock */
CLOCK_DisableClock(kCLOCK_Crc0); CLOCK_DisableClock(kCLOCK_Crc0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
/*! /*!
* @brief Loads default values to CRC protocol configuration structure. * @brief Loads default values to the CRC protocol configuration structure.
* *
* Loads default values to CRC protocol configuration structure. The default values are: * Loads default values to the CRC protocol configuration structure. The default values are as follows.
* @code * @code
* config->polynomial = 0x1021; * config->polynomial = 0x1021;
* config->seed = 0xFFFF; * config->seed = 0xFFFF;
@ -143,14 +145,14 @@ static inline void CRC_Deinit(CRC_Type *base)
* config->crcResult = kCrcFinalChecksum; * config->crcResult = kCrcFinalChecksum;
* @endcode * @endcode
* *
* @param config CRC protocol configuration structure * @param config CRC protocol configuration structure.
*/ */
void CRC_GetDefaultConfig(crc_config_t *config); void CRC_GetDefaultConfig(crc_config_t *config);
/*! /*!
* @brief Writes data to the CRC module. * @brief Writes data to the CRC module.
* *
* Writes input data buffer bytes to CRC data register. * Writes input data buffer bytes to the CRC data register.
* The configured type of transpose is applied. * The configured type of transpose is applied.
* *
* @param base CRC peripheral address. * @param base CRC peripheral address.
@ -160,27 +162,24 @@ void CRC_GetDefaultConfig(crc_config_t *config);
void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize); void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize);
/*! /*!
* @brief Reads 32-bit checksum from the CRC module. * @brief Reads the 32-bit checksum from the CRC module.
* *
* Reads CRC data register (intermediate or final checksum). * Reads the CRC data register (either an intermediate or the final checksum).
* The configured type of transpose and complement are applied. * The configured type of transpose and complement is applied.
* *
* @param base CRC peripheral address. * @param base CRC peripheral address.
* @return intermediate or final 32-bit checksum, after configured transpose and complement operations. * @return An intermediate or the final 32-bit checksum, after configured transpose and complement operations.
*/ */
static inline uint32_t CRC_Get32bitResult(CRC_Type *base) uint32_t CRC_Get32bitResult(CRC_Type *base);
{
return base->DATA;
}
/*! /*!
* @brief Reads 16-bit checksum from the CRC module. * @brief Reads a 16-bit checksum from the CRC module.
* *
* Reads CRC data register (intermediate or final checksum). * Reads the CRC data register (either an intermediate or the final checksum).
* The configured type of transpose and complement are applied. * The configured type of transpose and complement is applied.
* *
* @param base CRC peripheral address. * @param base CRC peripheral address.
* @return intermediate or final 16-bit checksum, after configured transpose and complement operations. * @return An intermediate or the final 16-bit checksum, after configured transpose and complement operations.
*/ */
uint16_t CRC_Get16bitResult(CRC_Type *base); uint16_t CRC_Get16bitResult(CRC_Type *base);

View File

@ -45,8 +45,10 @@ static uint32_t DAC_GetInstance(DAC_Type *base);
******************************************************************************/ ******************************************************************************/
/*! @brief Pointers to DAC bases for each instance. */ /*! @brief Pointers to DAC bases for each instance. */
static DAC_Type *const s_dacBases[] = DAC_BASE_PTRS; static DAC_Type *const s_dacBases[] = DAC_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to DAC clocks for each instance. */ /*! @brief Pointers to DAC clocks for each instance. */
const clock_ip_name_t s_dacClocks[] = DAC_CLOCKS; static const clock_ip_name_t s_dacClocks[] = DAC_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/******************************************************************************* /*******************************************************************************
* Codes * Codes
@ -75,8 +77,10 @@ void DAC_Init(DAC_Type *base, const dac_config_t *config)
uint8_t tmp8; uint8_t tmp8;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock. */ /* Enable the clock. */
CLOCK_EnableClock(s_dacClocks[DAC_GetInstance(base)]); CLOCK_EnableClock(s_dacClocks[DAC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure. */ /* Configure. */
/* DACx_C0. */ /* DACx_C0. */
@ -91,15 +95,18 @@ void DAC_Init(DAC_Type *base, const dac_config_t *config)
} }
base->C0 = tmp8; base->C0 = tmp8;
DAC_Enable(base, true); /* DAC_Enable(base, true); */
/* Tip: The DAC output can be enabled till then after user sets their own available data in application. */
} }
void DAC_Deinit(DAC_Type *base) void DAC_Deinit(DAC_Type *base)
{ {
DAC_Enable(base, false); DAC_Enable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock. */ /* Disable the clock. */
CLOCK_DisableClock(s_dacClocks[DAC_GetInstance(base)]); CLOCK_DisableClock(s_dacClocks[DAC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void DAC_GetDefaultConfig(dac_config_t *config) void DAC_GetDefaultConfig(dac_config_t *config)

View File

@ -38,7 +38,6 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -46,8 +45,8 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief DAC driver version 2.0.0. */ /*! @brief DAC driver version 2.0.1. */
#define FSL_DAC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) #define FSL_DAC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
/*@}*/ /*@}*/
/*! /*!
@ -104,15 +103,15 @@ typedef enum _dac_buffer_watermark
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD #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. */ kDAC_BufferWatermark1Word = 0U, /*!< 1 word away from the upper limit. */
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD */ #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD */
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_2_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_2_WORD #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS) && FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS
kDAC_BufferWatermark2Word = 1U, /*!< 2 words away from the upper limit. */ kDAC_BufferWatermark2Word = 1U, /*!< 2 words away from the upper limit. */
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_2_WORD */ #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS */
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_3_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_3_WORD #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS) && FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS
kDAC_BufferWatermark3Word = 2U, /*!< 3 words away from the upper limit. */ kDAC_BufferWatermark3Word = 2U, /*!< 3 words away from the upper limit. */
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_3_WORD */ #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS */
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_4_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_4_WORD #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS) && FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS
kDAC_BufferWatermark4Word = 3U, /*!< 4 words away from the upper limit. */ kDAC_BufferWatermark4Word = 3U, /*!< 4 words away from the upper limit. */
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_4_WORD */ #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS */
} dac_buffer_watermark_t; } dac_buffer_watermark_t;
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
@ -137,7 +136,7 @@ typedef enum _dac_buffer_work_mode
typedef struct _dac_config typedef struct _dac_config
{ {
dac_reference_voltage_source_t referenceVoltageSource; /*!< Select the DAC reference voltage source. */ dac_reference_voltage_source_t referenceVoltageSource; /*!< Select the DAC reference voltage source. */
bool enableLowPowerMode; /*!< Enable the low power mode. */ bool enableLowPowerMode; /*!< Enable the low-power mode. */
} dac_config_t; } dac_config_t;
/*! /*!
@ -150,8 +149,8 @@ typedef struct _dac_buffer_config
dac_buffer_watermark_t watermark; /*!< Select the buffer's watermark. */ dac_buffer_watermark_t watermark; /*!< Select the buffer's watermark. */
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
dac_buffer_work_mode_t workMode; /*!< Select the buffer's work mode. */ dac_buffer_work_mode_t workMode; /*!< Select the buffer's work mode. */
uint8_t upperLimit; /*!< Set the upper limit for buffer index. uint8_t upperLimit; /*!< Set the upper limit for the buffer index.
Normally, 0-15 is available for buffer with 16 item. */ Normally, 0-15 is available for a buffer with 16 items. */
} dac_buffer_config_t; } dac_buffer_config_t;
/******************************************************************************* /*******************************************************************************
@ -169,7 +168,7 @@ extern "C" {
/*! /*!
* @brief Initializes the DAC module. * @brief Initializes the DAC module.
* *
* This function initializes the DAC module, including: * This function initializes the DAC module including the following operations.
* - Enabling the clock for DAC module. * - Enabling the clock for DAC module.
* - Configuring the DAC converter with a user configuration. * - Configuring the DAC converter with a user configuration.
* - Enabling the DAC module. * - Enabling the DAC module.
@ -182,7 +181,7 @@ void DAC_Init(DAC_Type *base, const dac_config_t *config);
/*! /*!
* @brief De-initializes the DAC module. * @brief De-initializes the DAC module.
* *
* This function de-initializes the DAC module, including: * This function de-initializes the DAC module including the following operations.
* - Disabling the DAC module. * - Disabling the DAC module.
* - Disabling the clock for the DAC module. * - Disabling the clock for the DAC module.
* *
@ -193,7 +192,7 @@ void DAC_Deinit(DAC_Type *base);
/*! /*!
* @brief Initializes the DAC user configuration structure. * @brief Initializes the DAC user configuration structure.
* *
* This function initializes the user configuration structure to a default value. The default values are: * This function initializes the user configuration structure to a default value. The default values are as follows.
* @code * @code
* config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2; * config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2;
* config->enableLowPowerMode = false; * config->enableLowPowerMode = false;
@ -206,7 +205,7 @@ void DAC_GetDefaultConfig(dac_config_t *config);
* @brief Enables the DAC module. * @brief Enables the DAC module.
* *
* @param base DAC peripheral base address. * @param base DAC peripheral base address.
* @param enable Enables the feature or not. * @param enable Enables or disables the feature.
*/ */
static inline void DAC_Enable(DAC_Type *base, bool enable) static inline void DAC_Enable(DAC_Type *base, bool enable)
{ {
@ -231,7 +230,7 @@ static inline void DAC_Enable(DAC_Type *base, bool enable)
* @brief Enables the DAC buffer. * @brief Enables the DAC buffer.
* *
* @param base DAC peripheral base address. * @param base DAC peripheral base address.
* @param enable Enables the feature or not. * @param enable Enables or disables the feature.
*/ */
static inline void DAC_EnableBuffer(DAC_Type *base, bool enable) static inline void DAC_EnableBuffer(DAC_Type *base, bool enable)
{ {
@ -256,7 +255,7 @@ void DAC_SetBufferConfig(DAC_Type *base, const dac_buffer_config_t *config);
/*! /*!
* @brief Initializes the DAC buffer configuration structure. * @brief Initializes the DAC buffer configuration structure.
* *
* This function initializes the DAC buffer configuration structure to a default value. The default values are: * This function initializes the DAC buffer configuration structure to default values. The default values are as follows.
* @code * @code
* config->triggerMode = kDAC_BufferTriggerBySoftwareMode; * config->triggerMode = kDAC_BufferTriggerBySoftwareMode;
* config->watermark = kDAC_BufferWatermark1Word; * config->watermark = kDAC_BufferWatermark1Word;
@ -271,7 +270,7 @@ void DAC_GetDefaultBufferConfig(dac_buffer_config_t *config);
* @brief Enables the DMA for DAC buffer. * @brief Enables the DMA for DAC buffer.
* *
* @param base DAC peripheral base address. * @param base DAC peripheral base address.
* @param enable Enables the feature or not. * @param enable Enables or disables the feature.
*/ */
static inline void DAC_EnableBufferDMA(DAC_Type *base, bool enable) static inline void DAC_EnableBufferDMA(DAC_Type *base, bool enable)
{ {
@ -289,15 +288,15 @@ static inline void DAC_EnableBufferDMA(DAC_Type *base, bool enable)
* @brief Sets the value for items in the buffer. * @brief Sets the value for items in the buffer.
* *
* @param base DAC peripheral base address. * @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 index Setting the 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. * @param value Setting the value for items in the buffer. 12-bits are available.
*/ */
void DAC_SetBufferValue(DAC_Type *base, uint8_t index, uint16_t value); 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. * @brief Triggers the buffer using 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 * This function triggers the function using 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. * after this function is called. Changing the read pointer depends on the buffer's work mode.
* *
* @param base DAC peripheral base address. * @param base DAC peripheral base address.
@ -311,12 +310,12 @@ static inline void DAC_DoSoftwareTriggerBuffer(DAC_Type *base)
* @brief Gets the current read pointer of the DAC buffer. * @brief Gets the current read pointer of the DAC buffer.
* *
* This function 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 * The current output value depends on the item indexed by the read pointer. It is updated either
* by software trigger or hardware trigger. * by a software trigger or a hardware trigger.
* *
* @param base DAC peripheral base address. * @param base DAC peripheral base address.
* *
* @return Current read pointer of DAC buffer. * @return The current read pointer of the DAC buffer.
*/ */
static inline uint8_t DAC_GetBufferReadPointer(DAC_Type *base) static inline uint8_t DAC_GetBufferReadPointer(DAC_Type *base)
{ {
@ -327,11 +326,11 @@ static inline uint8_t DAC_GetBufferReadPointer(DAC_Type *base)
* @brief Sets the current read pointer of the DAC buffer. * @brief Sets the current read pointer of the DAC buffer.
* *
* This function 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 * The current output value depends on the item indexed by the read pointer. It is updated either by a
* software trigger or hardware trigger. After the read pointer changes, the DAC output value also changes. * software trigger or a hardware trigger. After the read pointer changes, the DAC output value also changes.
* *
* @param base DAC peripheral base address. * @param base DAC peripheral base address.
* @param index Setting index value for the pointer. * @param index Setting an index value for the pointer.
*/ */
void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index); void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index);

View File

@ -52,8 +52,10 @@ static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base);
/*! @brief Array to map DMAMUX instance number to base pointer. */ /*! @brief Array to map DMAMUX instance number to base pointer. */
static DMAMUX_Type *const s_dmamuxBases[] = DMAMUX_BASE_PTRS; static DMAMUX_Type *const s_dmamuxBases[] = DMAMUX_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Array to map DMAMUX instance number to clock name. */ /*! @brief Array to map DMAMUX instance number to clock name. */
static const clock_ip_name_t s_dmamuxClockName[] = DMAMUX_CLOCKS; static const clock_ip_name_t s_dmamuxClockName[] = DMAMUX_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/******************************************************************************* /*******************************************************************************
* Code * Code
@ -78,10 +80,14 @@ static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base)
void DMAMUX_Init(DMAMUX_Type *base) void DMAMUX_Init(DMAMUX_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); CLOCK_EnableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void DMAMUX_Deinit(DMAMUX_Type *base) void DMAMUX_Deinit(DMAMUX_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_DisableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); CLOCK_DisableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }

View File

@ -38,7 +38,6 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -46,8 +45,8 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief DMAMUX driver version 2.0.0. */ /*! @brief DMAMUX driver version 2.0.2. */
#define FSL_DMAMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) #define FSL_DMAMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
/*@}*/ /*@}*/
/******************************************************************************* /*******************************************************************************
@ -59,14 +58,14 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/*! /*!
* @name DMAMUX Initialize and De-initialize * @name DMAMUX Initialization and de-initialization
* @{ * @{
*/ */
/*! /*!
* @brief Initializes DMAMUX peripheral. * @brief Initializes the DMAMUX peripheral.
* *
* This function ungate the DMAMUX clock. * This function ungates the DMAMUX clock.
* *
* @param base DMAMUX peripheral base address. * @param base DMAMUX peripheral base address.
* *
@ -74,9 +73,9 @@ extern "C" {
void DMAMUX_Init(DMAMUX_Type *base); void DMAMUX_Init(DMAMUX_Type *base);
/*! /*!
* @brief Deinitializes DMAMUX peripheral. * @brief Deinitializes the DMAMUX peripheral.
* *
* This function gate the DMAMUX clock. * This function gates the DMAMUX clock.
* *
* @param base DMAMUX peripheral base address. * @param base DMAMUX peripheral base address.
*/ */
@ -89,9 +88,9 @@ void DMAMUX_Deinit(DMAMUX_Type *base);
*/ */
/*! /*!
* @brief Enable DMAMUX channel. * @brief Enables the DMAMUX channel.
* *
* This function enable DMAMUX channel to work. * This function enables the DMAMUX channel.
* *
* @param base DMAMUX peripheral base address. * @param base DMAMUX peripheral base address.
* @param channel DMAMUX channel number. * @param channel DMAMUX channel number.
@ -104,11 +103,11 @@ static inline void DMAMUX_EnableChannel(DMAMUX_Type *base, uint32_t channel)
} }
/*! /*!
* @brief Disable DMAMUX channel. * @brief Disables the DMAMUX channel.
* *
* This function disable DMAMUX channel. * This function disables the DMAMUX channel.
* *
* @note User must disable DMAMUX channel before configure it. * @note The user must disable the DMAMUX channel before configuring it.
* @param base DMAMUX peripheral base address. * @param base DMAMUX peripheral base address.
* @param channel DMAMUX channel number. * @param channel DMAMUX channel number.
*/ */
@ -120,13 +119,13 @@ static inline void DMAMUX_DisableChannel(DMAMUX_Type *base, uint32_t channel)
} }
/*! /*!
* @brief Configure DMAMUX channel source. * @brief Configures the DMAMUX channel source.
* *
* @param base DMAMUX peripheral base address. * @param base DMAMUX peripheral base address.
* @param channel DMAMUX channel number. * @param channel DMAMUX channel number.
* @param source Channel source which is used to trigger DMA transfer. * @param source Channel source, which is used to trigger the DMA transfer.
*/ */
static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint8_t source) static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint32_t source)
{ {
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
@ -135,9 +134,9 @@ static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint8_t
#if defined(FSL_FEATURE_DMAMUX_HAS_TRIG) && FSL_FEATURE_DMAMUX_HAS_TRIG > 0U #if defined(FSL_FEATURE_DMAMUX_HAS_TRIG) && FSL_FEATURE_DMAMUX_HAS_TRIG > 0U
/*! /*!
* @brief Enable DMAMUX period trigger. * @brief Enables the DMAMUX period trigger.
* *
* This function enable DMAMUX period trigger feature. * This function enables the DMAMUX period trigger feature.
* *
* @param base DMAMUX peripheral base address. * @param base DMAMUX peripheral base address.
* @param channel DMAMUX channel number. * @param channel DMAMUX channel number.
@ -150,9 +149,9 @@ static inline void DMAMUX_EnablePeriodTrigger(DMAMUX_Type *base, uint32_t channe
} }
/*! /*!
* @brief Disable DMAMUX period trigger. * @brief Disables the DMAMUX period trigger.
* *
* This function disable DMAMUX period trigger. * This function disables the DMAMUX period trigger.
* *
* @param base DMAMUX peripheral base address. * @param base DMAMUX peripheral base address.
* @param channel DMAMUX channel number. * @param channel DMAMUX channel number.
@ -165,6 +164,31 @@ static inline void DMAMUX_DisablePeriodTrigger(DMAMUX_Type *base, uint32_t chann
} }
#endif /* FSL_FEATURE_DMAMUX_HAS_TRIG */ #endif /* FSL_FEATURE_DMAMUX_HAS_TRIG */
#if (defined(FSL_FEATURE_DMAMUX_HAS_A_ON) && FSL_FEATURE_DMAMUX_HAS_A_ON)
/*!
* @brief Enables the DMA channel to be always ON.
*
* This function enables the DMAMUX channel always ON feature.
*
* @param base DMAMUX peripheral base address.
* @param channel DMAMUX channel number.
* @param enable Switcher of the always ON feature. "true" means enabled, "false" means disabled.
*/
static inline void DMAMUX_EnableAlwaysOn(DMAMUX_Type *base, uint32_t channel, bool enable)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
if (enable)
{
base->CHCFG[channel] |= DMAMUX_CHCFG_A_ON_MASK;
}
else
{
base->CHCFG[channel] &= ~DMAMUX_CHCFG_A_ON_MASK;
}
}
#endif /* FSL_FEATURE_DMAMUX_HAS_A_ON */
/* @} */ /* @} */
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -123,8 +123,10 @@ static SPI_Type *const s_dspiBases[] = SPI_BASE_PTRS;
/*! @brief Pointers to dspi IRQ number for each instance. */ /*! @brief Pointers to dspi IRQ number for each instance. */
static IRQn_Type const s_dspiIRQ[] = SPI_IRQS; static IRQn_Type const s_dspiIRQ[] = SPI_IRQS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to dspi clocks for each instance. */ /*! @brief Pointers to dspi clocks for each instance. */
static clock_ip_name_t const s_dspiClock[] = DSPI_CLOCKS; static clock_ip_name_t const s_dspiClock[] = DSPI_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*! @brief Pointers to dspi handles for each instance. */ /*! @brief Pointers to dspi handles for each instance. */
static void *g_dspiHandle[FSL_FEATURE_SOC_DSPI_COUNT]; static void *g_dspiHandle[FSL_FEATURE_SOC_DSPI_COUNT];
@ -158,9 +160,13 @@ uint32_t DSPI_GetInstance(SPI_Type *base)
void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz) void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz)
{ {
assert(masterConfig);
uint32_t temp; uint32_t temp;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* enable DSPI clock */ /* enable DSPI clock */
CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]); CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
DSPI_Enable(base, true); DSPI_Enable(base, true);
DSPI_StopTransfer(base); DSPI_StopTransfer(base);
@ -201,6 +207,8 @@ void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, u
void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig) void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig)
{ {
assert(masterConfig);
masterConfig->whichCtar = kDSPI_Ctar0; masterConfig->whichCtar = kDSPI_Ctar0;
masterConfig->ctarConfig.baudRate = 500000; masterConfig->ctarConfig.baudRate = 500000;
masterConfig->ctarConfig.bitsPerFrame = 8; masterConfig->ctarConfig.bitsPerFrame = 8;
@ -223,10 +231,14 @@ void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig)
void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig) void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig)
{ {
assert(slaveConfig);
uint32_t temp = 0; uint32_t temp = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* enable DSPI clock */ /* enable DSPI clock */
CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]); CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
DSPI_Enable(base, true); DSPI_Enable(base, true);
DSPI_StopTransfer(base); DSPI_StopTransfer(base);
@ -255,6 +267,8 @@ void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig)
void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig) void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig)
{ {
assert(slaveConfig);
slaveConfig->whichCtar = kDSPI_Ctar0; slaveConfig->whichCtar = kDSPI_Ctar0;
slaveConfig->ctarConfig.bitsPerFrame = 8; slaveConfig->ctarConfig.bitsPerFrame = 8;
slaveConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh; slaveConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh;
@ -271,8 +285,10 @@ void DSPI_Deinit(SPI_Type *base)
DSPI_StopTransfer(base); DSPI_StopTransfer(base);
DSPI_Enable(base, false); DSPI_Enable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* disable DSPI clock */ /* disable DSPI clock */
CLOCK_DisableClock(s_dspiClock[DSPI_GetInstance(base)]); CLOCK_DisableClock(s_dspiClock[DSPI_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
static void DSPI_SetOnePcsPolarity(SPI_Type *base, dspi_which_pcs_t pcs, dspi_pcs_polarity_config_t activeLowOrHigh) static void DSPI_SetOnePcsPolarity(SPI_Type *base, dspi_which_pcs_t pcs, dspi_pcs_polarity_config_t activeLowOrHigh)
@ -457,6 +473,8 @@ uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base,
void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command) void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command)
{ {
assert(command);
command->isPcsContinuous = false; command->isPcsContinuous = false;
command->whichCtar = kDSPI_Ctar0; command->whichCtar = kDSPI_Ctar0;
command->whichPcs = kDSPI_Pcs0; command->whichPcs = kDSPI_Pcs0;
@ -466,6 +484,8 @@ void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command)
void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data) void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data)
{ {
assert(command);
/* First, clear Transmit Complete Flag (TCF) */ /* First, clear Transmit Complete Flag (TCF) */
DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag); DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag);
@ -562,7 +582,7 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
uint16_t wordToSend = 0; uint16_t wordToSend = 0;
uint16_t wordReceived = 0; uint16_t wordReceived = 0;
uint8_t dummyData = DSPI_MASTER_DUMMY_DATA; uint8_t dummyData = DSPI_DUMMY_DATA;
uint8_t bitsPerFrame; uint8_t bitsPerFrame;
uint32_t command; uint32_t command;
@ -598,6 +618,7 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
command = DSPI_MasterGetFormattedCommand(&(commandStruct)); command = DSPI_MasterGetFormattedCommand(&(commandStruct));
commandStruct.isEndOfQueue = true;
commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer); commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer);
lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct)); lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));
@ -626,25 +647,6 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
{ {
if (remainingSendByteCount == 1) if (remainingSendByteCount == 1)
{ {
while ((remainingReceiveByteCount - remainingSendByteCount) >= fifoSize)
{
if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
{
if (rxData != NULL)
{
*(rxData) = DSPI_ReadData(base);
rxData++;
}
else
{
DSPI_ReadData(base);
}
remainingReceiveByteCount--;
DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
}
}
while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)) while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
{ {
DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
@ -702,20 +704,23 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) while ((remainingReceiveByteCount - remainingSendByteCount) >= fifoSize)
{ {
if (rxData != NULL) if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
{ {
*(rxData) = DSPI_ReadData(base); if (rxData != NULL)
rxData++; {
} *(rxData) = DSPI_ReadData(base);
else rxData++;
{ }
DSPI_ReadData(base); else
} {
remainingReceiveByteCount--; DSPI_ReadData(base);
}
remainingReceiveByteCount--;
DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
}
} }
} }
} }
@ -726,25 +731,6 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
{ {
if (remainingSendByteCount <= 2) if (remainingSendByteCount <= 2)
{ {
while (((remainingReceiveByteCount - remainingSendByteCount) / 2) >= fifoSize)
{
if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
{
wordReceived = DSPI_ReadData(base);
if (rxData != NULL)
{
*rxData = wordReceived;
++rxData;
*rxData = wordReceived >> 8;
++rxData;
}
remainingReceiveByteCount -= 2;
DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
}
}
while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)) while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
{ {
DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
@ -825,20 +811,23 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) while (((remainingReceiveByteCount - remainingSendByteCount) / 2) >= fifoSize)
{ {
wordReceived = DSPI_ReadData(base); if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
if (rxData != NULL)
{ {
*rxData = wordReceived; wordReceived = DSPI_ReadData(base);
++rxData;
*rxData = wordReceived >> 8;
++rxData;
}
remainingReceiveByteCount -= 2;
DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); if (rxData != NULL)
{
*rxData = wordReceived;
++rxData;
*rxData = wordReceived >> 8;
++rxData;
}
remainingReceiveByteCount -= 2;
DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
}
} }
} }
} }
@ -849,6 +838,9 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer) static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer)
{ {
assert(handle);
assert(transfer);
dspi_command_data_config_t commandStruct; dspi_command_data_config_t commandStruct;
DSPI_StopTransfer(base); DSPI_StopTransfer(base);
@ -864,6 +856,7 @@ static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *han
commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous); commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous);
handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct)); handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct));
commandStruct.isEndOfQueue = true;
commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer); commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer);
handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct)); handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));
@ -886,7 +879,8 @@ static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *han
status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer) status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer)
{ {
assert(handle && transfer); assert(handle);
assert(transfer);
/* If the transfer count is zero, then return immediately.*/ /* If the transfer count is zero, then return immediately.*/
if (transfer->dataSize == 0) if (transfer->dataSize == 0)
@ -943,6 +937,8 @@ status_t DSPI_MasterTransferGetCount(SPI_Type *base, dspi_master_handle_t *handl
static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *handle) static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *handle)
{ {
assert(handle);
/* Disable interrupt requests*/ /* Disable interrupt requests*/
DSPI_DisableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable); DSPI_DisableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable);
@ -967,8 +963,10 @@ static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *ha
static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t *handle) static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t *handle)
{ {
assert(handle);
uint16_t wordToSend = 0; uint16_t wordToSend = 0;
uint8_t dummyData = DSPI_MASTER_DUMMY_DATA; uint8_t dummyData = DSPI_DUMMY_DATA;
/* If bits/frame is greater than one byte */ /* If bits/frame is greater than one byte */
if (handle->bitsPerFrame > 8) if (handle->bitsPerFrame > 8)
@ -1081,6 +1079,8 @@ static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t
void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle) void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle)
{ {
assert(handle);
DSPI_StopTransfer(base); DSPI_StopTransfer(base);
/* Disable interrupt requests*/ /* Disable interrupt requests*/
@ -1091,6 +1091,8 @@ void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle)
void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle) void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle)
{ {
assert(handle);
/* RECEIVE IRQ handler: Check read buffer only if there are remaining bytes to read. */ /* RECEIVE IRQ handler: Check read buffer only if there are remaining bytes to read. */
if (handle->remainingReceiveByteCount) if (handle->remainingReceiveByteCount)
{ {
@ -1212,7 +1214,8 @@ void DSPI_SlaveTransferCreateHandle(SPI_Type *base,
status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer) status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer)
{ {
assert(handle && transfer); assert(handle);
assert(transfer);
/* If receive length is zero */ /* If receive length is zero */
if (transfer->dataSize == 0) if (transfer->dataSize == 0)
@ -1300,8 +1303,10 @@ status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle,
static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *handle) static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *handle)
{ {
assert(handle);
uint16_t transmitData = 0; uint16_t transmitData = 0;
uint8_t dummyPattern = DSPI_SLAVE_DUMMY_DATA; uint8_t dummyPattern = DSPI_DUMMY_DATA;
/* Service the transmitter, if transmit buffer provided, transmit the data, /* Service the transmitter, if transmit buffer provided, transmit the data,
* else transmit dummy pattern * else transmit dummy pattern
@ -1386,6 +1391,8 @@ static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *
static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *handle) static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *handle)
{ {
assert(handle);
/* Disable interrupt requests */ /* Disable interrupt requests */
DSPI_DisableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable | DSPI_DisableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable |
kDSPI_RxFifoOverflowInterruptEnable | kDSPI_RxFifoDrainRequestInterruptEnable); kDSPI_RxFifoOverflowInterruptEnable | kDSPI_RxFifoDrainRequestInterruptEnable);
@ -1416,6 +1423,8 @@ static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *hand
void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle) void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle)
{ {
assert(handle);
DSPI_StopTransfer(base); DSPI_StopTransfer(base);
/* Disable interrupt requests */ /* Disable interrupt requests */
@ -1429,7 +1438,9 @@ void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle)
void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle) void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle)
{ {
uint8_t dummyPattern = DSPI_SLAVE_DUMMY_DATA; assert(handle);
uint8_t dummyPattern = DSPI_DUMMY_DATA;
uint32_t dataReceived; uint32_t dataReceived;
uint32_t dataSend = 0; uint32_t dataSend = 0;
@ -1606,7 +1617,7 @@ static void DSPI_CommonIRQHandler(SPI_Type *base, void *param)
} }
} }
#if defined(SPI0) #if (FSL_FEATURE_SOC_DSPI_COUNT > 0)
void SPI0_DriverIRQHandler(void) void SPI0_DriverIRQHandler(void)
{ {
assert(g_dspiHandle[0]); assert(g_dspiHandle[0]);
@ -1614,7 +1625,7 @@ void SPI0_DriverIRQHandler(void)
} }
#endif #endif
#if defined(SPI1) #if (FSL_FEATURE_SOC_DSPI_COUNT > 1)
void SPI1_DriverIRQHandler(void) void SPI1_DriverIRQHandler(void)
{ {
assert(g_dspiHandle[1]); assert(g_dspiHandle[1]);
@ -1622,7 +1633,7 @@ void SPI1_DriverIRQHandler(void)
} }
#endif #endif
#if defined(SPI2) #if (FSL_FEATURE_SOC_DSPI_COUNT > 2)
void SPI2_DriverIRQHandler(void) void SPI2_DriverIRQHandler(void)
{ {
assert(g_dspiHandle[2]); assert(g_dspiHandle[2]);
@ -1630,7 +1641,7 @@ void SPI2_DriverIRQHandler(void)
} }
#endif #endif
#if defined(SPI3) #if (FSL_FEATURE_SOC_DSPI_COUNT > 3)
void SPI3_DriverIRQHandler(void) void SPI3_DriverIRQHandler(void)
{ {
assert(g_dspiHandle[3]); assert(g_dspiHandle[3]);
@ -1638,7 +1649,7 @@ void SPI3_DriverIRQHandler(void)
} }
#endif #endif
#if defined(SPI4) #if (FSL_FEATURE_SOC_DSPI_COUNT > 4)
void SPI4_DriverIRQHandler(void) void SPI4_DriverIRQHandler(void)
{ {
assert(g_dspiHandle[4]); assert(g_dspiHandle[4]);
@ -1646,7 +1657,7 @@ void SPI4_DriverIRQHandler(void)
} }
#endif #endif
#if defined(SPI5) #if (FSL_FEATURE_SOC_DSPI_COUNT > 5)
void SPI5_DriverIRQHandler(void) void SPI5_DriverIRQHandler(void)
{ {
assert(g_dspiHandle[5]); assert(g_dspiHandle[5]);

View File

@ -33,11 +33,10 @@
#include "fsl_common.h" #include "fsl_common.h"
/*! /*!
* @addtogroup dspi * @addtogroup dspi_driver
* @{ * @{
*/ */
/*! @file */
/********************************************************************************************************************** /**********************************************************************************************************************
* Definitions * Definitions
@ -45,15 +44,14 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief DSPI driver version 2.1.0. */ /*! @brief DSPI driver version 2.1.3. */
#define FSL_DSPI_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) #define FSL_DSPI_DRIVER_VERSION (MAKE_VERSION(2, 1, 3))
/*@}*/ /*@}*/
/*! @name Dummy data */ #ifndef DSPI_DUMMY_DATA
/*@{*/ /*! @brief DSPI dummy data if there is no Tx data.*/
#define DSPI_MASTER_DUMMY_DATA (0x00U) /*!< Master dummy data used for tx if there is not txData. */ #define DSPI_DUMMY_DATA (0x00U) /*!< Dummy data used for Tx if there is no txData. */
#define DSPI_SLAVE_DUMMY_DATA (0x00U) /*!< Slave dummy data used for tx if there is not txData. */ #endif
/*@}*/
/*! @brief Status for the DSPI driver.*/ /*! @brief Status for the DSPI driver.*/
enum _dspi_status enum _dspi_status
@ -61,7 +59,7 @@ enum _dspi_status
kStatus_DSPI_Busy = MAKE_STATUS(kStatusGroup_DSPI, 0), /*!< DSPI transfer is busy.*/ kStatus_DSPI_Busy = MAKE_STATUS(kStatusGroup_DSPI, 0), /*!< DSPI transfer is busy.*/
kStatus_DSPI_Error = MAKE_STATUS(kStatusGroup_DSPI, 1), /*!< DSPI driver error. */ kStatus_DSPI_Error = MAKE_STATUS(kStatusGroup_DSPI, 1), /*!< DSPI driver error. */
kStatus_DSPI_Idle = MAKE_STATUS(kStatusGroup_DSPI, 2), /*!< DSPI is idle.*/ kStatus_DSPI_Idle = MAKE_STATUS(kStatusGroup_DSPI, 2), /*!< DSPI is idle.*/
kStatus_DSPI_OutOfRange = MAKE_STATUS(kStatusGroup_DSPI, 3) /*!< DSPI transfer out Of range. */ kStatus_DSPI_OutOfRange = MAKE_STATUS(kStatusGroup_DSPI, 3) /*!< DSPI transfer out of range. */
}; };
/*! @brief DSPI status flags in SPIx_SR register.*/ /*! @brief DSPI status flags in SPIx_SR register.*/
@ -75,7 +73,7 @@ enum _dspi_flags
kDSPI_RxFifoDrainRequestFlag = SPI_SR_RFDF_MASK, /*!< Receive FIFO Drain Flag.*/ kDSPI_RxFifoDrainRequestFlag = SPI_SR_RFDF_MASK, /*!< Receive FIFO Drain Flag.*/
kDSPI_TxAndRxStatusFlag = SPI_SR_TXRXS_MASK, /*!< The module is in Stopped/Running state.*/ kDSPI_TxAndRxStatusFlag = SPI_SR_TXRXS_MASK, /*!< The module is in Stopped/Running state.*/
kDSPI_AllStatusFlag = SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | kDSPI_AllStatusFlag = SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK |
SPI_SR_RFDF_MASK | SPI_SR_TXRXS_MASK /*!< All status above.*/ SPI_SR_RFDF_MASK | SPI_SR_TXRXS_MASK /*!< All statuses above.*/
}; };
/*! @brief DSPI interrupt source.*/ /*! @brief DSPI interrupt source.*/
@ -109,8 +107,8 @@ typedef enum _dspi_master_slave_mode
} dspi_master_slave_mode_t; } dspi_master_slave_mode_t;
/*! /*!
* @brief DSPI Sample Point: Controls when the DSPI master samples SIN in Modified Transfer Format. This field is valid * @brief DSPI Sample Point: Controls when the DSPI master samples SIN in the Modified Transfer Format. This field is valid
* only when CPHA bit in CTAR register is 0. * only when the CPHA bit in the CTAR register is 0.
*/ */
typedef enum _dspi_master_sample_point typedef enum _dspi_master_sample_point
{ {
@ -169,36 +167,37 @@ typedef enum _dspi_clock_phase
typedef enum _dspi_shift_direction typedef enum _dspi_shift_direction
{ {
kDSPI_MsbFirst = 0U, /*!< Data transfers start with most significant bit.*/ kDSPI_MsbFirst = 0U, /*!< Data transfers start with most significant bit.*/
kDSPI_LsbFirst = 1U /*!< Data transfers start with least significant bit.*/ kDSPI_LsbFirst = 1U /*!< Data transfers start with least significant bit.
Shifting out of LSB is not supported for slave */
} dspi_shift_direction_t; } dspi_shift_direction_t;
/*! @brief DSPI delay type selection.*/ /*! @brief DSPI delay type selection.*/
typedef enum _dspi_delay_type typedef enum _dspi_delay_type
{ {
kDSPI_PcsToSck = 1U, /*!< Pcs-to-SCK delay. */ kDSPI_PcsToSck = 1U, /*!< Pcs-to-SCK delay. */
kDSPI_LastSckToPcs, /*!< Last SCK edge to Pcs delay. */ kDSPI_LastSckToPcs, /*!< The last SCK edge to Pcs delay. */
kDSPI_BetweenTransfer /*!< Delay between transfers. */ kDSPI_BetweenTransfer /*!< Delay between transfers. */
} dspi_delay_type_t; } dspi_delay_type_t;
/*! @brief DSPI Clock and Transfer Attributes Register (CTAR) selection.*/ /*! @brief DSPI Clock and Transfer Attributes Register (CTAR) selection.*/
typedef enum _dspi_ctar_selection typedef enum _dspi_ctar_selection
{ {
kDSPI_Ctar0 = 0U, /*!< CTAR0 selection option for master or slave mode, note that CTAR0 and CTAR0_SLAVE are the kDSPI_Ctar0 = 0U, /*!< CTAR0 selection option for master or slave mode; note that CTAR0 and CTAR0_SLAVE are the
same register address. */ same register address. */
kDSPI_Ctar1 = 1U, /*!< CTAR1 selection option for master mode only. */ kDSPI_Ctar1 = 1U, /*!< CTAR1 selection option for master mode only. */
kDSPI_Ctar2 = 2U, /*!< CTAR2 selection option for master mode only , note that some device do not support CTAR2. */ kDSPI_Ctar2 = 2U, /*!< CTAR2 selection option for master mode only; note that some devices do not support CTAR2. */
kDSPI_Ctar3 = 3U, /*!< CTAR3 selection option for master mode only , note that some device do not support CTAR3. */ kDSPI_Ctar3 = 3U, /*!< CTAR3 selection option for master mode only; note that some devices do not support CTAR3. */
kDSPI_Ctar4 = 4U, /*!< CTAR4 selection option for master mode only , note that some device do not support CTAR4. */ kDSPI_Ctar4 = 4U, /*!< CTAR4 selection option for master mode only; note that some devices do not support CTAR4. */
kDSPI_Ctar5 = 5U, /*!< CTAR5 selection option for master mode only , note that some device do not support CTAR5. */ kDSPI_Ctar5 = 5U, /*!< CTAR5 selection option for master mode only; note that some devices do not support CTAR5. */
kDSPI_Ctar6 = 6U, /*!< CTAR6 selection option for master mode only , note that some device do not support CTAR6. */ kDSPI_Ctar6 = 6U, /*!< CTAR6 selection option for master mode only; note that some devices do not support CTAR6. */
kDSPI_Ctar7 = 7U /*!< CTAR7 selection option for master mode only , note that some device do not support CTAR7. */ kDSPI_Ctar7 = 7U /*!< CTAR7 selection option for master mode only; note that some devices do not support CTAR7. */
} dspi_ctar_selection_t; } dspi_ctar_selection_t;
#define DSPI_MASTER_CTAR_SHIFT (0U) /*!< DSPI master CTAR shift macro , internal used. */ #define DSPI_MASTER_CTAR_SHIFT (0U) /*!< DSPI master CTAR shift macro; used internally. */
#define DSPI_MASTER_CTAR_MASK (0x0FU) /*!< DSPI master CTAR mask macro , internal used. */ #define DSPI_MASTER_CTAR_MASK (0x0FU) /*!< DSPI master CTAR mask macro; used internally. */
#define DSPI_MASTER_PCS_SHIFT (4U) /*!< DSPI master PCS shift macro , internal used. */ #define DSPI_MASTER_PCS_SHIFT (4U) /*!< DSPI master PCS shift macro; used internally. */
#define DSPI_MASTER_PCS_MASK (0xF0U) /*!< DSPI master PCS mask macro , internal used. */ #define DSPI_MASTER_PCS_MASK (0xF0U) /*!< DSPI master PCS mask macro; used internally. */
/*! @brief Can use this enumeration for DSPI master transfer configFlags. */ /*! @brief Use this enumeration for the DSPI master transfer configFlags. */
enum _dspi_transfer_config_flag_for_master enum _dspi_transfer_config_flag_for_master
{ {
kDSPI_MasterCtar0 = 0U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR0 setting. */ kDSPI_MasterCtar0 = 0U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR0 setting. */
@ -217,20 +216,20 @@ enum _dspi_transfer_config_flag_for_master
kDSPI_MasterPcs4 = 4U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS4 signal. */ kDSPI_MasterPcs4 = 4U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS4 signal. */
kDSPI_MasterPcs5 = 5U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS5 signal. */ kDSPI_MasterPcs5 = 5U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS5 signal. */
kDSPI_MasterPcsContinuous = 1U << 20, /*!< Is PCS signal continuous. */ kDSPI_MasterPcsContinuous = 1U << 20, /*!< Indicates whether the PCS signal is continuous. */
kDSPI_MasterActiveAfterTransfer = 1U << 21, /*!< Is PCS signal active after last frame transfer.*/ kDSPI_MasterActiveAfterTransfer = 1U << 21, /*!< Indicates whether the PCS signal is active after the last frame transfer.*/
}; };
#define DSPI_SLAVE_CTAR_SHIFT (0U) /*!< DSPI slave CTAR shift macro , internal used. */ #define DSPI_SLAVE_CTAR_SHIFT (0U) /*!< DSPI slave CTAR shift macro; used internally. */
#define DSPI_SLAVE_CTAR_MASK (0x07U) /*!< DSPI slave CTAR mask macro , internal used. */ #define DSPI_SLAVE_CTAR_MASK (0x07U) /*!< DSPI slave CTAR mask macro; used internally. */
/*! @brief Can use this enum for DSPI slave transfer configFlags. */ /*! @brief Use this enumeration for the DSPI slave transfer configFlags. */
enum _dspi_transfer_config_flag_for_slave enum _dspi_transfer_config_flag_for_slave
{ {
kDSPI_SlaveCtar0 = 0U << DSPI_SLAVE_CTAR_SHIFT, /*!< DSPI slave transfer use CTAR0 setting. */ kDSPI_SlaveCtar0 = 0U << DSPI_SLAVE_CTAR_SHIFT, /*!< DSPI slave transfer use CTAR0 setting. */
/*!< DSPI slave can only use PCS0. */ /*!< DSPI slave can only use PCS0. */
}; };
/*! @brief DSPI transfer state, which is used for DSPI transactional APIs' state machine. */ /*! @brief DSPI transfer state, which is used for DSPI transactional API state machine. */
enum _dspi_transfer_state enum _dspi_transfer_state
{ {
kDSPI_Idle = 0x0U, /*!< Nothing in the transmitter/receiver. */ kDSPI_Idle = 0x0U, /*!< Nothing in the transmitter/receiver. */
@ -238,15 +237,15 @@ enum _dspi_transfer_state
kDSPI_Error /*!< Transfer error. */ kDSPI_Error /*!< Transfer error. */
}; };
/*! @brief DSPI master command date configuration used for SPIx_PUSHR.*/ /*! @brief DSPI master command date configuration used for the SPIx_PUSHR.*/
typedef struct _dspi_command_data_config typedef struct _dspi_command_data_config
{ {
bool isPcsContinuous; /*!< Option to enable the continuous assertion of chip select between transfers.*/ bool isPcsContinuous; /*!< Option to enable the continuous assertion of the chip select between transfers.*/
dspi_ctar_selection_t whichCtar; /*!< The desired Clock and Transfer Attributes dspi_ctar_selection_t whichCtar; /*!< The desired Clock and Transfer Attributes
Register (CTAR) to use for CTAS.*/ Register (CTAR) to use for CTAS.*/
dspi_which_pcs_t whichPcs; /*!< The desired PCS signal to use for the data transfer.*/ dspi_which_pcs_t whichPcs; /*!< The desired PCS signal to use for the data transfer.*/
bool isEndOfQueue; /*!< Signals that the current transfer is the last in the queue.*/ bool isEndOfQueue; /*!< Signals that the current transfer is the last in the queue.*/
bool clearTransferCount; /*!< Clears SPI Transfer Counter (SPI_TCNT) before transmission starts.*/ bool clearTransferCount; /*!< Clears the SPI Transfer Counter (SPI_TCNT) before transmission starts.*/
} dspi_command_data_config_t; } dspi_command_data_config_t;
/*! @brief DSPI master ctar configuration structure.*/ /*! @brief DSPI master ctar configuration structure.*/
@ -258,33 +257,33 @@ typedef struct _dspi_master_ctar_config
dspi_clock_phase_t cpha; /*!< Clock phase. */ dspi_clock_phase_t cpha; /*!< Clock phase. */
dspi_shift_direction_t direction; /*!< MSB or LSB data shift direction. */ dspi_shift_direction_t direction; /*!< MSB or LSB data shift direction. */
uint32_t pcsToSckDelayInNanoSec; /*!< PCS to SCK delay time with nanosecond , set to 0 sets the minimum uint32_t pcsToSckDelayInNanoSec; /*!< PCS to SCK delay time in nanoseconds; setting to 0 sets the minimum
delay. It sets the boundary value if out of range that can be set.*/ delay. It also sets the boundary value if out of range.*/
uint32_t lastSckToPcsDelayInNanoSec; /*!< Last SCK to PCS delay time with nanosecond , set to 0 sets the uint32_t lastSckToPcsDelayInNanoSec; /*!< The last SCK to PCS delay time in nanoseconds; setting to 0 sets the
minimum delay.It sets the boundary value if out of range that can be minimum delay. It also sets the boundary value if out of range.*/
set.*/
uint32_t betweenTransferDelayInNanoSec; /*!< After SCK delay time with nanosecond , set to 0 sets the minimum uint32_t betweenTransferDelayInNanoSec; /*!< After the SCK delay time in nanoseconds; setting to 0 sets the minimum
delay.It sets the boundary value if out of range that can be set.*/ delay. It also sets the boundary value if out of range.*/
} dspi_master_ctar_config_t; } dspi_master_ctar_config_t;
/*! @brief DSPI master configuration structure.*/ /*! @brief DSPI master configuration structure.*/
typedef struct _dspi_master_config typedef struct _dspi_master_config
{ {
dspi_ctar_selection_t whichCtar; /*!< Desired CTAR to use. */ dspi_ctar_selection_t whichCtar; /*!< The desired CTAR to use. */
dspi_master_ctar_config_t ctarConfig; /*!< Set the ctarConfig to the desired CTAR. */ dspi_master_ctar_config_t ctarConfig; /*!< Set the ctarConfig to the desired CTAR. */
dspi_which_pcs_t whichPcs; /*!< Desired Peripheral Chip Select (pcs). */ dspi_which_pcs_t whichPcs; /*!< The desired Peripheral Chip Select (pcs). */
dspi_pcs_polarity_config_t pcsActiveHighOrLow; /*!< Desired PCS active high or low. */ dspi_pcs_polarity_config_t pcsActiveHighOrLow; /*!< The desired PCS active high or low. */
bool enableContinuousSCK; /*!< CONT_SCKE, continuous SCK enable . Note that continuous SCK is only bool enableContinuousSCK; /*!< CONT_SCKE, continuous SCK enable. Note that the continuous SCK is only
supported for CPHA = 1.*/ supported for CPHA = 1.*/
bool enableRxFifoOverWrite; /*!< ROOE, Receive FIFO overflow overwrite enable. ROOE = 0, the incoming bool enableRxFifoOverWrite; /*!< ROOE, receive FIFO overflow overwrite enable. If ROOE = 0, the incoming
data is ignored, the data from the transfer that generated the overflow data is ignored and the data from the transfer that generated the overflow
is either ignored. ROOE = 1, the incoming data is shifted in to the is also ignored. If ROOE = 1, the incoming data is shifted to the
shift to the shift register. */ shift register. */
bool enableModifiedTimingFormat; /*!< Enables a modified transfer format to be used if it's true.*/ bool enableModifiedTimingFormat; /*!< Enables a modified transfer format to be used if true.*/
dspi_master_sample_point_t samplePoint; /*!< Controls when the module master samples SIN in Modified Transfer dspi_master_sample_point_t samplePoint; /*!< Controls when the module master samples SIN in the Modified Transfer
Format. It's valid only when CPHA=0. */ Format. It's valid only when CPHA=0. */
} dspi_master_config_t; } dspi_master_config_t;
@ -294,23 +293,23 @@ typedef struct _dspi_slave_ctar_config
uint32_t bitsPerFrame; /*!< Bits per frame, minimum 4, maximum 16.*/ uint32_t bitsPerFrame; /*!< Bits per frame, minimum 4, maximum 16.*/
dspi_clock_polarity_t cpol; /*!< Clock polarity. */ dspi_clock_polarity_t cpol; /*!< Clock polarity. */
dspi_clock_phase_t cpha; /*!< Clock phase. */ dspi_clock_phase_t cpha; /*!< Clock phase. */
/*!< Slave only supports MSB , does not support LSB.*/ /*!< Slave only supports MSB and does not support LSB.*/
} dspi_slave_ctar_config_t; } dspi_slave_ctar_config_t;
/*! @brief DSPI slave configuration structure.*/ /*! @brief DSPI slave configuration structure.*/
typedef struct _dspi_slave_config typedef struct _dspi_slave_config
{ {
dspi_ctar_selection_t whichCtar; /*!< Desired CTAR to use. */ dspi_ctar_selection_t whichCtar; /*!< The desired CTAR to use. */
dspi_slave_ctar_config_t ctarConfig; /*!< Set the ctarConfig to the desired CTAR. */ dspi_slave_ctar_config_t ctarConfig; /*!< Set the ctarConfig to the desired CTAR. */
bool enableContinuousSCK; /*!< CONT_SCKE, continuous SCK enable. Note that continuous SCK is only bool enableContinuousSCK; /*!< CONT_SCKE, continuous SCK enable. Note that the continuous SCK is only
supported for CPHA = 1.*/ supported for CPHA = 1.*/
bool enableRxFifoOverWrite; /*!< ROOE, Receive FIFO overflow overwrite enable. ROOE = 0, the incoming bool enableRxFifoOverWrite; /*!< ROOE, receive FIFO overflow overwrite enable. If ROOE = 0, the incoming
data is ignored, the data from the transfer that generated the overflow data is ignored and the data from the transfer that generated the overflow
is either ignored. ROOE = 1, the incoming data is shifted in to the is also ignored. If ROOE = 1, the incoming data is shifted to the
shift to the shift register. */ shift register. */
bool enableModifiedTimingFormat; /*!< Enables a modified transfer format to be used if it's true.*/ bool enableModifiedTimingFormat; /*!< Enables a modified transfer format to be used if true.*/
dspi_master_sample_point_t samplePoint; /*!< Controls when the module master samples SIN in Modified Transfer dspi_master_sample_point_t samplePoint; /*!< Controls when the module master samples SIN in the Modified Transfer
Format. It's valid only when CPHA=0. */ Format. It's valid only when CPHA=0. */
} dspi_slave_config_t; } dspi_slave_config_t;
@ -357,7 +356,7 @@ typedef struct _dspi_transfer
volatile size_t dataSize; /*!< Transfer bytes. */ volatile size_t dataSize; /*!< Transfer bytes. */
uint32_t uint32_t
configFlags; /*!< Transfer transfer configuration flags , set from _dspi_transfer_config_flag_for_master if the configFlags; /*!< Transfer transfer configuration flags; set from _dspi_transfer_config_flag_for_master if the
transfer is used for master or _dspi_transfer_config_flag_for_slave enumeration if the transfer transfer is used for master or _dspi_transfer_config_flag_for_slave enumeration if the transfer
is used for slave.*/ is used for slave.*/
} dspi_transfer_t; } dspi_transfer_t;
@ -365,38 +364,38 @@ typedef struct _dspi_transfer
/*! @brief DSPI master transfer handle structure used for transactional API. */ /*! @brief DSPI master transfer handle structure used for transactional API. */
struct _dspi_master_handle struct _dspi_master_handle
{ {
uint32_t bitsPerFrame; /*!< Desired number of bits per frame. */ uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */
volatile uint32_t command; /*!< Desired data command. */ volatile uint32_t command; /*!< The desired data command. */
volatile uint32_t lastCommand; /*!< Desired last data command. */ volatile uint32_t lastCommand; /*!< The desired last data command. */
uint8_t fifoSize; /*!< FIFO dataSize. */ uint8_t fifoSize; /*!< FIFO dataSize. */
volatile bool isPcsActiveAfterTransfer; /*!< Is PCS signal keep active after the last frame transfer.*/ volatile bool isPcsActiveAfterTransfer; /*!< Indicates whether the PCS signal is active after the last frame transfer.*/
volatile bool isThereExtraByte; /*!< Is there extra byte.*/ volatile bool isThereExtraByte; /*!< Indicates whether there are extra bytes.*/
uint8_t *volatile txData; /*!< Send buffer. */ uint8_t *volatile txData; /*!< Send buffer. */
uint8_t *volatile rxData; /*!< Receive buffer. */ uint8_t *volatile rxData; /*!< Receive buffer. */
volatile size_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ volatile size_t remainingSendByteCount; /*!< A number of bytes remaining to send.*/
volatile size_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/
size_t totalByteCount; /*!< Number of transfer bytes*/ size_t totalByteCount; /*!< A number of transfer bytes*/
volatile uint8_t state; /*!< DSPI transfer state , _dspi_transfer_state.*/ volatile uint8_t state; /*!< DSPI transfer state, see _dspi_transfer_state.*/
dspi_master_transfer_callback_t callback; /*!< Completion callback. */ dspi_master_transfer_callback_t callback; /*!< Completion callback. */
void *userData; /*!< Callback user data. */ void *userData; /*!< Callback user data. */
}; };
/*! @brief DSPI slave transfer handle structure used for transactional API. */ /*! @brief DSPI slave transfer handle structure used for the transactional API. */
struct _dspi_slave_handle struct _dspi_slave_handle
{ {
uint32_t bitsPerFrame; /*!< Desired number of bits per frame. */ uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */
volatile bool isThereExtraByte; /*!< Is there extra byte.*/ volatile bool isThereExtraByte; /*!< Indicates whether there are extra bytes.*/
uint8_t *volatile txData; /*!< Send buffer. */ uint8_t *volatile txData; /*!< Send buffer. */
uint8_t *volatile rxData; /*!< Receive buffer. */ uint8_t *volatile rxData; /*!< Receive buffer. */
volatile size_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ volatile size_t remainingSendByteCount; /*!< A number of bytes remaining to send.*/
volatile size_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/
size_t totalByteCount; /*!< Number of transfer bytes*/ size_t totalByteCount; /*!< A number of transfer bytes*/
volatile uint8_t state; /*!< DSPI transfer state.*/ volatile uint8_t state; /*!< DSPI transfer state.*/
@ -421,18 +420,18 @@ extern "C" {
/*! /*!
* @brief Initializes the DSPI master. * @brief Initializes the DSPI master.
* *
* This function initializes the DSPI master configuration. An example use case is as follows: * This function initializes the DSPI master configuration. This is an example use case.
* @code * @code
* dspi_master_config_t masterConfig; * dspi_master_config_t masterConfig;
* masterConfig.whichCtar = kDSPI_Ctar0; * masterConfig.whichCtar = kDSPI_Ctar0;
* masterConfig.ctarConfig.baudRate = 500000000; * masterConfig.ctarConfig.baudRate = 500000000U;
* masterConfig.ctarConfig.bitsPerFrame = 8; * masterConfig.ctarConfig.bitsPerFrame = 8;
* masterConfig.ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh; * masterConfig.ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh;
* masterConfig.ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge; * masterConfig.ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge;
* masterConfig.ctarConfig.direction = kDSPI_MsbFirst; * masterConfig.ctarConfig.direction = kDSPI_MsbFirst;
* masterConfig.ctarConfig.pcsToSckDelayInNanoSec = 1000000000 / masterConfig.ctarConfig.baudRate ; * masterConfig.ctarConfig.pcsToSckDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ;
* masterConfig.ctarConfig.lastSckToPcsDelayInNanoSec = 1000000000 / masterConfig.ctarConfig.baudRate ; * masterConfig.ctarConfig.lastSckToPcsDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ;
* masterConfig.ctarConfig.betweenTransferDelayInNanoSec = 1000000000 / masterConfig.ctarConfig.baudRate ; * masterConfig.ctarConfig.betweenTransferDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ;
* masterConfig.whichPcs = kDSPI_Pcs0; * masterConfig.whichPcs = kDSPI_Pcs0;
* masterConfig.pcsActiveHighOrLow = kDSPI_PcsActiveLow; * masterConfig.pcsActiveHighOrLow = kDSPI_PcsActiveLow;
* masterConfig.enableContinuousSCK = false; * masterConfig.enableContinuousSCK = false;
@ -443,8 +442,8 @@ extern "C" {
* @endcode * @endcode
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param masterConfig Pointer to structure dspi_master_config_t. * @param masterConfig Pointer to the structure dspi_master_config_t.
* @param srcClock_Hz Module source input clock in Hertz * @param srcClock_Hz Module source input clock in Hertz.
*/ */
void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz); void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz);
@ -452,8 +451,8 @@ void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, u
* @brief Sets the dspi_master_config_t structure to default values. * @brief Sets the dspi_master_config_t structure to default values.
* *
* The purpose of this API is to get the configuration structure initialized for the DSPI_MasterInit(). * The purpose of this API is to get the configuration structure initialized for the DSPI_MasterInit().
* User may use the initialized structure unchanged in DSPI_MasterInit() or modify the structure * Users may use the initialized structure unchanged in the DSPI_MasterInit() or modify the structure
* before calling DSPI_MasterInit(). * before calling the DSPI_MasterInit().
* Example: * Example:
* @code * @code
* dspi_master_config_t masterConfig; * dspi_master_config_t masterConfig;
@ -466,7 +465,7 @@ void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig);
/*! /*!
* @brief DSPI slave configuration. * @brief DSPI slave configuration.
* *
* This function initializes the DSPI slave configuration. An example use case is as follows: * This function initializes the DSPI slave configuration. This is an example use case.
* @code * @code
* dspi_slave_config_t slaveConfig; * dspi_slave_config_t slaveConfig;
* slaveConfig->whichCtar = kDSPI_Ctar0; * slaveConfig->whichCtar = kDSPI_Ctar0;
@ -481,22 +480,22 @@ void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig);
* @endcode * @endcode
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param slaveConfig Pointer to structure dspi_master_config_t. * @param slaveConfig Pointer to the structure dspi_master_config_t.
*/ */
void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig); void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig);
/*! /*!
* @brief Sets the dspi_slave_config_t structure to default values. * @brief Sets the dspi_slave_config_t structure to a default value.
* *
* The purpose of this API is to get the configuration structure initialized for the DSPI_SlaveInit(). * The purpose of this API is to get the configuration structure initialized for the DSPI_SlaveInit().
* User may use the initialized structure unchanged in DSPI_SlaveInit(), or modify the structure * Users may use the initialized structure unchanged in the DSPI_SlaveInit() or modify the structure
* before calling DSPI_SlaveInit(). * before calling the DSPI_SlaveInit().
* Example: * This is an example.
* @code * @code
* dspi_slave_config_t slaveConfig; * dspi_slave_config_t slaveConfig;
* DSPI_SlaveGetDefaultConfig(&slaveConfig); * DSPI_SlaveGetDefaultConfig(&slaveConfig);
* @endcode * @endcode
* @param slaveConfig pointer to dspi_slave_config_t structure. * @param slaveConfig Pointer to the dspi_slave_config_t structure.
*/ */
void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig); void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig);
@ -510,7 +509,7 @@ void DSPI_Deinit(SPI_Type *base);
* @brief Enables the DSPI peripheral and sets the MCR MDIS to 0. * @brief Enables the DSPI peripheral and sets the MCR MDIS to 0.
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param enable pass true to enable module, false to disable module. * @param enable Pass true to enable module, false to disable module.
*/ */
static inline void DSPI_Enable(SPI_Type *base, bool enable) static inline void DSPI_Enable(SPI_Type *base, bool enable)
{ {
@ -536,7 +535,7 @@ static inline void DSPI_Enable(SPI_Type *base, bool enable)
/*! /*!
* @brief Gets the DSPI status flag state. * @brief Gets the DSPI status flag state.
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @return The DSPI status(in SR register). * @return DSPI status (in SR register).
*/ */
static inline uint32_t DSPI_GetStatusFlags(SPI_Type *base) static inline uint32_t DSPI_GetStatusFlags(SPI_Type *base)
{ {
@ -549,13 +548,13 @@ static inline uint32_t DSPI_GetStatusFlags(SPI_Type *base)
* This function clears the desired status bit by using a write-1-to-clear. The user passes in the base and the * This function clears the desired status bit by using a write-1-to-clear. The user passes in the base and the
* desired status bit to clear. The list of status bits is defined in the dspi_status_and_interrupt_request_t. The * desired status bit to clear. The list of status bits is defined in the dspi_status_and_interrupt_request_t. The
* function uses these bit positions in its algorithm to clear the desired flag state. * function uses these bit positions in its algorithm to clear the desired flag state.
* Example usage: * This is an example.
* @code * @code
* DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag|kDSPI_EndOfQueueFlag); * DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag|kDSPI_EndOfQueueFlag);
* @endcode * @endcode
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param statusFlags The status flag , used from type dspi_flags. * @param statusFlags The status flag used from the type dspi_flags.
*/ */
static inline void DSPI_ClearStatusFlags(SPI_Type *base, uint32_t statusFlags) static inline void DSPI_ClearStatusFlags(SPI_Type *base, uint32_t statusFlags)
{ {
@ -574,7 +573,7 @@ static inline void DSPI_ClearStatusFlags(SPI_Type *base, uint32_t statusFlags)
/*! /*!
* @brief Enables the DSPI interrupts. * @brief Enables the DSPI interrupts.
* *
* This function configures the various interrupt masks of the DSPI. The parameters are base and an interrupt mask. * This function configures the various interrupt masks of the DSPI. The parameters are a base and an interrupt mask.
* Note, for Tx Fill and Rx FIFO drain requests, enable the interrupt request and disable the DMA request. * Note, for Tx Fill and Rx FIFO drain requests, enable the interrupt request and disable the DMA request.
* *
* @code * @code
@ -582,7 +581,7 @@ static inline void DSPI_ClearStatusFlags(SPI_Type *base, uint32_t statusFlags)
* @endcode * @endcode
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param mask The interrupt mask, can use the enum _dspi_interrupt_enable. * @param mask The interrupt mask; use the enum _dspi_interrupt_enable.
*/ */
void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask); void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask);
@ -594,7 +593,7 @@ void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask);
* @endcode * @endcode
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param mask The interrupt mask, can use the enum _dspi_interrupt_enable. * @param mask The interrupt mask; use the enum _dspi_interrupt_enable.
*/ */
static inline void DSPI_DisableInterrupts(SPI_Type *base, uint32_t mask) static inline void DSPI_DisableInterrupts(SPI_Type *base, uint32_t mask)
{ {
@ -613,13 +612,13 @@ static inline void DSPI_DisableInterrupts(SPI_Type *base, uint32_t mask)
/*! /*!
* @brief Enables the DSPI DMA request. * @brief Enables the DSPI DMA request.
* *
* This function configures the Rx and Tx DMA mask of the DSPI. The parameters are base and a DMA mask. * This function configures the Rx and Tx DMA mask of the DSPI. The parameters are a base and a DMA mask.
* @code * @code
* DSPI_EnableDMA(base, kDSPI_TxDmaEnable | kDSPI_RxDmaEnable); * DSPI_EnableDMA(base, kDSPI_TxDmaEnable | kDSPI_RxDmaEnable);
* @endcode * @endcode
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param mask The interrupt mask can use the enum dspi_dma_enable. * @param mask The interrupt mask; use the enum dspi_dma_enable.
*/ */
static inline void DSPI_EnableDMA(SPI_Type *base, uint32_t mask) static inline void DSPI_EnableDMA(SPI_Type *base, uint32_t mask)
{ {
@ -629,13 +628,13 @@ static inline void DSPI_EnableDMA(SPI_Type *base, uint32_t mask)
/*! /*!
* @brief Disables the DSPI DMA request. * @brief Disables the DSPI DMA request.
* *
* This function configures the Rx and Tx DMA mask of the DSPI. The parameters are base and a DMA mask. * This function configures the Rx and Tx DMA mask of the DSPI. The parameters are a base and a DMA mask.
* @code * @code
* SPI_DisableDMA(base, kDSPI_TxDmaEnable | kDSPI_RxDmaEnable); * SPI_DisableDMA(base, kDSPI_TxDmaEnable | kDSPI_RxDmaEnable);
* @endcode * @endcode
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param mask The interrupt mask can use the enum dspi_dma_enable. * @param mask The interrupt mask; use the enum dspi_dma_enable.
*/ */
static inline void DSPI_DisableDMA(SPI_Type *base, uint32_t mask) static inline void DSPI_DisableDMA(SPI_Type *base, uint32_t mask)
{ {
@ -714,7 +713,7 @@ static inline bool DSPI_IsMaster(SPI_Type *base)
/*! /*!
* @brief Starts the DSPI transfers and clears HALT bit in MCR. * @brief Starts the DSPI transfers and clears HALT bit in MCR.
* *
* This function sets the module to begin data transfer in either master or slave mode. * This function sets the module to start data transfer in either master or slave mode.
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
*/ */
@ -723,9 +722,9 @@ static inline void DSPI_StartTransfer(SPI_Type *base)
base->MCR &= ~SPI_MCR_HALT_MASK; base->MCR &= ~SPI_MCR_HALT_MASK;
} }
/*! /*!
* @brief Stops (halts) DSPI transfers and sets HALT bit in MCR. * @brief Stops DSPI transfers and sets the HALT bit in MCR.
* *
* This function stops data transfers in either master or slave mode. * This function stops data transfers in either master or slave modes.
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
*/ */
@ -735,15 +734,15 @@ static inline void DSPI_StopTransfer(SPI_Type *base)
} }
/*! /*!
* @brief Enables (or disables) the DSPI FIFOs. * @brief Enables or disables the DSPI FIFOs.
* *
* This function allows the caller to disable/enable the Tx and Rx FIFOs (independently). * This function allows the caller to disable/enable the Tx and Rx FIFOs independently.
* Note that to disable, the caller must pass in a logic 0 (false) for the particular FIFO configuration. To enable, * Note that to disable, pass in a logic 0 (false) for the particular FIFO configuration. To enable,
* the caller must pass in a logic 1 (true). * pass in a logic 1 (true).
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param enableTxFifo Disables (false) the TX FIFO, else enables (true) the TX FIFO * @param enableTxFifo Disables (false) the TX FIFO; Otherwise, enables (true) the TX FIFO
* @param enableRxFifo Disables (false) the RX FIFO, else enables (true) the RX FIFO * @param enableRxFifo Disables (false) the RX FIFO; Otherwise, enables (true) the RX FIFO
*/ */
static inline void DSPI_SetFifoEnable(SPI_Type *base, bool enableTxFifo, bool enableRxFifo) static inline void DSPI_SetFifoEnable(SPI_Type *base, bool enableTxFifo, bool enableRxFifo)
{ {
@ -755,8 +754,8 @@ static inline void DSPI_SetFifoEnable(SPI_Type *base, bool enableTxFifo, bool en
* @brief Flushes the DSPI FIFOs. * @brief Flushes the DSPI FIFOs.
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param flushTxFifo Flushes (true) the Tx FIFO, else do not flush (false) the Tx FIFO * @param flushTxFifo Flushes (true) the Tx FIFO; Otherwise, does not flush (false) the Tx FIFO
* @param flushRxFifo Flushes (true) the Rx FIFO, else do not flush (false) the Rx FIFO * @param flushRxFifo Flushes (true) the Rx FIFO; Otherwise, does not flush (false) the Rx FIFO
*/ */
static inline void DSPI_FlushFifo(SPI_Type *base, bool flushTxFifo, bool flushRxFifo) static inline void DSPI_FlushFifo(SPI_Type *base, bool flushTxFifo, bool flushRxFifo)
{ {
@ -766,13 +765,13 @@ static inline void DSPI_FlushFifo(SPI_Type *base, bool flushTxFifo, bool flushRx
/*! /*!
* @brief Configures the DSPI peripheral chip select polarity simultaneously. * @brief Configures the DSPI peripheral chip select polarity simultaneously.
* For example, PCS0 and PCS1 set to active low and other PCS set to active high. Note that the number of * For example, PCS0 and PCS1 are set to active low and other PCS is set to active high. Note that the number of
* PCSs is specific to the device. * PCSs is specific to the device.
* @code * @code
* DSPI_SetAllPcsPolarity(base, kDSPI_Pcs0ActiveLow | kDSPI_Pcs1ActiveLow); * DSPI_SetAllPcsPolarity(base, kDSPI_Pcs0ActiveLow | kDSPI_Pcs1ActiveLow);
@endcode @endcode
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param mask The PCS polarity mask , can use the enum _dspi_pcs_polarity. * @param mask The PCS polarity mask; use the enum _dspi_pcs_polarity.
*/ */
static inline void DSPI_SetAllPcsPolarity(SPI_Type *base, uint32_t mask) static inline void DSPI_SetAllPcsPolarity(SPI_Type *base, uint32_t mask)
{ {
@ -801,19 +800,19 @@ uint32_t DSPI_MasterSetBaudRate(SPI_Type *base,
* @brief Manually configures the delay prescaler and scaler for a particular CTAR. * @brief Manually configures the delay prescaler and scaler for a particular CTAR.
* *
* This function configures the PCS to SCK delay pre-scalar (PcsSCK) and scalar (CSSCK), after SCK delay pre-scalar * This function configures the PCS to SCK delay pre-scalar (PcsSCK) and scalar (CSSCK), after SCK delay pre-scalar
* (PASC) and scalar (ASC), and the delay after transfer pre-scalar (PDT)and scalar (DT). * (PASC) and scalar (ASC), and the delay after transfer pre-scalar (PDT) and scalar (DT).
* *
* These delay names are available in type dspi_delay_type_t. * These delay names are available in the type dspi_delay_type_t.
* *
* The user passes the delay to configure along with the prescaler and scaler value. * The user passes the delay to the configuration along with the prescaler and scaler value.
* This allows the user to directly set the prescaler/scaler values if they have pre-calculated them or if they simply * This allows the user to directly set the prescaler/scaler values if pre-calculated or
* wish to manually increment either value. * to manually increment either value.
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type dspi_ctar_selection_t. * @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type dspi_ctar_selection_t.
* @param prescaler The prescaler delay value (can be an integer 0, 1, 2, or 3). * @param prescaler The prescaler delay value (can be an integer 0, 1, 2, or 3).
* @param scaler The scaler delay value (can be any integer between 0 to 15). * @param scaler The scaler delay value (can be any integer between 0 to 15).
* @param whichDelay The desired delay to configure, must be of type dspi_delay_type_t * @param whichDelay The desired delay to configure; must be of type dspi_delay_type_t
*/ */
void DSPI_MasterSetDelayScaler( void DSPI_MasterSetDelayScaler(
SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay); SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay);
@ -821,19 +820,19 @@ void DSPI_MasterSetDelayScaler(
/*! /*!
* @brief Calculates the delay prescaler and scaler based on the desired delay input in nanoseconds. * @brief Calculates the delay prescaler and scaler based on the desired delay input in nanoseconds.
* *
* This function calculates the values for: * This function calculates the values for the following.
* PCS to SCK delay pre-scalar (PCSSCK) and scalar (CSSCK), or * PCS to SCK delay pre-scalar (PCSSCK) and scalar (CSSCK), or
* After SCK delay pre-scalar (PASC) and scalar (ASC), or * After SCK delay pre-scalar (PASC) and scalar (ASC), or
* Delay after transfer pre-scalar (PDT)and scalar (DT). * Delay after transfer pre-scalar (PDT) and scalar (DT).
* *
* These delay names are available in type dspi_delay_type_t. * These delay names are available in the type dspi_delay_type_t.
* *
* The user passes which delay they want to configure along with the desired delay value in nanoseconds. The function * The user passes which delay to configure along with the desired delay value in nanoseconds. The function
* calculates the values needed for the prescaler and scaler and returning the actual calculated delay as an exact * calculates the values needed for the prescaler and scaler. Note that returning the calculated delay as an exact
* delay match may not be possible. In this case, the closest match is calculated without going below the desired * delay match may not be possible. In this case, the closest match is calculated without going below the desired
* delay value input. * delay value input.
* It is possible to input a very large delay value that exceeds the capability of the part, in which case the maximum * It is possible to input a very large delay value that exceeds the capability of the part, in which case the maximum
* supported delay is returned. The higher level peripheral driver alerts the user of an out of range delay * supported delay is returned. The higher-level peripheral driver alerts the user of an out of range delay
* input. * input.
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
@ -853,11 +852,11 @@ uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base,
* @brief Writes data into the data buffer for master mode. * @brief Writes data into the data buffer for master mode.
* *
* In master mode, the 16-bit data is appended to the 16-bit command info. The command portion * In master mode, the 16-bit data is appended to the 16-bit command info. The command portion
* provides characteristics of the data such as the optional continuous chip select * provides characteristics of the data, such as the optional continuous chip select
* operation between transfers, the desired Clock and Transfer Attributes register to use for the * operation between transfers, the desired Clock and Transfer Attributes register to use for the
* associated SPI frame, the desired PCS signal to use for the data transfer, whether the current * associated SPI frame, the desired PCS signal to use for the data transfer, whether the current
* transfer is the last in the queue, and whether to clear the transfer count (normally needed when * transfer is the last in the queue, and whether to clear the transfer count (normally needed when
* sending the first frame of a data packet). This is an example: * sending the first frame of a data packet). This is an example.
* @code * @code
* dspi_command_data_config_t commandConfig; * dspi_command_data_config_t commandConfig;
* commandConfig.isPcsContinuous = true; * commandConfig.isPcsContinuous = true;
@ -869,7 +868,7 @@ uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base,
@endcode @endcode
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param command Pointer to command structure. * @param command Pointer to the command structure.
* @param data The data word to be sent. * @param data The data word to be sent.
*/ */
static inline void DSPI_MasterWriteData(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data) static inline void DSPI_MasterWriteData(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data)
@ -883,14 +882,14 @@ static inline void DSPI_MasterWriteData(SPI_Type *base, dspi_command_data_config
* @brief Sets the dspi_command_data_config_t structure to default values. * @brief Sets the dspi_command_data_config_t structure to default values.
* *
* The purpose of this API is to get the configuration structure initialized for use in the DSPI_MasterWrite_xx(). * The purpose of this API is to get the configuration structure initialized for use in the DSPI_MasterWrite_xx().
* User may use the initialized structure unchanged in DSPI_MasterWrite_xx() or modify the structure * Users may use the initialized structure unchanged in the DSPI_MasterWrite_xx() or modify the structure
* before calling DSPI_MasterWrite_xx(). * before calling the DSPI_MasterWrite_xx().
* Example: * This is an example.
* @code * @code
* dspi_command_data_config_t command; * dspi_command_data_config_t command;
* DSPI_GetDefaultDataCommandConfig(&command); * DSPI_GetDefaultDataCommandConfig(&command);
* @endcode * @endcode
* @param command pointer to dspi_command_data_config_t structure. * @param command Pointer to the dspi_command_data_config_t structure.
*/ */
void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command); void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command);
@ -898,11 +897,11 @@ void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command);
* @brief Writes data into the data buffer master mode and waits till complete to return. * @brief Writes data into the data buffer master mode and waits till complete to return.
* *
* In master mode, the 16-bit data is appended to the 16-bit command info. The command portion * In master mode, the 16-bit data is appended to the 16-bit command info. The command portion
* provides characteristics of the data such as the optional continuous chip select * provides characteristics of the data, such as the optional continuous chip select
* operation between transfers, the desired Clock and Transfer Attributes register to use for the * operation between transfers, the desired Clock and Transfer Attributes register to use for the
* associated SPI frame, the desired PCS signal to use for the data transfer, whether the current * associated SPI frame, the desired PCS signal to use for the data transfer, whether the current
* transfer is the last in the queue, and whether to clear the transfer count (normally needed when * transfer is the last in the queue, and whether to clear the transfer count (normally needed when
* sending the first frame of a data packet). This is an example: * sending the first frame of a data packet). This is an example.
* @code * @code
* dspi_command_config_t commandConfig; * dspi_command_config_t commandConfig;
* commandConfig.isPcsContinuous = true; * commandConfig.isPcsContinuous = true;
@ -915,10 +914,10 @@ void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command);
* *
* Note that this function does not return until after the transmit is complete. Also note that the DSPI must be * Note that this function does not return until after the transmit is complete. Also note that the DSPI must be
* enabled and running to transmit data (MCR[MDIS] & [HALT] = 0). Because the SPI is a synchronous protocol, * enabled and running to transmit data (MCR[MDIS] & [HALT] = 0). Because the SPI is a synchronous protocol,
* receive data is available when transmit completes. * the received data is available when the transmit completes.
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param command Pointer to command structure. * @param command Pointer to the command structure.
* @param data The data word to be sent. * @param data The data word to be sent.
*/ */
void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data); void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data);
@ -933,10 +932,10 @@ void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *co
* improve performance in cases where the command structure is constant. For example, the user calls this function * improve performance in cases where the command structure is constant. For example, the user calls this function
* before starting a transfer to generate the command word. When they are ready to transmit the data, they OR * before starting a transfer to generate the command word. When they are ready to transmit the data, they OR
* this formatted command word with the desired data to transmit. This process increases transmit performance when * this formatted command word with the desired data to transmit. This process increases transmit performance when
* compared to calling send functions such as DSPI_HAL_WriteDataMastermode which format the command word each time a * compared to calling send functions, such as DSPI_HAL_WriteDataMastermode, which format the command word each time a
* data word is to be sent. * data word is to be sent.
* *
* @param command Pointer to command structure. * @param command Pointer to the command structure.
* @return The command word formatted to the PUSHR data register bit field. * @return The command word formatted to the PUSHR data register bit field.
*/ */
static inline uint32_t DSPI_MasterGetFormattedCommand(dspi_command_data_config_t *command) static inline uint32_t DSPI_MasterGetFormattedCommand(dspi_command_data_config_t *command)
@ -949,24 +948,23 @@ static inline uint32_t DSPI_MasterGetFormattedCommand(dspi_command_data_config_t
/*! /*!
* @brief Writes a 32-bit data word (16-bit command appended with 16-bit data) into the data * @brief Writes a 32-bit data word (16-bit command appended with 16-bit data) into the data
* buffer, master mode and waits till complete to return. * buffer master mode and waits till complete to return.
* *
* In this function, the user must append the 16-bit data to the 16-bit command info then provide the total 32-bit word * In this function, the user must append the 16-bit data to the 16-bit command information and then provide the total 32-bit word
* as the data to send. * as the data to send.
* The command portion provides characteristics of the data such as the optional continuous chip select operation * The command portion provides characteristics of the data, such as the optional continuous chip select operation
* between * between transfers, the desired Clock and Transfer Attributes register to use for the associated SPI frame, the desired PCS
* transfers, the desired Clock and Transfer Attributes register to use for the associated SPI frame, the desired PCS
* signal to use for the data transfer, whether the current transfer is the last in the queue, and whether to clear the * signal to use for the data transfer, whether the current transfer is the last in the queue, and whether to clear the
* transfer count (normally needed when sending the first frame of a data packet). The user is responsible for * transfer count (normally needed when sending the first frame of a data packet). The user is responsible for
* appending this command with the data to send. This is an example: * appending this command with the data to send. This is an example:
* @code * @code
* dataWord = <16-bit command> | <16-bit data>; * dataWord = <16-bit command> | <16-bit data>;
* DSPI_HAL_WriteCommandDataMastermodeBlocking(base, dataWord); * DSPI_MasterWriteCommandDataBlocking(base, dataWord);
* @endcode * @endcode
* *
* Note that this function does not return until after the transmit is complete. Also note that the DSPI must be * Note that this function does not return until after the transmit is complete. Also note that the DSPI must be
* enabled and running to transmit data (MCR[MDIS] & [HALT] = 0). * enabled and running to transmit data (MCR[MDIS] & [HALT] = 0).
* Because the SPI is a synchronous protocol, the receive data is available when transmit completes. * Because the SPI is a synchronous protocol, the received data is available when the transmit completes.
* *
* For a blocking polling transfer, see methods below. * For a blocking polling transfer, see methods below.
* Option 1: * Option 1:
@ -985,7 +983,7 @@ static inline uint32_t DSPI_MasterGetFormattedCommand(dspi_command_data_config_t
* DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_2); * DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_2);
* *
* @param base DSPI peripheral address. * @param base DSPI peripheral address.
* @param data The data word (command and data combined) to be sent * @param data The data word (command and data combined) to be sent.
*/ */
void DSPI_MasterWriteCommandDataBlocking(SPI_Type *base, uint32_t data); void DSPI_MasterWriteCommandDataBlocking(SPI_Type *base, uint32_t data);
@ -1037,13 +1035,13 @@ static inline uint32_t DSPI_ReadData(SPI_Type *base)
/*! /*!
* @brief Initializes the DSPI master handle. * @brief Initializes the DSPI master handle.
* *
* This function initializes the DSPI handle which can be used for other DSPI transactional APIs. Usually, for a * This function initializes the DSPI handle, which can be used for other DSPI transactional APIs. Usually, for a
* specified DSPI instance, call this API once to get the initialized handle. * specified DSPI instance, call this API once to get the initialized handle.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle DSPI handle pointer to dspi_master_handle_t. * @param handle DSPI handle pointer to dspi_master_handle_t.
* @param callback dspi callback. * @param callback DSPI callback.
* @param userData callback function parameter. * @param userData Callback function parameter.
*/ */
void DSPI_MasterTransferCreateHandle(SPI_Type *base, void DSPI_MasterTransferCreateHandle(SPI_Type *base,
dspi_master_handle_t *handle, dspi_master_handle_t *handle,
@ -1053,12 +1051,11 @@ void DSPI_MasterTransferCreateHandle(SPI_Type *base,
/*! /*!
* @brief DSPI master transfer data using polling. * @brief DSPI master transfer data using polling.
* *
* This function transfers data with polling. This is a blocking function, which does not return until all transfers * This function transfers data using polling. This is a blocking function, which does not return until all transfers
* have been * have been completed.
* completed.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param transfer pointer to dspi_transfer_t structure. * @param transfer Pointer to the dspi_transfer_t structure.
* @return status of status_t. * @return status of status_t.
*/ */
status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer); status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer);
@ -1067,12 +1064,11 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer);
* @brief DSPI master transfer data using interrupts. * @brief DSPI master transfer data using interrupts.
* *
* This function transfers data using interrupts. This is a non-blocking function, which returns right away. When all * This function transfers data using interrupts. This is a non-blocking function, which returns right away. When all
data * data is transferred, the callback function is called.
* have been transferred, the callback function is called.
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_master_handle_t structure which stores the transfer state. * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
* @param transfer pointer to dspi_transfer_t structure. * @param transfer Pointer to the dspi_transfer_t structure.
* @return status of status_t. * @return status of status_t.
*/ */
status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer); status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer);
@ -1083,19 +1079,19 @@ status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *ha
* This function gets the master transfer count. * This function gets the master transfer count.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_master_handle_t structure which stores the transfer state. * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
* @param count Number of bytes transferred so far by the non-blocking transaction. * @param count The number of bytes transferred by using the non-blocking transaction.
* @return status of status_t. * @return status of status_t.
*/ */
status_t DSPI_MasterTransferGetCount(SPI_Type *base, dspi_master_handle_t *handle, size_t *count); status_t DSPI_MasterTransferGetCount(SPI_Type *base, dspi_master_handle_t *handle, size_t *count);
/*! /*!
* @brief DSPI master aborts transfer using an interrupt. * @brief DSPI master aborts a transfer using an interrupt.
* *
* This function aborts a transfer using an interrupt. * This function aborts a transfer using an interrupt.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_master_handle_t structure which stores the transfer state. * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
*/ */
void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle); void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle);
@ -1105,7 +1101,7 @@ void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle);
* This function processes the DSPI transmit and receive IRQ. * This function processes the DSPI transmit and receive IRQ.
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_master_handle_t structure which stores the transfer state. * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
*/ */
void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle); void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle);
@ -1115,10 +1111,10 @@ void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle);
* This function initializes the DSPI handle, which can be used for other DSPI transactional APIs. Usually, for a * This function initializes the DSPI handle, which can be used for other DSPI transactional APIs. Usually, for a
* specified DSPI instance, call this API once to get the initialized handle. * specified DSPI instance, call this API once to get the initialized handle.
* *
* @param handle DSPI handle pointer to dspi_slave_handle_t. * @param handle DSPI handle pointer to the dspi_slave_handle_t.
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param callback DSPI callback. * @param callback DSPI callback.
* @param userData callback function parameter. * @param userData Callback function parameter.
*/ */
void DSPI_SlaveTransferCreateHandle(SPI_Type *base, void DSPI_SlaveTransferCreateHandle(SPI_Type *base,
dspi_slave_handle_t *handle, dspi_slave_handle_t *handle,
@ -1129,12 +1125,11 @@ void DSPI_SlaveTransferCreateHandle(SPI_Type *base,
* @brief DSPI slave transfers data using an interrupt. * @brief DSPI slave transfers data using an interrupt.
* *
* This function transfers data using an interrupt. This is a non-blocking function, which returns right away. When all * This function transfers data using an interrupt. This is a non-blocking function, which returns right away. When all
* data * data is transferred, the callback function is called.
* have been transferred, the callback function is called.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_slave_handle_t structure which stores the transfer state. * @param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state.
* @param transfer pointer to dspi_transfer_t structure. * @param transfer Pointer to the dspi_transfer_t structure.
* @return status of status_t. * @return status of status_t.
*/ */
status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer); status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer);
@ -1145,8 +1140,8 @@ status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *hand
* This function gets the slave transfer count. * This function gets the slave transfer count.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_master_handle_t structure which stores the transfer state. * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
* @param count Number of bytes transferred so far by the non-blocking transaction. * @param count The number of bytes transferred by using the non-blocking transaction.
* @return status of status_t. * @return status of status_t.
*/ */
status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle, size_t *count); status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle, size_t *count);
@ -1154,10 +1149,10 @@ status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle,
/*! /*!
* @brief DSPI slave aborts a transfer using an interrupt. * @brief DSPI slave aborts a transfer using an interrupt.
* *
* This function aborts transfer using an interrupt. * This function aborts a transfer using an interrupt.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_slave_handle_t structure which stores the transfer state. * @param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state.
*/ */
void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle); void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle);
@ -1167,7 +1162,7 @@ void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle);
* This function processes the DSPI transmit and receive IRQ. * This function processes the DSPI transmit and receive IRQ.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_slave_handle_t structure which stores the transfer state. * @param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state.
*/ */
void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle); void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle);

View File

@ -102,6 +102,9 @@ void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base,
edma_handle_t *edmaIntermediaryToTxRegHandle) edma_handle_t *edmaIntermediaryToTxRegHandle)
{ {
assert(handle); assert(handle);
assert(edmaRxRegToRxDataHandle);
assert(edmaTxDataToIntermediaryHandle);
assert(edmaIntermediaryToTxRegHandle);
/* Zero the handle. */ /* Zero the handle. */
memset(handle, 0, sizeof(*handle)); memset(handle, 0, sizeof(*handle));
@ -121,7 +124,8 @@ void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base,
status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, dspi_transfer_t *transfer) status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, dspi_transfer_t *transfer)
{ {
assert(handle && transfer); assert(handle);
assert(transfer);
/* If the transfer count is zero, then return immediately.*/ /* If the transfer count is zero, then return immediately.*/
if (transfer->dataSize == 0) if (transfer->dataSize == 0)
@ -143,7 +147,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
uint32_t instance = DSPI_GetInstance(base); uint32_t instance = DSPI_GetInstance(base);
uint16_t wordToSend = 0; uint16_t wordToSend = 0;
uint8_t dummyData = DSPI_MASTER_DUMMY_DATA; uint8_t dummyData = DSPI_DUMMY_DATA;
uint8_t dataAlreadyFed = 0; uint8_t dataAlreadyFed = 0;
uint8_t dataFedMax = 2; uint8_t dataFedMax = 2;
@ -156,7 +160,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
edma_transfer_config_t transferConfigB; edma_transfer_config_t transferConfigB;
edma_transfer_config_t transferConfigC; edma_transfer_config_t transferConfigC;
handle->txBuffIfNull = ((uint32_t)DSPI_MASTER_DUMMY_DATA << 8) | DSPI_MASTER_DUMMY_DATA; handle->txBuffIfNull = ((uint32_t)DSPI_DUMMY_DATA << 8) | DSPI_DUMMY_DATA;
handle->state = kDSPI_Busy; handle->state = kDSPI_Busy;
@ -174,6 +178,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous); commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous);
handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct)); handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct));
commandStruct.isEndOfQueue = true;
commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer); commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer);
handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct)); handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));
@ -193,7 +198,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
handle->remainingReceiveByteCount = transfer->dataSize; handle->remainingReceiveByteCount = transfer->dataSize;
handle->totalByteCount = transfer->dataSize; handle->totalByteCount = transfer->dataSize;
/* this limits the amount of data we can transfer due to the linked channel. /* This limits the amount of data we can transfer due to the linked channel.
* The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame * The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame
*/ */
if (handle->bitsPerFrame > 8) if (handle->bitsPerFrame > 8)
@ -211,22 +216,17 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
} }
} }
/*The data size should be even if the bitsPerFrame is greater than 8 (that is 2 bytes per frame in dspi) */
if ((handle->bitsPerFrame > 8) && (transfer->dataSize & 0x1))
{
return kStatus_InvalidArgument;
}
DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
EDMA_SetCallback(handle->edmaRxRegToRxDataHandle, EDMA_DspiMasterCallback, EDMA_SetCallback(handle->edmaRxRegToRxDataHandle, EDMA_DspiMasterCallback,
&s_dspiMasterEdmaPrivateHandle[instance]); &s_dspiMasterEdmaPrivateHandle[instance]);
handle->isThereExtraByte = false;
if (handle->bitsPerFrame > 8)
{
if (handle->remainingSendByteCount % 2 == 1)
{
handle->remainingSendByteCount++;
handle->remainingReceiveByteCount--;
handle->isThereExtraByte = true;
}
}
/*If dspi has separate dma request , prepare the first data in "intermediary" . /*If dspi has separate dma request , prepare the first data in "intermediary" .
else (dspi has shared dma request) , send first 2 data if there is fifo or send first 1 data if there is no fifo*/ else (dspi has shared dma request) , send first 2 data if there is fifo or send first 1 data if there is no fifo*/
if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
@ -243,16 +243,9 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
{ {
if (handle->txData) if (handle->txData)
{ {
if (handle->isThereExtraByte) wordToSend = *(handle->txData);
{ ++handle->txData; /* increment to next data byte */
wordToSend = *(handle->txData) | ((uint32_t)dummyData << 8); wordToSend |= (unsigned)(*(handle->txData)) << 8U;
}
else
{
wordToSend = *(handle->txData);
++handle->txData; /* increment to next data byte */
wordToSend |= (unsigned)(*(handle->txData)) << 8U;
}
} }
else else
{ {
@ -315,21 +308,13 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
{ {
if (handle->txData) if (handle->txData)
{ {
if (handle->isThereExtraByte) wordToSend = *(handle->txData);
{ ++handle->txData;
wordToSend = *(handle->txData) | ((uint32_t)dummyData << 8); wordToSend |= (unsigned)(*(handle->txData)) << 8U;
}
else
{
wordToSend = *(handle->txData);
++handle->txData;
wordToSend |= (unsigned)(*(handle->txData)) << 8U;
}
} }
else else
{ {
wordToSend = ((uint32_t)dummyData << 8) | dummyData; wordToSend = ((uint32_t)dummyData << 8) | dummyData;
;
} }
handle->remainingSendByteCount = 0; handle->remainingSendByteCount = 0;
base->PUSHR = (handle->lastCommand & 0xffff0000U) | wordToSend; base->PUSHR = (handle->lastCommand & 0xffff0000U) | wordToSend;
@ -347,7 +332,6 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
else else
{ {
wordToSend = ((uint32_t)dummyData << 8) | dummyData; wordToSend = ((uint32_t)dummyData << 8) | dummyData;
;
} }
handle->remainingSendByteCount -= 2; handle->remainingSendByteCount -= 2;
base->PUSHR = (handle->command & 0xffff0000U) | wordToSend; base->PUSHR = (handle->command & 0xffff0000U) | wordToSend;
@ -435,6 +419,10 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
transferConfigA.minorLoopBytes = 2; transferConfigA.minorLoopBytes = 2;
transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount / 2; transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount / 2;
} }
/* Store the initially configured eDMA minor byte transfer count into the DSPI handle */
handle->nbytes = transferConfigA.minorLoopBytes;
EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
&transferConfigA, NULL); &transferConfigA, NULL);
EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
@ -536,17 +524,9 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
} }
else else
{ {
if (handle->isThereExtraByte) handle->lastCommand = (handle->lastCommand & 0xffff0000U) |
{ ((uint32_t)handle->txData[bufferIndex - 1] << 8) |
handle->lastCommand = (handle->lastCommand & 0xffff0000U) | handle->txData[bufferIndex - 2] | handle->txData[bufferIndex - 2];
((uint32_t)dummyData << 8);
}
else
{
handle->lastCommand = (handle->lastCommand & 0xffff0000U) |
((uint32_t)handle->txData[bufferIndex - 1] << 8) |
handle->txData[bufferIndex - 2];
}
} }
} }
else else
@ -699,12 +679,6 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
EDMA_SetChannelLink(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, EDMA_SetChannelLink(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
kEDMA_MinorLink, handle->edmaTxDataToIntermediaryHandle->channel); kEDMA_MinorLink, handle->edmaTxDataToIntermediaryHandle->channel);
if (handle->isThereExtraByte)
{
EDMA_SetChannelLink(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
kEDMA_MajorLink, handle->edmaTxDataToIntermediaryHandle->channel);
}
EDMA_SetChannelLink(handle->edmaTxDataToIntermediaryHandle->base, EDMA_SetChannelLink(handle->edmaTxDataToIntermediaryHandle->base,
handle->edmaTxDataToIntermediaryHandle->channel, kEDMA_MinorLink, handle->edmaTxDataToIntermediaryHandle->channel, kEDMA_MinorLink,
handle->edmaIntermediaryToTxRegHandle->channel); handle->edmaIntermediaryToTxRegHandle->channel);
@ -723,26 +697,15 @@ static void EDMA_DspiMasterCallback(edma_handle_t *edmaHandle,
bool transferDone, bool transferDone,
uint32_t tcds) uint32_t tcds)
{ {
assert(edmaHandle);
assert(g_dspiEdmaPrivateHandle);
dspi_master_edma_private_handle_t *dspiEdmaPrivateHandle; dspi_master_edma_private_handle_t *dspiEdmaPrivateHandle;
dspiEdmaPrivateHandle = (dspi_master_edma_private_handle_t *)g_dspiEdmaPrivateHandle; dspiEdmaPrivateHandle = (dspi_master_edma_private_handle_t *)g_dspiEdmaPrivateHandle;
uint32_t dataReceived;
DSPI_DisableDMA((dspiEdmaPrivateHandle->base), kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); DSPI_DisableDMA((dspiEdmaPrivateHandle->base), kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
if (dspiEdmaPrivateHandle->handle->isThereExtraByte)
{
while (!((dspiEdmaPrivateHandle->base)->SR & SPI_SR_RFDF_MASK))
{
}
dataReceived = (dspiEdmaPrivateHandle->base)->POPR;
if (dspiEdmaPrivateHandle->handle->rxData)
{
(dspiEdmaPrivateHandle->handle->rxData[dspiEdmaPrivateHandle->handle->totalByteCount - 1]) = dataReceived;
}
}
if (dspiEdmaPrivateHandle->handle->callback) if (dspiEdmaPrivateHandle->handle->callback)
{ {
dspiEdmaPrivateHandle->handle->callback(dspiEdmaPrivateHandle->base, dspiEdmaPrivateHandle->handle, dspiEdmaPrivateHandle->handle->callback(dspiEdmaPrivateHandle->base, dspiEdmaPrivateHandle->handle,
@ -754,6 +717,8 @@ static void EDMA_DspiMasterCallback(edma_handle_t *edmaHandle,
void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle) void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle)
{ {
assert(handle);
DSPI_StopTransfer(base); DSPI_StopTransfer(base);
DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
@ -783,7 +748,8 @@ status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle
size_t bytes; size_t bytes;
bytes = EDMA_GetRemainingBytes(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel); bytes = (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->edmaRxRegToRxDataHandle->base,
handle->edmaRxRegToRxDataHandle->channel);
*count = handle->totalByteCount - bytes; *count = handle->totalByteCount - bytes;
@ -798,6 +764,8 @@ void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base,
edma_handle_t *edmaTxDataToTxRegHandle) edma_handle_t *edmaTxDataToTxRegHandle)
{ {
assert(handle); assert(handle);
assert(edmaRxRegToRxDataHandle);
assert(edmaTxDataToTxRegHandle);
/* Zero the handle. */ /* Zero the handle. */
memset(handle, 0, sizeof(*handle)); memset(handle, 0, sizeof(*handle));
@ -816,7 +784,8 @@ void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base,
status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, dspi_transfer_t *transfer) status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, dspi_transfer_t *transfer)
{ {
assert(handle && transfer); assert(handle);
assert(transfer);
/* If send/receive length is zero */ /* If send/receive length is zero */
if (transfer->dataSize == 0) if (transfer->dataSize == 0)
@ -836,8 +805,6 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
return kStatus_DSPI_Busy; return kStatus_DSPI_Busy;
} }
edma_tcd_t *softwareTCD = (edma_tcd_t *)((uint32_t)(&handle->dspiSoftwareTCD[1]) & (~0x1FU));
uint32_t instance = DSPI_GetInstance(base); uint32_t instance = DSPI_GetInstance(base);
uint8_t whichCtar = (transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT; uint8_t whichCtar = (transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT;
handle->bitsPerFrame = handle->bitsPerFrame =
@ -864,7 +831,8 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
} }
} }
if ((handle->bitsPerFrame > 8) && (transfer->dataSize < 2)) /*The data size should be even if the bitsPerFrame is greater than 8 (that is 2 bytes per frame in dspi) */
if ((handle->bitsPerFrame > 8) && (transfer->dataSize & 0x1))
{ {
return kStatus_InvalidArgument; return kStatus_InvalidArgument;
} }
@ -879,21 +847,9 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
handle->remainingSendByteCount = transfer->dataSize; handle->remainingSendByteCount = transfer->dataSize;
handle->remainingReceiveByteCount = transfer->dataSize; handle->remainingReceiveByteCount = transfer->dataSize;
handle->totalByteCount = transfer->dataSize; handle->totalByteCount = transfer->dataSize;
handle->errorCount = 0;
handle->isThereExtraByte = false;
if (handle->bitsPerFrame > 8)
{
if (handle->remainingSendByteCount % 2 == 1)
{
handle->remainingSendByteCount++;
handle->remainingReceiveByteCount--;
handle->isThereExtraByte = true;
}
}
uint16_t wordToSend = 0; uint16_t wordToSend = 0;
uint8_t dummyData = DSPI_SLAVE_DUMMY_DATA; uint8_t dummyData = DSPI_DUMMY_DATA;
uint8_t dataAlreadyFed = 0; uint8_t dataAlreadyFed = 0;
uint8_t dataFedMax = 2; uint8_t dataFedMax = 2;
@ -929,16 +885,9 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
{ {
wordToSend = *(handle->txData); wordToSend = *(handle->txData);
++handle->txData; /* Increment to next data byte */ ++handle->txData; /* Increment to next data byte */
if ((handle->remainingSendByteCount == 2) && (handle->isThereExtraByte))
{ wordToSend |= (unsigned)(*(handle->txData)) << 8U;
wordToSend |= (unsigned)(dummyData) << 8U; ++handle->txData; /* Increment to next data byte */
++handle->txData; /* Increment to next data byte */
}
else
{
wordToSend |= (unsigned)(*(handle->txData)) << 8U;
++handle->txData; /* Increment to next data byte */
}
} }
else else
{ {
@ -1025,6 +974,10 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
transferConfigA.minorLoopBytes = 2; transferConfigA.minorLoopBytes = 2;
transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount / 2; transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount / 2;
} }
/* Store the initially configured eDMA minor byte transfer count into the DSPI handle */
handle->nbytes = transferConfigA.minorLoopBytes;
EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
&transferConfigA, NULL); &transferConfigA, NULL);
EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
@ -1036,98 +989,47 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
/***channel_C *** used for carry the data from User_Send_Buffer to Tx_Data_Register(PUSHR_SLAVE)*/ /***channel_C *** used for carry the data from User_Send_Buffer to Tx_Data_Register(PUSHR_SLAVE)*/
EDMA_ResetChannel(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel); EDMA_ResetChannel(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel);
/*If there is extra byte , it would use the */ transferConfigC.destAddr = (uint32_t)txAddr;
if (handle->isThereExtraByte) transferConfigC.destOffset = 0;
{
if (handle->txData)
{
handle->txLastData =
handle->txData[handle->remainingSendByteCount - 2] | ((uint32_t)DSPI_SLAVE_DUMMY_DATA << 8);
}
else
{
handle->txLastData = DSPI_SLAVE_DUMMY_DATA | ((uint32_t)DSPI_SLAVE_DUMMY_DATA << 8);
}
transferConfigC.srcAddr = (uint32_t)(&(handle->txLastData));
transferConfigC.destAddr = (uint32_t)txAddr;
transferConfigC.srcTransferSize = kEDMA_TransferSize4Bytes;
transferConfigC.destTransferSize = kEDMA_TransferSize4Bytes;
transferConfigC.srcOffset = 0;
transferConfigC.destOffset = 0;
transferConfigC.minorLoopBytes = 4;
transferConfigC.majorLoopCounts = 1;
EDMA_TcdReset(softwareTCD); if (handle->txData)
EDMA_TcdSetTransferConfig(softwareTCD, &transferConfigC, NULL);
}
/*Set another transferConfigC*/
if ((handle->isThereExtraByte) && (handle->remainingSendByteCount == 2))
{ {
EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, transferConfigC.srcAddr = (uint32_t)(&(handle->txData[0]));
&transferConfigC, NULL); transferConfigC.srcOffset = 1;
} }
else else
{ {
transferConfigC.destAddr = (uint32_t)txAddr; transferConfigC.srcAddr = (uint32_t)(&handle->txBuffIfNull);
transferConfigC.destOffset = 0; transferConfigC.srcOffset = 0;
if (handle->txData)
{
transferConfigC.srcAddr = (uint32_t)(&(handle->txData[0]));
transferConfigC.srcOffset = 1;
}
else
{
transferConfigC.srcAddr = (uint32_t)(&handle->txBuffIfNull);
transferConfigC.srcOffset = 0;
if (handle->bitsPerFrame <= 8)
{
handle->txBuffIfNull = DSPI_SLAVE_DUMMY_DATA;
}
else
{
handle->txBuffIfNull = (DSPI_SLAVE_DUMMY_DATA << 8) | DSPI_SLAVE_DUMMY_DATA;
}
}
transferConfigC.srcTransferSize = kEDMA_TransferSize1Bytes;
if (handle->bitsPerFrame <= 8) if (handle->bitsPerFrame <= 8)
{ {
transferConfigC.destTransferSize = kEDMA_TransferSize1Bytes; handle->txBuffIfNull = DSPI_DUMMY_DATA;
transferConfigC.minorLoopBytes = 1;
transferConfigC.majorLoopCounts = handle->remainingSendByteCount;
} }
else else
{ {
transferConfigC.destTransferSize = kEDMA_TransferSize2Bytes; handle->txBuffIfNull = (DSPI_DUMMY_DATA << 8) | DSPI_DUMMY_DATA;
transferConfigC.minorLoopBytes = 2;
if (handle->isThereExtraByte)
{
transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2 - 1;
}
else
{
transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2;
}
} }
if (handle->isThereExtraByte)
{
EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
&transferConfigC, softwareTCD);
EDMA_EnableAutoStopRequest(handle->edmaTxDataToTxRegHandle->base,
handle->edmaTxDataToTxRegHandle->channel, false);
}
else
{
EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
&transferConfigC, NULL);
}
EDMA_StartTransfer(handle->edmaTxDataToTxRegHandle);
} }
transferConfigC.srcTransferSize = kEDMA_TransferSize1Bytes;
if (handle->bitsPerFrame <= 8)
{
transferConfigC.destTransferSize = kEDMA_TransferSize1Bytes;
transferConfigC.minorLoopBytes = 1;
transferConfigC.majorLoopCounts = handle->remainingSendByteCount;
}
else
{
transferConfigC.destTransferSize = kEDMA_TransferSize2Bytes;
transferConfigC.minorLoopBytes = 2;
transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2;
}
EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
&transferConfigC, NULL);
EDMA_StartTransfer(handle->edmaTxDataToTxRegHandle);
} }
EDMA_StartTransfer(handle->edmaRxRegToRxDataHandle); EDMA_StartTransfer(handle->edmaRxRegToRxDataHandle);
@ -1195,26 +1097,15 @@ static void EDMA_DspiSlaveCallback(edma_handle_t *edmaHandle,
bool transferDone, bool transferDone,
uint32_t tcds) uint32_t tcds)
{ {
assert(edmaHandle);
assert(g_dspiEdmaPrivateHandle);
dspi_slave_edma_private_handle_t *dspiEdmaPrivateHandle; dspi_slave_edma_private_handle_t *dspiEdmaPrivateHandle;
dspiEdmaPrivateHandle = (dspi_slave_edma_private_handle_t *)g_dspiEdmaPrivateHandle; dspiEdmaPrivateHandle = (dspi_slave_edma_private_handle_t *)g_dspiEdmaPrivateHandle;
uint32_t dataReceived;
DSPI_DisableDMA((dspiEdmaPrivateHandle->base), kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); DSPI_DisableDMA((dspiEdmaPrivateHandle->base), kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
if (dspiEdmaPrivateHandle->handle->isThereExtraByte)
{
while (!((dspiEdmaPrivateHandle->base)->SR & SPI_SR_RFDF_MASK))
{
}
dataReceived = (dspiEdmaPrivateHandle->base)->POPR;
if (dspiEdmaPrivateHandle->handle->rxData)
{
(dspiEdmaPrivateHandle->handle->rxData[dspiEdmaPrivateHandle->handle->totalByteCount - 1]) = dataReceived;
}
}
if (dspiEdmaPrivateHandle->handle->callback) if (dspiEdmaPrivateHandle->handle->callback)
{ {
dspiEdmaPrivateHandle->handle->callback(dspiEdmaPrivateHandle->base, dspiEdmaPrivateHandle->handle, dspiEdmaPrivateHandle->handle->callback(dspiEdmaPrivateHandle->base, dspiEdmaPrivateHandle->handle,
@ -1226,6 +1117,8 @@ static void EDMA_DspiSlaveCallback(edma_handle_t *edmaHandle,
void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle) void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle)
{ {
assert(handle);
DSPI_StopTransfer(base); DSPI_StopTransfer(base);
DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
@ -1254,7 +1147,8 @@ status_t DSPI_SlaveTransferGetCountEDMA(SPI_Type *base, dspi_slave_edma_handle_t
size_t bytes; size_t bytes;
bytes = EDMA_GetRemainingBytes(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel); bytes = (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->edmaRxRegToRxDataHandle->base,
handle->edmaRxRegToRxDataHandle->channel);
*count = handle->totalByteCount - bytes; *count = handle->totalByteCount - bytes;

View File

@ -37,8 +37,6 @@
* @{ * @{
*/ */
/*! @file */
/*********************************************************************************************************************** /***********************************************************************************************************************
* Definitions * Definitions
**********************************************************************************************************************/ **********************************************************************************************************************/
@ -57,9 +55,9 @@ typedef struct _dspi_slave_edma_handle dspi_slave_edma_handle_t;
* @brief Completion callback function pointer type. * @brief Completion callback function pointer type.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle Pointer to the handle for the DSPI master. * @param handle A pointer to the handle for the DSPI master.
* @param status Success or error code describing whether the transfer completed. * @param status Success or error code describing whether the transfer completed.
* @param userData Arbitrary pointer-dataSized value passed from the application. * @param userData An arbitrary pointer-dataSized value passed from the application.
*/ */
typedef void (*dspi_master_edma_transfer_callback_t)(SPI_Type *base, typedef void (*dspi_master_edma_transfer_callback_t)(SPI_Type *base,
dspi_master_edma_handle_t *handle, dspi_master_edma_handle_t *handle,
@ -69,38 +67,39 @@ typedef void (*dspi_master_edma_transfer_callback_t)(SPI_Type *base,
* @brief Completion callback function pointer type. * @brief Completion callback function pointer type.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle Pointer to the handle for the DSPI slave. * @param handle A pointer to the handle for the DSPI slave.
* @param status Success or error code describing whether the transfer completed. * @param status Success or error code describing whether the transfer completed.
* @param userData Arbitrary pointer-dataSized value passed from the application. * @param userData An arbitrary pointer-dataSized value passed from the application.
*/ */
typedef void (*dspi_slave_edma_transfer_callback_t)(SPI_Type *base, typedef void (*dspi_slave_edma_transfer_callback_t)(SPI_Type *base,
dspi_slave_edma_handle_t *handle, dspi_slave_edma_handle_t *handle,
status_t status, status_t status,
void *userData); void *userData);
/*! @brief DSPI master eDMA transfer handle structure used for transactional API. */ /*! @brief DSPI master eDMA transfer handle structure used for the transactional API. */
struct _dspi_master_edma_handle struct _dspi_master_edma_handle
{ {
uint32_t bitsPerFrame; /*!< Desired number of bits per frame. */ uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */
volatile uint32_t command; /*!< Desired data command. */ volatile uint32_t command; /*!< The desired data command. */
volatile uint32_t lastCommand; /*!< Desired last data command. */ volatile uint32_t lastCommand; /*!< The desired last data command. */
uint8_t fifoSize; /*!< FIFO dataSize. */ uint8_t fifoSize; /*!< FIFO dataSize. */
volatile bool isPcsActiveAfterTransfer; /*!< Is PCS signal keep active after the last frame transfer.*/ volatile bool
volatile bool isThereExtraByte; /*!< Is there extra byte.*/ isPcsActiveAfterTransfer; /*!< Indicates whether the PCS signal keeps active after the last frame transfer.*/
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
volatile uint8_t state; /*!< DSPI transfer state , _dspi_transfer_state.*/
uint8_t *volatile txData; /*!< Send buffer. */ uint8_t *volatile txData; /*!< Send buffer. */
uint8_t *volatile rxData; /*!< Receive buffer. */ uint8_t *volatile rxData; /*!< Receive buffer. */
volatile size_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ volatile size_t remainingSendByteCount; /*!< A number of bytes remaining to send.*/
volatile size_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/
size_t totalByteCount; /*!< Number of transfer bytes*/ size_t totalByteCount; /*!< A number of transfer bytes*/
uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/ uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/
uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/ uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/
volatile uint8_t state; /*!< DSPI transfer state , _dspi_transfer_state.*/
dspi_master_edma_transfer_callback_t callback; /*!< Completion callback. */ dspi_master_edma_transfer_callback_t callback; /*!< Completion callback. */
void *userData; /*!< Callback user data. */ void *userData; /*!< Callback user data. */
@ -111,33 +110,30 @@ struct _dspi_master_edma_handle
edma_tcd_t dspiSoftwareTCD[2]; /*!<SoftwareTCD , internal used*/ edma_tcd_t dspiSoftwareTCD[2]; /*!<SoftwareTCD , internal used*/
}; };
/*! @brief DSPI slave eDMA transfer handle structure used for transactional API.*/ /*! @brief DSPI slave eDMA transfer handle structure used for the transactional API.*/
struct _dspi_slave_edma_handle struct _dspi_slave_edma_handle
{ {
uint32_t bitsPerFrame; /*!< Desired number of bits per frame. */ uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */
volatile bool isThereExtraByte; /*!< Is there extra byte.*/
uint8_t *volatile txData; /*!< Send buffer. */ uint8_t *volatile txData; /*!< Send buffer. */
uint8_t *volatile rxData; /*!< Receive buffer. */ uint8_t *volatile rxData; /*!< Receive buffer. */
volatile size_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ volatile size_t remainingSendByteCount; /*!< A number of bytes remaining to send.*/
volatile size_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/
size_t totalByteCount; /*!< Number of transfer bytes*/ size_t totalByteCount; /*!< A number of transfer bytes*/
uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/ uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/
uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/ uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/
uint32_t txLastData; /*!< Used if there is an extra byte when 16bits per frame for DMA purpose.*/ uint32_t txLastData; /*!< Used if there is an extra byte when 16bits per frame for DMA purpose.*/
volatile uint8_t state; /*!< DSPI transfer state.*/ uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
uint32_t errorCount; /*!< Error count for slave transfer.*/ volatile uint8_t state; /*!< DSPI transfer state.*/
dspi_slave_edma_transfer_callback_t callback; /*!< Completion callback. */ dspi_slave_edma_transfer_callback_t callback; /*!< Completion callback. */
void *userData; /*!< Callback user data. */ void *userData; /*!< Callback user data. */
edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/ edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/
edma_handle_t *edmaTxDataToTxRegHandle; /*!<edma_handle_t handle point used for TxData to TxReg*/ edma_handle_t *edmaTxDataToTxRegHandle; /*!<edma_handle_t handle point used for TxData to TxReg*/
edma_tcd_t dspiSoftwareTCD[2]; /*!<SoftwareTCD , internal used*/
}; };
/*********************************************************************************************************************** /***********************************************************************************************************************
@ -153,17 +149,18 @@ extern "C" {
* @brief Initializes the DSPI master eDMA handle. * @brief Initializes the DSPI master eDMA handle.
* *
* This function initializes the DSPI eDMA handle which can be used for other DSPI transactional APIs. Usually, for a * This function initializes the DSPI eDMA handle which can be used for other DSPI transactional APIs. Usually, for a
* specified DSPI instance, user need only call this API once to get the initialized handle. * specified DSPI instance, call this API once to get the initialized handle.
* *
* Note that DSPI eDMA has separated (RX and TX as two sources) or shared (RX and TX are the same source) DMA request source. * Note that DSPI eDMA has separated (RX and TX as two sources) or shared (RX and TX are the same source) DMA request
* (1)For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and * source.
* (1) For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and
* TX DMAMUX source for edmaIntermediaryToTxRegHandle. * TX DMAMUX source for edmaIntermediaryToTxRegHandle.
* (2)For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle. * (2) For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle DSPI handle pointer to dspi_master_edma_handle_t. * @param handle DSPI handle pointer to dspi_master_edma_handle_t.
* @param callback DSPI callback. * @param callback DSPI callback.
* @param userData callback function parameter. * @param userData A callback function parameter.
* @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t. * @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
* @param edmaTxDataToIntermediaryHandle edmaTxDataToIntermediaryHandle pointer to edma_handle_t. * @param edmaTxDataToIntermediaryHandle edmaTxDataToIntermediaryHandle pointer to edma_handle_t.
* @param edmaIntermediaryToTxRegHandle edmaIntermediaryToTxRegHandle pointer to edma_handle_t. * @param edmaIntermediaryToTxRegHandle edmaIntermediaryToTxRegHandle pointer to edma_handle_t.
@ -179,34 +176,34 @@ void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base,
/*! /*!
* @brief DSPI master transfer data using eDMA. * @brief DSPI master transfer data using eDMA.
* *
* This function transfer data using eDMA. This is non-blocking function, which returns right away. When all data * This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
* have been transfer, the callback function is called. * is transferred, the callback function is called.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_master_edma_handle_t structure which stores the transfer state. * @param handle A pointer to the dspi_master_edma_handle_t structure which stores the transfer state.
* @param transfer pointer to dspi_transfer_t structure. * @param transfer A pointer to the dspi_transfer_t structure.
* @return status of status_t. * @return status of status_t.
*/ */
status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, dspi_transfer_t *transfer); status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, dspi_transfer_t *transfer);
/*! /*!
* @brief DSPI master aborts a transfer which using eDMA. * @brief DSPI master aborts a transfer which is using eDMA.
* *
* This function aborts a transfer which using eDMA. * This function aborts a transfer which is using eDMA.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_master_edma_handle_t structure which stores the transfer state. * @param handle A pointer to the dspi_master_edma_handle_t structure which stores the transfer state.
*/ */
void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle); void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle);
/*! /*!
* @brief Gets the master eDMA transfer count. * @brief Gets the master eDMA transfer count.
* *
* This function get the master eDMA transfer count. * This function gets the master eDMA transfer count.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_master_edma_handle_t structure which stores the transfer state. * @param handle A pointer to the dspi_master_edma_handle_t structure which stores the transfer state.
* @param count Number of bytes transferred so far by the non-blocking transaction. * @param count A number of bytes transferred by the non-blocking transaction.
* @return status of status_t. * @return status of status_t.
*/ */
status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, size_t *count); status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, size_t *count);
@ -217,7 +214,8 @@ status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle
* This function initializes the DSPI eDMA handle which can be used for other DSPI transactional APIs. Usually, for a * This function initializes the DSPI eDMA handle which can be used for other DSPI transactional APIs. Usually, for a
* specified DSPI instance, call this API once to get the initialized handle. * specified DSPI instance, call this API once to get the initialized handle.
* *
* Note that DSPI eDMA has separated (RN and TX in 2 sources) or shared (RX and TX are the same source) DMA request source. * Note that DSPI eDMA has separated (RN and TX in 2 sources) or shared (RX and TX are the same source) DMA request
* source.
* (1)For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and * (1)For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and
* TX DMAMUX source for edmaTxDataToTxRegHandle. * TX DMAMUX source for edmaTxDataToTxRegHandle.
* (2)For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle. * (2)For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle.
@ -225,7 +223,7 @@ status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle DSPI handle pointer to dspi_slave_edma_handle_t. * @param handle DSPI handle pointer to dspi_slave_edma_handle_t.
* @param callback DSPI callback. * @param callback DSPI callback.
* @param userData callback function parameter. * @param userData A callback function parameter.
* @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t. * @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
* @param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t. * @param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t.
*/ */
@ -239,25 +237,25 @@ void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base,
/*! /*!
* @brief DSPI slave transfer data using eDMA. * @brief DSPI slave transfer data using eDMA.
* *
* This function transfer data using eDMA. This is non-blocking function, which returns right away. When all data * This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
* have been transfer, the callback function is called. * is transferred, the callback function is called.
* Note that slave EDMA transfer cannot support the situation that transfer_size is 1 when the bitsPerFrame is greater * Note that the slave eDMA transfer doesn't support transfer_size is 1 when the bitsPerFrame is greater
* than 8 . * than eight.
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_slave_edma_handle_t structure which stores the transfer state. * @param handle A pointer to the dspi_slave_edma_handle_t structure which stores the transfer state.
* @param transfer pointer to dspi_transfer_t structure. * @param transfer A pointer to the dspi_transfer_t structure.
* @return status of status_t. * @return status of status_t.
*/ */
status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, dspi_transfer_t *transfer); status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, dspi_transfer_t *transfer);
/*! /*!
* @brief DSPI slave aborts a transfer which using eDMA. * @brief DSPI slave aborts a transfer which is using eDMA.
* *
* This function aborts a transfer which using eDMA. * This function aborts a transfer which is using eDMA.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_slave_edma_handle_t structure which stores the transfer state. * @param handle A pointer to the dspi_slave_edma_handle_t structure which stores the transfer state.
*/ */
void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle); void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle);
@ -267,8 +265,8 @@ void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handl
* This function gets the slave eDMA transfer count. * This function gets the slave eDMA transfer count.
* *
* @param base DSPI peripheral base address. * @param base DSPI peripheral base address.
* @param handle pointer to dspi_slave_edma_handle_t structure which stores the transfer state. * @param handle A pointer to the dspi_slave_edma_handle_t structure which stores the transfer state.
* @param count Number of bytes transferred so far by the non-blocking transaction. * @param count A number of bytes transferred so far by the non-blocking transaction.
* @return status of status_t. * @return status of status_t.
*/ */
status_t DSPI_SlaveTransferGetCountEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, size_t *count); status_t DSPI_SlaveTransferGetCountEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, size_t *count);

View File

@ -63,11 +63,18 @@ static void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd);
/*! @brief Array to map EDMA instance number to base pointer. */ /*! @brief Array to map EDMA instance number to base pointer. */
static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS; static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Array to map EDMA instance number to clock name. */ /*! @brief Array to map EDMA instance number to clock name. */
static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS; static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT == 1U)
/*! @brief Array to map EDMA instance number to IRQ number. */ /*! @brief Array to map EDMA instance number to IRQ number. */
static const IRQn_Type s_edmaIRQNumber[] = DMA_CHN_IRQS; static const IRQn_Type s_edmaIRQNumber[] = DMA_CHN_IRQS;
#elif defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 1U)
/*! @brief Array to map EDMA instance number to IRQ number. */
static const IRQn_Type s_edmaIRQNumber[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = DMA_CHN_IRQS;
#endif
/*! @brief Pointers to transfer handle for each EDMA channel. */ /*! @brief Pointers to transfer handle for each EDMA channel. */
static edma_handle_t *s_EDMAHandle[FSL_FEATURE_EDMA_MODULE_CHANNEL * FSL_FEATURE_SOC_EDMA_COUNT]; static edma_handle_t *s_EDMAHandle[FSL_FEATURE_EDMA_MODULE_CHANNEL * FSL_FEATURE_SOC_EDMA_COUNT];
@ -122,8 +129,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config)
uint32_t tmpreg; uint32_t tmpreg;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate EDMA periphral clock */ /* Ungate EDMA periphral clock */
CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]); CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure EDMA peripheral according to the configuration structure. */ /* Configure EDMA peripheral according to the configuration structure. */
tmpreg = base->CR; tmpreg = base->CR;
tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK);
@ -134,8 +143,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config)
void EDMA_Deinit(DMA_Type *base) void EDMA_Deinit(DMA_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate EDMA periphral clock */ /* Gate EDMA periphral clock */
CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void EDMA_GetDefaultConfig(edma_config_t *config) void EDMA_GetDefaultConfig(edma_config_t *config)
@ -409,46 +420,32 @@ void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask)
} }
} }
uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel) uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel)
{ {
assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL);
uint32_t nbytes = 0; uint32_t remainingCount = 0;
uint32_t remainingBytes = 0;
if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR) if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR)
{ {
remainingBytes = 0; remainingCount = 0;
} }
else else
{ {
/* Calculate the nbytes */
if (base->TCD[channel].NBYTES_MLOFFYES & (DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK))
{
nbytes = (base->TCD[channel].NBYTES_MLOFFYES & DMA_NBYTES_MLOFFYES_NBYTES_MASK) >>
DMA_NBYTES_MLOFFYES_NBYTES_SHIFT;
}
else
{
nbytes =
(base->TCD[channel].NBYTES_MLOFFNO & DMA_NBYTES_MLOFFNO_NBYTES_MASK) >> DMA_NBYTES_MLOFFNO_NBYTES_SHIFT;
}
/* Calculate the unfinished bytes */ /* Calculate the unfinished bytes */
if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK) if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK)
{ {
remainingBytes = ((base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> remainingCount =
DMA_CITER_ELINKYES_CITER_SHIFT) * (base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> DMA_CITER_ELINKYES_CITER_SHIFT;
nbytes;
} }
else else
{ {
remainingBytes = remainingCount =
((base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT) * (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT;
nbytes;
} }
} }
return remainingBytes; return remainingCount;
} }
uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel)
@ -503,8 +500,13 @@ void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel)
edmaInstance = EDMA_GetInstance(base); edmaInstance = EDMA_GetInstance(base);
channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel;
s_EDMAHandle[channelIndex] = handle; s_EDMAHandle[channelIndex] = handle;
#if defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT == 1U)
/* Enable NVIC interrupt */ /* Enable NVIC interrupt */
EnableIRQ(s_edmaIRQNumber[channelIndex]); EnableIRQ(s_edmaIRQNumber[channel]);
#elif defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 1U)
/* Enable NVIC interrupt */
EnableIRQ(s_edmaIRQNumber[edmaInstance][channel]);
#endif
/* /*
Reset TCD registers to zero. Unlike the EDMA_TcdReset(DREQ will be set), Reset TCD registers to zero. Unlike the EDMA_TcdReset(DREQ will be set),
CSR will be 0. Because in order to suit EDMA busy check mechanism in CSR will be 0. Because in order to suit EDMA busy check mechanism in
@ -558,8 +560,8 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config,
assert(config != NULL); assert(config != NULL);
assert(srcAddr != NULL); assert(srcAddr != NULL);
assert(destAddr != NULL); assert(destAddr != NULL);
assert(srcWidth == 1U || srcWidth == 2U || srcWidth == 4U || srcWidth == 16U || srcWidth == 32U); assert((srcWidth == 1U) || (srcWidth == 2U) || (srcWidth == 4U) || (srcWidth == 16U) || (srcWidth == 32U));
assert(destWidth == 1U || destWidth == 2U || destWidth == 4U || destWidth == 16U || destWidth == 32U); assert((destWidth == 1U) || (destWidth == 2U) || (destWidth == 4U) || (destWidth == 16U) || (destWidth == 32U));
assert(transferBytes % bytesEachRequest == 0); assert(transferBytes % bytesEachRequest == 0);
config->destAddr = (uint32_t)destAddr; config->destAddr = (uint32_t)destAddr;
@ -825,11 +827,11 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
/* Clear EDMA interrupt flag */ /* Clear EDMA interrupt flag */
handle->base->CINT = handle->channel; handle->base->CINT = handle->channel;
if (handle->tcdPool == NULL) if ((handle->tcdPool == NULL) && (handle->callback != NULL))
{ {
(handle->callback)(handle, handle->userData, true, 0); (handle->callback)(handle, handle->userData, true, 0);
} }
else /* Use the TCD queue. */ else /* Use the TCD queue. Please refer to the API descriptions in the eDMA header file for detailed information. */
{ {
uint32_t sga = handle->base->TCD[handle->channel].DLAST_SGA; uint32_t sga = handle->base->TCD[handle->channel].DLAST_SGA;
uint32_t sga_index; uint32_t sga_index;
@ -839,19 +841,19 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
/* Check if transfer is already finished. */ /* Check if transfer is already finished. */
transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0); transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0);
/* Get the offset of the current transfer TCD blcoks. */ /* Get the offset of the next transfer TCD blcoks to be loaded into the eDMA engine. */
sga -= (uint32_t)handle->tcdPool; sga -= (uint32_t)handle->tcdPool;
/* Get the index of the current transfer TCD blcoks. */ /* Get the index of the next transfer TCD blcoks to be loaded into the eDMA engine. */
sga_index = sga / sizeof(edma_tcd_t); sga_index = sga / sizeof(edma_tcd_t);
/* Adjust header positions. */ /* Adjust header positions. */
if (transfer_done) if (transfer_done)
{ {
/* New header shall point to the next TCD (current one is already finished) */ /* New header shall point to the next TCD to be loaded (current one is already finished) */
new_header = sga_index; new_header = sga_index;
} }
else else
{ {
/* New header shall point to this descriptor (not finished yet) */ /* New header shall point to this descriptor currently loaded (not finished yet) */
new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U; new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U;
} }
/* Calculate the number of finished TCDs */ /* Calculate the number of finished TCDs */
@ -863,7 +865,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
} }
else else
{ {
/* Internal error occurs. */ /* No TCD in the memory are going to be loaded or internal error occurs. */
tcds_done = 0; tcds_done = 0;
} }
} }
@ -875,9 +877,9 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
tcds_done += handle->tcdSize; tcds_done += handle->tcdSize;
} }
} }
/* Advance header to the point beyond the last finished TCD block. */ /* Advance header which points to the TCD to be loaded into the eDMA engine from memory. */
handle->header = new_header; handle->header = new_header;
/* Release TCD blocks. */ /* Release TCD blocks. tcdUsed is the TCD number which can be used/loaded in the memory pool. */
handle->tcdUsed -= tcds_done; handle->tcdUsed -= tcds_done;
/* Invoke callback function. */ /* Invoke callback function. */
if (handle->callback) if (handle->callback)
@ -937,12 +939,260 @@ void DMA0_37_DriverIRQHandler(void)
EDMA_HandleIRQ(s_EDMAHandle[7]); EDMA_HandleIRQ(s_EDMAHandle[7]);
} }
} }
#if defined(DMA1)
void DMA1_04_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[8]);
}
if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[12]);
}
}
void DMA1_15_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[9]);
}
if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[13]);
}
}
void DMA1_26_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[10]);
}
if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[14]);
}
}
void DMA1_37_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[11]);
}
if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[15]);
}
}
#endif
#endif /* 8 channels (Shared) */ #endif /* 8 channels (Shared) */
/* 16 channels (Shared): K32H844P */
#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 16U
void DMA0_08_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[0]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[8]);
}
}
void DMA0_19_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[1]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[9]);
}
}
void DMA0_210_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[2]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[10]);
}
}
void DMA0_311_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[3]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[11]);
}
}
void DMA0_412_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[4]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[12]);
}
}
void DMA0_513_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[5]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[13]);
}
}
void DMA0_614_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[6]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[14]);
}
}
void DMA0_715_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[7]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[15]);
}
}
#if defined(DMA1)
void DMA1_08_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[16]);
}
if ((EDMA_GetChannelStatusFlags(DMA1, 8U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[24]);
}
}
void DMA1_19_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[17]);
}
if ((EDMA_GetChannelStatusFlags(DMA1, 9U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[25]);
}
}
void DMA1_210_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[18]);
}
if ((EDMA_GetChannelStatusFlags(DMA1, 10U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[26]);
}
}
void DMA1_311_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[19]);
}
if ((EDMA_GetChannelStatusFlags(DMA1, 11U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[27]);
}
}
void DMA1_412_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[20]);
}
if ((EDMA_GetChannelStatusFlags(DMA1, 12U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[28]);
}
}
void DMA1_513_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[21]);
}
if ((EDMA_GetChannelStatusFlags(DMA1, 13U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[29]);
}
}
void DMA1_614_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[22]);
}
if ((EDMA_GetChannelStatusFlags(DMA1, 14U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[30]);
}
}
void DMA1_715_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[23]);
}
if ((EDMA_GetChannelStatusFlags(DMA1, 15U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[31]);
}
}
#endif
#endif /* 16 channels (Shared) */
/* 32 channels (Shared): k80 */ /* 32 channels (Shared): k80 */
#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U
void DMA0_DMA16_IRQHandler(void) void DMA0_DMA16_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -954,7 +1204,7 @@ void DMA0_DMA16_IRQHandler(void)
} }
} }
void DMA1_DMA17_IRQHandler(void) void DMA1_DMA17_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -966,7 +1216,7 @@ void DMA1_DMA17_IRQHandler(void)
} }
} }
void DMA2_DMA18_IRQHandler(void) void DMA2_DMA18_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -978,7 +1228,7 @@ void DMA2_DMA18_IRQHandler(void)
} }
} }
void DMA3_DMA19_IRQHandler(void) void DMA3_DMA19_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -990,7 +1240,7 @@ void DMA3_DMA19_IRQHandler(void)
} }
} }
void DMA4_DMA20_IRQHandler(void) void DMA4_DMA20_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1002,7 +1252,7 @@ void DMA4_DMA20_IRQHandler(void)
} }
} }
void DMA5_DMA21_IRQHandler(void) void DMA5_DMA21_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1014,7 +1264,7 @@ void DMA5_DMA21_IRQHandler(void)
} }
} }
void DMA6_DMA22_IRQHandler(void) void DMA6_DMA22_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1026,7 +1276,7 @@ void DMA6_DMA22_IRQHandler(void)
} }
} }
void DMA7_DMA23_IRQHandler(void) void DMA7_DMA23_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1038,7 +1288,7 @@ void DMA7_DMA23_IRQHandler(void)
} }
} }
void DMA8_DMA24_IRQHandler(void) void DMA8_DMA24_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1050,7 +1300,7 @@ void DMA8_DMA24_IRQHandler(void)
} }
} }
void DMA9_DMA25_IRQHandler(void) void DMA9_DMA25_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1062,7 +1312,7 @@ void DMA9_DMA25_IRQHandler(void)
} }
} }
void DMA10_DMA26_IRQHandler(void) void DMA10_DMA26_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1074,7 +1324,7 @@ void DMA10_DMA26_IRQHandler(void)
} }
} }
void DMA11_DMA27_IRQHandler(void) void DMA11_DMA27_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1086,7 +1336,7 @@ void DMA11_DMA27_IRQHandler(void)
} }
} }
void DMA12_DMA28_IRQHandler(void) void DMA12_DMA28_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1098,7 +1348,7 @@ void DMA12_DMA28_IRQHandler(void)
} }
} }
void DMA13_DMA29_IRQHandler(void) void DMA13_DMA29_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1110,7 +1360,7 @@ void DMA13_DMA29_IRQHandler(void)
} }
} }
void DMA14_DMA30_IRQHandler(void) void DMA14_DMA30_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1122,7 +1372,7 @@ void DMA14_DMA30_IRQHandler(void)
} }
} }
void DMA15_DMA31_IRQHandler(void) void DMA15_DMA31_DriverIRQHandler(void)
{ {
if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1135,6 +1385,202 @@ void DMA15_DMA31_IRQHandler(void)
} }
#endif /* 32 channels (Shared) */ #endif /* 32 channels (Shared) */
/* 32 channels (Shared): MCIMX7U5_M4 */
#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U
void DMA0_0_4_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[0]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[4]);
}
}
void DMA0_1_5_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[1]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[5]);
}
}
void DMA0_2_6_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[2]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[6]);
}
}
void DMA0_3_7_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[3]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[7]);
}
}
void DMA0_8_12_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[8]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[12]);
}
}
void DMA0_9_13_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[9]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[13]);
}
}
void DMA0_10_14_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[10]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[14]);
}
}
void DMA0_11_15_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[11]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[15]);
}
}
void DMA0_16_20_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[16]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[20]);
}
}
void DMA0_17_21_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[17]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[21]);
}
}
void DMA0_18_22_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[18]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[22]);
}
}
void DMA0_19_23_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[19]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[23]);
}
}
void DMA0_24_28_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[24]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[28]);
}
}
void DMA0_25_29_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[25]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[29]);
}
}
void DMA0_26_30_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[26]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[30]);
}
}
void DMA0_27_31_DriverIRQHandler(void)
{
if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[27]);
}
if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & kEDMA_InterruptFlag) != 0U)
{
EDMA_HandleIRQ(s_EDMAHandle[31]);
}
}
#endif /* 32 channels (Shared): MCIMX7U5 */
/* 4 channels (No Shared): kv10 */ /* 4 channels (No Shared): kv10 */
#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0 #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0

View File

@ -34,11 +34,10 @@
#include "fsl_common.h" #include "fsl_common.h"
/*! /*!
* @addtogroup edma_driver * @addtogroup edma
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
@ -46,7 +45,7 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief eDMA driver version */ /*! @brief eDMA driver version */
#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ #define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1. */
/*@}*/ /*@}*/
/*! @brief Compute the offset unit from DCHPRI3 */ /*! @brief Compute the offset unit from DCHPRI3 */
@ -78,28 +77,28 @@ typedef enum _edma_modulo
kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */ kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */
kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */ kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */
kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */ kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */
kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1K bytes. */ kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1 K bytes. */
kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2K bytes. */ kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2 K bytes. */
kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4K bytes. */ kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4 K bytes. */
kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8K bytes. */ kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8 K bytes. */
kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16K bytes. */ kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16 K bytes. */
kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32K bytes. */ kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32 K bytes. */
kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64K bytes. */ kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64 K bytes. */
kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128K bytes. */ kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128 K bytes. */
kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256K bytes. */ kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256 K bytes. */
kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512K bytes. */ kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512 K bytes. */
kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1M bytes. */ kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1 M bytes. */
kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2M bytes. */ kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2 M bytes. */
kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4M bytes. */ kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4 M bytes. */
kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8M bytes. */ kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8 M bytes. */
kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16M bytes. */ kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16 M bytes. */
kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32M bytes. */ kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32 M bytes. */
kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64M bytes. */ kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64 M bytes. */
kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128M bytes. */ kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128 M bytes. */
kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256M bytes. */ kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256 M bytes. */
kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512M bytes. */ kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512 M bytes. */
kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1G bytes. */ kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1 G bytes. */
kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2G bytes. */ kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2 G bytes. */
} edma_modulo_t; } edma_modulo_t;
/*! @brief Bandwidth control */ /*! @brief Bandwidth control */
@ -143,7 +142,7 @@ enum _edma_error_status_flags
#if defined(FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT) && FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 1 #if defined(FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT) && FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 1
kEDMA_GroupPriorityErrorFlag = DMA_ES_GPE_MASK, /*!< Group priority is not unique. */ kEDMA_GroupPriorityErrorFlag = DMA_ES_GPE_MASK, /*!< Group priority is not unique. */
#endif #endif
kEDMA_ValidFlag = DMA_ES_VLD_MASK, /*!< No error occurred, this bit will be 0, otherwise be 1 */ kEDMA_ValidFlag = DMA_ES_VLD_MASK, /*!< No error occurred, this bit is 0. Otherwise, it is 1. */
}; };
/*! @brief eDMA interrupt source */ /*! @brief eDMA interrupt source */
@ -178,7 +177,7 @@ typedef struct _edma_config
the link channel is itself. */ the link channel is itself. */
bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set.
Subsequently, all service requests are ignored until the HALT bit is cleared.*/ Subsequently, all service requests are ignored until the HALT bit is cleared.*/
bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method, or fixed priority bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method or fixed priority
arbitration is used for channel selection */ arbitration is used for channel selection */
bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of
a new channel. Executing channels are allowed to complete. */ a new channel. Executing channels are allowed to complete. */
@ -212,15 +211,15 @@ typedef struct _edma_transfer_config
form the next-state value as each source read is completed. */ form the next-state value as each source read is completed. */
int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to
form the next-state value as each destination write is completed. */ form the next-state value as each destination write is completed. */
uint16_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ uint32_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/
uint32_t majorLoopCounts; /*!< Major loop iteration count. */ uint32_t majorLoopCounts; /*!< Major loop iteration count. */
} edma_transfer_config_t; } edma_transfer_config_t;
/*! @brief eDMA channel priority configuration */ /*! @brief eDMA channel priority configuration */
typedef struct _edma_channel_Preemption_config typedef struct _edma_channel_Preemption_config
{ {
bool enableChannelPreemption; /*!< If true: channel can be suspended by other channel with higher priority */ bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */
bool enablePreemptAbility; /*!< If true: channel can suspend other channel with low priority */ bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */
uint8_t channelPriority; /*!< Channel priority */ uint8_t channelPriority; /*!< Channel priority */
} edma_channel_Preemption_config_t; } edma_channel_Preemption_config_t;
@ -229,14 +228,14 @@ typedef struct _edma_minor_offset_config
{ {
bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */ bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */
bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */ bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */
uint32_t minorOffset; /*!< Offset for minor loop mapping. */ uint32_t minorOffset; /*!< Offset for a minor loop mapping. */
} edma_minor_offset_config_t; } edma_minor_offset_config_t;
/*! /*!
* @brief eDMA TCD. * @brief eDMA TCD.
* *
* This structure is same as TCD register which is described in reference manual, * This structure is same as TCD register which is described in reference manual,
* and is used to configure scatter/gather feature as a next hardware TCD. * and is used to configure the scatter/gather feature as a next hardware TCD.
*/ */
typedef struct _edma_tcd typedef struct _edma_tcd
{ {
@ -256,20 +255,21 @@ typedef struct _edma_tcd
/*! @brief Callback for eDMA */ /*! @brief Callback for eDMA */
struct _edma_handle; struct _edma_handle;
/*! @brief Define Callback function for eDMA. */ /*! @brief Define callback function for eDMA. */
typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds); typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds);
/*! @brief eDMA transfer handle structure */ /*! @brief eDMA transfer handle structure */
typedef struct _edma_handle typedef struct _edma_handle
{ {
edma_callback callback; /*!< Callback function for major count exhausted. */ edma_callback callback; /*!< Callback function for major count exhausted. */
void *userData; /*!< Callback function parameter. */ void *userData; /*!< Callback function parameter. */
DMA_Type *base; /*!< eDMA peripheral base address. */ DMA_Type *base; /*!< eDMA peripheral base address. */
edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */
uint8_t channel; /*!< eDMA channel number. */ uint8_t channel; /*!< eDMA channel number. */
volatile int8_t header; /*!< The first TCD index. */ volatile int8_t header; /*!< The first TCD index. Should point to the next TCD to be loaded into the eDMA engine. */
volatile int8_t tail; /*!< The last TCD index. */ volatile int8_t tail; /*!< The last TCD index. Should point to the next TCD to be stored into the memory pool. */
volatile int8_t tcdUsed; /*!< The number of used TCD slots. */ volatile int8_t tcdUsed; /*!< The number of used TCD slots. Should reflect the number of TCDs can be used/loaded in
the memory. */
volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */ volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */
uint8_t flags; /*!< The status of the current channel. */ uint8_t flags; /*!< The status of the current channel. */
} edma_handle_t; } edma_handle_t;
@ -282,24 +282,24 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/*! /*!
* @name eDMA initialization and De-initialization * @name eDMA initialization and de-initialization
* @{ * @{
*/ */
/*! /*!
* @brief Initializes eDMA peripheral. * @brief Initializes the eDMA peripheral.
* *
* This function ungates the eDMA clock and configure eDMA peripheral according * This function ungates the eDMA clock and configures the eDMA peripheral according
* to the configuration structure. * to the configuration structure.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param config Pointer to configuration structure, see "edma_config_t". * @param config A pointer to the configuration structure, see "edma_config_t".
* @note This function enable the minor loop map feature. * @note This function enables the minor loop map feature.
*/ */
void EDMA_Init(DMA_Type *base, const edma_config_t *config); void EDMA_Init(DMA_Type *base, const edma_config_t *config);
/*! /*!
* @brief Deinitializes eDMA peripheral. * @brief Deinitializes the eDMA peripheral.
* *
* This function gates the eDMA clock. * This function gates the eDMA clock.
* *
@ -310,8 +310,8 @@ void EDMA_Deinit(DMA_Type *base);
/*! /*!
* @brief Gets the eDMA default configuration structure. * @brief Gets the eDMA default configuration structure.
* *
* This function sets the configuration structure to a default value. * This function sets the configuration structure to default values.
* The default configuration is set to the following value: * The default configuration is set to the following values.
* @code * @code
* config.enableContinuousLinkMode = false; * config.enableContinuousLinkMode = false;
* config.enableHaltOnError = true; * config.enableHaltOnError = true;
@ -319,7 +319,7 @@ void EDMA_Deinit(DMA_Type *base);
* config.enableDebugMode = false; * config.enableDebugMode = false;
* @endcode * @endcode
* *
* @param config Pointer to eDMA configuration structure. * @param config A pointer to the eDMA configuration structure.
*/ */
void EDMA_GetDefaultConfig(edma_config_t *config); void EDMA_GetDefaultConfig(edma_config_t *config);
@ -330,22 +330,22 @@ void EDMA_GetDefaultConfig(edma_config_t *config);
*/ */
/*! /*!
* @brief Sets all TCD registers to a default value. * @brief Sets all TCD registers to default values.
* *
* This function sets TCD registers for this channel to default value. * This function sets TCD registers for this channel to default values.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @note This function must not be called while the channel transfer is on-going, * @note This function must not be called while the channel transfer is ongoing
* or it will case unpredicated results. * or it causes unpredictable results.
* @note This function will enable auto stop request feature. * @note This function enables the auto stop request feature.
*/ */
void EDMA_ResetChannel(DMA_Type *base, uint32_t channel); void EDMA_ResetChannel(DMA_Type *base, uint32_t channel);
/*! /*!
* @brief Configures the eDMA transfer attribute. * @brief Configures the eDMA transfer attribute.
* *
* This function configure the transfer attribute, including source address, destination address, * This function configures the transfer attribute, including source address, destination address,
* transfer size, address offset, and so on. It also configures the scatter gather feature if the * transfer size, address offset, and so on. It also configures the scatter gather feature if the
* user supplies the TCD address. * user supplies the TCD address.
* Example: * Example:
@ -361,11 +361,11 @@ void EDMA_ResetChannel(DMA_Type *base, uint32_t channel);
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param config Pointer to eDMA transfer configuration structure. * @param config Pointer to eDMA transfer configuration structure.
* @param nextTcd Point to TCD structure. It can be NULL if user * @param nextTcd Point to TCD structure. It can be NULL if users
* do not want to enable scatter/gather feature. * do not want to enable scatter/gather feature.
* @note If nextTcd is not NULL, it means scatter gather feature will be enabled. * @note If nextTcd is not NULL, it means scatter gather feature is enabled
* And DREQ bit will be cleared in the previous transfer configuration which * and DREQ bit is cleared in the previous transfer configuration, which
* will be set in eDMA_ResetChannel. * is set in the eDMA_ResetChannel.
*/ */
void EDMA_SetTransferConfig(DMA_Type *base, void EDMA_SetTransferConfig(DMA_Type *base,
uint32_t channel, uint32_t channel,
@ -375,12 +375,12 @@ void EDMA_SetTransferConfig(DMA_Type *base,
/*! /*!
* @brief Configures the eDMA minor offset feature. * @brief Configures the eDMA minor offset feature.
* *
* Minor offset means signed-extended value added to source address or destination * The minor offset means that the signed-extended value is added to the source address or destination
* address after each minor loop. * address after each minor loop.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param config Pointer to Minor offset configuration structure. * @param config A pointer to the minor offset configuration structure.
*/ */
void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config); void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config);
@ -391,7 +391,7 @@ void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_mino
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number * @param channel eDMA channel number
* @param config Pointer to channel preemption configuration structure. * @param config A pointer to the channel preemption configuration structure.
*/ */
static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base,
uint32_t channel, uint32_t channel,
@ -408,30 +408,31 @@ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base,
/*! /*!
* @brief Sets the channel link for the eDMA transfer. * @brief Sets the channel link for the eDMA transfer.
* *
* This function configures minor link or major link mode. The minor link means that the channel link is * This function configures either the minor link or the major link mode. The minor link means that the channel link is
* triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is exhausted. * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is
* exhausted.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param type Channel link type, it can be one of: * @param type A channel link type, which can be one of the following:
* @arg kEDMA_LinkNone * @arg kEDMA_LinkNone
* @arg kEDMA_MinorLink * @arg kEDMA_MinorLink
* @arg kEDMA_MajorLink * @arg kEDMA_MajorLink
* @param linkedChannel The linked channel number. * @param linkedChannel The linked channel number.
* @note User should ensure that DONE flag is cleared before call this interface, or the configuration will be invalid. * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid.
*/ */
void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel); void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel);
/*! /*!
* @brief Sets the bandwidth for the eDMA transfer. * @brief Sets the bandwidth for the eDMA transfer.
* *
* In general, because the eDMA processes the minor loop, it continuously generates read/write sequences * Because the eDMA processes the minor loop, it continuously generates read/write sequences
* until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of
* each read/write access to control the bus request bandwidth seen by the crossbar switch. * each read/write access to control the bus request bandwidth seen by the crossbar switch.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param bandWidth Bandwidth setting, it can be one of: * @param bandWidth A bandwidth setting, which can be one of the following:
* @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStallNone
* @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall4Cycle
* @arg kEDMABandwidthStall8Cycle * @arg kEDMABandwidthStall8Cycle
@ -439,7 +440,7 @@ void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_typ
void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth); void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth);
/*! /*!
* @brief Sets the source modulo and destination modulo for eDMA transfer. * @brief Sets the source modulo and the destination modulo for the eDMA transfer.
* *
* This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF)
* calculation is performed or the original register value. It provides the ability to implement a circular data * calculation is performed or the original register value. It provides the ability to implement a circular data
@ -447,8 +448,8 @@ void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWi
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param srcModulo Source modulo value. * @param srcModulo A source modulo value.
* @param destModulo Destination modulo value. * @param destModulo A destination modulo value.
*/ */
void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo); void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo);
@ -458,7 +459,7 @@ void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, e
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param enable The command for enable(ture) or disable(false). * @param enable The command to enable (true) or disable (false).
*/ */
static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable) static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable)
{ {
@ -475,7 +476,7 @@ static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, boo
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param enable The command for enable (true) or disable (false). * @param enable The command to enable (true) or disable (false).
*/ */
static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable) static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable)
{ {
@ -489,7 +490,7 @@ static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel,
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param mask The mask of interrupt source to be set. User need to use * @param mask The mask of interrupt source to be set. Users need to use
* the defined edma_interrupt_enable_t type. * the defined edma_interrupt_enable_t type.
*/ */
void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask);
@ -499,7 +500,7 @@ void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mas
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param mask The mask of interrupt source to be set. Use * @param mask The mask of the interrupt source to be set. Use
* the defined edma_interrupt_enable_t type. * the defined edma_interrupt_enable_t type.
*/ */
void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask);
@ -516,15 +517,15 @@ void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t ma
* This function sets all fields for this TCD structure to default value. * This function sets all fields for this TCD structure to default value.
* *
* @param tcd Pointer to the TCD structure. * @param tcd Pointer to the TCD structure.
* @note This function will enable auto stop request feature. * @note This function enables the auto stop request feature.
*/ */
void EDMA_TcdReset(edma_tcd_t *tcd); void EDMA_TcdReset(edma_tcd_t *tcd);
/*! /*!
* @brief Configures the eDMA TCD transfer attribute. * @brief Configures the eDMA TCD transfer attribute.
* *
* TCD is a transfer control descriptor. The content of the TCD is the same as hardware TCD registers. * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers.
* STCD is used in scatter-gather mode. * The STCD is used in the scatter-gather mode.
* This function configures the TCD transfer attribute, including source address, destination address, * This function configures the TCD transfer attribute, including source address, destination address,
* transfer size, address offset, and so on. It also configures the scatter gather feature if the * transfer size, address offset, and so on. It also configures the scatter gather feature if the
* user supplies the next TCD address. * user supplies the next TCD address.
@ -540,33 +541,34 @@ void EDMA_TcdReset(edma_tcd_t *tcd);
* *
* @param tcd Pointer to the TCD structure. * @param tcd Pointer to the TCD structure.
* @param config Pointer to eDMA transfer configuration structure. * @param config Pointer to eDMA transfer configuration structure.
* @param nextTcd Pointer to the next TCD structure. It can be NULL if user * @param nextTcd Pointer to the next TCD structure. It can be NULL if users
* do not want to enable scatter/gather feature. * do not want to enable scatter/gather feature.
* @note TCD address should be 32 bytes aligned, or it will cause eDMA error. * @note TCD address should be 32 bytes aligned or it causes an eDMA error.
* @note If nextTcd is not NULL, it means scatter gather feature will be enabled. * @note If the nextTcd is not NULL, the scatter gather feature is enabled
* And DREQ bit will be cleared in the previous transfer configuration which * and DREQ bit is cleared in the previous transfer configuration, which
* will be set in EDMA_TcdReset. * is set in the EDMA_TcdReset.
*/ */
void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd); void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd);
/*! /*!
* @brief Configures the eDMA TCD minor offset feature. * @brief Configures the eDMA TCD minor offset feature.
* *
* Minor offset is a signed-extended value added to the source address or destination * A minor offset is a signed-extended value added to the source address or a destination
* address after each minor loop. * address after each minor loop.
* *
* @param tcd Point to the TCD structure. * @param tcd A point to the TCD structure.
* @param config Pointer to Minor offset configuration structure. * @param config A pointer to the minor offset configuration structure.
*/ */
void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config); void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config);
/*! /*!
* @brief Sets the channel link for eDMA TCD. * @brief Sets the channel link for the eDMA TCD.
* *
* This function configures either a minor link or a major link. The minor link means the channel link is * This function configures either a minor link or a major link. The minor link means the channel link is
* triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is exhausted. * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is
* exhausted.
* *
* @note User should ensure that DONE flag is cleared before call this interface, or the configuration will be invalid. * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid.
* @param tcd Point to the TCD structure. * @param tcd Point to the TCD structure.
* @param type Channel link type, it can be one of: * @param type Channel link type, it can be one of:
* @arg kEDMA_LinkNone * @arg kEDMA_LinkNone
@ -579,11 +581,11 @@ void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint
/*! /*!
* @brief Sets the bandwidth for the eDMA TCD. * @brief Sets the bandwidth for the eDMA TCD.
* *
* In general, because the eDMA processes the minor loop, it continuously generates read/write sequences * Because the eDMA processes the minor loop, it continuously generates read/write sequences
* until the minor count is exhausted. Bandwidth forces the eDMA to stall after the completion of * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of
* each read/write access to control the bus request bandwidth seen by the crossbar switch. * each read/write access to control the bus request bandwidth seen by the crossbar switch.
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param bandWidth Bandwidth setting, it can be one of: * @param bandWidth A bandwidth setting, which can be one of the following:
* @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStallNone
* @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall4Cycle
* @arg kEDMABandwidthStall8Cycle * @arg kEDMABandwidthStall8Cycle
@ -597,15 +599,15 @@ static inline void EDMA_TcdSetBandWidth(edma_tcd_t *tcd, edma_bandwidth_t bandWi
} }
/*! /*!
* @brief Sets the source modulo and destination modulo for eDMA TCD. * @brief Sets the source modulo and the destination modulo for the eDMA TCD.
* *
* This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF)
* calculation is performed or the original register value. It provides the ability to implement a circular data * calculation is performed or the original register value. It provides the ability to implement a circular data
* queue easily. * queue easily.
* *
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param srcModulo Source modulo value. * @param srcModulo A source modulo value.
* @param destModulo Destination modulo value. * @param destModulo A destination modulo value.
*/ */
void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo);
@ -614,8 +616,8 @@ void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t d
* *
* If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request. * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request.
* *
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param enable The command for enable(ture) or disable(false). * @param enable The command to enable (true) or disable (false).
*/ */
static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable)
{ {
@ -629,7 +631,7 @@ static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable)
* @brief Enables the interrupt source for the eDMA TCD. * @brief Enables the interrupt source for the eDMA TCD.
* *
* @param tcd Point to the TCD structure. * @param tcd Point to the TCD structure.
* @param mask The mask of interrupt source to be set. User need to use * @param mask The mask of interrupt source to be set. Users need to use
* the defined edma_interrupt_enable_t type. * the defined edma_interrupt_enable_t type.
*/ */
void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask); void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask);
@ -638,7 +640,7 @@ void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask);
* @brief Disables the interrupt source for the eDMA TCD. * @brief Disables the interrupt source for the eDMA TCD.
* *
* @param tcd Point to the TCD structure. * @param tcd Point to the TCD structure.
* @param mask The mask of interrupt source to be set. User need to use * @param mask The mask of interrupt source to be set. Users need to use
* the defined edma_interrupt_enable_t type. * the defined edma_interrupt_enable_t type.
*/ */
void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask); void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask);
@ -680,7 +682,7 @@ static inline void EDMA_DisableChannelRequest(DMA_Type *base, uint32_t channel)
} }
/*! /*!
* @brief Starts the eDMA transfer by software trigger. * @brief Starts the eDMA transfer by using the software trigger.
* *
* This function starts a minor loop transfer. * This function starts a minor loop transfer.
* *
@ -701,25 +703,34 @@ static inline void EDMA_TriggerChannelStart(DMA_Type *base, uint32_t channel)
*/ */
/*! /*!
* @brief Gets the Remaining bytes from the eDMA current channel TCD. * @brief Gets the remaining major loop count from the eDMA current channel TCD.
* *
* This function checks the TCD (Task Control Descriptor) status for a specified * This function checks the TCD (Task Control Descriptor) status for a specified
* eDMA channel and returns the the number of bytes that have not finished. * eDMA channel and returns the the number of major loop count that has not finished.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @return Bytes have not been transferred yet for the current TCD. * @return Major loop count which has not been transferred yet for the current TCD.
* @note This function can only be used to get unfinished bytes of transfer without * @note 1. This function can only be used to get unfinished major loop count of transfer without
* the next TCD, or it might be inaccuracy. * the next TCD, or it might be inaccuracy.
* 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while
* the channel is running.
* Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO
* register is needed while the eDMA IP does not support getting it while a channel is active.
* In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine
* is working with while a channel is running.
* Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example
* copied before enabling the channel) is needed. The formula to calculate it is shown below:
* RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured)
*/ */
uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel); uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel);
/*! /*!
* @brief Gets the eDMA channel error status flags. * @brief Gets the eDMA channel error status flags.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @return The mask of error status flags. User need to use the * @return The mask of error status flags. Users need to use the
* _edma_error_status_flags type to decode the return variables. * _edma_error_status_flags type to decode the return variables.
*/ */
static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base) static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base)
{ {
@ -731,7 +742,7 @@ static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base)
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @return The mask of channel status flags. User need to use the * @return The mask of channel status flags. Users need to use the
* _edma_channel_status_flags type to decode the return variables. * _edma_channel_status_flags type to decode the return variables.
*/ */
uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel); uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel);
@ -741,7 +752,7 @@ uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel);
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param mask The mask of channel status to be cleared. User need to use * @param mask The mask of channel status to be cleared. Users need to use
* the defined _edma_channel_status_flags type. * the defined _edma_channel_status_flags type.
*/ */
void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask); void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask);
@ -754,8 +765,8 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas
/*! /*!
* @brief Creates the eDMA handle. * @brief Creates the eDMA handle.
* *
* This function is called if using transaction API for eDMA. This function * This function is called if using the transactional API for eDMA. This function
* initializes the internal state of eDMA handle. * initializes the internal state of the eDMA handle.
* *
* @param handle eDMA handle pointer. The eDMA handle stores callback function and * @param handle eDMA handle pointer. The eDMA handle stores callback function and
* parameters. * parameters.
@ -765,12 +776,12 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas
void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel); void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel);
/*! /*!
* @brief Installs the TCDs memory pool into eDMA handle. * @brief Installs the TCDs memory pool into the eDMA handle.
* *
* This function is called after the EDMA_CreateHandle to use scatter/gather feature. * This function is called after the EDMA_CreateHandle to use scatter/gather feature.
* *
* @param handle eDMA handle pointer. * @param handle eDMA handle pointer.
* @param tcdPool Memory pool to store TCDs. It must be 32 bytes aligned. * @param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned.
* @param tcdSize The number of TCD slots. * @param tcdSize The number of TCD slots.
*/ */
void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize);
@ -778,12 +789,12 @@ void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t
/*! /*!
* @brief Installs a callback function for the eDMA transfer. * @brief Installs a callback function for the eDMA transfer.
* *
* This callback is called in eDMA IRQ handler. Use the callback to do something after * This callback is called in the eDMA IRQ handler. Use the callback to do something after
* the current major loop transfer completes. * the current major loop transfer completes.
* *
* @param handle eDMA handle pointer. * @param handle eDMA handle pointer.
* @param callback eDMA callback function pointer. * @param callback eDMA callback function pointer.
* @param userData Parameter for callback function. * @param userData A parameter for the callback function.
*/ */
void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData); void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData);
@ -801,8 +812,8 @@ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userD
* @param transferBytes eDMA transfer bytes to be transferred. * @param transferBytes eDMA transfer bytes to be transferred.
* @param type eDMA transfer type. * @param type eDMA transfer type.
* @note The data address and the data width must be consistent. For example, if the SRC * @note The data address and the data width must be consistent. For example, if the SRC
* is 4 bytes, so the source address must be 4 bytes aligned, or it shall result in * is 4 bytes, the source address must be 4 bytes aligned, or it results in
* source address error(SAE). * source address error (SAE).
*/ */
void EDMA_PrepareTransfer(edma_transfer_config_t *config, void EDMA_PrepareTransfer(edma_transfer_config_t *config,
void *srcAddr, void *srcAddr,
@ -817,7 +828,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config,
* @brief Submits the eDMA transfer request. * @brief Submits the eDMA transfer request.
* *
* This function submits the eDMA transfer request according to the transfer configuration structure. * This function submits the eDMA transfer request according to the transfer configuration structure.
* If the user submits the transfer request repeatedly, this function packs an unprocessed request as * If submitting the transfer request repeatedly, this function packs an unprocessed request as
* a TCD and enables scatter/gather feature to process it in the next time. * a TCD and enables scatter/gather feature to process it in the next time.
* *
* @param handle eDMA handle pointer. * @param handle eDMA handle pointer.
@ -829,9 +840,9 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config,
status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config); status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config);
/*! /*!
* @brief eDMA start transfer. * @brief eDMA starts transfer.
* *
* This function enables the channel request. User can call this function after submitting the transfer request * This function enables the channel request. Users can call this function after submitting the transfer request
* or before submitting the transfer request. * or before submitting the transfer request.
* *
* @param handle eDMA handle pointer. * @param handle eDMA handle pointer.
@ -839,9 +850,9 @@ status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t
void EDMA_StartTransfer(edma_handle_t *handle); void EDMA_StartTransfer(edma_handle_t *handle);
/*! /*!
* @brief eDMA stop transfer. * @brief eDMA stops transfer.
* *
* This function disables the channel request to pause the transfer. User can call EDMA_StartTransfer() * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer()
* again to resume the transfer. * again to resume the transfer.
* *
* @param handle eDMA handle pointer. * @param handle eDMA handle pointer.
@ -849,21 +860,41 @@ void EDMA_StartTransfer(edma_handle_t *handle);
void EDMA_StopTransfer(edma_handle_t *handle); void EDMA_StopTransfer(edma_handle_t *handle);
/*! /*!
* @brief eDMA abort transfer. * @brief eDMA aborts transfer.
* *
* This function disables the channel request and clear transfer status bits. * This function disables the channel request and clear transfer status bits.
* User can submit another transfer after calling this API. * Users can submit another transfer after calling this API.
* *
* @param handle DMA handle pointer. * @param handle DMA handle pointer.
*/ */
void EDMA_AbortTransfer(edma_handle_t *handle); void EDMA_AbortTransfer(edma_handle_t *handle);
/*! /*!
* @brief eDMA IRQ handler for current major loop transfer complete. * @brief eDMA IRQ handler for the current major loop transfer completion.
* *
* This function clears the channel major interrupt flag and call * This function clears the channel major interrupt flag and calls
* the callback function if it is not NULL. * the callback function if it is not NULL.
* *
* Note:
* For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed.
* These include the final address adjustments and reloading of the BITER field into the CITER.
* Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from
* memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled).
*
* For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine.
* As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index
* in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be
* (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have
* been loaded into the eDMA engine at this point already.).
*
* For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not
* load a new TCD) from the memory pool to the eDMA engine when major loop completes.
* Therefore, ensure that the header and tcdUsed updated are identical for them.
* tcdUsed are both 0 in this case as no TCD to be loaded.
*
* See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for
* further details.
*
* @param handle eDMA handle pointer. * @param handle eDMA handle pointer.
*/ */
void EDMA_HandleIRQ(edma_handle_t *handle); void EDMA_HandleIRQ(edma_handle_t *handle);

View File

@ -106,6 +106,8 @@
#define ENET_NTOHS(n) __REV16(n) #define ENET_NTOHS(n) __REV16(n)
#define ENET_NTOHL(n) __REV(n) #define ENET_NTOHL(n) __REV(n)
/* Typedef for interrupt handler. */
typedef void (*enet_isr_t)(ENET_Type *base, enet_handle_t *handle);
/******************************************************************************* /*******************************************************************************
* Prototypes * Prototypes
******************************************************************************/ ******************************************************************************/
@ -225,23 +227,29 @@ static status_t ENET_StoreRxFrameTime(ENET_Type *base, enet_handle_t *handle, en
/*! @brief Pointers to enet handles for each instance. */ /*! @brief Pointers to enet handles for each instance. */
static enet_handle_t *s_ENETHandle[FSL_FEATURE_SOC_ENET_COUNT] = {NULL}; static enet_handle_t *s_ENETHandle[FSL_FEATURE_SOC_ENET_COUNT] = {NULL};
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to enet clocks for each instance. */ /*! @brief Pointers to enet clocks for each instance. */
const clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT] = ENET_CLOCKS; const clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT] = ENET_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*! @brief Pointers to enet transmit IRQ number for each instance. */ /*! @brief Pointers to enet transmit IRQ number for each instance. */
const IRQn_Type s_enetTxIrqId[] = ENET_Transmit_IRQS; static const IRQn_Type s_enetTxIrqId[] = ENET_Transmit_IRQS;
/*! @brief Pointers to enet receive IRQ number for each instance. */ /*! @brief Pointers to enet receive IRQ number for each instance. */
const IRQn_Type s_enetRxIrqId[] = ENET_Receive_IRQS; static const IRQn_Type s_enetRxIrqId[] = ENET_Receive_IRQS;
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE #if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
/*! @brief Pointers to enet timestamp IRQ number for each instance. */ /*! @brief Pointers to enet timestamp IRQ number for each instance. */
const IRQn_Type s_enetTsIrqId[] = ENET_1588_Timer_IRQS; static const IRQn_Type s_enetTsIrqId[] = ENET_1588_Timer_IRQS;
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
/*! @brief Pointers to enet error IRQ number for each instance. */ /*! @brief Pointers to enet error IRQ number for each instance. */
const IRQn_Type s_enetErrIrqId[] = ENET_Error_IRQS; static const IRQn_Type s_enetErrIrqId[] = ENET_Error_IRQS;
/*! @brief Pointers to enet bases for each instance. */ /*! @brief Pointers to enet bases for each instance. */
static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS; static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS;
/* ENET ISR for transactional APIs. */
static enet_isr_t s_enetTxIsr;
static enet_isr_t s_enetRxIsr;
static enet_isr_t s_enetErrIsr;
/******************************************************************************* /*******************************************************************************
* Code * Code
******************************************************************************/ ******************************************************************************/
@ -299,8 +307,10 @@ void ENET_Init(ENET_Type *base,
uint32_t instance = ENET_GetInstance(base); uint32_t instance = ENET_GetInstance(base);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate ENET clock. */ /* Ungate ENET clock. */
CLOCK_EnableClock(s_enetClock[instance]); CLOCK_EnableClock(s_enetClock[instance]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Reset ENET module. */ /* Reset ENET module. */
ENET_Reset(base); ENET_Reset(base);
@ -312,7 +322,7 @@ void ENET_Init(ENET_Type *base,
/* Initializes the ENET receive buffer descriptors. */ /* Initializes the ENET receive buffer descriptors. */
ENET_SetRxBufferDescriptors(bufferConfig->rxBdStartAddrAlign, bufferConfig->rxBufferAlign, ENET_SetRxBufferDescriptors(bufferConfig->rxBdStartAddrAlign, bufferConfig->rxBufferAlign,
bufferConfig->rxBuffSizeAlign, bufferConfig->rxBdNumber, bufferConfig->rxBuffSizeAlign, bufferConfig->rxBdNumber,
!!(config->interrupt & (kENET_RxFrameInterrupt | kENET_RxByteInterrupt))); !!(config->interrupt & (kENET_RxFrameInterrupt | kENET_RxBufferInterrupt)));
/* Initializes the ENET MAC controller. */ /* Initializes the ENET MAC controller. */
ENET_SetMacController(base, config, bufferConfig, macAddr, srcClock_Hz); ENET_SetMacController(base, config, bufferConfig, macAddr, srcClock_Hz);
@ -323,7 +333,6 @@ void ENET_Init(ENET_Type *base,
/* Store transfer parameters in handle pointer. */ /* Store transfer parameters in handle pointer. */
handle->rxBdBase = bufferConfig->rxBdStartAddrAlign; handle->rxBdBase = bufferConfig->rxBdStartAddrAlign;
handle->rxBdCurrent = bufferConfig->rxBdStartAddrAlign; handle->rxBdCurrent = bufferConfig->rxBdStartAddrAlign;
handle->rxBdDirty = bufferConfig->rxBdStartAddrAlign;
handle->txBdBase = bufferConfig->txBdStartAddrAlign; handle->txBdBase = bufferConfig->txBdStartAddrAlign;
handle->txBdCurrent = bufferConfig->txBdStartAddrAlign; handle->txBdCurrent = bufferConfig->txBdStartAddrAlign;
handle->txBdDirty = bufferConfig->txBdStartAddrAlign; handle->txBdDirty = bufferConfig->txBdStartAddrAlign;
@ -332,6 +341,14 @@ void ENET_Init(ENET_Type *base,
/* Save the handle pointer in the global variables. */ /* Save the handle pointer in the global variables. */
s_ENETHandle[instance] = handle; s_ENETHandle[instance] = handle;
/* Set the IRQ handler when the interrupt is enabled. */
if (config->interrupt)
{
s_enetTxIsr = ENET_TransmitIRQHandler;
s_enetRxIsr = ENET_ReceiveIRQHandler;
s_enetErrIsr = ENET_ErrorIRQHandler;
}
} }
void ENET_Deinit(ENET_Type *base) void ENET_Deinit(ENET_Type *base)
@ -342,8 +359,10 @@ void ENET_Deinit(ENET_Type *base)
/* Disable ENET. */ /* Disable ENET. */
base->ECR &= ~ENET_ECR_ETHEREN_MASK; base->ECR &= ~ENET_ECR_ETHEREN_MASK;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disables the clock source. */ /* Disables the clock source. */
CLOCK_DisableClock(s_enetClock[ENET_GetInstance(base)]); CLOCK_DisableClock(s_enetClock[ENET_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void ENET_SetCallback(enet_handle_t *handle, enet_callback_t callback, void *userData) void ENET_SetCallback(enet_handle_t *handle, enet_callback_t callback, void *userData)
@ -452,11 +471,11 @@ static void ENET_SetMacController(ENET_Type *base,
/* Enables Ethernet interrupt and NVIC. */ /* Enables Ethernet interrupt and NVIC. */
ENET_EnableInterrupts(base, config->interrupt); ENET_EnableInterrupts(base, config->interrupt);
if (config->interrupt & (kENET_RxByteInterrupt | kENET_RxFrameInterrupt)) if (config->interrupt & (kENET_RxBufferInterrupt | kENET_RxFrameInterrupt))
{ {
EnableIRQ(s_enetRxIrqId[instance]); EnableIRQ(s_enetRxIrqId[instance]);
} }
if (config->interrupt & (kENET_TxByteInterrupt | kENET_TxFrameInterrupt)) if (config->interrupt & (kENET_TxBufferInterrupt | kENET_TxFrameInterrupt))
{ {
EnableIRQ(s_enetTxIrqId[instance]); EnableIRQ(s_enetTxIrqId[instance]);
} }
@ -744,13 +763,15 @@ status_t ENET_GetRxFrameSize(enet_handle_t *handle, uint32_t *length)
assert(handle->rxBdCurrent); assert(handle->rxBdCurrent);
assert(length); assert(length);
/* Reset the length to zero. */
*length = 0;
uint16_t validLastMask = ENET_BUFFDESCRIPTOR_RX_LAST_MASK | ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; uint16_t validLastMask = ENET_BUFFDESCRIPTOR_RX_LAST_MASK | ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent; volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent;
/* Check the current buffer descriptor's empty flag. if empty means there is no frame received. */ /* Check the current buffer descriptor's empty flag. if empty means there is no frame received. */
if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK) if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK)
{ {
*length = 0;
return kStatus_ENET_RxFrameEmpty; return kStatus_ENET_RxFrameEmpty;
} }
@ -766,7 +787,6 @@ status_t ENET_GetRxFrameSize(enet_handle_t *handle, uint32_t *length)
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
) )
{ {
*length = 0;
return kStatus_ENET_RxFrameError; return kStatus_ENET_RxFrameError;
} }
/* FCS is removed by MAC. */ /* FCS is removed by MAC. */
@ -796,8 +816,9 @@ status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u
uint32_t len = 0; uint32_t len = 0;
uint32_t offset = 0; uint32_t offset = 0;
uint16_t control;
bool isLastBuff = false; bool isLastBuff = false;
volatile enet_rx_bd_struct_t *curBuffDescrip; volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent;
status_t result = kStatus_Success; status_t result = kStatus_Success;
/* For data-NULL input, only update the buffer descriptor. */ /* For data-NULL input, only update the buffer descriptor. */
@ -805,37 +826,24 @@ status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u
{ {
do do
{ {
/* Get the current buffer descriptor. */ /* Update the control flag. */
curBuffDescrip = handle->rxBdCurrent; control = handle->rxBdCurrent->control;
/* Increase current buffer descriptor to the next one. */ /* Updates the receive buffer descriptors. */
if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK) ENET_UpdateReadBuffers(base, handle);
{
handle->rxBdCurrent = handle->rxBdBase;
}
else
{
handle->rxBdCurrent++;
}
/* The last buffer descriptor of a frame. */ /* Find the last buffer descriptor for the frame. */
if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK) if (control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
{ {
/* Find the last buffer descriptor for the frame*/
break; break;
} }
} while (handle->rxBdCurrent != handle->rxBdDirty);
/* Update all receive buffer descriptors for the whole frame. */ } while (handle->rxBdCurrent != curBuffDescrip);
ENET_UpdateReadBuffers(base, handle);
return result; return result;
} }
else else
{ {
/* Frame read from the MAC to user buffer and update the buffer descriptors. /* A frame on one buffer or several receive buffers are both considered. */
Process the frame, a frame on several receive buffers are considered . */
/* Get the current buffer descriptor. */
curBuffDescrip = handle->rxBdCurrent;
#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
enet_ptp_time_data_t ptpTimestamp; enet_ptp_time_data_t ptpTimestamp;
bool isPtpEventMessage = false; bool isPtpEventMessage = false;
@ -846,16 +854,6 @@ status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u
while (!isLastBuff) while (!isLastBuff)
{ {
/* Increase current buffer descriptor to the next one. */
if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
{
handle->rxBdCurrent = handle->rxBdBase;
}
else
{
handle->rxBdCurrent++;
}
/* The last buffer descriptor of a frame. */ /* The last buffer descriptor of a frame. */
if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK) if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
{ {
@ -875,28 +873,39 @@ status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u
result = ENET_StoreRxFrameTime(base, handle, &ptpTimestamp); result = ENET_StoreRxFrameTime(base, handle, &ptpTimestamp);
} }
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
/* Updates the receive buffer descriptors. */
ENET_UpdateReadBuffers(base, handle); ENET_UpdateReadBuffers(base, handle);
return result; return result;
} }
else
{
/* Updates the receive buffer descriptors. */
ENET_UpdateReadBuffers(base, handle);
}
} }
else else
{ {
/* Store the fragments of a frame on several buffer descriptors. */ /* Store a frame on several buffer descriptors. */
isLastBuff = false; isLastBuff = false;
memcpy(data + offset, curBuffDescrip->buffer, handle->rxBuffSizeAlign); /* Length check. */
offset += handle->rxBuffSizeAlign;
if (offset >= length) if (offset >= length)
{ {
break; break;
} }
memcpy(data + offset, curBuffDescrip->buffer, handle->rxBuffSizeAlign);
offset += handle->rxBuffSizeAlign;
/* Updates the receive buffer descriptors. */
ENET_UpdateReadBuffers(base, handle);
} }
/* Get the current buffer descriptor. */ /* Get the current buffer descriptor. */
curBuffDescrip = handle->rxBdCurrent; curBuffDescrip = handle->rxBdCurrent;
} }
/* All error happens will break the while loop and arrive here to update receive buffers. */
ENET_UpdateReadBuffers(base, handle);
} }
return kStatus_ENET_RxFrameFail; return kStatus_ENET_RxFrameFail;
} }
@ -904,26 +913,23 @@ static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle)
{ {
assert(handle); assert(handle);
do /* Clears status. */
handle->rxBdCurrent->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
/* Sets the receive buffer descriptor with the empty flag. */
handle->rxBdCurrent->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
/* Increase current buffer descriptor to the next one. */
if (handle->rxBdCurrent->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
{ {
/* Clears status. */ handle->rxBdCurrent = handle->rxBdBase;
handle->rxBdDirty->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK; }
/* Sets the receive buffer descriptor with the empty flag. */ else
handle->rxBdDirty->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; {
/* Increases the buffer descriptor to the next one. */ handle->rxBdCurrent++;
if (handle->rxBdDirty->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK) }
{
handle->rxBdDirty = handle->rxBdBase;
}
else
{
handle->rxBdDirty++;
}
/* Actives the receive buffer descriptor. */ /* Actives the receive buffer descriptor. */
base->RDAR = ENET_RDAR_RDAR_MASK; base->RDAR = ENET_RDAR_RDAR_MASK;
} while (handle->rxBdDirty != handle->rxBdCurrent);
} }
status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length) status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length)
@ -960,6 +966,11 @@ status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u
{ {
curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
} }
else
{
curBuffDescrip->controlExtend1 &= ~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
}
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK); curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
@ -982,12 +993,17 @@ status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u
/* One frame requires more than one transmit buffers. */ /* One frame requires more than one transmit buffers. */
do do
{ {
#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
/* For enable the timestamp. */ /* For enable the timestamp. */
if (isPtpEventMessage) if (isPtpEventMessage)
{ {
curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
} }
else
{
curBuffDescrip->controlExtend1 &= ~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
}
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
/* Increase the buffer descriptor address. */ /* Increase the buffer descriptor address. */
@ -1009,6 +1025,7 @@ status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u
curBuffDescrip->length = handle->txBuffSizeAlign; curBuffDescrip->length = handle->txBuffSizeAlign;
len += handle->txBuffSizeAlign; len += handle->txBuffSizeAlign;
/* Sets the control flag. */ /* Sets the control flag. */
curBuffDescrip->control &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK; curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK;
/* Active the transmit buffer descriptor*/ /* Active the transmit buffer descriptor*/
base->TDAR = ENET_TDAR_TDAR_MASK; base->TDAR = ENET_TDAR_TDAR_MASK;
@ -1029,7 +1046,7 @@ status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u
} while (!(curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)); } while (!(curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK));
return kStatus_ENET_TxFrameFail; return kStatus_ENET_TxFrameBusy;
} }
} }
@ -1276,8 +1293,11 @@ void ENET_Ptp1588Configure(ENET_Type *base, enet_handle_t *handle, enet_ptp_conf
ENET_EnableInterrupts(base, kENET_TsTimerInterrupt); ENET_EnableInterrupts(base, kENET_TsTimerInterrupt);
EnableIRQ(s_enetTsIrqId[instance]); EnableIRQ(s_enetTsIrqId[instance]);
/* Enables the transmit interrupt to store the transmit frame time-stamp. */ /* Enables only frame interrupt for transmit side to store the transmit
frame time-stamp when the whole frame is transmitted out. */
ENET_EnableInterrupts(base, kENET_TxFrameInterrupt); ENET_EnableInterrupts(base, kENET_TxFrameInterrupt);
ENET_DisableInterrupts(base, kENET_TxBufferInterrupt);
EnableIRQ(s_enetTxIrqId[instance]); EnableIRQ(s_enetTxIrqId[instance]);
/* Setting the receive and transmit state for transaction. */ /* Setting the receive and transmit state for transaction. */
@ -1292,6 +1312,9 @@ void ENET_Ptp1588Configure(ENET_Type *base, enet_handle_t *handle, enet_ptp_conf
handle->msTimerSecond = 0; handle->msTimerSecond = 0;
handle->txBdDirtyTime = handle->txBdBase; handle->txBdDirtyTime = handle->txBdBase;
handle->txBdDirtyStatic = handle->txBdBase; handle->txBdDirtyStatic = handle->txBdBase;
/* Set the IRQ handler when the interrupt is enabled. */
s_enetTxIsr = ENET_TransmitIRQHandler;
} }
void ENET_Ptp1588StartTimer(ENET_Type *base, uint32_t ptpClkSrc) void ENET_Ptp1588StartTimer(ENET_Type *base, uint32_t ptpClkSrc)
@ -1591,14 +1614,19 @@ void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle)
assert(handle); assert(handle);
/* Check if the transmit interrupt happen. */ /* Check if the transmit interrupt happen. */
if ((kENET_TxByteInterrupt | kENET_TxFrameInterrupt) & base->EIR) while ((kENET_TxBufferInterrupt | kENET_TxFrameInterrupt) & base->EIR)
{ {
/* Clear the transmit interrupt event. */
base->EIR = kENET_TxFrameInterrupt | kENET_TxByteInterrupt;
#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
/* Store the transmit timestamp from the buffer descriptor should be done here. */ if (base->EIR & kENET_TxFrameInterrupt)
ENET_StoreTxFrameTime(base, handle); {
/* Store the transmit timestamp from the buffer descriptor should be done here. */
ENET_StoreTxFrameTime(base, handle);
}
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
/* Clear the transmit interrupt event. */
base->EIR = kENET_TxFrameInterrupt | kENET_TxBufferInterrupt;
/* Callback function. */ /* Callback function. */
if (handle->callback) if (handle->callback)
{ {
@ -1612,10 +1640,10 @@ void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle)
assert(handle); assert(handle);
/* Check if the receive interrupt happen. */ /* Check if the receive interrupt happen. */
if ((kENET_RxByteInterrupt | kENET_RxFrameInterrupt) & base->EIR) while ((kENET_RxBufferInterrupt | kENET_RxFrameInterrupt) & base->EIR)
{ {
/* Clear the transmit interrupt event. */ /* Clear the transmit interrupt event. */
base->EIR = kENET_RxFrameInterrupt | kENET_RxByteInterrupt; base->EIR = kENET_RxFrameInterrupt | kENET_RxBufferInterrupt;
/* Callback function. */ /* Callback function. */
if (handle->callback) if (handle->callback)
@ -1632,7 +1660,7 @@ void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle)
uint32_t errMask = kENET_BabrInterrupt | kENET_BabtInterrupt | kENET_EBusERInterrupt | kENET_PayloadRxInterrupt | uint32_t errMask = kENET_BabrInterrupt | kENET_BabtInterrupt | kENET_EBusERInterrupt | kENET_PayloadRxInterrupt |
kENET_LateCollisionInterrupt | kENET_RetryLimitInterrupt | kENET_UnderrunInterrupt; kENET_LateCollisionInterrupt | kENET_RetryLimitInterrupt | kENET_UnderrunInterrupt;
/* Check if the PTP time stamp interrupt happen. */ /* Check if the error interrupt happen. */
if (kENET_WakeupInterrupt & base->EIR) if (kENET_WakeupInterrupt & base->EIR)
{ {
/* Clear the wakeup interrupt. */ /* Clear the wakeup interrupt. */
@ -1647,7 +1675,7 @@ void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle)
} }
else else
{ {
/* Clear the time stamp interrupt. */ /* Clear the error interrupt event status. */
errMask &= base->EIR; errMask &= base->EIR;
base->EIR = errMask; base->EIR = errMask;
/* Callback function. */ /* Callback function. */
@ -1688,26 +1716,24 @@ void ENET_Ptp1588TimerIRQHandler(ENET_Type *base, enet_handle_t *handle)
} }
} }
} }
void ENET_1588_Timer_IRQHandler(void)
{
ENET_Ptp1588TimerIRQHandler(ENET, s_ENETHandle[0]);
}
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
void ENET_Transmit_IRQHandler(void) void ENET_Transmit_IRQHandler(void)
{ {
ENET_TransmitIRQHandler(ENET, s_ENETHandle[0]); s_enetTxIsr(ENET, s_ENETHandle[0]);
} }
void ENET_Receive_IRQHandler(void) void ENET_Receive_IRQHandler(void)
{ {
ENET_ReceiveIRQHandler(ENET, s_ENETHandle[0]); s_enetRxIsr(ENET, s_ENETHandle[0]);
} }
void ENET_Error_IRQHandler(void) void ENET_Error_IRQHandler(void)
{ {
ENET_ErrorIRQHandler(ENET, s_ENETHandle[0]); s_enetErrIsr(ENET, s_ENETHandle[0]);
}
void ENET_1588_Timer_IRQHandler(void)
{
#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
ENET_Ptp1588TimerIRQHandler(ENET, s_ENETHandle[0]);
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
} }

View File

@ -37,7 +37,6 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -46,7 +45,7 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief Defines the driver version. */ /*! @brief Defines the driver version. */
#define FSL_ENET_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ #define FSL_ENET_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1. */
/*@}*/ /*@}*/
/*! @name Control and status region bit masks of the receive buffer descriptor. */ /*! @name Control and status region bit masks of the receive buffer descriptor. */
@ -224,9 +223,9 @@ typedef enum _enet_interrupt_enable
kENET_BabtInterrupt = ENET_EIR_BABT_MASK, /*!< Babbling transmit error interrupt source */ kENET_BabtInterrupt = ENET_EIR_BABT_MASK, /*!< Babbling transmit error interrupt source */
kENET_GraceStopInterrupt = ENET_EIR_GRA_MASK, /*!< Graceful stop complete interrupt source */ kENET_GraceStopInterrupt = ENET_EIR_GRA_MASK, /*!< Graceful stop complete interrupt source */
kENET_TxFrameInterrupt = ENET_EIR_TXF_MASK, /*!< TX FRAME interrupt source */ kENET_TxFrameInterrupt = ENET_EIR_TXF_MASK, /*!< TX FRAME interrupt source */
kENET_TxByteInterrupt = ENET_EIR_TXB_MASK, /*!< TX BYTE interrupt source */ kENET_TxBufferInterrupt = ENET_EIR_TXB_MASK, /*!< TX BUFFER interrupt source */
kENET_RxFrameInterrupt = ENET_EIR_RXF_MASK, /*!< RX FRAME interrupt source */ kENET_RxFrameInterrupt = ENET_EIR_RXF_MASK, /*!< RX FRAME interrupt source */
kENET_RxByteInterrupt = ENET_EIR_RXB_MASK, /*!< RX BYTE interrupt source */ kENET_RxBufferInterrupt = ENET_EIR_RXB_MASK, /*!< RX BUFFER interrupt source */
kENET_MiiInterrupt = ENET_EIR_MII_MASK, /*!< MII interrupt source */ kENET_MiiInterrupt = ENET_EIR_MII_MASK, /*!< MII interrupt source */
kENET_EBusERInterrupt = ENET_EIR_EBERR_MASK, /*!< Ethernet bus error interrupt source */ kENET_EBusERInterrupt = ENET_EIR_EBERR_MASK, /*!< Ethernet bus error interrupt source */
kENET_LateCollisionInterrupt = ENET_EIR_LC_MASK, /*!< Late collision interrupt source */ kENET_LateCollisionInterrupt = ENET_EIR_LC_MASK, /*!< Late collision interrupt source */
@ -376,9 +375,9 @@ typedef struct _enet_data_error_stats
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
} enet_data_error_stats_t; } enet_data_error_stats_t;
/*! @brief Defines the receive buffer descriptor configure structure. /*! @brief Defines the receive buffer descriptor configuration structure.
* *
* Note: For the internal DMA requirements, the buffers have a corresponding alignment requirement: * Note that for the internal DMA requirements, the buffers have a corresponding alignment requirements.
* 1. The aligned receive and transmit buffer size must be evenly divisible by 16. * 1. The aligned receive and transmit buffer size must be evenly divisible by 16.
* 2. The aligned transmit and receive buffer descriptor start address must be at * 2. The aligned transmit and receive buffer descriptor start address must be at
* least 64 bit aligned. However, it's recommended to be evenly divisible by 16. * least 64 bit aligned. However, it's recommended to be evenly divisible by 16.
@ -425,7 +424,7 @@ typedef struct _enet_ptp_time_data_ring
enet_ptp_time_data_t *ptpTsData; /*!< PTP message data structure. */ enet_ptp_time_data_t *ptpTsData; /*!< PTP message data structure. */
} enet_ptp_time_data_ring_t; } enet_ptp_time_data_ring_t;
/*! @brief Defines the ENET PTP configure structure. */ /*! @brief Defines the ENET PTP configuration structure. */
typedef struct _enet_ptp_config typedef struct _enet_ptp_config
{ {
uint8_t ptpTsRxBuffNum; /*!< Receive 1588 timestamp buffer number*/ uint8_t ptpTsRxBuffNum; /*!< Receive 1588 timestamp buffer number*/
@ -442,14 +441,14 @@ typedef struct _enet_ptp_config
/*! @brief Defines the basic configuration structure for the ENET device. /*! @brief Defines the basic configuration structure for the ENET device.
* *
* Note: * Note:
* 1. macSpecialConfig is used for a special control configuration, A logical OR of * 1. macSpecialConfig is used for a special control configuration, a logical OR of
* "enet_special_control_flag_t". For a special configuration for MAC, * "enet_special_control_flag_t". For a special configuration for MAC,
* set this parameter to 0. * set this parameter to 0.
* 2. txWatermark is used for a cut-through operation. It is in steps of 64 bytes: * 2. txWatermark is used for a cut-through operation. It is in steps of 64 bytes.
* 0/1 - 64 bytes written to TX FIFO before transmission of a frame begins. * 0/1 - 64 bytes written to TX FIFO before transmission of a frame begins.
* 2 - 128 bytes written to TX FIFO .... * 2 - 128 bytes written to TX FIFO ....
* 3 - 192 bytes written to TX FIFO .... * 3 - 192 bytes written to TX FIFO ....
* The maximum of txWatermark is 0x2F - 4032 bytes written to TX FIFO .... * The maximum of txWatermark is 0x2F - 4032 bytes written to TX FIFO.
* txWatermark allows minimizing the transmit latency to set the txWatermark to 0 or 1 * txWatermark allows minimizing the transmit latency to set the txWatermark to 0 or 1
* or for larger bus access latency 3 or larger due to contention for the system bus. * or for larger bus access latency 3 or larger due to contention for the system bus.
* 3. rxFifoFullThreshold is similar to the txWatermark for cut-through operation in RX. * 3. rxFifoFullThreshold is similar to the txWatermark for cut-through operation in RX.
@ -503,7 +502,6 @@ struct _enet_handle
{ {
volatile enet_rx_bd_struct_t *rxBdBase; /*!< Receive buffer descriptor base address pointer. */ volatile enet_rx_bd_struct_t *rxBdBase; /*!< Receive buffer descriptor base address pointer. */
volatile enet_rx_bd_struct_t *rxBdCurrent; /*!< The current available receive buffer descriptor pointer. */ volatile enet_rx_bd_struct_t *rxBdCurrent; /*!< The current available receive buffer descriptor pointer. */
volatile enet_rx_bd_struct_t *rxBdDirty; /*!< The dirty receive buffer descriptor needed to be updated from. */
volatile enet_tx_bd_struct_t *txBdBase; /*!< Transmit buffer descriptor base address pointer. */ volatile enet_tx_bd_struct_t *txBdBase; /*!< Transmit buffer descriptor base address pointer. */
volatile enet_tx_bd_struct_t *txBdCurrent; /*!< The current available transmit buffer descriptor pointer. */ volatile enet_tx_bd_struct_t *txBdCurrent; /*!< The current available transmit buffer descriptor pointer. */
volatile enet_tx_bd_struct_t *txBdDirty; /*!< The dirty transmit buffer descriptor needed to be updated from. */ volatile enet_tx_bd_struct_t *txBdDirty; /*!< The dirty transmit buffer descriptor needed to be updated from. */
@ -529,7 +527,7 @@ extern "C" {
#endif #endif
/*! /*!
* @name Initialization and De-initialization * @name Initialization and de-initialization
* @{ * @{
*/ */
@ -537,10 +535,10 @@ extern "C" {
* @brief Gets the ENET default configuration structure. * @brief Gets the ENET default configuration structure.
* *
* The purpose of this API is to get the default ENET MAC controller * The purpose of this API is to get the default ENET MAC controller
* configure structure for ENET_Init(). User may use the initialized * configuration structure for ENET_Init(). Users may use the initialized
* structure unchanged in ENET_Init(), or modify some fields of the * structure unchanged in ENET_Init() or modify fields of the
* structure before calling ENET_Init(). * structure before calling ENET_Init().
* Example: * This is an example.
@code @code
enet_config_t config; enet_config_t config;
ENET_GetDefaultConfig(&config); ENET_GetDefaultConfig(&config);
@ -556,18 +554,18 @@ void ENET_GetDefaultConfig(enet_config_t *config);
* *
* @param base ENET peripheral base address. * @param base ENET peripheral base address.
* @param handle ENET handler pointer. * @param handle ENET handler pointer.
* @param config ENET mac configuration structure pointer. * @param config ENET Mac configuration structure pointer.
* The "enet_config_t" type mac configuration return from ENET_GetDefaultConfig * The "enet_config_t" type mac configuration return from ENET_GetDefaultConfig
* can be used directly. It is also possible to verify the Mac configuration using other methods. * can be used directly. It is also possible to verify the Mac configuration using other methods.
* @param bufferConfig ENET buffer configuration structure pointer. * @param bufferConfig ENET buffer configuration structure pointer.
* The buffer configuration should be prepared for ENET Initialization. * The buffer configuration should be prepared for ENET Initialization.
* @param macAddr ENET mac address of Ethernet device. This MAC address should be * @param macAddr ENET mac address of the Ethernet device. This Mac address should be
* provided. * provided.
* @param srcClock_Hz The internal module clock source for MII clock. * @param srcClock_Hz The internal module clock source for MII clock.
* *
* @note ENET has two buffer descriptors: legacy buffer descriptors and * @note ENET has two buffer descriptors legacy buffer descriptors and
* enhanced 1588 buffer descriptors. The legacy descriptor is used by default. To * enhanced IEEE 1588 buffer descriptors. The legacy descriptor is used by default. To
* use 1588 feature, use the enhanced 1588 buffer descriptor * use the IEEE 1588 feature, use the enhanced IEEE 1588 buffer descriptor
* by defining "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" and calling ENET_Ptp1588Configure() * by defining "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" and calling ENET_Ptp1588Configure()
* to configure the 1588 feature and related buffers after calling ENET_Init(). * to configure the 1588 feature and related buffers after calling ENET_Init().
*/ */
@ -589,8 +587,8 @@ void ENET_Deinit(ENET_Type *base);
/*! /*!
* @brief Resets the ENET module. * @brief Resets the ENET module.
* *
* This function restores the ENET module to reset state. * This function restores the ENET module to the reset state.
* Note that this function sets all registers to * Note that this function sets all registers to the
* reset state. As a result, the ENET module can't work after calling this function. * reset state. As a result, the ENET module can't work after calling this function.
* *
* @param base ENET peripheral base address. * @param base ENET peripheral base address.
@ -630,7 +628,7 @@ void ENET_SetSMI(ENET_Type *base, uint32_t srcClock_Hz, bool isPreambleDisabled)
/*! /*!
* @brief Gets the ENET SMI- MII management interface configuration. * @brief Gets the ENET SMI- MII management interface configuration.
* *
* This API is used to get the SMI configuration to check if the MII management * This API is used to get the SMI configuration to check whether the MII management
* interface has been set. * interface has been set.
* *
* @param base ENET peripheral base address. * @param base ENET peripheral base address.
@ -642,7 +640,7 @@ static inline bool ENET_GetSMI(ENET_Type *base)
} }
/*! /*!
* @brief Reads data from the PHY register through SMI interface. * @brief Reads data from the PHY register through an SMI interface.
* *
* @param base ENET peripheral base address. * @param base ENET peripheral base address.
* @return The data read from PHY * @return The data read from PHY
@ -663,7 +661,7 @@ static inline uint32_t ENET_ReadSMIData(ENET_Type *base)
void ENET_StartSMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_read_t operation); void ENET_StartSMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_read_t operation);
/*! /*!
* @brief Starts a SMI write command. * @brief Starts an SMI write command.
* *
* @param base ENET peripheral base address. * @param base ENET peripheral base address.
* @param phyAddr The PHY address. * @param phyAddr The PHY address.
@ -717,7 +715,7 @@ void ENET_LeaveMulticastGroup(ENET_Type *base, uint8_t *address);
/* @} */ /* @} */
/*! /*!
* @name Other basic operation * @name Other basic operations
* @{ * @{
*/ */
@ -758,13 +756,13 @@ static inline void ENET_EnableSleepMode(ENET_Type *base, bool enable)
} }
/*! /*!
* @brief Gets ENET transmit and receive accelerator functions from MAC controller. * @brief Gets ENET transmit and receive accelerator functions from the MAC controller.
* *
* @param base ENET peripheral base address. * @param base ENET peripheral base address.
* @param txAccelOption The transmit accelerator option. The "enet_tx_accelerator_t" is * @param txAccelOption The transmit accelerator option. The "enet_tx_accelerator_t" is
* recommended to be used to as the mask to get the exact the accelerator option. * recommended as the mask to get the exact the accelerator option.
* @param rxAccelOption The receive accelerator option. The "enet_rx_accelerator_t" is * @param rxAccelOption The receive accelerator option. The "enet_rx_accelerator_t" is
* recommended to be used to as the mask to get the exact the accelerator option. * recommended as the mask to get the exact the accelerator option.
*/ */
static inline void ENET_GetAccelFunction(ENET_Type *base, uint32_t *txAccelOption, uint32_t *rxAccelOption) static inline void ENET_GetAccelFunction(ENET_Type *base, uint32_t *txAccelOption, uint32_t *rxAccelOption)
{ {
@ -778,7 +776,7 @@ static inline void ENET_GetAccelFunction(ENET_Type *base, uint32_t *txAccelOptio
/* @} */ /* @} */
/*! /*!
* @name Interrupts. * @name Interrupts
* @{ * @{
*/ */
@ -787,7 +785,7 @@ static inline void ENET_GetAccelFunction(ENET_Type *base, uint32_t *txAccelOptio
* *
* This function enables the ENET interrupt according to the provided mask. The mask * This function enables the ENET interrupt according to the provided mask. The mask
* is a logical OR of enumeration members. See @ref enet_interrupt_enable_t. * is a logical OR of enumeration members. See @ref enet_interrupt_enable_t.
* For example, to enable the TX frame interrupt and RX frame interrupt, do this: * For example, to enable the TX frame interrupt and RX frame interrupt, do the following.
* @code * @code
* ENET_EnableInterrupts(ENET, kENET_TxFrameInterrupt | kENET_RxFrameInterrupt); * ENET_EnableInterrupts(ENET, kENET_TxFrameInterrupt | kENET_RxFrameInterrupt);
* @endcode * @endcode
@ -806,7 +804,7 @@ static inline void ENET_EnableInterrupts(ENET_Type *base, uint32_t mask)
* *
* This function disables the ENET interrupts according to the provided mask. The mask * This function disables the ENET interrupts according to the provided mask. The mask
* is a logical OR of enumeration members. See @ref enet_interrupt_enable_t. * is a logical OR of enumeration members. See @ref enet_interrupt_enable_t.
* For example, to disable the TX frame interrupt and RX frame interrupt, do this: * For example, to disable the TX frame interrupt and RX frame interrupt, do the following.
* @code * @code
* ENET_DisableInterrupts(ENET, kENET_TxFrameInterrupt | kENET_RxFrameInterrupt); * ENET_DisableInterrupts(ENET, kENET_TxFrameInterrupt | kENET_RxFrameInterrupt);
* @endcode * @endcode
@ -837,7 +835,7 @@ static inline uint32_t ENET_GetInterruptStatus(ENET_Type *base)
* *
* This function clears enabled ENET interrupts according to the provided mask. The mask * This function clears enabled ENET interrupts according to the provided mask. The mask
* is a logical OR of enumeration members. See the @ref enet_interrupt_enable_t. * is a logical OR of enumeration members. See the @ref enet_interrupt_enable_t.
* For example, to clear the TX frame interrupt and RX frame interrupt, do this: * For example, to clear the TX frame interrupt and RX frame interrupt, do the following.
* @code * @code
* ENET_ClearInterruptStatus(ENET, kENET_TxFrameInterrupt | kENET_RxFrameInterrupt); * ENET_ClearInterruptStatus(ENET, kENET_TxFrameInterrupt | kENET_RxFrameInterrupt);
* @endcode * @endcode
@ -859,8 +857,8 @@ static inline void ENET_ClearInterruptStatus(ENET_Type *base, uint32_t mask)
*/ */
/*! /*!
* @brief Set the callback function. * @brief Sets the callback function.
* This API is provided for application callback required case when ENET * This API is provided for the application callback required case when ENET
* interrupt is enabled. This API should be called after calling ENET_Init. * interrupt is enabled. This API should be called after calling ENET_Init.
* *
* @param handle ENET handler pointer. Should be provided by application. * @param handle ENET handler pointer. Should be provided by application.
@ -875,7 +873,7 @@ void ENET_SetCallback(enet_handle_t *handle, enet_callback_t callback, void *use
* This API must be called after the ENET_GetRxFrameSize and before the ENET_ReadFrame(). * This API must be called after the ENET_GetRxFrameSize and before the ENET_ReadFrame().
* If the ENET_GetRxFrameSize returns kStatus_ENET_RxFrameError, * If the ENET_GetRxFrameSize returns kStatus_ENET_RxFrameError,
* the ENET_GetRxErrBeforeReadFrame can be used to get the exact error statistics. * the ENET_GetRxErrBeforeReadFrame can be used to get the exact error statistics.
* For example: * This is an example.
* @code * @code
* status = ENET_GetRxFrameSize(&g_handle, &length); * status = ENET_GetRxFrameSize(&g_handle, &length);
* if (status == kStatus_ENET_RxFrameError) * if (status == kStatus_ENET_RxFrameError)
@ -907,29 +905,54 @@ void ENET_GetRxErrBeforeReadFrame(enet_handle_t *handle, enet_data_error_stats_t
*/ */
status_t ENET_GetTxErrAfterSendFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic); status_t ENET_GetTxErrAfterSendFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic);
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
/*! /*!
* @brief Gets the size of the read frame. * @brief Gets the size of the read frame.
* This function reads a received frame size from the ENET buffer descriptors. * This function gets a received frame size from the ENET buffer descriptors.
* @note The FCS of the frame is removed by MAC controller and the size is the length without the FCS. * @note The FCS of the frame is automatically removed by Mac and the size is the length without the FCS.
* After calling ENET_GetRxFrameSize, ENET_ReadFrame() should be called to update the * After calling ENET_GetRxFrameSize, ENET_ReadFrame() should be called to update the
* receive buffers If the result is not "kStatus_ENET_RxFrameEmpty". * receive buffers If the result is not "kStatus_ENET_RxFrameEmpty".
* *
* @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. * @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
* @param length The length of the valid frame received. * @param length The length of the valid frame received.
* @retval kStatus_ENET_RxFrameEmpty No frame received. Should not call ENET_ReadFrame to read frame. * @retval kStatus_ENET_RxFrameEmpty No frame received. Should not call ENET_ReadFrame to read frame.
* @retval kStatus_ENET_RxFrameError Data error happens. ENET_ReadFrame should be called with NULL data * @retval kStatus_ENET_RxFrameError Data error happens. ENET_ReadFrame should be called with NULL data
* and NULL length to update the receive buffers. * and NULL length to update the receive buffers.
* @retval kStatus_Success Receive a frame Successfully then the ENET_ReadFrame * @retval kStatus_Success Receive a frame Successfully then the ENET_ReadFrame
* should be called with the right data buffer and the captured data length input. * should be called with the right data buffer and the captured data length input.
*/ */
status_t ENET_GetRxFrameSize(enet_handle_t *handle, uint32_t *length); status_t ENET_GetRxFrameSize(enet_handle_t *handle, uint32_t *length);
/*! /*!
* @brief Reads a frame from the ENET device. * @brief Reads a frame from the ENET device.
* This function reads a frame (both the data and the length) from the ENET buffer descriptors. * This function reads a frame (both the data and the length) from the ENET buffer descriptors.
* The ENET_GetRxFrameSize should be used to get the size of the prepared data buffer. * The ENET_GetRxFrameSize should be used to get the size of the prepared data buffer.
* @note The FCS of the frame is removed by MAC controller and is not delivered to the application. * This is an example.
* * @code
* uint32_t length;
* enet_handle_t g_handle;
* //Get the received frame size firstly.
* status = ENET_GetRxFrameSize(&g_handle, &length);
* if (length != 0)
* {
* //Allocate memory here with the size of "length"
* uint8_t *data = memory allocate interface;
* if (!data)
* {
* ENET_ReadFrame(ENET, &g_handle, NULL, 0);
* //Add the console warning log.
* }
* else
* {
* status = ENET_ReadFrame(ENET, &g_handle, data, length);
* //Call stack input API to deliver the data to stack
* }
* }
* else if (status == kStatus_ENET_RxFrameError)
* {
* //Update the received buffer when a error frame is received.
* ENET_ReadFrame(ENET, &g_handle, NULL, 0);
* }
* @endcode
* @param base ENET peripheral base address. * @param base ENET peripheral base address.
* @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. * @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
* @param data The data buffer provided by user to store the frame which memory size should be at least "length". * @param data The data buffer provided by user to store the frame which memory size should be at least "length".
@ -948,8 +971,10 @@ status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u
* @param data The data buffer provided by user to be send. * @param data The data buffer provided by user to be send.
* @param length The length of the data to be send. * @param length The length of the data to be send.
* @retval kStatus_Success Send frame succeed. * @retval kStatus_Success Send frame succeed.
* @retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmit. * @retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmission.
* @retval kStatus_ENET_TxFrameFail Transmit frame fail. * The transmit busy happens when the data send rate is over the MAC capacity.
* The waiting mechanism is recommended to be added after each call return with
* kStatus_ENET_TxFrameBusy.
*/ */
status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length); status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length);
@ -986,7 +1011,7 @@ void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle);
*/ */
/*! /*!
* @brief Configures the ENET PTP 1588 feature with the basic configuration. * @brief Configures the ENET PTP IEEE 1588 feature with the basic configuration.
* The function sets the clock for PTP 1588 timer and enables * The function sets the clock for PTP 1588 timer and enables
* time stamp interrupts and transmit interrupts for PTP 1588 features. * time stamp interrupts and transmit interrupts for PTP 1588 features.
* This API should be called when the 1588 feature is enabled * This API should be called when the 1588 feature is enabled
@ -1040,7 +1065,7 @@ static inline void ENET_Ptp1588StopTimer(ENET_Type *base)
void ENET_Ptp1588AdjustTimer(ENET_Type *base, uint32_t corrIncrease, uint32_t corrPeriod); void ENET_Ptp1588AdjustTimer(ENET_Type *base, uint32_t corrIncrease, uint32_t corrPeriod);
/*! /*!
* @brief Sets ENET PTP 1588 timer channel mode. * @brief Sets the ENET PTP 1588 timer channel mode.
* *
* @param base ENET peripheral base address. * @param base ENET peripheral base address.
* @param channel The ENET PTP timer channel number. * @param channel The ENET PTP timer channel number.
@ -1061,7 +1086,7 @@ static inline void ENET_Ptp1588SetChannelMode(ENET_Type *base,
} }
/*! /*!
* @brief Sets ENET PTP 1588 timer channel comparison value. * @brief Sets the ENET PTP 1588 timer channel comparison value.
* *
* @param base ENET peripheral base address. * @param base ENET peripheral base address.
* @param channel The PTP timer channel, see "enet_ptp_timer_channel_t". * @param channel The PTP timer channel, see "enet_ptp_timer_channel_t".

View File

@ -40,7 +40,9 @@ void EWM_Init(EWM_Type *base, const ewm_config_t *config)
uint32_t value = 0U; uint32_t value = 0U;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(kCLOCK_Ewm0); CLOCK_EnableClock(kCLOCK_Ewm0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
value = EWM_CTRL_EWMEN(config->enableEwm) | EWM_CTRL_ASSIN(config->setInputAssertLogic) | value = EWM_CTRL_EWMEN(config->enableEwm) | EWM_CTRL_ASSIN(config->setInputAssertLogic) |
EWM_CTRL_INEN(config->enableEwmInput) | EWM_CTRL_INTEN(config->enableInterrupt); EWM_CTRL_INEN(config->enableEwmInput) | EWM_CTRL_INTEN(config->enableInterrupt);
#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER #if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
@ -59,7 +61,9 @@ void EWM_Init(EWM_Type *base, const ewm_config_t *config)
void EWM_Deinit(EWM_Type *base) void EWM_Deinit(EWM_Type *base)
{ {
EWM_DisableInterrupts(base, kEWM_InterruptEnable); EWM_DisableInterrupts(base, kEWM_InterruptEnable);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_DisableClock(kCLOCK_Ewm0); CLOCK_DisableClock(kCLOCK_Ewm0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void EWM_GetDefaultConfig(ewm_config_t *config) void EWM_GetDefaultConfig(ewm_config_t *config)

View File

@ -33,11 +33,10 @@
#include "fsl_common.h" #include "fsl_common.h"
/*! /*!
* @addtogroup ewm_driver * @addtogroup ewm
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -49,14 +48,14 @@
#define FSL_EWM_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) #define FSL_EWM_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
/*@}*/ /*@}*/
/*! @brief Describes ewm clock source. */ /*! @brief Describes EWM clock source. */
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT #if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
typedef enum _ewm_lpo_clock_source typedef enum _ewm_lpo_clock_source
{ {
kEWM_LpoClockSource0 = 0U, /*!< ewm clock sourced from lpo_clk[0]*/ kEWM_LpoClockSource0 = 0U, /*!< EWM clock sourced from lpo_clk[0]*/
kEWM_LpoClockSource1 = 1U, /*!< ewm clock sourced from lpo_clk[1]*/ kEWM_LpoClockSource1 = 1U, /*!< EWM clock sourced from lpo_clk[1]*/
kEWM_LpoClockSource2 = 2U, /*!< ewm clock sourced from lpo_clk[2]*/ kEWM_LpoClockSource2 = 2U, /*!< EWM clock sourced from lpo_clk[2]*/
kEWM_LpoClockSource3 = 3U, /*!< ewm clock sourced from lpo_clk[3]*/ kEWM_LpoClockSource3 = 3U, /*!< EWM clock sourced from lpo_clk[3]*/
} ewm_lpo_clock_source_t; } ewm_lpo_clock_source_t;
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */ #endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */
@ -77,18 +76,18 @@ typedef struct _ewm_config
#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER #if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
uint8_t prescaler; /*!< Clock prescaler value */ uint8_t prescaler; /*!< Clock prescaler value */
#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */ #endif /* FSL_FEATURE_EWM_HAS_PRESCALER */
uint8_t compareLowValue; /*!< Compare low register value */ uint8_t compareLowValue; /*!< Compare low-register value */
uint8_t compareHighValue; /*!< Compare high register value */ uint8_t compareHighValue; /*!< Compare high-register value */
} ewm_config_t; } ewm_config_t;
/*! /*!
* @brief EWM interrupt configuration structure, default settings all disabled. * @brief EWM interrupt configuration structure with default settings all disabled.
* *
* This structure contains the settings for all of the EWM interrupt configurations. * This structure contains the settings for all of EWM interrupt configurations.
*/ */
enum _ewm_interrupt_enable_t enum _ewm_interrupt_enable_t
{ {
kEWM_InterruptEnable = EWM_CTRL_INTEN_MASK, /*!< Enable EWM to generate an interrupt*/ kEWM_InterruptEnable = EWM_CTRL_INTEN_MASK, /*!< Enable the EWM to generate an interrupt*/
}; };
/*! /*!
@ -98,7 +97,7 @@ enum _ewm_interrupt_enable_t
*/ */
enum _ewm_status_flags_t enum _ewm_status_flags_t
{ {
kEWM_RunningFlag = EWM_CTRL_EWMEN_MASK, /*!< Running flag, set when ewm is enabled*/ kEWM_RunningFlag = EWM_CTRL_EWMEN_MASK, /*!< Running flag, set when EWM is enabled*/
}; };
/******************************************************************************* /*******************************************************************************
@ -110,7 +109,7 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/*! /*!
* @name EWM Initialization and De-initialization * @name EWM initialization and de-initialization
* @{ * @{
*/ */
@ -119,10 +118,10 @@ extern "C" {
* *
* This function is used to initialize the EWM. After calling, the EWM * This function is used to initialize the EWM. After calling, the EWM
* runs immediately according to the configuration. * runs immediately according to the configuration.
* Note that except for interrupt enable control bit, other control bits and registers are write once after a * Note that, except for the interrupt enable control bit, other control bits and registers are write once after a
* CPU reset. Modifying them more than once generates a bus transfer error. * CPU reset. Modifying them more than once generates a bus transfer error.
* *
* Example: * This is an example.
* @code * @code
* ewm_config_t config; * ewm_config_t config;
* EWM_GetDefaultConfig(&config); * EWM_GetDefaultConfig(&config);
@ -131,7 +130,7 @@ extern "C" {
* @endcode * @endcode
* *
* @param base EWM peripheral base address * @param base EWM peripheral base address
* @param config The configuration of EWM * @param config The configuration of the EWM
*/ */
void EWM_Init(EWM_Type *base, const ewm_config_t *config); void EWM_Init(EWM_Type *base, const ewm_config_t *config);
@ -147,8 +146,8 @@ void EWM_Deinit(EWM_Type *base);
/*! /*!
* @brief Initializes the EWM configuration structure. * @brief Initializes the EWM configuration structure.
* *
* This function initializes the EWM configure structure to default values. The default * This function initializes the EWM configuration structure to default values. The default
* values are: * values are as follows.
* @code * @code
* ewmConfig->enableEwm = true; * ewmConfig->enableEwm = true;
* ewmConfig->enableEwmInput = false; * ewmConfig->enableEwmInput = false;
@ -160,7 +159,7 @@ void EWM_Deinit(EWM_Type *base);
* ewmConfig->compareHighValue = 0xFEU; * ewmConfig->compareHighValue = 0xFEU;
* @endcode * @endcode
* *
* @param config Pointer to EWM configuration structure. * @param config Pointer to the EWM configuration structure.
* @see ewm_config_t * @see ewm_config_t
*/ */
void EWM_GetDefaultConfig(ewm_config_t *config); void EWM_GetDefaultConfig(ewm_config_t *config);
@ -179,7 +178,7 @@ void EWM_GetDefaultConfig(ewm_config_t *config);
* *
* @param base EWM peripheral base address * @param base EWM peripheral base address
* @param mask The interrupts to enable * @param mask The interrupts to enable
* The parameter can be combination of the following source if defined: * The parameter can be combination of the following source if defined
* @arg kEWM_InterruptEnable * @arg kEWM_InterruptEnable
*/ */
static inline void EWM_EnableInterrupts(EWM_Type *base, uint32_t mask) static inline void EWM_EnableInterrupts(EWM_Type *base, uint32_t mask)
@ -194,7 +193,7 @@ static inline void EWM_EnableInterrupts(EWM_Type *base, uint32_t mask)
* *
* @param base EWM peripheral base address * @param base EWM peripheral base address
* @param mask The interrupts to disable * @param mask The interrupts to disable
* The parameter can be combination of the following source if defined: * The parameter can be combination of the following source if defined
* @arg kEWM_InterruptEnable * @arg kEWM_InterruptEnable
*/ */
static inline void EWM_DisableInterrupts(EWM_Type *base, uint32_t mask) static inline void EWM_DisableInterrupts(EWM_Type *base, uint32_t mask)
@ -203,19 +202,19 @@ static inline void EWM_DisableInterrupts(EWM_Type *base, uint32_t mask)
} }
/*! /*!
* @brief Gets EWM all status flags. * @brief Gets all status flags.
* *
* This function gets all status flags. * This function gets all status flags.
* *
* Example for getting Running Flag: * This is an example for getting the running flag.
* @code * @code
* uint32_t status; * uint32_t status;
* status = EWM_GetStatusFlags(ewm_base) & kEWM_RunningFlag; * status = EWM_GetStatusFlags(ewm_base) & kEWM_RunningFlag;
* @endcode * @endcode
* @param base EWM peripheral base address * @param base EWM peripheral base address
* @return State of the status flag: asserted (true) or not-asserted (false).@see _ewm_status_flags_t * @return State of the status flag: asserted (true) or not-asserted (false).@see _ewm_status_flags_t
* - true: related status flag has been set. * - True: a related status flag has been set.
* - false: related status flag is not set. * - False: a related status flag is not set.
*/ */
static inline uint32_t EWM_GetStatusFlags(EWM_Type *base) static inline uint32_t EWM_GetStatusFlags(EWM_Type *base)
{ {
@ -223,9 +222,9 @@ static inline uint32_t EWM_GetStatusFlags(EWM_Type *base)
} }
/*! /*!
* @brief Service EWM. * @brief Services the EWM.
* *
* This function reset EWM counter to zero. * This function resets the EWM counter to zero.
* *
* @param base EWM peripheral base address * @param base EWM peripheral base address
*/ */

View File

@ -50,8 +50,10 @@ static uint32_t FLEXBUS_GetInstance(FB_Type *base);
/*! @brief Pointers to FLEXBUS bases for each instance. */ /*! @brief Pointers to FLEXBUS bases for each instance. */
static FB_Type *const s_flexbusBases[] = FB_BASE_PTRS; static FB_Type *const s_flexbusBases[] = FB_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to FLEXBUS clocks for each instance. */ /*! @brief Pointers to FLEXBUS clocks for each instance. */
static const clock_ip_name_t s_flexbusClocks[] = FLEXBUS_CLOCKS; static const clock_ip_name_t s_flexbusClocks[] = FLEXBUS_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/******************************************************************************* /*******************************************************************************
* Code * Code
@ -84,8 +86,10 @@ void FLEXBUS_Init(FB_Type *base, const flexbus_config_t *config)
uint32_t chip = 0; uint32_t chip = 0;
uint32_t reg_value = 0; uint32_t reg_value = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate clock for FLEXBUS */ /* Ungate clock for FLEXBUS */
CLOCK_EnableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]); CLOCK_EnableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Reset all the register to default state */ /* Reset all the register to default state */
for (chip = 0; chip < FB_CSAR_COUNT; chip++) for (chip = 0; chip < FB_CSAR_COUNT; chip++)
@ -168,8 +172,10 @@ void FLEXBUS_Init(FB_Type *base, const flexbus_config_t *config)
void FLEXBUS_Deinit(FB_Type *base) void FLEXBUS_Deinit(FB_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate clock for FLEXBUS */ /* Gate clock for FLEXBUS */
CLOCK_EnableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]); CLOCK_DisableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void FLEXBUS_GetDefaultConfig(flexbus_config_t *config) void FLEXBUS_GetDefaultConfig(flexbus_config_t *config)

View File

@ -38,7 +38,6 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -46,7 +45,7 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
#define FSL_FLEXBUS_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ #define FSL_FLEXBUS_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1. */
/*@}*/ /*@}*/
/*! /*!
@ -197,11 +196,11 @@ extern "C" {
* *
* This function enables the clock gate for FlexBus module. * This function enables the clock gate for FlexBus module.
* Only chip 0 is validated and set to known values. Other chips are disabled. * Only chip 0 is validated and set to known values. Other chips are disabled.
* NOTE: In this function, certain parameters, depending on external memories, must * Note that in this function, certain parameters, depending on external memories, must
* be set before using FLEXBUS_Init() function. * be set before using the FLEXBUS_Init() function.
* This example shows how to set up the uart_state_t and the * This example shows how to set up the uart_state_t and the
* flexbus_config_t parameters and how to call the FLEXBUS_Init function by passing * flexbus_config_t parameters and how to call the FLEXBUS_Init function by passing
* in these parameters: * in these parameters.
@code @code
flexbus_config_t flexbusConfig; flexbus_config_t flexbusConfig;
FLEXBUS_GetDefaultConfig(&flexbusConfig); FLEXBUS_GetDefaultConfig(&flexbusConfig);
@ -212,7 +211,7 @@ extern "C" {
@endcode @endcode
* *
* @param base FlexBus peripheral address. * @param base FlexBus peripheral address.
* @param config Pointer to the configure structure * @param config Pointer to the configuration structure
*/ */
void FLEXBUS_Init(FB_Type *base, const flexbus_config_t *config); void FLEXBUS_Init(FB_Type *base, const flexbus_config_t *config);
@ -229,7 +228,7 @@ void FLEXBUS_Deinit(FB_Type *base);
* @brief Initializes the FlexBus configuration structure. * @brief Initializes the FlexBus configuration structure.
* *
* This function initializes the FlexBus configuration structure to default value. The default * This function initializes the FlexBus configuration structure to default value. The default
* values are: * values are.
@code @code
fbConfig->chip = 0; fbConfig->chip = 0;
fbConfig->writeProtect = 0; fbConfig->writeProtect = 0;

View File

@ -179,8 +179,10 @@ static const IRQn_Type s_flexcanErrorIRQ[] = CAN_Error_IRQS;
static const IRQn_Type s_flexcanBusOffIRQ[] = CAN_Bus_Off_IRQS; static const IRQn_Type s_flexcanBusOffIRQ[] = CAN_Bus_Off_IRQS;
static const IRQn_Type s_flexcanMbIRQ[] = CAN_ORed_Message_buffer_IRQS; static const IRQn_Type s_flexcanMbIRQ[] = CAN_ORed_Message_buffer_IRQS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Array of FlexCAN clock name. */ /* Array of FlexCAN clock name. */
static const clock_ip_name_t s_flexcanClock[] = FLEXCAN_CLOCKS; static const clock_ip_name_t s_flexcanClock[] = FLEXCAN_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* FlexCAN ISR for transactional APIs. */ /* FlexCAN ISR for transactional APIs. */
static flexcan_isr_t s_flexcanIsr; static flexcan_isr_t s_flexcanIsr;
@ -425,8 +427,10 @@ void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourc
assert(config); assert(config);
assert((config->maxMbNum > 0) && (config->maxMbNum <= FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base))); assert((config->maxMbNum > 0) && (config->maxMbNum <= FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)));
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable FlexCAN clock. */ /* Enable FlexCAN clock. */
CLOCK_EnableClock(s_flexcanClock[FLEXCAN_GetInstance(base)]); CLOCK_EnableClock(s_flexcanClock[FLEXCAN_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Disable FlexCAN Module. */ /* Disable FlexCAN Module. */
FLEXCAN_Enable(base, false); FLEXCAN_Enable(base, false);
@ -478,8 +482,10 @@ void FLEXCAN_Deinit(CAN_Type *base)
/* Disable FlexCAN module. */ /* Disable FlexCAN module. */
FLEXCAN_Enable(base, false); FLEXCAN_Enable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable FlexCAN clock. */ /* Disable FlexCAN clock. */
CLOCK_DisableClock(s_flexcanClock[FLEXCAN_GetInstance(base)]); CLOCK_DisableClock(s_flexcanClock[FLEXCAN_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void FLEXCAN_GetDefaultConfig(flexcan_config_t *config) void FLEXCAN_GetDefaultConfig(flexcan_config_t *config)

View File

@ -195,7 +195,7 @@ typedef enum _flexcan_rx_fifo_filter_type
} flexcan_rx_fifo_filter_type_t; } flexcan_rx_fifo_filter_type_t;
/*! /*!
* @brief FlexCAN Rx FIFO priority * @brief FlexCAN Rx FIFO priority.
* *
* The matching process starts from the Rx MB(or Rx FIFO) with higher priority. * The matching process starts from the Rx MB(or Rx FIFO) with higher priority.
* If no MB(or Rx FIFO filter) is satisfied, the matching process goes on with * If no MB(or Rx FIFO filter) is satisfied, the matching process goes on with
@ -366,7 +366,7 @@ typedef struct _flexcan_rx_mb_config
/*! @brief FlexCAN Rx FIFO configuration structure. */ /*! @brief FlexCAN Rx FIFO configuration structure. */
typedef struct _flexcan_rx_fifo_config typedef struct _flexcan_rx_fifo_config
{ {
uint32_t *idFilterTable; /*!< Pointer to FlexCAN Rx FIFO identifier filter table. */ uint32_t *idFilterTable; /*!< Pointer to the FlexCAN Rx FIFO identifier filter table. */
uint8_t idFilterNum; /*!< The quantity of filter elements. */ uint8_t idFilterNum; /*!< The quantity of filter elements. */
flexcan_rx_fifo_filter_type_t idFilterType; /*!< The FlexCAN Rx FIFO Filter type. */ flexcan_rx_fifo_filter_type_t idFilterType; /*!< The FlexCAN Rx FIFO Filter type. */
flexcan_rx_fifo_priority_t priority; /*!< The FlexCAN Rx FIFO receive priority. */ flexcan_rx_fifo_priority_t priority; /*!< The FlexCAN Rx FIFO receive priority. */
@ -431,7 +431,7 @@ extern "C" {
* *
* This function initializes the FlexCAN module with user-defined settings. * This function initializes the FlexCAN module with user-defined settings.
* This example shows how to set up the flexcan_config_t parameters and how * This example shows how to set up the flexcan_config_t parameters and how
* to call the FLEXCAN_Init function by passing in these parameters: * to call the FLEXCAN_Init function by passing in these parameters.
* @code * @code
* flexcan_config_t flexcanConfig; * flexcan_config_t flexcanConfig;
* flexcanConfig.clkSrc = kFLEXCAN_ClkSrcOsc; * flexcanConfig.clkSrc = kFLEXCAN_ClkSrcOsc;
@ -445,7 +445,7 @@ extern "C" {
* @endcode * @endcode
* *
* @param base FlexCAN peripheral base address. * @param base FlexCAN peripheral base address.
* @param config Pointer to user-defined configuration structure. * @param config Pointer to the user-defined configuration structure.
* @param sourceClock_Hz FlexCAN Protocol Engine clock source frequency in Hz. * @param sourceClock_Hz FlexCAN Protocol Engine clock source frequency in Hz.
*/ */
void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourceClock_Hz); void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourceClock_Hz);
@ -453,18 +453,18 @@ void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourc
/*! /*!
* @brief De-initializes a FlexCAN instance. * @brief De-initializes a FlexCAN instance.
* *
* This function disable the FlexCAN module clock and set all register value * This function disables the FlexCAN module clock and sets all register values
* to reset value. * to the reset value.
* *
* @param base FlexCAN peripheral base address. * @param base FlexCAN peripheral base address.
*/ */
void FLEXCAN_Deinit(CAN_Type *base); void FLEXCAN_Deinit(CAN_Type *base);
/*! /*!
* @brief Get the default configuration structure. * @brief Gets the default configuration structure.
* *
* This function initializes the FlexCAN configuration structure to default value. The default * This function initializes the FlexCAN configuration structure to default values. The default
* value are: * values are as follows.
* flexcanConfig->clkSrc = KFLEXCAN_ClkSrcOsc; * flexcanConfig->clkSrc = KFLEXCAN_ClkSrcOsc;
* flexcanConfig->baudRate = 125000U; * flexcanConfig->baudRate = 125000U;
* flexcanConfig->maxMbNum = 16; * flexcanConfig->maxMbNum = 16;
@ -473,7 +473,7 @@ void FLEXCAN_Deinit(CAN_Type *base);
* flexcanConfig->enableIndividMask = false; * flexcanConfig->enableIndividMask = false;
* flexcanConfig->enableDoze = false; * flexcanConfig->enableDoze = false;
* *
* @param config Pointer to FlexCAN configuration structure. * @param config Pointer to the FlexCAN configuration structure.
*/ */
void FLEXCAN_GetDefaultConfig(flexcan_config_t *config); void FLEXCAN_GetDefaultConfig(flexcan_config_t *config);
@ -503,7 +503,7 @@ void FLEXCAN_SetTimingConfig(CAN_Type *base, const flexcan_timing_config_t *conf
/*! /*!
* @brief Sets the FlexCAN receive message buffer global mask. * @brief Sets the FlexCAN receive message buffer global mask.
* *
* This function sets the global mask for FlexCAN message buffer in a matching process. * This function sets the global mask for the FlexCAN message buffer in a matching process.
* The configuration is only effective when the Rx individual mask is disabled in the FLEXCAN_Init(). * The configuration is only effective when the Rx individual mask is disabled in the FLEXCAN_Init().
* *
* @param base FlexCAN peripheral base address. * @param base FlexCAN peripheral base address.
@ -524,12 +524,12 @@ void FLEXCAN_SetRxFifoGlobalMask(CAN_Type *base, uint32_t mask);
/*! /*!
* @brief Sets the FlexCAN receive individual mask. * @brief Sets the FlexCAN receive individual mask.
* *
* This function sets the individual mask for FlexCAN matching process. * This function sets the individual mask for the FlexCAN matching process.
* The configuration is only effective when the Rx individual mask is enabled in FLEXCAN_Init(). * The configuration is only effective when the Rx individual mask is enabled in the FLEXCAN_Init().
* If Rx FIFO is disabled, the individual mask is applied to the corresponding Message Buffer. * If the Rx FIFO is disabled, the individual mask is applied to the corresponding Message Buffer.
* If Rx FIFO is enabled, the individual mask for Rx FIFO occupied Message Buffer is applied to * If the Rx FIFO is enabled, the individual mask for Rx FIFO occupied Message Buffer is applied to
* the Rx Filter with same index. What calls for special attention is that only the first 32 * the Rx Filter with the same index. Note that only the first 32
* individual masks can be used as Rx FIFO filter mask. * individual masks can be used as the Rx FIFO filter mask.
* *
* @param base FlexCAN peripheral base address. * @param base FlexCAN peripheral base address.
* @param maskIdx The Index of individual Mask. * @param maskIdx The Index of individual Mask.
@ -545,7 +545,7 @@ void FLEXCAN_SetRxIndividualMask(CAN_Type *base, uint8_t maskIdx, uint32_t mask)
* *
* @param base FlexCAN peripheral base address. * @param base FlexCAN peripheral base address.
* @param mbIdx The Message Buffer index. * @param mbIdx The Message Buffer index.
* @param enable Enable/Disable Tx Message Buffer. * @param enable Enable/disable Tx Message Buffer.
* - true: Enable Tx Message Buffer. * - true: Enable Tx Message Buffer.
* - false: Disable Tx Message Buffer. * - false: Disable Tx Message Buffer.
*/ */
@ -559,8 +559,8 @@ void FLEXCAN_SetTxMbConfig(CAN_Type *base, uint8_t mbIdx, bool enable);
* *
* @param base FlexCAN peripheral base address. * @param base FlexCAN peripheral base address.
* @param mbIdx The Message Buffer index. * @param mbIdx The Message Buffer index.
* @param config Pointer to FlexCAN Message Buffer configuration structure. * @param config Pointer to the FlexCAN Message Buffer configuration structure.
* @param enable Enable/Disable Rx Message Buffer. * @param enable Enable/disable Rx Message Buffer.
* - true: Enable Rx Message Buffer. * - true: Enable Rx Message Buffer.
* - false: Disable Rx Message Buffer. * - false: Disable Rx Message Buffer.
*/ */
@ -572,8 +572,8 @@ void FLEXCAN_SetRxMbConfig(CAN_Type *base, uint8_t mbIdx, const flexcan_rx_mb_co
* This function configures the Rx FIFO with given Rx FIFO configuration. * This function configures the Rx FIFO with given Rx FIFO configuration.
* *
* @param base FlexCAN peripheral base address. * @param base FlexCAN peripheral base address.
* @param config Pointer to FlexCAN Rx FIFO configuration structure. * @param config Pointer to the FlexCAN Rx FIFO configuration structure.
* @param enable Enable/Disable Rx FIFO. * @param enable Enable/disable Rx FIFO.
* - true: Enable Rx FIFO. * - true: Enable Rx FIFO.
* - false: Disable Rx FIFO. * - false: Disable Rx FIFO.
*/ */
@ -691,9 +691,9 @@ static inline void FLEXCAN_ClearMbStatusFlags(CAN_Type *base, uint32_t mask)
*/ */
/*! /*!
* @brief Enables FlexCAN interrupts according to provided mask. * @brief Enables FlexCAN interrupts according to the provided mask.
* *
* This function enables the FlexCAN interrupts according to provided mask. The mask * This function enables the FlexCAN interrupts according to the provided mask. The mask
* is a logical OR of enumeration members, see @ref _flexcan_interrupt_enable. * is a logical OR of enumeration members, see @ref _flexcan_interrupt_enable.
* *
* @param base FlexCAN peripheral base address. * @param base FlexCAN peripheral base address.
@ -712,9 +712,9 @@ static inline void FLEXCAN_EnableInterrupts(CAN_Type *base, uint32_t mask)
} }
/*! /*!
* @brief Disables FlexCAN interrupts according to provided mask. * @brief Disables FlexCAN interrupts according to the provided mask.
* *
* This function disables the FlexCAN interrupts according to provided mask. The mask * This function disables the FlexCAN interrupts according to the provided mask. The mask
* is a logical OR of enumeration members, see @ref _flexcan_interrupt_enable. * is a logical OR of enumeration members, see @ref _flexcan_interrupt_enable.
* *
* @param base FlexCAN peripheral base address. * @param base FlexCAN peripheral base address.
@ -735,7 +735,7 @@ static inline void FLEXCAN_DisableInterrupts(CAN_Type *base, uint32_t mask)
/*! /*!
* @brief Enables FlexCAN Message Buffer interrupts. * @brief Enables FlexCAN Message Buffer interrupts.
* *
* This function enables the interrupts of given Message Buffers * This function enables the interrupts of given Message Buffers.
* *
* @param base FlexCAN peripheral base address. * @param base FlexCAN peripheral base address.
* @param mask The ORed FlexCAN Message Buffer mask. * @param mask The ORed FlexCAN Message Buffer mask.
@ -757,7 +757,7 @@ static inline void FLEXCAN_EnableMbInterrupts(CAN_Type *base, uint32_t mask)
/*! /*!
* @brief Disables FlexCAN Message Buffer interrupts. * @brief Disables FlexCAN Message Buffer interrupts.
* *
* This function disables the interrupts of given Message Buffers * This function disables the interrupts of given Message Buffers.
* *
* @param base FlexCAN peripheral base address. * @param base FlexCAN peripheral base address.
* @param mask The ORed FlexCAN Message Buffer mask. * @param mask The ORed FlexCAN Message Buffer mask.
@ -846,7 +846,7 @@ static inline void FLEXCAN_Enable(CAN_Type *base, bool enable)
} }
/*! /*!
* @brief Writes a FlexCAN Message to Transmit Message Buffer. * @brief Writes a FlexCAN Message to the Transmit Message Buffer.
* *
* This function writes a CAN Message to the specified Transmit Message Buffer * This function writes a CAN Message to the specified Transmit Message Buffer
* and changes the Message Buffer state to start CAN Message transmit. After * and changes the Message Buffer state to start CAN Message transmit. After
@ -938,7 +938,7 @@ status_t FLEXCAN_TransferReceiveFifoBlocking(CAN_Type *base, flexcan_frame_t *rx
/*! /*!
* @brief Initializes the FlexCAN handle. * @brief Initializes the FlexCAN handle.
* *
* This function initializes the FlexCAN handle which can be used for other FlexCAN * This function initializes the FlexCAN handle, which can be used for other FlexCAN
* transactional APIs. Usually, for a specified FlexCAN instance, * transactional APIs. Usually, for a specified FlexCAN instance,
* call this API once to get the initialized handle. * call this API once to get the initialized handle.
* *

View File

@ -72,8 +72,10 @@ static void FTM_SetReloadPoints(FTM_Type *base, uint32_t reloadPoints);
/*! @brief Pointers to FTM bases for each instance. */ /*! @brief Pointers to FTM bases for each instance. */
static FTM_Type *const s_ftmBases[] = FTM_BASE_PTRS; static FTM_Type *const s_ftmBases[] = FTM_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to FTM clocks for each instance. */ /*! @brief Pointers to FTM clocks for each instance. */
static const clock_ip_name_t s_ftmClocks[] = FTM_CLOCKS; static const clock_ip_name_t s_ftmClocks[] = FTM_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/******************************************************************************* /*******************************************************************************
* Code * Code
@ -228,8 +230,10 @@ status_t FTM_Init(FTM_Type *base, const ftm_config_t *config)
return kStatus_Fail; return kStatus_Fail;
} }
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate the FTM clock*/ /* Ungate the FTM clock*/
CLOCK_EnableClock(s_ftmClocks[FTM_GetInstance(base)]); CLOCK_EnableClock(s_ftmClocks[FTM_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure the fault mode, enable FTM mode and disable write protection */ /* Configure the fault mode, enable FTM mode and disable write protection */
base->MODE = FTM_MODE_FAULTM(config->faultMode) | FTM_MODE_FTMEN_MASK | FTM_MODE_WPDIS_MASK; base->MODE = FTM_MODE_FAULTM(config->faultMode) | FTM_MODE_FTMEN_MASK | FTM_MODE_WPDIS_MASK;
@ -266,7 +270,13 @@ status_t FTM_Init(FTM_Type *base, const ftm_config_t *config)
#endif /* FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER */ #endif /* FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER */
/* FTM deadtime insertion control */ /* FTM deadtime insertion control */
base->DEADTIME = (FTM_DEADTIME_DTPS(config->deadTimePrescale) | FTM_DEADTIME_DTVAL(config->deadTimeValue)); base->DEADTIME = (0u |
#if defined(FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE) && (FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE)
/* Has extended deadtime value register) */
FTM_DEADTIME_DTVALEX(config->deadTimeValue >> 6) |
#endif /* FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE */
FTM_DEADTIME_DTPS(config->deadTimePrescale) |
FTM_DEADTIME_DTVAL(config->deadTimeValue));
/* FTM fault filter value */ /* FTM fault filter value */
reg = base->FLTCTRL; reg = base->FLTCTRL;
@ -282,8 +292,10 @@ void FTM_Deinit(FTM_Type *base)
/* Set clock source to none to disable counter */ /* Set clock source to none to disable counter */
base->SC &= ~(FTM_SC_CLKS_MASK); base->SC &= ~(FTM_SC_CLKS_MASK);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate the FTM clock */ /* Gate the FTM clock */
CLOCK_DisableClock(s_ftmClocks[FTM_GetInstance(base)]); CLOCK_DisableClock(s_ftmClocks[FTM_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void FTM_GetDefaultConfig(ftm_config_t *config) void FTM_GetDefaultConfig(ftm_config_t *config)

View File

@ -37,7 +37,6 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -45,8 +44,8 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
#define FSL_FTM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ #define FSL_FTM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2 */
/*@}*/ /*@}*/
/*! /*!
* @brief List of FTM channels * @brief List of FTM channels
@ -162,7 +161,7 @@ typedef struct _ftm_phase_param
typedef struct _ftm_fault_param typedef struct _ftm_fault_param
{ {
bool enableFaultInput; /*!< True: Fault input is enabled; false: Fault input is disabled */ bool enableFaultInput; /*!< True: Fault input is enabled; false: Fault input is disabled */
bool faultLevel; /*!< True: Fault polarity is active low i.e., '0' indicates a fault; bool faultLevel; /*!< True: Fault polarity is active low; in other words, '0' indicates a fault;
False: Fault polarity is active high */ False: Fault polarity is active high */
bool useFaultFilter; /*!< True: Use the filtered fault signal; bool useFaultFilter; /*!< True: Use the filtered fault signal;
False: Use the direct path from fault input */ False: Use the direct path from fault input */
@ -310,6 +309,17 @@ typedef enum _ftm_status_flags
kFTM_ReloadFlag = (1U << 11) /*!< Reload Flag; Available only on certain SoC's */ kFTM_ReloadFlag = (1U << 11) /*!< Reload Flag; Available only on certain SoC's */
} ftm_status_flags_t; } ftm_status_flags_t;
/*!
* @brief List of FTM Quad Decoder flags.
*/
enum _ftm_quad_decoder_flags
{
kFTM_QuadDecoderCountingIncreaseFlag = FTM_QDCTRL_QUADIR_MASK, /*!< Counting direction is increasing (FTM counter
increment), or the direction is decreasing. */
kFTM_QuadDecoderCountingOverflowOnTopFlag = FTM_QDCTRL_TOFDIR_MASK, /*!< Indicates if the TOF bit was set on the top
or the bottom of counting. */
};
/*! /*!
* @brief FTM configuration structure * @brief FTM configuration structure
* *
@ -333,7 +343,9 @@ typedef struct _ftm_config
ftm_fault_mode_t faultMode; /*!< FTM fault control mode */ ftm_fault_mode_t faultMode; /*!< FTM fault control mode */
uint8_t faultFilterValue; /*!< Fault input filter value */ uint8_t faultFilterValue; /*!< Fault input filter value */
ftm_deadtime_prescale_t deadTimePrescale; /*!< The dead time prescalar value */ ftm_deadtime_prescale_t deadTimePrescale; /*!< The dead time prescalar value */
uint8_t deadTimeValue; /*!< The dead time value */ uint32_t deadTimeValue; /*!< The dead time value
deadTimeValue's available range is 0-1023 when register has DTVALEX,
otherwise its available range is 0-63. */
uint32_t extTriggers; /*!< External triggers to enable. Multiple trigger sources can be uint32_t extTriggers; /*!< External triggers to enable. Multiple trigger sources can be
enabled by providing an OR'ed list of options available in enabled by providing an OR'ed list of options available in
enumeration ::ftm_external_trigger_t. */ enumeration ::ftm_external_trigger_t. */
@ -359,7 +371,7 @@ extern "C" {
/*! /*!
* @brief Ungates the FTM clock and configures the peripheral for basic operation. * @brief Ungates the FTM clock and configures the peripheral for basic operation.
* *
* @note This API should be called at the beginning of the application using the FTM driver. * @note This API should be called at the beginning of the application which is using the FTM driver.
* *
* @param base FTM peripheral base address * @param base FTM peripheral base address
* @param config Pointer to the user configuration structure. * @param config Pointer to the user configuration structure.
@ -508,19 +520,6 @@ void FTM_SetupDualEdgeCapture(FTM_Type *base,
/*! @}*/ /*! @}*/
/*!
* @brief Configures the parameters and activates the quadrature decoder mode.
*
* @param base FTM 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 FTM_SetupQuadDecode(FTM_Type *base,
const ftm_phase_params_t *phaseAParams,
const ftm_phase_params_t *phaseBParams,
ftm_quad_decode_mode_t quadMode);
/*! /*!
* @brief Sets up the working of the FTM fault protection. * @brief Sets up the working of the FTM fault protection.
* *
@ -711,7 +710,7 @@ static inline void FTM_SetOutputMask(FTM_Type *base, ftm_chnl_t chnlNumber, bool
#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) #if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
/*! /*!
* @brief Allows user to enable an output on an FTM channel. * @brief Allows users to enable an output on an FTM channel.
* *
* To enable the PWM channel output call this function with val=true. For input mode, * To enable the PWM channel output call this function with val=true. For input mode,
* call this function with val=false. * call this function with val=false.
@ -816,6 +815,76 @@ static inline void FTM_SetInvertEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber
/*! @}*/ /*! @}*/
/*!
* @name Quad Decoder
* @{
*/
/*!
* @brief Configures the parameters and activates the quadrature decoder mode.
*
* @param base FTM 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 FTM_SetupQuadDecode(FTM_Type *base,
const ftm_phase_params_t *phaseAParams,
const ftm_phase_params_t *phaseBParams,
ftm_quad_decode_mode_t quadMode);
/*!
* @brief Gets the FTM Quad Decoder flags.
*
* @param base FTM peripheral base address.
* @return Flag mask of FTM Quad Decoder, see #_ftm_quad_decoder_flags.
*/
static inline uint32_t FTM_GetQuadDecoderFlags(FTM_Type *base)
{
return base->QDCTRL & (FTM_QDCTRL_QUADIR_MASK | FTM_QDCTRL_TOFDIR_MASK);
}
/*!
* @brief Sets the modulo values for Quad Decoder.
*
* The modulo values configure the minimum and maximum values that the Quad decoder counter can reach. After the counter goes
* over, the counter value goes to the other side and decrease/increase again.
*
* @param base FTM peripheral base address.
* @param startValue The low limit value for Quad Decoder counter.
* @param overValue The high limit value for Quad Decoder counter.
*/
static inline void FTM_SetQuadDecoderModuloValue(FTM_Type *base, uint32_t startValue, uint32_t overValue)
{
base->CNTIN = startValue;
base->MOD = overValue;
}
/*!
* @brief Gets the current Quad Decoder counter value.
*
* @param base FTM peripheral base address.
* @return Current quad Decoder counter value.
*/
static inline uint32_t FTM_GetQuadDecoderCounterValue(FTM_Type *base)
{
return base->CNT;
}
/*!
* @brief Clears the current Quad Decoder counter value.
*
* The counter is set as the initial value.
*
* @param base FTM peripheral base address.
*/
static inline void FTM_ClearQuadDecoderCounterValue(FTM_Type *base)
{
base->CNT = base->CNTIN;
}
/*! @}*/
/*! /*!
* @brief Enables or disables the FTM software trigger for PWM synchronization. * @brief Enables or disables the FTM software trigger for PWM synchronization.
* *

View File

@ -103,6 +103,14 @@ void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask)
portBase->ISFR = mask; portBase->ISFR = mask;
} }
#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute)
{
base->GACR = ((uint32_t)attribute << GPIO_GACR_ACB0_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB1_SHIFT) |
((uint32_t)attribute << GPIO_GACR_ACB2_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB3_SHIFT);
}
#endif
#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT #if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
/******************************************************************************* /*******************************************************************************
@ -176,4 +184,12 @@ void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask)
portBase->ISFR = mask; portBase->ISFR = mask;
} }
#if defined(FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER
void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute)
{
base->GACR = (attribute << FGPIO_GACR_ACB0_SHIFT) | (attribute << FGPIO_GACR_ACB1_SHIFT) |
(attribute << FGPIO_GACR_ACB2_SHIFT) | (attribute << FGPIO_GACR_ACB3_SHIFT);
}
#endif
#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */ #endif /* FSL_FEATURE_SOC_FGPIO_COUNT */

View File

@ -38,38 +38,60 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief GPIO driver version 2.1.0. */ /*! @brief GPIO driver version 2.1.1. */
#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) #define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 1))
/*@}*/ /*@}*/
/*! @brief GPIO direction definition*/ /*! @brief GPIO direction definition */
typedef enum _gpio_pin_direction typedef enum _gpio_pin_direction
{ {
kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/ kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/
kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/ kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/
} gpio_pin_direction_t; } gpio_pin_direction_t;
#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
/*! @brief GPIO checker attribute */
typedef enum _gpio_checker_attribute
{
kGPIO_UsernonsecureRWUsersecureRWPrivilegedsecureRW =
0x00U, /*!< User nonsecure:Read+Write; User Secure:Read+Write; Privileged Secure:Read+Write */
kGPIO_UsernonsecureRUsersecureRWPrivilegedsecureRW =
0x01U, /*!< User nonsecure:Read; User Secure:Read+Write; Privileged Secure:Read+Write */
kGPIO_UsernonsecureNUsersecureRWPrivilegedsecureRW =
0x02U, /*!< User nonsecure:None; User Secure:Read+Write; Privileged Secure:Read+Write */
kGPIO_UsernonsecureRUsersecureRPrivilegedsecureRW =
0x03U, /*!< User nonsecure:Read; User Secure:Read; Privileged Secure:Read+Write */
kGPIO_UsernonsecureNUsersecureRPrivilegedsecureRW =
0x04U, /*!< User nonsecure:None; User Secure:Read; Privileged Secure:Read+Write */
kGPIO_UsernonsecureNUsersecureNPrivilegedsecureRW =
0x05U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:Read+Write */
kGPIO_UsernonsecureNUsersecureNPrivilegedsecureR =
0x06U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:Read */
kGPIO_UsernonsecureNUsersecureNPrivilegedsecureN =
0x07U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:None */
kGPIO_IgnoreAttributeCheck = 0x10U, /*!< Ignores the attribute check */
} gpio_checker_attribute_t;
#endif
/*! /*!
* @brief The GPIO pin configuration structure. * @brief The GPIO pin configuration structure.
* *
* Every pin can only be configured as either output pin or input pin at a time. * Each pin can only be configured as either an output pin or an input pin at a time.
* If configured as a input pin, then leave the outputConfig unused * If configured as an input pin, leave the outputConfig unused.
* Note : In some cases, the corresponding port property should be configured in advance * Note that in some use cases, the corresponding port property should be configured in advance
* with the PORT_SetPinConfig() * with the PORT_SetPinConfig().
*/ */
typedef struct _gpio_pin_config typedef struct _gpio_pin_config
{ {
gpio_pin_direction_t pinDirection; /*!< gpio direction, input or output */ gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */
/* Output configurations, please ignore if configured as a input one */ /* Output configurations; ignore if configured as an input pin */
uint8_t outputLogic; /*!< Set default output logic, no use in input */ uint8_t outputLogic; /*!< Set a default output logic, which has no use in input */
} gpio_pin_config_t; } gpio_pin_config_t;
/*! @} */ /*! @} */
@ -93,10 +115,10 @@ extern "C" {
/*! /*!
* @brief Initializes a GPIO pin used by the board. * @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. * To initialize the GPIO, define a pin configuration, as either input or output, in the user file.
* Then, call the GPIO_PinInit() function. * Then, call the GPIO_PinInit() function.
* *
* This is an example to define an input pin or output pin configuration: * This is an example to define an input pin or an output pin configuration.
* @code * @code
* // Define a digital input pin configuration, * // Define a digital input pin configuration,
* gpio_pin_config_t config = * gpio_pin_config_t config =
@ -112,7 +134,7 @@ extern "C" {
* } * }
* @endcode * @endcode
* *
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param pin GPIO port pin number * @param pin GPIO port pin number
* @param config GPIO pin configuration pointer * @param config GPIO pin configuration pointer
*/ */
@ -126,29 +148,29 @@ void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config
/*! /*!
* @brief Sets the output level of the multiple GPIO pins to the logic 1 or 0. * @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 base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param pin GPIO pin's number * @param pin GPIO pin number
* @param output GPIO pin output logic level. * @param output GPIO pin output logic level.
* - 0: corresponding pin output low logic level. * - 0: corresponding pin output low-logic level.
* - 1: corresponding pin output high logic level. * - 1: corresponding pin output high-logic level.
*/ */
static inline void GPIO_WritePinOutput(GPIO_Type *base, uint32_t pin, uint8_t output) static inline void GPIO_WritePinOutput(GPIO_Type *base, uint32_t pin, uint8_t output)
{ {
if (output == 0U) if (output == 0U)
{ {
base->PCOR = 1 << pin; base->PCOR = 1U << pin;
} }
else else
{ {
base->PSOR = 1 << pin; base->PSOR = 1U << pin;
} }
} }
/*! /*!
* @brief Sets the output level of the multiple GPIO pins to the logic 1. * @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 base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pins' numbers macro * @param mask GPIO pin number macro
*/ */
static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask) static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask)
{ {
@ -158,8 +180,8 @@ static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask)
/*! /*!
* @brief Sets the output level of the multiple GPIO pins to the logic 0. * @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 base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pins' numbers macro * @param mask GPIO pin number macro
*/ */
static inline void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask) static inline void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask)
{ {
@ -167,10 +189,10 @@ static inline void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask)
} }
/*! /*!
* @brief Reverses current output logic of the multiple GPIO pins. * @brief Reverses the current output logic of the multiple GPIO pins.
* *
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pins' numbers macro * @param mask GPIO pin number macro
*/ */
static inline void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t mask) static inline void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t mask)
{ {
@ -182,13 +204,13 @@ static inline void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t mask)
/*@{*/ /*@{*/
/*! /*!
* @brief Reads the current input value of the whole GPIO port. * @brief Reads the current input value of the GPIO port.
* *
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param pin GPIO pin's number * @param pin GPIO pin number
* @retval GPIO port input value * @retval GPIO port input value
* - 0: corresponding pin input low logic level. * - 0: corresponding pin input low-logic level.
* - 1: corresponding pin input high logic level. * - 1: corresponding pin input high-logic level.
*/ */
static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin) static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin)
{ {
@ -200,7 +222,7 @@ static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin)
/*@{*/ /*@{*/
/*! /*!
* @brief Reads whole GPIO port interrupt status flag. * @brief Reads the GPIO port interrupt status flag.
* *
* If a pin is configured to generate the DMA request, the corresponding 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. * is cleared automatically at the completion of the requested DMA transfer.
@ -208,20 +230,34 @@ static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin)
* If configured for a level sensitive interrupt that remains asserted, the flag * If configured for a level sensitive interrupt that remains asserted, the flag
* is set again immediately. * is set again immediately.
* *
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @retval Current GPIO port interrupt status flag, for example, 0x00010001 means the * @retval The current GPIO port interrupt status flag, for example, 0x00010001 means the
* pin 0 and 17 have the interrupt. * pin 0 and 17 have the interrupt.
*/ */
uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base); uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base);
/*! /*!
* @brief Clears multiple GPIO pins' interrupt status flag. * @brief Clears multiple GPIO pin interrupt status flags.
* *
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pins' numbers macro * @param mask GPIO pin number macro
*/ */
void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask); void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask);
#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
/*!
* @brief The GPIO module supports a device-specific number of data ports, organized as 32-bit
* words. Each 32-bit data port includes a GACR register, which defines the byte-level
* attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data
* bytes in the GACR follow a standard little endian
* data convention.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute);
#endif
/*@}*/ /*@}*/
/*! @} */ /*! @} */
@ -231,10 +267,10 @@ void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask);
*/ */
/* /*
* Introduce the FGPIO feature. * Introduces the FGPIO feature.
* *
* The FGPIO features are only support on some of Kinetis chips. The FGPIO registers are aliased to the IOPORT * The FGPIO features are only support on some Kinetis MCUs. The FGPIO registers are aliased to the IOPORT
* interface. Accesses via the IOPORT interface occur in parallel with any instruction fetches and will therefore * interface. Accesses via the IOPORT interface occur in parallel with any instruction fetches and
* complete in a single cycle. This aliased Fast GPIO memory map is called FGPIO. * complete in a single cycle. This aliased Fast GPIO memory map is called FGPIO.
*/ */
@ -246,10 +282,10 @@ void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask);
/*! /*!
* @brief Initializes a FGPIO pin used by the board. * @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. * To initialize the FGPIO driver, define a pin configuration, as either input or output, in the user file.
* Then, call the FGPIO_PinInit() function. * Then, call the FGPIO_PinInit() function.
* *
* This is an example to define an input pin or output pin configuration: * This is an example to define an input pin or an output pin configuration:
* @code * @code
* // Define a digital input pin configuration, * // Define a digital input pin configuration,
* gpio_pin_config_t config = * gpio_pin_config_t config =
@ -265,7 +301,7 @@ void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask);
* } * }
* @endcode * @endcode
* *
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param pin FGPIO port pin number * @param pin FGPIO port pin number
* @param config FGPIO pin configuration pointer * @param config FGPIO pin configuration pointer
*/ */
@ -279,11 +315,11 @@ void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *conf
/*! /*!
* @brief Sets the output level of the multiple FGPIO pins to the logic 1 or 0. * @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 base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param pin FGPIO pin's number * @param pin FGPIO pin number
* @param output FGPIOpin output logic level. * @param output FGPIOpin output logic level.
* - 0: corresponding pin output low logic level. * - 0: corresponding pin output low-logic level.
* - 1: corresponding pin output high logic level. * - 1: corresponding pin output high-logic level.
*/ */
static inline void FGPIO_WritePinOutput(FGPIO_Type *base, uint32_t pin, uint8_t output) static inline void FGPIO_WritePinOutput(FGPIO_Type *base, uint32_t pin, uint8_t output)
{ {
@ -300,8 +336,8 @@ static inline void FGPIO_WritePinOutput(FGPIO_Type *base, uint32_t pin, uint8_t
/*! /*!
* @brief Sets the output level of the multiple FGPIO pins to the logic 1. * @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 base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param mask FGPIO pins' numbers macro * @param mask FGPIO pin number macro
*/ */
static inline void FGPIO_SetPinsOutput(FGPIO_Type *base, uint32_t mask) static inline void FGPIO_SetPinsOutput(FGPIO_Type *base, uint32_t mask)
{ {
@ -311,8 +347,8 @@ static inline void FGPIO_SetPinsOutput(FGPIO_Type *base, uint32_t mask)
/*! /*!
* @brief Sets the output level of the multiple FGPIO pins to the logic 0. * @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 base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param mask FGPIO pins' numbers macro * @param mask FGPIO pin number macro
*/ */
static inline void FGPIO_ClearPinsOutput(FGPIO_Type *base, uint32_t mask) static inline void FGPIO_ClearPinsOutput(FGPIO_Type *base, uint32_t mask)
{ {
@ -320,10 +356,10 @@ static inline void FGPIO_ClearPinsOutput(FGPIO_Type *base, uint32_t mask)
} }
/*! /*!
* @brief Reverses current output logic of the multiple FGPIO pins. * @brief Reverses the current output logic of the multiple FGPIO pins.
* *
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param mask FGPIO pins' numbers macro * @param mask FGPIO pin number macro
*/ */
static inline void FGPIO_TogglePinsOutput(FGPIO_Type *base, uint32_t mask) static inline void FGPIO_TogglePinsOutput(FGPIO_Type *base, uint32_t mask)
{ {
@ -335,13 +371,13 @@ static inline void FGPIO_TogglePinsOutput(FGPIO_Type *base, uint32_t mask)
/*@{*/ /*@{*/
/*! /*!
* @brief Reads the current input value of the whole FGPIO port. * @brief Reads the current input value of the FGPIO port.
* *
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param pin FGPIO pin's number * @param pin FGPIO pin number
* @retval FGPIO port input value * @retval FGPIO port input value
* - 0: corresponding pin input low logic level. * - 0: corresponding pin input low-logic level.
* - 1: corresponding pin input high logic level. * - 1: corresponding pin input high-logic level.
*/ */
static inline uint32_t FGPIO_ReadPinInput(FGPIO_Type *base, uint32_t pin) static inline uint32_t FGPIO_ReadPinInput(FGPIO_Type *base, uint32_t pin)
{ {
@ -353,28 +389,42 @@ static inline uint32_t FGPIO_ReadPinInput(FGPIO_Type *base, uint32_t pin)
/*@{*/ /*@{*/
/*! /*!
* @brief Reads the whole FGPIO port interrupt status flag. * @brief Reads the FGPIO port interrupt status flag.
* *
* If a pin is configured to generate the DMA request, the corresponding 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. * 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. * 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 * If configured for a level-sensitive interrupt that remains asserted, the flag
* is set again immediately. * is set again immediately.
* *
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @retval Current FGPIO port interrupt status flags, for example, 0x00010001 means the * @retval The current FGPIO port interrupt status flags, for example, 0x00010001 means the
* pin 0 and 17 have the interrupt. * pin 0 and 17 have the interrupt.
*/ */
uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base); uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base);
/*! /*!
* @brief Clears the multiple FGPIO pins' interrupt status flag. * @brief Clears the multiple FGPIO pin interrupt status flag.
* *
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param mask FGPIO pins' numbers macro * @param mask FGPIO pin number macro
*/ */
void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask); void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask);
#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
/*!
* @brief The FGPIO module supports a device-specific number of data ports, organized as 32-bit
* words. Each 32-bit data port includes a GACR register, which defines the byte-level
* attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data
* bytes in the GACR follow a standard little endian
* data convention.
*
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param mask FGPIO pin number macro
*/
void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute);
#endif
/*@}*/ /*@}*/
#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */ #endif /* FSL_FEATURE_SOC_FGPIO_COUNT */

View File

@ -75,6 +75,19 @@ typedef void (*i2c_isr_t)(I2C_Type *base, void *i2cHandle);
*/ */
uint32_t I2C_GetInstance(I2C_Type *base); uint32_t I2C_GetInstance(I2C_Type *base);
/*!
* @brief Set SCL/SDA hold time, this API receives SCL stop hold time, calculate the
* closest SCL divider and MULT value for the SDA hold time, SCL start and SCL stop
* hold time. To reduce the ROM size, SDA/SCL hold value mapping table is not provided,
* assume SCL divider = SCL stop hold value *2 to get the closest SCL divider value and MULT
* value, then the related SDA hold time, SCL start and SCL stop hold time is used.
*
* @param base I2C peripheral base address.
* @param sourceClock_Hz I2C functional clock frequency in Hertz.
* @param sclStopHoldTime_ns SCL stop hold time in ns.
*/
static void I2C_SetHoldTime(I2C_Type *base, uint32_t sclStopHoldTime_ns, uint32_t sourceClock_Hz);
/*! /*!
* @brief Set up master transfer, send slave address and decide the initial * @brief Set up master transfer, send slave address and decide the initial
* transfer state. * transfer state.
@ -125,20 +138,22 @@ static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle);
static void *s_i2cHandle[FSL_FEATURE_SOC_I2C_COUNT] = {NULL}; static void *s_i2cHandle[FSL_FEATURE_SOC_I2C_COUNT] = {NULL};
/*! @brief SCL clock divider used to calculate baudrate. */ /*! @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, static const uint16_t s_i2cDividerTable[] = {
48, 56, 68, 48, 56, 64, 72, 80, 88, 104, 128, 80, 96, 20, 22, 24, 26, 28, 30, 34, 40, 28, 32, 36, 40, 44, 48, 56, 68,
112, 128, 144, 160, 192, 240, 160, 192, 224, 256, 288, 320, 384, 48, 56, 64, 72, 80, 88, 104, 128, 80, 96, 112, 128, 144, 160, 192, 240,
480, 320, 384, 448, 512, 576, 640, 768, 960, 640, 768, 896, 1024, 160, 192, 224, 256, 288, 320, 384, 480, 320, 384, 448, 512, 576, 640, 768, 960,
1152, 1280, 1536, 1920, 1280, 1536, 1792, 2048, 2304, 2560, 3072, 3840}; 640, 768, 896, 1024, 1152, 1280, 1536, 1920, 1280, 1536, 1792, 2048, 2304, 2560, 3072, 3840};
/*! @brief Pointers to i2c bases for each instance. */ /*! @brief Pointers to i2c bases for each instance. */
static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS; static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS;
/*! @brief Pointers to i2c IRQ number for each instance. */ /*! @brief Pointers to i2c IRQ number for each instance. */
const IRQn_Type s_i2cIrqs[] = I2C_IRQS; static const IRQn_Type s_i2cIrqs[] = I2C_IRQS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to i2c clocks for each instance. */ /*! @brief Pointers to i2c clocks for each instance. */
const clock_ip_name_t s_i2cClocks[] = I2C_CLOCKS; static const clock_ip_name_t s_i2cClocks[] = I2C_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*! @brief Pointer to master IRQ handler for each instance. */ /*! @brief Pointer to master IRQ handler for each instance. */
static i2c_isr_t s_i2cMasterIsr; static i2c_isr_t s_i2cMasterIsr;
@ -168,11 +183,58 @@ uint32_t I2C_GetInstance(I2C_Type *base)
return instance; return instance;
} }
static void I2C_SetHoldTime(I2C_Type *base, uint32_t sclStopHoldTime_ns, uint32_t sourceClock_Hz)
{
uint32_t multiplier;
uint32_t computedSclHoldTime;
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. */
/* SDA hold time = bus period (s) * mul * SDA hold value. */
/* SCL start hold time = bus period (s) * mul * SCL start hold value. */
/* SCL stop hold time = bus period (s) * mul * SCL stop hold value. */
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(s_i2cDividerTable[0]); ++i)
{
/* Assume SCL hold(stop) value = s_i2cDividerTable[i]/2. */
computedSclHoldTime = ((multiplier * s_i2cDividerTable[i]) * 500000000U) / sourceClock_Hz;
absError = sclStopHoldTime_ns > computedSclHoldTime ? (sclStopHoldTime_ns - computedSclHoldTime) :
(computedSclHoldTime - sclStopHoldTime_ns);
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);
}
static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer) static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer)
{ {
status_t result = kStatus_Success; status_t result = kStatus_Success;
i2c_direction_t direction = xfer->direction; i2c_direction_t direction = xfer->direction;
uint16_t timeout = UINT16_MAX;
/* Initialize the handle transfer information. */ /* Initialize the handle transfer information. */
handle->transfer = *xfer; handle->transfer = *xfer;
@ -183,27 +245,13 @@ static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t
/* Initial transfer state. */ /* Initial transfer state. */
if (handle->transfer.subaddressSize > 0) if (handle->transfer.subaddressSize > 0)
{ {
handle->state = kSendCommandState;
if (xfer->direction == kI2C_Read) if (xfer->direction == kI2C_Read)
{ {
direction = kI2C_Write; direction = kI2C_Write;
} }
} }
else
{
handle->state = kCheckAddressState;
}
/* Wait until the data register is ready for transmit. */ handle->state = kCheckAddressState;
while ((!(base->S & kI2C_TransferCompleteFlag)) && (--timeout))
{
}
/* Failed to start the transfer. */
if (timeout == 0)
{
return kStatus_I2C_Timeout;
}
/* Clear all status before transfer. */ /* Clear all status before transfer. */
I2C_MasterClearStatusFlags(base, kClearFlags); I2C_MasterClearStatusFlags(base, kClearFlags);
@ -265,34 +313,41 @@ static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_han
result = kStatus_Success; result = kStatus_Success;
} }
if (result)
{
return result;
}
/* Handle Check address state to check the slave address is Acked in slave /* Handle Check address state to check the slave address is Acked in slave
probe application. */ probe application. */
if (handle->state == kCheckAddressState) if (handle->state == kCheckAddressState)
{ {
if (statusFlags & kI2C_ReceiveNakFlag) if (statusFlags & kI2C_ReceiveNakFlag)
{ {
return kStatus_I2C_Nak; result = kStatus_I2C_Addr_Nak;
} }
else else
{ {
if (handle->transfer.direction == kI2C_Write) if (handle->transfer.subaddressSize > 0)
{ {
/* Next state, send data. */ handle->state = kSendCommandState;
handle->state = kSendDataState;
} }
else else
{ {
/* Next state, receive data begin. */ if (handle->transfer.direction == kI2C_Write)
handle->state = kReceiveDataBeginState; {
/* Next state, send data. */
handle->state = kSendDataState;
}
else
{
/* Next state, receive data begin. */
handle->state = kReceiveDataBeginState;
}
} }
} }
} }
if (result)
{
return result;
}
/* Run state machine. */ /* Run state machine. */
switch (handle->state) switch (handle->state)
{ {
@ -375,6 +430,10 @@ static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_han
{ {
result = I2C_MasterStop(base); result = I2C_MasterStop(base);
} }
else
{
base->C1 |= I2C_C1_TX_MASK;
}
} }
/* Send NAK at the last receive byte. */ /* Send NAK at the last receive byte. */
@ -407,6 +466,7 @@ static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle)
{ {
s_i2cSlaveIsr(base, handle); s_i2cSlaveIsr(base, handle);
} }
__DSB();
} }
void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz) void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
@ -418,9 +478,13 @@ void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uin
#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION #if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION
uint8_t c2Reg; uint8_t c2Reg;
#endif #endif
#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
uint8_t s2Reg;
#endif
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable I2C clock. */ /* Enable I2C clock. */
CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]); CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Disable I2C prior to configuring it. */ /* Disable I2C prior to configuring it. */
base->C1 &= ~(I2C_C1_IICEN_MASK); base->C1 &= ~(I2C_C1_IICEN_MASK);
@ -455,6 +519,12 @@ void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uin
/* Write the register value back to the filter register. */ /* Write the register value back to the filter register. */
base->FLT = fltReg; base->FLT = fltReg;
/* Enable/Disable double buffering. */
#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
s2Reg = base->S2 & (~I2C_S2_DFEN_MASK);
base->S2 = s2Reg | I2C_S2_DFEN(masterConfig->enableDoubleBuffering);
#endif
/* Enable the I2C peripheral based on the configuration. */ /* Enable the I2C peripheral based on the configuration. */
base->C1 = I2C_C1_IICEN(masterConfig->enableMaster); base->C1 = I2C_C1_IICEN(masterConfig->enableMaster);
} }
@ -464,8 +534,10 @@ void I2C_MasterDeinit(I2C_Type *base)
/* Disable I2C module. */ /* Disable I2C module. */
I2C_Enable(base, false); I2C_Enable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable I2C clock. */ /* Disable I2C clock. */
CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]); CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig) void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig)
@ -488,12 +560,21 @@ void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig)
/* Default glitch filter value is no filter. */ /* Default glitch filter value is no filter. */
masterConfig->glitchFilterWidth = 0U; masterConfig->glitchFilterWidth = 0U;
/* Default enable double buffering. */
#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
masterConfig->enableDoubleBuffering = true;
#endif
/* Enable the I2C peripheral. */ /* Enable the I2C peripheral. */
masterConfig->enableMaster = true; masterConfig->enableMaster = true;
} }
void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask) void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask)
{ {
#ifdef I2C_HAS_STOP_DETECT
uint8_t fltReg;
#endif
if (mask & kI2C_GlobalInterruptEnable) if (mask & kI2C_GlobalInterruptEnable)
{ {
base->C1 |= I2C_C1_IICIE_MASK; base->C1 |= I2C_C1_IICIE_MASK;
@ -502,14 +583,28 @@ void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask)
#if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT #if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
if (mask & kI2C_StopDetectInterruptEnable) if (mask & kI2C_StopDetectInterruptEnable)
{ {
base->FLT |= I2C_FLT_STOPIE_MASK; fltReg = base->FLT;
/* Keep STOPF flag. */
fltReg &= ~I2C_FLT_STOPF_MASK;
/* Stop detect enable. */
fltReg |= I2C_FLT_STOPIE_MASK;
base->FLT = fltReg;
} }
#endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */ #endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */
#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
if (mask & kI2C_StartStopDetectInterruptEnable) if (mask & kI2C_StartStopDetectInterruptEnable)
{ {
base->FLT |= I2C_FLT_SSIE_MASK; fltReg = base->FLT;
/* Keep STARTF and STOPF flags. */
fltReg &= ~(I2C_FLT_STOPF_MASK | I2C_FLT_STARTF_MASK);
/* Start and stop detect enable. */
fltReg |= I2C_FLT_SSIE_MASK;
base->FLT = fltReg;
} }
#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
} }
@ -524,14 +619,14 @@ void I2C_DisableInterrupts(I2C_Type *base, uint32_t mask)
#if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT #if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
if (mask & kI2C_StopDetectInterruptEnable) if (mask & kI2C_StopDetectInterruptEnable)
{ {
base->FLT &= ~I2C_FLT_STOPIE_MASK; base->FLT &= ~(I2C_FLT_STOPIE_MASK | I2C_FLT_STOPF_MASK);
} }
#endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */ #endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */
#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
if (mask & kI2C_StartStopDetectInterruptEnable) if (mask & kI2C_StartStopDetectInterruptEnable)
{ {
base->FLT &= ~I2C_FLT_SSIE_MASK; base->FLT &= ~(I2C_FLT_SSIE_MASK | I2C_FLT_STOPF_MASK | I2C_FLT_STARTF_MASK);
} }
#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
} }
@ -623,7 +718,7 @@ status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_
base->F = savedMult & (~I2C_F_MULT_MASK); base->F = savedMult & (~I2C_F_MULT_MASK);
/* We are already in a transfer, so send a repeated start. */ /* We are already in a transfer, so send a repeated start. */
base->C1 |= I2C_C1_RSTA_MASK; base->C1 |= I2C_C1_RSTA_MASK | I2C_C1_TX_MASK;
/* Restore the multiplier factor. */ /* Restore the multiplier factor. */
base->F = savedMult; base->F = savedMult;
@ -690,7 +785,7 @@ uint32_t I2C_MasterGetStatusFlags(I2C_Type *base)
return statusFlags; return statusFlags;
} }
status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize) status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize, uint32_t flags)
{ {
status_t result = kStatus_Success; status_t result = kStatus_Success;
uint8_t statusFlags = 0; uint8_t statusFlags = 0;
@ -728,7 +823,7 @@ status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t t
result = kStatus_I2C_ArbitrationLost; result = kStatus_I2C_ArbitrationLost;
} }
if (statusFlags & kI2C_ReceiveNakFlag) if ((statusFlags & kI2C_ReceiveNakFlag) && txSize)
{ {
base->S = kI2C_ReceiveNakFlag; base->S = kI2C_ReceiveNakFlag;
result = kStatus_I2C_Nak; result = kStatus_I2C_Nak;
@ -741,10 +836,19 @@ status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t t
} }
} }
if (((result == kStatus_Success) && (!(flags & kI2C_TransferNoStopFlag))) || (result == kStatus_I2C_Nak))
{
/* Clear the IICIF flag. */
base->S = kI2C_IntPendingFlag;
/* Send stop. */
result = I2C_MasterStop(base);
}
return result; return result;
} }
status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize) status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize, uint32_t flags)
{ {
status_t result = kStatus_Success; status_t result = kStatus_Success;
volatile uint8_t dummy = 0; volatile uint8_t dummy = 0;
@ -786,8 +890,16 @@ status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize)
/* Single byte use case. */ /* Single byte use case. */
if (rxSize == 0) if (rxSize == 0)
{ {
/* Read the final byte. */ if (!(flags & kI2C_TransferNoStopFlag))
result = I2C_MasterStop(base); {
/* Issue STOP command before reading last byte. */
result = I2C_MasterStop(base);
}
else
{
/* Change direction to Tx to avoid extra clocks. */
base->C1 |= I2C_C1_TX_MASK;
}
} }
if (rxSize == 1) if (rxSize == 1)
@ -840,72 +952,6 @@ status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
return 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)) while (!(base->S & kI2C_IntPendingFlag))
{ {
} }
@ -918,32 +964,92 @@ status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
{ {
if (result == kStatus_I2C_Nak) if (result == kStatus_I2C_Nak)
{ {
result = kStatus_I2C_Addr_Nak;
I2C_MasterStop(base); I2C_MasterStop(base);
} }
return result; return result;
} }
/* Send subaddress. */
if (xfer->subaddressSize)
{
do
{
/* Clear interrupt pending flag. */
base->S = kI2C_IntPendingFlag;
xfer->subaddressSize--;
base->D = ((xfer->subaddress) >> (8 * xfer->subaddressSize));
/* Wait until data transfer complete. */
while (!(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;
}
} while ((xfer->subaddressSize > 0) && (result == kStatus_Success));
if (xfer->direction == kI2C_Read)
{
/* Clear pending flag. */
base->S = kI2C_IntPendingFlag;
/* Send repeated start and slave address. */
result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, kI2C_Read);
/* Return if error. */
if (result)
{
return result;
}
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
/* Check if there's transfer error. */
result = I2C_CheckAndClearError(base, base->S);
if (result)
{
if (result == kStatus_I2C_Nak)
{
result = kStatus_I2C_Addr_Nak;
I2C_MasterStop(base);
}
return result;
}
}
}
/* Transmit data. */ /* Transmit data. */
if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0)) if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0))
{ {
/* Send Data. */ /* Send Data. */
result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize); result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
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. */ /* Receive Data. */
if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0)) if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0))
{ {
result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize); result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
} }
return result; return result;
@ -1006,11 +1112,37 @@ void I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle)
{ {
assert(handle); assert(handle);
volatile uint8_t dummy = 0;
/* Add this to avoid build warning. */
dummy++;
/* Disable interrupt. */ /* Disable interrupt. */
I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable); I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable);
/* Reset the state to idle. */ /* Reset the state to idle. */
handle->state = kIdleState; handle->state = kIdleState;
/* Send STOP signal. */
if (handle->transfer.direction == kI2C_Read)
{
base->C1 |= I2C_C1_TXAK_MASK;
while (!(base->S & kI2C_IntPendingFlag))
{
}
base->S = kI2C_IntPendingFlag;
base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
dummy = base->D;
}
else
{
while (!(base->S & kI2C_IntPendingFlag))
{
}
base->S = kI2C_IntPendingFlag;
base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
}
} }
status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count) status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count)
@ -1044,7 +1176,8 @@ void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
if (isDone || result) if (isDone || result)
{ {
/* Send stop command if transfer done or received Nak. */ /* Send stop command if transfer done or received Nak. */
if ((!(handle->transfer.flags & kI2C_TransferNoStopFlag)) || (result == kStatus_I2C_Nak)) if ((!(handle->transfer.flags & kI2C_TransferNoStopFlag)) || (result == kStatus_I2C_Nak) ||
(result == kStatus_I2C_Addr_Nak))
{ {
/* Ensure stop command is a need. */ /* Ensure stop command is a need. */
if ((base->C1 & I2C_C1_MST_MASK)) if ((base->C1 & I2C_C1_MST_MASK))
@ -1070,13 +1203,15 @@ void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
} }
} }
void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig) void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz)
{ {
assert(slaveConfig); assert(slaveConfig);
uint8_t tmpReg; uint8_t tmpReg;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]); CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure addressing mode. */ /* Configure addressing mode. */
switch (slaveConfig->addressingMode) switch (slaveConfig->addressingMode)
@ -1110,6 +1245,15 @@ void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig)
tmpReg |= I2C_C2_HDRS(slaveConfig->enableHighDrive); tmpReg |= I2C_C2_HDRS(slaveConfig->enableHighDrive);
#endif #endif
base->C2 = tmpReg; base->C2 = tmpReg;
/* Enable/Disable double buffering. */
#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
tmpReg = base->S2 & (~I2C_S2_DFEN_MASK);
base->S2 = tmpReg | I2C_S2_DFEN(slaveConfig->enableDoubleBuffering);
#endif
/* Set hold time. */
I2C_SetHoldTime(base, slaveConfig->sclStopHoldTime_ns, srcClock_Hz);
} }
void I2C_SlaveDeinit(I2C_Type *base) void I2C_SlaveDeinit(I2C_Type *base)
@ -1117,8 +1261,10 @@ void I2C_SlaveDeinit(I2C_Type *base)
/* Disable I2C module. */ /* Disable I2C module. */
I2C_Enable(base, false); I2C_Enable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable I2C clock. */ /* Disable I2C clock. */
CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]); CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig) void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig)
@ -1142,40 +1288,103 @@ void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig)
/* Independent slave mode baud rate at maximum frequency is disabled. */ /* Independent slave mode baud rate at maximum frequency is disabled. */
slaveConfig->enableBaudRateCtl = false; slaveConfig->enableBaudRateCtl = false;
/* Default enable double buffering. */
#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
slaveConfig->enableDoubleBuffering = true;
#endif
/* Set default SCL stop hold time to 4us which is minimum requirement in I2C spec. */
slaveConfig->sclStopHoldTime_ns = 4000;
/* Enable the I2C peripheral. */ /* Enable the I2C peripheral. */
slaveConfig->enableSlave = true; slaveConfig->enableSlave = true;
} }
status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize) status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize)
{ {
return I2C_MasterWriteBlocking(base, txBuff, txSize); status_t result = kStatus_Success;
volatile uint8_t dummy = 0;
/* Add this to avoid build warning. */
dummy++;
#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
/* Check start flag. */
while (!(base->FLT & I2C_FLT_STARTF_MASK))
{
}
/* Clear STARTF flag. */
base->FLT |= I2C_FLT_STARTF_MASK;
/* Clear the IICIF flag. */
base->S = kI2C_IntPendingFlag;
#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
/* Wait for address match flag. */
while (!(base->S & kI2C_AddressMatchFlag))
{
}
/* Read dummy to release bus. */
dummy = base->D;
result = I2C_MasterWriteBlocking(base, txBuff, txSize, kI2C_TransferDefaultFlag);
/* Switch to receive mode. */
base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
/* Read dummy to release bus. */
dummy = base->D;
return result;
} }
void I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize) void I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize)
{ {
/* Clear the IICIF flag. */ volatile uint8_t dummy = 0;
base->S = kI2C_IntPendingFlag;
/* Wait until the data register is ready for receive. */ /* Add this to avoid build warning. */
while (!(base->S & kI2C_TransferCompleteFlag)) dummy++;
/* Wait until address match. */
#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
/* Check start flag. */
while (!(base->FLT & I2C_FLT_STARTF_MASK))
{ {
} }
/* Clear STARTF flag. */
base->FLT |= I2C_FLT_STARTF_MASK;
/* Clear the IICIF flag. */
base->S = kI2C_IntPendingFlag;
#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
/* Wait for address match and int pending flag. */
while (!(base->S & kI2C_AddressMatchFlag))
{
}
while (!(base->S & kI2C_IntPendingFlag))
{
}
/* Read dummy to release bus. */
dummy = base->D;
/* Clear the IICIF flag. */
base->S = kI2C_IntPendingFlag;
/* Setup the I2C peripheral to receive data. */ /* Setup the I2C peripheral to receive data. */
base->C1 &= ~(I2C_C1_TX_MASK); base->C1 &= ~(I2C_C1_TX_MASK);
while (rxSize--) while (rxSize--)
{ {
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
/* Clear the IICIF flag. */ /* Clear the IICIF flag. */
base->S = kI2C_IntPendingFlag; base->S = kI2C_IntPendingFlag;
/* Read from the data register. */ /* Read from the data register. */
*rxBuff++ = base->D; *rxBuff++ = base->D;
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
} }
} }
@ -1226,7 +1435,7 @@ status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle
handle->isBusy = true; handle->isBusy = true;
/* Set up event mask. tx and rx are always enabled. */ /* Set up event mask. tx and rx are always enabled. */
handle->eventMask = eventMask | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent; handle->eventMask = eventMask | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent | kI2C_SlaveGenaralcallEvent;
/* Clear all flags. */ /* Clear all flags. */
I2C_SlaveClearStatusFlags(base, kClearFlags); I2C_SlaveClearStatusFlags(base, kClearFlags);
@ -1328,7 +1537,7 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
/* Clear the interrupt flag. */ /* Clear the interrupt flag. */
base->S = kI2C_IntPendingFlag; base->S = kI2C_IntPendingFlag;
xfer->event = kI2C_SlaveRepeatedStartEvent; xfer->event = kI2C_SlaveStartEvent;
if ((handle->eventMask & xfer->event) && (handle->callback)) if ((handle->eventMask & xfer->event) && (handle->callback))
{ {
@ -1385,31 +1594,12 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
handle->isBusy = true; handle->isBusy = true;
xfer->event = kI2C_SlaveAddressMatchEvent; xfer->event = kI2C_SlaveAddressMatchEvent;
if ((handle->eventMask & xfer->event) && (handle->callback))
{
handle->callback(base, xfer, handle->userData);
}
/* Slave transmit, master reading from slave. */ /* Slave transmit, master reading from slave. */
if (status & kI2C_TransferDirectionFlag) if (status & kI2C_TransferDirectionFlag)
{ {
/* Change direction to send data. */ /* Change direction to send data. */
base->C1 |= I2C_C1_TX_MASK; 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; doTransmit = true;
} }
else else
@ -1417,6 +1607,30 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
/* Slave receive, master writing to slave. */ /* Slave receive, master writing to slave. */
base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
/* Read dummy to release the bus. */
dummy = base->D;
if (dummy == 0)
{
xfer->event = kI2C_SlaveGenaralcallEvent;
}
}
if ((handle->eventMask & xfer->event) && (handle->callback))
{
handle->callback(base, xfer, handle->userData);
}
}
/* Check transfer complete flag. */
else if (status & kI2C_TransferCompleteFlag)
{
/* Slave transmit, master reading from slave. */
if (status & kI2C_TransferDirectionFlag)
{
doTransmit = true;
}
else
{
/* If we're out of data, invoke callback to get more. */ /* If we're out of data, invoke callback to get more. */
if ((!xfer->data) || (!xfer->dataSize)) if ((!xfer->data) || (!xfer->dataSize))
{ {
@ -1431,20 +1645,6 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
xfer->transferredCount = 0; 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. */ /* Slave receive, master writing to slave. */
uint8_t data = base->D; uint8_t data = base->D;
@ -1480,6 +1680,20 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
/* Send data if there is the need. */ /* Send data if there is the need. */
if (doTransmit) if (doTransmit)
{ {
/* 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;
}
if (handle->transfer.dataSize) if (handle->transfer.dataSize)
{ {
/* Send data. */ /* Send data. */

View File

@ -37,16 +37,14 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief I2C driver version 2.0.0. */ /*! @brief I2C driver version 2.0.2. */
#define FSL_I2C_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) #define FSL_I2C_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
/*@}*/ /*@}*/
#if (defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT || \ #if (defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT || \
@ -62,6 +60,7 @@ enum _i2c_status
kStatus_I2C_Nak = MAKE_STATUS(kStatusGroup_I2C, 2), /*!< NAK received during transfer. */ 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_ArbitrationLost = MAKE_STATUS(kStatusGroup_I2C, 3), /*!< Arbitration lost during transfer. */
kStatus_I2C_Timeout = MAKE_STATUS(kStatusGroup_I2C, 4), /*!< Wait event timeout. */ kStatus_I2C_Timeout = MAKE_STATUS(kStatusGroup_I2C, 4), /*!< Wait event timeout. */
kStatus_I2C_Addr_Nak = MAKE_STATUS(kStatusGroup_I2C, 5), /*!< NAK received during the address probe. */
}; };
/*! /*!
@ -109,11 +108,11 @@ enum _i2c_interrupt_enable
#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
}; };
/*! @brief Direction of master and slave transfers. */ /*! @brief The direction of master and slave transfers. */
typedef enum _i2c_direction typedef enum _i2c_direction
{ {
kI2C_Write = 0x0U, /*!< Master transmit to slave. */ kI2C_Write = 0x0U, /*!< Master transmits to the slave. */
kI2C_Read = 0x1U, /*!< Master receive from slave. */ kI2C_Read = 0x1U, /*!< Master receives from the slave. */
} i2c_direction_t; } i2c_direction_t;
/*! @brief Addressing mode. */ /*! @brief Addressing mode. */
@ -126,17 +125,17 @@ typedef enum _i2c_slave_address_mode
/*! @brief I2C transfer control flag. */ /*! @brief I2C transfer control flag. */
enum _i2c_master_transfer_flags enum _i2c_master_transfer_flags
{ {
kI2C_TransferDefaultFlag = 0x0U, /*!< Transfer starts with a start signal, stops with a stop signal. */ kI2C_TransferDefaultFlag = 0x0U, /*!< A transfer starts with a start signal, stops with a stop signal. */
kI2C_TransferNoStartFlag = 0x1U, /*!< Transfer starts without a start signal. */ kI2C_TransferNoStartFlag = 0x1U, /*!< A transfer starts without a start signal. */
kI2C_TransferRepeatedStartFlag = 0x2U, /*!< Transfer starts with a repeated start signal. */ kI2C_TransferRepeatedStartFlag = 0x2U, /*!< A transfer starts with a repeated start signal. */
kI2C_TransferNoStopFlag = 0x4U, /*!< Transfer ends without a stop signal. */ kI2C_TransferNoStopFlag = 0x4U, /*!< A transfer ends without a stop signal. */
}; };
/*! /*!
* @brief Set of events sent to the callback for nonblocking slave transfers. * @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 * 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. * events is passed to I2C_SlaveTransferNonBlocking() to specify which events to enable.
* Then, when the slave callback is invoked, it is passed the current event through its @a transfer * Then, when the slave callback is invoked, it is passed the current event through its @a transfer
* parameter. * parameter.
* *
@ -145,22 +144,23 @@ enum _i2c_master_transfer_flags
typedef enum _i2c_slave_transfer_event typedef enum _i2c_slave_transfer_event
{ {
kI2C_SlaveAddressMatchEvent = 0x01U, /*!< Received the slave address after a start or repeated start. */ kI2C_SlaveAddressMatchEvent = 0x01U, /*!< Received the slave address after a start or repeated start. */
kI2C_SlaveTransmitEvent = 0x02U, /*!< Callback is requested to provide data to transmit kI2C_SlaveTransmitEvent = 0x02U, /*!< A callback is requested to provide data to transmit
(slave-transmitter role). */ (slave-transmitter role). */
kI2C_SlaveReceiveEvent = 0x04U, /*!< Callback is requested to provide a buffer in which to place received kI2C_SlaveReceiveEvent = 0x04U, /*!< A callback is requested to provide a buffer in which to place received
data (slave-receiver role). */ data (slave-receiver role). */
kI2C_SlaveTransmitAckEvent = 0x08U, /*!< Callback needs to either transmit an ACK or NACK. */ kI2C_SlaveTransmitAckEvent = 0x08U, /*!< A 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 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
kI2C_SlaveRepeatedStartEvent = 0x10U, /*!< A repeated start was detected. */ kI2C_SlaveStartEvent = 0x10U, /*!< A start/repeated start was detected. */
#endif #endif
kI2C_SlaveCompletionEvent = 0x20U, /*!< A stop was detected or finished transfer, completing the transfer. */ kI2C_SlaveCompletionEvent = 0x20U, /*!< A stop was detected or finished transfer, completing the transfer. */
kI2C_SlaveGenaralcallEvent = 0x40U, /*!< Received the general call address after a start or repeated start. */
/*! Bit mask of all available events. */ /*! A bit mask of all available events. */
kI2C_SlaveAllEvents = kI2C_SlaveAddressMatchEvent | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent | kI2C_SlaveAllEvents = kI2C_SlaveAddressMatchEvent | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent |
#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
kI2C_SlaveRepeatedStartEvent | kI2C_SlaveStartEvent |
#endif #endif
kI2C_SlaveCompletionEvent, kI2C_SlaveCompletionEvent | kI2C_SlaveGenaralcallEvent,
} i2c_slave_transfer_event_t; } i2c_slave_transfer_event_t;
/*! @brief I2C master user configuration. */ /*! @brief I2C master user configuration. */
@ -172,6 +172,10 @@ typedef struct _i2c_master_config
#endif #endif
#if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF #if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF
bool enableStopHold; /*!< Controls the stop hold enable. */ bool enableStopHold; /*!< Controls the stop hold enable. */
#endif
#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
bool enableDoubleBuffering; /*!< Controls double buffer enable; notice that
enabling the double buffer disables the clock stretch. */
#endif #endif
uint32_t baudRate_Bps; /*!< Baud rate configuration of I2C peripheral. */ uint32_t baudRate_Bps; /*!< Baud rate configuration of I2C peripheral. */
uint8_t glitchFilterWidth; /*!< Controls the width of the glitch. */ uint8_t glitchFilterWidth; /*!< Controls the width of the glitch. */
@ -181,15 +185,23 @@ typedef struct _i2c_master_config
typedef struct _i2c_slave_config typedef struct _i2c_slave_config
{ {
bool enableSlave; /*!< Enables the I2C peripheral at initialization time. */ bool enableSlave; /*!< Enables the I2C peripheral at initialization time. */
bool enableGeneralCall; /*!< Enable general call addressing mode. */ bool enableGeneralCall; /*!< Enables the general call addressing mode. */
bool enableWakeUp; /*!< Enables/disables waking up MCU from low power 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 #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. */ bool enableHighDrive; /*!< Controls the drive capability of the I2C pads. */
#endif
#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
bool enableDoubleBuffering; /*!< Controls a double buffer enable; notice that
enabling the double buffer disables the clock stretch. */
#endif #endif
bool enableBaudRateCtl; /*!< Enables/disables independent slave baud rate on SCL in very fast I2C modes. */ bool enableBaudRateCtl; /*!< Enables/disables independent slave baud rate on SCL in very fast I2C modes. */
uint16_t slaveAddress; /*!< Slave address configuration. */ uint16_t slaveAddress; /*!< A slave address configuration. */
uint16_t upperAddress; /*!< Maximum boundary slave address used in range matching mode. */ uint16_t upperAddress; /*!< A maximum boundary slave address used in a range matching mode. */
i2c_slave_address_mode_t addressingMode; /*!< Addressing mode configuration of i2c_slave_address_mode_config_t. */ i2c_slave_address_mode_t
addressingMode; /*!< An addressing mode configuration of i2c_slave_address_mode_config_t. */
uint32_t sclStopHoldTime_ns; /*!< the delay from the rising edge of SCL (I2C clock) to the rising edge of SDA (I2C
data) while SCL is high (stop condition), SDA hold time and SCL start hold time
are also configured according to the SCL stop hold time. */
} i2c_slave_config_t; } i2c_slave_config_t;
/*! @brief I2C master handle typedef. */ /*! @brief I2C master handle typedef. */
@ -207,13 +219,13 @@ typedef struct _i2c_slave_handle i2c_slave_handle_t;
/*! @brief I2C master transfer structure. */ /*! @brief I2C master transfer structure. */
typedef struct _i2c_master_transfer typedef struct _i2c_master_transfer
{ {
uint32_t flags; /*!< Transfer flag which controls the transfer. */ uint32_t flags; /*!< A transfer flag which controls the transfer. */
uint8_t slaveAddress; /*!< 7-bit slave address. */ uint8_t slaveAddress; /*!< 7-bit slave address. */
i2c_direction_t direction; /*!< Transfer direction, read or write. */ i2c_direction_t direction; /*!< A transfer direction, read or write. */
uint32_t subaddress; /*!< Sub address. Transferred MSB first. */ uint32_t subaddress; /*!< A sub address. Transferred MSB first. */
uint8_t subaddressSize; /*!< Size of command buffer. */ uint8_t subaddressSize; /*!< A size of the command buffer. */
uint8_t *volatile data; /*!< Transfer buffer. */ uint8_t *volatile data; /*!< A transfer buffer. */
volatile size_t dataSize; /*!< Transfer size. */ volatile size_t dataSize; /*!< A transfer size. */
} i2c_master_transfer_t; } i2c_master_transfer_t;
/*! @brief I2C master handle structure. */ /*! @brief I2C master handle structure. */
@ -221,20 +233,21 @@ struct _i2c_master_handle
{ {
i2c_master_transfer_t transfer; /*!< I2C master transfer copy. */ i2c_master_transfer_t transfer; /*!< I2C master transfer copy. */
size_t transferSize; /*!< Total bytes to be transferred. */ size_t transferSize; /*!< Total bytes to be transferred. */
uint8_t state; /*!< Transfer state maintained during transfer. */ uint8_t state; /*!< A transfer state maintained during transfer. */
i2c_master_transfer_callback_t completionCallback; /*!< Callback function called when transfer finished. */ i2c_master_transfer_callback_t completionCallback; /*!< A callback function called when the transfer is finished. */
void *userData; /*!< Callback parameter passed to callback function. */ void *userData; /*!< A callback parameter passed to the callback function. */
}; };
/*! @brief I2C slave transfer structure. */ /*! @brief I2C slave transfer structure. */
typedef struct _i2c_slave_transfer typedef struct _i2c_slave_transfer
{ {
i2c_slave_transfer_event_t event; /*!< Reason the callback is being invoked. */ i2c_slave_transfer_event_t event; /*!< A reason that the callback is invoked. */
uint8_t *volatile data; /*!< Transfer buffer. */ uint8_t *volatile data; /*!< A transfer buffer. */
volatile size_t dataSize; /*!< Transfer size. */ volatile size_t dataSize; /*!< A transfer size. */
status_t completionStatus; /*!< Success or error code describing how the transfer completed. Only applies for status_t completionStatus; /*!< Success or error code describing how the transfer completed. Only applies for
#kI2C_SlaveCompletionEvent. */ #kI2C_SlaveCompletionEvent. */
size_t transferredCount; /*!< Number of bytes actually transferred since start or last repeated start. */ size_t transferredCount; /*!< A number of bytes actually transferred since the start or since the last repeated
start. */
} i2c_slave_transfer_t; } i2c_slave_transfer_t;
/*! @brief I2C slave transfer callback typedef. */ /*! @brief I2C slave transfer callback typedef. */
@ -243,11 +256,11 @@ typedef void (*i2c_slave_transfer_callback_t)(I2C_Type *base, i2c_slave_transfer
/*! @brief I2C slave handle structure. */ /*! @brief I2C slave handle structure. */
struct _i2c_slave_handle struct _i2c_slave_handle
{ {
bool isBusy; /*!< Whether transfer is busy. */ volatile bool isBusy; /*!< Indicates whether a transfer is busy. */
i2c_slave_transfer_t transfer; /*!< I2C slave transfer copy. */ i2c_slave_transfer_t transfer; /*!< I2C slave transfer copy. */
uint32_t eventMask; /*!< Mask of enabled events. */ uint32_t eventMask; /*!< A mask of enabled events. */
i2c_slave_transfer_callback_t callback; /*!< Callback function called at transfer event. */ i2c_slave_transfer_callback_t callback; /*!< A callback function called at the transfer event. */
void *userData; /*!< Callback parameter passed to callback. */ void *userData; /*!< A callback parameter passed to the callback. */
}; };
/******************************************************************************* /*******************************************************************************
@ -267,12 +280,12 @@ extern "C" {
* @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock * @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock
* and configure the I2C with master configuration. * and configure the I2C with master configuration.
* *
* @note This API should be called at the beginning of the application to use * @note This API should be called at the beginning of the application.
* the I2C driver, or any operation to the I2C module could cause hard fault * Otherwise, any operation to the I2C module can cause a hard fault
* because clock is not enabled. The configuration structure can be filled by user * because the clock is not enabled. The configuration structure can be custom filled
* from scratch, or be set with default values by I2C_MasterGetDefaultConfig(). * or it can be set with default values by using the I2C_MasterGetDefaultConfig().
* After calling this API, the master is ready to transfer. * After calling this API, the master is ready to transfer.
* Example: * This is an example.
* @code * @code
* i2c_master_config_t config = { * i2c_master_config_t config = {
* .enableMaster = true, * .enableMaster = true,
@ -285,20 +298,20 @@ extern "C" {
* @endcode * @endcode
* *
* @param base I2C base pointer * @param base I2C base pointer
* @param masterConfig pointer to master configuration structure * @param masterConfig A pointer to the master configuration structure
* @param srcClock_Hz I2C peripheral clock frequency in Hz * @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); 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 * @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock
* and initializes the I2C with slave configuration. * and initialize the I2C with the slave configuration.
* *
* @note This API should be called at the beginning of the application to use * @note This API should be called at the beginning of the application.
* the I2C driver, or any operation to the I2C module can cause a hard fault * Otherwise, any operation to the I2C module can cause a hard fault
* because the clock is not enabled. The configuration structure can partly be set * 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. * with default values by I2C_SlaveGetDefaultConfig() or it can be custom filled by the user.
* Example * This is an example.
* @code * @code
* i2c_slave_config_t config = { * i2c_slave_config_t config = {
* .enableSlave = true, * .enableSlave = true,
@ -307,15 +320,17 @@ void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uin
* .slaveAddress = 0x1DU, * .slaveAddress = 0x1DU,
* .enableWakeUp = false, * .enableWakeUp = false,
* .enablehighDrive = false, * .enablehighDrive = false,
* .enableBaudRateCtl = false * .enableBaudRateCtl = false,
* .sclStopHoldTime_ns = 4000
* }; * };
* I2C_SlaveInit(I2C0, &config); * I2C_SlaveInit(I2C0, &config, 12000000U);
* @endcode * @endcode
* *
* @param base I2C base pointer * @param base I2C base pointer
* @param slaveConfig pointer to slave configuration structure * @param slaveConfig A pointer to the slave configuration structure
* @param srcClock_Hz I2C peripheral clock frequency in Hz
*/ */
void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig); void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz);
/*! /*!
* @brief De-initializes the I2C master peripheral. Call this API to gate the I2C clock. * @brief De-initializes the I2C master peripheral. Call this API to gate the I2C clock.
@ -335,28 +350,28 @@ void I2C_SlaveDeinit(I2C_Type *base);
* @brief Sets the I2C master configuration structure to default values. * @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(). * 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 * Use the initialized structure unchanged in the I2C_MasterConfigure() or modify
* the structure before calling I2C_MasterConfigure(). * the structure before calling the I2C_MasterConfigure().
* Example: * This is an example.
* @code * @code
* i2c_master_config_t config; * i2c_master_config_t config;
* I2C_MasterGetDefaultConfig(&config); * I2C_MasterGetDefaultConfig(&config);
* @endcode * @endcode
* @param masterConfig Pointer to the master configuration structure. * @param masterConfig A pointer to the master configuration structure.
*/ */
void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig); void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig);
/*! /*!
* @brief Sets the I2C slave configuration structure to default values. * @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(). * The purpose of this API is to get the configuration structure initialized for use in the I2C_SlaveConfigure().
* Modify fields of the structure before calling the I2C_SlaveConfigure(). * Modify fields of the structure before calling the I2C_SlaveConfigure().
* Example: * This is an example.
* @code * @code
* i2c_slave_config_t config; * i2c_slave_config_t config;
* I2C_SlaveGetDefaultConfig(&config); * I2C_SlaveGetDefaultConfig(&config);
* @endcode * @endcode
* @param slaveConfig Pointer to the slave configuration structure. * @param slaveConfig A pointer to the slave configuration structure.
*/ */
void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig); void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig);
@ -364,7 +379,7 @@ void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig);
* @brief Enables or disabless the I2C peripheral operation. * @brief Enables or disabless the I2C peripheral operation.
* *
* @param base I2C base pointer * @param base I2C base pointer
* @param enable pass true to enable module, false to disable module * @param enable Pass true to enable and false to disable the module.
*/ */
static inline void I2C_Enable(I2C_Type *base, bool enable) static inline void I2C_Enable(I2C_Type *base, bool enable)
{ {
@ -389,7 +404,7 @@ static inline void I2C_Enable(I2C_Type *base, bool enable)
* @brief Gets the I2C status flags. * @brief Gets the I2C status flags.
* *
* @param base I2C base pointer * @param base I2C base pointer
* @return status flag, use status flag to AND #_i2c_flags could get the related status. * @return status flag, use status flag to AND #_i2c_flags to get the related status.
*/ */
uint32_t I2C_MasterGetStatusFlags(I2C_Type *base); uint32_t I2C_MasterGetStatusFlags(I2C_Type *base);
@ -397,7 +412,7 @@ uint32_t I2C_MasterGetStatusFlags(I2C_Type *base);
* @brief Gets the I2C status flags. * @brief Gets the I2C status flags.
* *
* @param base I2C base pointer * @param base I2C base pointer
* @return status flag, use status flag to AND #_i2c_flags could get the related status. * @return status flag, use status flag to AND #_i2c_flags to get the related status.
*/ */
static inline uint32_t I2C_SlaveGetStatusFlags(I2C_Type *base) static inline uint32_t I2C_SlaveGetStatusFlags(I2C_Type *base)
{ {
@ -407,11 +422,11 @@ static inline uint32_t I2C_SlaveGetStatusFlags(I2C_Type *base)
/*! /*!
* @brief Clears the I2C status flag state. * @brief Clears the I2C status flag state.
* *
* The following status register flags can be cleared: kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag * The following status register flags can be cleared kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag.
* *
* @param base I2C base pointer * @param base I2C base pointer
* @param statusMask The status flag mask, defined in type i2c_status_flag_t. * @param statusMask The status flag mask, defined in type i2c_status_flag_t.
* The parameter could be any combination of the following values: * The parameter can be any combination of the following values:
* @arg kI2C_StartDetectFlag (if available) * @arg kI2C_StartDetectFlag (if available)
* @arg kI2C_StopDetectFlag (if available) * @arg kI2C_StopDetectFlag (if available)
* @arg kI2C_ArbitrationLostFlag * @arg kI2C_ArbitrationLostFlag
@ -442,11 +457,11 @@ static inline void I2C_MasterClearStatusFlags(I2C_Type *base, uint32_t statusMas
/*! /*!
* @brief Clears the I2C status flag state. * @brief Clears the I2C status flag state.
* *
* The following status register flags can be cleared: kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag * The following status register flags can be cleared kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag
* *
* @param base I2C base pointer * @param base I2C base pointer
* @param statusMask The status flag mask, defined in type i2c_status_flag_t. * @param statusMask The status flag mask, defined in type i2c_status_flag_t.
* The parameter could be any combination of the following values: * The parameter can be any combination of the following values:
* @arg kI2C_StartDetectFlag (if available) * @arg kI2C_StartDetectFlag (if available)
* @arg kI2C_StopDetectFlag (if available) * @arg kI2C_StopDetectFlag (if available)
* @arg kI2C_ArbitrationLostFlag * @arg kI2C_ArbitrationLostFlag
@ -574,19 +589,21 @@ status_t I2C_MasterStop(I2C_Type *base);
status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction); 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. * @brief Performs a polling send transaction on the I2C bus.
* *
* @param base The I2C peripheral base pointer. * @param base The I2C peripheral base pointer.
* @param txBuff The pointer to the data to be transferred. * @param txBuff The pointer to the data to be transferred.
* @param txSize The length in bytes of the data to be transferred. * @param txSize The length in bytes of the data to be transferred.
* @param flags Transfer control flag to decide whether need to send a stop, use kI2C_TransferDefaultFlag
* to issue a stop and kI2C_TransferNoStop to not send a stop.
* @retval kStatus_Success Successfully complete the data transmission. * @retval kStatus_Success Successfully complete the data transmission.
* @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
* @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer.
*/ */
status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize); status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize, uint32_t flags);
/*! /*!
* @brief Performs a polling receive transaction on the I2C bus with a STOP signal. * @brief Performs a polling receive transaction on the I2C bus.
* *
* @note The I2C_MasterReadBlocking function stops the bus before reading the final byte. * @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 * Without stopping the bus prior for the final read, the bus issues another read, resulting
@ -595,10 +612,12 @@ status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t t
* @param base I2C peripheral base pointer. * @param base I2C peripheral base pointer.
* @param rxBuff The pointer to the data to store the received data. * @param rxBuff The pointer to the data to store the received data.
* @param rxSize The length in bytes of the data to be received. * @param rxSize The length in bytes of the data to be received.
* @param flags Transfer control flag to decide whether need to send a stop, use kI2C_TransferDefaultFlag
* to issue a stop and kI2C_TransferNoStop to not send a stop.
* @retval kStatus_Success Successfully complete the data transmission. * @retval kStatus_Success Successfully complete the data transmission.
* @retval kStatus_I2C_Timeout Send stop signal failed, timeout. * @retval kStatus_I2C_Timeout Send stop signal failed, timeout.
*/ */
status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize); status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize, uint32_t flags);
/*! /*!
* @brief Performs a polling send transaction on the I2C bus. * @brief Performs a polling send transaction on the I2C bus.
@ -650,7 +669,7 @@ status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
* @param base I2C base pointer. * @param base I2C base pointer.
* @param handle pointer to i2c_master_handle_t structure to store the transfer state. * @param handle pointer to i2c_master_handle_t structure to store the transfer state.
* @param callback pointer to user callback function. * @param callback pointer to user callback function.
* @param userData user paramater passed to the callback function. * @param userData user parameter passed to the callback function.
*/ */
void I2C_MasterTransferCreateHandle(I2C_Type *base, void I2C_MasterTransferCreateHandle(I2C_Type *base,
i2c_master_handle_t *handle, i2c_master_handle_t *handle,
@ -660,15 +679,15 @@ void I2C_MasterTransferCreateHandle(I2C_Type *base,
/*! /*!
* @brief Performs a master interrupt non-blocking transfer on the I2C bus. * @brief Performs a master interrupt non-blocking transfer on the I2C bus.
* *
* @note Calling the API will return immediately after transfer initiates, user needs * @note Calling the API returns immediately after transfer initiates. The user needs
* to call I2C_MasterGetTransferCount to poll the transfer status to check whether * 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 * the transfer is finished. If the return status is not kStatus_I2C_Busy, the transfer
* is finished. * is finished.
* *
* @param base I2C base pointer. * @param base I2C base pointer.
* @param handle pointer to i2c_master_handle_t structure which stores the transfer state. * @param handle pointer to i2c_master_handle_t structure which stores the transfer state.
* @param xfer pointer to i2c_master_transfer_t structure. * @param xfer pointer to i2c_master_transfer_t structure.
* @retval kStatus_Success Sucessully start the data transmission. * @retval kStatus_Success Successfully start the data transmission.
* @retval kStatus_I2C_Busy Previous transmission still not finished. * @retval kStatus_I2C_Busy Previous transmission still not finished.
* @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout.
*/ */

View File

@ -162,6 +162,26 @@ static void I2C_MasterTransferCallbackEDMA(edma_handle_t *handle, void *userData
result = I2C_MasterStop(i2cPrivateHandle->base); result = I2C_MasterStop(i2cPrivateHandle->base);
} }
} }
else
{
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))
{
}
/* Change direction to send. */
i2cPrivateHandle->base->C1 |= I2C_C1_TX_MASK;
/* Read the last data byte. */
*(i2cPrivateHandle->handle->transfer.data + i2cPrivateHandle->handle->transfer.dataSize - 1) =
i2cPrivateHandle->base->D;
}
}
i2cPrivateHandle->handle->state = kIdleState; i2cPrivateHandle->handle->state = kIdleState;
@ -203,7 +223,6 @@ static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
assert(xfer); assert(xfer);
status_t result = kStatus_Success; status_t result = kStatus_Success;
uint16_t timeout = UINT16_MAX;
if (handle->state != kIdleState) if (handle->state != kIdleState)
{ {
@ -221,16 +240,6 @@ static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
handle->state = kTransferDataState; 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. */ /* Clear all status before transfer. */
I2C_MasterClearStatusFlags(base, kClearFlags); I2C_MasterClearStatusFlags(base, kClearFlags);
@ -250,22 +259,55 @@ static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction); result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction);
} }
if (result)
{
return result;
}
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)
{
result = kStatus_I2C_Addr_Nak;
if (I2C_MasterStop(base) != kStatus_Success)
{
result = kStatus_I2C_Timeout;
}
if (handle->completionCallback)
{
(handle->completionCallback)(base, handle, result, handle->userData);
}
}
return result;
}
/* Send subaddress. */ /* Send subaddress. */
if (handle->transfer.subaddressSize) if (handle->transfer.subaddressSize)
{ {
do do
{ {
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
/* Clear interrupt pending flag. */ /* Clear interrupt pending flag. */
base->S = kI2C_IntPendingFlag; base->S = kI2C_IntPendingFlag;
handle->transfer.subaddressSize--; handle->transfer.subaddressSize--;
base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize)); base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize));
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
/* Check if there's transfer error. */ /* Check if there's transfer error. */
result = I2C_CheckAndClearError(base, base->S); result = I2C_CheckAndClearError(base, base->S);
@ -278,34 +320,34 @@ static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
if (handle->transfer.direction == kI2C_Read) if (handle->transfer.direction == kI2C_Read)
{ {
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
/* Clear pending flag. */ /* Clear pending flag. */
base->S = kI2C_IntPendingFlag; base->S = kI2C_IntPendingFlag;
/* Send repeated start and slave address. */ /* Send repeated start and slave address. */
result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read); result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read);
if (result)
{
return result;
}
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
/* Check if there's transfer error. */
result = I2C_CheckAndClearError(base, base->S);
if (result)
{
return result;
}
} }
} }
if (result)
{
return result;
}
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
/* Clear pending flag. */ /* Clear pending flag. */
base->S = kI2C_IntPendingFlag; base->S = kI2C_IntPendingFlag;
/* Check if there's transfer error. */
result = I2C_CheckAndClearError(base, base->S);
} }
return result; return result;
@ -319,17 +361,7 @@ static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_
{ {
transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base); transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base);
transfer_config.destAddr = (uint32_t)(handle->transfer.data); transfer_config.destAddr = (uint32_t)(handle->transfer.data);
transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1);
/* Send stop if kI2C_TransferNoStop flag is not asserted. */
if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
{
transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1);
}
else
{
transfer_config.majorLoopCounts = handle->transfer.dataSize;
}
transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes; transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes;
transfer_config.srcOffset = 0; transfer_config.srcOffset = 0;
transfer_config.destTransferSize = kEDMA_TransferSize1Bytes; transfer_config.destTransferSize = kEDMA_TransferSize1Bytes;
@ -348,6 +380,9 @@ static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_
transfer_config.minorLoopBytes = 1; transfer_config.minorLoopBytes = 1;
} }
/* Store the initially configured eDMA minor byte transfer count into the I2C handle */
handle->nbytes = transfer_config.minorLoopBytes;
EDMA_SubmitTransfer(handle->dmaHandle, &transfer_config); EDMA_SubmitTransfer(handle->dmaHandle, &transfer_config);
EDMA_StartTransfer(handle->dmaHandle); EDMA_StartTransfer(handle->dmaHandle);
} }
@ -427,7 +462,7 @@ status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle
if (handle->transfer.direction == kI2C_Read) if (handle->transfer.direction == kI2C_Read)
{ {
/* Change direction for receive. */ /* Change direction for receive. */
base->C1 &= ~I2C_C1_TX_MASK; base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
/* Read dummy to release the bus. */ /* Read dummy to release the bus. */
dummy = base->D; dummy = base->D;
@ -479,6 +514,11 @@ status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle
{ {
result = I2C_MasterStop(base); result = I2C_MasterStop(base);
} }
else
{
/* Change direction to send. */
base->C1 |= I2C_C1_TX_MASK;
}
/* Read the last byte of data. */ /* Read the last byte of data. */
if (handle->transfer.direction == kI2C_Read) if (handle->transfer.direction == kI2C_Read)
@ -504,7 +544,9 @@ status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t
if (kIdleState != handle->state) if (kIdleState != handle->state)
{ {
*count = (handle->transferSize - EDMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel)); *count = (handle->transferSize -
(uint32_t)handle->nbytes *
EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel));
} }
else else
{ {

View File

@ -39,31 +39,30 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/*! @brief I2C master edma handle typedef. */ /*! @brief I2C master eDMA handle typedef. */
typedef struct _i2c_master_edma_handle i2c_master_edma_handle_t; typedef struct _i2c_master_edma_handle i2c_master_edma_handle_t;
/*! @brief I2C master edma transfer callback typedef. */ /*! @brief I2C master eDMA transfer callback typedef. */
typedef void (*i2c_master_edma_transfer_callback_t)(I2C_Type *base, typedef void (*i2c_master_edma_transfer_callback_t)(I2C_Type *base,
i2c_master_edma_handle_t *handle, i2c_master_edma_handle_t *handle,
status_t status, status_t status,
void *userData); void *userData);
/*! @brief I2C master edma transfer structure. */ /*! @brief I2C master eDMA transfer structure. */
struct _i2c_master_edma_handle struct _i2c_master_edma_handle
{ {
i2c_master_transfer_t transfer; /*!< I2C master transfer struct. */ i2c_master_transfer_t transfer; /*!< I2C master transfer structure. */
size_t transferSize; /*!< Total bytes to be transferred. */ size_t transferSize; /*!< Total bytes to be transferred. */
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
uint8_t state; /*!< I2C master transfer status. */ uint8_t state; /*!< I2C master transfer status. */
edma_handle_t *dmaHandle; /*!< The eDMA handler used. */ edma_handle_t *dmaHandle; /*!< The eDMA handler used. */
i2c_master_edma_transfer_callback_t i2c_master_edma_transfer_callback_t
completionCallback; /*!< Callback function called after edma transfer finished. */ completionCallback; /*!< A callback function called after the eDMA transfer is finished. */
void *userData; /*!< Callback parameter passed to callback function. */ void *userData; /*!< A callback parameter passed to the callback function. */
}; };
/******************************************************************************* /*******************************************************************************
@ -75,18 +74,18 @@ extern "C" {
#endif /*_cplusplus. */ #endif /*_cplusplus. */
/*! /*!
* @name I2C Block EDMA Transfer Operation * @name I2C Block eDMA Transfer Operation
* @{ * @{
*/ */
/*! /*!
* @brief Init the I2C handle which is used in transcational functions. * @brief Initializes the I2C handle which is used in transcational functions.
* *
* @param base I2C peripheral base address. * @param base I2C peripheral base address.
* @param handle pointer to i2c_master_edma_handle_t structure. * @param handle A pointer to the i2c_master_edma_handle_t structure.
* @param callback pointer to user callback function. * @param callback A pointer to the user callback function.
* @param userData user param passed to the callback function. * @param userData A user parameter passed to the callback function.
* @param edmaHandle EDMA handle pointer. * @param edmaHandle eDMA handle pointer.
*/ */
void I2C_MasterCreateEDMAHandle(I2C_Type *base, void I2C_MasterCreateEDMAHandle(I2C_Type *base,
i2c_master_edma_handle_t *handle, i2c_master_edma_handle_t *handle,
@ -95,33 +94,33 @@ void I2C_MasterCreateEDMAHandle(I2C_Type *base,
edma_handle_t *edmaHandle); edma_handle_t *edmaHandle);
/*! /*!
* @brief Performs a master edma non-blocking transfer on the I2C bus. * @brief Performs a master eDMA non-blocking transfer on the I2C bus.
* *
* @param base I2C peripheral base address. * @param base I2C peripheral base address.
* @param handle pointer to i2c_master_edma_handle_t structure. * @param handle A pointer to the i2c_master_edma_handle_t structure.
* @param xfer pointer to transfer structure of i2c_master_transfer_t. * @param xfer A pointer to the transfer structure of i2c_master_transfer_t.
* @retval kStatus_Success Sucessully complete the data transmission. * @retval kStatus_Success Sucessfully completed the data transmission.
* @retval kStatus_I2C_Busy Previous transmission still not finished. * @retval kStatus_I2C_Busy A previous transmission is still not finished.
* @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. * @retval kStatus_I2C_Timeout Transfer error, waits for a signal timeout.
* @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
* @retval kStataus_I2C_Nak Transfer error, receive Nak during transfer. * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer.
*/ */
status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, i2c_master_transfer_t *xfer); status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, i2c_master_transfer_t *xfer);
/*! /*!
* @brief Get master transfer status during a edma non-blocking transfer. * @brief Gets a master transfer status during the eDMA non-blocking transfer.
* *
* @param base I2C peripheral base address. * @param base I2C peripheral base address.
* @param handle pointer to i2c_master_edma_handle_t structure. * @param handle A pointer to the i2c_master_edma_handle_t structure.
* @param count Number of bytes transferred so far by the non-blocking transaction. * @param count A number of bytes transferred by the non-blocking transaction.
*/ */
status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, size_t *count); status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, size_t *count);
/*! /*!
* @brief Abort a master edma non-blocking transfer in a early time. * @brief Aborts a master eDMA non-blocking transfer early.
* *
* @param base I2C peripheral base address. * @param base I2C peripheral base address.
* @param handle pointer to i2c_master_edma_handle_t structure. * @param handle A pointer to the i2c_master_edma_handle_t structure.
*/ */
void I2C_MasterTransferAbortEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle); void I2C_MasterTransferAbortEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle);

View File

@ -35,7 +35,6 @@
/*! @addtogroup llwu */ /*! @addtogroup llwu */
/*! @{ */ /*! @{ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -52,9 +51,9 @@
*/ */
typedef enum _llwu_external_pin_mode typedef enum _llwu_external_pin_mode
{ {
kLLWU_ExternalPinDisable = 0U, /*!< Pin disabled as wakeup input. */ kLLWU_ExternalPinDisable = 0U, /*!< Pin disabled as a wakeup input. */
kLLWU_ExternalPinRisingEdge = 1U, /*!< Pin enabled with rising edge detection. */ kLLWU_ExternalPinRisingEdge = 1U, /*!< Pin enabled with the rising edge detection. */
kLLWU_ExternalPinFallingEdge = 2U, /*!< Pin enabled with falling edge detection.*/ kLLWU_ExternalPinFallingEdge = 2U, /*!< Pin enabled with the falling edge detection.*/
kLLWU_ExternalPinAnyEdge = 3U /*!< Pin enabled with any change detection. */ kLLWU_ExternalPinAnyEdge = 3U /*!< Pin enabled with any change detection. */
} llwu_external_pin_mode_t; } llwu_external_pin_mode_t;
@ -75,9 +74,9 @@ typedef enum _llwu_pin_filter_mode
*/ */
typedef struct _llwu_version_id typedef struct _llwu_version_id
{ {
uint16_t feature; /*!< Feature Specification Number. */ uint16_t feature; /*!< A feature specification number. */
uint8_t minor; /*!< Minor version number. */ uint8_t minor; /*!< The minor version number. */
uint8_t major; /*!< Major version number. */ uint8_t major; /*!< The major version number. */
} llwu_version_id_t; } llwu_version_id_t;
#endif /* FSL_FEATURE_LLWU_HAS_VERID */ #endif /* FSL_FEATURE_LLWU_HAS_VERID */
@ -87,20 +86,20 @@ typedef struct _llwu_version_id
*/ */
typedef struct _llwu_param typedef struct _llwu_param
{ {
uint8_t filters; /*!< Number of pin filter. */ uint8_t filters; /*!< A number of the pin filter. */
uint8_t dmas; /*!< Number of wakeup DMA. */ uint8_t dmas; /*!< A number of the wakeup DMA. */
uint8_t modules; /*!< Number of wakeup module. */ uint8_t modules; /*!< A number of the wakeup module. */
uint8_t pins; /*!< Number of wake up pin. */ uint8_t pins; /*!< A number of the wake up pin. */
} llwu_param_t; } llwu_param_t;
#endif /* FSL_FEATURE_LLWU_HAS_PARAM */ #endif /* FSL_FEATURE_LLWU_HAS_PARAM */
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER) #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER)
/*! /*!
* @brief External input pin filter control structure * @brief An external input pin filter control structure
*/ */
typedef struct _llwu_external_pin_filter_mode typedef struct _llwu_external_pin_filter_mode
{ {
uint32_t pinIndex; /*!< Pin number */ uint32_t pinIndex; /*!< A pin number */
llwu_pin_filter_mode_t filterMode; /*!< Filter mode */ llwu_pin_filter_mode_t filterMode; /*!< Filter mode */
} llwu_external_pin_filter_mode_t; } llwu_external_pin_filter_mode_t;
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ #endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
@ -122,11 +121,11 @@ extern "C" {
/*! /*!
* @brief Gets the LLWU version ID. * @brief Gets the LLWU version ID.
* *
* This function gets the LLWU version ID, including major version number, * This function gets the LLWU version ID, including the major version number,
* minor version number, and feature specification number. * the minor version number, and the feature specification number.
* *
* @param base LLWU peripheral base address. * @param base LLWU peripheral base address.
* @param versionId Pointer to version ID structure. * @param versionId A pointer to the version ID structure.
*/ */
static inline void LLWU_GetVersionId(LLWU_Type *base, llwu_version_id_t *versionId) static inline void LLWU_GetVersionId(LLWU_Type *base, llwu_version_id_t *versionId)
{ {
@ -138,11 +137,11 @@ static inline void LLWU_GetVersionId(LLWU_Type *base, llwu_version_id_t *version
/*! /*!
* @brief Gets the LLWU parameter. * @brief Gets the LLWU parameter.
* *
* This function gets the LLWU parameter, including wakeup pin number, module * This function gets the LLWU parameter, including a wakeup pin number, a module
* number, DMA number, and pin filter number. * number, a DMA number, and a pin filter number.
* *
* @param base LLWU peripheral base address. * @param base LLWU peripheral base address.
* @param param Pointer to LLWU param structure. * @param param A pointer to the LLWU parameter structure.
*/ */
static inline void LLWU_GetParam(LLWU_Type *base, llwu_param_t *param) static inline void LLWU_GetParam(LLWU_Type *base, llwu_param_t *param)
{ {
@ -158,8 +157,8 @@ static inline void LLWU_GetParam(LLWU_Type *base, llwu_param_t *param)
* as a wake up source. * as a wake up source.
* *
* @param base LLWU peripheral base address. * @param base LLWU peripheral base address.
* @param pinIndex pin index which to be enabled as external wakeup source, start from 1. * @param pinIndex A pin index to be enabled as an external wakeup source starting from 1.
* @param pinMode pin configuration mode defined in llwu_external_pin_modes_t * @param pinMode A pin configuration mode defined in the llwu_external_pin_modes_t.
*/ */
void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_external_pin_mode_t pinMode); void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_external_pin_mode_t pinMode);
@ -167,11 +166,11 @@ void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_exte
* @brief Gets the external wakeup source flag. * @brief Gets the external wakeup source flag.
* *
* This function checks the external pin flag to detect whether the MCU is * This function checks the external pin flag to detect whether the MCU is
* woke up by the specific pin. * woken up by the specific pin.
* *
* @param base LLWU peripheral base address. * @param base LLWU peripheral base address.
* @param pinIndex pin index, start from 1. * @param pinIndex A pin index, which starts from 1.
* @return true if the specific pin is wake up source. * @return True if the specific pin is a wakeup source.
*/ */
bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex); bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex);
@ -181,7 +180,7 @@ bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex);
* This function clears the external wakeup source flag for a specific pin. * This function clears the external wakeup source flag for a specific pin.
* *
* @param base LLWU peripheral base address. * @param base LLWU peripheral base address.
* @param pinIndex pin index, start from 1. * @param pinIndex A pin index, which starts from 1.
*/ */
void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex); void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex);
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
@ -194,8 +193,8 @@ void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex);
* as a wake up source. * as a wake up source.
* *
* @param base LLWU peripheral base address. * @param base LLWU peripheral base address.
* @param moduleIndex module index which to be enabled as internal wakeup source, start from 1. * @param moduleIndex A module index to be enabled as an internal wakeup source starting from 1.
* @param enable enable or disable setting * @param enable An enable or a disable setting
*/ */
static inline void LLWU_EnableInternalModuleInterruptWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable) static inline void LLWU_EnableInternalModuleInterruptWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable)
{ {
@ -213,31 +212,31 @@ static inline void LLWU_EnableInternalModuleInterruptWakup(LLWU_Type *base, uint
* @brief Gets the external wakeup source flag. * @brief Gets the external wakeup source flag.
* *
* This function checks the external pin flag to detect whether the system is * This function checks the external pin flag to detect whether the system is
* woke up by the specific pin. * woken up by the specific pin.
* *
* @param base LLWU peripheral base address. * @param base LLWU peripheral base address.
* @param moduleIndex module index, start from 1. * @param moduleIndex A module index, which starts from 1.
* @return true if the specific pin is wake up source. * @return True if the specific pin is a wake up source.
*/ */
static inline bool LLWU_GetInternalWakeupModuleFlag(LLWU_Type *base, uint32_t moduleIndex) static inline bool LLWU_GetInternalWakeupModuleFlag(LLWU_Type *base, uint32_t moduleIndex)
{ {
#if (defined(FSL_FEATURE_LLWU_HAS_MF) && FSL_FEATURE_LLWU_HAS_MF)
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) #if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
return (bool)(base->MF & (1U << moduleIndex)); return (bool)(base->MF & (1U << moduleIndex));
#else #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)); return (bool)(base->MF5 & (1U << moduleIndex));
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
#else #else
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
return (bool)(base->F5 & (1U << moduleIndex)); return (bool)(base->F5 & (1U << moduleIndex));
#endif /* FSL_FEATURE_LLWU_HAS_PF */
#else #else
#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF) #if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF)
return (bool)(base->PF3 & (1U << moduleIndex)); return (bool)(base->PF3 & (1U << moduleIndex));
#else #else
return (bool)(base->F3 & (1U << moduleIndex)); return (bool)(base->F3 & (1U << moduleIndex));
#endif #endif /* FSL_FEATURE_LLWU_HAS_PF */
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ #endif /* FSL_FEATURE_LLWU_HAS_MF */
} }
#endif /* FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE */ #endif /* FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE */
@ -248,8 +247,8 @@ static inline bool LLWU_GetInternalWakeupModuleFlag(LLWU_Type *base, uint32_t mo
* This function enables/disables the internal DMA that is used as a wake up source. * This function enables/disables the internal DMA that is used as a wake up source.
* *
* @param base LLWU peripheral base address. * @param base LLWU peripheral base address.
* @param moduleIndex Internal module index which used as DMA request source, start from 1. * @param moduleIndex An internal module index which is used as a DMA request source, starting from 1.
* @param enable Enable or disable DMA request source * @param enable Enable or disable the DMA request source
*/ */
static inline void LLWU_EnableInternalModuleDmaRequestWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable) static inline void LLWU_EnableInternalModuleDmaRequestWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable)
{ {
@ -271,8 +270,8 @@ static inline void LLWU_EnableInternalModuleDmaRequestWakup(LLWU_Type *base, uin
* This function sets the pin filter configuration. * This function sets the pin filter configuration.
* *
* @param base LLWU peripheral base address. * @param base LLWU peripheral base address.
* @param filterIndex pin filter index which used to enable/disable the digital filter, start from 1. * @param filterIndex A pin filter index used to enable/disable the digital filter, starting from 1.
* @param filterMode filter mode configuration * @param filterMode A filter mode configuration
*/ */
void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_pin_filter_mode_t filterMode); void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_pin_filter_mode_t filterMode);
@ -282,18 +281,18 @@ void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_
* This function gets the pin filter flag. * This function gets the pin filter flag.
* *
* @param base LLWU peripheral base address. * @param base LLWU peripheral base address.
* @param filterIndex pin filter index, start from 1. * @param filterIndex A pin filter index, which starts from 1.
* @return true if the flag is a source of existing a low-leakage power mode. * @return True if the flag is a source of the existing low-leakage power mode.
*/ */
bool LLWU_GetPinFilterFlag(LLWU_Type *base, uint32_t filterIndex); bool LLWU_GetPinFilterFlag(LLWU_Type *base, uint32_t filterIndex);
/*! /*!
* @brief Clear the pin filter configuration. * @brief Clears the pin filter configuration.
* *
* This function clear the pin filter flag. * This function clears the pin filter flag.
* *
* @param base LLWU peripheral base address. * @param base LLWU peripheral base address.
* @param filterIndex pin filter index which to be clear the flag, start from 1. * @param filterIndex A pin filter index to clear the flag, starting from 1.
*/ */
void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex); void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex);
@ -303,10 +302,10 @@ void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex);
/*! /*!
* @brief Sets the reset pin mode. * @brief Sets the reset pin mode.
* *
* This function sets how the reset pin is used as a low leakage mode exit source. * This function determines how the reset pin is used as a low leakage mode exit source.
* *
* @param pinEnable Enable reset pin filter * @param pinEnable Enable reset the pin filter
* @param pinFilterEnable Specify whether pin filter is enabled in Low-Leakage power mode. * @param pinFilterEnable Specify whether the pin filter is enabled in Low-Leakage power mode.
*/ */
void LLWU_SetResetPinMode(LLWU_Type *base, bool pinEnable, bool enableInLowLeakageMode); void LLWU_SetResetPinMode(LLWU_Type *base, bool pinEnable, bool enableInLowLeakageMode);
#endif /* FSL_FEATURE_LLWU_HAS_RESET_ENABLE */ #endif /* FSL_FEATURE_LLWU_HAS_RESET_ENABLE */

View File

@ -48,8 +48,10 @@ static uint32_t LPTMR_GetInstance(LPTMR_Type *base);
/*! @brief Pointers to LPTMR bases for each instance. */ /*! @brief Pointers to LPTMR bases for each instance. */
static LPTMR_Type *const s_lptmrBases[] = LPTMR_BASE_PTRS; static LPTMR_Type *const s_lptmrBases[] = LPTMR_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to LPTMR clocks for each instance. */ /*! @brief Pointers to LPTMR clocks for each instance. */
static const clock_ip_name_t s_lptmrClocks[] = LPTMR_CLOCKS; static const clock_ip_name_t s_lptmrClocks[] = LPTMR_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/******************************************************************************* /*******************************************************************************
* Code * Code
@ -76,8 +78,10 @@ void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config)
{ {
assert(config); assert(config);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate the LPTMR clock*/ /* Ungate the LPTMR clock*/
CLOCK_EnableClock(s_lptmrClocks[LPTMR_GetInstance(base)]); CLOCK_EnableClock(s_lptmrClocks[LPTMR_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure the timers operation mode and input pin setup */ /* Configure the timers operation mode and input pin setup */
base->CSR = (LPTMR_CSR_TMS(config->timerMode) | LPTMR_CSR_TFC(config->enableFreeRunning) | base->CSR = (LPTMR_CSR_TMS(config->timerMode) | LPTMR_CSR_TFC(config->enableFreeRunning) |
@ -92,8 +96,10 @@ void LPTMR_Deinit(LPTMR_Type *base)
{ {
/* Disable the LPTMR and reset the internal logic */ /* Disable the LPTMR and reset the internal logic */
base->CSR &= ~LPTMR_CSR_TEN_MASK; base->CSR &= ~LPTMR_CSR_TEN_MASK;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate the LPTMR clock*/ /* Gate the LPTMR clock*/
CLOCK_DisableClock(s_lptmrClocks[LPTMR_GetInstance(base)]); CLOCK_DisableClock(s_lptmrClocks[LPTMR_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void LPTMR_GetDefaultConfig(lptmr_config_t *config) void LPTMR_GetDefaultConfig(lptmr_config_t *config)

View File

@ -33,12 +33,10 @@
#include "fsl_common.h" #include "fsl_common.h"
/*! /*!
* @addtogroup lptmr_driver * @addtogroup lptmr
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
@ -48,7 +46,7 @@
#define FSL_LPTMR_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ #define FSL_LPTMR_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
/*@}*/ /*@}*/
/*! @brief LPTMR pin selection, used in pulse counter mode.*/ /*! @brief LPTMR pin selection used in pulse counter mode.*/
typedef enum _lptmr_pin_select typedef enum _lptmr_pin_select
{ {
kLPTMR_PinSelectInput_0 = 0x0U, /*!< Pulse counter input 0 is selected */ kLPTMR_PinSelectInput_0 = 0x0U, /*!< Pulse counter input 0 is selected */
@ -57,7 +55,7 @@ typedef enum _lptmr_pin_select
kLPTMR_PinSelectInput_3 = 0x3U /*!< Pulse counter input 3 is selected */ kLPTMR_PinSelectInput_3 = 0x3U /*!< Pulse counter input 3 is selected */
} lptmr_pin_select_t; } lptmr_pin_select_t;
/*! @brief LPTMR pin polarity, used in pulse counter mode.*/ /*! @brief LPTMR pin polarity used in pulse counter mode.*/
typedef enum _lptmr_pin_polarity typedef enum _lptmr_pin_polarity
{ {
kLPTMR_PinPolarityActiveHigh = 0x0U, /*!< Pulse Counter input source is active-high */ kLPTMR_PinPolarityActiveHigh = 0x0U, /*!< Pulse Counter input source is active-high */
@ -104,13 +102,13 @@ typedef enum _lptmr_prescaler_clock_select
kLPTMR_PrescalerClock_3 = 0x3U, /*!< Prescaler/glitch filter clock 3 selected. */ kLPTMR_PrescalerClock_3 = 0x3U, /*!< Prescaler/glitch filter clock 3 selected. */
} lptmr_prescaler_clock_select_t; } lptmr_prescaler_clock_select_t;
/*! @brief List of LPTMR interrupts */ /*! @brief List of the LPTMR interrupts */
typedef enum _lptmr_interrupt_enable typedef enum _lptmr_interrupt_enable
{ {
kLPTMR_TimerInterruptEnable = LPTMR_CSR_TIE_MASK, /*!< Timer interrupt enable */ kLPTMR_TimerInterruptEnable = LPTMR_CSR_TIE_MASK, /*!< Timer interrupt enable */
} lptmr_interrupt_enable_t; } lptmr_interrupt_enable_t;
/*! @brief List of LPTMR status flags */ /*! @brief List of the LPTMR status flags */
typedef enum _lptmr_status_flags typedef enum _lptmr_status_flags
{ {
kLPTMR_TimerCompareFlag = LPTMR_CSR_TCF_MASK, /*!< Timer compare flag */ kLPTMR_TimerCompareFlag = LPTMR_CSR_TCF_MASK, /*!< Timer compare flag */
@ -121,18 +119,18 @@ typedef enum _lptmr_status_flags
* *
* This structure holds the configuration settings for the LPTMR peripheral. To initialize this * 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 * structure to reasonable defaults, call the LPTMR_GetDefaultConfig() function and pass a
* pointer to your config structure instance. * pointer to your configuration structure instance.
* *
* The config struct can be made const so it resides in flash * The configuration struct can be made constant so it resides in flash.
*/ */
typedef struct _lptmr_config typedef struct _lptmr_config
{ {
lptmr_timer_mode_t timerMode; /*!< Time counter mode or pulse counter mode */ 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_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 */ 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 bool enableFreeRunning; /*!< True: enable free running, counter is reset on overflow
false: counter is reset when the compare flag is set */ False: counter is reset when the compare flag is set */
bool bypassPrescaler; /*!< true: bypass prescaler; false: use clock from prescaler */ bool bypassPrescaler; /*!< True: bypass prescaler; false: use clock from prescaler */
lptmr_prescaler_clock_select_t prescalerClockSource; /*!< LPTMR clock source */ lptmr_prescaler_clock_select_t prescalerClockSource; /*!< LPTMR clock source */
lptmr_prescaler_glitch_value_t value; /*!< Prescaler or glitch filter value */ lptmr_prescaler_glitch_value_t value; /*!< Prescaler or glitch filter value */
} lptmr_config_t; } lptmr_config_t;
@ -151,26 +149,26 @@ extern "C" {
*/ */
/*! /*!
* @brief Ungate the LPTMR clock and configures the peripheral for basic operation. * @brief Ungates the LPTMR clock and configures the peripheral for a basic operation.
* *
* @note This API should be called at the beginning of the application using the LPTMR driver. * @note This API should be called at the beginning of the application using the LPTMR driver.
* *
* @param base LPTMR peripheral base address * @param base LPTMR peripheral base address
* @param config Pointer to user's LPTMR config structure. * @param config A pointer to the LPTMR configuration structure.
*/ */
void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config); void LPTMR_Init(LPTMR_Type* base, const lptmr_config_t* config);
/*! /*!
* @brief Gate the LPTMR clock * @brief Gates the LPTMR clock.
* *
* @param base LPTMR peripheral base address * @param base LPTMR peripheral base address
*/ */
void LPTMR_Deinit(LPTMR_Type *base); void LPTMR_Deinit(LPTMR_Type* base);
/*! /*!
* @brief Fill in the LPTMR config struct with the default settings * @brief Fills in the LPTMR configuration structure with default settings.
* *
* The default values are: * The default values are as follows.
* @code * @code
* config->timerMode = kLPTMR_TimerModeTimeCounter; * config->timerMode = kLPTMR_TimerModeTimeCounter;
* config->pinSelect = kLPTMR_PinSelectInput_0; * config->pinSelect = kLPTMR_PinSelectInput_0;
@ -180,9 +178,9 @@ void LPTMR_Deinit(LPTMR_Type *base);
* config->prescalerClockSource = kLPTMR_PrescalerClock_1; * config->prescalerClockSource = kLPTMR_PrescalerClock_1;
* config->value = kLPTMR_Prescale_Glitch_0; * config->value = kLPTMR_Prescale_Glitch_0;
* @endcode * @endcode
* @param config Pointer to user's LPTMR config structure. * @param config A pointer to the LPTMR configuration structure.
*/ */
void LPTMR_GetDefaultConfig(lptmr_config_t *config); void LPTMR_GetDefaultConfig(lptmr_config_t* config);
/*! @}*/ /*! @}*/
@ -198,9 +196,14 @@ void LPTMR_GetDefaultConfig(lptmr_config_t *config);
* @param mask The interrupts to enable. This is a logical OR of members of the * @param mask The interrupts to enable. This is a logical OR of members of the
* enumeration ::lptmr_interrupt_enable_t * enumeration ::lptmr_interrupt_enable_t
*/ */
static inline void LPTMR_EnableInterrupts(LPTMR_Type *base, uint32_t mask) static inline void LPTMR_EnableInterrupts(LPTMR_Type* base, uint32_t mask)
{ {
base->CSR |= mask; uint32_t reg = base->CSR;
/* Clear the TCF bit so that we don't clear this w1c bit when writing back */
reg &= ~(LPTMR_CSR_TCF_MASK);
reg |= mask;
base->CSR = reg;
} }
/*! /*!
@ -208,11 +211,16 @@ static inline void LPTMR_EnableInterrupts(LPTMR_Type *base, uint32_t mask)
* *
* @param base LPTMR peripheral base address * @param base LPTMR peripheral base address
* @param mask The interrupts to disable. This is a logical OR of members of the * @param mask The interrupts to disable. This is a logical OR of members of the
* enumeration ::lptmr_interrupt_enable_t * enumeration ::lptmr_interrupt_enable_t.
*/ */
static inline void LPTMR_DisableInterrupts(LPTMR_Type *base, uint32_t mask) static inline void LPTMR_DisableInterrupts(LPTMR_Type* base, uint32_t mask)
{ {
base->CSR &= ~mask; uint32_t reg = base->CSR;
/* Clear the TCF bit so that we don't clear this w1c bit when writing back */
reg &= ~(LPTMR_CSR_TCF_MASK);
reg &= ~mask;
base->CSR = reg;
} }
/*! /*!
@ -223,7 +231,7 @@ static inline void LPTMR_DisableInterrupts(LPTMR_Type *base, uint32_t mask)
* @return The enabled interrupts. This is the logical OR of members of the * @return The enabled interrupts. This is the logical OR of members of the
* enumeration ::lptmr_interrupt_enable_t * enumeration ::lptmr_interrupt_enable_t
*/ */
static inline uint32_t LPTMR_GetEnabledInterrupts(LPTMR_Type *base) static inline uint32_t LPTMR_GetEnabledInterrupts(LPTMR_Type* base)
{ {
return (base->CSR & LPTMR_CSR_TIE_MASK); return (base->CSR & LPTMR_CSR_TIE_MASK);
} }
@ -236,26 +244,26 @@ static inline uint32_t LPTMR_GetEnabledInterrupts(LPTMR_Type *base)
*/ */
/*! /*!
* @brief Gets the LPTMR status flags * @brief Gets the LPTMR status flags.
* *
* @param base LPTMR peripheral base address * @param base LPTMR peripheral base address
* *
* @return The status flags. This is the logical OR of members of the * @return The status flags. This is the logical OR of members of the
* enumeration ::lptmr_status_flags_t * enumeration ::lptmr_status_flags_t
*/ */
static inline uint32_t LPTMR_GetStatusFlags(LPTMR_Type *base) static inline uint32_t LPTMR_GetStatusFlags(LPTMR_Type* base)
{ {
return (base->CSR & LPTMR_CSR_TCF_MASK); return (base->CSR & LPTMR_CSR_TCF_MASK);
} }
/*! /*!
* @brief Clears the LPTMR status flags * @brief Clears the LPTMR status flags.
* *
* @param base LPTMR peripheral base address * @param base LPTMR peripheral base address
* @param mask The status flags to clear. This is a logical OR of members of the * @param mask The status flags to clear. This is a logical OR of members of the
* enumeration ::lptmr_status_flags_t * enumeration ::lptmr_status_flags_t.
*/ */
static inline void LPTMR_ClearStatusFlags(LPTMR_Type *base, uint32_t mask) static inline void LPTMR_ClearStatusFlags(LPTMR_Type* base, uint32_t mask)
{ {
base->CSR |= mask; base->CSR |= mask;
} }
@ -263,43 +271,43 @@ static inline void LPTMR_ClearStatusFlags(LPTMR_Type *base, uint32_t mask)
/*! @}*/ /*! @}*/
/*! /*!
* @name Read and Write the timer period * @name Read and write the timer period
* @{ * @{
*/ */
/*! /*!
* @brief Sets the timer period in units of count. * @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 * Timers counts from 0 until it equals the count value set here. The count value is written to
* the CMR register. * the CMR register.
* *
* @note * @note
* 1. The TCF flag is set with the CNR equals the count provided here and then increments. * 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 * 2. Call the utility macros provided in the fsl_common.h to convert to ticks.
* *
* @param base LPTMR peripheral base address * @param base LPTMR peripheral base address
* @param ticks Timer period in units of ticks * @param ticks A timer period in units of ticks, which should be equal or greater than 1.
*/ */
static inline void LPTMR_SetTimerPeriod(LPTMR_Type *base, uint16_t ticks) static inline void LPTMR_SetTimerPeriod(LPTMR_Type* base, uint16_t ticks)
{ {
base->CMR = ticks; base->CMR = ticks - 1;
} }
/*! /*!
* @brief Reads the current timer counting value. * @brief Reads the current timer counting value.
* *
* This function returns the real-time timer counting value, in a range from 0 to a * This function returns the real-time timer counting value in a range from 0 to a
* timer period. * timer period.
* *
* @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec * @note Call the utility macros provided in the fsl_common.h to convert ticks to usec or msec.
* *
* @param base LPTMR peripheral base address * @param base LPTMR peripheral base address
* *
* @return Current counter value in ticks * @return The current counter value in ticks
*/ */
static inline uint16_t LPTMR_GetCurrentTimerCount(LPTMR_Type *base) 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 /* Must first write any value to the CNR. This synchronizes and registers the current value
* of the CNR into a temporary register which can then be read * of the CNR into a temporary register which can then be read
*/ */
base->CNR = 0U; base->CNR = 0U;
@ -314,30 +322,40 @@ static inline uint16_t LPTMR_GetCurrentTimerCount(LPTMR_Type *base)
*/ */
/*! /*!
* @brief Starts the timer counting. * @brief Starts the timer.
* *
* After calling this function, the timer counts up to the CMR register value. * 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 * Each time the timer reaches the CMR value and then increments, it generates a
* trigger pulse and sets the timeout interrupt flag. An interrupt will also be * trigger pulse and sets the timeout interrupt flag. An interrupt is also
* triggered if the timer interrupt is enabled. * triggered if the timer interrupt is enabled.
* *
* @param base LPTMR peripheral base address * @param base LPTMR peripheral base address
*/ */
static inline void LPTMR_StartTimer(LPTMR_Type *base) static inline void LPTMR_StartTimer(LPTMR_Type* base)
{ {
base->CSR |= LPTMR_CSR_TEN_MASK; uint32_t reg = base->CSR;
/* Clear the TCF bit to avoid clearing the w1c bit when writing back. */
reg &= ~(LPTMR_CSR_TCF_MASK);
reg |= LPTMR_CSR_TEN_MASK;
base->CSR = reg;
} }
/*! /*!
* @brief Stops the timer counting. * @brief Stops the timer.
* *
* This function stops the timer counting and resets the timer's counter register * This function stops the timer and resets the timer's counter register.
* *
* @param base LPTMR peripheral base address * @param base LPTMR peripheral base address
*/ */
static inline void LPTMR_StopTimer(LPTMR_Type *base) static inline void LPTMR_StopTimer(LPTMR_Type* base)
{ {
base->CSR &= ~LPTMR_CSR_TEN_MASK; uint32_t reg = base->CSR;
/* Clear the TCF bit to avoid clearing the w1c bit when writing back. */
reg &= ~(LPTMR_CSR_TCF_MASK);
reg &= ~LPTMR_CSR_TEN_MASK;
base->CSR = reg;
} }
/*! @}*/ /*! @}*/

View File

@ -30,18 +30,13 @@
#include "fsl_mpu.h" #include "fsl_mpu.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Defines the register numbers of the region descriptor configure. */
#define MPU_REGIONDESCRIPTOR_WROD_REGNUM (4U)
/******************************************************************************* /*******************************************************************************
* Variables * Variables
******************************************************************************/ ******************************************************************************/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
const clock_ip_name_t g_mpuClock[FSL_FEATURE_SOC_MPU_COUNT] = MPU_CLOCKS; const clock_ip_name_t g_mpuClock[FSL_FEATURE_SOC_MPU_COUNT] = MPU_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/******************************************************************************* /*******************************************************************************
* Codes * Codes
@ -52,8 +47,10 @@ void MPU_Init(MPU_Type *base, const mpu_config_t *config)
assert(config); assert(config);
uint8_t count; uint8_t count;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Un-gate MPU clock */ /* Un-gate MPU clock */
CLOCK_EnableClock(g_mpuClock[0]); CLOCK_EnableClock(g_mpuClock[0]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Initializes the regions. */ /* Initializes the regions. */
for (count = 1; count < FSL_FEATURE_MPU_DESCRIPTOR_COUNT; count++) for (count = 1; count < FSL_FEATURE_MPU_DESCRIPTOR_COUNT; count++)
@ -80,8 +77,10 @@ void MPU_Deinit(MPU_Type *base)
/* Disable MPU. */ /* Disable MPU. */
MPU_Enable(base, false); MPU_Enable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate the clock. */ /* Gate the clock. */
CLOCK_DisableClock(g_mpuClock[0]); CLOCK_DisableClock(g_mpuClock[0]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void MPU_GetHardwareInfo(MPU_Type *base, mpu_hardware_info_t *hardwareInform) void MPU_GetHardwareInfo(MPU_Type *base, mpu_hardware_info_t *hardwareInform)
@ -98,98 +97,113 @@ void MPU_GetHardwareInfo(MPU_Type *base, mpu_hardware_info_t *hardwareInform)
void MPU_SetRegionConfig(MPU_Type *base, const mpu_region_config_t *regionConfig) void MPU_SetRegionConfig(MPU_Type *base, const mpu_region_config_t *regionConfig)
{ {
assert(regionConfig); assert(regionConfig);
assert(regionConfig->regionNum < FSL_FEATURE_MPU_DESCRIPTOR_COUNT);
uint32_t wordReg = 0; uint32_t wordReg = 0;
uint8_t count; uint8_t msPortNum;
uint8_t number = regionConfig->regionNum; uint8_t regNumber = regionConfig->regionNum;
/* The start and end address of the region descriptor. */ /* The start and end address of the region descriptor. */
base->WORD[number][0] = regionConfig->startAddress; base->WORD[regNumber][0] = regionConfig->startAddress;
base->WORD[number][1] = regionConfig->endAddress; base->WORD[regNumber][1] = regionConfig->endAddress;
/* The region descriptor access rights control. */ /* Set the privilege rights for master 0 ~ master 3. */
for (count = 0; count < MPU_REGIONDESCRIPTOR_WROD_REGNUM; count++) for (msPortNum = 0; msPortNum <= MPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX; msPortNum++)
{ {
wordReg |= MPU_WORD_LOW_MASTER(count, (((uint32_t)regionConfig->accessRights1[count].superAccessRights << 3U) | wordReg |= MPU_REGION_RWXRIGHTS_MASTER(
(uint8_t)regionConfig->accessRights1[count].userAccessRights)) | msPortNum, (((uint32_t)regionConfig->accessRights1[msPortNum].superAccessRights << 3U) |
MPU_WORD_HIGH_MASTER(count, ((uint32_t)regionConfig->accessRights2[count].readEnable << 1U | (uint32_t)regionConfig->accessRights1[msPortNum].userAccessRights));
(uint8_t)regionConfig->accessRights2[count].writeEnable));
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER #if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
wordReg |= MPU_WORD_MASTER_PE(count, regionConfig->accessRights1[count].processIdentifierEnable); wordReg |=
MPU_REGION_RWXRIGHTS_MASTER_PE(msPortNum, regionConfig->accessRights1[msPortNum].processIdentifierEnable);
#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ #endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */
} }
/* Set the normal read write rights for master 4 ~ master 7. */
for (msPortNum = FSL_FEATURE_MPU_PRIVILEGED_RIGHTS_MASTER_COUNT; msPortNum < FSL_FEATURE_MPU_MASTER_COUNT;
msPortNum++)
{
wordReg |= MPU_REGION_RWRIGHTS_MASTER(msPortNum,
((uint32_t)regionConfig->accessRights2[msPortNum - FSL_FEATURE_MPU_PRIVILEGED_RIGHTS_MASTER_COUNT].readEnable << 1U |
(uint32_t)regionConfig->accessRights2[msPortNum - FSL_FEATURE_MPU_PRIVILEGED_RIGHTS_MASTER_COUNT].writeEnable));
}
/* Set region descriptor access rights. */ /* Set region descriptor access rights. */
base->WORD[number][2] = wordReg; base->WORD[regNumber][2] = wordReg;
wordReg = MPU_WORD_VLD(1); wordReg = MPU_WORD_VLD(1);
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER #if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
wordReg |= MPU_WORD_PID(regionConfig->processIdentifier) | MPU_WORD_PIDMASK(regionConfig->processIdMask); wordReg |= MPU_WORD_PID(regionConfig->processIdentifier) | MPU_WORD_PIDMASK(regionConfig->processIdMask);
#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ #endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */
base->WORD[number][3] = wordReg; base->WORD[regNumber][3] = wordReg;
} }
void MPU_SetRegionAddr(MPU_Type *base, mpu_region_num_t regionNum, uint32_t startAddr, uint32_t endAddr) void MPU_SetRegionAddr(MPU_Type *base, uint32_t regionNum, uint32_t startAddr, uint32_t endAddr)
{ {
assert(regionNum < FSL_FEATURE_MPU_DESCRIPTOR_COUNT);
base->WORD[regionNum][0] = startAddr; base->WORD[regionNum][0] = startAddr;
base->WORD[regionNum][1] = endAddr; base->WORD[regionNum][1] = endAddr;
} }
void MPU_SetRegionLowMasterAccessRights(MPU_Type *base, void MPU_SetRegionRwxMasterAccessRights(MPU_Type *base,
mpu_region_num_t regionNum, uint32_t regionNum,
mpu_master_t masterNum, uint32_t masterNum,
const mpu_low_masters_access_rights_t *accessRights) const mpu_rwxrights_master_access_control_t *accessRights)
{ {
assert(accessRights); assert(accessRights);
#if FSL_FEATURE_MPU_HAS_MASTER4 assert(regionNum < FSL_FEATURE_MPU_DESCRIPTOR_COUNT);
assert(masterNum < kMPU_Master4); assert(masterNum <= MPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX);
#endif
uint32_t mask = MPU_WORD_LOW_MASTER_MASK(masterNum); uint32_t mask = MPU_REGION_RWXRIGHTS_MASTER_MASK(masterNum);
uint32_t right = base->RGDAAC[regionNum]; uint32_t right = base->RGDAAC[regionNum];
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER #if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
mask |= MPU_LOW_MASTER_PE_MASK(masterNum); mask |= MPU_REGION_RWXRIGHTS_MASTER_PE_MASK(masterNum);
#endif #endif
/* Build rights control value. */ /* Build rights control value. */
right &= ~mask; right &= ~mask;
right |= MPU_WORD_LOW_MASTER(masterNum, right |= MPU_REGION_RWXRIGHTS_MASTER(
((uint32_t)(accessRights->superAccessRights << 3U) | accessRights->userAccessRights)); masterNum, ((uint32_t)(accessRights->superAccessRights << 3U) | accessRights->userAccessRights));
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER #if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
right |= MPU_WORD_MASTER_PE(masterNum, accessRights->processIdentifierEnable); right |= MPU_REGION_RWXRIGHTS_MASTER_PE(masterNum, accessRights->processIdentifierEnable);
#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ #endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */
/* Set low master region access rights. */ /* Set low master region access rights. */
base->RGDAAC[regionNum] = right; base->RGDAAC[regionNum] = right;
} }
void MPU_SetRegionHighMasterAccessRights(MPU_Type *base, #if FSL_FEATURE_MPU_HAS_MASTER_4_7
mpu_region_num_t regionNum, void MPU_SetRegionRwMasterAccessRights(MPU_Type *base,
mpu_master_t masterNum, uint32_t regionNum,
const mpu_high_masters_access_rights_t *accessRights) uint32_t masterNum,
const mpu_rwrights_master_access_control_t *accessRights)
{ {
assert(accessRights); assert(accessRights);
#if FSL_FEATURE_MPU_HAS_MASTER3 assert(regionNum < FSL_FEATURE_MPU_DESCRIPTOR_COUNT);
assert(masterNum > kMPU_Master3); assert(masterNum > MPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX);
#endif assert(masterNum <= FSL_FEATURE_MPU_MASTER_MAX_INDEX);
uint32_t mask = MPU_WORD_HIGH_MASTER_MASK(masterNum);
uint32_t mask = MPU_REGION_RWRIGHTS_MASTER_MASK(masterNum);
uint32_t right = base->RGDAAC[regionNum]; uint32_t right = base->RGDAAC[regionNum];
/* Build rights control value. */ /* Build rights control value. */
right &= ~mask; right &= ~mask;
right |= MPU_WORD_HIGH_MASTER((masterNum - (uint8_t)kMPU_RegionNum04), right |=
(((uint32_t)accessRights->readEnable << 1U) | accessRights->writeEnable)); MPU_REGION_RWRIGHTS_MASTER(masterNum, (((uint32_t)accessRights->readEnable << 1U) | accessRights->writeEnable));
/* Set low master region access rights. */ /* Set low master region access rights. */
base->RGDAAC[regionNum] = right; base->RGDAAC[regionNum] = right;
} }
#endif /* FSL_FEATURE_MPU_HAS_MASTER_4_7 */
bool MPU_GetSlavePortErrorStatus(MPU_Type *base, mpu_slave_t slaveNum) bool MPU_GetSlavePortErrorStatus(MPU_Type *base, mpu_slave_t slaveNum)
{ {
uint8_t sperr; uint8_t sperr;
sperr = ((base->CESR & MPU_CESR_SPERR_MASK) >> MPU_CESR_SPERR_SHIFT) & (0x1U << slaveNum); sperr = ((base->CESR & MPU_CESR_SPERR_MASK) >> MPU_CESR_SPERR_SHIFT) & (0x1U << (MPU_SLAVE_PORT_NUM - slaveNum));
return (sperr != 0) ? true : false; return (sperr != 0) ? true : false;
} }
@ -199,6 +213,7 @@ void MPU_GetDetailErrorAccessInfo(MPU_Type *base, mpu_slave_t slaveNum, mpu_acce
assert(errInform); assert(errInform);
uint16_t value; uint16_t value;
uint32_t cesReg;
/* Error address. */ /* Error address. */
errInform->address = base->SP[slaveNum].EAR; errInform->address = base->SP[slaveNum].EAR;
@ -219,14 +234,14 @@ void MPU_GetDetailErrorAccessInfo(MPU_Type *base, mpu_slave_t slaveNum, mpu_acce
} }
value = base->SP[slaveNum].EDR; value = base->SP[slaveNum].EDR;
errInform->master = (mpu_master_t)((value & MPU_EDR_EMN_MASK) >> MPU_EDR_EMN_SHIFT); errInform->master = (uint32_t)((value & MPU_EDR_EMN_MASK) >> MPU_EDR_EMN_SHIFT);
errInform->attributes = (mpu_err_attributes_t)((value & MPU_EDR_EATTR_MASK) >> MPU_EDR_EATTR_SHIFT); errInform->attributes = (mpu_err_attributes_t)((value & MPU_EDR_EATTR_MASK) >> MPU_EDR_EATTR_SHIFT);
errInform->accessType = (mpu_err_access_type_t)((value & MPU_EDR_ERW_MASK) >> MPU_EDR_ERW_SHIFT); errInform->accessType = (mpu_err_access_type_t)((value & MPU_EDR_ERW_MASK) >> MPU_EDR_ERW_SHIFT);
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER #if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
errInform->processorIdentification = (uint8_t)((value & MPU_EDR_EPID_MASK) >> MPU_EDR_EPID_SHIFT); errInform->processorIdentification = (uint8_t)((value & MPU_EDR_EPID_MASK) >> MPU_EDR_EPID_SHIFT);
#endif #endif
/*!< Clears error slave port bit. */ /* Clears error slave port bit. */
value = (base->CESR & ~MPU_CESR_SPERR_MASK) | (0x1U << slaveNum); cesReg = (base->CESR & ~MPU_CESR_SPERR_MASK) | ((0x1U << slaveNum) << MPU_CESR_SPERR_SHIFT);
base->CESR = value; base->CESR = cesReg;
} }

View File

@ -37,7 +37,6 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -45,130 +44,47 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief MPU driver version 2.0.0. */ /*! @brief MPU driver version 2.1.0. */
#define FSL_MPU_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) #define FSL_MPU_DRIVER_VERSION (MAKE_VERSION(2, 1, 1))
/*@}*/ /*@}*/
/*! @brief MPU low master bit shift. */ /*! @brief MPU the bit shift for masters with privilege rights: read write and execute. */
#define MPU_WORD_LOW_MASTER_SHIFT(n) (n * 6) #define MPU_REGION_RWXRIGHTS_MASTER_SHIFT(n) (n * 6)
/*! @brief MPU low master bit mask. */ /*! @brief MPU masters with read, write and execute rights bit mask. */
#define MPU_WORD_LOW_MASTER_MASK(n) (0x1Fu << MPU_WORD_LOW_MASTER_SHIFT(n)) #define MPU_REGION_RWXRIGHTS_MASTER_MASK(n) (0x1Fu << MPU_REGION_RWXRIGHTS_MASTER_SHIFT(n))
/*! @brief MPU low master bit width. */ /*! @brief MPU masters with read, write and execute rights bit width. */
#define MPU_WORD_LOW_MASTER_WIDTH 5 #define MPU_REGION_RWXRIGHTS_MASTER_WIDTH 5
/*! @brief MPU low master priority setting. */ /*! @brief MPU masters with read, write and execute rights priority setting. */
#define MPU_WORD_LOW_MASTER(n, x) \ #define MPU_REGION_RWXRIGHTS_MASTER(n, x) \
(((uint32_t)(((uint32_t)(x)) << MPU_WORD_LOW_MASTER_SHIFT(n))) & MPU_WORD_LOW_MASTER_MASK(n)) (((uint32_t)(((uint32_t)(x)) << MPU_REGION_RWXRIGHTS_MASTER_SHIFT(n))) & MPU_REGION_RWXRIGHTS_MASTER_MASK(n))
/*! @brief MPU low master process enable bit shift. */ /*! @brief MPU masters with read, write and execute rights process enable bit shift. */
#define MPU_LOW_MASTER_PE_SHIFT(n) (n * 6 + 5) #define MPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n) (n * 6 + MPU_REGION_RWXRIGHTS_MASTER_WIDTH)
/*! @brief MPU low master process enable bit mask. */ /*! @brief MPU masters with read, write and execute rights process enable bit mask. */
#define MPU_LOW_MASTER_PE_MASK(n) (0x1u << MPU_LOW_MASTER_PE_SHIFT(n)) #define MPU_REGION_RWXRIGHTS_MASTER_PE_MASK(n) (0x1u << MPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n))
/*! @brief MPU low master process enable width. */ /*! @brief MPU masters with read, write and execute rights process enable setting. */
#define MPU_WORD_MASTER_PE_WIDTH 1 #define MPU_REGION_RWXRIGHTS_MASTER_PE(n, x) \
(((uint32_t)(((uint32_t)(x)) << MPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n))) & MPU_REGION_RWXRIGHTS_MASTER_PE_MASK(n))
/*! @brief MPU low master process enable setting. */ /*! @brief MPU masters with normal read write permission bit shift. */
#define MPU_WORD_MASTER_PE(n, x) \ #define MPU_REGION_RWRIGHTS_MASTER_SHIFT(n) ((n - FSL_FEATURE_MPU_PRIVILEGED_RIGHTS_MASTER_COUNT) * 2 + 24)
(((uint32_t)(((uint32_t)(x)) << MPU_LOW_MASTER_PE_SHIFT(n))) & MPU_LOW_MASTER_PE_MASK(n))
/*! @brief MPU high master bit shift. */ /*! @brief MPU masters with normal read write rights bit mask. */
#define MPU_WORD_HIGH_MASTER_SHIFT(n) (n * 2 + 24) #define MPU_REGION_RWRIGHTS_MASTER_MASK(n) (0x3u << MPU_REGION_RWRIGHTS_MASTER_SHIFT(n))
/*! @brief MPU high master bit mask. */ /*! @brief MPU masters with normal read write rights priority setting. */
#define MPU_WORD_HIGH_MASTER_MASK(n) (0x03u << MPU_WORD_HIGH_MASTER_SHIFT(n)) #define MPU_REGION_RWRIGHTS_MASTER(n, x) \
(((uint32_t)(((uint32_t)(x)) << MPU_REGION_RWRIGHTS_MASTER_SHIFT(n))) & MPU_REGION_RWRIGHTS_MASTER_MASK(n))
/*! @brief MPU high master bit width. */ /*! @brief the Slave port numbers. */
#define MPU_WORD_HIGH_MASTER_WIDTH 2 #define MPU_SLAVE_PORT_NUM (4u)
/*! @brief define the maximum index of master with privileged rights. */
/*! @brief MPU high master priority setting. */ #define MPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX (3)
#define MPU_WORD_HIGH_MASTER(n, x) \
(((uint32_t)(((uint32_t)(x)) << MPU_WORD_HIGH_MASTER_SHIFT(n))) & MPU_WORD_HIGH_MASTER_MASK(n))
/*! @brief MPU region number. */
typedef enum _mpu_region_num
{
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 0U
kMPU_RegionNum00 = 0U, /*!< MPU region number 0. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 1U
kMPU_RegionNum01 = 1U, /*!< MPU region number 1. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 2U
kMPU_RegionNum02 = 2U, /*!< MPU region number 2. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 3U
kMPU_RegionNum03 = 3U, /*!< MPU region number 3. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 4U
kMPU_RegionNum04 = 4U, /*!< MPU region number 4. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 5U
kMPU_RegionNum05 = 5U, /*!< MPU region number 5. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 6U
kMPU_RegionNum06 = 6U, /*!< MPU region number 6. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 7U
kMPU_RegionNum07 = 7U, /*!< MPU region number 7. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 8U
kMPU_RegionNum08 = 8U, /*!< MPU region number 8. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 9U
kMPU_RegionNum09 = 9U, /*!< MPU region number 9. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 10U
kMPU_RegionNum10 = 10U, /*!< MPU region number 10. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 11U
kMPU_RegionNum11 = 11U, /*!< MPU region number 11. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 12U
kMPU_RegionNum12 = 12U, /*!< MPU region number 12. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 13U
kMPU_RegionNum13 = 13U, /*!< MPU region number 13. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 14U
kMPU_RegionNum14 = 14U, /*!< MPU region number 14. */
#endif
#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 15U
kMPU_RegionNum15 = 15U, /*!< MPU region number 15. */
#endif
} mpu_region_num_t;
/*! @brief MPU master number. */
typedef enum _mpu_master
{
#if FSL_FEATURE_MPU_HAS_MASTER0
kMPU_Master0 = 0U, /*!< MPU master core. */
#endif
#if FSL_FEATURE_MPU_HAS_MASTER1
kMPU_Master1 = 1U, /*!< MPU master defined in SoC. */
#endif
#if FSL_FEATURE_MPU_HAS_MASTER2
kMPU_Master2 = 2U, /*!< MPU master defined in SoC. */
#endif
#if FSL_FEATURE_MPU_HAS_MASTER3
kMPU_Master3 = 3U, /*!< MPU master defined in SoC. */
#endif
#if FSL_FEATURE_MPU_HAS_MASTER4
kMPU_Master4 = 4U, /*!< MPU master defined in SoC. */
#endif
#if FSL_FEATURE_MPU_HAS_MASTER5
kMPU_Master5 = 5U, /*!< MPU master defined in SoC. */
#endif
#if FSL_FEATURE_MPU_HAS_MASTER6
kMPU_Master6 = 6U, /*!< MPU master defined in SoC. */
#endif
#if FSL_FEATURE_MPU_HAS_MASTER7
kMPU_Master7 = 7U /*!< MPU master defined in SoC. */
#endif
} mpu_master_t;
/*! @brief Describes the number of MPU regions. */ /*! @brief Describes the number of MPU regions. */
typedef enum _mpu_region_total_num typedef enum _mpu_region_total_num
@ -181,11 +97,11 @@ typedef enum _mpu_region_total_num
/*! @brief MPU slave port number. */ /*! @brief MPU slave port number. */
typedef enum _mpu_slave typedef enum _mpu_slave
{ {
kMPU_Slave0 = 4U, /*!< MPU slave port 0. */ kMPU_Slave0 = 0U, /*!< MPU slave port 0. */
kMPU_Slave1 = 3U, /*!< MPU slave port 1. */ kMPU_Slave1 = 1U, /*!< MPU slave port 1. */
kMPU_Slave2 = 2U, /*!< MPU slave port 2. */ kMPU_Slave2 = 2U, /*!< MPU slave port 2. */
kMPU_Slave3 = 1U, /*!< MPU slave port 3. */ kMPU_Slave3 = 3U, /*!< MPU slave port 3. */
kMPU_Slave4 = 0U /*!< MPU slave port 4. */ kMPU_Slave4 = 4U /*!< MPU slave port 4. */
} mpu_slave_t; } mpu_slave_t;
/*! @brief MPU error access control detail. */ /*! @brief MPU error access control detail. */
@ -212,7 +128,7 @@ typedef enum _mpu_err_attributes
kMPU_DataAccessInSupervisorMode = 3U /*!< Access data error in supervisor mode. */ kMPU_DataAccessInSupervisorMode = 3U /*!< Access data error in supervisor mode. */
} mpu_err_attributes_t; } mpu_err_attributes_t;
/*! @brief MPU access rights in supervisor mode for master port 0 ~ port 3. */ /*! @brief MPU access rights in supervisor mode for bus master 0 ~ 3. */
typedef enum _mpu_supervisor_access_rights typedef enum _mpu_supervisor_access_rights
{ {
kMPU_SupervisorReadWriteExecute = 0U, /*!< Read write and execute operations are allowed in supervisor mode. */ kMPU_SupervisorReadWriteExecute = 0U, /*!< Read write and execute operations are allowed in supervisor mode. */
@ -221,7 +137,7 @@ typedef enum _mpu_supervisor_access_rights
kMPU_SupervisorEqualToUsermode = 3U /*!< Access permission equal to user mode. */ kMPU_SupervisorEqualToUsermode = 3U /*!< Access permission equal to user mode. */
} mpu_supervisor_access_rights_t; } mpu_supervisor_access_rights_t;
/*! @brief MPU access rights in user mode for master port 0 ~ port 3. */ /*! @brief MPU access rights in user mode for bus master 0 ~ 3. */
typedef enum _mpu_user_access_rights typedef enum _mpu_user_access_rights
{ {
kMPU_UserNoAccessRights = 0U, /*!< No access allowed in user mode. */ kMPU_UserNoAccessRights = 0U, /*!< No access allowed in user mode. */
@ -245,7 +161,7 @@ typedef struct _mpu_hardware_info
/*! @brief MPU detail error access information. */ /*! @brief MPU detail error access information. */
typedef struct _mpu_access_err_info typedef struct _mpu_access_err_info
{ {
mpu_master_t master; /*!< Access error master. */ uint32_t master; /*!< Access error master. */
mpu_err_attributes_t attributes; /*!< Access error attributes. */ mpu_err_attributes_t attributes; /*!< Access error attributes. */
mpu_err_access_type_t accessType; /*!< Access error type. */ mpu_err_access_type_t accessType; /*!< Access error type. */
mpu_err_access_control_t accessControl; /*!< Access error control. */ mpu_err_access_control_t accessControl; /*!< Access error control. */
@ -255,50 +171,50 @@ typedef struct _mpu_access_err_info
#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ #endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */
} mpu_access_err_info_t; } mpu_access_err_info_t;
/*! @brief MPU access rights for low master master port 0 ~ port 3. */ /*! @brief MPU read/write/execute rights control for bus master 0 ~ 3. */
typedef struct _mpu_low_masters_access_rights typedef struct _mpu_rwxrights_master_access_control
{ {
mpu_supervisor_access_rights_t superAccessRights; /*!< Master access rights in supervisor mode. */ mpu_supervisor_access_rights_t superAccessRights; /*!< Master access rights in supervisor mode. */
mpu_user_access_rights_t userAccessRights; /*!< Master access rights in user mode. */ mpu_user_access_rights_t userAccessRights; /*!< Master access rights in user mode. */
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER #if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
bool processIdentifierEnable; /*!< Enables or disables process identifier. */ bool processIdentifierEnable; /*!< Enables or disables process identifier. */
#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ #endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */
} mpu_low_masters_access_rights_t; } mpu_rwxrights_master_access_control_t;
/*! @brief MPU access rights mode for high master port 4 ~ port 7. */ /*! @brief MPU read/write access control for bus master 4 ~ 7. */
typedef struct _mpu_high_masters_access_rights typedef struct _mpu_rwrights_master_access_control
{ {
bool writeEnable; /*!< Enables or disables write permission. */ bool writeEnable; /*!< Enables or disables write permission. */
bool readEnable; /*!< Enables or disables read permission. */ bool readEnable; /*!< Enables or disables read permission. */
} mpu_high_masters_access_rights_t; } mpu_rwrights_master_access_control_t;
/*! /*!
* @brief MPU region configuration structure. * @brief MPU region configuration structure.
* *
* This structure is used to configure the regionNum region. * This structure is used to configure the regionNum region.
* The accessRights1[0] ~ accessRights1[3] are used to configure the four low master * The accessRights1[0] ~ accessRights1[3] are used to configure the bus master
* numbers: master 0 ~ master 3. The accessRights2[0] ~ accessRights2[3] are * 0 ~ 3 with the privilege rights setting. The accessRights2[0] ~ accessRights2[3]
* used to configure the four high master numbers: master 4 ~ master 7. * are used to configure the high master 4 ~ 7 with the normal read write permission.
* The master port assignment is the chip configuration. Normally, the core is the * The master port assignment is the chip configuration. Normally, the core is the
* master 0, debugger is the master 1. * master 0, debugger is the master 1.
* Note: MPU assigns a priority scheme where the debugger is treated as the highest * Note that the MPU assigns a priority scheme where the debugger is treated as the highest
* priority master followed by the core and then all the remaining masters. * priority master followed by the core and then all the remaining masters.
* MPU protection does not allow writes from the core to affect the "regionNum 0" start * MPU protection does not allow writes from the core to affect the "regionNum 0" start
* and end address nor the permissions associated with the debugger. It can only write * and end address nor the permissions associated with the debugger. It can only write
* the permission fields associated with the other masters. This protection guarantee * the permission fields associated with the other masters. This protection guarantees that
* the debugger always has access to the entire address space and those rights can't * the debugger always has access to the entire address space and those rights can't
* be changed by the core or any other bus master. Prepare * be changed by the core or any other bus master. Prepare
* the region configuration when regionNum is kMPU_RegionNum00. * the region configuration when regionNum is 0.
*/ */
typedef struct _mpu_region_config typedef struct _mpu_region_config
{ {
mpu_region_num_t regionNum; /*!< MPU region number. */ uint32_t regionNum; /*!< MPU region number, range form 0 ~ FSL_FEATURE_MPU_DESCRIPTOR_COUNT - 1. */
uint32_t startAddress; /*!< Memory region start address. Note: bit0 ~ bit4 always be marked as 0 by MPU. The actual uint32_t startAddress; /*!< Memory region start address. Note: bit0 ~ bit4 always be marked as 0 by MPU. The actual
start address is 0-modulo-32 byte address. */ start address is 0-modulo-32 byte address. */
uint32_t endAddress; /*!< Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by MPU. The actual end uint32_t endAddress; /*!< Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by MPU. The actual end
address is 31-modulo-32 byte address. */ address is 31-modulo-32 byte address. */
mpu_low_masters_access_rights_t accessRights1[4]; /*!< Low masters access permission. */ mpu_rwxrights_master_access_control_t accessRights1[4]; /*!< Masters with read, write and execute rights setting. */
mpu_high_masters_access_rights_t accessRights2[4]; /*!< High masters access permission. */ mpu_rwrights_master_access_control_t accessRights2[4]; /*!< Masters with normal read write rights setting. */
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER #if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
uint8_t processIdentifier; /*!< Process identifier used when "processIdentifierEnable" set with true. */ uint8_t processIdentifier; /*!< Process identifier used when "processIdentifierEnable" set with true. */
uint8_t uint8_t
@ -313,8 +229,8 @@ typedef struct _mpu_region_config
*/ */
typedef struct _mpu_config typedef struct _mpu_config
{ {
mpu_region_config_t regionConfig; /*!< region access permission. */ mpu_region_config_t regionConfig; /*!< Region access permission. */
struct _mpu_config *next; /*!< pointer to the next structure. */ struct _mpu_config *next; /*!< Pointer to the next structure. */
} mpu_config_t; } mpu_config_t;
/******************************************************************************* /*******************************************************************************
@ -385,7 +301,7 @@ static inline void MPU_Enable(MPU_Type *base, bool enable)
* @param number MPU region number. * @param number MPU region number.
* @param enable True enable the special region MPU, false disable the special region MPU. * @param enable True enable the special region MPU, false disable the special region MPU.
*/ */
static inline void MPU_RegionEnable(MPU_Type *base, mpu_region_num_t number, bool enable) static inline void MPU_RegionEnable(MPU_Type *base, uint32_t number, bool enable)
{ {
if (enable) if (enable)
{ {
@ -409,7 +325,7 @@ void MPU_GetHardwareInfo(MPU_Type *base, mpu_hardware_info_t *hardwareInform);
/*! /*!
* @brief Sets the MPU region. * @brief Sets the MPU region.
* *
* Note: Due to the MPU protection, the kMPU_RegionNum00 does not allow writes from the * Note: Due to the MPU protection, the region number 0 does not allow writes from
* core to affect the start and end address nor the permissions associated with * core to affect the start and end address nor the permissions associated with
* the debugger. It can only write the permission fields associated * the debugger. It can only write the permission fields associated
* with the other masters. * with the other masters.
@ -425,45 +341,61 @@ void MPU_SetRegionConfig(MPU_Type *base, const mpu_region_config_t *regionConfig
* Memory region start address. Note: bit0 ~ bit4 is always marked as 0 by MPU. * Memory region start address. Note: bit0 ~ bit4 is always marked as 0 by MPU.
* The actual start address by MPU is 0-modulo-32 byte address. * The actual start address by MPU is 0-modulo-32 byte address.
* Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by MPU. * Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by MPU.
* The actual end address used by MPU is 31-modulo-32 byte address. * The end address used by the MPU is 31-modulo-32 byte address.
* Note: Due to the MPU protection, the startAddr and endAddr can't be * Note: Due to the MPU protection, the startAddr and endAddr can't be
* changed by the core when regionNum is "kMPU_RegionNum00". * changed by the core when regionNum is 0.
* *
* @param base MPU peripheral base address. * @param base MPU peripheral base address.
* @param regionNum MPU region number. * @param regionNum MPU region number. The range is from 0 to
* FSL_FEATURE_MPU_DESCRIPTOR_COUNT - 1.
* @param startAddr Region start address. * @param startAddr Region start address.
* @param endAddr Region end address. * @param endAddr Region end address.
*/ */
void MPU_SetRegionAddr(MPU_Type *base, mpu_region_num_t regionNum, uint32_t startAddr, uint32_t endAddr); void MPU_SetRegionAddr(MPU_Type *base, uint32_t regionNum, uint32_t startAddr, uint32_t endAddr);
/*! /*!
* @brief Sets the MPU region access rights for low master port 0 ~ port 3. * @brief Sets the MPU region access rights for masters with read, write, and execute rights.
* This can be used to change the region access rights for any master port for any region. * The MPU access rights depend on two board classifications of bus masters.
* The privilege rights masters and the normal rights masters.
* The privilege rights masters have the read, write, and execute access rights.
* Except the normal read and write rights, the execute rights are also
* allowed for these masters. The privilege rights masters normally range from
* bus masters 0 - 3. However, the maximum master number is device-specific.
* See the "MPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX".
* The normal rights masters access rights control see
* "MPU_SetRegionRwMasterAccessRights()".
* *
* @param base MPU peripheral base address. * @param base MPU peripheral base address.
* @param regionNum MPU region number. * @param regionNum MPU region number. Should range from 0 to
* @param masterNum MPU master number. Should range from kMPU_Master0 ~ kMPU_Master3. * FSL_FEATURE_MPU_DESCRIPTOR_COUNT - 1.
* @param accessRights The pointer to the MPU access rights configuration. See "mpu_low_masters_access_rights_t". * @param masterNum MPU bus master number. Should range from 0 to
* MPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX.
* @param accessRights The pointer to the MPU access rights configuration. See "mpu_rwxrights_master_access_control_t".
*/ */
void MPU_SetRegionLowMasterAccessRights(MPU_Type *base, void MPU_SetRegionRwxMasterAccessRights(MPU_Type *base,
mpu_region_num_t regionNum, uint32_t regionNum,
mpu_master_t masterNum, uint32_t masterNum,
const mpu_low_masters_access_rights_t *accessRights); const mpu_rwxrights_master_access_control_t *accessRights);
#if FSL_FEATURE_MPU_HAS_MASTER_4_7
/*! /*!
* @brief Sets the MPU region access rights for high master port 4 ~ port 7. * @brief Sets the MPU region access rights for masters with read and write rights.
* This can be used to change the region access rights for any master port for any region. * The MPU access rights depend on two board classifications of bus masters.
* The privilege rights masters and the normal rights masters.
* The normal rights masters only have the read and write access permissions.
* The privilege rights access control see "MPU_SetRegionRwxMasterAccessRights".
* *
* @param base MPU peripheral base address. * @param base MPU peripheral base address.
* @param regionNum MPU region number. * @param regionNum MPU region number. The range is from 0 to
* @param masterNum MPU master number. Should range from kMPU_Master4 ~ kMPU_Master7. * FSL_FEATURE_MPU_DESCRIPTOR_COUNT - 1.
* @param accessRights The pointer to the MPU access rights configuration. See "mpu_high_masters_access_rights_t". * @param masterNum MPU bus master number. Should range from FSL_FEATURE_MPU_PRIVILEGED_RIGHTS_MASTER_COUNT
* to ~ FSL_FEATURE_MPU_MASTER_MAX_INDEX.
* @param accessRights The pointer to the MPU access rights configuration. See "mpu_rwrights_master_access_control_t".
*/ */
void MPU_SetRegionHighMasterAccessRights(MPU_Type *base, void MPU_SetRegionRwMasterAccessRights(MPU_Type *base,
mpu_region_num_t regionNum, uint32_t regionNum,
mpu_master_t masterNum, uint32_t masterNum,
const mpu_high_masters_access_rights_t *accessRights); const mpu_rwrights_master_access_control_t *accessRights);
#endif /* FSL_FEATURE_MPU_HAS_MASTER_4_7 */
/*! /*!
* @brief Gets the numbers of slave ports where errors occur. * @brief Gets the numbers of slave ports where errors occur.
* *

View File

@ -45,8 +45,10 @@ static uint32_t PDB_GetInstance(PDB_Type *base);
******************************************************************************/ ******************************************************************************/
/*! @brief Pointers to PDB bases for each instance. */ /*! @brief Pointers to PDB bases for each instance. */
static PDB_Type *const s_pdbBases[] = PDB_BASE_PTRS; static PDB_Type *const s_pdbBases[] = PDB_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to PDB clocks for each instance. */ /*! @brief Pointers to PDB clocks for each instance. */
const clock_ip_name_t s_pdbClocks[] = PDB_CLOCKS; static const clock_ip_name_t s_pdbClocks[] = PDB_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/******************************************************************************* /*******************************************************************************
* Codes * Codes
@ -75,8 +77,10 @@ void PDB_Init(PDB_Type *base, const pdb_config_t *config)
uint32_t tmp32; uint32_t tmp32;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock. */ /* Enable the clock. */
CLOCK_EnableClock(s_pdbClocks[PDB_GetInstance(base)]); CLOCK_EnableClock(s_pdbClocks[PDB_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure. */ /* Configure. */
/* PDBx_SC. */ /* PDBx_SC. */
@ -98,8 +102,10 @@ void PDB_Deinit(PDB_Type *base)
{ {
PDB_Enable(base, false); /* Disable the PDB module. */ PDB_Enable(base, false); /* Disable the PDB module. */
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock. */ /* Disable the clock. */
CLOCK_DisableClock(s_pdbClocks[PDB_GetInstance(base)]); CLOCK_DisableClock(s_pdbClocks[PDB_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void PDB_GetDefaultConfig(pdb_config_t *config) void PDB_GetDefaultConfig(pdb_config_t *config)

View File

@ -38,7 +38,6 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -67,32 +66,32 @@ enum _pdb_status_flags
enum _pdb_adc_pretrigger_flags enum _pdb_adc_pretrigger_flags
{ {
/* PDB PreTrigger channel match flags. */ /* PDB PreTrigger channel match flags. */
kPDB_ADCPreTriggerChannel0Flag = PDB_S_CF(1U << 0), /*!< Pre-Trigger 0 flag. */ kPDB_ADCPreTriggerChannel0Flag = PDB_S_CF(1U << 0), /*!< Pre-trigger 0 flag. */
kPDB_ADCPreTriggerChannel1Flag = PDB_S_CF(1U << 1), /*!< Pre-Trigger 1 flag. */ kPDB_ADCPreTriggerChannel1Flag = PDB_S_CF(1U << 1), /*!< Pre-trigger 1 flag. */
#if (PDB_DLY_COUNT > 2) #if (PDB_DLY_COUNT2 > 2)
kPDB_ADCPreTriggerChannel2Flag = PDB_S_CF(1U << 2), /*!< Pre-Trigger 2 flag. */ kPDB_ADCPreTriggerChannel2Flag = PDB_S_CF(1U << 2), /*!< Pre-trigger 2 flag. */
kPDB_ADCPreTriggerChannel3Flag = PDB_S_CF(1U << 3), /*!< Pre-Trigger 3 flag. */ kPDB_ADCPreTriggerChannel3Flag = PDB_S_CF(1U << 3), /*!< Pre-trigger 3 flag. */
#endif /* PDB_DLY_COUNT > 2 */ #endif /* PDB_DLY_COUNT2 > 2 */
#if (PDB_DLY_COUNT > 4) #if (PDB_DLY_COUNT2 > 4)
kPDB_ADCPreTriggerChannel4Flag = PDB_S_CF(1U << 4), /*!< Pre-Trigger 4 flag. */ kPDB_ADCPreTriggerChannel4Flag = PDB_S_CF(1U << 4), /*!< Pre-trigger 4 flag. */
kPDB_ADCPreTriggerChannel5Flag = PDB_S_CF(1U << 5), /*!< Pre-Trigger 5 flag. */ kPDB_ADCPreTriggerChannel5Flag = PDB_S_CF(1U << 5), /*!< Pre-trigger 5 flag. */
kPDB_ADCPreTriggerChannel6Flag = PDB_S_CF(1U << 6), /*!< Pre-Trigger 6 flag. */ kPDB_ADCPreTriggerChannel6Flag = PDB_S_CF(1U << 6), /*!< Pre-trigger 6 flag. */
kPDB_ADCPreTriggerChannel7Flag = PDB_S_CF(1U << 7), /*!< Pre-Trigger 7 flag. */ kPDB_ADCPreTriggerChannel7Flag = PDB_S_CF(1U << 7), /*!< Pre-trigger 7 flag. */
#endif /* PDB_DLY_COUNT > 4 */ #endif /* PDB_DLY_COUNT2 > 4 */
/* PDB PreTrigger channel error flags. */ /* PDB PreTrigger channel error flags. */
kPDB_ADCPreTriggerChannel0ErrorFlag = PDB_S_ERR(1U << 0), /*!< Pre-Trigger 0 Error. */ kPDB_ADCPreTriggerChannel0ErrorFlag = PDB_S_ERR(1U << 0), /*!< Pre-trigger 0 Error. */
kPDB_ADCPreTriggerChannel1ErrorFlag = PDB_S_ERR(1U << 1), /*!< Pre-Trigger 1 Error. */ kPDB_ADCPreTriggerChannel1ErrorFlag = PDB_S_ERR(1U << 1), /*!< Pre-trigger 1 Error. */
#if (PDB_DLY_COUNT > 2) #if (PDB_DLY_COUNT2 > 2)
kPDB_ADCPreTriggerChannel2ErrorFlag = PDB_S_ERR(1U << 2), /*!< Pre-Trigger 2 Error. */ kPDB_ADCPreTriggerChannel2ErrorFlag = PDB_S_ERR(1U << 2), /*!< Pre-trigger 2 Error. */
kPDB_ADCPreTriggerChannel3ErrorFlag = PDB_S_ERR(1U << 3), /*!< Pre-Trigger 3 Error. */ kPDB_ADCPreTriggerChannel3ErrorFlag = PDB_S_ERR(1U << 3), /*!< Pre-trigger 3 Error. */
#endif /* PDB_DLY_COUNT > 2 */ #endif /* PDB_DLY_COUNT2 > 2 */
#if (PDB_DLY_COUNT > 4) #if (PDB_DLY_COUNT2 > 4)
kPDB_ADCPreTriggerChannel4ErrorFlag = PDB_S_ERR(1U << 4), /*!< Pre-Trigger 4 Error. */ kPDB_ADCPreTriggerChannel4ErrorFlag = PDB_S_ERR(1U << 4), /*!< Pre-trigger 4 Error. */
kPDB_ADCPreTriggerChannel5ErrorFlag = PDB_S_ERR(1U << 5), /*!< Pre-Trigger 5 Error. */ kPDB_ADCPreTriggerChannel5ErrorFlag = PDB_S_ERR(1U << 5), /*!< Pre-trigger 5 Error. */
kPDB_ADCPreTriggerChannel6ErrorFlag = PDB_S_ERR(1U << 6), /*!< Pre-Trigger 6 Error. */ kPDB_ADCPreTriggerChannel6ErrorFlag = PDB_S_ERR(1U << 6), /*!< Pre-trigger 6 Error. */
kPDB_ADCPreTriggerChannel7ErrorFlag = PDB_S_ERR(1U << 7), /*!< Pre-Trigger 7 Error. */ kPDB_ADCPreTriggerChannel7ErrorFlag = PDB_S_ERR(1U << 7), /*!< Pre-trigger 7 Error. */
#endif /* PDB_DLY_COUNT > 4 */ #endif /* PDB_DLY_COUNT2 > 4 */
}; };
/*! /*!
@ -108,7 +107,7 @@ enum _pdb_interrupt_enable
* @brief PDB load value mode. * @brief PDB load value mode.
* *
* Selects the mode to load the internal values after doing the load operation (write 1 to PDBx_SC[LDOK]). * Selects the mode to load the internal values after doing the load operation (write 1 to PDBx_SC[LDOK]).
* These values are for: * These values are for the following operations.
* - PDB counter (PDBx_MOD, PDBx_IDLY) * - PDB counter (PDBx_MOD, PDBx_IDLY)
* - ADC trigger (PDBx_CHnDLYm) * - ADC trigger (PDBx_CHnDLYm)
* - DAC trigger (PDBx_DACINTx) * - DAC trigger (PDBx_DACINTx)
@ -158,7 +157,7 @@ typedef enum _pdb_divider_multiplication_factor
* @brief Trigger input source * @brief Trigger input source
* *
* Selects the trigger input source for the PDB. The trigger input source can be internal or external (EXTRG pin), or * Selects the trigger input source for the PDB. The trigger input source can be internal or external (EXTRG pin), or
* the software trigger. Refer to chip configuration details for the actual PDB input trigger connections. * the software trigger. See chip configuration details for the actual PDB input trigger connections.
*/ */
typedef enum _pdb_trigger_input_source typedef enum _pdb_trigger_input_source
{ {
@ -177,7 +176,7 @@ typedef enum _pdb_trigger_input_source
kPDB_TriggerInput12 = 12U, /*!< Trigger-In 12. */ kPDB_TriggerInput12 = 12U, /*!< Trigger-In 12. */
kPDB_TriggerInput13 = 13U, /*!< Trigger-In 13. */ kPDB_TriggerInput13 = 13U, /*!< Trigger-In 13. */
kPDB_TriggerInput14 = 14U, /*!< Trigger-In 14. */ kPDB_TriggerInput14 = 14U, /*!< Trigger-In 14. */
kPDB_TriggerSoftware = 15U, /*!< Trigger-In 15. */ kPDB_TriggerSoftware = 15U, /*!< Trigger-In 15, software trigger. */
} pdb_trigger_input_source_t; } pdb_trigger_input_source_t;
/*! /*!
@ -193,15 +192,15 @@ typedef struct _pdb_config
} pdb_config_t; } pdb_config_t;
/*! /*!
* @brief PDB ADC Pre-Trigger configuration. * @brief PDB ADC Pre-trigger configuration.
*/ */
typedef struct _pdb_adc_pretrigger_config typedef struct _pdb_adc_pretrigger_config
{ {
uint32_t enablePreTriggerMask; /*!< PDB Channel Pre-Trigger Enable. */ uint32_t enablePreTriggerMask; /*!< PDB Channel Pre-trigger Enable. */
uint32_t enableOutputMask; /*!< PDB Channel Pre-Trigger Output Select. uint32_t enableOutputMask; /*!< PDB Channel Pre-trigger Output Select.
PDB channel's corresponding pre-trigger asserts when the counter PDB channel's corresponding pre-trigger asserts when the counter
reaches the channel delay register. */ reaches the channel delay register. */
uint32_t enableBackToBackOperationMask; /*!< PDB Channel Pre-Trigger Back-to-Back Operation Enable. uint32_t enableBackToBackOperationMask; /*!< PDB Channel pre-trigger Back-to-Back Operation Enable.
Back-to-back operation enables the ADC conversions complete to trigger Back-to-back operation enables the ADC conversions complete to trigger
the next PDB channel pre-trigger and trigger output, so that the ADC the next PDB channel pre-trigger and trigger output, so that the ADC
conversions can be triggered on next set of configuration and results conversions can be triggered on next set of configuration and results
@ -230,29 +229,29 @@ extern "C" {
*/ */
/*! /*!
* @brief Initializes the PDB module. * @brief Initializes the PDB module.
* *
* This function is to make the initialization for PDB module. The operations includes are: * This function initializes the PDB module. The operations included are as follows.
* - Enable the clock for PDB instance. * - Enable the clock for PDB instance.
* - Configure the PDB module. * - Configure the PDB module.
* - Enable the PDB module. * - Enable the PDB module.
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.
* @param config Pointer to configuration structure. See "pdb_config_t". * @param config Pointer to the configuration structure. See "pdb_config_t".
*/ */
void PDB_Init(PDB_Type *base, const pdb_config_t *config); void PDB_Init(PDB_Type *base, const pdb_config_t *config);
/*! /*!
* @brief De-initializes the PDB module. * @brief De-initializes the PDB module.
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.
*/ */
void PDB_Deinit(PDB_Type *base); void PDB_Deinit(PDB_Type *base);
/*! /*!
* @brief Initializes the PDB user configure structure. * @brief Initializes the PDB user configuration structure.
* *
* This function initializes the user configure structure to default value. the default value are: * This function initializes the user configuration structure to a default value. The default values are as follows.
* @code * @code
* config->loadValueMode = kPDB_LoadValueImmediately; * config->loadValueMode = kPDB_LoadValueImmediately;
* config->prescalerDivider = kPDB_PrescalerDivider1; * config->prescalerDivider = kPDB_PrescalerDivider1;
@ -302,7 +301,7 @@ static inline void PDB_DoSoftwareTrigger(PDB_Type *base)
/*! /*!
* @brief Loads the counter values. * @brief Loads the counter values.
* *
* This function is to load the counter values from their internal buffer. * This function loads the counter values from the internal buffer.
* See "pdb_load_value_mode_t" about PDB's load mode. * See "pdb_load_value_mode_t" about PDB's load mode.
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.
@ -382,7 +381,7 @@ static inline void PDB_ClearStatusFlags(PDB_Type *base, uint32_t mask)
} }
/*! /*!
* @brief Specifies the period of the counter. * @brief Specifies the counter period.
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.
* @param value Setting value for the modulus. 16-bit is available. * @param value Setting value for the modulus. 16-bit is available.
@ -405,7 +404,7 @@ static inline uint32_t PDB_GetCounterValue(PDB_Type *base)
} }
/*! /*!
* @brief Sets the value for PDB counter delay event. * @brief Sets the value for the PDB counter delay event.
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.
* @param value Setting value for PDB counter delay event. 16-bit is available. * @param value Setting value for PDB counter delay event. 16-bit is available.
@ -417,16 +416,16 @@ static inline void PDB_SetCounterDelayValue(PDB_Type *base, uint32_t value)
/* @} */ /* @} */
/*! /*!
* @name ADC Pre-Trigger * @name ADC Pre-trigger
* @{ * @{
*/ */
/*! /*!
* @brief Configures the ADC PreTrigger in PDB module. * @brief Configures the ADC pre-trigger in the PDB module.
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.
* @param channel Channel index for ADC instance. * @param channel Channel index for ADC instance.
* @param config Pointer to configuration structure. See "pdb_adc_pretrigger_config_t". * @param config Pointer to the configuration structure. See "pdb_adc_pretrigger_config_t".
*/ */
static inline void PDB_SetADCPreTriggerConfig(PDB_Type *base, uint32_t channel, pdb_adc_pretrigger_config_t *config) static inline void PDB_SetADCPreTriggerConfig(PDB_Type *base, uint32_t channel, pdb_adc_pretrigger_config_t *config)
{ {
@ -434,30 +433,31 @@ static inline void PDB_SetADCPreTriggerConfig(PDB_Type *base, uint32_t channel,
assert(NULL != config); assert(NULL != config);
base->CH[channel].C1 = PDB_C1_BB(config->enableBackToBackOperationMask) | PDB_C1_TOS(config->enableOutputMask) | base->CH[channel].C1 = PDB_C1_BB(config->enableBackToBackOperationMask) | PDB_C1_TOS(config->enableOutputMask) |
PDB_C1_EN(config->enableOutputMask); PDB_C1_EN(config->enablePreTriggerMask);
} }
/*! /*!
* @brief Sets the value for ADC Pre-Trigger delay event. * @brief Sets the value for the ADC pre-trigger delay event.
* *
* This function is to set the value for ADC Pre-Trigger delay event. IT Specifies the delay value for the channel's * This function sets the value for ADC pre-trigger delay event. It specifies the delay value for the channel's
* corresponding pre-trigger. The pre-trigger asserts when the PDB counter is equal to the setting value here. * corresponding pre-trigger. The pre-trigger asserts when the PDB counter is equal to the set value.
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.
* @param channel Channel index for ADC instance. * @param channel Channel index for ADC instance.
* @param preChannel Channel group index for ADC instance. * @param preChannel Channel group index for ADC instance.
* @param value Setting value for ADC Pre-Trigger delay event. 16-bit is available. * @param value Setting value for ADC pre-trigger delay event. 16-bit is available.
*/ */
static inline void PDB_SetADCPreTriggerDelayValue(PDB_Type *base, uint32_t channel, uint32_t preChannel, uint32_t value) static inline void PDB_SetADCPreTriggerDelayValue(PDB_Type *base, uint32_t channel, uint32_t preChannel, uint32_t value)
{ {
assert(channel < PDB_C1_COUNT); assert(channel < PDB_C1_COUNT);
assert(preChannel < PDB_DLY_COUNT); assert(preChannel < PDB_DLY_COUNT2);
/* xx_COUNT2 is actually the count for pre-triggers in header file. xx_COUNT is used for the count of channels. */
base->CH[channel].DLY[preChannel] = PDB_DLY_DLY(value); base->CH[channel].DLY[preChannel] = PDB_DLY_DLY(value);
} }
/*! /*!
* @brief Gets the ADC Pre-Trigger's status flags. * @brief Gets the ADC pre-trigger's status flags.
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.
* @param channel Channel index for ADC instance. * @param channel Channel index for ADC instance.
@ -472,7 +472,7 @@ static inline uint32_t PDB_GetADCPreTriggerStatusFlags(PDB_Type *base, uint32_t
} }
/*! /*!
* @brief Clears the ADC Pre-Trigger's status flags. * @brief Clears the ADC pre-trigger status flags.
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.
* @param channel Channel index for ADC instance. * @param channel Channel index for ADC instance.
@ -494,19 +494,19 @@ static inline void PDB_ClearADCPreTriggerStatusFlags(PDB_Type *base, uint32_t ch
*/ */
/*! /*!
* @brief Configures the DAC trigger in PDB module. * @brief Configures the DAC trigger in the PDB module.
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.
* @param channel Channel index for DAC instance. * @param channel Channel index for DAC instance.
* @param config Pointer to configuration structure. See "pdb_dac_trigger_config_t". * @param config Pointer to the configuration structure. See "pdb_dac_trigger_config_t".
*/ */
void PDB_SetDACTriggerConfig(PDB_Type *base, uint32_t channel, pdb_dac_trigger_config_t *config); void PDB_SetDACTriggerConfig(PDB_Type *base, uint32_t channel, pdb_dac_trigger_config_t *config);
/*! /*!
* @brief Sets the value for the DAC interval event. * @brief Sets the value for the DAC interval event.
* *
* This fucntion is to set the value for DAC interval event. DAC interval trigger would trigger the DAC module to update * This fucntion sets the value for DAC interval event. DAC interval trigger triggers the DAC module to update
* buffer when the DAC interval counter is equal to the setting value here. * the buffer when the DAC interval counter is equal to the set value.
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.
* @param channel Channel index for DAC instance. * @param channel Channel index for DAC instance.
@ -532,7 +532,7 @@ static inline void PDB_SetDACTriggerIntervalValue(PDB_Type *base, uint32_t chann
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.
* @param channelMask Channel mask value for multiple pulse out trigger channel. * @param channelMask Channel mask value for multiple pulse out trigger channel.
* @param enable Enable the feature or not. * @param enable Whether the feature is enabled or not.
*/ */
static inline void PDB_EnablePulseOutTrigger(PDB_Type *base, uint32_t channelMask, bool enable) static inline void PDB_EnablePulseOutTrigger(PDB_Type *base, uint32_t channelMask, bool enable)
{ {
@ -547,11 +547,11 @@ static inline void PDB_EnablePulseOutTrigger(PDB_Type *base, uint32_t channelMas
} }
/*! /*!
* @brief Sets event values for pulse out trigger. * @brief Sets event values for the pulse out trigger.
* *
* This function is used to set event values for pulse output trigger. * This function is used to set event values for the pulse output trigger.
* These pulse output trigger delay values specify the delay for the PDB Pulse-Out. Pulse-Out goes high when the PDB * These pulse output trigger delay values specify the delay for the PDB Pulse-out. Pulse-out goes high when the PDB
* counter is equal to the pulse output high value (value1). Pulse-Out goes low when the PDB counter is equal to the * counter is equal to the pulse output high value (value1). Pulse-out goes low when the PDB counter is equal to the
* pulse output low value (value2). * pulse output low value (value2).
* *
* @param base PDB peripheral base address. * @param base PDB peripheral base address.

View File

@ -48,8 +48,10 @@ static uint32_t PIT_GetInstance(PIT_Type *base);
/*! @brief Pointers to PIT bases for each instance. */ /*! @brief Pointers to PIT bases for each instance. */
static PIT_Type *const s_pitBases[] = PIT_BASE_PTRS; static PIT_Type *const s_pitBases[] = PIT_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to PIT clocks for each instance. */ /*! @brief Pointers to PIT clocks for each instance. */
static const clock_ip_name_t s_pitClocks[] = PIT_CLOCKS; static const clock_ip_name_t s_pitClocks[] = PIT_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/******************************************************************************* /*******************************************************************************
* Code * Code
@ -76,8 +78,10 @@ void PIT_Init(PIT_Type *base, const pit_config_t *config)
{ {
assert(config); assert(config);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate the PIT clock*/ /* Ungate the PIT clock*/
CLOCK_EnableClock(s_pitClocks[PIT_GetInstance(base)]); CLOCK_EnableClock(s_pitClocks[PIT_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Enable PIT timers */ /* Enable PIT timers */
base->MCR &= ~PIT_MCR_MDIS_MASK; base->MCR &= ~PIT_MCR_MDIS_MASK;
@ -98,8 +102,10 @@ void PIT_Deinit(PIT_Type *base)
/* Disable PIT timers */ /* Disable PIT timers */
base->MCR |= PIT_MCR_MDIS_MASK; base->MCR |= PIT_MCR_MDIS_MASK;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate the PIT clock*/ /* Gate the PIT clock*/
CLOCK_DisableClock(s_pitClocks[PIT_GetInstance(base)]); CLOCK_DisableClock(s_pitClocks[PIT_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
#if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && FSL_FEATURE_PIT_HAS_LIFETIME_TIMER #if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && FSL_FEATURE_PIT_HAS_LIFETIME_TIMER

View File

@ -33,11 +33,10 @@
#include "fsl_common.h" #include "fsl_common.h"
/*! /*!
* @addtogroup pit_driver * @addtogroup pit
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -73,13 +72,13 @@ typedef enum _pit_status_flags
} pit_status_flags_t; } pit_status_flags_t;
/*! /*!
* @brief PIT config structure * @brief PIT configuration structure
* *
* This structure holds the configuration settings for the PIT peripheral. To initialize this * 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 * structure to reasonable defaults, call the PIT_GetDefaultConfig() function and pass a
* pointer to your config structure instance. * pointer to your config structure instance.
* *
* The config struct can be made const so it resides in flash * The configuration structure can be made constant so it resides in flash.
*/ */
typedef struct _pit_config typedef struct _pit_config
{ {
@ -100,30 +99,30 @@ extern "C" {
*/ */
/*! /*!
* @brief Ungates the PIT clock, enables the PIT module and configures the peripheral for basic operation. * @brief Ungates the PIT clock, enables the PIT module, and configures the peripheral for basic operations.
* *
* @note This API should be called at the beginning of the application using the PIT driver. * @note This API should be called at the beginning of the application using the PIT driver.
* *
* @param base PIT peripheral base address * @param base PIT peripheral base address
* @param config Pointer to user's PIT config structure * @param config Pointer to the user's PIT config structure
*/ */
void PIT_Init(PIT_Type *base, const pit_config_t *config); void PIT_Init(PIT_Type *base, const pit_config_t *config);
/*! /*!
* @brief Gate the PIT clock and disable the PIT module * @brief Gates the PIT clock and disables the PIT module.
* *
* @param base PIT peripheral base address * @param base PIT peripheral base address
*/ */
void PIT_Deinit(PIT_Type *base); void PIT_Deinit(PIT_Type *base);
/*! /*!
* @brief Fill in the PIT config struct with the default settings * @brief Fills in the PIT configuration structure with the default settings.
* *
* The default values are: * The default values are as follows.
* @code * @code
* config->enableRunInDebug = false; * config->enableRunInDebug = false;
* @endcode * @endcode
* @param config Pointer to user's PIT config structure. * @param config Pointer to the onfiguration structure.
*/ */
static inline void PIT_GetDefaultConfig(pit_config_t *config) static inline void PIT_GetDefaultConfig(pit_config_t *config)
{ {
@ -140,9 +139,9 @@ static inline void PIT_GetDefaultConfig(pit_config_t *config)
* *
* When a timer has a chain mode enabled, it only counts after the previous * 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 * 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 * decrements the value by one. Each timer is 32-bits, which allows the developers
* to chain timers together and form a longer timer (64-bits and larger). The first timer * 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. * (timer 0) can't be chained to any other timer.
* *
* @param base PIT peripheral base address * @param base PIT peripheral base address
* @param channel Timer channel number which is chained with the previous timer * @param channel Timer channel number which is chained with the previous timer
@ -219,7 +218,7 @@ static inline uint32_t PIT_GetEnabledInterrupts(PIT_Type *base, pit_chnl_t chann
*/ */
/*! /*!
* @brief Gets the PIT status flags * @brief Gets the PIT status flags.
* *
* @param base PIT peripheral base address * @param base PIT peripheral base address
* @param channel Timer channel number * @param channel Timer channel number
@ -256,11 +255,11 @@ static inline void PIT_ClearStatusFlags(PIT_Type *base, pit_chnl_t channel, uint
* @brief Sets the timer period in units of count. * @brief Sets the timer period in units of count.
* *
* Timers begin counting from the value set by this function until it reaches 0, * 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. * then it generates an interrupt and load this register value again.
* Writing a new value to this register will not restart the timer; instead the value * Writing a new value to this register does not restart the timer. Instead, the value
* will be loaded after the timer expires. * is loaded after the timer expires.
* *
* @note User can call the utility macros provided in fsl_common.h to convert to ticks * @note Users can call the utility macros provided in fsl_common.h to convert to ticks.
* *
* @param base PIT peripheral base address * @param base PIT peripheral base address
* @param channel Timer channel number * @param channel Timer channel number
@ -277,7 +276,7 @@ static inline void PIT_SetTimerPeriod(PIT_Type *base, pit_chnl_t channel, uint32
* This function returns the real-time timer counting value, in a range from 0 to a * This function returns the real-time timer counting value, in a range from 0 to a
* timer period. * timer period.
* *
* @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec * @note Users can call the utility macros provided in fsl_common.h to convert ticks to usec or msec.
* *
* @param base PIT peripheral base address * @param base PIT peripheral base address
* @param channel Timer channel number * @param channel Timer channel number

View File

@ -35,7 +35,6 @@
/*! @addtogroup pmc */ /*! @addtogroup pmc */
/*! @{ */ /*! @{ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -49,36 +48,36 @@
#if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV) #if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV)
/*! /*!
* @brief Low-Voltage Detect Voltage Select * @brief Low-voltage Detect Voltage Select
*/ */
typedef enum _pmc_low_volt_detect_volt_select typedef enum _pmc_low_volt_detect_volt_select
{ {
kPMC_LowVoltDetectLowTrip = 0U, /*!< Low trip point selected (VLVD = VLVDL )*/ kPMC_LowVoltDetectLowTrip = 0U, /*!< Low-trip point selected (VLVD = VLVDL )*/
kPMC_LowVoltDetectHighTrip = 1U /*!< High trip point selected (VLVD = VLVDH )*/ kPMC_LowVoltDetectHighTrip = 1U /*!< High-trip point selected (VLVD = VLVDH )*/
} pmc_low_volt_detect_volt_select_t; } pmc_low_volt_detect_volt_select_t;
#endif #endif
#if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV) #if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV)
/*! /*!
* @brief Low-Voltage Warning Voltage Select * @brief Low-voltage Warning Voltage Select
*/ */
typedef enum _pmc_low_volt_warning_volt_select typedef enum _pmc_low_volt_warning_volt_select
{ {
kPMC_LowVoltWarningLowTrip = 0U, /*!< Low trip point selected (VLVW = VLVW1)*/ kPMC_LowVoltWarningLowTrip = 0U, /*!< Low-trip point selected (VLVW = VLVW1)*/
kPMC_LowVoltWarningMid1Trip = 1U, /*!< Mid 1 trip point selected (VLVW = VLVW2)*/ kPMC_LowVoltWarningMid1Trip = 1U, /*!< Mid 1 trip point selected (VLVW = VLVW2)*/
kPMC_LowVoltWarningMid2Trip = 2U, /*!< Mid 2 trip point selected (VLVW = VLVW3)*/ kPMC_LowVoltWarningMid2Trip = 2U, /*!< Mid 2 trip point selected (VLVW = VLVW3)*/
kPMC_LowVoltWarningHighTrip = 3U /*!< High trip point selected (VLVW = VLVW4)*/ kPMC_LowVoltWarningHighTrip = 3U /*!< High-trip point selected (VLVW = VLVW4)*/
} pmc_low_volt_warning_volt_select_t; } pmc_low_volt_warning_volt_select_t;
#endif #endif
#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) #if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1)
/*! /*!
* @brief High-Voltage Detect Voltage Select * @brief High-voltage Detect Voltage Select
*/ */
typedef enum _pmc_high_volt_detect_volt_select typedef enum _pmc_high_volt_detect_volt_select
{ {
kPMC_HighVoltDetectLowTrip = 0U, /*!< Low trip point selected (VHVD = VHVDL )*/ kPMC_HighVoltDetectLowTrip = 0U, /*!< Low-trip point selected (VHVD = VHVDL )*/
kPMC_HighVoltDetectHighTrip = 1U /*!< High trip point selected (VHVD = VHVDH )*/ kPMC_HighVoltDetectHighTrip = 1U /*!< High-trip point selected (VHVD = VHVDH )*/
} pmc_high_volt_detect_volt_select_t; } pmc_high_volt_detect_volt_select_t;
#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */ #endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */
@ -88,8 +87,8 @@ typedef enum _pmc_high_volt_detect_volt_select
*/ */
typedef enum _pmc_bandgap_buffer_drive_select typedef enum _pmc_bandgap_buffer_drive_select
{ {
kPMC_BandgapBufferDriveLow = 0U, /*!< Low drive. */ kPMC_BandgapBufferDriveLow = 0U, /*!< Low-drive. */
kPMC_BandgapBufferDriveHigh = 1U /*!< High drive. */ kPMC_BandgapBufferDriveHigh = 1U /*!< High-drive. */
} pmc_bandgap_buffer_drive_select_t; } pmc_bandgap_buffer_drive_select_t;
#endif /* FSL_FEATURE_PMC_HAS_BGBDS */ #endif /* FSL_FEATURE_PMC_HAS_BGBDS */
@ -126,37 +125,37 @@ typedef struct _pmc_param
#endif /* FSL_FEATURE_PMC_HAS_PARAM */ #endif /* FSL_FEATURE_PMC_HAS_PARAM */
/*! /*!
* @brief Low-Voltage Detect Configuration Structure * @brief Low-voltage Detect Configuration Structure
*/ */
typedef struct _pmc_low_volt_detect_config typedef struct _pmc_low_volt_detect_config
{ {
bool enableInt; /*!< Enable interrupt when low voltage detect*/ bool enableInt; /*!< Enable interrupt when Low-voltage detect*/
bool enableReset; /*!< Enable system reset 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) #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*/ pmc_low_volt_detect_volt_select_t voltSelect; /*!< Low-voltage detect trip point voltage selection*/
#endif #endif
} pmc_low_volt_detect_config_t; } pmc_low_volt_detect_config_t;
/*! /*!
* @brief Low-Voltage Warning Configuration Structure * @brief Low-voltage Warning Configuration Structure
*/ */
typedef struct _pmc_low_volt_warning_config typedef struct _pmc_low_volt_warning_config
{ {
bool enableInt; /*!< Enable interrupt when low voltage warning*/ bool enableInt; /*!< Enable interrupt when low-voltage warning*/
#if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV) #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*/ pmc_low_volt_warning_volt_select_t voltSelect; /*!< Low-voltage warning trip point voltage selection*/
#endif #endif
} pmc_low_volt_warning_config_t; } pmc_low_volt_warning_config_t;
#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) #if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1)
/*! /*!
* @brief High-Voltage Detect Configuration Structure * @brief High-voltage Detect Configuration Structure
*/ */
typedef struct _pmc_high_volt_detect_config typedef struct _pmc_high_volt_detect_config
{ {
bool enableInt; /*!< Enable interrupt when high voltage detect*/ bool enableInt; /*!< Enable interrupt when high-voltage detect*/
bool enableReset; /*!< Enable system reset 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_volt_select_t voltSelect; /*!< High-voltage detect trip point voltage selection*/
} pmc_high_volt_detect_config_t; } pmc_high_volt_detect_config_t;
#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */ #endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */
@ -172,7 +171,7 @@ typedef struct _pmc_bandgap_buffer_config
bool enable; /*!< Enable bandgap buffer. */ bool enable; /*!< Enable bandgap buffer. */
#endif #endif
#if (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) #if (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN)
bool enableInLowPowerMode; /*!< Enable bandgap buffer in low power mode. */ bool enableInLowPowerMode; /*!< Enable bandgap buffer in low-power mode. */
#endif /* FSL_FEATURE_PMC_HAS_BGEN */ #endif /* FSL_FEATURE_PMC_HAS_BGEN */
#if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS) #if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS)
pmc_bandgap_buffer_drive_select_t drive; /*!< Bandgap buffer drive select. */ pmc_bandgap_buffer_drive_select_t drive; /*!< Bandgap buffer drive select. */
@ -196,7 +195,7 @@ extern "C" {
* @brief Gets the PMC version ID. * @brief Gets the PMC version ID.
* *
* This function gets the PMC version ID, including major version number, * This function gets the PMC version ID, including major version number,
* minor version number and feature specification number. * minor version number, and a feature specification number.
* *
* @param base PMC peripheral base address. * @param base PMC peripheral base address.
* @param versionId Pointer to version ID structure. * @param versionId Pointer to version ID structure.
@ -211,7 +210,7 @@ static inline void PMC_GetVersionId(PMC_Type *base, pmc_version_id_t *versionId)
/*! /*!
* @brief Gets the PMC parameter. * @brief Gets the PMC parameter.
* *
* This function gets the PMC parameter, including VLPO enable and HVD enable. * This function gets the PMC parameter including the VLPO enable and the HVD enable.
* *
* @param base PMC peripheral base address. * @param base PMC peripheral base address.
* @param param Pointer to PMC param structure. * @param param Pointer to PMC param structure.
@ -220,26 +219,25 @@ void PMC_GetParam(PMC_Type *base, pmc_param_t *param);
#endif #endif
/*! /*!
* @brief Configure the low voltage detect setting. * @brief Configures the low-voltage detect setting.
* *
* This function configures the low voltage detect setting, including the trip * This function configures the low-voltage detect setting, including the trip
* point voltage setting, enable interrupt or not, enable system reset or not. * point voltage setting, enables or disables the interrupt, enables or disables the system reset.
* *
* @param base PMC peripheral base address. * @param base PMC peripheral base address.
* @param config Low-Voltage detect configuration structure. * @param config Low-voltage detect configuration structure.
*/ */
void PMC_ConfigureLowVoltDetect(PMC_Type *base, const pmc_low_volt_detect_config_t *config); void PMC_ConfigureLowVoltDetect(PMC_Type *base, const pmc_low_volt_detect_config_t *config);
/*! /*!
* @brief Get Low-Voltage Detect Flag status * @brief Gets the Low-voltage Detect Flag status.
* *
* This function reads the current LVDF status. If it returns 1, a low * This function reads the current LVDF status. If it returns 1, a low-voltage event is detected.
* voltage event is detected.
* *
* @param base PMC peripheral base address. * @param base PMC peripheral base address.
* @return Current low voltage detect flag * @return Current low-voltage detect flag
* - true: Low-Voltage detected * - true: Low-voltage detected
* - false: Low-Voltage not detected * - false: Low-voltage not detected
*/ */
static inline bool PMC_GetLowVoltDetectFlag(PMC_Type *base) static inline bool PMC_GetLowVoltDetectFlag(PMC_Type *base)
{ {
@ -247,9 +245,9 @@ static inline bool PMC_GetLowVoltDetectFlag(PMC_Type *base)
} }
/*! /*!
* @brief Acknowledge to clear the Low-Voltage Detect flag * @brief Acknowledges clearing the Low-voltage Detect flag.
* *
* This function acknowledges the low voltage detection errors (write 1 to * This function acknowledges the low-voltage detection errors (write 1 to
* clear LVDF). * clear LVDF).
* *
* @param base PMC peripheral base address. * @param base PMC peripheral base address.
@ -260,18 +258,18 @@ static inline void PMC_ClearLowVoltDetectFlag(PMC_Type *base)
} }
/*! /*!
* @brief Configure the low voltage warning setting. * @brief Configures the low-voltage warning setting.
* *
* This function configures the low voltage warning setting, including the trip * This function configures the low-voltage warning setting, including the trip
* point voltage setting and enable interrupt or not. * point voltage setting and enabling or disabling the interrupt.
* *
* @param base PMC peripheral base address. * @param base PMC peripheral base address.
* @param config Low-Voltage warning configuration structure. * @param config Low-voltage warning configuration structure.
*/ */
void PMC_ConfigureLowVoltWarning(PMC_Type *base, const pmc_low_volt_warning_config_t *config); void PMC_ConfigureLowVoltWarning(PMC_Type *base, const pmc_low_volt_warning_config_t *config);
/*! /*!
* @brief Get Low-Voltage Warning Flag status * @brief Gets the Low-voltage Warning Flag status.
* *
* This function polls the current LVWF status. When 1 is returned, it * 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 * indicates a low-voltage warning event. LVWF is set when V Supply transitions
@ -279,8 +277,8 @@ void PMC_ConfigureLowVoltWarning(PMC_Type *base, const pmc_low_volt_warning_conf
* *
* @param base PMC peripheral base address. * @param base PMC peripheral base address.
* @return Current LVWF status * @return Current LVWF status
* - true: Low-Voltage Warning Flag is set. * - true: Low-voltage Warning Flag is set.
* - false: the Low-Voltage Warning does not happen. * - false: the Low-voltage Warning does not happen.
*/ */
static inline bool PMC_GetLowVoltWarningFlag(PMC_Type *base) static inline bool PMC_GetLowVoltWarningFlag(PMC_Type *base)
{ {
@ -288,7 +286,7 @@ static inline bool PMC_GetLowVoltWarningFlag(PMC_Type *base)
} }
/*! /*!
* @brief Acknowledge to Low-Voltage Warning flag * @brief Acknowledges the Low-voltage Warning flag.
* *
* This function acknowledges the low voltage warning errors (write 1 to * This function acknowledges the low voltage warning errors (write 1 to
* clear LVWF). * clear LVWF).
@ -302,26 +300,26 @@ static inline void PMC_ClearLowVoltWarningFlag(PMC_Type *base)
#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) #if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1)
/*! /*!
* @brief Configure the high voltage detect setting. * @brief Configures the high-voltage detect setting.
* *
* This function configures the high voltage detect setting, including the trip * This function configures the high-voltage detect setting, including the trip
* point voltage setting, enable interrupt or not, enable system reset or not. * point voltage setting, enabling or disabling the interrupt, enabling or disabling the system reset.
* *
* @param base PMC peripheral base address. * @param base PMC peripheral base address.
* @param config High-Voltage detect configuration structure. * @param config High-voltage detect configuration structure.
*/ */
void PMC_ConfigureHighVoltDetect(PMC_Type *base, const pmc_high_volt_detect_config_t *config); void PMC_ConfigureHighVoltDetect(PMC_Type *base, const pmc_high_volt_detect_config_t *config);
/*! /*!
* @brief Get High-Voltage Detect Flag status * @brief Gets the High-voltage Detect Flag status.
* *
* This function reads the current HVDF status. If it returns 1, a low * This function reads the current HVDF status. If it returns 1, a low
* voltage event is detected. * voltage event is detected.
* *
* @param base PMC peripheral base address. * @param base PMC peripheral base address.
* @return Current high voltage detect flag * @return Current high-voltage detect flag
* - true: High-Voltage detected * - true: High-voltage detected
* - false: High-Voltage not detected * - false: High-voltage not detected
*/ */
static inline bool PMC_GetHighVoltDetectFlag(PMC_Type *base) static inline bool PMC_GetHighVoltDetectFlag(PMC_Type *base)
{ {
@ -329,9 +327,9 @@ static inline bool PMC_GetHighVoltDetectFlag(PMC_Type *base)
} }
/*! /*!
* @brief Acknowledge to clear the High-Voltage Detect flag * @brief Acknowledges clearing the High-voltage Detect flag.
* *
* This function acknowledges the high voltage detection errors (write 1 to * This function acknowledges the high-voltage detection errors (write 1 to
* clear HVDF). * clear HVDF).
* *
* @param base PMC peripheral base address. * @param base PMC peripheral base address.
@ -346,10 +344,10 @@ static inline void PMC_ClearHighVoltDetectFlag(PMC_Type *base)
(defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) || \ (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) || \
(defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS)) (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS))
/*! /*!
* @brief Configure the PMC bandgap * @brief Configures the PMC bandgap.
* *
* This function configures the PMC bandgap, including the drive select and * This function configures the PMC bandgap, including the drive select and
* behavior in low power mode. * behavior in low-power mode.
* *
* @param base PMC peripheral base address. * @param base PMC peripheral base address.
* @param config Pointer to the configuration structure * @param config Pointer to the configuration structure
@ -378,7 +376,7 @@ static inline bool PMC_GetPeriphIOIsolationFlag(PMC_Type *base)
} }
/*! /*!
* @brief Acknowledge to Peripherals and I/O pads isolation flag. * @brief Acknowledges the isolation flag to Peripherals and I/O pads.
* *
* This function clears the ACK Isolation flag. Writing one to this setting * 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 * when it is set releases the I/O pads and certain peripherals to their normal
@ -394,9 +392,9 @@ static inline void PMC_ClearPeriphIOIsolationFlag(PMC_Type *base)
#if (defined(FSL_FEATURE_PMC_HAS_REGONS) && FSL_FEATURE_PMC_HAS_REGONS) #if (defined(FSL_FEATURE_PMC_HAS_REGONS) && FSL_FEATURE_PMC_HAS_REGONS)
/*! /*!
* @brief Gets the Regulator regulation status. * @brief Gets the regulator regulation status.
* *
* This function returns the regulator to a run regulation status. It provides * This function returns the regulator to run a regulation status. It provides
* the current status of the internal voltage regulator. * the current status of the internal voltage regulator.
* *
* @param base PMC peripheral base address. * @param base PMC peripheral base address.

View File

@ -33,59 +33,65 @@
#include "fsl_common.h" #include "fsl_common.h"
/*! /*!
* @addtogroup port_driver * @addtogroup port
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! Version 2.0.1. */ /*! Version 2.0.2. */
#define FSL_PORT_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) #define FSL_PORT_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
/*@}*/ /*@}*/
#if defined(FSL_FEATURE_PORT_HAS_PULL_ENABLE) && FSL_FEATURE_PORT_HAS_PULL_ENABLE
/*! @brief Internal resistor pull feature selection */ /*! @brief Internal resistor pull feature selection */
enum _port_pull enum _port_pull
{ {
kPORT_PullDisable = 0U, /*!< internal pull-up/down resistor is disabled. */ kPORT_PullDisable = 0U, /*!< Internal pull-up/down resistor is disabled. */
kPORT_PullDown = 2U, /*!< internal pull-down resistor is enabled. */ kPORT_PullDown = 2U, /*!< Internal pull-down resistor is enabled. */
kPORT_PullUp = 3U, /*!< internal pull-up resistor is enabled. */ kPORT_PullUp = 3U, /*!< Internal pull-up resistor is enabled. */
}; };
#endif /* FSL_FEATURE_PORT_HAS_PULL_ENABLE */
#if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE
/*! @brief Slew rate selection */ /*! @brief Slew rate selection */
enum _port_slew_rate enum _port_slew_rate
{ {
kPORT_FastSlewRate = 0U, /*!< fast slew rate is configured. */ kPORT_FastSlewRate = 0U, /*!< Fast slew rate is configured. */
kPORT_SlowSlewRate = 1U, /*!< slow slew rate is configured. */ kPORT_SlowSlewRate = 1U, /*!< Slow slew rate is configured. */
}; };
#endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */
#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN #if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
/*! @brief Internal resistor pull feature enable/disable */ /*! @brief Open Drain feature enable/disable */
enum _port_open_drain_enable enum _port_open_drain_enable
{ {
kPORT_OpenDrainDisable = 0U, /*!< internal pull-down resistor is disabled. */ kPORT_OpenDrainDisable = 0U, /*!< Open drain output is disabled. */
kPORT_OpenDrainEnable = 1U, /*!< internal pull-up resistor is enabled. */ kPORT_OpenDrainEnable = 1U, /*!< Open drain output is enabled. */
}; };
#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */ #endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */
#if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER
/*! @brief Passive filter feature enable/disable */ /*! @brief Passive filter feature enable/disable */
enum _port_passive_filter_enable enum _port_passive_filter_enable
{ {
kPORT_PassiveFilterDisable = 0U, /*!< fast slew rate is configured. */ kPORT_PassiveFilterDisable = 0U, /*!< Passive input filter is disabled. */
kPORT_PassiveFilterEnable = 1U, /*!< slow slew rate is configured. */ kPORT_PassiveFilterEnable = 1U, /*!< Passive input filter is enabled. */
}; };
#endif
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH
/*! @brief Configures the drive strength. */ /*! @brief Configures the drive strength. */
enum _port_drive_strength enum _port_drive_strength
{ {
kPORT_LowDriveStrength = 0U, /*!< low drive strength is configured. */ kPORT_LowDriveStrength = 0U, /*!< Low-drive strength is configured. */
kPORT_HighDriveStrength = 1U, /*!< high drive strength is configured. */ kPORT_HighDriveStrength = 1U, /*!< High-drive strength is configured. */
}; };
#endif /* FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH */
#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK #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] */ /*! @brief Unlock/lock the pin control register field[15:0] */
@ -96,18 +102,28 @@ enum _port_lock_register
}; };
#endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */ #endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */
#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH
/*! @brief Pin mux selection */ /*! @brief Pin mux selection */
typedef enum _port_mux typedef enum _port_mux
{ {
kPORT_PinDisabledOrAnalog = 0U, /*!< corresponding pin is disabled, but is used as an analog pin. */ kPORT_PinDisabledOrAnalog = 0U, /*!< Corresponding pin is disabled, but is used as an analog pin. */
kPORT_MuxAsGpio = 1U, /*!< corresponding pin is configured as GPIO. */ kPORT_MuxAsGpio = 1U, /*!< Corresponding pin is configured as GPIO. */
kPORT_MuxAlt2 = 2U, /*!< chip-specific */ kPORT_MuxAlt2 = 2U, /*!< Chip-specific */
kPORT_MuxAlt3 = 3U, /*!< chip-specific */ kPORT_MuxAlt3 = 3U, /*!< Chip-specific */
kPORT_MuxAlt4 = 4U, /*!< chip-specific */ kPORT_MuxAlt4 = 4U, /*!< Chip-specific */
kPORT_MuxAlt5 = 5U, /*!< chip-specific */ kPORT_MuxAlt5 = 5U, /*!< Chip-specific */
kPORT_MuxAlt6 = 6U, /*!< chip-specific */ kPORT_MuxAlt6 = 6U, /*!< Chip-specific */
kPORT_MuxAlt7 = 7U, /*!< chip-specific */ kPORT_MuxAlt7 = 7U, /*!< Chip-specific */
kPORT_MuxAlt8 = 8U, /*!< Chip-specific */
kPORT_MuxAlt9 = 9U, /*!< Chip-specific */
kPORT_MuxAlt10 = 10U, /*!< Chip-specific */
kPORT_MuxAlt11 = 11U, /*!< Chip-specific */
kPORT_MuxAlt12 = 12U, /*!< Chip-specific */
kPORT_MuxAlt13 = 13U, /*!< Chip-specific */
kPORT_MuxAlt14 = 14U, /*!< Chip-specific */
kPORT_MuxAlt15 = 15U, /*!< Chip-specific */
} port_mux_t; } port_mux_t;
#endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */
/*! @brief Configures the interrupt generation condition. */ /*! @brief Configures the interrupt generation condition. */
typedef enum _port_interrupt typedef enum _port_interrupt
@ -129,8 +145,8 @@ typedef enum _port_interrupt
kPORT_InterruptEitherEdge = 0xBU, /*!< Interrupt on either edge. */ kPORT_InterruptEitherEdge = 0xBU, /*!< Interrupt on either edge. */
kPORT_InterruptLogicOne = 0xCU, /*!< Interrupt when logic one. */ kPORT_InterruptLogicOne = 0xCU, /*!< Interrupt when logic one. */
#if defined(FSL_FEATURE_PORT_HAS_IRQC_TRIGGER) && FSL_FEATURE_PORT_HAS_IRQC_TRIGGER #if defined(FSL_FEATURE_PORT_HAS_IRQC_TRIGGER) && FSL_FEATURE_PORT_HAS_IRQC_TRIGGER
kPORT_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high trigger output. */ kPORT_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high-trigger output. */
kPORT_ActiveLowTriggerOutputEnable = 0xEU, /*!< Enable active low trigger output. */ kPORT_ActiveLowTriggerOutputEnable = 0xEU, /*!< Enable active low-trigger output. */
#endif #endif
} port_interrupt_t; } port_interrupt_t;
@ -150,44 +166,76 @@ typedef struct _port_digital_filter_config
} port_digital_filter_config_t; } port_digital_filter_config_t;
#endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */ #endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */
/*! @brief PORT pin config structure */ #if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH
/*! @brief PORT pin configuration structure */
typedef struct _port_pin_config typedef struct _port_pin_config
{ {
uint16_t pullSelect : 2; /*!< no-pull/pull-down/pull-up select */ #if defined(FSL_FEATURE_PORT_HAS_PULL_ENABLE) && FSL_FEATURE_PORT_HAS_PULL_ENABLE
uint16_t slewRate : 1; /*!< fast/slow slew rate Configure */ uint16_t pullSelect : 2; /*!< No-pull/pull-down/pull-up select */
uint16_t : 1; #else
uint16_t passiveFilterEnable : 1; /*!< passive filter enable/disable */ uint16_t : 2;
#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN #endif /* FSL_FEATURE_PORT_HAS_PULL_ENABLE */
uint16_t openDrainEnable : 1; /*!< open drain enable/disable */
#if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE
uint16_t slewRate : 1; /*!< Fast/slow slew rate Configure */
#else #else
uint16_t : 1; uint16_t : 1;
#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */ #endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */
uint16_t driveStrength : 1; /*!< fast/slow drive strength configure */
uint16_t : 1; uint16_t : 1;
uint16_t mux : 3; /*!< pin mux Configure */
#if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER
uint16_t passiveFilterEnable : 1; /*!< Passive filter enable/disable */
#else
uint16_t : 1;
#endif /* FSL_FEATURE_PORT_HAS_PASSIVE_FILTER */
#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 */
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH
uint16_t driveStrength : 1; /*!< Fast/slow drive strength configure */
#else
uint16_t : 1;
#endif
uint16_t : 1;
#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH
uint16_t mux : 3; /*!< Pin mux Configure */
#else
uint16_t : 3;
#endif
uint16_t : 4; uint16_t : 4;
#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK #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] */ uint16_t lockRegister : 1; /*!< Lock/unlock the PCR field[15:0] */
#else #else
uint16_t : 1; uint16_t : 1;
#endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */ #endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */
} port_pin_config_t; } port_pin_config_t;
#endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */
/******************************************************************************* /*******************************************************************************
* API * API
******************************************************************************/ ******************************************************************************/
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH
/*! @name Configuration */ /*! @name Configuration */
/*@{*/ /*@{*/
/*! /*!
* @brief Sets the port PCR register. * @brief Sets the port PCR register.
* *
* This is an example to define an input pin or output pin PCR configuration: * This is an example to define an input pin or output pin PCR configuration.
* @code * @code
* // Define a digital input pin PCR configuration * // Define a digital input pin PCR configuration
* port_pin_config_t config = { * port_pin_config_t config = {
@ -203,7 +251,7 @@ extern "C" {
* *
* @param base PORT peripheral base pointer. * @param base PORT peripheral base pointer.
* @param pin PORT pin number. * @param pin PORT pin number.
* @param config PORT PCR register configure structure. * @param config PORT PCR register configuration structure.
*/ */
static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_pin_config_t *config) static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_pin_config_t *config)
{ {
@ -215,7 +263,7 @@ static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_p
/*! /*!
* @brief Sets the port PCR register for multiple pins. * @brief Sets the port PCR register for multiple pins.
* *
* This is an example to define input pins or output pins PCR configuration: * This is an example to define input pins or output pins PCR configuration.
* @code * @code
* // Define a digital input pin PCR configuration * // Define a digital input pin PCR configuration
* port_pin_config_t config = { * port_pin_config_t config = {
@ -231,8 +279,8 @@ static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_p
* @endcode * @endcode
* *
* @param base PORT peripheral base pointer. * @param base PORT peripheral base pointer.
* @param mask PORT pins' numbers macro. * @param mask PORT pin number macro.
* @param config PORT PCR register configure structure. * @param config PORT PCR register configuration structure.
*/ */
static inline void PORT_SetMultiplePinsConfig(PORT_Type *base, uint32_t mask, const port_pin_config_t *config) static inline void PORT_SetMultiplePinsConfig(PORT_Type *base, uint32_t mask, const port_pin_config_t *config)
{ {
@ -265,15 +313,16 @@ static inline void PORT_SetMultiplePinsConfig(PORT_Type *base, uint32_t mask, co
* - #kPORT_MuxAlt6 : chip-specific. * - #kPORT_MuxAlt6 : chip-specific.
* - #kPORT_MuxAlt7 : chip-specific. * - #kPORT_MuxAlt7 : chip-specific.
* @Note : This function is NOT recommended to use together with the PORT_SetPinsConfig, because * @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 * the PORT_SetPinsConfig need to configure the pin mux anyway (Otherwise the pin mux is
* be reset to zero : kPORT_PinDisabledOrAnalog). * reset to zero : kPORT_PinDisabledOrAnalog).
* This function is recommended to use in the case you just need to reset the pin mux * This function is recommended to use to reset the pin mux
* *
*/ */
static inline void PORT_SetPinMux(PORT_Type *base, uint32_t pin, port_mux_t 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); base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(mux);
} }
#endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */
#if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER #if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER
@ -281,7 +330,7 @@ static inline void PORT_SetPinMux(PORT_Type *base, uint32_t pin, port_mux_t mux)
* @brief Enables the digital filter in one port, each bit of the 32-bit register represents one pin. * @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 base PORT peripheral base pointer.
* @param mask PORT pins' numbers macro. * @param mask PORT pin number macro.
*/ */
static inline void PORT_EnablePinsDigitalFilter(PORT_Type *base, uint32_t mask, bool enable) static inline void PORT_EnablePinsDigitalFilter(PORT_Type *base, uint32_t mask, bool enable)
{ {
@ -334,8 +383,8 @@ static inline void PORT_SetDigitalFilterConfig(PORT_Type *base, const port_digit
* - #kPORT_InterruptFallingEdge: Interrupt on falling edge. * - #kPORT_InterruptFallingEdge: Interrupt on falling edge.
* - #kPORT_InterruptEitherEdge : Interrupt on either edge. * - #kPORT_InterruptEitherEdge : Interrupt on either edge.
* - #kPORT_InterruptLogicOne : Interrupt when logic one. * - #kPORT_InterruptLogicOne : Interrupt when logic one.
* - #kPORT_ActiveHighTriggerOutputEnable : Enable active high trigger output(if the trigger states exit). * - #kPORT_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit).
* - #kPORT_ActiveLowTriggerOutputEnable : Enable active low 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) static inline void PORT_SetPinInterruptConfig(PORT_Type *base, uint32_t pin, port_interrupt_t config)
{ {
@ -351,9 +400,9 @@ static inline void PORT_SetPinInterruptConfig(PORT_Type *base, uint32_t pin, por
* If configured for a level sensitive interrupt that remains asserted, the flag * If configured for a level sensitive interrupt that remains asserted, the flag
* is set again immediately. * is set again immediately.
* *
* @param base PORT peripheral base pointer. * @param base PORT peripheral base pointer.
* @return Current port interrupt status flags, for example, 0x00010001 means the * @return Current port interrupt status flags, for example, 0x00010001 means the
* pin 0 and 17 have the interrupt. * pin 0 and 16 have the interrupt.
*/ */
static inline uint32_t PORT_GetPinsInterruptFlags(PORT_Type *base) static inline uint32_t PORT_GetPinsInterruptFlags(PORT_Type *base)
{ {
@ -361,10 +410,10 @@ static inline uint32_t PORT_GetPinsInterruptFlags(PORT_Type *base)
} }
/*! /*!
* @brief Clears the multiple pins' interrupt status flag. * @brief Clears the multiple pin interrupt status flag.
* *
* @param base PORT peripheral base pointer. * @param base PORT peripheral base pointer.
* @param mask PORT pins' numbers macro. * @param mask PORT pin number macro.
*/ */
static inline void PORT_ClearPinsInterruptFlags(PORT_Type *base, uint32_t mask) static inline void PORT_ClearPinsInterruptFlags(PORT_Type *base, uint32_t mask)
{ {

View File

@ -32,6 +32,8 @@
void RCM_ConfigureResetPinFilter(RCM_Type *base, const rcm_reset_pin_filter_config_t *config) void RCM_ConfigureResetPinFilter(RCM_Type *base, const rcm_reset_pin_filter_config_t *config)
{ {
assert(config);
#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32)) #if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32))
uint32_t reg; uint32_t reg;

View File

@ -35,7 +35,6 @@
/*! @addtogroup rcm */ /*! @addtogroup rcm */
/*! @{*/ /*! @{*/
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -43,8 +42,8 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief RCM driver version 2.0.0. */ /*! @brief RCM driver version 2.0.1. */
#define FSL_RCM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) #define FSL_RCM_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
/*@}*/ /*@}*/
/*! /*!
@ -57,7 +56,7 @@ typedef enum _rcm_reset_source
#if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP) #if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP)
kRCM_SourceWakeup = RCM_SRS_WAKEUP_MASK, /*!< Low-leakage wakeup reset */ kRCM_SourceWakeup = RCM_SRS_WAKEUP_MASK, /*!< Low-leakage wakeup reset */
#endif #endif
kRCM_SourceLvd = RCM_SRS_LVD_MASK, /*!< low voltage detect reset */ kRCM_SourceLvd = RCM_SRS_LVD_MASK, /*!< Low-voltage detect reset */
#if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC) #if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC)
kRCM_SourceLoc = RCM_SRS_LOC_MASK, /*!< Loss of clock reset */ kRCM_SourceLoc = RCM_SRS_LOC_MASK, /*!< Loss of clock reset */
#endif /* FSL_FEATURE_RCM_HAS_LOC */ #endif /* FSL_FEATURE_RCM_HAS_LOC */
@ -85,7 +84,7 @@ typedef enum _rcm_reset_source
#if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP) #if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP)
kRCM_SourceWakeup = RCM_SRS0_WAKEUP_MASK, /*!< Low-leakage wakeup reset */ kRCM_SourceWakeup = RCM_SRS0_WAKEUP_MASK, /*!< Low-leakage wakeup reset */
#endif #endif
kRCM_SourceLvd = RCM_SRS0_LVD_MASK, /*!< low voltage detect reset */ kRCM_SourceLvd = RCM_SRS0_LVD_MASK, /*!< Low-voltage detect reset */
#if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC) #if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC)
kRCM_SourceLoc = RCM_SRS0_LOC_MASK, /*!< Loss of clock reset */ kRCM_SourceLoc = RCM_SRS0_LOC_MASK, /*!< Loss of clock reset */
#endif /* FSL_FEATURE_RCM_HAS_LOC */ #endif /* FSL_FEATURE_RCM_HAS_LOC */
@ -99,7 +98,7 @@ typedef enum _rcm_reset_source
kRCM_SourceJtag = RCM_SRS1_JTAG_MASK << 8U, /*!< JTAG generated reset */ kRCM_SourceJtag = RCM_SRS1_JTAG_MASK << 8U, /*!< JTAG generated reset */
#endif /* FSL_FEATURE_RCM_HAS_JTAG */ #endif /* FSL_FEATURE_RCM_HAS_JTAG */
kRCM_SourceLockup = RCM_SRS1_LOCKUP_MASK << 8U, /*!< Core lock up reset */ kRCM_SourceLockup = RCM_SRS1_LOCKUP_MASK << 8U, /*!< Core lock up reset */
kRCM_SourceSw = RCM_SRS1_SW_MASK, /*!< Software reset */ kRCM_SourceSw = RCM_SRS1_SW_MASK << 8U, /*!< Software reset */
#if (defined(FSL_FEATURE_RCM_HAS_MDM_AP) && FSL_FEATURE_RCM_HAS_MDM_AP) #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 */ kRCM_SourceMdmap = RCM_SRS1_MDM_AP_MASK << 8U, /*!< MDM-AP system reset */
#endif /* FSL_FEATURE_RCM_HAS_MDM_AP */ #endif /* FSL_FEATURE_RCM_HAS_MDM_AP */
@ -112,7 +111,7 @@ typedef enum _rcm_reset_source
} rcm_reset_source_t; } rcm_reset_source_t;
/*! /*!
* @brief Reset pin filter select in Run and Wait modes * @brief Reset pin filter select in Run and Wait modes.
*/ */
typedef enum _rcm_run_wait_filter_mode typedef enum _rcm_run_wait_filter_mode
{ {
@ -136,7 +135,7 @@ typedef enum _rcm_boot_rom_config
#if (defined(FSL_FEATURE_RCM_HAS_SRIE) && FSL_FEATURE_RCM_HAS_SRIE) #if (defined(FSL_FEATURE_RCM_HAS_SRIE) && FSL_FEATURE_RCM_HAS_SRIE)
/*! /*!
* @brief Max delay time from interrupt asserts to system reset. * @brief Maximum delay time from interrupt asserts to system reset.
*/ */
typedef enum _rcm_reset_delay typedef enum _rcm_reset_delay
{ {
@ -187,7 +186,7 @@ typedef struct _rcm_version_id
#endif #endif
/*! /*!
* @brief Reset pin filter configuration * @brief Reset pin filter configuration.
*/ */
typedef struct _rcm_reset_pin_filter_config typedef struct _rcm_reset_pin_filter_config
{ {
@ -214,7 +213,7 @@ extern "C" {
* the minor version number, and the feature specification number. * the minor version number, and the feature specification number.
* *
* @param base RCM peripheral base address. * @param base RCM peripheral base address.
* @param versionId Pointer to version ID structure. * @param versionId Pointer to the version ID structure.
*/ */
static inline void RCM_GetVersionId(RCM_Type *base, rcm_version_id_t *versionId) static inline void RCM_GetVersionId(RCM_Type *base, rcm_version_id_t *versionId)
{ {
@ -229,7 +228,7 @@ static inline void RCM_GetVersionId(RCM_Type *base, rcm_version_id_t *versionId)
* This function gets the RCM parameter that indicates whether the corresponding reset source is implemented. * 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. * Use source masks defined in the rcm_reset_source_t to get the desired source status.
* *
* Example: * This is an example.
@code @code
uint32_t status; uint32_t status;
@ -252,7 +251,7 @@ static inline uint32_t RCM_GetResetSourceImplementedStatus(RCM_Type *base)
* This function gets the current reset source status. Use source masks * This function gets the current reset source status. Use source masks
* defined in the rcm_reset_source_t to get the desired source status. * defined in the rcm_reset_source_t to get the desired source status.
* *
* Example: * This is an example.
@code @code
uint32_t resetStatus; uint32_t resetStatus;
@ -283,9 +282,9 @@ static inline uint32_t RCM_GetPreviousResetSources(RCM_Type *base)
* @brief Gets the sticky reset source status. * @brief Gets the sticky reset source status.
* *
* This function gets the current reset source status that has not been cleared * This function gets the current reset source status that has not been cleared
* by software for some specific source. * by software for a specific source.
* *
* Example: * This is an example.
@code @code
uint32_t resetStatus; uint32_t resetStatus;
@ -316,7 +315,7 @@ static inline uint32_t RCM_GetStickyResetSources(RCM_Type *base)
* *
* This function clears the sticky system reset flags indicated by source masks. * This function clears the sticky system reset flags indicated by source masks.
* *
* Example: * This is an example.
@code @code
// Clears multiple reset sources. // Clears multiple reset sources.
RCM_ClearStickyResetSources(kRCM_SourceWdog | kRCM_SourcePin); RCM_ClearStickyResetSources(kRCM_SourceWdog | kRCM_SourcePin);
@ -403,7 +402,7 @@ void RCM_SetForceBootRomSource(RCM_Type *base, rcm_boot_rom_config_t config);
/*! /*!
* @brief Sets the system reset interrupt configuration. * @brief Sets the system reset interrupt configuration.
* *
* For graceful shutdown, the RCM supports delaying the assertion of the system * For a graceful shut down, the RCM supports delaying the assertion of the system
* reset for a period of time when the reset interrupt is generated. This function * 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 * 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 * are passed in as bit mask. See rcm_int_t for details. For example, to

View File

@ -181,10 +181,14 @@ static uint32_t rnga_ReadEntropy(RNG_Type *base);
void RNGA_Init(RNG_Type *base) void RNGA_Init(RNG_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock gate. */ /* Enable the clock gate. */
CLOCK_EnableClock(kCLOCK_Rnga0); CLOCK_EnableClock(kCLOCK_Rnga0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
CLOCK_DisableClock(kCLOCK_Rnga0); /* To solve the release version on twrkm43z75m */ CLOCK_DisableClock(kCLOCK_Rnga0); /* To solve the release version on twrkm43z75m */
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(kCLOCK_Rnga0); CLOCK_EnableClock(kCLOCK_Rnga0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Reset the registers for RNGA module to reset state. */ /* Reset the registers for RNGA module to reset state. */
RNG_WR_CR(base, 0); RNG_WR_CR(base, 0);
@ -194,8 +198,10 @@ void RNGA_Init(RNG_Type *base)
void RNGA_Deinit(RNG_Type *base) void RNGA_Deinit(RNG_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock for RNGA module.*/ /* Disable the clock for RNGA module.*/
CLOCK_DisableClock(kCLOCK_Rnga0); CLOCK_DisableClock(kCLOCK_Rnga0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
/*! /*!

View File

@ -34,11 +34,10 @@
#if defined(FSL_FEATURE_SOC_RNG_COUNT) && FSL_FEATURE_SOC_RNG_COUNT #if defined(FSL_FEATURE_SOC_RNG_COUNT) && FSL_FEATURE_SOC_RNG_COUNT
/*! /*!
* @addtogroup rnga_driver * @addtogroup rnga
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions

View File

@ -74,6 +74,8 @@ static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datet
******************************************************************************/ ******************************************************************************/
static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime) static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime)
{ {
assert(datetime);
/* Table of days in a month for a non leap year. First entry in the table is not used, /* Table of days in a month for a non leap year. First entry in the table is not used,
* valid months start from 1 * valid months start from 1
*/ */
@ -88,13 +90,13 @@ static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime)
} }
/* Adjust the days in February for a leap year */ /* Adjust the days in February for a leap year */
if (!(datetime->year & 3U)) if ((((datetime->year & 3U) == 0) && (datetime->year % 100 != 0)) || (datetime->year % 400 == 0))
{ {
daysPerMonth[2] = 29U; daysPerMonth[2] = 29U;
} }
/* Check the validity of the day */ /* Check the validity of the day */
if (datetime->day > daysPerMonth[datetime->month]) if ((datetime->day > daysPerMonth[datetime->month]) || (datetime->day < 1U))
{ {
return false; return false;
} }
@ -104,6 +106,9 @@ static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime)
static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime) static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime)
{ {
assert(datetime);
/* Number of days from begin of the non Leap-year*/
/* Number of days from begin of the non Leap-year*/ /* 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}; uint16_t monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U};
uint32_t seconds; uint32_t seconds;
@ -131,6 +136,8 @@ static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime)
static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime) static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime)
{ {
assert(datetime);
uint32_t x; uint32_t x;
uint32_t secondsRemaining, days; uint32_t secondsRemaining, days;
uint16_t daysInYear; uint16_t daysInYear;
@ -204,7 +211,9 @@ void RTC_Init(RTC_Type *base, const rtc_config_t *config)
uint32_t reg; uint32_t reg;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(kCLOCK_Rtc0); CLOCK_EnableClock(kCLOCK_Rtc0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Issue a software reset if timer is invalid */ /* Issue a software reset if timer is invalid */
if (RTC_GetStatusFlags(RTC) & kRTC_TimeInvalidFlag) if (RTC_GetStatusFlags(RTC) & kRTC_TimeInvalidFlag)
@ -216,7 +225,7 @@ void RTC_Init(RTC_Type *base, const rtc_config_t *config)
/* Setup the update mode and supervisor access mode */ /* Setup the update mode and supervisor access mode */
reg &= ~(RTC_CR_UM_MASK | RTC_CR_SUP_MASK); reg &= ~(RTC_CR_UM_MASK | RTC_CR_SUP_MASK);
reg |= RTC_CR_UM(config->updateMode) | RTC_CR_SUP(config->supervisorAccess); 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 #if defined(FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION) && FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION
/* Setup the wakeup pin select */ /* Setup the wakeup pin select */
reg &= ~(RTC_CR_WPS_MASK); reg &= ~(RTC_CR_WPS_MASK);
reg |= RTC_CR_WPS(config->wakeupSelect); reg |= RTC_CR_WPS(config->wakeupSelect);
@ -340,6 +349,8 @@ void RTC_ClearStatusFlags(RTC_Type *base, uint32_t mask)
void RTC_GetMonotonicCounter(RTC_Type *base, uint64_t *counter) void RTC_GetMonotonicCounter(RTC_Type *base, uint64_t *counter)
{ {
assert(counter);
*counter = (((uint64_t)base->MCHR << 32) | ((uint64_t)base->MCLR)); *counter = (((uint64_t)base->MCHR << 32) | ((uint64_t)base->MCLR));
} }

View File

@ -33,11 +33,10 @@
#include "fsl_common.h" #include "fsl_common.h"
/*! /*!
* @addtogroup rtc_driver * @addtogroup rtc
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -65,15 +64,19 @@ typedef enum _rtc_status_flags
kRTC_AlarmFlag = RTC_SR_TAF_MASK /*!< Alarm flag*/ kRTC_AlarmFlag = RTC_SR_TAF_MASK /*!< Alarm flag*/
} rtc_status_flags_t; } rtc_status_flags_t;
#if (defined(FSL_FEATURE_RTC_HAS_OSC_SCXP) && FSL_FEATURE_RTC_HAS_OSC_SCXP)
/*! @brief List of RTC Oscillator capacitor load settings */ /*! @brief List of RTC Oscillator capacitor load settings */
typedef enum _rtc_osc_cap_load typedef enum _rtc_osc_cap_load
{ {
kRTC_Capacitor_2p = RTC_CR_SC2P_MASK, /*!< 2pF capacitor load */ kRTC_Capacitor_2p = RTC_CR_SC2P_MASK, /*!< 2 pF capacitor load */
kRTC_Capacitor_4p = RTC_CR_SC4P_MASK, /*!< 4pF capacitor load */ kRTC_Capacitor_4p = RTC_CR_SC4P_MASK, /*!< 4 pF capacitor load */
kRTC_Capacitor_8p = RTC_CR_SC8P_MASK, /*!< 8pF capacitor load */ kRTC_Capacitor_8p = RTC_CR_SC8P_MASK, /*!< 8 pF capacitor load */
kRTC_Capacitor_16p = RTC_CR_SC16P_MASK /*!< 16pF capacitor load */ kRTC_Capacitor_16p = RTC_CR_SC16P_MASK /*!< 16 pF capacitor load */
} rtc_osc_cap_load_t; } rtc_osc_cap_load_t;
#endif /* FSL_FEATURE_SCG_HAS_OSC_SCXP */
/*! @brief Structure is used to hold the date and time */ /*! @brief Structure is used to hold the date and time */
typedef struct _rtc_datetime typedef struct _rtc_datetime
{ {
@ -96,7 +99,7 @@ typedef struct _rtc_datetime
*/ */
typedef struct _rtc_config typedef struct _rtc_config
{ {
bool wakeupSelect; /*!< true: Wakeup pin outputs the 32KHz clock; bool wakeupSelect; /*!< true: Wakeup pin outputs the 32 KHz clock;
false:Wakeup pin used to wakeup the chip */ false:Wakeup pin used to wakeup the chip */
bool updateMode; /*!< true: Registers can be written even when locked under certain bool updateMode; /*!< true: Registers can be written even when locked under certain
conditions, false: No writes allowed when registers are locked */ conditions, false: No writes allowed when registers are locked */
@ -122,17 +125,17 @@ extern "C" {
/*! /*!
* @brief Ungates the RTC clock and configures the peripheral for basic operation. * @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. * This function issues 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. * @note This API should be called at the beginning of the application using the RTC driver.
* *
* @param base RTC peripheral base address * @param base RTC peripheral base address
* @param config Pointer to user's RTC config structure. * @param config Pointer to the user's RTC configuration structure.
*/ */
void RTC_Init(RTC_Type *base, const rtc_config_t *config); void RTC_Init(RTC_Type *base, const rtc_config_t *config);
/*! /*!
* @brief Stop the timer and gate the RTC clock * @brief Stops the timer and gate the RTC clock.
* *
* @param base RTC peripheral base address * @param base RTC peripheral base address
*/ */
@ -141,14 +144,16 @@ static inline void RTC_Deinit(RTC_Type *base)
/* Stop the RTC timer */ /* Stop the RTC timer */
base->SR &= ~RTC_SR_TCE_MASK; base->SR &= ~RTC_SR_TCE_MASK;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate the module clock */ /* Gate the module clock */
CLOCK_DisableClock(kCLOCK_Rtc0); CLOCK_DisableClock(kCLOCK_Rtc0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
/*! /*!
* @brief Fill in the RTC config struct with the default settings * @brief Fills in the RTC config struct with the default settings.
* *
* The default values are: * The default values are as follows.
* @code * @code
* config->wakeupSelect = false; * config->wakeupSelect = false;
* config->updateMode = false; * config->updateMode = false;
@ -156,7 +161,7 @@ static inline void RTC_Deinit(RTC_Type *base)
* config->compensationInterval = 0; * config->compensationInterval = 0;
* config->compensationTime = 0; * config->compensationTime = 0;
* @endcode * @endcode
* @param config Pointer to user's RTC config structure. * @param config Pointer to the user's RTC configuration structure.
*/ */
void RTC_GetDefaultConfig(rtc_config_t *config); void RTC_GetDefaultConfig(rtc_config_t *config);
@ -170,11 +175,11 @@ void RTC_GetDefaultConfig(rtc_config_t *config);
/*! /*!
* @brief Sets the RTC date and time according to the given time structure. * @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 * The RTC counter must be stopped prior to calling this function because writes to the RTC
* seconds register will fail if the RTC counter is running. * seconds register fail if the RTC counter is running.
* *
* @param base RTC peripheral base address * @param base RTC peripheral base address
* @param datetime Pointer to structure where the date and time details to set are stored * @param datetime Pointer to the structure where the date and time details are stored.
* *
* @return kStatus_Success: Success in setting the time and starting the RTC * @return kStatus_Success: Success in setting the time and starting the RTC
* kStatus_InvalidArgument: Error because the datetime format is incorrect * kStatus_InvalidArgument: Error because the datetime format is incorrect
@ -185,18 +190,18 @@ 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. * @brief Gets the RTC time and stores it in the given time structure.
* *
* @param base RTC peripheral base address * @param base RTC peripheral base address
* @param datetime Pointer to structure where the date and time details are stored. * @param datetime Pointer to the structure where the date and time details are stored.
*/ */
void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime); void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime);
/*! /*!
* @brief Sets the RTC alarm time * @brief Sets the RTC alarm time.
* *
* The function checks whether the specified alarm time is greater than the present * 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. * time. If not, the function does not set the alarm and returns an error.
* *
* @param base RTC peripheral base address * @param base RTC peripheral base address
* @param alarmTime Pointer to structure where the alarm time is stored. * @param alarmTime Pointer to the structure where the alarm time is stored.
* *
* @return kStatus_Success: success in setting the RTC alarm * @return kStatus_Success: success in setting the RTC alarm
* kStatus_InvalidArgument: Error because the alarm datetime format is incorrect * kStatus_InvalidArgument: Error because the alarm datetime format is incorrect
@ -208,7 +213,7 @@ status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime);
* @brief Returns the RTC alarm time. * @brief Returns the RTC alarm time.
* *
* @param base RTC peripheral base address * @param base RTC peripheral base address
* @param datetime Pointer to structure where the alarm date and time details are stored. * @param datetime Pointer to the structure where the alarm date and time details are stored.
*/ */
void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime); void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime);
@ -264,7 +269,7 @@ static inline uint32_t RTC_GetEnabledInterrupts(RTC_Type *base)
*/ */
/*! /*!
* @brief Gets the RTC status flags * @brief Gets the RTC status flags.
* *
* @param base RTC peripheral base address * @param base RTC peripheral base address
* *
@ -319,6 +324,8 @@ static inline void RTC_StopTimer(RTC_Type *base)
/*! @}*/ /*! @}*/
#if (defined(FSL_FEATURE_RTC_HAS_OSC_SCXP) && FSL_FEATURE_RTC_HAS_OSC_SCXP)
/*! /*!
* @brief This function sets the specified capacitor configuration for the RTC oscillator. * @brief This function sets the specified capacitor configuration for the RTC oscillator.
* *
@ -336,6 +343,8 @@ static inline void RTC_SetOscCapLoad(RTC_Type *base, uint32_t capLoad)
base->CR = reg; base->CR = reg;
} }
#endif /* FSL_FEATURE_SCG_HAS_OSC_SCXP */
/*! /*!
* @brief Performs a software reset on the RTC module. * @brief Performs a software reset on the RTC module.
* *

View File

@ -102,8 +102,10 @@ static I2S_Type *const s_saiBases[] = I2S_BASE_PTRS;
/* IRQ number array */ /* IRQ number array */
static const IRQn_Type s_saiTxIRQ[] = I2S_TX_IRQS; static const IRQn_Type s_saiTxIRQ[] = I2S_TX_IRQS;
static const IRQn_Type s_saiRxIRQ[] = I2S_RX_IRQS; static const IRQn_Type s_saiRxIRQ[] = I2S_RX_IRQS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Clock name array */ /* Clock name array */
static const clock_ip_name_t s_saiClock[] = SAI_CLOCKS; static const clock_ip_name_t s_saiClock[] = SAI_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*! @brief Pointer to tx IRQ handler for each instance. */ /*! @brief Pointer to tx IRQ handler for each instance. */
static sai_tx_isr_t s_saiTxIsr; static sai_tx_isr_t s_saiTxIsr;
/*! @brief Pointer to tx IRQ handler for each instance. */ /*! @brief Pointer to tx IRQ handler for each instance. */
@ -237,8 +239,10 @@ void SAI_TxInit(I2S_Type *base, const sai_config_t *config)
{ {
uint32_t val = 0; uint32_t val = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the SAI clock */ /* Enable the SAI clock */
CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]); CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
/* Master clock source setting */ /* Master clock source setting */
@ -339,8 +343,10 @@ void SAI_RxInit(I2S_Type *base, const sai_config_t *config)
{ {
uint32_t val = 0; uint32_t val = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable SAI clock first. */ /* Enable SAI clock first. */
CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]); CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
/* Master clock source setting */ /* Master clock source setting */
@ -441,7 +447,9 @@ void SAI_Deinit(I2S_Type *base)
{ {
SAI_TxEnable(base, false); SAI_TxEnable(base, false);
SAI_RxEnable(base, false); SAI_RxEnable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_DisableClock(s_saiClock[SAI_GetInstance(base)]); CLOCK_DisableClock(s_saiClock[SAI_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void SAI_TxGetDefaultConfig(sai_config_t *config) void SAI_TxGetDefaultConfig(sai_config_t *config)

View File

@ -186,16 +186,16 @@ typedef struct _sai_config
/*! @brief Audio sample rate */ /*! @brief Audio sample rate */
typedef enum _sai_sample_rate typedef enum _sai_sample_rate
{ {
kSAI_SampleRate8KHz = 8000U, /*!< Sample rate 8000Hz */ kSAI_SampleRate8KHz = 8000U, /*!< Sample rate 8000 Hz */
kSAI_SampleRate11025Hz = 11025U, /*!< Sample rate 11025Hz */ kSAI_SampleRate11025Hz = 11025U, /*!< Sample rate 11025 Hz */
kSAI_SampleRate12KHz = 12000U, /*!< Sample rate 12000Hz */ kSAI_SampleRate12KHz = 12000U, /*!< Sample rate 12000 Hz */
kSAI_SampleRate16KHz = 16000U, /*!< Sample rate 16000Hz */ kSAI_SampleRate16KHz = 16000U, /*!< Sample rate 16000 Hz */
kSAI_SampleRate22050Hz = 22050U, /*!< Sample rate 22050Hz */ kSAI_SampleRate22050Hz = 22050U, /*!< Sample rate 22050 Hz */
kSAI_SampleRate24KHz = 24000U, /*!< Sample rate 24000Hz */ kSAI_SampleRate24KHz = 24000U, /*!< Sample rate 24000 Hz */
kSAI_SampleRate32KHz = 32000U, /*!< Sample rate 32000Hz */ kSAI_SampleRate32KHz = 32000U, /*!< Sample rate 32000 Hz */
kSAI_SampleRate44100Hz = 44100U, /*!< Sample rate 44100Hz */ kSAI_SampleRate44100Hz = 44100U, /*!< Sample rate 44100 Hz */
kSAI_SampleRate48KHz = 48000U, /*!< Sample rate 48000Hz */ kSAI_SampleRate48KHz = 48000U, /*!< Sample rate 48000 Hz */
kSAI_SampleRate96KHz = 96000U /*!< Sample rate 96000Hz */ kSAI_SampleRate96KHz = 96000U /*!< Sample rate 96000 Hz */
} sai_sample_rate_t; } sai_sample_rate_t;
/*! @brief Audio word width */ /*! @brief Audio word width */
@ -211,7 +211,7 @@ typedef enum _sai_word_width
typedef struct _sai_transfer_format typedef struct _sai_transfer_format
{ {
uint32_t sampleRate_Hz; /*!< Sample rate of audio data */ uint32_t sampleRate_Hz; /*!< Sample rate of audio data */
uint32_t bitWidth; /*!< Data length of audio data, usually 8/16/24/32bits */ uint32_t bitWidth; /*!< Data length of audio data, usually 8/16/24/32 bits */
sai_mono_stereo_t stereo; /*!< Mono or stereo */ sai_mono_stereo_t stereo; /*!< Mono or stereo */
uint32_t masterClockHz; /*!< Master clock frequency in Hz */ uint32_t masterClockHz; /*!< Master clock frequency in Hz */
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
@ -239,7 +239,7 @@ struct _sai_handle
uint32_t state; /*!< Transfer status */ uint32_t state; /*!< Transfer status */
sai_transfer_callback_t callback; /*!< Callback function called at transfer event*/ sai_transfer_callback_t callback; /*!< Callback function called at transfer event*/
void *userData; /*!< Callback parameter passed to callback function*/ void *userData; /*!< Callback parameter passed to callback function*/
uint8_t bitWidth; /*!< Bit width for transfer, 8/16/24/32bits */ uint8_t bitWidth; /*!< Bit width for transfer, 8/16/24/32 bits */
uint8_t channel; /*!< Transfer channel */ uint8_t channel; /*!< Transfer channel */
sai_transfer_t saiQueue[SAI_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer */ 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 */ size_t transferSize[SAI_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */
@ -301,7 +301,7 @@ void SAI_RxInit(I2S_Type *base, const sai_config_t *config);
* This API initializes the configuration structure for use in SAI_TxConfig(). * 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 * The initialized structure can remain unchanged in SAI_TxConfig(), or it can be modified
* before calling SAI_TxConfig(). * before calling SAI_TxConfig().
* Example: * This is an example.
@code @code
sai_config_t config; sai_config_t config;
SAI_TxGetDefaultConfig(&config); SAI_TxGetDefaultConfig(&config);
@ -317,7 +317,7 @@ void SAI_TxGetDefaultConfig(sai_config_t *config);
* This API initializes the configuration structure for use in SAI_RxConfig(). * 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 * The initialized structure can remain unchanged in SAI_RxConfig() or it can be modified
* before calling SAI_RxConfig(). * before calling SAI_RxConfig().
* Example: * This is an example.
@code @code
sai_config_t config; sai_config_t config;
SAI_RxGetDefaultConfig(&config); SAI_RxGetDefaultConfig(&config);
@ -356,7 +356,7 @@ void SAI_TxReset(I2S_Type *base);
void SAI_RxReset(I2S_Type *base); void SAI_RxReset(I2S_Type *base);
/*! /*!
* @brief Enables/disables SAI Tx. * @brief Enables/disables the SAI Tx.
* *
* @param base SAI base pointer * @param base SAI base pointer
* @param enable True means enable SAI Tx, false means disable. * @param enable True means enable SAI Tx, false means disable.
@ -364,7 +364,7 @@ void SAI_RxReset(I2S_Type *base);
void SAI_TxEnable(I2S_Type *base, bool enable); void SAI_TxEnable(I2S_Type *base, bool enable);
/*! /*!
* @brief Enables/disables SAI Rx. * @brief Enables/disables the SAI Rx.
* *
* @param base SAI base pointer * @param base SAI base pointer
* @param enable True means enable SAI Rx, false means disable. * @param enable True means enable SAI Rx, false means disable.
@ -418,7 +418,7 @@ static inline uint32_t SAI_RxGetStatusFlag(I2S_Type *base)
* @brief Clears the SAI Rx status flag state. * @brief Clears the SAI Rx status flag state.
* *
* @param base SAI base pointer * @param base SAI base pointer
* @param mask State mask. It can be a combination of the following source if defined: * @param mask State mask. It can be a combination of the following sources if defined.
* @arg kSAI_WordStartFlag * @arg kSAI_WordStartFlag
* @arg kSAI_SyncErrorFlag * @arg kSAI_SyncErrorFlag
* @arg kSAI_FIFOErrorFlag * @arg kSAI_FIFOErrorFlag
@ -436,11 +436,11 @@ static inline void SAI_RxClearStatusFlags(I2S_Type *base, uint32_t mask)
*/ */
/*! /*!
* @brief Enables SAI Tx interrupt requests. * @brief Enables the SAI Tx interrupt requests.
* *
* @param base SAI base pointer * @param base SAI base pointer
* @param mask interrupt source * @param mask interrupt source
* The parameter can be a combination of the following source if defined: * The parameter can be a combination of the following sources if defined.
* @arg kSAI_WordStartInterruptEnable * @arg kSAI_WordStartInterruptEnable
* @arg kSAI_SyncErrorInterruptEnable * @arg kSAI_SyncErrorInterruptEnable
* @arg kSAI_FIFOWarningInterruptEnable * @arg kSAI_FIFOWarningInterruptEnable
@ -453,11 +453,11 @@ static inline void SAI_TxEnableInterrupts(I2S_Type *base, uint32_t mask)
} }
/*! /*!
* @brief Enables SAI Rx interrupt requests. * @brief Enables the SAI Rx interrupt requests.
* *
* @param base SAI base pointer * @param base SAI base pointer
* @param mask interrupt source * @param mask interrupt source
* The parameter can be a combination of the following source if defined: * The parameter can be a combination of the following sources if defined.
* @arg kSAI_WordStartInterruptEnable * @arg kSAI_WordStartInterruptEnable
* @arg kSAI_SyncErrorInterruptEnable * @arg kSAI_SyncErrorInterruptEnable
* @arg kSAI_FIFOWarningInterruptEnable * @arg kSAI_FIFOWarningInterruptEnable
@ -470,11 +470,11 @@ static inline void SAI_RxEnableInterrupts(I2S_Type *base, uint32_t mask)
} }
/*! /*!
* @brief Disables SAI Tx interrupt requests. * @brief Disables the SAI Tx interrupt requests.
* *
* @param base SAI base pointer * @param base SAI base pointer
* @param mask interrupt source * @param mask interrupt source
* The parameter can be a combination of the following source if defined: * The parameter can be a combination of the following sources if defined.
* @arg kSAI_WordStartInterruptEnable * @arg kSAI_WordStartInterruptEnable
* @arg kSAI_SyncErrorInterruptEnable * @arg kSAI_SyncErrorInterruptEnable
* @arg kSAI_FIFOWarningInterruptEnable * @arg kSAI_FIFOWarningInterruptEnable
@ -487,11 +487,11 @@ static inline void SAI_TxDisableInterrupts(I2S_Type *base, uint32_t mask)
} }
/*! /*!
* @brief Disables SAI Rx interrupt requests. * @brief Disables the SAI Rx interrupt requests.
* *
* @param base SAI base pointer * @param base SAI base pointer
* @param mask interrupt source * @param mask interrupt source
* The parameter can be a combination of the following source if defined: * The parameter can be a combination of the following sources if defined.
* @arg kSAI_WordStartInterruptEnable * @arg kSAI_WordStartInterruptEnable
* @arg kSAI_SyncErrorInterruptEnable * @arg kSAI_SyncErrorInterruptEnable
* @arg kSAI_FIFOWarningInterruptEnable * @arg kSAI_FIFOWarningInterruptEnable
@ -511,10 +511,10 @@ static inline void SAI_RxDisableInterrupts(I2S_Type *base, uint32_t mask)
*/ */
/*! /*!
* @brief Enables/disables SAI Tx DMA requests. * @brief Enables/disables the SAI Tx DMA requests.
* @param base SAI base pointer * @param base SAI base pointer
* @param mask DMA source * @param mask DMA source
* The parameter can be combination of the following source if defined: * The parameter can be combination of the following sources if defined.
* @arg kSAI_FIFOWarningDMAEnable * @arg kSAI_FIFOWarningDMAEnable
* @arg kSAI_FIFORequestDMAEnable * @arg kSAI_FIFORequestDMAEnable
* @param enable True means enable DMA, false means disable DMA. * @param enable True means enable DMA, false means disable DMA.
@ -532,10 +532,10 @@ static inline void SAI_TxEnableDMA(I2S_Type *base, uint32_t mask, bool enable)
} }
/*! /*!
* @brief Enables/disables SAI Rx DMA requests. * @brief Enables/disables the SAI Rx DMA requests.
* @param base SAI base pointer * @param base SAI base pointer
* @param mask DMA source * @param mask DMA source
* The parameter can be a combination of the following source if defined: * The parameter can be a combination of the following sources if defined.
* @arg kSAI_FIFOWarningDMAEnable * @arg kSAI_FIFOWarningDMAEnable
* @arg kSAI_FIFORequestDMAEnable * @arg kSAI_FIFORequestDMAEnable
* @param enable True means enable DMA, false means disable DMA. * @param enable True means enable DMA, false means disable DMA.
@ -555,7 +555,7 @@ static inline void SAI_RxEnableDMA(I2S_Type *base, uint32_t mask, bool enable)
/*! /*!
* @brief Gets the SAI Tx data register address. * @brief Gets the SAI Tx data register address.
* *
* This API is used to provide a transfer address for SAI DMA transfer configuration. * This API is used to provide a transfer address for the SAI DMA transfer configuration.
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param channel Which data channel used. * @param channel Which data channel used.
@ -569,7 +569,7 @@ static inline uint32_t SAI_TxGetDataRegisterAddress(I2S_Type *base, uint32_t cha
/*! /*!
* @brief Gets the SAI Rx data register address. * @brief Gets the SAI Rx data register address.
* *
* This API is used to provide a transfer address for SAI DMA transfer configuration. * This API is used to provide a transfer address for the SAI DMA transfer configuration.
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param channel Which data channel used. * @param channel Which data channel used.
@ -594,10 +594,10 @@ static inline uint32_t SAI_RxGetDataRegisterAddress(I2S_Type *base, uint32_t cha
* format to be transferred. * format to be transferred.
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param format Pointer to SAI audio data format structure. * @param format Pointer to the SAI audio data format structure.
* @param mclkSourceClockHz SAI master clock source frequency in Hz. * @param mclkSourceClockHz SAI master clock source frequency in Hz.
* @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If the bit clock source is a master
* clock, this value should equals to masterClockHz in format. * clock, this value should equal the masterClockHz.
*/ */
void SAI_TxSetFormat(I2S_Type *base, void SAI_TxSetFormat(I2S_Type *base,
sai_transfer_format_t *format, sai_transfer_format_t *format,
@ -611,10 +611,10 @@ void SAI_TxSetFormat(I2S_Type *base,
* format to be transferred. * format to be transferred.
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param format Pointer to SAI audio data format structure. * @param format Pointer to the SAI audio data format structure.
* @param mclkSourceClockHz SAI master clock source frequency in Hz. * @param mclkSourceClockHz SAI master clock source frequency in Hz.
* @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If the bit clock source is a master
* clock, this value should equals to masterClockHz in format. * clock, this value should equal the masterClockHz.
*/ */
void SAI_RxSetFormat(I2S_Type *base, void SAI_RxSetFormat(I2S_Type *base,
sai_transfer_format_t *format, sai_transfer_format_t *format,
@ -628,7 +628,7 @@ void SAI_RxSetFormat(I2S_Type *base,
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param channel Data channel used. * @param channel Data channel used.
* @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. * @param bitWidth How many bits in an audio word; usually 8/16/24/32 bits.
* @param buffer Pointer to the data to be written. * @param buffer Pointer to the data to be written.
* @param size Bytes to be written. * @param size Bytes to be written.
*/ */
@ -653,14 +653,14 @@ static inline void SAI_WriteData(I2S_Type *base, uint32_t channel, uint32_t data
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param channel Data channel used. * @param channel Data channel used.
* @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. * @param bitWidth How many bits in an audio word; usually 8/16/24/32 bits.
* @param buffer Pointer to the data to be read. * @param buffer Pointer to the data to be read.
* @param size Bytes 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); void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size);
/*! /*!
* @brief Reads data from SAI FIFO. * @brief Reads data from the SAI FIFO.
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param channel Data channel used. * @param channel Data channel used.
@ -681,26 +681,26 @@ static inline uint32_t SAI_ReadData(I2S_Type *base, uint32_t channel)
/*! /*!
* @brief Initializes the SAI Tx handle. * @brief Initializes the SAI Tx handle.
* *
* This function initializes the Tx handle for SAI Tx transactional APIs. Call * This function initializes the Tx handle for the SAI Tx transactional APIs. Call
* this function one time to get the handle initialized. * this function once to get the handle initialized.
* *
* @param base SAI base pointer * @param base SAI base pointer
* @param handle SAI handle pointer. * @param handle SAI handle pointer.
* @param callback pointer to user callback function * @param callback Pointer to the user callback function.
* @param userData user parameter passed to the 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); void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData);
/*! /*!
* @brief Initializes the SAI Rx handle. * @brief Initializes the SAI Rx handle.
* *
* This function initializes the Rx handle for SAI Rx transactional APIs. Call * This function initializes the Rx handle for the SAI Rx transactional APIs. Call
* this function one time to get the handle initialized. * this function once to get the handle initialized.
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param handle SAI handle pointer. * @param handle SAI handle pointer.
* @param callback pointer to user callback function * @param callback Pointer to the user callback function.
* @param userData user parameter passed to the 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); void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData);
@ -712,11 +712,11 @@ void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transf
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param handle SAI handle pointer. * @param handle SAI handle pointer.
* @param format Pointer to SAI audio data format structure. * @param format Pointer to the SAI audio data format structure.
* @param mclkSourceClockHz SAI master clock source frequency in Hz. * @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 * @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. * clock, this value should equal the masterClockHz in format.
* @return Status of this function. Return value is one of status_t. * @return Status of this function. Return value is the status_t.
*/ */
status_t SAI_TransferTxSetFormat(I2S_Type *base, status_t SAI_TransferTxSetFormat(I2S_Type *base,
sai_handle_t *handle, sai_handle_t *handle,
@ -732,10 +732,10 @@ status_t SAI_TransferTxSetFormat(I2S_Type *base,
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param handle SAI handle pointer. * @param handle SAI handle pointer.
* @param format Pointer to SAI audio data format structure. * @param format Pointer to the SAI audio data format structure.
* @param mclkSourceClockHz SAI master clock source frequency in Hz. * @param mclkSourceClockHz SAI master clock source frequency in Hz.
* @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is a master
* clock, this value should equals to masterClockHz in format. * clock, this value should equal the masterClockHz in format.
* @return Status of this function. Return value is one of status_t. * @return Status of this function. Return value is one of status_t.
*/ */
status_t SAI_TransferRxSetFormat(I2S_Type *base, status_t SAI_TransferRxSetFormat(I2S_Type *base,
@ -752,9 +752,9 @@ status_t SAI_TransferRxSetFormat(I2S_Type *base,
* the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer * the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer
* is finished. * is finished.
* *
* @param base SAI base pointer * @param base SAI base pointer.
* @param handle pointer to sai_handle_t structure which stores the transfer state * @param handle Pointer to the sai_handle_t structure which stores the transfer state.
* @param xfer pointer to sai_transfer_t structure * @param xfer Pointer to the sai_transfer_t structure.
* @retval kStatus_Success Successfully started the data receive. * @retval kStatus_Success Successfully started the data receive.
* @retval kStatus_SAI_TxBusy Previous receive still not finished. * @retval kStatus_SAI_TxBusy Previous receive still not finished.
* @retval kStatus_InvalidArgument The input parameter is invalid. * @retval kStatus_InvalidArgument The input parameter is invalid.
@ -770,8 +770,8 @@ status_t SAI_TransferSendNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_t
* is finished. * is finished.
* *
* @param base SAI base pointer * @param base SAI base pointer
* @param handle pointer to sai_handle_t structure which stores the transfer state * @param handle Pointer to the sai_handle_t structure which stores the transfer state.
* @param xfer pointer to sai_transfer_t structure * @param xfer Pointer to the sai_transfer_t structure.
* @retval kStatus_Success Successfully started the data receive. * @retval kStatus_Success Successfully started the data receive.
* @retval kStatus_SAI_RxBusy Previous receive still not finished. * @retval kStatus_SAI_RxBusy Previous receive still not finished.
* @retval kStatus_InvalidArgument The input parameter is invalid. * @retval kStatus_InvalidArgument The input parameter is invalid.
@ -782,7 +782,7 @@ status_t SAI_TransferReceiveNonBlocking(I2S_Type *base, sai_handle_t *handle, sa
* @brief Gets a set byte count. * @brief Gets a set byte count.
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param handle pointer to sai_handle_t structure which stores the transfer state. * @param handle Pointer to the sai_handle_t structure which stores the transfer state.
* @param count Bytes count sent. * @param count Bytes count sent.
* @retval kStatus_Success Succeed get the transfer count. * @retval kStatus_Success Succeed get the transfer count.
* @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
@ -793,7 +793,7 @@ status_t SAI_TransferGetSendCount(I2S_Type *base, sai_handle_t *handle, size_t *
* @brief Gets a received byte count. * @brief Gets a received byte count.
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param handle pointer to sai_handle_t structure which stores the transfer state. * @param handle Pointer to the sai_handle_t structure which stores the transfer state.
* @param count Bytes count received. * @param count Bytes count received.
* @retval kStatus_Success Succeed get the transfer count. * @retval kStatus_Success Succeed get the transfer count.
* @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
@ -807,18 +807,18 @@ status_t SAI_TransferGetReceiveCount(I2S_Type *base, sai_handle_t *handle, size_
* to abort the transfer early. * to abort the transfer early.
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param handle pointer to sai_handle_t structure which stores the transfer state. * @param handle Pointer to the sai_handle_t structure which stores the transfer state.
*/ */
void SAI_TransferAbortSend(I2S_Type *base, sai_handle_t *handle); void SAI_TransferAbortSend(I2S_Type *base, sai_handle_t *handle);
/*! /*!
* @brief Aborts the the current IRQ receive. * @brief Aborts the the current IRQ receive.
* *
* @note This API can be called any time when an interrupt non-blocking transfer initiates * @note This API can be called when an interrupt non-blocking transfer initiates
* to abort the transfer early. * to abort the transfer early.
* *
* @param base SAI base pointer * @param base SAI base pointer
* @param handle pointer to sai_handle_t structure which stores the transfer state. * @param handle Pointer to the sai_handle_t structure which stores the transfer state.
*/ */
void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle); void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle);
@ -826,7 +826,7 @@ void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle);
* @brief Tx interrupt handler. * @brief Tx interrupt handler.
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param handle pointer to sai_handle_t structure. * @param handle Pointer to the sai_handle_t structure.
*/ */
void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle); void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle);
@ -834,7 +834,7 @@ void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle);
* @brief Tx interrupt handler. * @brief Tx interrupt handler.
* *
* @param base SAI base pointer. * @param base SAI base pointer.
* @param handle pointer to sai_handle_t structure. * @param handle Pointer to the sai_handle_t structure.
*/ */
void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle); void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle);

View File

@ -253,6 +253,9 @@ status_t SAI_TransferSendEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_tra
EDMA_PrepareTransfer(&config, xfer->data, handle->bytesPerFrame, (void *)destAddr, handle->bytesPerFrame, EDMA_PrepareTransfer(&config, xfer->data, handle->bytesPerFrame, (void *)destAddr, handle->bytesPerFrame,
handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_MemoryToPeripheral); handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_MemoryToPeripheral);
/* Store the initially configured eDMA minor byte transfer count into the SAI handle */
handle->nbytes = handle->count * handle->bytesPerFrame;
EDMA_SubmitTransfer(handle->dmaHandle, &config); EDMA_SubmitTransfer(handle->dmaHandle, &config);
/* Start DMA transfer */ /* Start DMA transfer */
@ -298,6 +301,9 @@ status_t SAI_TransferReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_
EDMA_PrepareTransfer(&config, (void *)srcAddr, handle->bytesPerFrame, xfer->data, handle->bytesPerFrame, EDMA_PrepareTransfer(&config, (void *)srcAddr, handle->bytesPerFrame, xfer->data, handle->bytesPerFrame,
handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_PeripheralToMemory); handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_PeripheralToMemory);
/* Store the initially configured eDMA minor byte transfer count into the SAI handle */
handle->nbytes = handle->count * handle->bytesPerFrame;
EDMA_SubmitTransfer(handle->dmaHandle, &config); EDMA_SubmitTransfer(handle->dmaHandle, &config);
/* Start DMA transfer */ /* Start DMA transfer */
@ -322,6 +328,9 @@ void SAI_TransferAbortSendEDMA(I2S_Type *base, sai_edma_handle_t *handle)
/* Disable DMA enable bit */ /* Disable DMA enable bit */
SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, false); SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, false);
/* Disable Tx */
SAI_TxEnable(base, false);
/* Set the handle state */ /* Set the handle state */
handle->state = kSAI_Idle; handle->state = kSAI_Idle;
} }
@ -335,6 +344,9 @@ void SAI_TransferAbortReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle)
/* Disable DMA enable bit */ /* Disable DMA enable bit */
SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, false); SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, false);
/* Disable Rx */
SAI_RxEnable(base, false);
/* Set the handle state */ /* Set the handle state */
handle->state = kSAI_Idle; handle->state = kSAI_Idle;
@ -353,7 +365,8 @@ status_t SAI_TransferGetSendCountEDMA(I2S_Type *base, sai_edma_handle_t *handle,
else else
{ {
*count = (handle->transferSize[handle->queueDriver] - *count = (handle->transferSize[handle->queueDriver] -
EDMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel)); (uint32_t)handle->nbytes *
EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel));
} }
return status; return status;
@ -372,7 +385,8 @@ status_t SAI_TransferGetReceiveCountEDMA(I2S_Type *base, sai_edma_handle_t *hand
else else
{ {
*count = (handle->transferSize[handle->queueDriver] - *count = (handle->transferSize[handle->queueDriver] -
EDMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel)); (uint32_t)handle->nbytes *
EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel));
} }
return status; return status;

View File

@ -38,8 +38,6 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
@ -53,6 +51,7 @@ typedef void (*sai_edma_callback_t)(I2S_Type *base, sai_edma_handle_t *handle, s
struct _sai_edma_handle struct _sai_edma_handle
{ {
edma_handle_t *dmaHandle; /*!< DMA handler for SAI send */ edma_handle_t *dmaHandle; /*!< DMA handler for SAI send */
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
uint8_t bytesPerFrame; /*!< Bytes in a frame */ uint8_t bytesPerFrame; /*!< Bytes in a frame */
uint8_t channel; /*!< Which data channel */ uint8_t channel; /*!< Which data channel */
uint8_t count; /*!< The transfer data count in a DMA request */ uint8_t count; /*!< The transfer data count in a DMA request */

View File

@ -230,8 +230,10 @@ static SDHC_Type *const s_sdhcBase[] = SDHC_BASE_PTRS;
/*! @brief SDHC IRQ name array */ /*! @brief SDHC IRQ name array */
static const IRQn_Type s_sdhcIRQ[] = SDHC_IRQS; static const IRQn_Type s_sdhcIRQ[] = SDHC_IRQS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief SDHC clock array name */ /*! @brief SDHC clock array name */
static const clock_ip_name_t s_sdhcClock[] = SDHC_CLOCKS; static const clock_ip_name_t s_sdhcClock[] = SDHC_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* SDHC ISR for transactional APIs. */ /* SDHC ISR for transactional APIs. */
static sdhc_isr_t s_sdhcIsr; static sdhc_isr_t s_sdhcIsr;
@ -411,10 +413,10 @@ static uint32_t SDHC_ReadDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t t
uint32_t readWatermark = ((base->WML & SDHC_WML_RDWML_MASK) >> SDHC_WML_RDWML_SHIFT); uint32_t readWatermark = ((base->WML & SDHC_WML_RDWML_MASK) >> SDHC_WML_RDWML_SHIFT);
/* /*
* Add non aligned access support ,user need make sure your buffer size is big * Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size * enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned * is 4 byte aligned
*/ */
if (data->blockSize % sizeof(uint32_t) != 0U) if (data->blockSize % sizeof(uint32_t) != 0U)
{ {
data->blockSize += data->blockSize +=
@ -458,10 +460,10 @@ static status_t SDHC_ReadByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data)
status_t error = kStatus_Success; status_t error = kStatus_Success;
/* /*
* Add non aligned access support ,user need make sure your buffer size is big * Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size * enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned * is 4 byte aligned
*/ */
if (data->blockSize % sizeof(uint32_t) != 0U) if (data->blockSize % sizeof(uint32_t) != 0U)
{ {
data->blockSize += data->blockSize +=
@ -506,10 +508,10 @@ static uint32_t SDHC_WriteDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t
uint32_t writeWatermark = ((base->WML & SDHC_WML_WRWML_MASK) >> SDHC_WML_WRWML_SHIFT); uint32_t writeWatermark = ((base->WML & SDHC_WML_WRWML_MASK) >> SDHC_WML_WRWML_SHIFT);
/* /*
* Add non aligned access support ,user need make sure your buffer size is big * Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size * enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned * is 4 byte aligned
*/ */
if (data->blockSize % sizeof(uint32_t) != 0U) if (data->blockSize % sizeof(uint32_t) != 0U)
{ {
data->blockSize += data->blockSize +=
@ -553,10 +555,10 @@ static status_t SDHC_WriteByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data)
status_t error = kStatus_Success; status_t error = kStatus_Success;
/* /*
* Add non aligned access support ,user need make sure your buffer size is big * Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size * enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned * is 4 byte aligned
*/ */
if (data->blockSize % sizeof(uint32_t) != 0U) if (data->blockSize % sizeof(uint32_t) != 0U)
{ {
data->blockSize += data->blockSize +=
@ -787,8 +789,10 @@ void SDHC_Init(SDHC_Type *base, const sdhc_config_t *config)
uint32_t proctl; uint32_t proctl;
uint32_t wml; uint32_t wml;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable SDHC clock. */ /* Enable SDHC clock. */
CLOCK_EnableClock(s_sdhcClock[SDHC_GetInstance(base)]); CLOCK_EnableClock(s_sdhcClock[SDHC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Reset SDHC. */ /* Reset SDHC. */
SDHC_Reset(base, kSDHC_ResetAll, 100); SDHC_Reset(base, kSDHC_ResetAll, 100);
@ -822,8 +826,10 @@ void SDHC_Init(SDHC_Type *base, const sdhc_config_t *config)
void SDHC_Deinit(SDHC_Type *base) void SDHC_Deinit(SDHC_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable clock. */ /* Disable clock. */
CLOCK_DisableClock(s_sdhcClock[SDHC_GetInstance(base)]); CLOCK_DisableClock(s_sdhcClock[SDHC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
bool SDHC_Reset(SDHC_Type *base, uint32_t mask, uint32_t timeout) bool SDHC_Reset(SDHC_Type *base, uint32_t mask, uint32_t timeout)
@ -923,7 +929,7 @@ bool SDHC_SetCardActive(SDHC_Type *base, uint32_t timeout)
{ {
base->SYSCTL |= SDHC_SYSCTL_INITA_MASK; base->SYSCTL |= SDHC_SYSCTL_INITA_MASK;
/* Delay some time to wait card become active state. */ /* Delay some time to wait card become active state. */
while (base->SYSCTL & SDHC_SYSCTL_INITA_MASK) while ((base->SYSCTL & SDHC_SYSCTL_INITA_MASK))
{ {
if (!timeout) if (!timeout)
{ {
@ -1008,7 +1014,7 @@ void SDHC_SetMmcBootConfig(SDHC_Type *base, const sdhc_boot_config_t *config)
uint32_t mmcboot = 0U; uint32_t mmcboot = 0U;
mmcboot = (SDHC_MMCBOOT_DTOCVACK(config->ackTimeoutCount) | SDHC_MMCBOOT_BOOTMODE(config->bootMode) | mmcboot = (SDHC_MMCBOOT_DTOCVACK(config->ackTimeoutCount) | SDHC_MMCBOOT_BOOTMODE(config->bootMode) |
SDHC_MMCBOOT_BOOTBLKCNT(config->blockCount)); SDHC_MMCBOOT_BOOTBLKCNT(config->blockCount));
if (config->enableBootAck) if (config->enableBootAck)
{ {
mmcboot |= SDHC_MMCBOOT_BOOTACK_MASK; mmcboot |= SDHC_MMCBOOT_BOOTACK_MASK;
@ -1118,10 +1124,10 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
#endif /* FSL_SDHC_ENABLE_ADMA1 */ #endif /* FSL_SDHC_ENABLE_ADMA1 */
case kSDHC_DmaModeAdma2: case kSDHC_DmaModeAdma2:
/* /*
* Add non aligned access support ,user need make sure your buffer size is big * Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size * enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned * is 4 byte aligned
*/ */
if (dataBytes % sizeof(uint32_t) != 0U) if (dataBytes % sizeof(uint32_t) != 0U)
{ {
dataBytes += dataBytes +=

View File

@ -477,7 +477,8 @@ typedef struct _sdhc_config
* @brief Card data descriptor * @brief Card data descriptor
* *
* Defines a structure to contain data-related attribute. 'enableIgnoreError' is used for the case that upper card * Defines a structure to contain data-related attribute. 'enableIgnoreError' is used for the case that upper card
* driver want to ignore the error event to read/write all the data not to stop read/write immediately when error event * driver
* want to ignore the error event to read/write all the data not to stop read/write immediately when error event
* happen for example bus testing procedure for MMC card. * happen for example bus testing procedure for MMC card.
*/ */
typedef struct _sdhc_data typedef struct _sdhc_data
@ -829,7 +830,8 @@ static inline void SDHC_SetDataBusWidth(SDHC_Type *base, sdhc_data_bus_width_t w
* @brief Sets the card transfer-related configuration. * @brief Sets the card transfer-related configuration.
* *
* This function fills the card transfer-related command argument/transfer flag/data size. The command and data are sent * This function fills the card transfer-related command argument/transfer flag/data size. The command and data are sent
* by SDHC after calling this function. by
* SDHC after calling this function.
* *
* Example: * Example:
@code @code
@ -929,7 +931,8 @@ static inline void SDHC_EnableCardDetectTest(SDHC_Type *base, bool enable)
* *
* This function sets the card detection test level to indicate whether the card is inserted into the SDHC when DAT[3]/ * This function sets the card detection test level to indicate whether the card is inserted into the SDHC when DAT[3]/
* CD pin is selected as a card detection pin. This function can also assert the pin logic when DAT[3]/CD pin is * CD pin is selected as a card detection pin. This function can also assert the pin logic when DAT[3]/CD pin is
* selected as the card detection pin. * selected
* as the card detection pin.
* *
* @param base SDHC peripheral base address. * @param base SDHC peripheral base address.
* @param high True to set the card detect level to high. * @param high True to set the card detect level to high.
@ -1007,7 +1010,8 @@ static inline void SDHC_SetForceEvent(SDHC_Type *base, uint32_t mask)
* @brief Transfers the command/data using a blocking method. * @brief Transfers the command/data using a blocking method.
* *
* This function waits until the command response/data is received or the SDHC encounters an error by polling the status * This function waits until the command response/data is received or the SDHC encounters an error by polling the status
* flag. The application must not call this API in multiple threads at the same time. Because of that this API doesn't support * flag.
* The application must not call this API in multiple threads at the same time. Because of that this API doesn't support
* the re-entry mechanism. * the re-entry mechanism.
* *
* @note There is no need to call the API 'SDHC_TransferCreateHandle' when calling this API. * @note There is no need to call the API 'SDHC_TransferCreateHandle' when calling this API.
@ -1044,7 +1048,8 @@ void SDHC_TransferCreateHandle(SDHC_Type *base,
* @brief Transfers the command/data using an interrupt and an asynchronous method. * @brief Transfers the command/data using an interrupt and an asynchronous method.
* *
* This function sends a command and data and returns immediately. It doesn't wait the transfer complete or encounter an * This function sends a command and data and returns immediately. It doesn't wait the transfer complete or encounter an
* error. The application must not call this API in multiple threads at the same time. Because of that this API doesn't support * error.
* The application must not call this API in multiple threads at the same time. Because of that this API doesn't support
* the re-entry mechanism. * the re-entry mechanism.
* *
* @note Call the API 'SDHC_TransferCreateHandle' when calling this API. * @note Call the API 'SDHC_TransferCreateHandle' when calling this API.

View File

@ -36,7 +36,6 @@
/*! @addtogroup sim */ /*! @addtogroup sim */
/*! @{*/ /*! @{*/
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -90,10 +89,10 @@ extern "C" {
* @brief Sets the USB voltage regulator setting. * @brief Sets the USB voltage regulator setting.
* *
* This function configures whether the USB voltage regulator is enabled in * 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 * 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 * are passed in as mask value of \ref _sim_usb_volt_reg_enable_mode. For example, to enable
* USB voltage regulator in RUN/VLPR/VLPW modes and disable in STOP/VLPS/LLS/VLLS mode, * USB voltage regulator in RUN/VLPR/VLPW modes and disable in STOP/VLPS/LLS/VLLS mode,
* please use: * use:
* *
* SIM_SetUsbVoltRegulatorEnableMode(kSIM_UsbVoltRegEnable | kSIM_UsbVoltRegEnableInLowPower); * SIM_SetUsbVoltRegulatorEnableMode(kSIM_UsbVoltRegEnable | kSIM_UsbVoltRegEnableInLowPower);
* *
@ -103,16 +102,16 @@ void SIM_SetUsbVoltRegulatorEnableMode(uint32_t mask);
#endif /* FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR */ #endif /* FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR */
/*! /*!
* @brief Get the unique identification register value. * @brief Gets the unique identification register value.
* *
* @param uid Pointer to the structure to save the UID value. * @param uid Pointer to the structure to save the UID value.
*/ */
void SIM_GetUniqueId(sim_uid_t *uid); void SIM_GetUniqueId(sim_uid_t *uid);
/*! /*!
* @brief Set the flash enable mode. * @brief Sets the flash enable mode.
* *
* @param mode The mode to set, see \ref _sim_flash_mode for mode details. * @param mode The mode to set; see \ref _sim_flash_mode for mode details.
*/ */
static inline void SIM_SetFlashMode(uint8_t mode) static inline void SIM_SetFlashMode(uint8_t mode)
{ {

View File

@ -29,6 +29,7 @@
*/ */
#include "fsl_smc.h" #include "fsl_smc.h"
#include "fsl_flash.h"
#if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM)
void SMC_GetParam(SMC_Type *base, smc_param_t *param) void SMC_GetParam(SMC_Type *base, smc_param_t *param)
@ -41,6 +42,39 @@ void SMC_GetParam(SMC_Type *base, smc_param_t *param)
} }
#endif /* FSL_FEATURE_SMC_HAS_PARAM */ #endif /* FSL_FEATURE_SMC_HAS_PARAM */
void SMC_PreEnterStopModes(void)
{
flash_prefetch_speculation_status_t speculationStatus =
{
kFLASH_prefetchSpeculationOptionDisable, /* Disable instruction speculation.*/
kFLASH_prefetchSpeculationOptionDisable, /* Disable data speculation.*/
};
__disable_irq();
__ISB();
/*
* Before enter stop modes, the flash cache prefetch should be disabled.
* Otherwise the prefetch might be interrupted by stop, then the data and
* and instruction from flash are wrong.
*/
FLASH_PflashSetPrefetchSpeculation(&speculationStatus);
}
void SMC_PostExitStopModes(void)
{
flash_prefetch_speculation_status_t speculationStatus =
{
kFLASH_prefetchSpeculationOptionEnable, /* Enable instruction speculation.*/
kFLASH_prefetchSpeculationOptionEnable, /* Enable data speculation.*/
};
FLASH_PflashSetPrefetchSpeculation(&speculationStatus);
__enable_irq();
__ISB();
}
status_t SMC_SetPowerModeRun(SMC_Type *base) status_t SMC_SetPowerModeRun(SMC_Type *base)
{ {
uint8_t reg; uint8_t reg;
@ -73,7 +107,9 @@ status_t SMC_SetPowerModeWait(SMC_Type *base)
{ {
/* configure Normal Wait mode */ /* configure Normal Wait mode */
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
__DSB();
__WFI(); __WFI();
__ISB();
return kStatus_Success; return kStatus_Success;
} }
@ -101,7 +137,9 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option)
/* read back to make sure the configuration valid before enter stop mode */ /* read back to make sure the configuration valid before enter stop mode */
(void)base->PMCTRL; (void)base->PMCTRL;
__DSB();
__WFI(); __WFI();
__ISB();
/* check whether the power mode enter Stop mode succeed */ /* check whether the power mode enter Stop mode succeed */
if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)
@ -148,16 +186,12 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base
status_t SMC_SetPowerModeVlpw(SMC_Type *base) 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 */ /* configure VLPW mode */
/* Set the SLEEPDEEP bit to enable deep sleep mode */ /* Set the SLEEPDEEP bit to enable deep sleep mode */
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
__DSB();
__WFI(); __WFI();
__ISB();
return kStatus_Success; return kStatus_Success;
} }
@ -177,7 +211,9 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base)
/* read back to make sure the configuration valid before enter stop mode */ /* read back to make sure the configuration valid before enter stop mode */
(void)base->PMCTRL; (void)base->PMCTRL;
__DSB();
__WFI(); __WFI();
__ISB();
/* check whether the power mode enter VLPS mode succeed */ /* check whether the power mode enter VLPS mode succeed */
if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)
@ -231,7 +267,9 @@ status_t SMC_SetPowerModeLls(SMC_Type *base
/* read back to make sure the configuration valid before enter stop mode */ /* read back to make sure the configuration valid before enter stop mode */
(void)base->PMCTRL; (void)base->PMCTRL;
__DSB();
__WFI(); __WFI();
__ISB();
/* check whether the power mode enter LLS mode succeed */ /* check whether the power mode enter LLS mode succeed */
if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)
@ -345,7 +383,9 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t
/* read back to make sure the configuration valid before enter stop mode */ /* read back to make sure the configuration valid before enter stop mode */
(void)base->PMCTRL; (void)base->PMCTRL;
__DSB();
__WFI(); __WFI();
__ISB();
/* check whether the power mode enter LLS mode succeed */ /* check whether the power mode enter LLS mode succeed */
if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)

View File

@ -36,7 +36,6 @@
/*! @addtogroup smc */ /*! @addtogroup smc */
/*! @{ */ /*! @{ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -44,8 +43,8 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief SMC driver version 2.0.1. */ /*! @brief SMC driver version 2.0.3. */
#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) #define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 3))
/*@}*/ /*@}*/
/*! /*!
@ -54,14 +53,14 @@
typedef enum _smc_power_mode_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) #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. */ kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-low-leakage Stop Mode. */
#endif #endif
#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) #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. */ kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-leakage Stop Mode. */
#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */
kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-Power 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) #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. */ kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High-speed Run mode. */
#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
kSMC_AllowPowerModeAll = (0U kSMC_AllowPowerModeAll = (0U
#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
@ -107,10 +106,10 @@ typedef enum _smc_power_state
*/ */
typedef enum _smc_run_mode typedef enum _smc_run_mode
{ {
kSMC_RunNormal = 0U, /*!< normal RUN mode. */ kSMC_RunNormal = 0U, /*!< Normal RUN mode. */
kSMC_RunVlpr = 2U, /*!< Very-Low-Power 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) #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). */ kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */
#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
} smc_run_mode_t; } smc_run_mode_t;
@ -120,12 +119,12 @@ typedef enum _smc_run_mode
typedef enum _smc_stop_mode typedef enum _smc_stop_mode
{ {
kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ kSMC_StopNormal = 0U, /*!< Normal STOP mode. */
kSMC_StopVlps = 2U, /*!< Very-Low-Power 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) #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. */ kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */
#endif /* FSL_FEATURE_SMC_HAS_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) #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. */ kSMC_StopVlls = 4U /*!< Very-low-leakage Stop mode. */
#endif #endif
} smc_stop_mode_t; } smc_stop_mode_t;
@ -155,7 +154,7 @@ typedef enum _smc_partial_stop_mode
} smc_partial_stop_option_t; } smc_partial_stop_option_t;
/*! /*!
* @brief SMC configuration status * @brief SMC configuration status.
*/ */
enum _smc_status enum _smc_status
{ {
@ -190,7 +189,7 @@ typedef struct _smc_param
#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \ #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) (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)
/*! /*!
* @brief SMC Low-Leakage Stop power mode config * @brief SMC Low-Leakage Stop power mode configuration.
*/ */
typedef struct _smc_power_mode_lls_config typedef struct _smc_power_mode_lls_config
{ {
@ -205,7 +204,7 @@ typedef struct _smc_power_mode_lls_config
#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_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 SMC Very Low-Leakage Stop power mode config * @brief SMC Very Low-Leakage Stop power mode configuration.
*/ */
typedef struct _smc_power_mode_vlls_config typedef struct _smc_power_mode_vlls_config
{ {
@ -242,10 +241,10 @@ extern "C" {
* @brief Gets the SMC version ID. * @brief Gets the SMC version ID.
* *
* This function gets the SMC version ID, including major version number, * This function gets the SMC version ID, including major version number,
* minor version number and feature specification number. * minor version number, and feature specification number.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @param versionId Pointer to version ID structure. * @param versionId Pointer to the version ID structure.
*/ */
static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId)
{ {
@ -257,10 +256,10 @@ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId)
/*! /*!
* @brief Gets the SMC parameter. * @brief Gets the SMC parameter.
* *
* This function gets the SMC parameter, including the enabled power mdoes. * This function gets the SMC parameter including the enabled power mdoes.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @param param Pointer to SMC param structure. * @param param Pointer to the SMC param structure.
*/ */
void SMC_GetParam(SMC_Type *base, smc_param_t *param); void SMC_GetParam(SMC_Type *base, smc_param_t *param);
#endif #endif
@ -274,7 +273,7 @@ void SMC_GetParam(SMC_Type *base, smc_param_t *param);
* system level initialization stage. See the reference manual for details. * system level initialization stage. See the reference manual for details.
* This register can only write once after the power reset. * 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, * The allowed modes are passed as bit map. For example, to allow LLS and VLLS,
* use SMC_SetPowerModeProtection(kSMC_AllowPowerModeVlls | kSMC_AllowPowerModeVlps). * use SMC_SetPowerModeProtection(kSMC_AllowPowerModeVlls | kSMC_AllowPowerModeVlps).
* To allow all modes, use SMC_SetPowerModeProtection(kSMC_AllowPowerModeAll). * To allow all modes, use SMC_SetPowerModeProtection(kSMC_AllowPowerModeAll).
* *
@ -289,13 +288,13 @@ static inline void SMC_SetPowerModeProtection(SMC_Type *base, uint8_t allowedMod
/*! /*!
* @brief Gets the current power mode status. * @brief Gets the current power mode status.
* *
* This function returns the current power mode stat. Once application * This function returns the current power mode status. After the application
* switches the power mode, it should always check the stat to check whether it * switches the power mode, it should always check the status to check whether it
* runs into the specified mode or not. An application should check * runs into the specified mode or not. The application should check
* this mode before switching to a different mode. The system requires that * this mode before switching to a different mode. The system requires that
* only certain modes can switch to other specific modes. See the * only certain modes can switch to other specific modes. See the
* reference manual for details and the smc_power_state_t for information about * reference manual for details and the smc_power_state_t for information about
* the power stat. * the power status.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @return Current power mode status. * @return Current power mode status.
@ -306,7 +305,45 @@ static inline smc_power_state_t SMC_GetPowerModeState(SMC_Type *base)
} }
/*! /*!
* @brief Configure the system to RUN power mode. * @brief Prepares to enter stop modes.
*
* This function should be called before entering STOP/VLPS/LLS/VLLS modes.
*/
void SMC_PreEnterStopModes(void);
/*!
* @brief Recovers after wake up from stop modes.
*
* This function should be called after wake up from STOP/VLPS/LLS/VLLS modes.
* It is used with @ref SMC_PreEnterStopModes.
*/
void SMC_PostExitStopModes(void);
/*!
* @brief Prepares to enter wait modes.
*
* This function should be called before entering WAIT/VLPW modes.
*/
static inline void SMC_PreEnterWaitModes(void)
{
__disable_irq();
__ISB();
}
/*!
* @brief Recovers after wake up from stop modes.
*
* This function should be called after wake up from WAIT/VLPW modes.
* It is used with @ref SMC_PreEnterWaitModes.
*/
static inline void SMC_PostExitWaitModes(void)
{
__enable_irq();
__ISB();
}
/*!
* @brief Configures the system to RUN power mode.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @return SMC configuration error code. * @return SMC configuration error code.
@ -315,7 +352,7 @@ 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) #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. * @brief Configures the system to HSRUN power mode.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @return SMC configuration error code. * @return SMC configuration error code.
@ -324,7 +361,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base);
#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
/*! /*!
* @brief Configure the system to WAIT power mode. * @brief Configures the system to WAIT power mode.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @return SMC configuration error code. * @return SMC configuration error code.
@ -332,7 +369,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base);
status_t SMC_SetPowerModeWait(SMC_Type *base); status_t SMC_SetPowerModeWait(SMC_Type *base);
/*! /*!
* @brief Configure the system to Stop power mode. * @brief Configures the system to Stop power mode.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @param option Partial Stop mode option. * @param option Partial Stop mode option.
@ -342,7 +379,7 @@ 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) #if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI)
/*! /*!
* @brief Configure the system to VLPR power mode. * @brief Configures the system to VLPR power mode.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @param wakeupMode Enter Normal Run mode if true, else stay in VLPR mode. * @param wakeupMode Enter Normal Run mode if true, else stay in VLPR mode.
@ -351,7 +388,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option);
status_t SMC_SetPowerModeVlpr(SMC_Type *base, bool wakeupMode); status_t SMC_SetPowerModeVlpr(SMC_Type *base, bool wakeupMode);
#else #else
/*! /*!
* @brief Configure the system to VLPR power mode. * @brief Configures the system to VLPR power mode.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @return SMC configuration error code. * @return SMC configuration error code.
@ -360,7 +397,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base);
#endif /* FSL_FEATURE_SMC_HAS_LPWUI */ #endif /* FSL_FEATURE_SMC_HAS_LPWUI */
/*! /*!
* @brief Configure the system to VLPW power mode. * @brief Configures the system to VLPW power mode.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @return SMC configuration error code. * @return SMC configuration error code.
@ -368,7 +405,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base);
status_t SMC_SetPowerModeVlpw(SMC_Type *base); status_t SMC_SetPowerModeVlpw(SMC_Type *base);
/*! /*!
* @brief Configure the system to VLPS power mode. * @brief Configures the system to VLPS power mode.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @return SMC configuration error code. * @return SMC configuration error code.
@ -379,7 +416,7 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base);
#if ((defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \ #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)) (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO))
/*! /*!
* @brief Configure the system to LLS power mode. * @brief Configures the system to LLS power mode.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @param config The LLS power mode configuration structure * @param config The LLS power mode configuration structure
@ -388,7 +425,7 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base);
status_t SMC_SetPowerModeLls(SMC_Type *base, const smc_power_mode_lls_config_t *config); status_t SMC_SetPowerModeLls(SMC_Type *base, const smc_power_mode_lls_config_t *config);
#else #else
/*! /*!
* @brief Configure the system to LLS power mode. * @brief Configures the system to LLS power mode.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @return SMC configuration error code. * @return SMC configuration error code.
@ -399,7 +436,7 @@ status_t SMC_SetPowerModeLls(SMC_Type *base);
#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_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. * @brief Configures the system to VLLS power mode.
* *
* @param base SMC peripheral base address. * @param base SMC peripheral base address.
* @param config The VLLS power mode configuration structure. * @param config The VLLS power mode configuration structure.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -37,10 +37,12 @@
/* UART transfer state. */ /* UART transfer state. */
enum _uart_tansfer_states enum _uart_tansfer_states
{ {
kUART_TxIdle, /* TX idle. */ kUART_TxIdle, /* TX idle. */
kUART_TxBusy, /* TX busy. */ kUART_TxBusy, /* TX busy. */
kUART_RxIdle, /* RX idle. */ kUART_RxIdle, /* RX idle. */
kUART_RxBusy /* RX busy. */ kUART_RxBusy, /* RX busy. */
kUART_RxFramingError, /* Rx framing error */
kUART_RxParityError /* Rx parity error */
}; };
/* Typedef for interrupt handler. */ /* Typedef for interrupt handler. */
@ -138,8 +140,10 @@ static UART_Type *const s_uartBases[] = UART_BASE_PTRS;
/* Array of UART IRQ number. */ /* Array of UART IRQ number. */
static const IRQn_Type s_uartIRQ[] = UART_RX_TX_IRQS; static const IRQn_Type s_uartIRQ[] = UART_RX_TX_IRQS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Array of UART clock name. */ /* Array of UART clock name. */
static const clock_ip_name_t s_uartClock[] = UART_CLOCKS; static const clock_ip_name_t s_uartClock[] = UART_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* UART ISR for transactional APIs. */ /* UART ISR for transactional APIs. */
static uart_isr_t s_uartIsr; static uart_isr_t s_uartIsr;
@ -169,6 +173,8 @@ uint32_t UART_GetInstance(UART_Type *base)
static size_t UART_TransferGetRxRingBufferLength(uart_handle_t *handle) static size_t UART_TransferGetRxRingBufferLength(uart_handle_t *handle)
{ {
assert(handle);
size_t size; size_t size;
if (handle->rxRingBufferTail > handle->rxRingBufferHead) if (handle->rxRingBufferTail > handle->rxRingBufferHead)
@ -185,6 +191,8 @@ static size_t UART_TransferGetRxRingBufferLength(uart_handle_t *handle)
static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle) static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle)
{ {
assert(handle);
bool full; bool full;
if (UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U)) if (UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U))
@ -199,36 +207,72 @@ static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle)
return full; return full;
} }
void UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz) status_t UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz)
{ {
assert(config); assert(config);
assert(config->baudRate_Bps);
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO #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->txFifoWatermark);
assert(FSL_FEATURE_UART_FIFO_SIZEn(base) >= config->rxFifoWatermark); assert(FSL_FEATURE_UART_FIFO_SIZEn(base) >= config->rxFifoWatermark);
#endif #endif
uint16_t sbr; uint16_t sbr = 0;
uint8_t temp; uint8_t temp = 0;
uint32_t baudDiff = 0;
/* 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*/ /* Calculate the baud rate modulo divisor, sbr*/
sbr = srcClock_Hz / (config->baudRate_Bps * 16); sbr = srcClock_Hz / (config->baudRate_Bps * 16);
/* set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate */
if (sbr == 0)
{
sbr = 1;
}
#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. */
uint32_t tempBaud = 0;
uint16_t brfa = (2 * srcClock_Hz / (config->baudRate_Bps)) - 32 * sbr;
/* Calculate the baud rate based on the temporary SBR values and BRFA */
tempBaud = (srcClock_Hz * 2 / ((sbr * 32 + brfa)));
baudDiff =
(tempBaud > config->baudRate_Bps) ? (tempBaud - config->baudRate_Bps) : (config->baudRate_Bps - tempBaud);
#else
/* Calculate the baud rate based on the temporary SBR values */
baudDiff = (srcClock_Hz / (sbr * 16)) - config->baudRate_Bps;
/* Select the better value between sbr and (sbr + 1) */
if (baudDiff > (config->baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1)))))
{
baudDiff = config->baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1)));
sbr++;
}
#endif
/* next, check to see if actual baud rate is within 3% of desired baud rate
* based on the calculate SBR value */
if (baudDiff > ((config->baudRate_Bps / 100) * 3))
{
/* Unacceptable baud rate difference of more than 3%*/
return kStatus_UART_BaudrateNotSupport;
}
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable uart clock */
CLOCK_EnableClock(s_uartClock[UART_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Disable UART TX RX before setting. */
base->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK);
/* Write the sbr value to the BDH and BDL registers*/ /* Write the sbr value to the BDH and BDL registers*/
base->BDH = (base->BDH & ~UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8); base->BDH = (base->BDH & ~UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8);
base->BDL = (uint8_t)sbr; 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 #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*/ /* Write the brfa value to the register*/
base->C4 = (base->C4 & ~UART_C4_BRFA_MASK) | (brfa & UART_C4_BRFA_MASK); base->C4 = (base->C4 & ~UART_C4_BRFA_MASK) | (brfa & UART_C4_BRFA_MASK);
#endif #endif
@ -274,6 +318,8 @@ void UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_H
} }
base->C2 = temp; base->C2 = temp;
return kStatus_Success;
} }
void UART_Deinit(UART_Type *base) void UART_Deinit(UART_Type *base)
@ -292,8 +338,10 @@ void UART_Deinit(UART_Type *base)
/* Disable the module. */ /* Disable the module. */
base->C2 = 0; base->C2 = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable uart clock */ /* Disable uart clock */
CLOCK_DisableClock(s_uartClock[UART_GetInstance(base)]); CLOCK_DisableClock(s_uartClock[UART_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void UART_GetDefaultConfig(uart_config_t *config) void UART_GetDefaultConfig(uart_config_t *config)
@ -313,61 +361,101 @@ void UART_GetDefaultConfig(uart_config_t *config)
config->enableRx = false; config->enableRx = false;
} }
void UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) status_t UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
{ {
uint16_t sbr; assert(baudRate_Bps);
uint16_t sbr = 0;
uint32_t baudDiff = 0;
uint8_t oldCtrl; 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*/ /* Calculate the baud rate modulo divisor, sbr*/
sbr = srcClock_Hz / (baudRate_Bps * 16); sbr = srcClock_Hz / (baudRate_Bps * 16);
/* set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate */
/* Write the sbr value to the BDH and BDL registers*/ if (sbr == 0)
base->BDH = (base->BDH & ~UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8); {
base->BDL = (uint8_t)sbr; sbr = 1;
}
#if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT #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 /* Determine if a fractional divider is needed to fine tune closer to the
* desired baud, each value of brfa is in 1/32 increments, * desired baud, each value of brfa is in 1/32 increments,
* hence the multiply-by-32. */ * hence the multiply-by-32. */
uint16_t brfa = (32 * srcClock_Hz / (baudRate_Bps * 16)) - 32 * sbr; uint32_t tempBaud = 0;
/* Write the brfa value to the register*/ uint16_t brfa = (2 * srcClock_Hz / (baudRate_Bps)) - 32 * sbr;
base->C4 = (base->C4 & ~UART_C4_BRFA_MASK) | (brfa & UART_C4_BRFA_MASK);
/* Calculate the baud rate based on the temporary SBR values and BRFA */
tempBaud = (srcClock_Hz * 2 / ((sbr * 32 + brfa)));
baudDiff = (tempBaud > baudRate_Bps) ? (tempBaud - baudRate_Bps) : (baudRate_Bps - tempBaud);
#else
/* Calculate the baud rate based on the temporary SBR values */
baudDiff = (srcClock_Hz / (sbr * 16)) - baudRate_Bps;
/* Select the better value between sbr and (sbr + 1) */
if (baudDiff > (baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1)))))
{
baudDiff = baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1)));
sbr++;
}
#endif #endif
/* Restore C2. */ /* next, check to see if actual baud rate is within 3% of desired baud rate
base->C2 = oldCtrl; * based on the calculate SBR value */
if (baudDiff < ((baudRate_Bps / 100) * 3))
{
/* 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);
/* 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
/* 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;
return kStatus_Success;
}
else
{
/* Unacceptable baud rate difference of more than 3%*/
return kStatus_UART_BaudrateNotSupport;
}
} }
void UART_EnableInterrupts(UART_Type *base, uint32_t mask) void UART_EnableInterrupts(UART_Type *base, uint32_t mask)
{ {
mask &= kUART_AllInterruptsEnable;
/* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH)) /* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH))
*/ */
base->BDH |= (mask & 0xFF); base->BDH |= mask;
base->C2 |= ((mask >> 8) & 0xFF); base->C2 |= (mask >> 8);
base->C3 |= ((mask >> 16) & 0xFF); base->C3 |= (mask >> 16);
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
base->CFIFO |= ((mask >> 24) & 0xFF); base->CFIFO |= (mask >> 24);
#endif #endif
} }
void UART_DisableInterrupts(UART_Type *base, uint32_t mask) void UART_DisableInterrupts(UART_Type *base, uint32_t mask)
{ {
mask &= kUART_AllInterruptsEnable;
/* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH)) /* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH))
*/ */
base->BDH &= ~(mask & 0xFF); base->BDH &= ~mask;
base->C2 &= ~((mask >> 8) & 0xFF); base->C2 &= ~(mask >> 8);
base->C3 &= ~((mask >> 16) & 0xFF); base->C3 &= ~(mask >> 16);
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
base->CFIFO &= ~((mask >> 24) & 0xFF); base->CFIFO &= ~(mask >> 24);
#endif #endif
} }
@ -381,7 +469,7 @@ uint32_t UART_GetEnabledInterrupts(UART_Type *base)
temp |= ((uint32_t)(base->CFIFO) << 24); temp |= ((uint32_t)(base->CFIFO) << 24);
#endif #endif
return temp; return temp & kUART_AllInterruptsEnable;
} }
uint32_t UART_GetStatusFlags(UART_Type *base) uint32_t UART_GetStatusFlags(UART_Type *base)
@ -418,14 +506,24 @@ status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask)
base->SFIFO = (uint8_t)(mask >> 24); base->SFIFO = (uint8_t)(mask >> 24);
#endif #endif
if (mask & (kUART_IdleLineFlag | kUART_RxOverrunFlag | kUART_NoiseErrorFlag | kUART_FramingErrorFlag | if (mask & (kUART_IdleLineFlag | kUART_NoiseErrorFlag | kUART_FramingErrorFlag | kUART_ParityErrorFlag))
kUART_ParityErrorFlag))
{ {
/* Read base->D to clear the flags. */ /* Read base->D to clear the flags. */
(void)base->S1; (void)base->S1;
(void)base->D; (void)base->D;
} }
if (mask & kUART_RxOverrunFlag)
{
/* Read base->D to clear the flags and Flush all data in FIFO. */
(void)base->S1;
(void)base->D;
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
/* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */
base->CFIFO |= UART_CFIFO_RXFLUSH_MASK;
#endif
}
/* If some flags still pending. */ /* If some flags still pending. */
if (mask & UART_GetStatusFlags(base)) if (mask & UART_GetStatusFlags(base))
{ {
@ -457,6 +555,8 @@ void UART_WriteBlocking(UART_Type *base, const uint8_t *data, size_t length)
static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t length) static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t length)
{ {
assert(data);
size_t i; size_t i;
/* The Non Blocking write data API assume user have ensured there is enough space in /* The Non Blocking write data API assume user have ensured there is enough space in
@ -469,6 +569,8 @@ static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t l
status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length) status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length)
{ {
assert(data);
uint32_t statusFlag; uint32_t statusFlag;
while (length--) while (length--)
@ -509,6 +611,8 @@ status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length)
static void UART_ReadNonBlocking(UART_Type *base, uint8_t *data, size_t length) static void UART_ReadNonBlocking(UART_Type *base, uint8_t *data, size_t length)
{ {
assert(data);
size_t i; size_t i;
/* The Non Blocking read data API assume user have ensured there is enough space in /* The Non Blocking read data API assume user have ensured there is enough space in
@ -558,7 +662,6 @@ void UART_TransferCreateHandle(UART_Type *base,
s_uartHandle[instance] = handle; s_uartHandle[instance] = handle;
s_uartIsr = UART_TransferHandleIRQ; s_uartIsr = UART_TransferHandleIRQ;
/* Enable interrupt in NVIC. */ /* Enable interrupt in NVIC. */
EnableIRQ(s_uartIRQ[instance]); EnableIRQ(s_uartIRQ[instance]);
} }
@ -566,17 +669,21 @@ void UART_TransferCreateHandle(UART_Type *base,
void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize) void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize)
{ {
assert(handle); assert(handle);
assert(ringBuffer);
/* Setup the ringbuffer address */ /* Setup the ringbuffer address */
if (ringBuffer) handle->rxRingBuffer = ringBuffer;
{ handle->rxRingBufferSize = ringBufferSize;
handle->rxRingBuffer = ringBuffer; handle->rxRingBufferHead = 0U;
handle->rxRingBufferSize = ringBufferSize; handle->rxRingBufferTail = 0U;
handle->rxRingBufferHead = 0U;
handle->rxRingBufferTail = 0U;
/* Enable the interrupt to accept the data when user need the ring buffer. */ /* Enable the interrupt to accept the data when user need the ring buffer. */
UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); UART_EnableInterrupts(
base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | kUART_FramingErrorInterruptEnable);
/* Enable parity error interrupt when parity mode is enable*/
if (UART_C1_PE_MASK & base->C1)
{
UART_EnableInterrupts(base, kUART_ParityErrorInterruptEnable);
} }
} }
@ -586,7 +693,13 @@ void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle)
if (handle->rxState == kUART_RxIdle) if (handle->rxState == kUART_RxIdle)
{ {
UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable |
kUART_FramingErrorInterruptEnable);
/* Disable parity error interrupt when parity mode is enable*/
if (UART_C1_PE_MASK & base->C1)
{
UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable);
}
} }
handle->rxRingBuffer = NULL; handle->rxRingBuffer = NULL;
@ -597,13 +710,12 @@ void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle)
status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer) status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer)
{ {
status_t status; assert(handle);
assert(xfer);
assert(xfer->dataSize);
assert(xfer->data);
/* Return error if xfer invalid. */ status_t status;
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* Return error if current TX busy. */ /* Return error if current TX busy. */
if (kUART_TxBusy == handle->txState) if (kUART_TxBusy == handle->txState)
@ -628,6 +740,8 @@ status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, ua
void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle) void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle)
{ {
assert(handle);
UART_DisableInterrupts(base, kUART_TxDataRegEmptyInterruptEnable | kUART_TransmissionCompleteInterruptEnable); UART_DisableInterrupts(base, kUART_TxDataRegEmptyInterruptEnable | kUART_TransmissionCompleteInterruptEnable);
handle->txDataSize = 0; handle->txDataSize = 0;
@ -636,16 +750,14 @@ void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle)
status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count) status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count)
{ {
assert(handle);
assert(count);
if (kUART_TxIdle == handle->txState) if (kUART_TxIdle == handle->txState)
{ {
return kStatus_NoTransferInProgress; return kStatus_NoTransferInProgress;
} }
if (!count)
{
return kStatus_InvalidArgument;
}
*count = handle->txDataSizeAll - handle->txDataSize; *count = handle->txDataSizeAll - handle->txDataSize;
return kStatus_Success; return kStatus_Success;
@ -656,6 +768,11 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base,
uart_transfer_t *xfer, uart_transfer_t *xfer,
size_t *receivedBytes) size_t *receivedBytes)
{ {
assert(handle);
assert(xfer);
assert(xfer->data);
assert(xfer->dataSize);
uint32_t i; uint32_t i;
status_t status; status_t status;
/* How many bytes to copy from ring buffer to user memory. */ /* How many bytes to copy from ring buffer to user memory. */
@ -664,13 +781,6 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base,
size_t bytesToReceive; size_t bytesToReceive;
/* How many bytes currently have received. */ /* How many bytes currently have received. */
size_t bytesCurrentReceived; 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: /* How to get data:
1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
@ -694,8 +804,8 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base,
/* If RX ring buffer is used. */ /* If RX ring buffer is used. */
if (handle->rxRingBuffer) if (handle->rxRingBuffer)
{ {
/* Disable IRQ, protect ring buffer. */ /* Disable UART RX IRQ, protect ring buffer. */
regPrimask = DisableGlobalIRQ(); UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable);
/* How many bytes in RX ring buffer currently. */ /* How many bytes in RX ring buffer currently. */
bytesToCopy = UART_TransferGetRxRingBufferLength(handle); bytesToCopy = UART_TransferGetRxRingBufferLength(handle);
@ -733,8 +843,8 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base,
handle->rxState = kUART_RxBusy; handle->rxState = kUART_RxBusy;
} }
/* Enable IRQ if previously enabled. */ /* Enable UART RX IRQ if previously enabled. */
EnableGlobalIRQ(regPrimask); UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable);
/* Call user callback since all data are received. */ /* Call user callback since all data are received. */
if (0 == bytesToReceive) if (0 == bytesToReceive)
@ -753,8 +863,14 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base,
handle->rxDataSizeAll = bytesToReceive; handle->rxDataSizeAll = bytesToReceive;
handle->rxState = kUART_RxBusy; handle->rxState = kUART_RxBusy;
/* Enable RX interrupt. */ /* Enable RX/Rx overrun/framing error interrupt. */
UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable |
kUART_FramingErrorInterruptEnable);
/* Enable parity error interrupt when parity mode is enable*/
if (UART_C1_PE_MASK & base->C1)
{
UART_EnableInterrupts(base, kUART_ParityErrorInterruptEnable);
}
} }
/* Return the how many bytes have read. */ /* Return the how many bytes have read. */
@ -771,11 +887,19 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base,
void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle) void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle)
{ {
assert(handle);
/* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
if (!handle->rxRingBuffer) if (!handle->rxRingBuffer)
{ {
/* Disable RX interrupt. */ /* Disable RX interrupt. */
UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable |
kUART_FramingErrorInterruptEnable);
/* Disable parity error interrupt when parity mode is enable*/
if (UART_C1_PE_MASK & base->C1)
{
UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable);
}
} }
handle->rxDataSize = 0U; handle->rxDataSize = 0U;
@ -784,6 +908,9 @@ void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle)
status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, uint32_t *count) status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, uint32_t *count)
{ {
assert(handle);
assert(count);
if (kUART_RxIdle == handle->rxState) if (kUART_RxIdle == handle->rxState)
{ {
return kStatus_NoTransferInProgress; return kStatus_NoTransferInProgress;
@ -801,17 +928,67 @@ status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, ui
void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle) void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle)
{ {
assert(handle);
uint8_t count; uint8_t count;
uint8_t tempCount; uint8_t tempCount;
assert(handle); /* If RX framing error */
if (UART_S1_FE_MASK & base->S1)
{
/* Read base->D to clear framing error flag, otherwise the RX does not work. */
while (base->S1 & UART_S1_RDRF_MASK)
{
(void)base->D;
}
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
/* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */
base->CFIFO |= UART_CFIFO_RXFLUSH_MASK;
#endif
handle->rxState = kUART_RxFramingError;
handle->rxDataSize = 0U;
/* Trigger callback. */
if (handle->callback)
{
handle->callback(base, handle, kStatus_UART_FramingError, handle->userData);
}
}
/* If RX parity error */
if (UART_S1_PF_MASK & base->S1)
{
/* Read base->D to clear parity error flag, otherwise the RX does not work. */
while (base->S1 & UART_S1_RDRF_MASK)
{
(void)base->D;
}
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
/* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */
base->CFIFO |= UART_CFIFO_RXFLUSH_MASK;
#endif
handle->rxState = kUART_RxParityError;
handle->rxDataSize = 0U;
/* Trigger callback. */
if (handle->callback)
{
handle->callback(base, handle, kStatus_UART_ParityError, handle->userData);
}
}
/* If RX overrun. */ /* If RX overrun. */
if (UART_S1_OR_MASK & base->S1) if (UART_S1_OR_MASK & base->S1)
{ {
/* Read base->D, otherwise the RX does not work. */ /* Read base->D to clear overrun flag, otherwise the RX does not work. */
(void)base->D; while (base->S1 & UART_S1_RDRF_MASK)
{
(void)base->D;
}
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
/* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */
base->CFIFO |= UART_CFIFO_RXFLUSH_MASK;
#endif
/* Trigger callback. */ /* Trigger callback. */
if (handle->callback) if (handle->callback)
{ {
@ -898,16 +1075,38 @@ void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle)
} }
} }
} }
/* If no receive requst pending, stop RX interrupt. */
else if (!handle->rxDataSize) else if (!handle->rxDataSize)
{ {
UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); /* Disable RX interrupt/overrun interrupt/fram error interrupt */
UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable |
kUART_FramingErrorInterruptEnable);
/* Disable parity error interrupt when parity mode is enable*/
if (UART_C1_PE_MASK & base->C1)
{
UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable);
}
} }
else else
{ {
} }
} }
/* If framing error or parity error happened, stop the RX interrupt when ues no ring buffer */
if (((handle->rxState == kUART_RxFramingError) || (handle->rxState == kUART_RxParityError)) &&
(!handle->rxRingBuffer))
{
UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable |
kUART_FramingErrorInterruptEnable);
/* Disable parity error interrupt when parity mode is enable*/
if (UART_C1_PE_MASK & base->C1)
{
UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable);
}
}
/* Send data register empty and the interrupt is enabled. */ /* Send data register empty and the interrupt is enabled. */
if ((base->S1 & UART_S1_TDRE_MASK) && (base->C2 & UART_C2_TIE_MASK)) if ((base->S1 & UART_S1_TDRE_MASK) && (base->C2 & UART_C2_TIE_MASK))
{ {
@ -952,7 +1151,7 @@ void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle)
void UART_TransferHandleErrorIRQ(UART_Type *base, uart_handle_t *handle) void UART_TransferHandleErrorIRQ(UART_Type *base, uart_handle_t *handle)
{ {
/* TODO: To be implemented. */ /* To be implemented by User. */
} }
#if defined(UART0) #if defined(UART0)
@ -992,7 +1191,6 @@ void UART2_RX_TX_DriverIRQHandler(void)
{ {
UART2_DriverIRQHandler(); UART2_DriverIRQHandler();
} }
#endif #endif
#if defined(UART3) #if defined(UART3)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -37,16 +37,14 @@
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief UART driver version 2.1.0. */ /*! @brief UART driver version 2.1.4. */
#define FSL_UART_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) #define FSL_UART_DRIVER_VERSION (MAKE_VERSION(2, 1, 4))
/*@}*/ /*@}*/
/*! @brief Error codes for the UART driver. */ /*! @brief Error codes for the UART driver. */
@ -66,6 +64,8 @@ enum _uart_status
kStatus_UART_NoiseError = MAKE_STATUS(kStatusGroup_UART, 10), /*!< UART noise error. */ kStatus_UART_NoiseError = MAKE_STATUS(kStatusGroup_UART, 10), /*!< UART noise error. */
kStatus_UART_FramingError = MAKE_STATUS(kStatusGroup_UART, 11), /*!< UART framing error. */ kStatus_UART_FramingError = MAKE_STATUS(kStatusGroup_UART, 11), /*!< UART framing error. */
kStatus_UART_ParityError = MAKE_STATUS(kStatusGroup_UART, 12), /*!< UART parity error. */ kStatus_UART_ParityError = MAKE_STATUS(kStatusGroup_UART, 12), /*!< UART parity error. */
kStatus_UART_BaudrateNotSupport =
MAKE_STATUS(kStatusGroup_UART, 13), /*!< Baudrate is not support in current clock source */
}; };
/*! @brief UART parity mode. */ /*! @brief UART parity mode. */
@ -103,10 +103,23 @@ enum _uart_interrupt_enable
kUART_FramingErrorInterruptEnable = (UART_C3_FEIE_MASK << 16), /*!< Framing 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. */ kUART_ParityErrorInterruptEnable = (UART_C3_PEIE_MASK << 16), /*!< Parity error flag interrupt. */
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
kUART_RxFifoOverflowInterruptEnable = (UART_CFIFO_TXOFE_MASK << 24), /*!< TX FIFO overflow interrupt. */ kUART_RxFifoOverflowInterruptEnable = (UART_CFIFO_RXOFE_MASK << 24), /*!< RX FIFO overflow interrupt. */
kUART_TxFifoOverflowInterruptEnable = (UART_CFIFO_RXUFE_MASK << 24), /*!< RX FIFO underflow interrupt. */ kUART_TxFifoOverflowInterruptEnable = (UART_CFIFO_TXOFE_MASK << 24), /*!< TX FIFO overflow interrupt. */
kUART_RxFifoUnderflowInterruptEnable = (UART_CFIFO_RXUFE_MASK << 24), /*!< RX FIFO underflow interrupt. */ kUART_RxFifoUnderflowInterruptEnable = (UART_CFIFO_RXUFE_MASK << 24), /*!< RX FIFO underflow interrupt. */
#endif #endif
kUART_AllInterruptsEnable =
#if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT
kUART_LinBreakInterruptEnable |
#endif
kUART_RxActiveEdgeInterruptEnable | kUART_TxDataRegEmptyInterruptEnable |
kUART_TransmissionCompleteInterruptEnable | kUART_RxDataRegFullInterruptEnable | kUART_IdleLineInterruptEnable |
kUART_RxOverrunInterruptEnable | kUART_NoiseErrorInterruptEnable | kUART_FramingErrorInterruptEnable |
kUART_ParityErrorInterruptEnable
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
|
kUART_RxFifoOverflowInterruptEnable | kUART_TxFifoOverflowInterruptEnable | kUART_RxFifoUnderflowInterruptEnable
#endif
,
}; };
/*! /*!
@ -128,13 +141,16 @@ enum _uart_flags
kUART_ParityErrorFlag = (UART_S1_PF_MASK), /*!< If parity enabled, sets upon parity error detection */ 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 #if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT
kUART_LinBreakFlag = kUART_LinBreakFlag =
(UART_S2_LBKDIF_MASK << 8), /*!< LIN break detect interrupt flag, sets when (UART_S2_LBKDIF_MASK
<< 8), /*!< LIN break detect interrupt flag, sets when
LIN break char detected and LIN circuit enabled */ LIN break char detected and LIN circuit enabled */
#endif #endif
kUART_RxActiveEdgeFlag = (UART_S2_RXEDGIF_MASK << 8), /*!< RX pin active edge interrupt flag, kUART_RxActiveEdgeFlag =
sets when active edge detected */ (UART_S2_RXEDGIF_MASK << 8), /*!< RX pin active edge interrupt flag,
kUART_RxActiveFlag = (UART_S2_RAF_MASK << 8), /*!< Receiver Active Flag (RAF), sets when active edge detected */
sets at beginning of valid start bit */ 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 #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_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. */ kUART_ParityErrorInRxDataRegFlag = (UART_ED_PARITYE_MASK << 16), /*!< Paritye bit, sets if parity error detected. */
@ -213,11 +229,11 @@ extern "C" {
*/ */
/*! /*!
* @brief Initializes a UART instance with user configuration structure and peripheral clock. * @brief Initializes a UART instance with a user configuration structure and peripheral clock.
* *
* This function configures the UART module with the user-defined settings. The user can configure the configuration * 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. * structure and also get the default configuration by using the UART_GetDefaultConfig() function.
* Example below shows how to use this API to configure UART. * The example below shows how to use this API to configure UART.
* @code * @code
* uart_config_t uartConfig; * uart_config_t uartConfig;
* uartConfig.baudRate_Bps = 115200U; * uartConfig.baudRate_Bps = 115200U;
@ -229,10 +245,12 @@ extern "C" {
* @endcode * @endcode
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param config Pointer to user-defined configuration structure. * @param config Pointer to the user-defined configuration structure.
* @param srcClock_Hz UART clock source frequency in HZ. * @param srcClock_Hz UART clock source frequency in HZ.
* @retval kStatus_UART_BaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_Success Status UART initialize succeed
*/ */
void UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz); status_t UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz);
/*! /*!
* @brief Deinitializes a UART instance. * @brief Deinitializes a UART instance.
@ -247,7 +265,7 @@ void UART_Deinit(UART_Type *base);
* @brief Gets the default configuration structure. * @brief Gets the default configuration structure.
* *
* This function initializes the UART configuration structure to a default value. The default * This function initializes the UART configuration structure to a default value. The default
* values are: * values are as follows.
* uartConfig->baudRate_Bps = 115200U; * uartConfig->baudRate_Bps = 115200U;
* uartConfig->bitCountPerChar = kUART_8BitsPerChar; * uartConfig->bitCountPerChar = kUART_8BitsPerChar;
* uartConfig->parityMode = kUART_ParityDisabled; * uartConfig->parityMode = kUART_ParityDisabled;
@ -272,9 +290,11 @@ void UART_GetDefaultConfig(uart_config_t *config);
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param baudRate_Bps UART baudrate to be set. * @param baudRate_Bps UART baudrate to be set.
* @param srcClock_Hz UART clock source freqency in HZ. * @param srcClock_Hz UART clock source freqency in Hz.
* @retval kStatus_UART_BaudrateNotSupport Baudrate is not support in the current clock source.
* @retval kStatus_Success Set baudrate succeeded.
*/ */
void UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); status_t UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
/* @} */ /* @} */
@ -284,12 +304,12 @@ void UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_
*/ */
/*! /*!
* @brief Get UART status flags. * @brief Gets UART status flags.
* *
* This function get all UART status flags, the flags are returned as the logical * This function gets all UART status flags. The flags are returned as the logical
* OR value of the enumerators @ref _uart_flags. To check specific status, * OR value of the enumerators @ref _uart_flags. To check a specific status,
* compare the return value with enumerators in @ref _uart_flags. * compare the return value with enumerators in @ref _uart_flags.
* For example, to check whether the TX is empty: * For example, to check whether the TX is empty, do the following.
* @code * @code
* if (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(UART1)) * if (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(UART1))
* { * {
@ -305,19 +325,19 @@ uint32_t UART_GetStatusFlags(UART_Type *base);
/*! /*!
* @brief Clears status flags with the provided mask. * @brief Clears status flags with the provided mask.
* *
* This function clears UART status flags with a provided mask. Automatically cleared flag * This function clears UART status flags with a provided mask. An automatically cleared flag
* can't be cleared by this function. * can't be cleared by this function.
* Some flags can only be cleared or set by hardware itself. These flags are: * These flags can only be cleared or set by hardware.
* kUART_TxDataRegEmptyFlag, kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag, * kUART_TxDataRegEmptyFlag, kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag,
* kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag, kUART_ParityErrorInRxDataRegFlag, * kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag, kUART_ParityErrorInRxDataRegFlag,
* kUART_TxFifoEmptyFlag,kUART_RxFifoEmptyFlag * kUART_TxFifoEmptyFlag,kUART_RxFifoEmptyFlag
* Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects. * Note that this API should be called when the Tx/Rx is idle. Otherwise it has no effect.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param mask The status flags to be cleared, it is logical OR value of @ref _uart_flags. * @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 * @retval kStatus_UART_FlagCannotClearManually The flag can't be cleared by this function but
* it is cleared automatically by hardware. * it is cleared automatically by hardware.
* @retval kStatus_Success Status in the mask are cleared. * @retval kStatus_Success Status in the mask is cleared.
*/ */
status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask); status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask);
@ -333,7 +353,7 @@ status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask);
* *
* This function enables the UART interrupts according to the provided mask. The 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. * is a logical OR of enumeration members. See @ref _uart_interrupt_enable.
* For example, to enable TX empty interrupt and RX full interrupt: * For example, to enable TX empty interrupt and RX full interrupt, do the following.
* @code * @code
* UART_EnableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable); * UART_EnableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable);
* @endcode * @endcode
@ -348,7 +368,7 @@ void UART_EnableInterrupts(UART_Type *base, uint32_t mask);
* *
* This function disables the UART interrupts according to the provided mask. The 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. * is a logical OR of enumeration members. See @ref _uart_interrupt_enable.
* For example, to disable TX empty interrupt and RX full interrupt: * For example, to disable TX empty interrupt and RX full interrupt do the following.
* @code * @code
* UART_DisableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable); * UART_DisableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable);
* @endcode * @endcode
@ -363,9 +383,9 @@ void UART_DisableInterrupts(UART_Type *base, uint32_t mask);
* *
* This function gets the enabled UART interrupts. The enabled interrupts are returned * 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 * as the logical OR value of the enumerators @ref _uart_interrupt_enable. To check
* specific interrupts enable status, compare the return value with enumerators * a specific interrupts enable status, compare the return value with enumerators
* in @ref _uart_interrupt_enable. * in @ref _uart_interrupt_enable.
* For example, to check whether TX empty interrupt is enabled: * For example, to check whether TX empty interrupt is enabled, do the following.
* @code * @code
* uint32_t enabledInterrupts = UART_GetEnabledInterrupts(UART1); * uint32_t enabledInterrupts = UART_GetEnabledInterrupts(UART1);
* *
@ -394,7 +414,7 @@ uint32_t UART_GetEnabledInterrupts(UART_Type *base);
* This function returns the UART data register address, which is mainly used by DMA/eDMA. * This function returns the UART data register address, which is mainly used by DMA/eDMA.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @return UART data register address which are used both by transmitter and receiver. * @return UART data register addresses which are used both by the transmitter and the receiver.
*/ */
static inline uint32_t UART_GetDataRegisterAddress(UART_Type *base) static inline uint32_t UART_GetDataRegisterAddress(UART_Type *base)
{ {
@ -526,7 +546,7 @@ static inline void UART_WriteByte(UART_Type *base, uint8_t data)
/*! /*!
* @brief Reads the RX register directly. * @brief Reads the RX register directly.
* *
* This function reads data from the TX register directly. The upper layer must * This function reads data from the RX register directly. The upper layer must
* ensure that the RX register is full or that the TX FIFO has data before calling this function. * ensure that the RX register is full or that the TX FIFO has data before calling this function.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
@ -543,7 +563,7 @@ static inline uint8_t UART_ReadByte(UART_Type *base)
* This function polls the TX register, waits for the TX register to be empty or for the TX FIFO * 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. * 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. * @note This function does not check whether all data is sent out to the bus.
* Before disabling the TX, check kUART_TransmissionCompleteFlag to ensure that the TX is * Before disabling the TX, check kUART_TransmissionCompleteFlag to ensure that the TX is
* finished. * finished.
* *
@ -557,15 +577,15 @@ void UART_WriteBlocking(UART_Type *base, const uint8_t *data, size_t length);
* @brief Read RX data register using a blocking method. * @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 * 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. * have data, and reads data from the TX register.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param data Start address of the buffer to store the received data. * @param data Start address of the buffer to store the received data.
* @param length Size of the buffer. * @param length Size of the buffer.
* @retval kStatus_UART_RxHardwareOverrun Receiver overrun happened while receiving data. * @retval kStatus_UART_RxHardwareOverrun Receiver overrun occurred while receiving data.
* @retval kStatus_UART_NoiseError Noise error happened while receiving data. * @retval kStatus_UART_NoiseError A noise error occurred while receiving data.
* @retval kStatus_UART_FramingError Framing error happened while receiving data. * @retval kStatus_UART_FramingError A framing error occurred while receiving data.
* @retval kStatus_UART_ParityError Parity error happened while receiving data. * @retval kStatus_UART_ParityError A parity error occurred while receiving data.
* @retval kStatus_Success Successfully received all data. * @retval kStatus_Success Successfully received all data.
*/ */
status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length); status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length);
@ -600,16 +620,16 @@ void UART_TransferCreateHandle(UART_Type *base,
* This function sets up the RX ring buffer to a specific UART handle. * 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 * 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 * user doesn't call the UART_TransferReceiveNonBlocking() API. If data is already received
* in the ring buffer, the user can get the received data from the ring buffer directly. * 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 * @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. * words, if @p ringBufferSize is 32, only 31 bytes are used for saving data.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle UART handle pointer. * @param handle UART handle pointer.
* @param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer. * @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. * @param ringBufferSize Size of the ring buffer.
*/ */
void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize); void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize);
@ -632,23 +652,23 @@ void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle);
* function and passes the @ref kStatus_UART_TxIdle as status parameter. * 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 * @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, * to the TX register. However, it does not ensure that all data is sent out. Before disabling the TX,
* check the kUART_TransmissionCompleteFlag to ensure that the TX is finished. * check the kUART_TransmissionCompleteFlag to ensure that the TX is finished.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle UART handle pointer. * @param handle UART handle pointer.
* @param xfer UART transfer structure. See #uart_transfer_t. * @param xfer UART transfer structure. See #uart_transfer_t.
* @retval kStatus_Success Successfully start the data transmission. * @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_UART_TxBusy Previous transmission still not finished; data not all written to TX register yet.
* @retval kStatus_InvalidArgument Invalid argument. * @retval kStatus_InvalidArgument Invalid argument.
*/ */
status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer); status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer);
/*! /*!
* @brief Aborts the interrupt driven data transmit. * @brief Aborts the interrupt-driven data transmit.
* *
* This function aborts the interrupt driven data sending. The user can get the remainBytes to find out * 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. * how many bytes are not sent out.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle UART handle pointer. * @param handle UART handle pointer.
@ -656,16 +676,16 @@ status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, ua
void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle); void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle);
/*! /*!
* @brief Get the number of bytes that have been written to UART TX register. * @brief Gets the number of bytes written to the UART TX register.
* *
* This function gets the number of bytes that have been written to UART TX * This function gets the number of bytes written to the UART TX
* register by interrupt method. * register by using the interrupt method.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle UART handle pointer. * @param handle UART handle pointer.
* @param count Send bytes count. * @param count Send bytes count.
* @retval kStatus_NoTransferInProgress No send in progress. * @retval kStatus_NoTransferInProgress No send in progress.
* @retval kStatus_InvalidArgument Parameter is invalid. * @retval kStatus_InvalidArgument The parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count; * @retval kStatus_Success Get successfully through the parameter \p count;
*/ */
status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count); status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count);
@ -690,7 +710,7 @@ status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint3
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle UART handle pointer. * @param handle UART handle pointer.
* @param xfer UART transfer structure, refer to #uart_transfer_t. * @param xfer UART transfer structure, see #uart_transfer_t.
* @param receivedBytes Bytes received from the ring buffer directly. * @param receivedBytes Bytes received from the ring buffer directly.
* @retval kStatus_Success Successfully queue the transfer into transmit queue. * @retval kStatus_Success Successfully queue the transfer into transmit queue.
* @retval kStatus_UART_RxBusy Previous receive request is not finished. * @retval kStatus_UART_RxBusy Previous receive request is not finished.
@ -705,7 +725,7 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base,
* @brief Aborts the interrupt-driven data receiving. * @brief Aborts the interrupt-driven data receiving.
* *
* This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
* how many bytes not received yet. * how many bytes are not received yet.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle UART handle pointer. * @param handle UART handle pointer.
@ -713,7 +733,7 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base,
void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle); void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle);
/*! /*!
* @brief Get the number of bytes that have been received. * @brief Gets the number of bytes that have been received.
* *
* This function gets the number of bytes that have been received. * This function gets the number of bytes that have been received.
* *
@ -739,7 +759,7 @@ void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle);
/*! /*!
* @brief UART Error IRQ handle function. * @brief UART Error IRQ handle function.
* *
* This function handle the UART error IRQ request. * This function handles the UART error IRQ request.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle UART handle pointer. * @param handle UART handle pointer.

View File

@ -125,6 +125,8 @@ extern uint32_t UART_GetInstance(UART_Type *base);
static void UART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) static void UART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{ {
assert(param);
uart_edma_private_handle_t *uartPrivateHandle = (uart_edma_private_handle_t *)param; uart_edma_private_handle_t *uartPrivateHandle = (uart_edma_private_handle_t *)param;
/* Avoid the warning for unused variables. */ /* Avoid the warning for unused variables. */
@ -145,6 +147,8 @@ static void UART_SendEDMACallback(edma_handle_t *handle, void *param, bool trans
static void UART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) static void UART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{ {
assert(param);
uart_edma_private_handle_t *uartPrivateHandle = (uart_edma_private_handle_t *)param; uart_edma_private_handle_t *uartPrivateHandle = (uart_edma_private_handle_t *)param;
/* Avoid warning for unused parameters. */ /* Avoid warning for unused parameters. */
@ -165,11 +169,11 @@ static void UART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool tr
} }
void UART_TransferCreateHandleEDMA(UART_Type *base, void UART_TransferCreateHandleEDMA(UART_Type *base,
uart_edma_handle_t *handle, uart_edma_handle_t *handle,
uart_edma_transfer_callback_t callback, uart_edma_transfer_callback_t callback,
void *userData, void *userData,
edma_handle_t *txEdmaHandle, edma_handle_t *txEdmaHandle,
edma_handle_t *rxEdmaHandle) edma_handle_t *rxEdmaHandle)
{ {
assert(handle); assert(handle);
@ -219,17 +223,15 @@ void UART_TransferCreateHandleEDMA(UART_Type *base,
status_t UART_SendEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfer_t *xfer) status_t UART_SendEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfer_t *xfer)
{ {
assert(handle);
assert(handle->txEdmaHandle); assert(handle->txEdmaHandle);
assert(xfer);
assert(xfer->data);
assert(xfer->dataSize);
edma_transfer_config_t xferConfig; edma_transfer_config_t xferConfig;
status_t status; status_t status;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* If previous TX not finished. */ /* If previous TX not finished. */
if (kUART_TxBusy == handle->txState) if (kUART_TxBusy == handle->txState)
{ {
@ -244,6 +246,9 @@ status_t UART_SendEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfe
EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)UART_GetDataRegisterAddress(base), EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)UART_GetDataRegisterAddress(base),
sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_MemoryToPeripheral); sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_MemoryToPeripheral);
/* Store the initially configured eDMA minor byte transfer count into the UART handle */
handle->nbytes = sizeof(uint8_t);
/* Submit transfer. */ /* Submit transfer. */
EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig); EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig);
EDMA_StartTransfer(handle->txEdmaHandle); EDMA_StartTransfer(handle->txEdmaHandle);
@ -259,17 +264,15 @@ status_t UART_SendEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfe
status_t UART_ReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfer_t *xfer) status_t UART_ReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfer_t *xfer)
{ {
assert(handle);
assert(handle->rxEdmaHandle); assert(handle->rxEdmaHandle);
assert(xfer);
assert(xfer->data);
assert(xfer->dataSize);
edma_transfer_config_t xferConfig; edma_transfer_config_t xferConfig;
status_t status; status_t status;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* If previous RX not finished. */ /* If previous RX not finished. */
if (kUART_RxBusy == handle->rxState) if (kUART_RxBusy == handle->rxState)
{ {
@ -284,6 +287,9 @@ status_t UART_ReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_tran
EDMA_PrepareTransfer(&xferConfig, (void *)UART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data, EDMA_PrepareTransfer(&xferConfig, (void *)UART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data,
sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory); sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory);
/* Store the initially configured eDMA minor byte transfer count into the UART handle */
handle->nbytes = sizeof(uint8_t);
/* Submit transfer. */ /* Submit transfer. */
EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig); EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig);
EDMA_StartTransfer(handle->rxEdmaHandle); EDMA_StartTransfer(handle->rxEdmaHandle);
@ -299,6 +305,7 @@ status_t UART_ReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_tran
void UART_TransferAbortSendEDMA(UART_Type *base, uart_edma_handle_t *handle) void UART_TransferAbortSendEDMA(UART_Type *base, uart_edma_handle_t *handle)
{ {
assert(handle);
assert(handle->txEdmaHandle); assert(handle->txEdmaHandle);
/* Disable UART TX EDMA. */ /* Disable UART TX EDMA. */
@ -312,6 +319,7 @@ void UART_TransferAbortSendEDMA(UART_Type *base, uart_edma_handle_t *handle)
void UART_TransferAbortReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle) void UART_TransferAbortReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle)
{ {
assert(handle);
assert(handle->rxEdmaHandle); assert(handle->rxEdmaHandle);
/* Disable UART RX EDMA. */ /* Disable UART RX EDMA. */
@ -325,38 +333,36 @@ void UART_TransferAbortReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle)
status_t UART_TransferGetReceiveCountEDMA(UART_Type *base, uart_edma_handle_t *handle, uint32_t *count) status_t UART_TransferGetReceiveCountEDMA(UART_Type *base, uart_edma_handle_t *handle, uint32_t *count)
{ {
assert(handle);
assert(handle->rxEdmaHandle); assert(handle->rxEdmaHandle);
assert(count);
if (kUART_RxIdle == handle->rxState) if (kUART_RxIdle == handle->rxState)
{ {
return kStatus_NoTransferInProgress; return kStatus_NoTransferInProgress;
} }
if (!count) *count = handle->rxDataSizeAll -
{ (uint32_t)handle->nbytes *
return kStatus_InvalidArgument; EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel);
}
*count = handle->rxDataSizeAll - EDMA_GetRemainingBytes(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel);
return kStatus_Success; return kStatus_Success;
} }
status_t UART_TransferGetSendCountEDMA(UART_Type *base, uart_edma_handle_t *handle, uint32_t *count) status_t UART_TransferGetSendCountEDMA(UART_Type *base, uart_edma_handle_t *handle, uint32_t *count)
{ {
assert(handle);
assert(handle->txEdmaHandle); assert(handle->txEdmaHandle);
assert(count);
if (kUART_TxIdle == handle->txState) if (kUART_TxIdle == handle->txState)
{ {
return kStatus_NoTransferInProgress; return kStatus_NoTransferInProgress;
} }
if (!count) *count = handle->txDataSizeAll -
{ (uint32_t)handle->nbytes *
return kStatus_InvalidArgument; EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel);
}
*count = handle->txDataSizeAll - EDMA_GetRemainingBytes(handle->txEdmaHandle->base, handle->txEdmaHandle->channel);
return kStatus_Success; return kStatus_Success;
} }

View File

@ -39,8 +39,6 @@
* @{ * @{
*/ */
/*! @file*/
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
@ -67,6 +65,8 @@ struct _uart_edma_handle
edma_handle_t *txEdmaHandle; /*!< The eDMA TX channel used. */ edma_handle_t *txEdmaHandle; /*!< The eDMA TX channel used. */
edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */ edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
volatile uint8_t txState; /*!< TX transfer state. */ volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */ volatile uint8_t rxState; /*!< RX transfer state */
}; };
@ -87,18 +87,18 @@ extern "C" {
/*! /*!
* @brief Initializes the UART handle which is used in transactional functions. * @brief Initializes the UART handle which is used in transactional functions.
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle Pointer to uart_edma_handle_t structure. * @param handle Pointer to the uart_edma_handle_t structure.
* @param callback UART callback, NULL means no callback. * @param callback UART callback, NULL means no callback.
* @param userData User callback function data. * @param userData User callback function data.
* @param rxEdmaHandle User requested DMA handle for RX DMA transfer. * @param rxEdmaHandle User-requested DMA handle for RX DMA transfer.
* @param txEdmaHandle User requested DMA handle for TX DMA transfer. * @param txEdmaHandle User-requested DMA handle for TX DMA transfer.
*/ */
void UART_TransferCreateHandleEDMA(UART_Type *base, void UART_TransferCreateHandleEDMA(UART_Type *base,
uart_edma_handle_t *handle, uart_edma_handle_t *handle,
uart_edma_transfer_callback_t callback, uart_edma_transfer_callback_t callback,
void *userData, void *userData,
edma_handle_t *txEdmaHandle, edma_handle_t *txEdmaHandle,
edma_handle_t *rxEdmaHandle); edma_handle_t *rxEdmaHandle);
/*! /*!
* @brief Sends data using eDMA. * @brief Sends data using eDMA.
@ -109,23 +109,23 @@ void UART_TransferCreateHandleEDMA(UART_Type *base,
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle UART handle pointer. * @param handle UART handle pointer.
* @param xfer UART eDMA transfer structure. See #uart_transfer_t. * @param xfer UART eDMA transfer structure. See #uart_transfer_t.
* @retval kStatus_Success if succeed, others failed. * @retval kStatus_Success if succeeded; otherwise failed.
* @retval kStatus_UART_TxBusy Previous transfer on going. * @retval kStatus_UART_TxBusy Previous transfer ongoing.
* @retval kStatus_InvalidArgument Invalid argument. * @retval kStatus_InvalidArgument Invalid argument.
*/ */
status_t UART_SendEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfer_t *xfer); status_t UART_SendEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfer_t *xfer);
/*! /*!
* @brief Receive data using eDMA. * @brief Receives data using eDMA.
* *
* This function receives data using eDMA. This is a non-blocking function, which returns * This function receives data using eDMA. This is a non-blocking function, which returns
* right away. When all data is received, the receive callback function is called. * right away. When all data is received, the receive callback function is called.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle Pointer to uart_edma_handle_t structure. * @param handle Pointer to the uart_edma_handle_t structure.
* @param xfer UART eDMA transfer structure. See #uart_transfer_t. * @param xfer UART eDMA transfer structure. See #uart_transfer_t.
* @retval kStatus_Success if succeed, others failed. * @retval kStatus_Success if succeeded; otherwise failed.
* @retval kStatus_UART_RxBusy Previous transfer on going. * @retval kStatus_UART_RxBusy Previous transfer ongoing.
* @retval kStatus_InvalidArgument Invalid argument. * @retval kStatus_InvalidArgument Invalid argument.
*/ */
status_t UART_ReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfer_t *xfer); status_t UART_ReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfer_t *xfer);
@ -136,7 +136,7 @@ status_t UART_ReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_tran
* This function aborts sent data using eDMA. * This function aborts sent data using eDMA.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle Pointer to uart_edma_handle_t structure. * @param handle Pointer to the uart_edma_handle_t structure.
*/ */
void UART_TransferAbortSendEDMA(UART_Type *base, uart_edma_handle_t *handle); void UART_TransferAbortSendEDMA(UART_Type *base, uart_edma_handle_t *handle);
@ -146,12 +146,12 @@ void UART_TransferAbortSendEDMA(UART_Type *base, uart_edma_handle_t *handle);
* This function aborts receive data using eDMA. * This function aborts receive data using eDMA.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle Pointer to uart_edma_handle_t structure. * @param handle Pointer to the uart_edma_handle_t structure.
*/ */
void UART_TransferAbortReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle); void UART_TransferAbortReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle);
/*! /*!
* @brief Get the number of bytes that have been written to UART TX register. * @brief Gets 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 * This function gets the number of bytes that have been written to UART TX
* register by DMA. * register by DMA.
@ -166,9 +166,9 @@ void UART_TransferAbortReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle);
status_t UART_TransferGetSendCountEDMA(UART_Type *base, uart_edma_handle_t *handle, uint32_t *count); status_t UART_TransferGetSendCountEDMA(UART_Type *base, uart_edma_handle_t *handle, uint32_t *count);
/*! /*!
* @brief Get the number of bytes that have been received. * @brief Gets the number of received bytes.
* *
* This function gets the number of bytes that have been received. * This function gets the number of received bytes.
* *
* @param base UART peripheral base address. * @param base UART peripheral base address.
* @param handle UART handle pointer. * @param handle UART handle pointer.

View File

@ -50,8 +50,10 @@ static uint32_t VREF_GetInstance(VREF_Type *base);
/*! @brief Pointers to VREF bases for each instance. */ /*! @brief Pointers to VREF bases for each instance. */
static VREF_Type *const s_vrefBases[] = VREF_BASE_PTRS; static VREF_Type *const s_vrefBases[] = VREF_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to VREF clocks for each instance. */ /*! @brief Pointers to VREF clocks for each instance. */
static const clock_ip_name_t s_vrefClocks[] = VREF_CLOCKS; static const clock_ip_name_t s_vrefClocks[] = VREF_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/******************************************************************************* /*******************************************************************************
* Code * Code
@ -81,15 +83,24 @@ void VREF_Init(VREF_Type *base, const vref_config_t *config)
uint8_t reg = 0U; uint8_t reg = 0U;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate clock for VREF */ /* Ungate clock for VREF */
CLOCK_EnableClock(s_vrefClocks[VREF_GetInstance(base)]); CLOCK_EnableClock(s_vrefClocks[VREF_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure VREF to a known state */ /* Configure VREF to a known state */
#if defined(FSL_FEATURE_VREF_HAS_CHOP_OSC) && FSL_FEATURE_VREF_HAS_CHOP_OSC #if defined(FSL_FEATURE_VREF_HAS_CHOP_OSC) && FSL_FEATURE_VREF_HAS_CHOP_OSC
/* Set chop oscillator bit */ /* Set chop oscillator bit */
base->TRM |= VREF_TRM_CHOPEN_MASK; base->TRM |= VREF_TRM_CHOPEN_MASK;
#endif /* FSL_FEATURE_VREF_HAS_CHOP_OSC */ #endif /* FSL_FEATURE_VREF_HAS_CHOP_OSC */
/* Get current SC register */
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
reg = base->VREFH_SC;
#else
reg = base->SC; reg = base->SC;
#endif/* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */
/* Clear old buffer mode selection bits */
reg &= ~VREF_SC_MODE_LV_MASK;
/* Set buffer Mode selection and Regulator enable bit */ /* Set buffer Mode selection and Regulator enable bit */
reg |= VREF_SC_MODE_LV(config->bufferMode) | VREF_SC_REGEN(1U); reg |= VREF_SC_MODE_LV(config->bufferMode) | VREF_SC_REGEN(1U);
#if defined(FSL_FEATURE_VREF_HAS_COMPENSATION) && FSL_FEATURE_VREF_HAS_COMPENSATION #if defined(FSL_FEATURE_VREF_HAS_COMPENSATION) && FSL_FEATURE_VREF_HAS_COMPENSATION
@ -99,30 +110,51 @@ void VREF_Init(VREF_Type *base, const vref_config_t *config)
/* Enable VREF module */ /* Enable VREF module */
reg |= VREF_SC_VREFEN(1U); reg |= VREF_SC_VREFEN(1U);
/* Update bit-field from value to Status and Control register */ /* Update bit-field from value to Status and Control register */
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
base->VREFH_SC = reg;
#else
base->SC = reg; base->SC = reg;
#endif/* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE #if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
reg = base->VREFL_TRM; reg = base->VREFL_TRM;
/* Clear old select external voltage reference and VREFL (0.4 V) reference buffer enable bits*/ /* 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); 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 */ /* 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); reg |= VREF_VREFL_TRM_VREFL_SEL(config->enableExternalVoltRef) | VREF_VREFL_TRM_VREFL_EN(config->enableLowRef);
base->VREFL_TRM = reg; base->VREFL_TRM = reg;
#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ #endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */
#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4
reg = base->TRM4;
/* Clear old select internal voltage reference bit (2.1V) */
reg &= ~VREF_TRM4_VREF2V1_EN_MASK;
/* Select internal voltage reference (2.1V) */
reg |= VREF_TRM4_VREF2V1_EN(config->enable2V1VoltRef);
base->TRM4 = reg;
#endif /* FSL_FEATURE_VREF_HAS_TRM4 */
/* Wait until internal voltage stable */ /* Wait until internal voltage stable */
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
while ((base->VREFH_SC & VREF_SC_VREFST_MASK) == 0)
#else
while ((base->SC & VREF_SC_VREFST_MASK) == 0) while ((base->SC & VREF_SC_VREFST_MASK) == 0)
#endif/* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */
{ {
} }
} }
void VREF_Deinit(VREF_Type *base) void VREF_Deinit(VREF_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate clock for VREF */ /* Gate clock for VREF */
CLOCK_DisableClock(s_vrefClocks[VREF_GetInstance(base)]); CLOCK_DisableClock(s_vrefClocks[VREF_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void VREF_GetDefaultConfig(vref_config_t *config) void VREF_GetDefaultConfig(vref_config_t *config)
{ {
assert(config);
/* Set High power buffer mode in */ /* Set High power buffer mode in */
#if defined(FSL_FEATURE_VREF_MODE_LV_TYPE) && FSL_FEATURE_VREF_MODE_LV_TYPE #if defined(FSL_FEATURE_VREF_MODE_LV_TYPE) && FSL_FEATURE_VREF_MODE_LV_TYPE
config->bufferMode = kVREF_ModeHighPowerBuffer; config->bufferMode = kVREF_ModeHighPowerBuffer;
@ -136,6 +168,11 @@ void VREF_GetDefaultConfig(vref_config_t *config)
/* Set VREFL (0.4 V) reference buffer disable */ /* Set VREFL (0.4 V) reference buffer disable */
config->enableLowRef = false; config->enableLowRef = false;
#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ #endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */
#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4
/* Disable internal voltage reference (2.1V) */
config->enable2V1VoltRef = false;
#endif /* FSL_FEATURE_VREF_HAS_TRM4 */
} }
void VREF_SetTrimVal(VREF_Type *base, uint8_t trimValue) void VREF_SetTrimVal(VREF_Type *base, uint8_t trimValue)
@ -147,10 +184,30 @@ void VREF_SetTrimVal(VREF_Type *base, uint8_t trimValue)
reg = ((reg & ~VREF_TRM_TRIM_MASK) | VREF_TRM_TRIM(trimValue)); reg = ((reg & ~VREF_TRM_TRIM_MASK) | VREF_TRM_TRIM(trimValue));
base->TRM = reg; base->TRM = reg;
/* Wait until internal voltage stable */ /* Wait until internal voltage stable */
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
while ((base->VREFH_SC & VREF_SC_VREFST_MASK) == 0)
#else
while ((base->SC & VREF_SC_VREFST_MASK) == 0)
#endif/* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */
{
}
}
#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4
void VREF_SetTrim2V1Val(VREF_Type *base, uint8_t trimValue)
{
uint8_t reg = 0U;
/* Set TRIM bits value in voltage reference (2V1) */
reg = base->TRM4;
reg = ((reg & ~VREF_TRM4_TRIM2V1_MASK) | VREF_TRM4_TRIM2V1(trimValue));
base->TRM4 = reg;
/* Wait until internal voltage stable */
while ((base->SC & VREF_SC_VREFST_MASK) == 0) while ((base->SC & VREF_SC_VREFST_MASK) == 0)
{ {
} }
} }
#endif /* FSL_FEATURE_VREF_HAS_TRM4 */
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE #if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
void VREF_SetLowReferenceTrimVal(VREF_Type *base, uint8_t trimValue) void VREF_SetLowReferenceTrimVal(VREF_Type *base, uint8_t trimValue)
@ -165,7 +222,8 @@ void VREF_SetLowReferenceTrimVal(VREF_Type *base, uint8_t trimValue)
reg = ((reg & ~VREF_VREFL_TRM_VREFL_TRIM_MASK) | VREF_VREFL_TRM_VREFL_TRIM(trimValue)); reg = ((reg & ~VREF_VREFL_TRM_VREFL_TRIM_MASK) | VREF_VREFL_TRM_VREFL_TRIM(trimValue));
base->VREFL_TRM = reg; base->VREFL_TRM = reg;
/* Wait until internal voltage stable */ /* Wait until internal voltage stable */
while ((base->SC & VREF_SC_VREFST_MASK) == 0)
while ((base->VREFH_SC & VREF_SC_VREFST_MASK) == 0)
{ {
} }
} }

View File

@ -38,7 +38,6 @@
* @{ * @{
*/ */
/*! @file */
/****************************************************************************** /******************************************************************************
* Definitions * Definitions
@ -46,12 +45,11 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
#define FSL_VREF_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ #define FSL_VREF_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0. */
/*@}*/ /*@}*/
/* Those macros below defined to support SoC family which have VREFL (0.4V) reference */ /* 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 #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_MODE_LV VREF_VREFH_SC_MODE_LV
#define VREF_SC_REGEN VREF_VREFH_SC_REGEN #define VREF_SC_REGEN VREF_VREFH_SC_REGEN
#define VREF_SC_VREFEN VREF_VREFH_SC_VREFEN #define VREF_SC_VREFEN VREF_VREFH_SC_VREFEN
@ -80,8 +78,8 @@ typedef enum _vref_buffer_mode
{ {
kVREF_ModeBandgapOnly = 0U, /*!< Bandgap on only, for stabilization and startup */ kVREF_ModeBandgapOnly = 0U, /*!< Bandgap on only, for stabilization and startup */
#if defined(FSL_FEATURE_VREF_MODE_LV_TYPE) && FSL_FEATURE_VREF_MODE_LV_TYPE #if defined(FSL_FEATURE_VREF_MODE_LV_TYPE) && FSL_FEATURE_VREF_MODE_LV_TYPE
kVREF_ModeHighPowerBuffer = 1U, /*!< High power buffer mode enabled */ kVREF_ModeHighPowerBuffer = 1U, /*!< High-power buffer mode enabled */
kVREF_ModeLowPowerBuffer = 2U /*!< Low power buffer mode enabled */ kVREF_ModeLowPowerBuffer = 2U /*!< Low-power buffer mode enabled */
#else #else
kVREF_ModeTightRegulationBuffer = 2U /*!< Tight regulation buffer enabled */ kVREF_ModeTightRegulationBuffer = 2U /*!< Tight regulation buffer enabled */
#endif /* FSL_FEATURE_VREF_MODE_LV_TYPE */ #endif /* FSL_FEATURE_VREF_MODE_LV_TYPE */
@ -97,6 +95,9 @@ typedef struct _vref_config
bool enableLowRef; /*!< Set VREFL (0.4 V) reference buffer enable or disable */ bool enableLowRef; /*!< Set VREFL (0.4 V) reference buffer enable or disable */
bool enableExternalVoltRef; /*!< Select external voltage reference or not (internal) */ bool enableExternalVoltRef; /*!< Select external voltage reference or not (internal) */
#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ #endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */
#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4
bool enable2V1VoltRef; /*!< Enable Internal Voltage Reference (2.1V) */
#endif /* FSL_FEATURE_VREF_HAS_TRM4 */
} vref_config_t; } vref_config_t;
/****************************************************************************** /******************************************************************************
@ -115,11 +116,11 @@ extern "C" {
/*! /*!
* @brief Enables the clock gate and configures the VREF module according to the configuration structure. * @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, * This function must be called before calling all other VREF driver functions,
* read/write registers, and configurations with user-defined settings. * read/write registers, and configurations with user-defined settings.
* The example below shows how to set up vref_config_t parameters and * 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: * how to call the VREF_Init function by passing in these parameters.
* Example: * This is an example.
* @code * @code
* vref_config_t vrefConfig; * vref_config_t vrefConfig;
* vrefConfig.bufferMode = kVREF_ModeHighPowerBuffer; * vrefConfig.bufferMode = kVREF_ModeHighPowerBuffer;
@ -137,7 +138,7 @@ void VREF_Init(VREF_Type *base, const vref_config_t *config);
* @brief Stops and disables the clock for the VREF module. * @brief Stops and disables the clock for the VREF module.
* *
* This function should be called to shut down the module. * This function should be called to shut down the module.
* Example: * This is an example.
* @code * @code
* vref_config_t vrefUserConfig; * vref_config_t vrefUserConfig;
* VREF_Init(VREF); * VREF_Init(VREF);
@ -153,8 +154,8 @@ void VREF_Deinit(VREF_Type *base);
/*! /*!
* @brief Initializes the VREF configuration structure. * @brief Initializes the VREF configuration structure.
* *
* This function initializes the VREF configuration structure to a default value. * This function initializes the VREF configuration structure to default values.
* Example: * This is an example.
* @code * @code
* vrefConfig->bufferMode = kVREF_ModeHighPowerBuffer; * vrefConfig->bufferMode = kVREF_ModeHighPowerBuffer;
* vrefConfig->enableExternalVoltRef = false; * vrefConfig->enableExternalVoltRef = false;
@ -166,9 +167,9 @@ void VREF_Deinit(VREF_Type *base);
void VREF_GetDefaultConfig(vref_config_t *config); void VREF_GetDefaultConfig(vref_config_t *config);
/*! /*!
* @brief Sets a TRIM value for reference voltage. * @brief Sets a TRIM value for the reference voltage.
* *
* This function sets a TRIM value for reference voltage. * This function sets a TRIM value for the reference voltage.
* Note that the TRIM value maximum is 0x3F. * Note that the TRIM value maximum is 0x3F.
* *
* @param base VREF peripheral address. * @param base VREF peripheral address.
@ -188,13 +189,40 @@ static inline uint8_t VREF_GetTrimVal(VREF_Type *base)
{ {
return (base->TRM & VREF_TRM_TRIM_MASK); return (base->TRM & VREF_TRM_TRIM_MASK);
} }
#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4
/*!
* @brief Sets a TRIM value for the reference voltage (2V1).
*
* This function sets a TRIM value for the reference voltage (2V1).
* 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_SetTrim2V1Val(VREF_Type *base, uint8_t trimValue);
/*!
* @brief Reads the value of the TRIM meaning output voltage (2V1).
*
* This function gets the TRIM value from the VREF_TRM4 register.
*
* @param base VREF peripheral address.
* @return Six-bit value of trim setting.
*/
static inline uint8_t VREF_GetTrim2V1Val(VREF_Type *base)
{
return (base->TRM4 & VREF_TRM4_TRIM2V1_MASK);
}
#endif /* FSL_FEATURE_VREF_HAS_TRM4 */
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE #if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
/*! /*!
* @brief Sets the TRIM value for low voltage reference. * @brief Sets the TRIM value for the low voltage reference.
* *
* This function sets the TRIM value for low reference voltage. * This function sets the TRIM value for low reference voltage.
* NOTE: * Note the following.
* - The TRIM value maximum is 0x05U * - The TRIM value maximum is 0x05U
* - The values 111b and 110b are not valid/allowed. * - The values 111b and 110b are not valid/allowed.
* *

View File

@ -33,11 +33,10 @@
#include "fsl_common.h" #include "fsl_common.h"
/*! /*!
* @addtogroup wdog_driver * @addtogroup wdog
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -136,7 +135,7 @@ typedef struct _wdog_test_config
*/ */
enum _wdog_interrupt_enable_t enum _wdog_interrupt_enable_t
{ {
kWDOG_InterruptEnable = WDOG_STCTRLH_IRQRSTEN_MASK, /*!< WDOG timeout will generate interrupt before reset*/ kWDOG_InterruptEnable = WDOG_STCTRLH_IRQRSTEN_MASK, /*!< WDOG timeout generates an interrupt before reset*/
}; };
/*! /*!
@ -164,10 +163,10 @@ extern "C" {
*/ */
/*! /*!
* @brief Initializes WDOG configure sturcture. * @brief Initializes the WDOG configuration sturcture.
* *
* This function initializes the WDOG configure structure to default value. The default * This function initializes the WDOG configuration structure to default values. The default
* value are: * values are as follows.
* @code * @code
* wdogConfig->enableWdog = true; * wdogConfig->enableWdog = true;
* wdogConfig->clockSource = kWDOG_LpoClockSource; * wdogConfig->clockSource = kWDOG_LpoClockSource;
@ -182,7 +181,7 @@ extern "C" {
* wdogConfig->timeoutValue = 0xFFFFU; * wdogConfig->timeoutValue = 0xFFFFU;
* @endcode * @endcode
* *
* @param config Pointer to WDOG config structure. * @param config Pointer to the WDOG configuration structure.
* @see wdog_config_t * @see wdog_config_t
*/ */
void WDOG_GetDefaultConfig(wdog_config_t *config); void WDOG_GetDefaultConfig(wdog_config_t *config);
@ -191,10 +190,10 @@ void WDOG_GetDefaultConfig(wdog_config_t *config);
* @brief Initializes the WDOG. * @brief Initializes the WDOG.
* *
* This function initializes the WDOG. When called, the WDOG runs according to the configuration. * This function initializes the WDOG. When called, the WDOG runs according to the configuration.
* If user wants to reconfigure WDOG without forcing a reset first, enableUpdate must be set to true * To reconfigure WDOG without forcing a reset first, enableUpdate must be set to true
* in configuration. * in the configuration.
* *
* Example: * This is an example.
* @code * @code
* wdog_config_t config; * wdog_config_t config;
* WDOG_GetDefaultConfig(&config); * WDOG_GetDefaultConfig(&config);
@ -212,18 +211,18 @@ void WDOG_Init(WDOG_Type *base, const wdog_config_t *config);
* @brief Shuts down the WDOG. * @brief Shuts down the WDOG.
* *
* This function shuts down the WDOG. * This function shuts down the WDOG.
* Make sure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which means that the register update is enabled. * Ensure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which indicates that the register update is enabled.
*/ */
void WDOG_Deinit(WDOG_Type *base); void WDOG_Deinit(WDOG_Type *base);
/*! /*!
* @brief Configures WDOG functional test. * @brief Configures the WDOG functional test.
* *
* This function is used to configure the WDOG functional test. When called, the WDOG goes into test mode * This function is used to configure the WDOG functional test. When called, the WDOG goes into test mode
* and runs according to the configuration. * and runs according to the configuration.
* Make sure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which means that the register update is enabled. * Ensure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which means that the register update is enabled.
* *
* Example: * This is an example.
* @code * @code
* wdog_test_config_t test_config; * wdog_test_config_t test_config;
* test_config.testMode = kWDOG_QuickTest; * test_config.testMode = kWDOG_QuickTest;
@ -259,9 +258,9 @@ static inline void WDOG_Enable(WDOG_Type *base)
/*! /*!
* @brief Disables the WDOG module. * @brief Disables the WDOG module.
* *
* This function write value into WDOG_STCTRLH register to disable the WDOG, it is a write-once register, * This function writes a value into the WDOG_STCTRLH register to disable the WDOG. It is a write-once register.
* make sure that the WCT window is still open and this register has not been written in this WCT * Ensure that the WCT window is still open and that register has not been written to in this WCT
* while this function is called. * while the function is called.
* *
* @param base WDOG peripheral base address * @param base WDOG peripheral base address
*/ */
@ -271,15 +270,15 @@ static inline void WDOG_Disable(WDOG_Type *base)
} }
/*! /*!
* @brief Enable WDOG interrupt. * @brief Enables the WDOG interrupt.
* *
* This function write value into WDOG_STCTRLH register to enable WDOG interrupt, it is a write-once register, * This function writes a value into the WDOG_STCTRLH register to enable the WDOG interrupt. It is a write-once register.
* make sure that the WCT window is still open and this register has not been written in this WCT * Ensure that the WCT window is still open and the register has not been written to in this WCT
* while this function is called. * while the function is called.
* *
* @param base WDOG peripheral base address * @param base WDOG peripheral base address
* @param mask The interrupts to enable * @param mask The interrupts to enable
* The parameter can be combination of the following source if defined: * The parameter can be combination of the following source if defined.
* @arg kWDOG_InterruptEnable * @arg kWDOG_InterruptEnable
*/ */
static inline void WDOG_EnableInterrupts(WDOG_Type *base, uint32_t mask) static inline void WDOG_EnableInterrupts(WDOG_Type *base, uint32_t mask)
@ -288,15 +287,15 @@ static inline void WDOG_EnableInterrupts(WDOG_Type *base, uint32_t mask)
} }
/*! /*!
* @brief Disable WDOG interrupt. * @brief Disables the WDOG interrupt.
* *
* This function write value into WDOG_STCTRLH register to disable WDOG interrupt, it is a write-once register, * This function writes a value into the WDOG_STCTRLH register to disable the WDOG interrupt. It is a write-once register.
* make sure that the WCT window is still open and this register has not been written in this WCT * Ensure that the WCT window is still open and the register has not been written to in this WCT
* while this function is called. * while the function is called.
* *
* @param base WDOG peripheral base address * @param base WDOG peripheral base address
* @param mask The interrupts to disable * @param mask The interrupts to disable
* The parameter can be combination of the following source if defined: * The parameter can be combination of the following source if defined.
* @arg kWDOG_InterruptEnable * @arg kWDOG_InterruptEnable
*/ */
static inline void WDOG_DisableInterrupts(WDOG_Type *base, uint32_t mask) static inline void WDOG_DisableInterrupts(WDOG_Type *base, uint32_t mask)
@ -305,50 +304,50 @@ static inline void WDOG_DisableInterrupts(WDOG_Type *base, uint32_t mask)
} }
/*! /*!
* @brief Gets WDOG all status flags. * @brief Gets the WDOG all status flags.
* *
* This function gets all status flags. * This function gets all status flags.
* *
* Example for getting Running Flag: * This is an example for getting the Running Flag.
* @code * @code
* uint32_t status; * uint32_t status;
* status = WDOG_GetStatusFlags(wdog_base) & kWDOG_RunningFlag; * status = WDOG_GetStatusFlags (wdog_base) & kWDOG_RunningFlag;
* @endcode * @endcode
* @param base WDOG peripheral base address * @param base WDOG peripheral base address
* @return State of the status flag: asserted (true) or not-asserted (false).@see _wdog_status_flags_t * @return State of the status flag: asserted (true) or not-asserted (false).@see _wdog_status_flags_t
* - true: related status flag has been set. * - true: a related status flag has been set.
* - false: related status flag is not set. * - false: a related status flag is not set.
*/ */
uint32_t WDOG_GetStatusFlags(WDOG_Type *base); uint32_t WDOG_GetStatusFlags(WDOG_Type *base);
/*! /*!
* @brief Clear WDOG flag. * @brief Clears the WDOG flag.
* *
* This function clears WDOG status flag. * This function clears the WDOG status flag.
* *
* Example for clearing timeout(interrupt) flag: * This is an example for clearing the timeout (interrupt) flag.
* @code * @code
* WDOG_ClearStatusFlags(wdog_base,kWDOG_TimeoutFlag); * WDOG_ClearStatusFlags(wdog_base,kWDOG_TimeoutFlag);
* @endcode * @endcode
* @param base WDOG peripheral base address * @param base WDOG peripheral base address
* @param mask The status flags to clear. * @param mask The status flags to clear.
* The parameter could be any combination of the following values: * The parameter could be any combination of the following values.
* kWDOG_TimeoutFlag * kWDOG_TimeoutFlag
*/ */
void WDOG_ClearStatusFlags(WDOG_Type *base, uint32_t mask); void WDOG_ClearStatusFlags(WDOG_Type *base, uint32_t mask);
/*! /*!
* @brief Set the WDOG timeout value. * @brief Sets the WDOG timeout value.
* *
* This function sets the timeout value. * This function sets the timeout value.
* It should be ensured that the time-out value for the WDOG is always greater than * It should be ensured that the time-out value for the WDOG is always greater than
* 2xWCT time + 20 bus clock cycles. * 2xWCT time + 20 bus clock cycles.
* This function write value into WDOG_TOVALH and WDOG_TOVALL registers which are wirte-once. * This function writes a value into WDOG_TOVALH and WDOG_TOVALL registers which are wirte-once.
* Make sure the WCT window is still open and these two registers have not been written in this WCT * Ensure the WCT window is still open and the two registers have not been written to in this WCT
* while this function is called. * while the function is called.
* *
* @param base WDOG peripheral base address * @param base WDOG peripheral base address
* @param timeoutCount WDOG timeout value, count of WDOG clock tick. * @param timeoutCount WDOG timeout value; count of WDOG clock tick.
*/ */
static inline void WDOG_SetTimeoutValue(WDOG_Type *base, uint32_t timeoutCount) static inline void WDOG_SetTimeoutValue(WDOG_Type *base, uint32_t timeoutCount)
{ {
@ -360,9 +359,9 @@ static inline void WDOG_SetTimeoutValue(WDOG_Type *base, uint32_t timeoutCount)
* @brief Sets the WDOG window value. * @brief Sets the WDOG window value.
* *
* This function sets the WDOG window value. * This function sets the WDOG window value.
* This function write value into WDOG_WINH and WDOG_WINL registers which are wirte-once. * This function writes a value into WDOG_WINH and WDOG_WINL registers which are wirte-once.
* Make sure the WCT window is still open and these two registers have not been written in this WCT * Ensure the WCT window is still open and the two registers have not been written to in this WCT
* while this function is called. * while the function is called.
* *
* @param base WDOG peripheral base address * @param base WDOG peripheral base address
* @param windowValue WDOG window value. * @param windowValue WDOG window value.
@ -378,7 +377,7 @@ static inline void WDOG_SetWindowValue(WDOG_Type *base, uint32_t windowValue)
* *
* This function unlocks the WDOG register written. * This function unlocks the WDOG register written.
* Before starting the unlock sequence and following congfiguration, disable the global interrupts. * Before starting the unlock sequence and following congfiguration, disable the global interrupts.
* Otherwise, an interrupt could effectively invalidate the unlock sequence and the WCT may expire, * Otherwise, an interrupt may invalidate the unlocking sequence and the WCT may expire.
* After the configuration finishes, re-enable the global interrupts. * After the configuration finishes, re-enable the global interrupts.
* *
* @param base WDOG peripheral base address * @param base WDOG peripheral base address
@ -393,7 +392,7 @@ static inline void WDOG_Unlock(WDOG_Type *base)
* @brief Refreshes the WDOG timer. * @brief Refreshes the WDOG timer.
* *
* This function feeds the WDOG. * This function feeds the WDOG.
* This function should be called before WDOG timer is in timeout. Otherwise, a reset is asserted. * This function should be called before the WDOG timer is in timeout. Otherwise, a reset is asserted.
* *
* @param base WDOG peripheral base address * @param base WDOG peripheral base address
*/ */
@ -405,7 +404,7 @@ void WDOG_Refresh(WDOG_Type *base);
* This function gets the WDOG reset count value. * This function gets the WDOG reset count value.
* *
* @param base WDOG peripheral base address * @param base WDOG peripheral base address
* @return WDOG reset count value * @return WDOG reset count value.
*/ */
static inline uint16_t WDOG_GetResetCount(WDOG_Type *base) static inline uint16_t WDOG_GetResetCount(WDOG_Type *base)
{ {