mirror of https://github.com/ARMmbed/mbed-os.git
Added Kinetis K64 support
Use Kinetis SDK 2.0. Moved this to TARGET_NXP Signed-off-by: Mahadevan Mahesh <Mahesh.Mahadevan@nxp.com>pull/1700/head
parent
acb896b3cb
commit
2c9c632aad
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,130 @@
|
|||
#! armcc -E
|
||||
/*
|
||||
** ###################################################################
|
||||
** Processors: MK64FN1M0VDC12
|
||||
** MK64FN1M0VLL12
|
||||
** MK64FN1M0VLQ12
|
||||
** MK64FN1M0VMD12
|
||||
**
|
||||
** Compiler: Keil ARM C/C++ Compiler
|
||||
** Reference manual: K64P144M120SF5RM, Rev.2, January 2014
|
||||
** Version: rev. 2.8, 2015-02-19
|
||||
** Build: b151009
|
||||
**
|
||||
** Abstract:
|
||||
** Linker file for the Keil ARM C/C++ Compiler
|
||||
**
|
||||
** Copyright (c) 2015 Freescale Semiconductor, Inc.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
** o Redistributions of source code must retain the above copyright notice, this list
|
||||
** of conditions and the following disclaimer.
|
||||
**
|
||||
** o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
** list of conditions and the following disclaimer in the documentation and/or
|
||||
** other materials provided with the distribution.
|
||||
**
|
||||
** o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
** contributors may be used to endorse or promote products derived from this
|
||||
** software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** http: www.freescale.com
|
||||
** mail: support@freescale.com
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
#define __ram_vector_table__ 1
|
||||
|
||||
/* Heap 1/4 of ram and stack 1/8 */
|
||||
#define __stack_size__ 0x8000
|
||||
#define __heap_size__ 0x10000
|
||||
|
||||
#if (defined(__ram_vector_table__))
|
||||
#define __ram_vector_table_size__ 0x00000400
|
||||
#else
|
||||
#define __ram_vector_table_size__ 0x00000000
|
||||
#endif
|
||||
|
||||
#define m_interrupts_start 0x00000000
|
||||
#define m_interrupts_size 0x00000400
|
||||
|
||||
#define m_flash_config_start 0x00000400
|
||||
#define m_flash_config_size 0x00000010
|
||||
|
||||
#define m_text_start 0x00000410
|
||||
#define m_text_size 0x000FFBF0
|
||||
|
||||
#define m_interrupts_ram_start 0x1FFF0000
|
||||
#define m_interrupts_ram_size __ram_vector_table_size__
|
||||
|
||||
#define m_data_start (m_interrupts_ram_start + m_interrupts_ram_size)
|
||||
#define m_data_size (0x00010000 - m_interrupts_ram_size)
|
||||
|
||||
#define m_data_2_start 0x20000000
|
||||
#define m_data_2_size 0x00030000
|
||||
|
||||
/* Sizes */
|
||||
#if (defined(__stack_size__))
|
||||
#define Stack_Size __stack_size__
|
||||
#else
|
||||
#define Stack_Size 0x0400
|
||||
#endif
|
||||
|
||||
#if (defined(__heap_size__))
|
||||
#define Heap_Size __heap_size__
|
||||
#else
|
||||
#define Heap_Size 0x0400
|
||||
#endif
|
||||
|
||||
LR_m_text m_text_start m_text_size { ; load region size_region
|
||||
ER_m_text m_text_start m_text_size { ; load address = execution address
|
||||
* (InRoot$$Sections)
|
||||
.ANY (+RO)
|
||||
}
|
||||
RW_m_data m_data_start m_data_size { ; RW data
|
||||
.ANY (+RW +ZI)
|
||||
}
|
||||
RW_m_data_2 m_data_2_start m_data_2_size-Stack_Size-Heap_Size { ; RW data
|
||||
.ANY (+RW +ZI)
|
||||
}
|
||||
RW_IRAM1 ((ImageLimit(RW_m_data_2) == m_data_2_start) ? ImageLimit(RW_m_data) : +0) EMPTY Heap_Size { ; Heap region growing up
|
||||
}
|
||||
}
|
||||
|
||||
LR_m_interrupts m_interrupts_start m_interrupts_size {
|
||||
#if (!defined(__ram_vector_table__))
|
||||
VECTOR_RAM m_interrupts_start EMPTY 0 {
|
||||
}
|
||||
#endif
|
||||
VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address
|
||||
* (RESET,+FIRST)
|
||||
}
|
||||
}
|
||||
|
||||
LR_m_flash_config m_flash_config_start m_flash_config_size {
|
||||
ER_m_flash_config m_flash_config_start m_flash_config_size { ; load address = execution address
|
||||
* (FlashConfig)
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined(__ram_vector_table__))
|
||||
LR_m_interrupts_ram m_interrupts_ram_start m_interrupts_ram_size {
|
||||
VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
|||
/* mbed Microcontroller Library - stackheap
|
||||
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* Setup a fixed single stack/heap memory model,
|
||||
* between the top of the RW/ZI region and the stackpointer
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <rt_misc.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern char Image$$RW_IRAM1$$ZI$$Limit[];
|
||||
|
||||
extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
|
||||
uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit;
|
||||
uint32_t sp_limit = __current_sp();
|
||||
|
||||
zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
|
||||
|
||||
struct __initial_stackheap r;
|
||||
r.heap_base = zi_limit;
|
||||
r.heap_limit = sp_limit;
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
** ###################################################################
|
||||
** Processors: MK64FN1M0VDC12
|
||||
** MK64FN1M0VLL12
|
||||
** MK64FN1M0VLQ12
|
||||
** MK64FN1M0VMD12
|
||||
**
|
||||
** Compiler: GNU C Compiler
|
||||
** Reference manual: K64P144M120SF5RM, Rev.2, January 2014
|
||||
** Version: rev. 2.8, 2015-02-19
|
||||
** Build: b151217
|
||||
**
|
||||
** Abstract:
|
||||
** Linker file for the GNU C Compiler
|
||||
**
|
||||
** Copyright (c) 2015 Freescale Semiconductor, Inc.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
** o Redistributions of source code must retain the above copyright notice, this list
|
||||
** of conditions and the following disclaimer.
|
||||
**
|
||||
** o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
** list of conditions and the following disclaimer in the documentation and/or
|
||||
** other materials provided with the distribution.
|
||||
**
|
||||
** o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
** contributors may be used to endorse or promote products derived from this
|
||||
** software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** http: www.freescale.com
|
||||
** mail: support@freescale.com
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
/* Entry Point */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
__ram_vector_table__ = 1;
|
||||
|
||||
/* Heap 1/4 of ram and stack 1/8 */
|
||||
__stack_size__ = 0x8000;
|
||||
__heap_size__ = 0x10000;
|
||||
|
||||
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
|
||||
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;
|
||||
M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x0400 : 0x0;
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000400
|
||||
m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
|
||||
m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x000FFBF0
|
||||
m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000
|
||||
m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00030000
|
||||
}
|
||||
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
/* The startup code goes first into internal flash */
|
||||
.interrupts :
|
||||
{
|
||||
__VECTOR_TABLE = .;
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} > m_interrupts
|
||||
|
||||
.flash_config :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */
|
||||
. = ALIGN(4);
|
||||
} > m_flash_config
|
||||
|
||||
/* The program code and other data goes into internal flash */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
*(.glue_7) /* glue arm to thumb code */
|
||||
*(.glue_7t) /* glue thumb to arm code */
|
||||
*(.eh_frame)
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
. = ALIGN(4);
|
||||
} > m_text
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} > m_text
|
||||
|
||||
.ARM :
|
||||
{
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} > m_text
|
||||
|
||||
.ctors :
|
||||
{
|
||||
__CTOR_LIST__ = .;
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
from the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
__CTOR_END__ = .;
|
||||
} > m_text
|
||||
|
||||
.dtors :
|
||||
{
|
||||
__DTOR_LIST__ = .;
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
__DTOR_END__ = .;
|
||||
} > m_text
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array*))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} > m_text
|
||||
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array*))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
} > m_text
|
||||
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array*))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} > m_text
|
||||
|
||||
__etext = .; /* define a global symbol at end of code */
|
||||
__DATA_ROM = .; /* Symbol is used by startup for data initialization */
|
||||
|
||||
.interrupts_ram :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__VECTOR_RAM__ = .;
|
||||
__interrupts_ram_start__ = .; /* Create a global symbol at data start */
|
||||
*(.m_interrupts_ram) /* This is a user defined section */
|
||||
. += M_VECTOR_RAM_SIZE;
|
||||
. = ALIGN(4);
|
||||
__interrupts_ram_end__ = .; /* Define a global symbol at data end */
|
||||
} > m_data
|
||||
|
||||
__VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts);
|
||||
__RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0;
|
||||
|
||||
.data : AT(__DATA_ROM)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__DATA_RAM = .;
|
||||
__data_start__ = .; /* create a global symbol at data start */
|
||||
*(.data) /* .data sections */
|
||||
*(.data*) /* .data* sections */
|
||||
KEEP(*(.jcr*))
|
||||
. = ALIGN(4);
|
||||
__data_end__ = .; /* define a global symbol at data end */
|
||||
} > m_data
|
||||
|
||||
__DATA_END = __DATA_ROM + (__data_end__ - __data_start__);
|
||||
text_end = ORIGIN(m_text) + LENGTH(m_text);
|
||||
ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")
|
||||
|
||||
USB_RAM_GAP = DEFINED(__usb_ram_size__) ? __usb_ram_size__ : 0x800;
|
||||
/* Uninitialized data section */
|
||||
.bss :
|
||||
{
|
||||
/* This is used by the startup in order to initialize the .bss section */
|
||||
. = ALIGN(4);
|
||||
__START_BSS = .;
|
||||
__bss_start__ = .;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
. = ALIGN(512);
|
||||
USB_RAM_START = .;
|
||||
. += USB_RAM_GAP;
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
__END_BSS = .;
|
||||
} > m_data
|
||||
|
||||
.heap :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
__end__ = .;
|
||||
PROVIDE(end = .);
|
||||
__HeapBase = .;
|
||||
. += HEAP_SIZE;
|
||||
__HeapLimit = .;
|
||||
__heap_limit = .; /* Add for _sbrk */
|
||||
} > m_data_2
|
||||
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
. += STACK_SIZE;
|
||||
} > m_data_2
|
||||
|
||||
m_usb_bdt USB_RAM_START (NOLOAD) :
|
||||
{
|
||||
*(m_usb_bdt)
|
||||
USB_RAM_BDT_END = .;
|
||||
}
|
||||
|
||||
m_usb_global USB_RAM_BDT_END (NOLOAD) :
|
||||
{
|
||||
*(m_usb_global)
|
||||
}
|
||||
|
||||
/* Initializes stack on the end of block */
|
||||
__StackTop = ORIGIN(m_data_2) + LENGTH(m_data_2);
|
||||
__StackLimit = __StackTop - STACK_SIZE;
|
||||
PROVIDE(__stack = __StackTop);
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
|
||||
ASSERT(__StackLimit >= __HeapLimit, "region m_data_2 overflowed with stack and heap")
|
||||
}
|
||||
|
|
@ -0,0 +1,993 @@
|
|||
/* ---------------------------------------------------------------------------------------*/
|
||||
/* @file: startup_MK64F12.s */
|
||||
/* @purpose: CMSIS Cortex-M4 Core Device Startup File */
|
||||
/* MK64F12 */
|
||||
/* @version: 2.8 */
|
||||
/* @date: 2015-2-19 */
|
||||
/* @build: b151210 */
|
||||
/* ---------------------------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Copyright (c) 1997 - 2015 , Freescale Semiconductor, Inc. */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* Redistribution and use in source and binary forms, with or without modification, */
|
||||
/* are permitted provided that the following conditions are met: */
|
||||
/* */
|
||||
/* o Redistributions of source code must retain the above copyright notice, this list */
|
||||
/* of conditions and the following disclaimer. */
|
||||
/* */
|
||||
/* o Redistributions in binary form must reproduce the above copyright notice, this */
|
||||
/* list of conditions and the following disclaimer in the documentation and/or */
|
||||
/* other materials provided with the distribution. */
|
||||
/* */
|
||||
/* o Neither the name of Freescale Semiconductor, Inc. nor the names of its */
|
||||
/* contributors may be used to endorse or promote products derived from this */
|
||||
/* software without specific prior written permission. */
|
||||
/* */
|
||||
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
|
||||
/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
|
||||
/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
|
||||
/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
|
||||
/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
|
||||
/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
|
||||
/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
|
||||
/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
|
||||
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
|
||||
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||
/*****************************************************************************/
|
||||
/* Version: GCC for ARM Embedded Processors */
|
||||
/*****************************************************************************/
|
||||
.syntax unified
|
||||
.arch armv7-m
|
||||
|
||||
.section .isr_vector, "a"
|
||||
.align 2
|
||||
.globl __isr_vector
|
||||
__isr_vector:
|
||||
.long __StackTop /* Top of Stack */
|
||||
.long Reset_Handler /* Reset Handler */
|
||||
.long NMI_Handler /* NMI Handler*/
|
||||
.long HardFault_Handler /* Hard Fault Handler*/
|
||||
.long MemManage_Handler /* MPU Fault Handler*/
|
||||
.long BusFault_Handler /* Bus Fault Handler*/
|
||||
.long UsageFault_Handler /* Usage Fault Handler*/
|
||||
.long 0 /* Reserved*/
|
||||
.long 0 /* Reserved*/
|
||||
.long 0 /* Reserved*/
|
||||
.long 0 /* Reserved*/
|
||||
.long SVC_Handler /* SVCall Handler*/
|
||||
.long DebugMon_Handler /* Debug Monitor Handler*/
|
||||
.long 0 /* Reserved*/
|
||||
.long PendSV_Handler /* PendSV Handler*/
|
||||
.long SysTick_Handler /* SysTick Handler*/
|
||||
|
||||
/* External Interrupts*/
|
||||
.long DMA0_IRQHandler /* DMA Channel 0 Transfer Complete*/
|
||||
.long DMA1_IRQHandler /* DMA Channel 1 Transfer Complete*/
|
||||
.long DMA2_IRQHandler /* DMA Channel 2 Transfer Complete*/
|
||||
.long DMA3_IRQHandler /* DMA Channel 3 Transfer Complete*/
|
||||
.long DMA4_IRQHandler /* DMA Channel 4 Transfer Complete*/
|
||||
.long DMA5_IRQHandler /* DMA Channel 5 Transfer Complete*/
|
||||
.long DMA6_IRQHandler /* DMA Channel 6 Transfer Complete*/
|
||||
.long DMA7_IRQHandler /* DMA Channel 7 Transfer Complete*/
|
||||
.long DMA8_IRQHandler /* DMA Channel 8 Transfer Complete*/
|
||||
.long DMA9_IRQHandler /* DMA Channel 9 Transfer Complete*/
|
||||
.long DMA10_IRQHandler /* DMA Channel 10 Transfer Complete*/
|
||||
.long DMA11_IRQHandler /* DMA Channel 11 Transfer Complete*/
|
||||
.long DMA12_IRQHandler /* DMA Channel 12 Transfer Complete*/
|
||||
.long DMA13_IRQHandler /* DMA Channel 13 Transfer Complete*/
|
||||
.long DMA14_IRQHandler /* DMA Channel 14 Transfer Complete*/
|
||||
.long DMA15_IRQHandler /* DMA Channel 15 Transfer Complete*/
|
||||
.long DMA_Error_IRQHandler /* DMA Error Interrupt*/
|
||||
.long MCM_IRQHandler /* Normal Interrupt*/
|
||||
.long FTFE_IRQHandler /* FTFE Command complete interrupt*/
|
||||
.long Read_Collision_IRQHandler /* Read Collision Interrupt*/
|
||||
.long LVD_LVW_IRQHandler /* Low Voltage Detect, Low Voltage Warning*/
|
||||
.long LLWU_IRQHandler /* Low Leakage Wakeup Unit*/
|
||||
.long WDOG_EWM_IRQHandler /* WDOG Interrupt*/
|
||||
.long RNG_IRQHandler /* RNG Interrupt*/
|
||||
.long I2C0_IRQHandler /* I2C0 interrupt*/
|
||||
.long I2C1_IRQHandler /* I2C1 interrupt*/
|
||||
.long SPI0_IRQHandler /* SPI0 Interrupt*/
|
||||
.long SPI1_IRQHandler /* SPI1 Interrupt*/
|
||||
.long I2S0_Tx_IRQHandler /* I2S0 transmit interrupt*/
|
||||
.long I2S0_Rx_IRQHandler /* I2S0 receive interrupt*/
|
||||
.long UART0_LON_IRQHandler /* UART0 LON interrupt*/
|
||||
.long UART0_RX_TX_IRQHandler /* UART0 Receive/Transmit interrupt*/
|
||||
.long UART0_ERR_IRQHandler /* UART0 Error interrupt*/
|
||||
.long UART1_RX_TX_IRQHandler /* UART1 Receive/Transmit interrupt*/
|
||||
.long UART1_ERR_IRQHandler /* UART1 Error interrupt*/
|
||||
.long UART2_RX_TX_IRQHandler /* UART2 Receive/Transmit interrupt*/
|
||||
.long UART2_ERR_IRQHandler /* UART2 Error interrupt*/
|
||||
.long UART3_RX_TX_IRQHandler /* UART3 Receive/Transmit interrupt*/
|
||||
.long UART3_ERR_IRQHandler /* UART3 Error interrupt*/
|
||||
.long ADC0_IRQHandler /* ADC0 interrupt*/
|
||||
.long CMP0_IRQHandler /* CMP0 interrupt*/
|
||||
.long CMP1_IRQHandler /* CMP1 interrupt*/
|
||||
.long FTM0_IRQHandler /* FTM0 fault, overflow and channels interrupt*/
|
||||
.long FTM1_IRQHandler /* FTM1 fault, overflow and channels interrupt*/
|
||||
.long FTM2_IRQHandler /* FTM2 fault, overflow and channels interrupt*/
|
||||
.long CMT_IRQHandler /* CMT interrupt*/
|
||||
.long RTC_IRQHandler /* RTC interrupt*/
|
||||
.long RTC_Seconds_IRQHandler /* RTC seconds interrupt*/
|
||||
.long PIT0_IRQHandler /* PIT timer channel 0 interrupt*/
|
||||
.long PIT1_IRQHandler /* PIT timer channel 1 interrupt*/
|
||||
.long PIT2_IRQHandler /* PIT timer channel 2 interrupt*/
|
||||
.long PIT3_IRQHandler /* PIT timer channel 3 interrupt*/
|
||||
.long PDB0_IRQHandler /* PDB0 Interrupt*/
|
||||
.long USB0_IRQHandler /* USB0 interrupt*/
|
||||
.long USBDCD_IRQHandler /* USBDCD Interrupt*/
|
||||
.long Reserved71_IRQHandler /* Reserved interrupt 71*/
|
||||
.long DAC0_IRQHandler /* DAC0 interrupt*/
|
||||
.long MCG_IRQHandler /* MCG Interrupt*/
|
||||
.long LPTMR0_IRQHandler /* LPTimer interrupt*/
|
||||
.long PORTA_IRQHandler /* Port A interrupt*/
|
||||
.long PORTB_IRQHandler /* Port B interrupt*/
|
||||
.long PORTC_IRQHandler /* Port C interrupt*/
|
||||
.long PORTD_IRQHandler /* Port D interrupt*/
|
||||
.long PORTE_IRQHandler /* Port E interrupt*/
|
||||
.long SWI_IRQHandler /* Software interrupt*/
|
||||
.long SPI2_IRQHandler /* SPI2 Interrupt*/
|
||||
.long UART4_RX_TX_IRQHandler /* UART4 Receive/Transmit interrupt*/
|
||||
.long UART4_ERR_IRQHandler /* UART4 Error interrupt*/
|
||||
.long UART5_RX_TX_IRQHandler /* UART5 Receive/Transmit interrupt*/
|
||||
.long UART5_ERR_IRQHandler /* UART5 Error interrupt*/
|
||||
.long CMP2_IRQHandler /* CMP2 interrupt*/
|
||||
.long FTM3_IRQHandler /* FTM3 fault, overflow and channels interrupt*/
|
||||
.long DAC1_IRQHandler /* DAC1 interrupt*/
|
||||
.long ADC1_IRQHandler /* ADC1 interrupt*/
|
||||
.long I2C2_IRQHandler /* I2C2 interrupt*/
|
||||
.long CAN0_ORed_Message_buffer_IRQHandler /* CAN0 OR'd message buffers interrupt*/
|
||||
.long CAN0_Bus_Off_IRQHandler /* CAN0 bus off interrupt*/
|
||||
.long CAN0_Error_IRQHandler /* CAN0 error interrupt*/
|
||||
.long CAN0_Tx_Warning_IRQHandler /* CAN0 Tx warning interrupt*/
|
||||
.long CAN0_Rx_Warning_IRQHandler /* CAN0 Rx warning interrupt*/
|
||||
.long CAN0_Wake_Up_IRQHandler /* CAN0 wake up interrupt*/
|
||||
.long SDHC_IRQHandler /* SDHC interrupt*/
|
||||
.long ENET_1588_Timer_IRQHandler /* Ethernet MAC IEEE 1588 Timer Interrupt*/
|
||||
.long ENET_Transmit_IRQHandler /* Ethernet MAC Transmit Interrupt*/
|
||||
.long ENET_Receive_IRQHandler /* Ethernet MAC Receive Interrupt*/
|
||||
.long ENET_Error_IRQHandler /* Ethernet MAC Error and miscelaneous Interrupt*/
|
||||
.long DefaultISR /* 102*/
|
||||
.long DefaultISR /* 103*/
|
||||
.long DefaultISR /* 104*/
|
||||
.long DefaultISR /* 105*/
|
||||
.long DefaultISR /* 106*/
|
||||
.long DefaultISR /* 107*/
|
||||
.long DefaultISR /* 108*/
|
||||
.long DefaultISR /* 109*/
|
||||
.long DefaultISR /* 110*/
|
||||
.long DefaultISR /* 111*/
|
||||
.long DefaultISR /* 112*/
|
||||
.long DefaultISR /* 113*/
|
||||
.long DefaultISR /* 114*/
|
||||
.long DefaultISR /* 115*/
|
||||
.long DefaultISR /* 116*/
|
||||
.long DefaultISR /* 117*/
|
||||
.long DefaultISR /* 118*/
|
||||
.long DefaultISR /* 119*/
|
||||
.long DefaultISR /* 120*/
|
||||
.long DefaultISR /* 121*/
|
||||
.long DefaultISR /* 122*/
|
||||
.long DefaultISR /* 123*/
|
||||
.long DefaultISR /* 124*/
|
||||
.long DefaultISR /* 125*/
|
||||
.long DefaultISR /* 126*/
|
||||
.long DefaultISR /* 127*/
|
||||
.long DefaultISR /* 128*/
|
||||
.long DefaultISR /* 129*/
|
||||
.long DefaultISR /* 130*/
|
||||
.long DefaultISR /* 131*/
|
||||
.long DefaultISR /* 132*/
|
||||
.long DefaultISR /* 133*/
|
||||
.long DefaultISR /* 134*/
|
||||
.long DefaultISR /* 135*/
|
||||
.long DefaultISR /* 136*/
|
||||
.long DefaultISR /* 137*/
|
||||
.long DefaultISR /* 138*/
|
||||
.long DefaultISR /* 139*/
|
||||
.long DefaultISR /* 140*/
|
||||
.long DefaultISR /* 141*/
|
||||
.long DefaultISR /* 142*/
|
||||
.long DefaultISR /* 143*/
|
||||
.long DefaultISR /* 144*/
|
||||
.long DefaultISR /* 145*/
|
||||
.long DefaultISR /* 146*/
|
||||
.long DefaultISR /* 147*/
|
||||
.long DefaultISR /* 148*/
|
||||
.long DefaultISR /* 149*/
|
||||
.long DefaultISR /* 150*/
|
||||
.long DefaultISR /* 151*/
|
||||
.long DefaultISR /* 152*/
|
||||
.long DefaultISR /* 153*/
|
||||
.long DefaultISR /* 154*/
|
||||
.long DefaultISR /* 155*/
|
||||
.long DefaultISR /* 156*/
|
||||
.long DefaultISR /* 157*/
|
||||
.long DefaultISR /* 158*/
|
||||
.long DefaultISR /* 159*/
|
||||
.long DefaultISR /* 160*/
|
||||
.long DefaultISR /* 161*/
|
||||
.long DefaultISR /* 162*/
|
||||
.long DefaultISR /* 163*/
|
||||
.long DefaultISR /* 164*/
|
||||
.long DefaultISR /* 165*/
|
||||
.long DefaultISR /* 166*/
|
||||
.long DefaultISR /* 167*/
|
||||
.long DefaultISR /* 168*/
|
||||
.long DefaultISR /* 169*/
|
||||
.long DefaultISR /* 170*/
|
||||
.long DefaultISR /* 171*/
|
||||
.long DefaultISR /* 172*/
|
||||
.long DefaultISR /* 173*/
|
||||
.long DefaultISR /* 174*/
|
||||
.long DefaultISR /* 175*/
|
||||
.long DefaultISR /* 176*/
|
||||
.long DefaultISR /* 177*/
|
||||
.long DefaultISR /* 178*/
|
||||
.long DefaultISR /* 179*/
|
||||
.long DefaultISR /* 180*/
|
||||
.long DefaultISR /* 181*/
|
||||
.long DefaultISR /* 182*/
|
||||
.long DefaultISR /* 183*/
|
||||
.long DefaultISR /* 184*/
|
||||
.long DefaultISR /* 185*/
|
||||
.long DefaultISR /* 186*/
|
||||
.long DefaultISR /* 187*/
|
||||
.long DefaultISR /* 188*/
|
||||
.long DefaultISR /* 189*/
|
||||
.long DefaultISR /* 190*/
|
||||
.long DefaultISR /* 191*/
|
||||
.long DefaultISR /* 192*/
|
||||
.long DefaultISR /* 193*/
|
||||
.long DefaultISR /* 194*/
|
||||
.long DefaultISR /* 195*/
|
||||
.long DefaultISR /* 196*/
|
||||
.long DefaultISR /* 197*/
|
||||
.long DefaultISR /* 198*/
|
||||
.long DefaultISR /* 199*/
|
||||
.long DefaultISR /* 200*/
|
||||
.long DefaultISR /* 201*/
|
||||
.long DefaultISR /* 202*/
|
||||
.long DefaultISR /* 203*/
|
||||
.long DefaultISR /* 204*/
|
||||
.long DefaultISR /* 205*/
|
||||
.long DefaultISR /* 206*/
|
||||
.long DefaultISR /* 207*/
|
||||
.long DefaultISR /* 208*/
|
||||
.long DefaultISR /* 209*/
|
||||
.long DefaultISR /* 210*/
|
||||
.long DefaultISR /* 211*/
|
||||
.long DefaultISR /* 212*/
|
||||
.long DefaultISR /* 213*/
|
||||
.long DefaultISR /* 214*/
|
||||
.long DefaultISR /* 215*/
|
||||
.long DefaultISR /* 216*/
|
||||
.long DefaultISR /* 217*/
|
||||
.long DefaultISR /* 218*/
|
||||
.long DefaultISR /* 219*/
|
||||
.long DefaultISR /* 220*/
|
||||
.long DefaultISR /* 221*/
|
||||
.long DefaultISR /* 222*/
|
||||
.long DefaultISR /* 223*/
|
||||
.long DefaultISR /* 224*/
|
||||
.long DefaultISR /* 225*/
|
||||
.long DefaultISR /* 226*/
|
||||
.long DefaultISR /* 227*/
|
||||
.long DefaultISR /* 228*/
|
||||
.long DefaultISR /* 229*/
|
||||
.long DefaultISR /* 230*/
|
||||
.long DefaultISR /* 231*/
|
||||
.long DefaultISR /* 232*/
|
||||
.long DefaultISR /* 233*/
|
||||
.long DefaultISR /* 234*/
|
||||
.long DefaultISR /* 235*/
|
||||
.long DefaultISR /* 236*/
|
||||
.long DefaultISR /* 237*/
|
||||
.long DefaultISR /* 238*/
|
||||
.long DefaultISR /* 239*/
|
||||
.long DefaultISR /* 240*/
|
||||
.long DefaultISR /* 241*/
|
||||
.long DefaultISR /* 242*/
|
||||
.long DefaultISR /* 243*/
|
||||
.long DefaultISR /* 244*/
|
||||
.long DefaultISR /* 245*/
|
||||
.long DefaultISR /* 246*/
|
||||
.long DefaultISR /* 247*/
|
||||
.long DefaultISR /* 248*/
|
||||
.long DefaultISR /* 249*/
|
||||
.long DefaultISR /* 250*/
|
||||
.long DefaultISR /* 251*/
|
||||
.long DefaultISR /* 252*/
|
||||
.long DefaultISR /* 253*/
|
||||
.long DefaultISR /* 254*/
|
||||
.long 0xFFFFFFFF /* Reserved for user TRIM value*/
|
||||
|
||||
.size __isr_vector, . - __isr_vector
|
||||
|
||||
/* Flash Configuration */
|
||||
.section .FlashConfig, "a"
|
||||
.long 0xFFFFFFFF
|
||||
.long 0xFFFFFFFF
|
||||
.long 0xFFFFFFFF
|
||||
.long 0xFFFFFFFE
|
||||
|
||||
.text
|
||||
.thumb
|
||||
|
||||
/* Reset Handler */
|
||||
|
||||
.thumb_func
|
||||
.align 2
|
||||
.globl Reset_Handler
|
||||
.weak Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
cpsid i /* Mask interrupts */
|
||||
.equ VTOR, 0xE000ED08
|
||||
ldr r0, =VTOR
|
||||
ldr r1, =__isr_vector
|
||||
str r1, [r0]
|
||||
#ifndef __NO_SYSTEM_INIT
|
||||
ldr r0,=SystemInit
|
||||
blx r0
|
||||
#endif
|
||||
/* Loop to copy data from read only memory to RAM. The ranges
|
||||
* of copy from/to are specified by following symbols evaluated in
|
||||
* linker script.
|
||||
* __etext: End of code section, i.e., begin of data sections to copy from.
|
||||
* __data_start__/__data_end__: RAM address range that data should be
|
||||
* copied to. Both must be aligned to 4 bytes boundary. */
|
||||
|
||||
ldr r1, =__etext
|
||||
ldr r2, =__data_start__
|
||||
ldr r3, =__data_end__
|
||||
|
||||
#if 1
|
||||
/* Here are two copies of loop implemenations. First one favors code size
|
||||
* and the second one favors performance. Default uses the first one.
|
||||
* Change to "#if 0" to use the second one */
|
||||
.LC0:
|
||||
cmp r2, r3
|
||||
ittt lt
|
||||
ldrlt r0, [r1], #4
|
||||
strlt r0, [r2], #4
|
||||
blt .LC0
|
||||
#else
|
||||
subs r3, r2
|
||||
ble .LC1
|
||||
.LC0:
|
||||
subs r3, #4
|
||||
ldr r0, [r1, r3]
|
||||
str r0, [r2, r3]
|
||||
bgt .LC0
|
||||
.LC1:
|
||||
#endif
|
||||
|
||||
#ifdef __STARTUP_CLEAR_BSS
|
||||
/* This part of work usually is done in C library startup code. Otherwise,
|
||||
* define this macro to enable it in this startup.
|
||||
*
|
||||
* Loop to zero out BSS section, which uses following symbols
|
||||
* in linker script:
|
||||
* __bss_start__: start of BSS section. Must align to 4
|
||||
* __bss_end__: end of BSS section. Must align to 4
|
||||
*/
|
||||
ldr r1, =__bss_start__
|
||||
ldr r2, =__bss_end__
|
||||
|
||||
movs r0, 0
|
||||
.LC2:
|
||||
cmp r1, r2
|
||||
itt lt
|
||||
strlt r0, [r1], #4
|
||||
blt .LC2
|
||||
#endif /* __STARTUP_CLEAR_BSS */
|
||||
|
||||
cpsie i /* Unmask interrupts */
|
||||
#ifndef __START
|
||||
#define __START _start
|
||||
#endif
|
||||
#ifndef __ATOLLIC__
|
||||
ldr r0,=__START
|
||||
blx r0
|
||||
#else
|
||||
ldr r0,=__libc_init_array
|
||||
blx r0
|
||||
ldr r0,=main
|
||||
bx r0
|
||||
#endif
|
||||
.pool
|
||||
.size Reset_Handler, . - Reset_Handler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DefaultISR
|
||||
.type DefaultISR, %function
|
||||
DefaultISR:
|
||||
b DefaultISR
|
||||
.size DefaultISR, . - DefaultISR
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak NMI_Handler
|
||||
.type NMI_Handler, %function
|
||||
NMI_Handler:
|
||||
ldr r0,=NMI_Handler
|
||||
bx r0
|
||||
.size NMI_Handler, . - NMI_Handler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak HardFault_Handler
|
||||
.type HardFault_Handler, %function
|
||||
HardFault_Handler:
|
||||
ldr r0,=HardFault_Handler
|
||||
bx r0
|
||||
.size HardFault_Handler, . - HardFault_Handler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak SVC_Handler
|
||||
.type SVC_Handler, %function
|
||||
SVC_Handler:
|
||||
ldr r0,=SVC_Handler
|
||||
bx r0
|
||||
.size SVC_Handler, . - SVC_Handler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak PendSV_Handler
|
||||
.type PendSV_Handler, %function
|
||||
PendSV_Handler:
|
||||
ldr r0,=PendSV_Handler
|
||||
bx r0
|
||||
.size PendSV_Handler, . - PendSV_Handler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak SysTick_Handler
|
||||
.type SysTick_Handler, %function
|
||||
SysTick_Handler:
|
||||
ldr r0,=SysTick_Handler
|
||||
bx r0
|
||||
.size SysTick_Handler, . - SysTick_Handler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA0_IRQHandler
|
||||
.type DMA0_IRQHandler, %function
|
||||
DMA0_IRQHandler:
|
||||
ldr r0,=DMA0_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA0_IRQHandler, . - DMA0_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA1_IRQHandler
|
||||
.type DMA1_IRQHandler, %function
|
||||
DMA1_IRQHandler:
|
||||
ldr r0,=DMA1_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA1_IRQHandler, . - DMA1_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA2_IRQHandler
|
||||
.type DMA2_IRQHandler, %function
|
||||
DMA2_IRQHandler:
|
||||
ldr r0,=DMA2_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA2_IRQHandler, . - DMA2_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA3_IRQHandler
|
||||
.type DMA3_IRQHandler, %function
|
||||
DMA3_IRQHandler:
|
||||
ldr r0,=DMA3_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA3_IRQHandler, . - DMA3_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA4_IRQHandler
|
||||
.type DMA4_IRQHandler, %function
|
||||
DMA4_IRQHandler:
|
||||
ldr r0,=DMA4_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA4_IRQHandler, . - DMA4_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA5_IRQHandler
|
||||
.type DMA5_IRQHandler, %function
|
||||
DMA5_IRQHandler:
|
||||
ldr r0,=DMA5_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA5_IRQHandler, . - DMA5_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA6_IRQHandler
|
||||
.type DMA6_IRQHandler, %function
|
||||
DMA6_IRQHandler:
|
||||
ldr r0,=DMA6_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA6_IRQHandler, . - DMA6_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA7_IRQHandler
|
||||
.type DMA7_IRQHandler, %function
|
||||
DMA7_IRQHandler:
|
||||
ldr r0,=DMA7_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA7_IRQHandler, . - DMA7_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA8_IRQHandler
|
||||
.type DMA8_IRQHandler, %function
|
||||
DMA8_IRQHandler:
|
||||
ldr r0,=DMA8_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA8_IRQHandler, . - DMA8_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA9_IRQHandler
|
||||
.type DMA9_IRQHandler, %function
|
||||
DMA9_IRQHandler:
|
||||
ldr r0,=DMA9_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA9_IRQHandler, . - DMA9_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA10_IRQHandler
|
||||
.type DMA10_IRQHandler, %function
|
||||
DMA10_IRQHandler:
|
||||
ldr r0,=DMA10_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA10_IRQHandler, . - DMA10_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA11_IRQHandler
|
||||
.type DMA11_IRQHandler, %function
|
||||
DMA11_IRQHandler:
|
||||
ldr r0,=DMA11_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA11_IRQHandler, . - DMA11_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA12_IRQHandler
|
||||
.type DMA12_IRQHandler, %function
|
||||
DMA12_IRQHandler:
|
||||
ldr r0,=DMA12_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA12_IRQHandler, . - DMA12_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA13_IRQHandler
|
||||
.type DMA13_IRQHandler, %function
|
||||
DMA13_IRQHandler:
|
||||
ldr r0,=DMA13_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA13_IRQHandler, . - DMA13_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA14_IRQHandler
|
||||
.type DMA14_IRQHandler, %function
|
||||
DMA14_IRQHandler:
|
||||
ldr r0,=DMA14_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA14_IRQHandler, . - DMA14_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA15_IRQHandler
|
||||
.type DMA15_IRQHandler, %function
|
||||
DMA15_IRQHandler:
|
||||
ldr r0,=DMA15_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA15_IRQHandler, . - DMA15_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak DMA_Error_IRQHandler
|
||||
.type DMA_Error_IRQHandler, %function
|
||||
DMA_Error_IRQHandler:
|
||||
ldr r0,=DMA_Error_DriverIRQHandler
|
||||
bx r0
|
||||
.size DMA_Error_IRQHandler, . - DMA_Error_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak I2C0_IRQHandler
|
||||
.type I2C0_IRQHandler, %function
|
||||
I2C0_IRQHandler:
|
||||
ldr r0,=I2C0_DriverIRQHandler
|
||||
bx r0
|
||||
.size I2C0_IRQHandler, . - I2C0_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak I2C1_IRQHandler
|
||||
.type I2C1_IRQHandler, %function
|
||||
I2C1_IRQHandler:
|
||||
ldr r0,=I2C1_DriverIRQHandler
|
||||
bx r0
|
||||
.size I2C1_IRQHandler, . - I2C1_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak SPI0_IRQHandler
|
||||
.type SPI0_IRQHandler, %function
|
||||
SPI0_IRQHandler:
|
||||
ldr r0,=SPI0_DriverIRQHandler
|
||||
bx r0
|
||||
.size SPI0_IRQHandler, . - SPI0_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak SPI1_IRQHandler
|
||||
.type SPI1_IRQHandler, %function
|
||||
SPI1_IRQHandler:
|
||||
ldr r0,=SPI1_DriverIRQHandler
|
||||
bx r0
|
||||
.size SPI1_IRQHandler, . - SPI1_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak I2S0_Tx_IRQHandler
|
||||
.type I2S0_Tx_IRQHandler, %function
|
||||
I2S0_Tx_IRQHandler:
|
||||
ldr r0,=I2S0_Tx_DriverIRQHandler
|
||||
bx r0
|
||||
.size I2S0_Tx_IRQHandler, . - I2S0_Tx_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak I2S0_Rx_IRQHandler
|
||||
.type I2S0_Rx_IRQHandler, %function
|
||||
I2S0_Rx_IRQHandler:
|
||||
ldr r0,=I2S0_Rx_DriverIRQHandler
|
||||
bx r0
|
||||
.size I2S0_Rx_IRQHandler, . - I2S0_Rx_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART0_LON_IRQHandler
|
||||
.type UART0_LON_IRQHandler, %function
|
||||
UART0_LON_IRQHandler:
|
||||
ldr r0,=UART0_LON_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART0_LON_IRQHandler, . - UART0_LON_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART0_RX_TX_IRQHandler
|
||||
.type UART0_RX_TX_IRQHandler, %function
|
||||
UART0_RX_TX_IRQHandler:
|
||||
ldr r0,=UART0_RX_TX_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART0_RX_TX_IRQHandler, . - UART0_RX_TX_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART0_ERR_IRQHandler
|
||||
.type UART0_ERR_IRQHandler, %function
|
||||
UART0_ERR_IRQHandler:
|
||||
ldr r0,=UART0_ERR_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART0_ERR_IRQHandler, . - UART0_ERR_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART1_RX_TX_IRQHandler
|
||||
.type UART1_RX_TX_IRQHandler, %function
|
||||
UART1_RX_TX_IRQHandler:
|
||||
ldr r0,=UART1_RX_TX_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART1_RX_TX_IRQHandler, . - UART1_RX_TX_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART1_ERR_IRQHandler
|
||||
.type UART1_ERR_IRQHandler, %function
|
||||
UART1_ERR_IRQHandler:
|
||||
ldr r0,=UART1_ERR_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART1_ERR_IRQHandler, . - UART1_ERR_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART2_RX_TX_IRQHandler
|
||||
.type UART2_RX_TX_IRQHandler, %function
|
||||
UART2_RX_TX_IRQHandler:
|
||||
ldr r0,=UART2_RX_TX_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART2_RX_TX_IRQHandler, . - UART2_RX_TX_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART2_ERR_IRQHandler
|
||||
.type UART2_ERR_IRQHandler, %function
|
||||
UART2_ERR_IRQHandler:
|
||||
ldr r0,=UART2_ERR_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART2_ERR_IRQHandler, . - UART2_ERR_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART3_RX_TX_IRQHandler
|
||||
.type UART3_RX_TX_IRQHandler, %function
|
||||
UART3_RX_TX_IRQHandler:
|
||||
ldr r0,=UART3_RX_TX_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART3_RX_TX_IRQHandler, . - UART3_RX_TX_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART3_ERR_IRQHandler
|
||||
.type UART3_ERR_IRQHandler, %function
|
||||
UART3_ERR_IRQHandler:
|
||||
ldr r0,=UART3_ERR_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART3_ERR_IRQHandler, . - UART3_ERR_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak SPI2_IRQHandler
|
||||
.type SPI2_IRQHandler, %function
|
||||
SPI2_IRQHandler:
|
||||
ldr r0,=SPI2_DriverIRQHandler
|
||||
bx r0
|
||||
.size SPI2_IRQHandler, . - SPI2_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART4_RX_TX_IRQHandler
|
||||
.type UART4_RX_TX_IRQHandler, %function
|
||||
UART4_RX_TX_IRQHandler:
|
||||
ldr r0,=UART4_RX_TX_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART4_RX_TX_IRQHandler, . - UART4_RX_TX_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART4_ERR_IRQHandler
|
||||
.type UART4_ERR_IRQHandler, %function
|
||||
UART4_ERR_IRQHandler:
|
||||
ldr r0,=UART4_ERR_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART4_ERR_IRQHandler, . - UART4_ERR_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART5_RX_TX_IRQHandler
|
||||
.type UART5_RX_TX_IRQHandler, %function
|
||||
UART5_RX_TX_IRQHandler:
|
||||
ldr r0,=UART5_RX_TX_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART5_RX_TX_IRQHandler, . - UART5_RX_TX_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak UART5_ERR_IRQHandler
|
||||
.type UART5_ERR_IRQHandler, %function
|
||||
UART5_ERR_IRQHandler:
|
||||
ldr r0,=UART5_ERR_DriverIRQHandler
|
||||
bx r0
|
||||
.size UART5_ERR_IRQHandler, . - UART5_ERR_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak I2C2_IRQHandler
|
||||
.type I2C2_IRQHandler, %function
|
||||
I2C2_IRQHandler:
|
||||
ldr r0,=I2C2_DriverIRQHandler
|
||||
bx r0
|
||||
.size I2C2_IRQHandler, . - I2C2_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak CAN0_ORed_Message_buffer_IRQHandler
|
||||
.type CAN0_ORed_Message_buffer_IRQHandler, %function
|
||||
CAN0_ORed_Message_buffer_IRQHandler:
|
||||
ldr r0,=CAN0_DriverIRQHandler
|
||||
bx r0
|
||||
.size CAN0_ORed_Message_buffer_IRQHandler, . - CAN0_ORed_Message_buffer_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak CAN0_Bus_Off_IRQHandler
|
||||
.type CAN0_Bus_Off_IRQHandler, %function
|
||||
CAN0_Bus_Off_IRQHandler:
|
||||
ldr r0,=CAN0_DriverIRQHandler
|
||||
bx r0
|
||||
.size CAN0_Bus_Off_IRQHandler, . - CAN0_Bus_Off_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak CAN0_Error_IRQHandler
|
||||
.type CAN0_Error_IRQHandler, %function
|
||||
CAN0_Error_IRQHandler:
|
||||
ldr r0,=CAN0_DriverIRQHandler
|
||||
bx r0
|
||||
.size CAN0_Error_IRQHandler, . - CAN0_Error_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak CAN0_Tx_Warning_IRQHandler
|
||||
.type CAN0_Tx_Warning_IRQHandler, %function
|
||||
CAN0_Tx_Warning_IRQHandler:
|
||||
ldr r0,=CAN0_DriverIRQHandler
|
||||
bx r0
|
||||
.size CAN0_Tx_Warning_IRQHandler, . - CAN0_Tx_Warning_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak CAN0_Rx_Warning_IRQHandler
|
||||
.type CAN0_Rx_Warning_IRQHandler, %function
|
||||
CAN0_Rx_Warning_IRQHandler:
|
||||
ldr r0,=CAN0_DriverIRQHandler
|
||||
bx r0
|
||||
.size CAN0_Rx_Warning_IRQHandler, . - CAN0_Rx_Warning_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak CAN0_Wake_Up_IRQHandler
|
||||
.type CAN0_Wake_Up_IRQHandler, %function
|
||||
CAN0_Wake_Up_IRQHandler:
|
||||
ldr r0,=CAN0_DriverIRQHandler
|
||||
bx r0
|
||||
.size CAN0_Wake_Up_IRQHandler, . - CAN0_Wake_Up_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak SDHC_IRQHandler
|
||||
.type SDHC_IRQHandler, %function
|
||||
SDHC_IRQHandler:
|
||||
ldr r0,=SDHC_DriverIRQHandler
|
||||
bx r0
|
||||
.size SDHC_IRQHandler, . - SDHC_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak ENET_1588_Timer_IRQHandler
|
||||
.type ENET_1588_Timer_IRQHandler, %function
|
||||
ENET_1588_Timer_IRQHandler:
|
||||
ldr r0,=ENET_1588_Timer_DriverIRQHandler
|
||||
bx r0
|
||||
.size ENET_1588_Timer_IRQHandler, . - ENET_1588_Timer_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak ENET_Transmit_IRQHandler
|
||||
.type ENET_Transmit_IRQHandler, %function
|
||||
ENET_Transmit_IRQHandler:
|
||||
ldr r0,=ENET_Transmit_DriverIRQHandler
|
||||
bx r0
|
||||
.size ENET_Transmit_IRQHandler, . - ENET_Transmit_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak ENET_Receive_IRQHandler
|
||||
.type ENET_Receive_IRQHandler, %function
|
||||
ENET_Receive_IRQHandler:
|
||||
ldr r0,=ENET_Receive_DriverIRQHandler
|
||||
bx r0
|
||||
.size ENET_Receive_IRQHandler, . - ENET_Receive_IRQHandler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak ENET_Error_IRQHandler
|
||||
.type ENET_Error_IRQHandler, %function
|
||||
ENET_Error_IRQHandler:
|
||||
ldr r0,=ENET_Error_DriverIRQHandler
|
||||
bx r0
|
||||
.size ENET_Error_IRQHandler, . - ENET_Error_IRQHandler
|
||||
|
||||
|
||||
/* Macro to define default handlers. Default handler
|
||||
* will be weak symbol and just dead loops. They can be
|
||||
* overwritten by other handlers */
|
||||
.macro def_irq_handler handler_name
|
||||
.weak \handler_name
|
||||
.set \handler_name, DefaultISR
|
||||
.endm
|
||||
|
||||
/* Exception Handlers */
|
||||
def_irq_handler MemManage_Handler
|
||||
def_irq_handler BusFault_Handler
|
||||
def_irq_handler UsageFault_Handler
|
||||
def_irq_handler DebugMon_Handler
|
||||
def_irq_handler DMA0_DriverIRQHandler
|
||||
def_irq_handler DMA1_DriverIRQHandler
|
||||
def_irq_handler DMA2_DriverIRQHandler
|
||||
def_irq_handler DMA3_DriverIRQHandler
|
||||
def_irq_handler DMA4_DriverIRQHandler
|
||||
def_irq_handler DMA5_DriverIRQHandler
|
||||
def_irq_handler DMA6_DriverIRQHandler
|
||||
def_irq_handler DMA7_DriverIRQHandler
|
||||
def_irq_handler DMA8_DriverIRQHandler
|
||||
def_irq_handler DMA9_DriverIRQHandler
|
||||
def_irq_handler DMA10_DriverIRQHandler
|
||||
def_irq_handler DMA11_DriverIRQHandler
|
||||
def_irq_handler DMA12_DriverIRQHandler
|
||||
def_irq_handler DMA13_DriverIRQHandler
|
||||
def_irq_handler DMA14_DriverIRQHandler
|
||||
def_irq_handler DMA15_DriverIRQHandler
|
||||
def_irq_handler DMA_Error_DriverIRQHandler
|
||||
def_irq_handler MCM_IRQHandler
|
||||
def_irq_handler FTFE_IRQHandler
|
||||
def_irq_handler Read_Collision_IRQHandler
|
||||
def_irq_handler LVD_LVW_IRQHandler
|
||||
def_irq_handler LLWU_IRQHandler
|
||||
def_irq_handler WDOG_EWM_IRQHandler
|
||||
def_irq_handler RNG_IRQHandler
|
||||
def_irq_handler I2C0_DriverIRQHandler
|
||||
def_irq_handler I2C1_DriverIRQHandler
|
||||
def_irq_handler SPI0_DriverIRQHandler
|
||||
def_irq_handler SPI1_DriverIRQHandler
|
||||
def_irq_handler I2S0_Tx_DriverIRQHandler
|
||||
def_irq_handler I2S0_Rx_DriverIRQHandler
|
||||
def_irq_handler UART0_LON_DriverIRQHandler
|
||||
def_irq_handler UART0_RX_TX_DriverIRQHandler
|
||||
def_irq_handler UART0_ERR_DriverIRQHandler
|
||||
def_irq_handler UART1_RX_TX_DriverIRQHandler
|
||||
def_irq_handler UART1_ERR_DriverIRQHandler
|
||||
def_irq_handler UART2_RX_TX_DriverIRQHandler
|
||||
def_irq_handler UART2_ERR_DriverIRQHandler
|
||||
def_irq_handler UART3_RX_TX_DriverIRQHandler
|
||||
def_irq_handler UART3_ERR_DriverIRQHandler
|
||||
def_irq_handler ADC0_IRQHandler
|
||||
def_irq_handler CMP0_IRQHandler
|
||||
def_irq_handler CMP1_IRQHandler
|
||||
def_irq_handler FTM0_IRQHandler
|
||||
def_irq_handler FTM1_IRQHandler
|
||||
def_irq_handler FTM2_IRQHandler
|
||||
def_irq_handler CMT_IRQHandler
|
||||
def_irq_handler RTC_IRQHandler
|
||||
def_irq_handler RTC_Seconds_IRQHandler
|
||||
def_irq_handler PIT0_IRQHandler
|
||||
def_irq_handler PIT1_IRQHandler
|
||||
def_irq_handler PIT2_IRQHandler
|
||||
def_irq_handler PIT3_IRQHandler
|
||||
def_irq_handler PDB0_IRQHandler
|
||||
def_irq_handler USB0_IRQHandler
|
||||
def_irq_handler USBDCD_IRQHandler
|
||||
def_irq_handler Reserved71_IRQHandler
|
||||
def_irq_handler DAC0_IRQHandler
|
||||
def_irq_handler MCG_IRQHandler
|
||||
def_irq_handler LPTMR0_IRQHandler
|
||||
def_irq_handler PORTA_IRQHandler
|
||||
def_irq_handler PORTB_IRQHandler
|
||||
def_irq_handler PORTC_IRQHandler
|
||||
def_irq_handler PORTD_IRQHandler
|
||||
def_irq_handler PORTE_IRQHandler
|
||||
def_irq_handler SWI_IRQHandler
|
||||
def_irq_handler SPI2_DriverIRQHandler
|
||||
def_irq_handler UART4_RX_TX_DriverIRQHandler
|
||||
def_irq_handler UART4_ERR_DriverIRQHandler
|
||||
def_irq_handler UART5_RX_TX_DriverIRQHandler
|
||||
def_irq_handler UART5_ERR_DriverIRQHandler
|
||||
def_irq_handler CMP2_IRQHandler
|
||||
def_irq_handler FTM3_IRQHandler
|
||||
def_irq_handler DAC1_IRQHandler
|
||||
def_irq_handler ADC1_IRQHandler
|
||||
def_irq_handler I2C2_DriverIRQHandler
|
||||
def_irq_handler CAN0_DriverIRQHandler
|
||||
def_irq_handler SDHC_DriverIRQHandler
|
||||
def_irq_handler ENET_1588_Timer_DriverIRQHandler
|
||||
def_irq_handler ENET_Transmit_DriverIRQHandler
|
||||
def_irq_handler ENET_Receive_DriverIRQHandler
|
||||
def_irq_handler ENET_Error_DriverIRQHandler
|
||||
|
||||
.end
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
** ###################################################################
|
||||
** Processors: MK64FN1M0VDC12
|
||||
** MK64FN1M0VLL12
|
||||
** MK64FN1M0VLQ12
|
||||
** MK64FN1M0VMD12
|
||||
**
|
||||
** Compiler: IAR ANSI C/C++ Compiler for ARM
|
||||
** Reference manual: K64P144M120SF5RM, Rev.2, January 2014
|
||||
** Version: rev. 2.8, 2015-02-19
|
||||
** Build: b151009
|
||||
**
|
||||
** Abstract:
|
||||
** Linker file for the IAR ANSI C/C++ Compiler for ARM
|
||||
**
|
||||
** Copyright (c) 2015 Freescale Semiconductor, Inc.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
** o Redistributions of source code must retain the above copyright notice, this list
|
||||
** of conditions and the following disclaimer.
|
||||
**
|
||||
** o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
** list of conditions and the following disclaimer in the documentation and/or
|
||||
** other materials provided with the distribution.
|
||||
**
|
||||
** o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
** contributors may be used to endorse or promote products derived from this
|
||||
** software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** http: www.freescale.com
|
||||
** mail: support@freescale.com
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
define symbol __ram_vector_table__ = 1;
|
||||
|
||||
/* Heap 1/4 of ram and stack 1/8 */
|
||||
define symbol __stack_size__=0x8000;
|
||||
define symbol __heap_size__=0x10000;
|
||||
|
||||
define symbol __ram_vector_table_size__ = isdefinedsymbol(__ram_vector_table__) ? 0x00000400 : 0;
|
||||
define symbol __ram_vector_table_offset__ = isdefinedsymbol(__ram_vector_table__) ? 0x000003FF : 0;
|
||||
|
||||
define symbol m_interrupts_start = 0x00000000;
|
||||
define symbol m_interrupts_end = 0x000003FF;
|
||||
|
||||
define symbol m_flash_config_start = 0x00000400;
|
||||
define symbol m_flash_config_end = 0x0000040F;
|
||||
|
||||
define symbol m_text_start = 0x00000410;
|
||||
define symbol m_text_end = 0x000FFFFF;
|
||||
|
||||
define symbol m_interrupts_ram_start = 0x1FFF0000;
|
||||
define symbol m_interrupts_ram_end = 0x1FFF0000 + __ram_vector_table_offset__;
|
||||
|
||||
define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__;
|
||||
define symbol m_data_end = 0x1FFFFFFF;
|
||||
|
||||
define symbol m_data_2_start = 0x20000000;
|
||||
define symbol m_data_2_end = 0x2002FFFF;
|
||||
|
||||
/* Sizes */
|
||||
if (isdefinedsymbol(__stack_size__)) {
|
||||
define symbol __size_cstack__ = __stack_size__;
|
||||
} else {
|
||||
define symbol __size_cstack__ = 0x0400;
|
||||
}
|
||||
|
||||
if (isdefinedsymbol(__heap_size__)) {
|
||||
define symbol __size_heap__ = __heap_size__;
|
||||
} else {
|
||||
define symbol __size_heap__ = 0x0400;
|
||||
}
|
||||
|
||||
define exported symbol __VECTOR_TABLE = m_interrupts_start;
|
||||
define exported symbol __VECTOR_RAM = isdefinedsymbol(__ram_vector_table__) ? m_interrupts_ram_start : m_interrupts_start;
|
||||
define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__;
|
||||
|
||||
define memory mem with size = 4G;
|
||||
define region m_flash_config_region = mem:[from m_flash_config_start to m_flash_config_end];
|
||||
define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end]
|
||||
| mem:[from m_text_start to m_text_end];
|
||||
define region DATA_region = mem:[from m_data_start to m_data_end]
|
||||
| mem:[from m_data_2_start to m_data_2_end-__size_cstack__];
|
||||
define region CSTACK_region = mem:[from m_data_2_end-__size_cstack__+1 to m_data_2_end];
|
||||
define region m_interrupts_ram_region = mem:[from m_interrupts_ram_start to m_interrupts_ram_end];
|
||||
|
||||
define block CSTACK with alignment = 8, size = __size_cstack__ { };
|
||||
define block HEAP with alignment = 8, size = __size_heap__ { };
|
||||
define block RW { readwrite };
|
||||
define block ZI { zi };
|
||||
|
||||
initialize by copy { readwrite, section .textrw };
|
||||
do not initialize { section .noinit };
|
||||
|
||||
place at address mem: m_interrupts_start { readonly section .intvec };
|
||||
place in m_flash_config_region { section FlashConfig };
|
||||
place in TEXT_region { readonly };
|
||||
place in DATA_region { block RW };
|
||||
place in DATA_region { block ZI };
|
||||
place in DATA_region { last block HEAP };
|
||||
place in CSTACK_region { block CSTACK };
|
||||
place in m_interrupts_ram_region { section m_interrupts_ram };
|
||||
|
|
@ -0,0 +1,870 @@
|
|||
; ---------------------------------------------------------------------------------------
|
||||
; @file: startup_MK64F12.s
|
||||
; @purpose: CMSIS Cortex-M4 Core Device Startup File
|
||||
; MK64F12
|
||||
; @version: 2.8
|
||||
; @date: 2015-2-19
|
||||
; @build: b151210
|
||||
; ---------------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 1997 - 2015 , Freescale Semiconductor, Inc.
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without modification,
|
||||
; are permitted provided that the following conditions are met:
|
||||
;
|
||||
; o Redistributions of source code must retain the above copyright notice, this list
|
||||
; of conditions and the following disclaimer.
|
||||
;
|
||||
; o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
; list of conditions and the following disclaimer in the documentation and/or
|
||||
; other materials provided with the distribution.
|
||||
;
|
||||
; o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
; contributors may be used to endorse or promote products derived from this
|
||||
; software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
; ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
; ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;
|
||||
; The modules in this file are included in the libraries, and may be replaced
|
||||
; by any user-defined modules that define the PUBLIC symbol _program_start or
|
||||
; a user defined start symbol.
|
||||
; To override the cstartup defined in the library, simply add your modified
|
||||
; version to the workbench project.
|
||||
;
|
||||
; The vector table is normally located at address 0.
|
||||
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
|
||||
; The name "__vector_table" has special meaning for C-SPY:
|
||||
; it is where the SP start value is found, and the NVIC vector
|
||||
; table register (VTOR) is initialized to this address if != 0.
|
||||
;
|
||||
; Cortex-M version
|
||||
;
|
||||
|
||||
MODULE ?cstartup
|
||||
|
||||
;; Forward declaration of sections.
|
||||
SECTION CSTACK:DATA:NOROOT(3)
|
||||
|
||||
SECTION .intvec:CODE:NOROOT(2)
|
||||
|
||||
EXTERN __iar_program_start
|
||||
EXTERN SystemInit
|
||||
PUBLIC __vector_table
|
||||
PUBLIC __vector_table_0x1c
|
||||
PUBLIC __Vectors
|
||||
PUBLIC __Vectors_End
|
||||
PUBLIC __Vectors_Size
|
||||
|
||||
DATA
|
||||
|
||||
__vector_table
|
||||
DCD sfe(CSTACK)
|
||||
DCD Reset_Handler
|
||||
|
||||
DCD NMI_Handler ;NMI Handler
|
||||
DCD HardFault_Handler ;Hard Fault Handler
|
||||
DCD MemManage_Handler ;MPU Fault Handler
|
||||
DCD BusFault_Handler ;Bus Fault Handler
|
||||
DCD UsageFault_Handler ;Usage Fault Handler
|
||||
__vector_table_0x1c
|
||||
DCD 0 ;Reserved
|
||||
DCD 0 ;Reserved
|
||||
DCD 0 ;Reserved
|
||||
DCD 0 ;Reserved
|
||||
DCD SVC_Handler ;SVCall Handler
|
||||
DCD DebugMon_Handler ;Debug Monitor Handler
|
||||
DCD 0 ;Reserved
|
||||
DCD PendSV_Handler ;PendSV Handler
|
||||
DCD SysTick_Handler ;SysTick Handler
|
||||
|
||||
;External Interrupts
|
||||
DCD DMA0_IRQHandler ;DMA Channel 0 Transfer Complete
|
||||
DCD DMA1_IRQHandler ;DMA Channel 1 Transfer Complete
|
||||
DCD DMA2_IRQHandler ;DMA Channel 2 Transfer Complete
|
||||
DCD DMA3_IRQHandler ;DMA Channel 3 Transfer Complete
|
||||
DCD DMA4_IRQHandler ;DMA Channel 4 Transfer Complete
|
||||
DCD DMA5_IRQHandler ;DMA Channel 5 Transfer Complete
|
||||
DCD DMA6_IRQHandler ;DMA Channel 6 Transfer Complete
|
||||
DCD DMA7_IRQHandler ;DMA Channel 7 Transfer Complete
|
||||
DCD DMA8_IRQHandler ;DMA Channel 8 Transfer Complete
|
||||
DCD DMA9_IRQHandler ;DMA Channel 9 Transfer Complete
|
||||
DCD DMA10_IRQHandler ;DMA Channel 10 Transfer Complete
|
||||
DCD DMA11_IRQHandler ;DMA Channel 11 Transfer Complete
|
||||
DCD DMA12_IRQHandler ;DMA Channel 12 Transfer Complete
|
||||
DCD DMA13_IRQHandler ;DMA Channel 13 Transfer Complete
|
||||
DCD DMA14_IRQHandler ;DMA Channel 14 Transfer Complete
|
||||
DCD DMA15_IRQHandler ;DMA Channel 15 Transfer Complete
|
||||
DCD DMA_Error_IRQHandler ;DMA Error Interrupt
|
||||
DCD MCM_IRQHandler ;Normal Interrupt
|
||||
DCD FTFE_IRQHandler ;FTFE Command complete interrupt
|
||||
DCD Read_Collision_IRQHandler ;Read Collision Interrupt
|
||||
DCD LVD_LVW_IRQHandler ;Low Voltage Detect, Low Voltage Warning
|
||||
DCD LLWU_IRQHandler ;Low Leakage Wakeup Unit
|
||||
DCD WDOG_EWM_IRQHandler ;WDOG Interrupt
|
||||
DCD RNG_IRQHandler ;RNG Interrupt
|
||||
DCD I2C0_IRQHandler ;I2C0 interrupt
|
||||
DCD I2C1_IRQHandler ;I2C1 interrupt
|
||||
DCD SPI0_IRQHandler ;SPI0 Interrupt
|
||||
DCD SPI1_IRQHandler ;SPI1 Interrupt
|
||||
DCD I2S0_Tx_IRQHandler ;I2S0 transmit interrupt
|
||||
DCD I2S0_Rx_IRQHandler ;I2S0 receive interrupt
|
||||
DCD UART0_LON_IRQHandler ;UART0 LON interrupt
|
||||
DCD UART0_RX_TX_IRQHandler ;UART0 Receive/Transmit interrupt
|
||||
DCD UART0_ERR_IRQHandler ;UART0 Error interrupt
|
||||
DCD UART1_RX_TX_IRQHandler ;UART1 Receive/Transmit interrupt
|
||||
DCD UART1_ERR_IRQHandler ;UART1 Error interrupt
|
||||
DCD UART2_RX_TX_IRQHandler ;UART2 Receive/Transmit interrupt
|
||||
DCD UART2_ERR_IRQHandler ;UART2 Error interrupt
|
||||
DCD UART3_RX_TX_IRQHandler ;UART3 Receive/Transmit interrupt
|
||||
DCD UART3_ERR_IRQHandler ;UART3 Error interrupt
|
||||
DCD ADC0_IRQHandler ;ADC0 interrupt
|
||||
DCD CMP0_IRQHandler ;CMP0 interrupt
|
||||
DCD CMP1_IRQHandler ;CMP1 interrupt
|
||||
DCD FTM0_IRQHandler ;FTM0 fault, overflow and channels interrupt
|
||||
DCD FTM1_IRQHandler ;FTM1 fault, overflow and channels interrupt
|
||||
DCD FTM2_IRQHandler ;FTM2 fault, overflow and channels interrupt
|
||||
DCD CMT_IRQHandler ;CMT interrupt
|
||||
DCD RTC_IRQHandler ;RTC interrupt
|
||||
DCD RTC_Seconds_IRQHandler ;RTC seconds interrupt
|
||||
DCD PIT0_IRQHandler ;PIT timer channel 0 interrupt
|
||||
DCD PIT1_IRQHandler ;PIT timer channel 1 interrupt
|
||||
DCD PIT2_IRQHandler ;PIT timer channel 2 interrupt
|
||||
DCD PIT3_IRQHandler ;PIT timer channel 3 interrupt
|
||||
DCD PDB0_IRQHandler ;PDB0 Interrupt
|
||||
DCD USB0_IRQHandler ;USB0 interrupt
|
||||
DCD USBDCD_IRQHandler ;USBDCD Interrupt
|
||||
DCD Reserved71_IRQHandler ;Reserved interrupt 71
|
||||
DCD DAC0_IRQHandler ;DAC0 interrupt
|
||||
DCD MCG_IRQHandler ;MCG Interrupt
|
||||
DCD LPTMR0_IRQHandler ;LPTimer interrupt
|
||||
DCD PORTA_IRQHandler ;Port A interrupt
|
||||
DCD PORTB_IRQHandler ;Port B interrupt
|
||||
DCD PORTC_IRQHandler ;Port C interrupt
|
||||
DCD PORTD_IRQHandler ;Port D interrupt
|
||||
DCD PORTE_IRQHandler ;Port E interrupt
|
||||
DCD SWI_IRQHandler ;Software interrupt
|
||||
DCD SPI2_IRQHandler ;SPI2 Interrupt
|
||||
DCD UART4_RX_TX_IRQHandler ;UART4 Receive/Transmit interrupt
|
||||
DCD UART4_ERR_IRQHandler ;UART4 Error interrupt
|
||||
DCD UART5_RX_TX_IRQHandler ;UART5 Receive/Transmit interrupt
|
||||
DCD UART5_ERR_IRQHandler ;UART5 Error interrupt
|
||||
DCD CMP2_IRQHandler ;CMP2 interrupt
|
||||
DCD FTM3_IRQHandler ;FTM3 fault, overflow and channels interrupt
|
||||
DCD DAC1_IRQHandler ;DAC1 interrupt
|
||||
DCD ADC1_IRQHandler ;ADC1 interrupt
|
||||
DCD I2C2_IRQHandler ;I2C2 interrupt
|
||||
DCD CAN0_ORed_Message_buffer_IRQHandler ;CAN0 OR'd message buffers interrupt
|
||||
DCD CAN0_Bus_Off_IRQHandler ;CAN0 bus off interrupt
|
||||
DCD CAN0_Error_IRQHandler ;CAN0 error interrupt
|
||||
DCD CAN0_Tx_Warning_IRQHandler ;CAN0 Tx warning interrupt
|
||||
DCD CAN0_Rx_Warning_IRQHandler ;CAN0 Rx warning interrupt
|
||||
DCD CAN0_Wake_Up_IRQHandler ;CAN0 wake up interrupt
|
||||
DCD SDHC_IRQHandler ;SDHC interrupt
|
||||
DCD ENET_1588_Timer_IRQHandler ;Ethernet MAC IEEE 1588 Timer Interrupt
|
||||
DCD ENET_Transmit_IRQHandler ;Ethernet MAC Transmit Interrupt
|
||||
DCD ENET_Receive_IRQHandler ;Ethernet MAC Receive Interrupt
|
||||
DCD ENET_Error_IRQHandler ;Ethernet MAC Error and miscelaneous Interrupt
|
||||
DCD DefaultISR ;102
|
||||
DCD DefaultISR ;103
|
||||
DCD DefaultISR ;104
|
||||
DCD DefaultISR ;105
|
||||
DCD DefaultISR ;106
|
||||
DCD DefaultISR ;107
|
||||
DCD DefaultISR ;108
|
||||
DCD DefaultISR ;109
|
||||
DCD DefaultISR ;110
|
||||
DCD DefaultISR ;111
|
||||
DCD DefaultISR ;112
|
||||
DCD DefaultISR ;113
|
||||
DCD DefaultISR ;114
|
||||
DCD DefaultISR ;115
|
||||
DCD DefaultISR ;116
|
||||
DCD DefaultISR ;117
|
||||
DCD DefaultISR ;118
|
||||
DCD DefaultISR ;119
|
||||
DCD DefaultISR ;120
|
||||
DCD DefaultISR ;121
|
||||
DCD DefaultISR ;122
|
||||
DCD DefaultISR ;123
|
||||
DCD DefaultISR ;124
|
||||
DCD DefaultISR ;125
|
||||
DCD DefaultISR ;126
|
||||
DCD DefaultISR ;127
|
||||
DCD DefaultISR ;128
|
||||
DCD DefaultISR ;129
|
||||
DCD DefaultISR ;130
|
||||
DCD DefaultISR ;131
|
||||
DCD DefaultISR ;132
|
||||
DCD DefaultISR ;133
|
||||
DCD DefaultISR ;134
|
||||
DCD DefaultISR ;135
|
||||
DCD DefaultISR ;136
|
||||
DCD DefaultISR ;137
|
||||
DCD DefaultISR ;138
|
||||
DCD DefaultISR ;139
|
||||
DCD DefaultISR ;140
|
||||
DCD DefaultISR ;141
|
||||
DCD DefaultISR ;142
|
||||
DCD DefaultISR ;143
|
||||
DCD DefaultISR ;144
|
||||
DCD DefaultISR ;145
|
||||
DCD DefaultISR ;146
|
||||
DCD DefaultISR ;147
|
||||
DCD DefaultISR ;148
|
||||
DCD DefaultISR ;149
|
||||
DCD DefaultISR ;150
|
||||
DCD DefaultISR ;151
|
||||
DCD DefaultISR ;152
|
||||
DCD DefaultISR ;153
|
||||
DCD DefaultISR ;154
|
||||
DCD DefaultISR ;155
|
||||
DCD DefaultISR ;156
|
||||
DCD DefaultISR ;157
|
||||
DCD DefaultISR ;158
|
||||
DCD DefaultISR ;159
|
||||
DCD DefaultISR ;160
|
||||
DCD DefaultISR ;161
|
||||
DCD DefaultISR ;162
|
||||
DCD DefaultISR ;163
|
||||
DCD DefaultISR ;164
|
||||
DCD DefaultISR ;165
|
||||
DCD DefaultISR ;166
|
||||
DCD DefaultISR ;167
|
||||
DCD DefaultISR ;168
|
||||
DCD DefaultISR ;169
|
||||
DCD DefaultISR ;170
|
||||
DCD DefaultISR ;171
|
||||
DCD DefaultISR ;172
|
||||
DCD DefaultISR ;173
|
||||
DCD DefaultISR ;174
|
||||
DCD DefaultISR ;175
|
||||
DCD DefaultISR ;176
|
||||
DCD DefaultISR ;177
|
||||
DCD DefaultISR ;178
|
||||
DCD DefaultISR ;179
|
||||
DCD DefaultISR ;180
|
||||
DCD DefaultISR ;181
|
||||
DCD DefaultISR ;182
|
||||
DCD DefaultISR ;183
|
||||
DCD DefaultISR ;184
|
||||
DCD DefaultISR ;185
|
||||
DCD DefaultISR ;186
|
||||
DCD DefaultISR ;187
|
||||
DCD DefaultISR ;188
|
||||
DCD DefaultISR ;189
|
||||
DCD DefaultISR ;190
|
||||
DCD DefaultISR ;191
|
||||
DCD DefaultISR ;192
|
||||
DCD DefaultISR ;193
|
||||
DCD DefaultISR ;194
|
||||
DCD DefaultISR ;195
|
||||
DCD DefaultISR ;196
|
||||
DCD DefaultISR ;197
|
||||
DCD DefaultISR ;198
|
||||
DCD DefaultISR ;199
|
||||
DCD DefaultISR ;200
|
||||
DCD DefaultISR ;201
|
||||
DCD DefaultISR ;202
|
||||
DCD DefaultISR ;203
|
||||
DCD DefaultISR ;204
|
||||
DCD DefaultISR ;205
|
||||
DCD DefaultISR ;206
|
||||
DCD DefaultISR ;207
|
||||
DCD DefaultISR ;208
|
||||
DCD DefaultISR ;209
|
||||
DCD DefaultISR ;210
|
||||
DCD DefaultISR ;211
|
||||
DCD DefaultISR ;212
|
||||
DCD DefaultISR ;213
|
||||
DCD DefaultISR ;214
|
||||
DCD DefaultISR ;215
|
||||
DCD DefaultISR ;216
|
||||
DCD DefaultISR ;217
|
||||
DCD DefaultISR ;218
|
||||
DCD DefaultISR ;219
|
||||
DCD DefaultISR ;220
|
||||
DCD DefaultISR ;221
|
||||
DCD DefaultISR ;222
|
||||
DCD DefaultISR ;223
|
||||
DCD DefaultISR ;224
|
||||
DCD DefaultISR ;225
|
||||
DCD DefaultISR ;226
|
||||
DCD DefaultISR ;227
|
||||
DCD DefaultISR ;228
|
||||
DCD DefaultISR ;229
|
||||
DCD DefaultISR ;230
|
||||
DCD DefaultISR ;231
|
||||
DCD DefaultISR ;232
|
||||
DCD DefaultISR ;233
|
||||
DCD DefaultISR ;234
|
||||
DCD DefaultISR ;235
|
||||
DCD DefaultISR ;236
|
||||
DCD DefaultISR ;237
|
||||
DCD DefaultISR ;238
|
||||
DCD DefaultISR ;239
|
||||
DCD DefaultISR ;240
|
||||
DCD DefaultISR ;241
|
||||
DCD DefaultISR ;242
|
||||
DCD DefaultISR ;243
|
||||
DCD DefaultISR ;244
|
||||
DCD DefaultISR ;245
|
||||
DCD DefaultISR ;246
|
||||
DCD DefaultISR ;247
|
||||
DCD DefaultISR ;248
|
||||
DCD DefaultISR ;249
|
||||
DCD DefaultISR ;250
|
||||
DCD DefaultISR ;251
|
||||
DCD DefaultISR ;252
|
||||
DCD DefaultISR ;253
|
||||
DCD DefaultISR ;254
|
||||
DCD 0xFFFFFFFF ; Reserved for user TRIM value
|
||||
__Vectors_End
|
||||
|
||||
SECTION FlashConfig:CODE
|
||||
__FlashConfig
|
||||
DCD 0xFFFFFFFF
|
||||
DCD 0xFFFFFFFF
|
||||
DCD 0xFFFFFFFF
|
||||
DCD 0xFFFFFFFE
|
||||
__FlashConfig_End
|
||||
|
||||
__Vectors EQU __vector_table
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Default interrupt handlers.
|
||||
;;
|
||||
THUMB
|
||||
|
||||
PUBWEAK Reset_Handler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
Reset_Handler
|
||||
CPSID I ; Mask interrupts
|
||||
LDR R0, =0xE000ED08
|
||||
LDR R1, =__vector_table
|
||||
STR R1, [R0]
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
CPSIE I ; Unmask interrupts
|
||||
LDR R0, =__iar_program_start
|
||||
BX R0
|
||||
|
||||
PUBWEAK NMI_Handler
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
NMI_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK HardFault_Handler
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
HardFault_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK MemManage_Handler
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
MemManage_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK BusFault_Handler
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
BusFault_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK UsageFault_Handler
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
UsageFault_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK SVC_Handler
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
SVC_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK DebugMon_Handler
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
DebugMon_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK PendSV_Handler
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
PendSV_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK SysTick_Handler
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
SysTick_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK DMA0_IRQHandler
|
||||
PUBWEAK DMA0_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA0_IRQHandler
|
||||
LDR R0, =DMA0_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA1_IRQHandler
|
||||
PUBWEAK DMA1_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA1_IRQHandler
|
||||
LDR R0, =DMA1_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA2_IRQHandler
|
||||
PUBWEAK DMA2_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA2_IRQHandler
|
||||
LDR R0, =DMA2_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA3_IRQHandler
|
||||
PUBWEAK DMA3_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA3_IRQHandler
|
||||
LDR R0, =DMA3_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA4_IRQHandler
|
||||
PUBWEAK DMA4_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA4_IRQHandler
|
||||
LDR R0, =DMA4_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA5_IRQHandler
|
||||
PUBWEAK DMA5_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA5_IRQHandler
|
||||
LDR R0, =DMA5_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA6_IRQHandler
|
||||
PUBWEAK DMA6_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA6_IRQHandler
|
||||
LDR R0, =DMA6_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA7_IRQHandler
|
||||
PUBWEAK DMA7_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA7_IRQHandler
|
||||
LDR R0, =DMA7_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA8_IRQHandler
|
||||
PUBWEAK DMA8_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA8_IRQHandler
|
||||
LDR R0, =DMA8_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA9_IRQHandler
|
||||
PUBWEAK DMA9_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA9_IRQHandler
|
||||
LDR R0, =DMA9_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA10_IRQHandler
|
||||
PUBWEAK DMA10_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA10_IRQHandler
|
||||
LDR R0, =DMA10_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA11_IRQHandler
|
||||
PUBWEAK DMA11_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA11_IRQHandler
|
||||
LDR R0, =DMA11_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA12_IRQHandler
|
||||
PUBWEAK DMA12_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA12_IRQHandler
|
||||
LDR R0, =DMA12_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA13_IRQHandler
|
||||
PUBWEAK DMA13_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA13_IRQHandler
|
||||
LDR R0, =DMA13_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA14_IRQHandler
|
||||
PUBWEAK DMA14_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA14_IRQHandler
|
||||
LDR R0, =DMA14_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA15_IRQHandler
|
||||
PUBWEAK DMA15_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA15_IRQHandler
|
||||
LDR R0, =DMA15_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DMA_Error_IRQHandler
|
||||
PUBWEAK DMA_Error_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
DMA_Error_IRQHandler
|
||||
LDR R0, =DMA_Error_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK MCM_IRQHandler
|
||||
PUBWEAK FTFE_IRQHandler
|
||||
PUBWEAK Read_Collision_IRQHandler
|
||||
PUBWEAK LVD_LVW_IRQHandler
|
||||
PUBWEAK LLWU_IRQHandler
|
||||
PUBWEAK WDOG_EWM_IRQHandler
|
||||
PUBWEAK RNG_IRQHandler
|
||||
PUBWEAK I2C0_IRQHandler
|
||||
PUBWEAK I2C0_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
I2C0_IRQHandler
|
||||
LDR R0, =I2C0_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK I2C1_IRQHandler
|
||||
PUBWEAK I2C1_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
I2C1_IRQHandler
|
||||
LDR R0, =I2C1_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK SPI0_IRQHandler
|
||||
PUBWEAK SPI0_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
SPI0_IRQHandler
|
||||
LDR R0, =SPI0_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK SPI1_IRQHandler
|
||||
PUBWEAK SPI1_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
SPI1_IRQHandler
|
||||
LDR R0, =SPI1_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK I2S0_Tx_IRQHandler
|
||||
PUBWEAK I2S0_Tx_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
I2S0_Tx_IRQHandler
|
||||
LDR R0, =I2S0_Tx_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK I2S0_Rx_IRQHandler
|
||||
PUBWEAK I2S0_Rx_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
I2S0_Rx_IRQHandler
|
||||
LDR R0, =I2S0_Rx_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART0_LON_IRQHandler
|
||||
PUBWEAK UART0_LON_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART0_LON_IRQHandler
|
||||
LDR R0, =UART0_LON_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART0_RX_TX_IRQHandler
|
||||
PUBWEAK UART0_RX_TX_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART0_RX_TX_IRQHandler
|
||||
LDR R0, =UART0_RX_TX_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART0_ERR_IRQHandler
|
||||
PUBWEAK UART0_ERR_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART0_ERR_IRQHandler
|
||||
LDR R0, =UART0_ERR_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART1_RX_TX_IRQHandler
|
||||
PUBWEAK UART1_RX_TX_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART1_RX_TX_IRQHandler
|
||||
LDR R0, =UART1_RX_TX_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART1_ERR_IRQHandler
|
||||
PUBWEAK UART1_ERR_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART1_ERR_IRQHandler
|
||||
LDR R0, =UART1_ERR_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART2_RX_TX_IRQHandler
|
||||
PUBWEAK UART2_RX_TX_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART2_RX_TX_IRQHandler
|
||||
LDR R0, =UART2_RX_TX_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART2_ERR_IRQHandler
|
||||
PUBWEAK UART2_ERR_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART2_ERR_IRQHandler
|
||||
LDR R0, =UART2_ERR_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART3_RX_TX_IRQHandler
|
||||
PUBWEAK UART3_RX_TX_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART3_RX_TX_IRQHandler
|
||||
LDR R0, =UART3_RX_TX_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART3_ERR_IRQHandler
|
||||
PUBWEAK UART3_ERR_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART3_ERR_IRQHandler
|
||||
LDR R0, =UART3_ERR_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK ADC0_IRQHandler
|
||||
PUBWEAK CMP0_IRQHandler
|
||||
PUBWEAK CMP1_IRQHandler
|
||||
PUBWEAK FTM0_IRQHandler
|
||||
PUBWEAK FTM1_IRQHandler
|
||||
PUBWEAK FTM2_IRQHandler
|
||||
PUBWEAK CMT_IRQHandler
|
||||
PUBWEAK RTC_IRQHandler
|
||||
PUBWEAK RTC_Seconds_IRQHandler
|
||||
PUBWEAK PIT0_IRQHandler
|
||||
PUBWEAK PIT1_IRQHandler
|
||||
PUBWEAK PIT2_IRQHandler
|
||||
PUBWEAK PIT3_IRQHandler
|
||||
PUBWEAK PDB0_IRQHandler
|
||||
PUBWEAK USB0_IRQHandler
|
||||
PUBWEAK USBDCD_IRQHandler
|
||||
PUBWEAK Reserved71_IRQHandler
|
||||
PUBWEAK DAC0_IRQHandler
|
||||
PUBWEAK MCG_IRQHandler
|
||||
PUBWEAK LPTMR0_IRQHandler
|
||||
PUBWEAK PORTA_IRQHandler
|
||||
PUBWEAK PORTB_IRQHandler
|
||||
PUBWEAK PORTC_IRQHandler
|
||||
PUBWEAK PORTD_IRQHandler
|
||||
PUBWEAK PORTE_IRQHandler
|
||||
PUBWEAK SWI_IRQHandler
|
||||
PUBWEAK SPI2_IRQHandler
|
||||
PUBWEAK SPI2_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
SPI2_IRQHandler
|
||||
LDR R0, =SPI2_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART4_RX_TX_IRQHandler
|
||||
PUBWEAK UART4_RX_TX_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART4_RX_TX_IRQHandler
|
||||
LDR R0, =UART4_RX_TX_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART4_ERR_IRQHandler
|
||||
PUBWEAK UART4_ERR_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART4_ERR_IRQHandler
|
||||
LDR R0, =UART4_ERR_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART5_RX_TX_IRQHandler
|
||||
PUBWEAK UART5_RX_TX_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART5_RX_TX_IRQHandler
|
||||
LDR R0, =UART5_RX_TX_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK UART5_ERR_IRQHandler
|
||||
PUBWEAK UART5_ERR_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
UART5_ERR_IRQHandler
|
||||
LDR R0, =UART5_ERR_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK CMP2_IRQHandler
|
||||
PUBWEAK FTM3_IRQHandler
|
||||
PUBWEAK DAC1_IRQHandler
|
||||
PUBWEAK ADC1_IRQHandler
|
||||
PUBWEAK I2C2_IRQHandler
|
||||
PUBWEAK I2C2_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
I2C2_IRQHandler
|
||||
LDR R0, =I2C2_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK CAN0_ORed_Message_buffer_IRQHandler
|
||||
PUBWEAK CAN0_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
CAN0_ORed_Message_buffer_IRQHandler
|
||||
LDR R0, =CAN0_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK CAN0_Bus_Off_IRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
CAN0_Bus_Off_IRQHandler
|
||||
LDR R0, =CAN0_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK CAN0_Error_IRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
CAN0_Error_IRQHandler
|
||||
LDR R0, =CAN0_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK CAN0_Tx_Warning_IRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
CAN0_Tx_Warning_IRQHandler
|
||||
LDR R0, =CAN0_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK CAN0_Rx_Warning_IRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
CAN0_Rx_Warning_IRQHandler
|
||||
LDR R0, =CAN0_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK CAN0_Wake_Up_IRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
CAN0_Wake_Up_IRQHandler
|
||||
LDR R0, =CAN0_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK SDHC_IRQHandler
|
||||
PUBWEAK SDHC_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
SDHC_IRQHandler
|
||||
LDR R0, =SDHC_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK ENET_1588_Timer_IRQHandler
|
||||
PUBWEAK ENET_1588_Timer_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
ENET_1588_Timer_IRQHandler
|
||||
LDR R0, =ENET_1588_Timer_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK ENET_Transmit_IRQHandler
|
||||
PUBWEAK ENET_Transmit_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
ENET_Transmit_IRQHandler
|
||||
LDR R0, =ENET_Transmit_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK ENET_Receive_IRQHandler
|
||||
PUBWEAK ENET_Receive_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
ENET_Receive_IRQHandler
|
||||
LDR R0, =ENET_Receive_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK ENET_Error_IRQHandler
|
||||
PUBWEAK ENET_Error_DriverIRQHandler
|
||||
SECTION .text:CODE:REORDER:NOROOT(2)
|
||||
ENET_Error_IRQHandler
|
||||
LDR R0, =ENET_Error_DriverIRQHandler
|
||||
BX R0
|
||||
|
||||
PUBWEAK DefaultISR
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
DMA0_DriverIRQHandler
|
||||
DMA1_DriverIRQHandler
|
||||
DMA2_DriverIRQHandler
|
||||
DMA3_DriverIRQHandler
|
||||
DMA4_DriverIRQHandler
|
||||
DMA5_DriverIRQHandler
|
||||
DMA6_DriverIRQHandler
|
||||
DMA7_DriverIRQHandler
|
||||
DMA8_DriverIRQHandler
|
||||
DMA9_DriverIRQHandler
|
||||
DMA10_DriverIRQHandler
|
||||
DMA11_DriverIRQHandler
|
||||
DMA12_DriverIRQHandler
|
||||
DMA13_DriverIRQHandler
|
||||
DMA14_DriverIRQHandler
|
||||
DMA15_DriverIRQHandler
|
||||
DMA_Error_DriverIRQHandler
|
||||
MCM_IRQHandler
|
||||
FTFE_IRQHandler
|
||||
Read_Collision_IRQHandler
|
||||
LVD_LVW_IRQHandler
|
||||
LLWU_IRQHandler
|
||||
WDOG_EWM_IRQHandler
|
||||
RNG_IRQHandler
|
||||
I2C0_DriverIRQHandler
|
||||
I2C1_DriverIRQHandler
|
||||
SPI0_DriverIRQHandler
|
||||
SPI1_DriverIRQHandler
|
||||
I2S0_Tx_DriverIRQHandler
|
||||
I2S0_Rx_DriverIRQHandler
|
||||
UART0_LON_DriverIRQHandler
|
||||
UART0_RX_TX_DriverIRQHandler
|
||||
UART0_ERR_DriverIRQHandler
|
||||
UART1_RX_TX_DriverIRQHandler
|
||||
UART1_ERR_DriverIRQHandler
|
||||
UART2_RX_TX_DriverIRQHandler
|
||||
UART2_ERR_DriverIRQHandler
|
||||
UART3_RX_TX_DriverIRQHandler
|
||||
UART3_ERR_DriverIRQHandler
|
||||
ADC0_IRQHandler
|
||||
CMP0_IRQHandler
|
||||
CMP1_IRQHandler
|
||||
FTM0_IRQHandler
|
||||
FTM1_IRQHandler
|
||||
FTM2_IRQHandler
|
||||
CMT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
RTC_Seconds_IRQHandler
|
||||
PIT0_IRQHandler
|
||||
PIT1_IRQHandler
|
||||
PIT2_IRQHandler
|
||||
PIT3_IRQHandler
|
||||
PDB0_IRQHandler
|
||||
USB0_IRQHandler
|
||||
USBDCD_IRQHandler
|
||||
Reserved71_IRQHandler
|
||||
DAC0_IRQHandler
|
||||
MCG_IRQHandler
|
||||
LPTMR0_IRQHandler
|
||||
PORTA_IRQHandler
|
||||
PORTB_IRQHandler
|
||||
PORTC_IRQHandler
|
||||
PORTD_IRQHandler
|
||||
PORTE_IRQHandler
|
||||
SWI_IRQHandler
|
||||
SPI2_DriverIRQHandler
|
||||
UART4_RX_TX_DriverIRQHandler
|
||||
UART4_ERR_DriverIRQHandler
|
||||
UART5_RX_TX_DriverIRQHandler
|
||||
UART5_ERR_DriverIRQHandler
|
||||
CMP2_IRQHandler
|
||||
FTM3_IRQHandler
|
||||
DAC1_IRQHandler
|
||||
ADC1_IRQHandler
|
||||
I2C2_DriverIRQHandler
|
||||
CAN0_DriverIRQHandler
|
||||
SDHC_DriverIRQHandler
|
||||
ENET_1588_Timer_DriverIRQHandler
|
||||
ENET_Transmit_DriverIRQHandler
|
||||
ENET_Receive_DriverIRQHandler
|
||||
ENET_Error_DriverIRQHandler
|
||||
DefaultISR
|
||||
B DefaultISR
|
||||
|
||||
END
|
|
@ -0,0 +1,13 @@
|
|||
/* mbed Microcontroller Library - CMSIS
|
||||
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* A generic CMSIS include header, pulling in LPC11U24 specifics
|
||||
*/
|
||||
|
||||
#ifndef MBED_CMSIS_H
|
||||
#define MBED_CMSIS_H
|
||||
|
||||
#include "fsl_device_registers.h"
|
||||
#include "cmsis_nvic.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,42 @@
|
|||
/* mbed Microcontroller Library
|
||||
* CMSIS-style functionality to support dynamic vectors
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2011 ARM Limited. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of ARM Limited nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "cmsis_nvic.h"
|
||||
|
||||
extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
|
||||
|
||||
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
|
||||
InstallIRQHandler(IRQn, vector);
|
||||
}
|
||||
|
||||
uint32_t NVIC_GetVector(IRQn_Type IRQn) {
|
||||
uint32_t *vectors = (uint32_t*)SCB->VTOR;
|
||||
return vectors[IRQn + 16];
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/* mbed Microcontroller Library
|
||||
* CMSIS-style functionality to support dynamic vectors
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2011 ARM Limited. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of ARM Limited nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef MBED_CMSIS_NVIC_H
|
||||
#define MBED_CMSIS_NVIC_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
|
||||
uint32_t NVIC_GetVector(IRQn_Type IRQn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __FSL_DEVICE_REGISTERS_H__
|
||||
#define __FSL_DEVICE_REGISTERS_H__
|
||||
|
||||
/*
|
||||
* Include the cpu specific register header files.
|
||||
*
|
||||
* The CPU macro should be declared in the project or makefile.
|
||||
*/
|
||||
#if (defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FX512VLL12) || \
|
||||
defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FX512VLQ12) || defined(CPU_MK64FN1M0VLQ12) || \
|
||||
defined(CPU_MK64FX512VMD12) || defined(CPU_MK64FN1M0VMD12))
|
||||
|
||||
#define K64F12_SERIES
|
||||
|
||||
/* CMSIS-style register definitions */
|
||||
#include "MK64F12.h"
|
||||
/* CPU specific feature definitions */
|
||||
#include "MK64F12_features.h"
|
||||
|
||||
#else
|
||||
#error "No valid CPU defined!"
|
||||
#endif
|
||||
|
||||
#endif /* __FSL_DEVICE_REGISTERS_H__ */
|
||||
|
||||
/*******************************************************************************
|
||||
* EOF
|
||||
******************************************************************************/
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
** ###################################################################
|
||||
** Processors: MK64FN1M0VDC12
|
||||
** MK64FN1M0VLL12
|
||||
** MK64FN1M0VLQ12
|
||||
** MK64FN1M0VMD12
|
||||
** MK64FX512VDC12
|
||||
** MK64FX512VLL12
|
||||
** MK64FX512VLQ12
|
||||
** MK64FX512VMD12
|
||||
**
|
||||
** Compilers: Keil ARM C/C++ Compiler
|
||||
** Freescale C/C++ for Embedded ARM
|
||||
** GNU C Compiler
|
||||
** IAR ANSI C/C++ Compiler for ARM
|
||||
**
|
||||
** Reference manual: K64P144M120SF5RM, Rev.2, January 2014
|
||||
** Version: rev. 2.8, 2015-02-19
|
||||
** Build: b151216
|
||||
**
|
||||
** Abstract:
|
||||
** Provides a system configuration function and a global variable that
|
||||
** contains the system frequency. It configures the device and initializes
|
||||
** the oscillator (PLL) that is part of the microcontroller device.
|
||||
**
|
||||
** Copyright (c) 2015 Freescale Semiconductor, Inc.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
** o Redistributions of source code must retain the above copyright notice, this list
|
||||
** of conditions and the following disclaimer.
|
||||
**
|
||||
** o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
** list of conditions and the following disclaimer in the documentation and/or
|
||||
** other materials provided with the distribution.
|
||||
**
|
||||
** o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
** contributors may be used to endorse or promote products derived from this
|
||||
** software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** http: www.freescale.com
|
||||
** mail: support@freescale.com
|
||||
**
|
||||
** Revisions:
|
||||
** - rev. 1.0 (2013-08-12)
|
||||
** Initial version.
|
||||
** - rev. 2.0 (2013-10-29)
|
||||
** Register accessor macros added to the memory map.
|
||||
** Symbols for Processor Expert memory map compatibility added to the memory map.
|
||||
** Startup file for gcc has been updated according to CMSIS 3.2.
|
||||
** System initialization updated.
|
||||
** MCG - registers updated.
|
||||
** PORTA, PORTB, PORTC, PORTE - registers for digital filter removed.
|
||||
** - rev. 2.1 (2013-10-30)
|
||||
** Definition of BITBAND macros updated to support peripherals with 32-bit acces disabled.
|
||||
** - rev. 2.2 (2013-12-09)
|
||||
** DMA - EARS register removed.
|
||||
** AIPS0, AIPS1 - MPRA register updated.
|
||||
** - rev. 2.3 (2014-01-24)
|
||||
** Update according to reference manual rev. 2
|
||||
** ENET, MCG, MCM, SIM, USB - registers updated
|
||||
** - rev. 2.4 (2014-02-10)
|
||||
** The declaration of clock configurations has been moved to separate header file system_MK64F12.h
|
||||
** Update of SystemInit() and SystemCoreClockUpdate() functions.
|
||||
** - rev. 2.5 (2014-02-10)
|
||||
** The declaration of clock configurations has been moved to separate header file system_MK64F12.h
|
||||
** Update of SystemInit() and SystemCoreClockUpdate() functions.
|
||||
** Module access macro module_BASES replaced by module_BASE_PTRS.
|
||||
** - rev. 2.6 (2014-08-28)
|
||||
** Update of system files - default clock configuration changed.
|
||||
** Update of startup files - possibility to override DefaultISR added.
|
||||
** - rev. 2.7 (2014-10-14)
|
||||
** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM.
|
||||
** - rev. 2.8 (2015-02-19)
|
||||
** Renamed interrupt vector LLW to LLWU.
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file MK64F12
|
||||
* @version 2.8
|
||||
* @date 2015-02-19
|
||||
* @brief Device specific configuration file for MK64F12 (implementation file)
|
||||
*
|
||||
* Provides a system configuration function and a global variable that contains
|
||||
* the system frequency. It configures the device and initializes the oscillator
|
||||
* (PLL) that is part of the microcontroller device.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "fsl_device_registers.h"
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- Core clock
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- SystemInit()
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
void SystemInit (void) {
|
||||
#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
|
||||
SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); /* set CP10, CP11 Full Access */
|
||||
#endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */
|
||||
#if (DISABLE_WDOG)
|
||||
/* WDOG->UNLOCK: WDOGUNLOCK=0xC520 */
|
||||
WDOG->UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */
|
||||
/* WDOG->UNLOCK: WDOGUNLOCK=0xD928 */
|
||||
WDOG->UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928); /* Key 2 */
|
||||
/* WDOG->STCTRLH: ?=0,DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,?=0,?=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */
|
||||
WDOG->STCTRLH = WDOG_STCTRLH_BYTESEL(0x00) |
|
||||
WDOG_STCTRLH_WAITEN_MASK |
|
||||
WDOG_STCTRLH_STOPEN_MASK |
|
||||
WDOG_STCTRLH_ALLOWUPDATE_MASK |
|
||||
WDOG_STCTRLH_CLKSRC_MASK |
|
||||
0x0100U;
|
||||
#endif /* (DISABLE_WDOG) */
|
||||
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- SystemCoreClockUpdate()
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
void SystemCoreClockUpdate (void) {
|
||||
uint32_t MCGOUTClock; /* Variable to store output clock frequency of the MCG module */
|
||||
uint16_t Divider;
|
||||
|
||||
if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x00U) {
|
||||
/* Output of FLL or PLL is selected */
|
||||
if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U) {
|
||||
/* FLL is selected */
|
||||
if ((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U) {
|
||||
/* External reference clock is selected */
|
||||
switch (MCG->C7 & MCG_C7_OSCSEL_MASK) {
|
||||
case 0x00U:
|
||||
MCGOUTClock = CPU_XTAL_CLK_HZ; /* System oscillator drives MCG clock */
|
||||
break;
|
||||
case 0x01U:
|
||||
MCGOUTClock = CPU_XTAL32k_CLK_HZ; /* RTC 32 kHz oscillator drives MCG clock */
|
||||
break;
|
||||
case 0x02U:
|
||||
default:
|
||||
MCGOUTClock = CPU_INT_IRC_CLK_HZ; /* IRC 48MHz oscillator drives MCG clock */
|
||||
break;
|
||||
}
|
||||
if (((MCG->C2 & MCG_C2_RANGE_MASK) != 0x00U) && ((MCG->C7 & MCG_C7_OSCSEL_MASK) != 0x01U)) {
|
||||
switch (MCG->C1 & MCG_C1_FRDIV_MASK) {
|
||||
case 0x38U:
|
||||
Divider = 1536U;
|
||||
break;
|
||||
case 0x30U:
|
||||
Divider = 1280U;
|
||||
break;
|
||||
default:
|
||||
Divider = (uint16_t)(32LU << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT));
|
||||
break;
|
||||
}
|
||||
} else {/* ((MCG->C2 & MCG_C2_RANGE_MASK) != 0x00U) */
|
||||
Divider = (uint16_t)(1LU << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT));
|
||||
}
|
||||
MCGOUTClock = (MCGOUTClock / Divider); /* Calculate the divided FLL reference clock */
|
||||
} else { /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U)) */
|
||||
MCGOUTClock = CPU_INT_SLOW_CLK_HZ; /* The slow internal reference clock is selected */
|
||||
} /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U)) */
|
||||
/* Select correct multiplier to calculate the MCG output clock */
|
||||
switch (MCG->C4 & (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) {
|
||||
case 0x00U:
|
||||
MCGOUTClock *= 640U;
|
||||
break;
|
||||
case 0x20U:
|
||||
MCGOUTClock *= 1280U;
|
||||
break;
|
||||
case 0x40U:
|
||||
MCGOUTClock *= 1920U;
|
||||
break;
|
||||
case 0x60U:
|
||||
MCGOUTClock *= 2560U;
|
||||
break;
|
||||
case 0x80U:
|
||||
MCGOUTClock *= 732U;
|
||||
break;
|
||||
case 0xA0U:
|
||||
MCGOUTClock *= 1464U;
|
||||
break;
|
||||
case 0xC0U:
|
||||
MCGOUTClock *= 2197U;
|
||||
break;
|
||||
case 0xE0U:
|
||||
MCGOUTClock *= 2929U;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else { /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U)) */
|
||||
/* PLL is selected */
|
||||
Divider = (((uint16_t)MCG->C5 & MCG_C5_PRDIV0_MASK) + 0x01U);
|
||||
MCGOUTClock = (uint32_t)(CPU_XTAL_CLK_HZ / Divider); /* Calculate the PLL reference clock */
|
||||
Divider = (((uint16_t)MCG->C6 & MCG_C6_VDIV0_MASK) + 24U);
|
||||
MCGOUTClock *= Divider; /* Calculate the MCG output clock */
|
||||
} /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U)) */
|
||||
} else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x40U) {
|
||||
/* Internal reference clock is selected */
|
||||
if ((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U) {
|
||||
MCGOUTClock = CPU_INT_SLOW_CLK_HZ; /* Slow internal reference clock selected */
|
||||
} else { /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U)) */
|
||||
Divider = (uint16_t)(0x01LU << ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT));
|
||||
MCGOUTClock = (uint32_t) (CPU_INT_FAST_CLK_HZ / Divider); /* Fast internal reference clock selected */
|
||||
} /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U)) */
|
||||
} else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U) {
|
||||
/* External reference clock is selected */
|
||||
switch (MCG->C7 & MCG_C7_OSCSEL_MASK) {
|
||||
case 0x00U:
|
||||
MCGOUTClock = CPU_XTAL_CLK_HZ; /* System oscillator drives MCG clock */
|
||||
break;
|
||||
case 0x01U:
|
||||
MCGOUTClock = CPU_XTAL32k_CLK_HZ; /* RTC 32 kHz oscillator drives MCG clock */
|
||||
break;
|
||||
case 0x02U:
|
||||
default:
|
||||
MCGOUTClock = CPU_INT_IRC_CLK_HZ; /* IRC 48MHz oscillator drives MCG clock */
|
||||
break;
|
||||
}
|
||||
} else { /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U)) */
|
||||
/* Reserved value */
|
||||
return;
|
||||
} /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U)) */
|
||||
SystemCoreClock = (MCGOUTClock / (0x01U + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT)));
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
** ###################################################################
|
||||
** Processors: MK64FN1M0VDC12
|
||||
** MK64FN1M0VLL12
|
||||
** MK64FN1M0VLQ12
|
||||
** MK64FN1M0VMD12
|
||||
** MK64FX512VDC12
|
||||
** MK64FX512VLL12
|
||||
** MK64FX512VLQ12
|
||||
** MK64FX512VMD12
|
||||
**
|
||||
** Compilers: Keil ARM C/C++ Compiler
|
||||
** Freescale C/C++ for Embedded ARM
|
||||
** GNU C Compiler
|
||||
** IAR ANSI C/C++ Compiler for ARM
|
||||
**
|
||||
** Reference manual: K64P144M120SF5RM, Rev.2, January 2014
|
||||
** Version: rev. 2.8, 2015-02-19
|
||||
** Build: b151216
|
||||
**
|
||||
** Abstract:
|
||||
** Provides a system configuration function and a global variable that
|
||||
** contains the system frequency. It configures the device and initializes
|
||||
** the oscillator (PLL) that is part of the microcontroller device.
|
||||
**
|
||||
** Copyright (c) 2015 Freescale Semiconductor, Inc.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
** o Redistributions of source code must retain the above copyright notice, this list
|
||||
** of conditions and the following disclaimer.
|
||||
**
|
||||
** o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
** list of conditions and the following disclaimer in the documentation and/or
|
||||
** other materials provided with the distribution.
|
||||
**
|
||||
** o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
** contributors may be used to endorse or promote products derived from this
|
||||
** software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** http: www.freescale.com
|
||||
** mail: support@freescale.com
|
||||
**
|
||||
** Revisions:
|
||||
** - rev. 1.0 (2013-08-12)
|
||||
** Initial version.
|
||||
** - rev. 2.0 (2013-10-29)
|
||||
** Register accessor macros added to the memory map.
|
||||
** Symbols for Processor Expert memory map compatibility added to the memory map.
|
||||
** Startup file for gcc has been updated according to CMSIS 3.2.
|
||||
** System initialization updated.
|
||||
** MCG - registers updated.
|
||||
** PORTA, PORTB, PORTC, PORTE - registers for digital filter removed.
|
||||
** - rev. 2.1 (2013-10-30)
|
||||
** Definition of BITBAND macros updated to support peripherals with 32-bit acces disabled.
|
||||
** - rev. 2.2 (2013-12-09)
|
||||
** DMA - EARS register removed.
|
||||
** AIPS0, AIPS1 - MPRA register updated.
|
||||
** - rev. 2.3 (2014-01-24)
|
||||
** Update according to reference manual rev. 2
|
||||
** ENET, MCG, MCM, SIM, USB - registers updated
|
||||
** - rev. 2.4 (2014-02-10)
|
||||
** The declaration of clock configurations has been moved to separate header file system_MK64F12.h
|
||||
** Update of SystemInit() and SystemCoreClockUpdate() functions.
|
||||
** - rev. 2.5 (2014-02-10)
|
||||
** The declaration of clock configurations has been moved to separate header file system_MK64F12.h
|
||||
** Update of SystemInit() and SystemCoreClockUpdate() functions.
|
||||
** Module access macro module_BASES replaced by module_BASE_PTRS.
|
||||
** - rev. 2.6 (2014-08-28)
|
||||
** Update of system files - default clock configuration changed.
|
||||
** Update of startup files - possibility to override DefaultISR added.
|
||||
** - rev. 2.7 (2014-10-14)
|
||||
** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM.
|
||||
** - rev. 2.8 (2015-02-19)
|
||||
** Renamed interrupt vector LLW to LLWU.
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file MK64F12
|
||||
* @version 2.8
|
||||
* @date 2015-02-19
|
||||
* @brief Device specific configuration file for MK64F12 (header file)
|
||||
*
|
||||
* Provides a system configuration function and a global variable that contains
|
||||
* the system frequency. It configures the device and initializes the oscillator
|
||||
* (PLL) that is part of the microcontroller device.
|
||||
*/
|
||||
|
||||
#ifndef _SYSTEM_MK64F12_H_
|
||||
#define _SYSTEM_MK64F12_H_ /**< Symbol preventing repeated inclusion */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#ifndef DISABLE_WDOG
|
||||
#define DISABLE_WDOG 1
|
||||
#endif
|
||||
|
||||
#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_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */
|
||||
#define CPU_INT_FAST_CLK_HZ 4000000u /* Value of the fast internal oscillator clock frequency in Hz */
|
||||
#define CPU_INT_IRC_CLK_HZ 48000000u /* Value of the 48M internal oscillator clock frequency in Hz */
|
||||
|
||||
/* RTC oscillator setting */
|
||||
/* RTC_CR: SC2P=0,SC4P=0,SC8P=0,SC16P=0,CLKO=1,OSCE=1,WPS=0,UM=0,SUP=0,WPE=0,SWR=0 */
|
||||
#define SYSTEM_RTC_CR_VALUE 0x0300U /* RTC_CR */
|
||||
|
||||
/* Low power mode enable */
|
||||
/* SMC_PMPROT: AVLP=1,ALLS=1,AVLLS=1 */
|
||||
#define SYSTEM_SMC_PMPROT_VALUE 0x2AU /* SMC_PMPROT */
|
||||
|
||||
#define DEFAULT_SYSTEM_CLOCK 20971520u /* Default System clock value */
|
||||
|
||||
|
||||
/**
|
||||
* @brief System clock frequency (core clock)
|
||||
*
|
||||
* The system clock frequency supplied to the SysTick timer and the processor
|
||||
* core clock. This variable can be used by the user application to setup the
|
||||
* SysTick timer or configure other parameters. It may also be used by debugger to
|
||||
* query the frequency of the debug timer or configure the trace clock speed
|
||||
* SystemCoreClock is initialized with a correct predefined value.
|
||||
*/
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
*
|
||||
* Typically this function configures the oscillator (PLL) that is part of the
|
||||
* microcontroller device. For systems with variable clock speed it also updates
|
||||
* the variable SystemCoreClock. SystemInit is called from startup_device file.
|
||||
*/
|
||||
void SystemInit (void);
|
||||
|
||||
/**
|
||||
* @brief Updates the SystemCoreClock variable.
|
||||
*
|
||||
* It must be called whenever the core clock is changed during program
|
||||
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
|
||||
* the current core clock.
|
||||
*/
|
||||
void SystemCoreClockUpdate (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYSTEM_MK64F12_H_ */
|
|
@ -0,0 +1,137 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MBED_PERIPHERALNAMES_H
|
||||
#define MBED_PERIPHERALNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
OSC32KCLK = 0,
|
||||
} RTCName;
|
||||
|
||||
typedef enum {
|
||||
UART_0 = 0,
|
||||
UART_1 = 1,
|
||||
UART_2 = 2,
|
||||
UART_3 = 3,
|
||||
UART_4 = 4,
|
||||
} UARTName;
|
||||
|
||||
#define STDIO_UART_TX USBTX
|
||||
#define STDIO_UART_RX USBRX
|
||||
#define STDIO_UART UART_0
|
||||
|
||||
typedef enum {
|
||||
I2C_0 = 0,
|
||||
I2C_1 = 1,
|
||||
I2C_2 = 2,
|
||||
} I2CName;
|
||||
|
||||
#define TPM_SHIFT 8
|
||||
typedef enum {
|
||||
PWM_1 = (0 << TPM_SHIFT) | (0), // FTM0 CH0
|
||||
PWM_2 = (0 << TPM_SHIFT) | (1), // FTM0 CH1
|
||||
PWM_3 = (0 << TPM_SHIFT) | (2), // FTM0 CH2
|
||||
PWM_4 = (0 << TPM_SHIFT) | (3), // FTM0 CH3
|
||||
PWM_5 = (0 << TPM_SHIFT) | (4), // FTM0 CH4
|
||||
PWM_6 = (0 << TPM_SHIFT) | (5), // FTM0 CH5
|
||||
PWM_7 = (0 << TPM_SHIFT) | (6), // FTM0 CH6
|
||||
PWM_8 = (0 << TPM_SHIFT) | (7), // FTM0 CH7
|
||||
PWM_9 = (1 << TPM_SHIFT) | (0), // FTM1 CH0
|
||||
PWM_10 = (1 << TPM_SHIFT) | (1), // FTM1 CH1
|
||||
PWM_11 = (1 << TPM_SHIFT) | (2), // FTM1 CH2
|
||||
PWM_12 = (1 << TPM_SHIFT) | (3), // FTM1 CH3
|
||||
PWM_13 = (1 << TPM_SHIFT) | (4), // FTM1 CH4
|
||||
PWM_14 = (1 << TPM_SHIFT) | (5), // FTM1 CH5
|
||||
PWM_15 = (1 << TPM_SHIFT) | (6), // FTM1 CH6
|
||||
PWM_16 = (1 << TPM_SHIFT) | (7), // FTM1 CH7
|
||||
PWM_17 = (2 << TPM_SHIFT) | (0), // FTM2 CH0
|
||||
PWM_18 = (2 << TPM_SHIFT) | (1), // FTM2 CH1
|
||||
PWM_19 = (2 << TPM_SHIFT) | (2), // FTM2 CH2
|
||||
PWM_20 = (2 << TPM_SHIFT) | (3), // FTM2 CH3
|
||||
PWM_21 = (2 << TPM_SHIFT) | (4), // FTM2 CH4
|
||||
PWM_22 = (2 << TPM_SHIFT) | (5), // FTM2 CH5
|
||||
PWM_23 = (2 << TPM_SHIFT) | (6), // FTM2 CH6
|
||||
PWM_24 = (2 << TPM_SHIFT) | (7), // FTM2 CH7
|
||||
PWM_25 = (3 << TPM_SHIFT) | (0), // FTM3 CH0
|
||||
PWM_26 = (3 << TPM_SHIFT) | (1), // FTM3 CH1
|
||||
PWM_27 = (3 << TPM_SHIFT) | (2), // FTM3 CH2
|
||||
PWM_28 = (3 << TPM_SHIFT) | (3), // FTM3 CH3
|
||||
PWM_29 = (3 << TPM_SHIFT) | (4), // FTM3 CH4
|
||||
PWM_30 = (3 << TPM_SHIFT) | (5), // FTM3 CH5
|
||||
PWM_31 = (3 << TPM_SHIFT) | (6), // FTM3 CH6
|
||||
PWM_32 = (3 << TPM_SHIFT) | (7), // FTM3 CH7
|
||||
} PWMName;
|
||||
|
||||
#define ADC_INSTANCE_SHIFT 8
|
||||
#define ADC_B_CHANNEL_SHIFT 5
|
||||
typedef enum {
|
||||
ADC0_SE4b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 4,
|
||||
ADC0_SE5b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 5,
|
||||
ADC0_SE6b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 6,
|
||||
ADC0_SE7b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 7,
|
||||
ADC0_SE8 = (0 << ADC_INSTANCE_SHIFT) | 8,
|
||||
ADC0_SE9 = (0 << ADC_INSTANCE_SHIFT) | 9,
|
||||
ADC0_SE12 = (0 << ADC_INSTANCE_SHIFT) | 12,
|
||||
ADC0_SE13 = (0 << ADC_INSTANCE_SHIFT) | 13,
|
||||
ADC0_SE14 = (0 << ADC_INSTANCE_SHIFT) | 14,
|
||||
ADC0_SE15 = (0 << ADC_INSTANCE_SHIFT) | 15,
|
||||
ADC0_SE16 = (0 << ADC_INSTANCE_SHIFT) | 16,
|
||||
ADC0_SE17 = (0 << ADC_INSTANCE_SHIFT) | 17,
|
||||
ADC0_SE18 = (0 << ADC_INSTANCE_SHIFT) | 18,
|
||||
ADC0_SE21 = (0 << ADC_INSTANCE_SHIFT) | 21,
|
||||
ADC0_SE22 = (0 << ADC_INSTANCE_SHIFT) | 22,
|
||||
ADC0_SE23 = (0 << ADC_INSTANCE_SHIFT) | 23,
|
||||
ADC1_SE4a = (1 << ADC_INSTANCE_SHIFT) | 4,
|
||||
ADC1_SE5a = (1 << ADC_INSTANCE_SHIFT) | 5,
|
||||
ADC1_SE6a = (1 << ADC_INSTANCE_SHIFT) | 6,
|
||||
ADC1_SE7a = (1 << ADC_INSTANCE_SHIFT) | 7,
|
||||
ADC1_SE4b = (1 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 4,
|
||||
ADC1_SE5b = (1 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 5,
|
||||
ADC1_SE6b = (1 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 6,
|
||||
ADC1_SE7b = (1 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 7,
|
||||
ADC1_SE8 = (1 << ADC_INSTANCE_SHIFT) | 8,
|
||||
ADC1_SE9 = (1 << ADC_INSTANCE_SHIFT) | 9,
|
||||
ADC1_SE12 = (1 << ADC_INSTANCE_SHIFT) | 12,
|
||||
ADC1_SE13 = (1 << ADC_INSTANCE_SHIFT) | 13,
|
||||
ADC1_SE14 = (1 << ADC_INSTANCE_SHIFT) | 14,
|
||||
ADC1_SE15 = (1 << ADC_INSTANCE_SHIFT) | 15,
|
||||
ADC1_SE16 = (1 << ADC_INSTANCE_SHIFT) | 16,
|
||||
ADC1_SE17 = (1 << ADC_INSTANCE_SHIFT) | 17,
|
||||
ADC1_SE18 = (1 << ADC_INSTANCE_SHIFT) | 18,
|
||||
ADC1_SE23 = (1 << ADC_INSTANCE_SHIFT) | 23,
|
||||
} ADCName;
|
||||
|
||||
typedef enum {
|
||||
DAC_0 = 0
|
||||
} DACName;
|
||||
|
||||
|
||||
typedef enum {
|
||||
SPI_0 = 0,
|
||||
SPI_1 = 1,
|
||||
SPI_2 = 2,
|
||||
} SPIName;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,208 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "PeripheralPins.h"
|
||||
|
||||
/************RTC***************/
|
||||
const PinMap PinMap_RTC[] = {
|
||||
{NC, OSC32KCLK, 0},
|
||||
};
|
||||
|
||||
/************ADC***************/
|
||||
const PinMap PinMap_ADC[] = {
|
||||
{PTA17, ADC1_SE17, 0},
|
||||
{PTB0 , ADC0_SE8 , 0},
|
||||
{PTB1 , ADC0_SE9 , 0},
|
||||
{PTB2 , ADC0_SE12, 0},
|
||||
{PTB3 , ADC0_SE13, 0},
|
||||
{PTB6 , ADC1_SE12, 0},
|
||||
{PTB7 , ADC1_SE13, 0},
|
||||
{PTB10, ADC1_SE14, 0},
|
||||
{PTB11, ADC1_SE15, 0},
|
||||
{PTC0 , ADC0_SE14, 0},
|
||||
{PTC1 , ADC0_SE15, 0},
|
||||
{PTC2, ADC0_SE4b, 0},
|
||||
{PTC8, ADC1_SE4b, 0},
|
||||
{PTC9, ADC1_SE5b, 0},
|
||||
{PTC10, ADC1_SE6b, 0},
|
||||
{PTC11, ADC1_SE7b, 0},
|
||||
{PTD1, ADC0_SE5b, 0},
|
||||
{PTD5, ADC0_SE6b, 0},
|
||||
{PTD6, ADC0_SE7b, 0},
|
||||
{PTE0, ADC1_SE4a, 0},
|
||||
{PTE1, ADC1_SE5a, 0},
|
||||
{PTE2, ADC1_SE6a, 0},
|
||||
{PTE3, ADC1_SE7a, 0},
|
||||
//{PTE24, ADC0_SE17, 0}, //I2C pull up
|
||||
//{PTE25, ADC0_SE18, 0}, //I2C pull up
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
/************DAC***************/
|
||||
const PinMap PinMap_DAC[] = {
|
||||
{DAC0_OUT, DAC_0, 0},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
/************I2C***************/
|
||||
const PinMap PinMap_I2C_SDA[] = {
|
||||
{PTE25, I2C_0, 5},
|
||||
{PTB1 , I2C_0, 2},
|
||||
{PTB3 , I2C_0, 2},
|
||||
{PTC11, I2C_1, 2},
|
||||
{PTA13, I2C_2, 5},
|
||||
{PTD3 , I2C_0, 7},
|
||||
{PTE0 , I2C_1, 6},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_I2C_SCL[] = {
|
||||
{PTE24, I2C_0, 5},
|
||||
{PTB0 , I2C_0, 2},
|
||||
{PTB2 , I2C_0, 2},
|
||||
{PTC10, I2C_1, 2},
|
||||
{PTA12, I2C_2, 5},
|
||||
{PTA14, I2C_2, 5},
|
||||
{PTD2 , I2C_0, 7},
|
||||
{PTE1 , I2C_1, 6},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
/************UART***************/
|
||||
const PinMap PinMap_UART_TX[] = {
|
||||
{PTB17, UART_0, 3},
|
||||
{PTC17, UART_3, 3},
|
||||
{PTD7 , UART_0, 3},
|
||||
{PTD3 , UART_2, 3},
|
||||
{PTC4 , UART_1, 3},
|
||||
{PTC15, UART_4, 3},
|
||||
{PTB11, UART_3, 3},
|
||||
{PTA14, UART_0, 3},
|
||||
{PTE24, UART_4, 3},
|
||||
{PTE4 , UART_3, 3},
|
||||
{PTE0, UART_1, 3},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_UART_RX[] = {
|
||||
{PTB16, UART_0, 3},
|
||||
{PTE1 , UART_1, 3},
|
||||
{PTE5 , UART_3, 3},
|
||||
{PTE25, UART_4, 3},
|
||||
{PTA15, UART_0, 3},
|
||||
{PTC16, UART_3, 3},
|
||||
{PTB10, UART_3, 3},
|
||||
{PTC3 , UART_1, 3},
|
||||
{PTC14, UART_4, 3},
|
||||
{PTD2 , UART_2, 3},
|
||||
{PTD6 , UART_0, 3},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
/************SPI***************/
|
||||
const PinMap PinMap_SPI_SCLK[] = {
|
||||
{PTD1 , SPI_0, 2},
|
||||
{PTE2 , SPI_1, 2},
|
||||
{PTA15, SPI_0, 2},
|
||||
{PTB11, SPI_1, 2},
|
||||
{PTB21, SPI_2, 2},
|
||||
{PTC5 , SPI_0, 2},
|
||||
{PTD5 , SPI_1, 7},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_SPI_MOSI[] = {
|
||||
{PTD2 , SPI_0, 2},
|
||||
{PTE1 , SPI_1, 2},
|
||||
{PTE3 , SPI_1, 7},
|
||||
{PTA16, SPI_0, 2},
|
||||
{PTB16, SPI_1, 2},
|
||||
{PTB22, SPI_2, 2},
|
||||
{PTC6 , SPI_0, 2},
|
||||
{PTD6 , SPI_1, 7},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_SPI_MISO[] = {
|
||||
{PTD3 , SPI_0, 2},
|
||||
{PTE1 , SPI_1, 7},
|
||||
{PTE3 , SPI_1, 2},
|
||||
{PTA17, SPI_0, 2},
|
||||
{PTB17, SPI_1, 2},
|
||||
{PTB23, SPI_2, 2},
|
||||
{PTC7 , SPI_0, 2},
|
||||
{PTD7 , SPI_1, 7},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_SPI_SSEL[] = {
|
||||
{PTD0 , SPI_0, 2},
|
||||
{PTE4 , SPI_1, 2},
|
||||
{PTA14, SPI_0, 2},
|
||||
{PTB10, SPI_1, 2},
|
||||
{PTB20, SPI_2, 2},
|
||||
{PTC4 , SPI_0, 2},
|
||||
{PTD4 , SPI_1, 7},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
/************PWM***************/
|
||||
const PinMap PinMap_PWM[] = {
|
||||
{PTA0 , PWM_6 , 3},
|
||||
{PTA1 , PWM_7 , 3},
|
||||
{PTA2 , PWM_8 , 3},
|
||||
{PTA3 , PWM_1 , 3},
|
||||
{PTA4 , PWM_2 , 3},
|
||||
{PTA5 , PWM_3 , 3},
|
||||
{PTA6 , PWM_4 , 3},
|
||||
{PTA7 , PWM_5 , 3},
|
||||
{PTA8 , PWM_9 , 3},
|
||||
{PTA9 , PWM_10, 3},
|
||||
{PTA10, PWM_17, 3},
|
||||
{PTA11, PWM_18, 3},
|
||||
{PTA12, PWM_9 , 3},
|
||||
{PTA13, PWM_10, 3},
|
||||
|
||||
{PTB0 , PWM_9 , 3},
|
||||
{PTB1 , PWM_10, 3},
|
||||
{PTB18, PWM_17, 3},
|
||||
{PTB19, PWM_18, 3},
|
||||
|
||||
{PTC1 , PWM_1 , 4},
|
||||
{PTC2 , PWM_2 , 4},
|
||||
{PTC3 , PWM_3 , 4},
|
||||
{PTC4 , PWM_4 , 4},
|
||||
{PTC5 , PWM_3 , 7},
|
||||
{PTC8 , PWM_29, 3},
|
||||
{PTC9 , PWM_30, 3},
|
||||
{PTC10, PWM_31, 3},
|
||||
{PTC11, PWM_32, 3},
|
||||
|
||||
{PTD0 , PWM_25, 4},
|
||||
{PTD1 , PWM_26, 4},
|
||||
{PTD2 , PWM_27, 4},
|
||||
{PTD3 , PWM_28, 4},
|
||||
{PTD4 , PWM_5 , 4},
|
||||
{PTD5 , PWM_6 , 4},
|
||||
{PTD6 , PWM_7 , 4},
|
||||
{PTD4 , PWM_5 , 4},
|
||||
{PTD7 , PWM_8 , 4},
|
||||
|
||||
{PTE5 , PWM_25, 6},
|
||||
{PTE6 , PWM_26, 6},
|
||||
|
||||
{NC , NC , 0}
|
||||
};
|
|
@ -0,0 +1,258 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define GPIO_PORT_SHIFT 12
|
||||
|
||||
typedef enum {
|
||||
PTA0 = (0 << GPIO_PORT_SHIFT | 0 ),
|
||||
PTA1 = (0 << GPIO_PORT_SHIFT | 1 ),
|
||||
PTA2 = (0 << GPIO_PORT_SHIFT | 2 ),
|
||||
PTA3 = (0 << GPIO_PORT_SHIFT | 3 ),
|
||||
PTA4 = (0 << GPIO_PORT_SHIFT | 4 ),
|
||||
PTA5 = (0 << GPIO_PORT_SHIFT | 5 ),
|
||||
PTA6 = (0 << GPIO_PORT_SHIFT | 6 ),
|
||||
PTA7 = (0 << GPIO_PORT_SHIFT | 7 ),
|
||||
PTA8 = (0 << GPIO_PORT_SHIFT | 8 ),
|
||||
PTA9 = (0 << GPIO_PORT_SHIFT | 9 ),
|
||||
PTA10 = (0 << GPIO_PORT_SHIFT | 10),
|
||||
PTA11 = (0 << GPIO_PORT_SHIFT | 11),
|
||||
PTA12 = (0 << GPIO_PORT_SHIFT | 12),
|
||||
PTA13 = (0 << GPIO_PORT_SHIFT | 13),
|
||||
PTA14 = (0 << GPIO_PORT_SHIFT | 14),
|
||||
PTA15 = (0 << GPIO_PORT_SHIFT | 15),
|
||||
PTA16 = (0 << GPIO_PORT_SHIFT | 16),
|
||||
PTA17 = (0 << GPIO_PORT_SHIFT | 17),
|
||||
PTA18 = (0 << GPIO_PORT_SHIFT | 18),
|
||||
PTA19 = (0 << GPIO_PORT_SHIFT | 19),
|
||||
PTA20 = (0 << GPIO_PORT_SHIFT | 20),
|
||||
PTA21 = (0 << GPIO_PORT_SHIFT | 21),
|
||||
PTA22 = (0 << GPIO_PORT_SHIFT | 22),
|
||||
PTA23 = (0 << GPIO_PORT_SHIFT | 23),
|
||||
PTA24 = (0 << GPIO_PORT_SHIFT | 24),
|
||||
PTA25 = (0 << GPIO_PORT_SHIFT | 25),
|
||||
PTA26 = (0 << GPIO_PORT_SHIFT | 26),
|
||||
PTA27 = (0 << GPIO_PORT_SHIFT | 27),
|
||||
PTA28 = (0 << GPIO_PORT_SHIFT | 28),
|
||||
PTA29 = (0 << GPIO_PORT_SHIFT | 29),
|
||||
PTA30 = (0 << GPIO_PORT_SHIFT | 30),
|
||||
PTA31 = (0 << GPIO_PORT_SHIFT | 31),
|
||||
PTB0 = (1 << GPIO_PORT_SHIFT | 0 ),
|
||||
PTB1 = (1 << GPIO_PORT_SHIFT | 1 ),
|
||||
PTB2 = (1 << GPIO_PORT_SHIFT | 2 ),
|
||||
PTB3 = (1 << GPIO_PORT_SHIFT | 3 ),
|
||||
PTB4 = (1 << GPIO_PORT_SHIFT | 4 ),
|
||||
PTB5 = (1 << GPIO_PORT_SHIFT | 5 ),
|
||||
PTB6 = (1 << GPIO_PORT_SHIFT | 6 ),
|
||||
PTB7 = (1 << GPIO_PORT_SHIFT | 7 ),
|
||||
PTB8 = (1 << GPIO_PORT_SHIFT | 8 ),
|
||||
PTB9 = (1 << GPIO_PORT_SHIFT | 9 ),
|
||||
PTB10 = (1 << GPIO_PORT_SHIFT | 10),
|
||||
PTB11 = (1 << GPIO_PORT_SHIFT | 11),
|
||||
PTB12 = (1 << GPIO_PORT_SHIFT | 12),
|
||||
PTB13 = (1 << GPIO_PORT_SHIFT | 13),
|
||||
PTB14 = (1 << GPIO_PORT_SHIFT | 14),
|
||||
PTB15 = (1 << GPIO_PORT_SHIFT | 15),
|
||||
PTB16 = (1 << GPIO_PORT_SHIFT | 16),
|
||||
PTB17 = (1 << GPIO_PORT_SHIFT | 17),
|
||||
PTB18 = (1 << GPIO_PORT_SHIFT | 18),
|
||||
PTB19 = (1 << GPIO_PORT_SHIFT | 19),
|
||||
PTB20 = (1 << GPIO_PORT_SHIFT | 20),
|
||||
PTB21 = (1 << GPIO_PORT_SHIFT | 21),
|
||||
PTB22 = (1 << GPIO_PORT_SHIFT | 22),
|
||||
PTB23 = (1 << GPIO_PORT_SHIFT | 23),
|
||||
PTB24 = (1 << GPIO_PORT_SHIFT | 24),
|
||||
PTB25 = (1 << GPIO_PORT_SHIFT | 25),
|
||||
PTB26 = (1 << GPIO_PORT_SHIFT | 26),
|
||||
PTB27 = (1 << GPIO_PORT_SHIFT | 27),
|
||||
PTB28 = (1 << GPIO_PORT_SHIFT | 28),
|
||||
PTB29 = (1 << GPIO_PORT_SHIFT | 29),
|
||||
PTB30 = (1 << GPIO_PORT_SHIFT | 30),
|
||||
PTB31 = (1 << GPIO_PORT_SHIFT | 31),
|
||||
PTC0 = (2 << GPIO_PORT_SHIFT | 0 ),
|
||||
PTC1 = (2 << GPIO_PORT_SHIFT | 1 ),
|
||||
PTC2 = (2 << GPIO_PORT_SHIFT | 2 ),
|
||||
PTC3 = (2 << GPIO_PORT_SHIFT | 3 ),
|
||||
PTC4 = (2 << GPIO_PORT_SHIFT | 4 ),
|
||||
PTC5 = (2 << GPIO_PORT_SHIFT | 5 ),
|
||||
PTC6 = (2 << GPIO_PORT_SHIFT | 6 ),
|
||||
PTC7 = (2 << GPIO_PORT_SHIFT | 7 ),
|
||||
PTC8 = (2 << GPIO_PORT_SHIFT | 8 ),
|
||||
PTC9 = (2 << GPIO_PORT_SHIFT | 9 ),
|
||||
PTC10 = (2 << GPIO_PORT_SHIFT | 10),
|
||||
PTC11 = (2 << GPIO_PORT_SHIFT | 11),
|
||||
PTC12 = (2 << GPIO_PORT_SHIFT | 12),
|
||||
PTC13 = (2 << GPIO_PORT_SHIFT | 13),
|
||||
PTC14 = (2 << GPIO_PORT_SHIFT | 14),
|
||||
PTC15 = (2 << GPIO_PORT_SHIFT | 15),
|
||||
PTC16 = (2 << GPIO_PORT_SHIFT | 16),
|
||||
PTC17 = (2 << GPIO_PORT_SHIFT | 17),
|
||||
PTC18 = (2 << GPIO_PORT_SHIFT | 18),
|
||||
PTC19 = (2 << GPIO_PORT_SHIFT | 19),
|
||||
PTC20 = (2 << GPIO_PORT_SHIFT | 20),
|
||||
PTC21 = (2 << GPIO_PORT_SHIFT | 21),
|
||||
PTC22 = (2 << GPIO_PORT_SHIFT | 22),
|
||||
PTC23 = (2 << GPIO_PORT_SHIFT | 23),
|
||||
PTC24 = (2 << GPIO_PORT_SHIFT | 24),
|
||||
PTC25 = (2 << GPIO_PORT_SHIFT | 25),
|
||||
PTC26 = (2 << GPIO_PORT_SHIFT | 26),
|
||||
PTC27 = (2 << GPIO_PORT_SHIFT | 27),
|
||||
PTC28 = (2 << GPIO_PORT_SHIFT | 28),
|
||||
PTC29 = (2 << GPIO_PORT_SHIFT | 29),
|
||||
PTC30 = (2 << GPIO_PORT_SHIFT | 30),
|
||||
PTC31 = (2 << GPIO_PORT_SHIFT | 31),
|
||||
PTD0 = (3 << GPIO_PORT_SHIFT | 0 ),
|
||||
PTD1 = (3 << GPIO_PORT_SHIFT | 1 ),
|
||||
PTD2 = (3 << GPIO_PORT_SHIFT | 2 ),
|
||||
PTD3 = (3 << GPIO_PORT_SHIFT | 3 ),
|
||||
PTD4 = (3 << GPIO_PORT_SHIFT | 4 ),
|
||||
PTD5 = (3 << GPIO_PORT_SHIFT | 5 ),
|
||||
PTD6 = (3 << GPIO_PORT_SHIFT | 6 ),
|
||||
PTD7 = (3 << GPIO_PORT_SHIFT | 7 ),
|
||||
PTD8 = (3 << GPIO_PORT_SHIFT | 8 ),
|
||||
PTD9 = (3 << GPIO_PORT_SHIFT | 9 ),
|
||||
PTD10 = (3 << GPIO_PORT_SHIFT | 10),
|
||||
PTD11 = (3 << GPIO_PORT_SHIFT | 11),
|
||||
PTD12 = (3 << GPIO_PORT_SHIFT | 12),
|
||||
PTD13 = (3 << GPIO_PORT_SHIFT | 13),
|
||||
PTD14 = (3 << GPIO_PORT_SHIFT | 14),
|
||||
PTD15 = (3 << GPIO_PORT_SHIFT | 15),
|
||||
PTD16 = (3 << GPIO_PORT_SHIFT | 16),
|
||||
PTD17 = (3 << GPIO_PORT_SHIFT | 17),
|
||||
PTD18 = (3 << GPIO_PORT_SHIFT | 18),
|
||||
PTD19 = (3 << GPIO_PORT_SHIFT | 19),
|
||||
PTD20 = (3 << GPIO_PORT_SHIFT | 20),
|
||||
PTD21 = (3 << GPIO_PORT_SHIFT | 21),
|
||||
PTD22 = (3 << GPIO_PORT_SHIFT | 22),
|
||||
PTD23 = (3 << GPIO_PORT_SHIFT | 23),
|
||||
PTD24 = (3 << GPIO_PORT_SHIFT | 24),
|
||||
PTD25 = (3 << GPIO_PORT_SHIFT | 25),
|
||||
PTD26 = (3 << GPIO_PORT_SHIFT | 26),
|
||||
PTD27 = (3 << GPIO_PORT_SHIFT | 27),
|
||||
PTD28 = (3 << GPIO_PORT_SHIFT | 28),
|
||||
PTD29 = (3 << GPIO_PORT_SHIFT | 29),
|
||||
PTD30 = (3 << GPIO_PORT_SHIFT | 30),
|
||||
PTD31 = (3 << GPIO_PORT_SHIFT | 31),
|
||||
PTE0 = (4 << GPIO_PORT_SHIFT | 0 ),
|
||||
PTE1 = (4 << GPIO_PORT_SHIFT | 1 ),
|
||||
PTE2 = (4 << GPIO_PORT_SHIFT | 2 ),
|
||||
PTE3 = (4 << GPIO_PORT_SHIFT | 3 ),
|
||||
PTE4 = (4 << GPIO_PORT_SHIFT | 4 ),
|
||||
PTE5 = (4 << GPIO_PORT_SHIFT | 5 ),
|
||||
PTE6 = (4 << GPIO_PORT_SHIFT | 6 ),
|
||||
PTE7 = (4 << GPIO_PORT_SHIFT | 7 ),
|
||||
PTE8 = (4 << GPIO_PORT_SHIFT | 8 ),
|
||||
PTE9 = (4 << GPIO_PORT_SHIFT | 9 ),
|
||||
PTE10 = (4 << GPIO_PORT_SHIFT | 10),
|
||||
PTE11 = (4 << GPIO_PORT_SHIFT | 11),
|
||||
PTE12 = (4 << GPIO_PORT_SHIFT | 12),
|
||||
PTE13 = (4 << GPIO_PORT_SHIFT | 13),
|
||||
PTE14 = (4 << GPIO_PORT_SHIFT | 14),
|
||||
PTE15 = (4 << GPIO_PORT_SHIFT | 15),
|
||||
PTE16 = (4 << GPIO_PORT_SHIFT | 16),
|
||||
PTE17 = (4 << GPIO_PORT_SHIFT | 17),
|
||||
PTE18 = (4 << GPIO_PORT_SHIFT | 18),
|
||||
PTE19 = (4 << GPIO_PORT_SHIFT | 19),
|
||||
PTE20 = (4 << GPIO_PORT_SHIFT | 20),
|
||||
PTE21 = (4 << GPIO_PORT_SHIFT | 21),
|
||||
PTE22 = (4 << GPIO_PORT_SHIFT | 22),
|
||||
PTE23 = (4 << GPIO_PORT_SHIFT | 23),
|
||||
PTE24 = (4 << GPIO_PORT_SHIFT | 24),
|
||||
PTE25 = (4 << GPIO_PORT_SHIFT | 25),
|
||||
PTE26 = (4 << GPIO_PORT_SHIFT | 26),
|
||||
PTE27 = (4 << GPIO_PORT_SHIFT | 27),
|
||||
PTE28 = (4 << GPIO_PORT_SHIFT | 28),
|
||||
PTE29 = (4 << GPIO_PORT_SHIFT | 29),
|
||||
PTE30 = (4 << GPIO_PORT_SHIFT | 30),
|
||||
PTE31 = (4 << GPIO_PORT_SHIFT | 31),
|
||||
|
||||
LED_RED = PTB22,
|
||||
LED_GREEN = PTE26,
|
||||
LED_BLUE = PTB21,
|
||||
|
||||
// mbed original LED naming
|
||||
LED1 = LED_RED,
|
||||
LED2 = LED_GREEN,
|
||||
LED3 = LED_BLUE,
|
||||
LED4 = LED_RED,
|
||||
|
||||
//Push buttons
|
||||
SW2 = PTC6,
|
||||
SW3 = PTA4,
|
||||
|
||||
// USB Pins
|
||||
USBTX = PTB17,
|
||||
USBRX = PTB16,
|
||||
|
||||
// Arduino Headers
|
||||
D0 = PTC16,
|
||||
D1 = PTC17,
|
||||
D2 = PTB9,
|
||||
D3 = PTA1,
|
||||
D4 = PTB23,
|
||||
D5 = PTA2,
|
||||
D6 = PTC2,
|
||||
D7 = PTC3,
|
||||
D8 = PTA0,
|
||||
D9 = PTC4,
|
||||
D10 = PTD0,
|
||||
D11 = PTD2,
|
||||
D12 = PTD3,
|
||||
D13 = PTD1,
|
||||
D14 = PTE25,
|
||||
D15 = PTE24,
|
||||
|
||||
I2C_SCL = D15,
|
||||
I2C_SDA = D14,
|
||||
|
||||
A0 = PTB2,
|
||||
A1 = PTB3,
|
||||
A2 = PTB10,
|
||||
A3 = PTB11,
|
||||
A4 = PTC11,
|
||||
A5 = PTC10,
|
||||
|
||||
DAC0_OUT = 0xFEFE, /* DAC does not have Pin Name in RM */
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF
|
||||
} PinName;
|
||||
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 1,
|
||||
PullUp = 2,
|
||||
PullDefault = PullUp
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,234 @@
|
|||
/**********************************************************************
|
||||
*
|
||||
* Filename: crc.c
|
||||
*
|
||||
* Description: Slow and fast implementations of the CRC standards.
|
||||
*
|
||||
* Notes: The parameters for each supported CRC standard are
|
||||
* defined in the header file crc.h. The implementations
|
||||
* here should stand up to further additions to that list.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2000 by Michael Barr. This software is placed into
|
||||
* the public domain and may be used for any purpose. However, this
|
||||
* notice must not be changed or removed and no warranty is either
|
||||
* expressed or implied by its publication or distribution.
|
||||
**********************************************************************/
|
||||
|
||||
#include "crc.h"
|
||||
|
||||
|
||||
/*
|
||||
* Derive parameters from the standard-specific parameters in crc.h.
|
||||
*/
|
||||
#define WIDTH (8 * sizeof(crc))
|
||||
#define TOPBIT (1 << (WIDTH - 1))
|
||||
|
||||
#if (REFLECT_DATA == TRUE)
|
||||
#undef REFLECT_DATA
|
||||
#define REFLECT_DATA(X) ((unsigned char) reflect((X), 8))
|
||||
#else
|
||||
#undef REFLECT_DATA
|
||||
#define REFLECT_DATA(X) (X)
|
||||
#endif
|
||||
|
||||
#if (REFLECT_REMAINDER == TRUE)
|
||||
#undef REFLECT_REMAINDER
|
||||
#define REFLECT_REMAINDER(X) ((crc) reflect((X), WIDTH))
|
||||
#else
|
||||
#undef REFLECT_REMAINDER
|
||||
#define REFLECT_REMAINDER(X) (X)
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function: reflect()
|
||||
*
|
||||
* Description: Reorder the bits of a binary sequence, by reflecting
|
||||
* them about the middle position.
|
||||
*
|
||||
* Notes: No checking is done that nBits <= 32.
|
||||
*
|
||||
* Returns: The reflection of the original data.
|
||||
*
|
||||
*********************************************************************/
|
||||
static unsigned long
|
||||
reflect(unsigned long data, unsigned char nBits)
|
||||
{
|
||||
unsigned long reflection = 0x00000000;
|
||||
unsigned char bit;
|
||||
|
||||
/*
|
||||
* Reflect the data about the center bit.
|
||||
*/
|
||||
for (bit = 0; bit < nBits; ++bit)
|
||||
{
|
||||
/*
|
||||
* If the LSB bit is set, set the reflection of it.
|
||||
*/
|
||||
if (data & 0x01)
|
||||
{
|
||||
reflection |= (1 << ((nBits - 1) - bit));
|
||||
}
|
||||
|
||||
data = (data >> 1);
|
||||
}
|
||||
|
||||
return (reflection);
|
||||
|
||||
} /* reflect() */
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function: crcSlow()
|
||||
*
|
||||
* Description: Compute the CRC of a given message.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Returns: The CRC of the message.
|
||||
*
|
||||
*********************************************************************/
|
||||
crc
|
||||
crcSlow(unsigned char const message[], int nBytes)
|
||||
{
|
||||
crc remainder = INITIAL_REMAINDER;
|
||||
int byte;
|
||||
unsigned char bit;
|
||||
|
||||
|
||||
/*
|
||||
* Perform modulo-2 division, a byte at a time.
|
||||
*/
|
||||
for (byte = 0; byte < nBytes; ++byte)
|
||||
{
|
||||
/*
|
||||
* Bring the next byte into the remainder.
|
||||
*/
|
||||
remainder ^= (REFLECT_DATA(message[byte]) << (WIDTH - 8));
|
||||
|
||||
/*
|
||||
* Perform modulo-2 division, a bit at a time.
|
||||
*/
|
||||
for (bit = 8; bit > 0; --bit)
|
||||
{
|
||||
/*
|
||||
* Try to divide the current data bit.
|
||||
*/
|
||||
if (remainder & TOPBIT)
|
||||
{
|
||||
remainder = (remainder << 1) ^ POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
remainder = (remainder << 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The final remainder is the CRC result.
|
||||
*/
|
||||
return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
|
||||
|
||||
} /* crcSlow() */
|
||||
|
||||
|
||||
crc crcTable[256];
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function: crcInit()
|
||||
*
|
||||
* Description: Populate the partial CRC lookup table.
|
||||
*
|
||||
* Notes: This function must be rerun any time the CRC standard
|
||||
* is changed. If desired, it can be run "offline" and
|
||||
* the table results stored in an embedded system's ROM.
|
||||
*
|
||||
* Returns: None defined.
|
||||
*
|
||||
*********************************************************************/
|
||||
void
|
||||
crcInit(void)
|
||||
{
|
||||
crc remainder;
|
||||
int dividend;
|
||||
unsigned char bit;
|
||||
|
||||
|
||||
/*
|
||||
* Compute the remainder of each possible dividend.
|
||||
*/
|
||||
for (dividend = 0; dividend < 256; ++dividend)
|
||||
{
|
||||
/*
|
||||
* Start with the dividend followed by zeros.
|
||||
*/
|
||||
remainder = dividend << (WIDTH - 8);
|
||||
|
||||
/*
|
||||
* Perform modulo-2 division, a bit at a time.
|
||||
*/
|
||||
for (bit = 8; bit > 0; --bit)
|
||||
{
|
||||
/*
|
||||
* Try to divide the current data bit.
|
||||
*/
|
||||
if (remainder & TOPBIT)
|
||||
{
|
||||
remainder = (remainder << 1) ^ POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
remainder = (remainder << 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the result into the table.
|
||||
*/
|
||||
crcTable[dividend] = remainder;
|
||||
}
|
||||
|
||||
} /* crcInit() */
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function: crcFast()
|
||||
*
|
||||
* Description: Compute the CRC of a given message.
|
||||
*
|
||||
* Notes: crcInit() must be called first.
|
||||
*
|
||||
* Returns: The CRC of the message.
|
||||
*
|
||||
*********************************************************************/
|
||||
crc
|
||||
crcFast(unsigned char const message[], int nBytes)
|
||||
{
|
||||
crc remainder = INITIAL_REMAINDER;
|
||||
unsigned char data;
|
||||
int byte;
|
||||
|
||||
|
||||
/*
|
||||
* Divide the message by the polynomial, a byte at a time.
|
||||
*/
|
||||
for (byte = 0; byte < nBytes; ++byte)
|
||||
{
|
||||
data = REFLECT_DATA(message[byte]) ^ (remainder >> (WIDTH - 8));
|
||||
remainder = crcTable[data] ^ (remainder << 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* The final remainder is the CRC.
|
||||
*/
|
||||
return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
|
||||
|
||||
} /* crcFast() */
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/**********************************************************************
|
||||
*
|
||||
* Filename: crc.h
|
||||
*
|
||||
* Description: A header file describing the various CRC standards.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2000 by Michael Barr. This software is placed into
|
||||
* the public domain and may be used for any purpose. However, this
|
||||
* notice must not be changed or removed and no warranty is either
|
||||
* expressed or implied by its publication or distribution.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef _crc_h
|
||||
#define _crc_h
|
||||
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE !FALSE
|
||||
|
||||
/*
|
||||
* Select the CRC standard from the list that follows.
|
||||
*/
|
||||
#define CRC16
|
||||
|
||||
|
||||
#if defined(CRC_CCITT)
|
||||
|
||||
typedef unsigned short crc;
|
||||
|
||||
#define CRC_NAME "CRC-CCITT"
|
||||
#define POLYNOMIAL 0x1021
|
||||
#define INITIAL_REMAINDER 0xFFFF
|
||||
#define FINAL_XOR_VALUE 0x0000
|
||||
#define REFLECT_DATA FALSE
|
||||
#define REFLECT_REMAINDER FALSE
|
||||
#define CHECK_VALUE 0x29B1
|
||||
|
||||
#elif defined(CRC16)
|
||||
|
||||
typedef unsigned short crc;
|
||||
|
||||
#define CRC_NAME "CRC-16"
|
||||
#define POLYNOMIAL 0x8005
|
||||
#define INITIAL_REMAINDER 0x0000
|
||||
#define FINAL_XOR_VALUE 0x0000
|
||||
#define REFLECT_DATA TRUE
|
||||
#define REFLECT_REMAINDER TRUE
|
||||
#define CHECK_VALUE 0xBB3D
|
||||
|
||||
#elif defined(CRC32)
|
||||
|
||||
typedef unsigned long crc;
|
||||
|
||||
#define CRC_NAME "CRC-32"
|
||||
#define POLYNOMIAL 0x04C11DB7
|
||||
#define INITIAL_REMAINDER 0xFFFFFFFF
|
||||
#define FINAL_XOR_VALUE 0xFFFFFFFF
|
||||
#define REFLECT_DATA TRUE
|
||||
#define REFLECT_REMAINDER TRUE
|
||||
#define CHECK_VALUE 0xCBF43926
|
||||
|
||||
#else
|
||||
|
||||
#error "One of CRC_CCITT, CRC16, or CRC32 must be #define'd."
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void crcInit(void);
|
||||
crc crcSlow(unsigned char const message[], int nBytes);
|
||||
crc crcFast(unsigned char const message[], int nBytes);
|
||||
|
||||
|
||||
#endif /* _crc_h */
|
|
@ -0,0 +1,58 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MBED_DEVICE_H
|
||||
#define MBED_DEVICE_H
|
||||
|
||||
#define DEVICE_PORTIN 1
|
||||
#define DEVICE_PORTOUT 1
|
||||
#define DEVICE_PORTINOUT 1
|
||||
|
||||
#define DEVICE_INTERRUPTIN 1
|
||||
|
||||
#define DEVICE_ANALOGIN 1
|
||||
#define DEVICE_ANALOGOUT 1
|
||||
|
||||
#define DEVICE_SERIAL 1
|
||||
|
||||
#define DEVICE_I2C 1
|
||||
#define DEVICE_I2CSLAVE 1
|
||||
|
||||
#define DEVICE_SPI 1
|
||||
#define DEVICE_SPISLAVE 1
|
||||
|
||||
#define DEVICE_CAN 0
|
||||
|
||||
#define DEVICE_RTC 1
|
||||
|
||||
#define DEVICE_ETHERNET 0
|
||||
|
||||
#define DEVICE_PWMOUT 1
|
||||
|
||||
#define DEVICE_SEMIHOST 0
|
||||
#define DEVICE_LOCALFILESYSTEM 0
|
||||
#define DEVICE_ID_LENGTH 24
|
||||
|
||||
#define DEVICE_SLEEP 1
|
||||
|
||||
#define DEVICE_DEBUG_AWARENESS 0
|
||||
|
||||
#define DEVICE_STDIO_MESSAGES 1
|
||||
|
||||
#define DEVICE_ERROR_RED 1
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_smc.h"
|
||||
#include "fsl_clock_config.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief Clock configuration structure. */
|
||||
typedef struct _clock_config
|
||||
{
|
||||
mcg_config_t mcgConfig; /*!< MCG configuration. */
|
||||
sim_clock_config_t simConfig; /*!< SIM configuration. */
|
||||
osc_config_t oscConfig; /*!< OSC configuration. */
|
||||
uint32_t coreClock; /*!< core clock frequency. */
|
||||
} clock_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/* System clock frequency. */
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
/* Configuration for enter VLPR mode. Core clock = 4MHz. */
|
||||
const clock_config_t g_defaultClockConfigVlpr = {
|
||||
.mcgConfig =
|
||||
{
|
||||
.mcgMode = kMCG_ModeBLPI, /* Work in BLPI mode. */
|
||||
.irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enable. */
|
||||
.ircs = kMCG_IrcFast, /* Select IRC4M. */
|
||||
.fcrdiv = 0U, /* FCRDIV is 0. */
|
||||
|
||||
.frdiv = 0U,
|
||||
.drs = kMCG_DrsLow, /* Low frequency range. */
|
||||
.dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25%. */
|
||||
.oscsel = kMCG_OscselOsc, /* Select OSC. */
|
||||
|
||||
.pll0Config =
|
||||
{
|
||||
.enableMode = 0U, /* Don't eanble PLL. */
|
||||
.prdiv = 0U,
|
||||
.vdiv = 0U,
|
||||
},
|
||||
},
|
||||
.simConfig =
|
||||
{
|
||||
.pllFllSel = 3U, /* PLLFLLSEL select IRC48MCLK. */
|
||||
.er32kSrc = 2U, /* ERCLK32K selection, use RTC. */
|
||||
.clkdiv1 = 0x00040000U, /* SIM_CLKDIV1. */
|
||||
},
|
||||
.oscConfig = {.freq = BOARD_XTAL0_CLK_HZ,
|
||||
.capLoad = 0,
|
||||
.workMode = kOSC_ModeExt,
|
||||
.oscerConfig =
|
||||
{
|
||||
.enableMode = kOSC_ErClkEnable,
|
||||
#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER)
|
||||
.erclkDiv = 0U,
|
||||
#endif
|
||||
}},
|
||||
.coreClock = 4000000U, /* Core clock frequency */
|
||||
};
|
||||
|
||||
/* Configuration for enter RUN mode. Core clock = 120MHz. */
|
||||
const clock_config_t g_defaultClockConfigRun = {
|
||||
.mcgConfig =
|
||||
{
|
||||
.mcgMode = kMCG_ModePEE, /* Work in PEE mode. */
|
||||
.irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enable. */
|
||||
.ircs = kMCG_IrcSlow, /* Select IRC32k. */
|
||||
.fcrdiv = 0U, /* FCRDIV is 0. */
|
||||
|
||||
.frdiv = 7U,
|
||||
.drs = kMCG_DrsLow, /* Low frequency range. */
|
||||
.dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25%. */
|
||||
.oscsel = kMCG_OscselOsc, /* Select OSC. */
|
||||
|
||||
.pll0Config =
|
||||
{
|
||||
.enableMode = 0U, .prdiv = 0x13U, .vdiv = 0x18U,
|
||||
},
|
||||
},
|
||||
.simConfig =
|
||||
{
|
||||
.pllFllSel = 1U, /* PLLFLLSEL select PLL. */
|
||||
.er32kSrc = 2U, /* ERCLK32K selection, use RTC. */
|
||||
.clkdiv1 = 0x01140000U, /* SIM_CLKDIV1. */
|
||||
},
|
||||
.oscConfig = {.freq = BOARD_XTAL0_CLK_HZ,
|
||||
.capLoad = 0,
|
||||
.workMode = kOSC_ModeExt,
|
||||
.oscerConfig =
|
||||
{
|
||||
.enableMode = kOSC_ErClkEnable,
|
||||
#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER)
|
||||
.erclkDiv = 0U,
|
||||
#endif
|
||||
}},
|
||||
.coreClock = 120000000U, /* Core clock frequency */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
/*
|
||||
* How to setup clock using clock driver functions:
|
||||
*
|
||||
* 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock
|
||||
* and flash clock are in allowed range during clock mode switch.
|
||||
*
|
||||
* 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode.
|
||||
*
|
||||
* 3. Set MCG configuration, MCG includes three parts: FLL clock, PLL clock and
|
||||
* internal reference clock(MCGIRCLK). Follow the steps to setup:
|
||||
*
|
||||
* 1). Call CLOCK_BootToXxxMode to set MCG to target mode.
|
||||
*
|
||||
* 2). If target mode is FBI/BLPI/PBI mode, the MCGIRCLK has been configured
|
||||
* correctly. For other modes, need to call CLOCK_SetInternalRefClkConfig
|
||||
* explicitly to setup MCGIRCLK.
|
||||
*
|
||||
* 3). Don't need to configure FLL explicitly, because if target mode is FLL
|
||||
* mode, then FLL has been configured by the function CLOCK_BootToXxxMode,
|
||||
* if the target mode is not FLL mode, the FLL is disabled.
|
||||
*
|
||||
* 4). If target mode is PEE/PBE/PEI/PBI mode, then the related PLL has been
|
||||
* setup by CLOCK_BootToXxxMode. In FBE/FBI/FEE/FBE mode, the PLL could
|
||||
* be enabled independently, call CLOCK_EnablePll0 explicitly in this case.
|
||||
*
|
||||
* 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM.
|
||||
*/
|
||||
|
||||
void BOARD_BootClockVLPR(void)
|
||||
{
|
||||
CLOCK_SetSimSafeDivs();
|
||||
|
||||
CLOCK_BootToBlpiMode(g_defaultClockConfigVlpr.mcgConfig.fcrdiv, g_defaultClockConfigVlpr.mcgConfig.ircs,
|
||||
g_defaultClockConfigVlpr.mcgConfig.irclkEnableMode);
|
||||
|
||||
CLOCK_SetSimConfig(&g_defaultClockConfigVlpr.simConfig);
|
||||
|
||||
SystemCoreClock = g_defaultClockConfigVlpr.coreClock;
|
||||
|
||||
SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll);
|
||||
SMC_SetPowerModeVlpr(SMC, false);
|
||||
while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void BOARD_BootClockRUN(void)
|
||||
{
|
||||
CLOCK_SetSimSafeDivs();
|
||||
|
||||
CLOCK_InitOsc0(&g_defaultClockConfigRun.oscConfig);
|
||||
CLOCK_SetXtal0Freq(BOARD_XTAL0_CLK_HZ);
|
||||
|
||||
CLOCK_BootToPeeMode(g_defaultClockConfigRun.mcgConfig.oscsel, kMCG_PllClkSelPll0,
|
||||
&g_defaultClockConfigRun.mcgConfig.pll0Config);
|
||||
|
||||
CLOCK_SetInternalRefClkConfig(g_defaultClockConfigRun.mcgConfig.irclkEnableMode,
|
||||
g_defaultClockConfigRun.mcgConfig.ircs, g_defaultClockConfigRun.mcgConfig.fcrdiv);
|
||||
|
||||
CLOCK_SetSimConfig(&g_defaultClockConfigRun.simConfig);
|
||||
|
||||
SystemCoreClock = g_defaultClockConfigRun.coreClock;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _CLOCK_CONFIG_H_
|
||||
#define _CLOCK_CONFIG_H_
|
||||
|
||||
/*******************************************************************************
|
||||
* DEFINITION
|
||||
******************************************************************************/
|
||||
#define BOARD_XTAL0_CLK_HZ 50000000U
|
||||
#define BOARD_XTAL32K_CLK_HZ 32768U
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
void BOARD_BootClockVLPR(void);
|
||||
void BOARD_BootClockRUN(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
#endif /* _CLOCK_CONFIG_H_ */
|
|
@ -0,0 +1,79 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "gpio_api.h"
|
||||
|
||||
#define CRC16
|
||||
#include "crc.h"
|
||||
#include "fsl_clock_config.h"
|
||||
|
||||
// called before main
|
||||
void mbed_sdk_init()
|
||||
{
|
||||
BOARD_BootClockRUN();
|
||||
}
|
||||
|
||||
// Change the NMI pin to an input. This allows NMI pin to
|
||||
// be used as a low power mode wakeup. The application will
|
||||
// need to change the pin back to NMI_b or wakeup only occurs once!
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
gpio_t gpio;
|
||||
gpio_init_in(&gpio, PTA4);
|
||||
}
|
||||
|
||||
// Enable the RTC oscillator if available on the board
|
||||
void rtc_setup_oscillator(RTC_Type *base)
|
||||
{
|
||||
/* Enable the RTC oscillator */
|
||||
RTC->CR |= RTC_CR_OSCE_MASK;
|
||||
}
|
||||
|
||||
// Provide ethernet devices with a semi-unique MAC address from the UUID
|
||||
void mbed_mac_address(char *mac)
|
||||
{
|
||||
|
||||
unsigned int UUID_LOC_BASE = 0x40048054; // First adddress of the 4-word UUID
|
||||
char uuid[16]; // So we can take a local copy of the UUID
|
||||
uint32_t MAC[3]; // 3 16 bits words for the MAC
|
||||
|
||||
// copy the UUID to the variable MAC[]
|
||||
memcpy(uuid,(const void*)UUID_LOC_BASE,sizeof(uuid));
|
||||
|
||||
// generate three CRC16's using different slices of the UUID
|
||||
MAC[0] = crcSlow(uuid, 8); // most significant half-word
|
||||
MAC[1] = crcSlow(uuid, 12);
|
||||
MAC[2] = crcSlow(uuid, 16); // least significant half word
|
||||
|
||||
// The network stack expects an array of 6 bytes
|
||||
// so we copy, and shift and copy from the half-word array to the byte array
|
||||
mac[0] = MAC[0] >> 8;
|
||||
mac[1] = MAC[0];
|
||||
mac[2] = MAC[1] >> 8;
|
||||
mac[3] = MAC[1];
|
||||
mac[4] = MAC[2] >> 8;
|
||||
mac[5] = MAC[2];
|
||||
|
||||
// We want to force bits [1:0] of the most significant byte [0]
|
||||
// to be "10"
|
||||
// http://en.wikipedia.org/wiki/MAC_address
|
||||
|
||||
mac[0] |= 0x02; // force bit 1 to a "1" = "Locally Administered"
|
||||
mac[0] &= 0xFE; // force bit 0 to a "0" = Unicast
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MBED_PERIPHERALNAMES_H
|
||||
#define MBED_PERIPHERALNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
OSC32KCLK = 0,
|
||||
} RTCName;
|
||||
|
||||
typedef enum {
|
||||
UART_0 = 0,
|
||||
UART_2 = 2,
|
||||
UART_3 = 3,
|
||||
UART_5 = 5,
|
||||
} UARTName;
|
||||
|
||||
#define STDIO_UART_TX USBTX
|
||||
#define STDIO_UART_RX USBRX
|
||||
#define STDIO_UART UART_0
|
||||
|
||||
typedef enum {
|
||||
I2C_0 = 0,
|
||||
I2C_1 = 1,
|
||||
} I2CName;
|
||||
|
||||
|
||||
#define TPM_SHIFT 8
|
||||
typedef enum {
|
||||
PWM_1 = (0 << TPM_SHIFT) | (0), // FTM0 CH0
|
||||
PWM_2 = (0 << TPM_SHIFT) | (1), // FTM0 CH1
|
||||
PWM_3 = (0 << TPM_SHIFT) | (2), // FTM0 CH2
|
||||
PWM_4 = (0 << TPM_SHIFT) | (3), // FTM0 CH3
|
||||
PWM_5 = (0 << TPM_SHIFT) | (4), // FTM0 CH4
|
||||
PWM_6 = (0 << TPM_SHIFT) | (5), // FTM0 CH5
|
||||
PWM_7 = (0 << TPM_SHIFT) | (6), // FTM0 CH6
|
||||
PWM_8 = (0 << TPM_SHIFT) | (7), // FTM0 CH7
|
||||
PWM_9 = (1 << TPM_SHIFT) | (0), // FTM1 CH0
|
||||
PWM_10 = (1 << TPM_SHIFT) | (1), // FTM1 CH1
|
||||
PWM_11 = (1 << TPM_SHIFT) | (2), // FTM1 CH2
|
||||
PWM_12 = (1 << TPM_SHIFT) | (3), // FTM1 CH3
|
||||
PWM_13 = (1 << TPM_SHIFT) | (4), // FTM1 CH4
|
||||
PWM_14 = (1 << TPM_SHIFT) | (5), // FTM1 CH5
|
||||
PWM_15 = (1 << TPM_SHIFT) | (6), // FTM1 CH6
|
||||
PWM_16 = (1 << TPM_SHIFT) | (7), // FTM1 CH7
|
||||
PWM_17 = (2 << TPM_SHIFT) | (0), // FTM2 CH0
|
||||
PWM_18 = (2 << TPM_SHIFT) | (1), // FTM2 CH1
|
||||
PWM_19 = (2 << TPM_SHIFT) | (2), // FTM2 CH2
|
||||
PWM_20 = (2 << TPM_SHIFT) | (3), // FTM2 CH3
|
||||
PWM_21 = (2 << TPM_SHIFT) | (4), // FTM2 CH4
|
||||
PWM_22 = (2 << TPM_SHIFT) | (5), // FTM2 CH5
|
||||
PWM_23 = (2 << TPM_SHIFT) | (6), // FTM2 CH6
|
||||
PWM_24 = (2 << TPM_SHIFT) | (7), // FTM2 CH7
|
||||
// could be 4 or could be 3... not sure what register
|
||||
// this is for... too much abstraction
|
||||
PWM_25 = (3 << TPM_SHIFT) | (0), // FTM3 CH0
|
||||
PWM_26 = (3 << TPM_SHIFT) | (1), // FTM3 CH1
|
||||
PWM_27 = (3 << TPM_SHIFT) | (2), // FTM3 CH2
|
||||
PWM_28 = (3 << TPM_SHIFT) | (3), // FTM3 CH3
|
||||
PWM_29 = (3 << TPM_SHIFT) | (4), // FTM3 CH4
|
||||
PWM_30 = (3 << TPM_SHIFT) | (5), // FTM3 CH5
|
||||
PWM_31 = (3 << TPM_SHIFT) | (6), // FTM3 CH6
|
||||
PWM_32 = (3 << TPM_SHIFT) | (7), // FTM3 CH7
|
||||
} PWMName;
|
||||
|
||||
|
||||
|
||||
#define ADC_INSTANCE_SHIFT 8
|
||||
#define ADC_B_CHANNEL_SHIFT 5
|
||||
typedef enum {
|
||||
ADC0_SE4b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 4,
|
||||
ADC0_SE5b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 5,
|
||||
ADC0_SE6b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 6,
|
||||
ADC0_SE7b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 7,
|
||||
ADC0_SE8 = (0 << ADC_INSTANCE_SHIFT) | 8,
|
||||
ADC0_SE9 = (0 << ADC_INSTANCE_SHIFT) | 9,
|
||||
ADC0_SE12 = (0 << ADC_INSTANCE_SHIFT) | 12,
|
||||
ADC0_SE13 = (0 << ADC_INSTANCE_SHIFT) | 13,
|
||||
ADC0_SE14 = (0 << ADC_INSTANCE_SHIFT) | 14,
|
||||
ADC0_SE15 = (0 << ADC_INSTANCE_SHIFT) | 15,
|
||||
ADC0_SE16 = (0 << ADC_INSTANCE_SHIFT) | 16,
|
||||
ADC0_SE17 = (0 << ADC_INSTANCE_SHIFT) | 17,
|
||||
ADC0_SE18 = (0 << ADC_INSTANCE_SHIFT) | 18,
|
||||
ADC1_SE4b = (1 << ADC_INSTANCE_SHIFT) | 4,
|
||||
ADC1_SE5b = (1 << ADC_INSTANCE_SHIFT) | 5,
|
||||
ADC1_SE6b = (1 << ADC_INSTANCE_SHIFT) | 6,
|
||||
ADC1_SE7b = (1 << ADC_INSTANCE_SHIFT) | 7,
|
||||
ADC1_SE8 = (1 << ADC_INSTANCE_SHIFT) | 8,
|
||||
ADC1_SE9 = (1 << ADC_INSTANCE_SHIFT) | 9,
|
||||
ADC1_SE12 = (1 << ADC_INSTANCE_SHIFT) | 12,
|
||||
ADC1_SE13 = (1 << ADC_INSTANCE_SHIFT) | 13,
|
||||
ADC1_SE14 = (1 << ADC_INSTANCE_SHIFT) | 14,
|
||||
ADC1_SE15 = (1 << ADC_INSTANCE_SHIFT) | 15,
|
||||
ADC1_SE16 = (1 << ADC_INSTANCE_SHIFT) | 16,
|
||||
ADC1_SE17 = (1 << ADC_INSTANCE_SHIFT) | 17,
|
||||
ADC1_SE18 = (1 << ADC_INSTANCE_SHIFT) | 18,
|
||||
} ADCName;
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
DAC_0 = 0
|
||||
} DACName;
|
||||
|
||||
|
||||
typedef enum {
|
||||
SPI_0 = 0,
|
||||
SPI_1 = 1,
|
||||
} SPIName;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,112 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "PeripheralPins.h"
|
||||
|
||||
/************RTC***************/
|
||||
const PinMap PinMap_RTC[] = {
|
||||
{NC, OSC32KCLK, 0},
|
||||
};
|
||||
|
||||
/************I2C***************/
|
||||
const PinMap PinMap_I2C_SDA[] = {
|
||||
{PTE25, I2C_0, 5},
|
||||
{PTB1 , I2C_0, 2},
|
||||
{PTB3 , I2C_0, 2},
|
||||
{PTC11, I2C_1, 2},
|
||||
{PTD3 , I2C_0, 7},
|
||||
{PTE0 , I2C_1, 6},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_I2C_SCL[] = {
|
||||
{PTE24, I2C_0, 5},
|
||||
{PTB0 , I2C_0, 2},
|
||||
{PTB2 , I2C_0, 2},
|
||||
{PTC10, I2C_1, 2},
|
||||
{PTD2 , I2C_0, 7},
|
||||
{PTE1 , I2C_1, 6},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
/************UART***************/
|
||||
const PinMap PinMap_UART_TX[] = {
|
||||
{PTB17, UART_0, 3},
|
||||
{PTC17, UART_3, 3},
|
||||
{PTD7 , UART_0, 3},
|
||||
{PTD3 , UART_2, 3},
|
||||
{PTB11, UART_3, 3},
|
||||
{PTA14, UART_0, 3},
|
||||
{PTE4 , UART_3, 3},
|
||||
{PTE8 , UART_5, 3},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_UART_RX[] = {
|
||||
{PTB16, UART_0, 3},
|
||||
{PTE5 , UART_3, 3},
|
||||
{PTA15, UART_0, 3},
|
||||
{PTC16, UART_3, 3},
|
||||
{PTB10, UART_3, 3},
|
||||
{PTD2 , UART_2, 3},
|
||||
{PTC6 , UART_0, 3},
|
||||
{PTE9 , UART_5, 3},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
/************SPI***************/
|
||||
const PinMap PinMap_SPI_SCLK[] = {
|
||||
{PTD1 , SPI_0, 2},
|
||||
{PTE2 , SPI_1, 2},
|
||||
{PTA15, SPI_0, 2},
|
||||
{PTB11, SPI_1, 2},
|
||||
{PTC5 , SPI_0, 2},
|
||||
{PTD5 , SPI_1, 7},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_SPI_MOSI[] = {
|
||||
{PTD2 , SPI_0, 2},
|
||||
{PTE1 , SPI_1, 2},
|
||||
{PTE3 , SPI_1, 7},
|
||||
{PTA16, SPI_0, 2},
|
||||
{PTB16, SPI_1, 2},
|
||||
{PTC6 , SPI_0, 2},
|
||||
{PTD6 , SPI_1, 7},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_SPI_MISO[] = {
|
||||
{PTD3 , SPI_0, 2},
|
||||
{PTE1 , SPI_1, 7},
|
||||
{PTE3 , SPI_1, 2},
|
||||
{PTA17, SPI_0, 2},
|
||||
{PTB17, SPI_1, 2},
|
||||
{PTC7 , SPI_0, 2},
|
||||
{PTD7 , SPI_1, 7},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
const PinMap PinMap_SPI_SSEL[] = {
|
||||
{PTD0 , SPI_0, 2},
|
||||
{PTE4 , SPI_1, 2},
|
||||
{PTA14, SPI_0, 2},
|
||||
{PTB10, SPI_1, 2},
|
||||
{PTC4 , SPI_0, 2},
|
||||
{PTD4 , SPI_1, 7},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define GPIO_PORT_SHIFT 12
|
||||
|
||||
typedef enum {
|
||||
PTA0 = (0 << GPIO_PORT_SHIFT | 0 ),
|
||||
PTA1 = (0 << GPIO_PORT_SHIFT | 1 ),
|
||||
PTA2 = (0 << GPIO_PORT_SHIFT | 2 ),
|
||||
PTA3 = (0 << GPIO_PORT_SHIFT | 3 ),
|
||||
PTA4 = (0 << GPIO_PORT_SHIFT | 4 ),
|
||||
PTA5 = (0 << GPIO_PORT_SHIFT | 5 ),
|
||||
PTA6 = (0 << GPIO_PORT_SHIFT | 6 ),
|
||||
PTA7 = (0 << GPIO_PORT_SHIFT | 7 ),
|
||||
PTA8 = (0 << GPIO_PORT_SHIFT | 8 ),
|
||||
PTA9 = (0 << GPIO_PORT_SHIFT | 9 ),
|
||||
PTA10 = (0 << GPIO_PORT_SHIFT | 10),
|
||||
PTA11 = (0 << GPIO_PORT_SHIFT | 11),
|
||||
PTA12 = (0 << GPIO_PORT_SHIFT | 12),
|
||||
PTA13 = (0 << GPIO_PORT_SHIFT | 13),
|
||||
PTA14 = (0 << GPIO_PORT_SHIFT | 14),
|
||||
PTA15 = (0 << GPIO_PORT_SHIFT | 15),
|
||||
PTA16 = (0 << GPIO_PORT_SHIFT | 16),
|
||||
PTA17 = (0 << GPIO_PORT_SHIFT | 17),
|
||||
PTA18 = (0 << GPIO_PORT_SHIFT | 18),
|
||||
PTA19 = (0 << GPIO_PORT_SHIFT | 19),
|
||||
PTA20 = (0 << GPIO_PORT_SHIFT | 20),
|
||||
PTA21 = (0 << GPIO_PORT_SHIFT | 21),
|
||||
PTA22 = (0 << GPIO_PORT_SHIFT | 22),
|
||||
PTA23 = (0 << GPIO_PORT_SHIFT | 23),
|
||||
PTA24 = (0 << GPIO_PORT_SHIFT | 24),
|
||||
PTA25 = (0 << GPIO_PORT_SHIFT | 25),
|
||||
PTA26 = (0 << GPIO_PORT_SHIFT | 26),
|
||||
PTA27 = (0 << GPIO_PORT_SHIFT | 27),
|
||||
PTA28 = (0 << GPIO_PORT_SHIFT | 28),
|
||||
PTA29 = (0 << GPIO_PORT_SHIFT | 29),
|
||||
PTA30 = (0 << GPIO_PORT_SHIFT | 30),
|
||||
PTA31 = (0 << GPIO_PORT_SHIFT | 31),
|
||||
PTB0 = (1 << GPIO_PORT_SHIFT | 0 ),
|
||||
PTB1 = (1 << GPIO_PORT_SHIFT | 1 ),
|
||||
PTB2 = (1 << GPIO_PORT_SHIFT | 2 ),
|
||||
PTB3 = (1 << GPIO_PORT_SHIFT | 3 ),
|
||||
PTB4 = (1 << GPIO_PORT_SHIFT | 4 ),
|
||||
PTB5 = (1 << GPIO_PORT_SHIFT | 5 ),
|
||||
PTB6 = (1 << GPIO_PORT_SHIFT | 6 ),
|
||||
PTB7 = (1 << GPIO_PORT_SHIFT | 7 ),
|
||||
PTB8 = (1 << GPIO_PORT_SHIFT | 8 ),
|
||||
PTB9 = (1 << GPIO_PORT_SHIFT | 9 ),
|
||||
PTB10 = (1 << GPIO_PORT_SHIFT | 10),
|
||||
PTB11 = (1 << GPIO_PORT_SHIFT | 11),
|
||||
PTB12 = (1 << GPIO_PORT_SHIFT | 12),
|
||||
PTB13 = (1 << GPIO_PORT_SHIFT | 13),
|
||||
PTB14 = (1 << GPIO_PORT_SHIFT | 14),
|
||||
PTB15 = (1 << GPIO_PORT_SHIFT | 15),
|
||||
PTB16 = (1 << GPIO_PORT_SHIFT | 16),
|
||||
PTB17 = (1 << GPIO_PORT_SHIFT | 17),
|
||||
PTB18 = (1 << GPIO_PORT_SHIFT | 18),
|
||||
PTB19 = (1 << GPIO_PORT_SHIFT | 19),
|
||||
PTB20 = (1 << GPIO_PORT_SHIFT | 20),
|
||||
PTB21 = (1 << GPIO_PORT_SHIFT | 21),
|
||||
PTB22 = (1 << GPIO_PORT_SHIFT | 22),
|
||||
PTB23 = (1 << GPIO_PORT_SHIFT | 23),
|
||||
PTB24 = (1 << GPIO_PORT_SHIFT | 24),
|
||||
PTB25 = (1 << GPIO_PORT_SHIFT | 25),
|
||||
PTB26 = (1 << GPIO_PORT_SHIFT | 26),
|
||||
PTB27 = (1 << GPIO_PORT_SHIFT | 27),
|
||||
PTB28 = (1 << GPIO_PORT_SHIFT | 28),
|
||||
PTB29 = (1 << GPIO_PORT_SHIFT | 29),
|
||||
PTB30 = (1 << GPIO_PORT_SHIFT | 30),
|
||||
PTB31 = (1 << GPIO_PORT_SHIFT | 31),
|
||||
PTC0 = (2 << GPIO_PORT_SHIFT | 0 ),
|
||||
PTC1 = (2 << GPIO_PORT_SHIFT | 1 ),
|
||||
PTC2 = (2 << GPIO_PORT_SHIFT | 2 ),
|
||||
PTC3 = (2 << GPIO_PORT_SHIFT | 3 ),
|
||||
PTC4 = (2 << GPIO_PORT_SHIFT | 4 ),
|
||||
PTC5 = (2 << GPIO_PORT_SHIFT | 5 ),
|
||||
PTC6 = (2 << GPIO_PORT_SHIFT | 6 ),
|
||||
PTC7 = (2 << GPIO_PORT_SHIFT | 7 ),
|
||||
PTC8 = (2 << GPIO_PORT_SHIFT | 8 ),
|
||||
PTC9 = (2 << GPIO_PORT_SHIFT | 9 ),
|
||||
PTC10 = (2 << GPIO_PORT_SHIFT | 10),
|
||||
PTC11 = (2 << GPIO_PORT_SHIFT | 11),
|
||||
PTC12 = (2 << GPIO_PORT_SHIFT | 12),
|
||||
PTC13 = (2 << GPIO_PORT_SHIFT | 13),
|
||||
PTC14 = (2 << GPIO_PORT_SHIFT | 14),
|
||||
PTC15 = (2 << GPIO_PORT_SHIFT | 15),
|
||||
PTC16 = (2 << GPIO_PORT_SHIFT | 16),
|
||||
PTC17 = (2 << GPIO_PORT_SHIFT | 17),
|
||||
PTC18 = (2 << GPIO_PORT_SHIFT | 18),
|
||||
PTC19 = (2 << GPIO_PORT_SHIFT | 19),
|
||||
PTC20 = (2 << GPIO_PORT_SHIFT | 20),
|
||||
PTC21 = (2 << GPIO_PORT_SHIFT | 21),
|
||||
PTC22 = (2 << GPIO_PORT_SHIFT | 22),
|
||||
PTC23 = (2 << GPIO_PORT_SHIFT | 23),
|
||||
PTC24 = (2 << GPIO_PORT_SHIFT | 24),
|
||||
PTC25 = (2 << GPIO_PORT_SHIFT | 25),
|
||||
PTC26 = (2 << GPIO_PORT_SHIFT | 26),
|
||||
PTC27 = (2 << GPIO_PORT_SHIFT | 27),
|
||||
PTC28 = (2 << GPIO_PORT_SHIFT | 28),
|
||||
PTC29 = (2 << GPIO_PORT_SHIFT | 29),
|
||||
PTC30 = (2 << GPIO_PORT_SHIFT | 30),
|
||||
PTC31 = (2 << GPIO_PORT_SHIFT | 31),
|
||||
PTD0 = (3 << GPIO_PORT_SHIFT | 0 ),
|
||||
PTD1 = (3 << GPIO_PORT_SHIFT | 1 ),
|
||||
PTD2 = (3 << GPIO_PORT_SHIFT | 2 ),
|
||||
PTD3 = (3 << GPIO_PORT_SHIFT | 3 ),
|
||||
PTD4 = (3 << GPIO_PORT_SHIFT | 4 ),
|
||||
PTD5 = (3 << GPIO_PORT_SHIFT | 5 ),
|
||||
PTD6 = (3 << GPIO_PORT_SHIFT | 6 ),
|
||||
PTD7 = (3 << GPIO_PORT_SHIFT | 7 ),
|
||||
PTD8 = (3 << GPIO_PORT_SHIFT | 8 ),
|
||||
PTD9 = (3 << GPIO_PORT_SHIFT | 9 ),
|
||||
PTD10 = (3 << GPIO_PORT_SHIFT | 10),
|
||||
PTD11 = (3 << GPIO_PORT_SHIFT | 11),
|
||||
PTD12 = (3 << GPIO_PORT_SHIFT | 12),
|
||||
PTD13 = (3 << GPIO_PORT_SHIFT | 13),
|
||||
PTD14 = (3 << GPIO_PORT_SHIFT | 14),
|
||||
PTD15 = (3 << GPIO_PORT_SHIFT | 15),
|
||||
PTD16 = (3 << GPIO_PORT_SHIFT | 16),
|
||||
PTD17 = (3 << GPIO_PORT_SHIFT | 17),
|
||||
PTD18 = (3 << GPIO_PORT_SHIFT | 18),
|
||||
PTD19 = (3 << GPIO_PORT_SHIFT | 19),
|
||||
PTD20 = (3 << GPIO_PORT_SHIFT | 20),
|
||||
PTD21 = (3 << GPIO_PORT_SHIFT | 21),
|
||||
PTD22 = (3 << GPIO_PORT_SHIFT | 22),
|
||||
PTD23 = (3 << GPIO_PORT_SHIFT | 23),
|
||||
PTD24 = (3 << GPIO_PORT_SHIFT | 24),
|
||||
PTD25 = (3 << GPIO_PORT_SHIFT | 25),
|
||||
PTD26 = (3 << GPIO_PORT_SHIFT | 26),
|
||||
PTD27 = (3 << GPIO_PORT_SHIFT | 27),
|
||||
PTD28 = (3 << GPIO_PORT_SHIFT | 28),
|
||||
PTD29 = (3 << GPIO_PORT_SHIFT | 29),
|
||||
PTD30 = (3 << GPIO_PORT_SHIFT | 30),
|
||||
PTD31 = (3 << GPIO_PORT_SHIFT | 31),
|
||||
PTE0 = (4 << GPIO_PORT_SHIFT | 0 ),
|
||||
PTE1 = (4 << GPIO_PORT_SHIFT | 1 ),
|
||||
PTE2 = (4 << GPIO_PORT_SHIFT | 2 ),
|
||||
PTE3 = (4 << GPIO_PORT_SHIFT | 3 ),
|
||||
PTE4 = (4 << GPIO_PORT_SHIFT | 4 ),
|
||||
PTE5 = (4 << GPIO_PORT_SHIFT | 5 ),
|
||||
PTE6 = (4 << GPIO_PORT_SHIFT | 6 ),
|
||||
PTE7 = (4 << GPIO_PORT_SHIFT | 7 ),
|
||||
PTE8 = (4 << GPIO_PORT_SHIFT | 8 ),
|
||||
PTE9 = (4 << GPIO_PORT_SHIFT | 9 ),
|
||||
PTE10 = (4 << GPIO_PORT_SHIFT | 10),
|
||||
PTE11 = (4 << GPIO_PORT_SHIFT | 11),
|
||||
PTE12 = (4 << GPIO_PORT_SHIFT | 12),
|
||||
PTE13 = (4 << GPIO_PORT_SHIFT | 13),
|
||||
PTE14 = (4 << GPIO_PORT_SHIFT | 14),
|
||||
PTE15 = (4 << GPIO_PORT_SHIFT | 15),
|
||||
PTE16 = (4 << GPIO_PORT_SHIFT | 16),
|
||||
PTE17 = (4 << GPIO_PORT_SHIFT | 17),
|
||||
PTE18 = (4 << GPIO_PORT_SHIFT | 18),
|
||||
PTE19 = (4 << GPIO_PORT_SHIFT | 19),
|
||||
PTE20 = (4 << GPIO_PORT_SHIFT | 20),
|
||||
PTE21 = (4 << GPIO_PORT_SHIFT | 21),
|
||||
PTE22 = (4 << GPIO_PORT_SHIFT | 22),
|
||||
PTE23 = (4 << GPIO_PORT_SHIFT | 23),
|
||||
PTE24 = (4 << GPIO_PORT_SHIFT | 24),
|
||||
PTE25 = (4 << GPIO_PORT_SHIFT | 25),
|
||||
PTE26 = (4 << GPIO_PORT_SHIFT | 26),
|
||||
PTE27 = (4 << GPIO_PORT_SHIFT | 27),
|
||||
PTE28 = (4 << GPIO_PORT_SHIFT | 28),
|
||||
PTE29 = (4 << GPIO_PORT_SHIFT | 29),
|
||||
PTE30 = (4 << GPIO_PORT_SHIFT | 30),
|
||||
PTE31 = (4 << GPIO_PORT_SHIFT | 31),
|
||||
|
||||
// led color naming
|
||||
LED_GREEN = PTC0,
|
||||
|
||||
// mbed original LED naming
|
||||
LED1 = PTD15,
|
||||
LED2 = PTD14,
|
||||
LED3 = PTD13,
|
||||
LED4 = PTD11,
|
||||
LED5 = PTD12,
|
||||
STATUS = LED_GREEN,
|
||||
|
||||
// USB Pins
|
||||
USBTX = PTB17,
|
||||
USBRX = PTB16,
|
||||
|
||||
// SPI Pins
|
||||
SPI0_SOUT = PTC6,
|
||||
SPI0_SIN = PTC7,
|
||||
SPI0_SCK = PTC5,
|
||||
|
||||
SPI1_SOUT = PTE3,
|
||||
SPI1_SIN = PTE1,
|
||||
SPI1_SCK = PTE2,
|
||||
|
||||
// SPI Chip Select Pins
|
||||
SPI0_NCS0 = PTC4,
|
||||
SPI0_NCS1 = PTC3,
|
||||
SPI0_NCS2 = PTC2,
|
||||
SPI0_NCS3 = PTC1,
|
||||
|
||||
SPI1_NCS0 = PTE4,
|
||||
SPI1_NCS1 = PTE0,
|
||||
SPI1_NCS2 = PTE5,
|
||||
SPI1_NCS3 = PTE6,
|
||||
|
||||
// GPIO's
|
||||
AP1_GPIO1 = PTB7,
|
||||
AP1_GPIO2 = PTB6,
|
||||
AP1_GPIO3 = PTB5,
|
||||
AP1_GPIO4 = PTB4,
|
||||
|
||||
AP2_GPIO1 = PTA27,
|
||||
AP2_GPIO2 = PTA26,
|
||||
AP2_GPIO3 = PTA25,
|
||||
AP2_GPIO4 = PTA24,
|
||||
|
||||
// Cellular Radio Serial Pins
|
||||
RADIO_SERIAL_TX = PTE8,
|
||||
RADIO_SERIAL_RX = PTE9,
|
||||
RADIO_SERIAL_RTS = PTE11,
|
||||
RADIO_SERIAL_CTS = PTE10,
|
||||
RADIO_SERIAL_DTR = PTE26,
|
||||
RADIO_SERIAL_DSR = PTE25,
|
||||
RADIO_SERIAL_RI = PTE24,
|
||||
RADIO_SERIAL_CD = PTE12,
|
||||
|
||||
DAC0_OUT = 0xFEFE, /* DAC does not have Pin Name in RM */
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF
|
||||
} PinName;
|
||||
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 1,
|
||||
PullUp = 2,
|
||||
PullDefault = PullUp
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MBED_DEVICE_H
|
||||
#define MBED_DEVICE_H
|
||||
|
||||
#define DEVICE_PORTIN 1
|
||||
#define DEVICE_PORTOUT 1
|
||||
#define DEVICE_PORTINOUT 1
|
||||
|
||||
#define DEVICE_INTERRUPTIN 1
|
||||
|
||||
#define DEVICE_ANALOGIN 0
|
||||
#define DEVICE_ANALOGOUT 0
|
||||
|
||||
#define DEVICE_SERIAL 1
|
||||
|
||||
#define DEVICE_I2C 1
|
||||
#define DEVICE_I2CSLAVE 1
|
||||
|
||||
#define DEVICE_SPI 1
|
||||
#define DEVICE_SPISLAVE 1
|
||||
|
||||
#define DEVICE_CAN 0
|
||||
|
||||
#define DEVICE_RTC 1
|
||||
|
||||
#define DEVICE_ETHERNET 0
|
||||
|
||||
#define DEVICE_PWMOUT 0
|
||||
|
||||
#define DEVICE_SEMIHOST 0
|
||||
#define DEVICE_LOCALFILESYSTEM 0
|
||||
#define DEVICE_ID_LENGTH 24
|
||||
|
||||
#define DEVICE_SLEEP 1
|
||||
|
||||
#define DEVICE_DEBUG_AWARENESS 0
|
||||
|
||||
#define DEVICE_STDIO_MESSAGES 1
|
||||
|
||||
#define DEVICE_ERROR_RED 0
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_smc.h"
|
||||
#include "fsl_clock_config.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief Clock configuration structure. */
|
||||
typedef struct _clock_config
|
||||
{
|
||||
mcg_config_t mcgConfig; /*!< MCG configuration. */
|
||||
sim_clock_config_t simConfig; /*!< SIM configuration. */
|
||||
osc_config_t oscConfig; /*!< OSC configuration. */
|
||||
uint32_t coreClock; /*!< core clock frequency. */
|
||||
} clock_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/* System clock frequency. */
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
/* Configuration for enter VLPR mode. Core clock = 4MHz. */
|
||||
const clock_config_t g_defaultClockConfigVlpr = {
|
||||
.mcgConfig =
|
||||
{
|
||||
.mcgMode = kMCG_ModeBLPI, /* Work in BLPI mode. */
|
||||
.irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enable. */
|
||||
.ircs = kMCG_IrcFast, /* Select IRC4M. */
|
||||
.fcrdiv = 0U, /* FCRDIV is 0. */
|
||||
|
||||
.frdiv = 0U,
|
||||
.drs = kMCG_DrsLow, /* Low frequency range. */
|
||||
.dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25%. */
|
||||
.oscsel = kMCG_OscselOsc, /* Select OSC. */
|
||||
|
||||
.pll0Config =
|
||||
{
|
||||
.enableMode = 0U, /* Don't eanble PLL. */
|
||||
.prdiv = 0U,
|
||||
.vdiv = 0U,
|
||||
},
|
||||
},
|
||||
.simConfig =
|
||||
{
|
||||
.pllFllSel = 3U, /* PLLFLLSEL select IRC48MCLK. */
|
||||
.er32kSrc = 2U, /* ERCLK32K selection, use RTC. */
|
||||
.clkdiv1 = 0x00040000U, /* SIM_CLKDIV1. */
|
||||
},
|
||||
.oscConfig = {.freq = BOARD_XTAL0_CLK_HZ,
|
||||
.capLoad = 0,
|
||||
.workMode = kOSC_ModeExt,
|
||||
.oscerConfig =
|
||||
{
|
||||
.enableMode = kOSC_ErClkEnable,
|
||||
#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER)
|
||||
.erclkDiv = 0U,
|
||||
#endif
|
||||
}},
|
||||
.coreClock = 4000000U, /* Core clock frequency */
|
||||
};
|
||||
|
||||
/* Configuration for enter RUN mode. Core clock = 120MHz. */
|
||||
const clock_config_t g_defaultClockConfigRun = {
|
||||
.mcgConfig =
|
||||
{
|
||||
.mcgMode = kMCG_ModePEE, /* Work in PEE mode. */
|
||||
.irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enable. */
|
||||
.ircs = kMCG_IrcSlow, /* Select IRC32k. */
|
||||
.fcrdiv = 0U, /* FCRDIV is 0. */
|
||||
|
||||
.frdiv = 7U,
|
||||
.drs = kMCG_DrsLow, /* Low frequency range. */
|
||||
.dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25%. */
|
||||
.oscsel = kMCG_OscselOsc, /* Select OSC. */
|
||||
|
||||
.pll0Config =
|
||||
{
|
||||
.enableMode = 0U, .prdiv = 0x13U, .vdiv = 0x18U,
|
||||
},
|
||||
},
|
||||
.simConfig =
|
||||
{
|
||||
.pllFllSel = 1U, /* PLLFLLSEL select PLL. */
|
||||
.er32kSrc = 2U, /* ERCLK32K selection, use RTC. */
|
||||
.clkdiv1 = 0x01140000U, /* SIM_CLKDIV1. */
|
||||
},
|
||||
.oscConfig = {.freq = BOARD_XTAL0_CLK_HZ,
|
||||
.capLoad = 0,
|
||||
.workMode = kOSC_ModeExt,
|
||||
.oscerConfig =
|
||||
{
|
||||
.enableMode = kOSC_ErClkEnable,
|
||||
#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER)
|
||||
.erclkDiv = 0U,
|
||||
#endif
|
||||
}},
|
||||
.coreClock = 120000000U, /* Core clock frequency */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
/*
|
||||
* How to setup clock using clock driver functions:
|
||||
*
|
||||
* 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock
|
||||
* and flash clock are in allowed range during clock mode switch.
|
||||
*
|
||||
* 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode.
|
||||
*
|
||||
* 3. Set MCG configuration, MCG includes three parts: FLL clock, PLL clock and
|
||||
* internal reference clock(MCGIRCLK). Follow the steps to setup:
|
||||
*
|
||||
* 1). Call CLOCK_BootToXxxMode to set MCG to target mode.
|
||||
*
|
||||
* 2). If target mode is FBI/BLPI/PBI mode, the MCGIRCLK has been configured
|
||||
* correctly. For other modes, need to call CLOCK_SetInternalRefClkConfig
|
||||
* explicitly to setup MCGIRCLK.
|
||||
*
|
||||
* 3). Don't need to configure FLL explicitly, because if target mode is FLL
|
||||
* mode, then FLL has been configured by the function CLOCK_BootToXxxMode,
|
||||
* if the target mode is not FLL mode, the FLL is disabled.
|
||||
*
|
||||
* 4). If target mode is PEE/PBE/PEI/PBI mode, then the related PLL has been
|
||||
* setup by CLOCK_BootToXxxMode. In FBE/FBI/FEE/FBE mode, the PLL could
|
||||
* be enabled independently, call CLOCK_EnablePll0 explicitly in this case.
|
||||
*
|
||||
* 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM.
|
||||
*/
|
||||
|
||||
void BOARD_BootClockVLPR(void)
|
||||
{
|
||||
CLOCK_SetSimSafeDivs();
|
||||
|
||||
CLOCK_BootToBlpiMode(g_defaultClockConfigVlpr.mcgConfig.fcrdiv, g_defaultClockConfigVlpr.mcgConfig.ircs,
|
||||
g_defaultClockConfigVlpr.mcgConfig.irclkEnableMode);
|
||||
|
||||
CLOCK_SetSimConfig(&g_defaultClockConfigVlpr.simConfig);
|
||||
|
||||
SystemCoreClock = g_defaultClockConfigVlpr.coreClock;
|
||||
|
||||
SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll);
|
||||
SMC_SetPowerModeVlpr(SMC, false);
|
||||
while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void BOARD_BootClockRUN(void)
|
||||
{
|
||||
CLOCK_SetSimSafeDivs();
|
||||
|
||||
CLOCK_InitOsc0(&g_defaultClockConfigRun.oscConfig);
|
||||
CLOCK_SetXtal0Freq(BOARD_XTAL0_CLK_HZ);
|
||||
|
||||
CLOCK_BootToPeeMode(g_defaultClockConfigRun.mcgConfig.oscsel, kMCG_PllClkSelPll0,
|
||||
&g_defaultClockConfigRun.mcgConfig.pll0Config);
|
||||
|
||||
CLOCK_SetInternalRefClkConfig(g_defaultClockConfigRun.mcgConfig.irclkEnableMode,
|
||||
g_defaultClockConfigRun.mcgConfig.ircs, g_defaultClockConfigRun.mcgConfig.fcrdiv);
|
||||
|
||||
CLOCK_SetSimConfig(&g_defaultClockConfigRun.simConfig);
|
||||
|
||||
SystemCoreClock = g_defaultClockConfigRun.coreClock;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _CLOCK_CONFIG_H_
|
||||
#define _CLOCK_CONFIG_H_
|
||||
|
||||
/*******************************************************************************
|
||||
* DEFINITION
|
||||
******************************************************************************/
|
||||
#define BOARD_XTAL0_CLK_HZ 50000000U
|
||||
#define BOARD_XTAL32K_CLK_HZ 32768U
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
void BOARD_BootClockVLPR(void);
|
||||
void BOARD_BootClockRUN(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
#endif /* _CLOCK_CONFIG_H_ */
|
|
@ -0,0 +1,29 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "gpio_api.h"
|
||||
#include "fsl_clock_config.h"
|
||||
// called before main
|
||||
void mbed_sdk_init()
|
||||
{
|
||||
BOARD_BootClockRUN();
|
||||
}
|
||||
|
||||
// Enable the RTC oscillator if available on the board
|
||||
void rtc_setup_oscillator(RTC_Type *base)
|
||||
{
|
||||
/* Enable the RTC oscillator */
|
||||
RTC->CR |= RTC_CR_OSCE_MASK;
|
||||
}
|
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_adc16.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Get instance number for ADC16 module.
|
||||
*
|
||||
* @param base ADC16 peripheral base address
|
||||
*/
|
||||
static uint32_t ADC16_GetInstance(ADC_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/*! @brief Pointers to ADC16 bases for each instance. */
|
||||
static ADC_Type *const s_adc16Bases[] = ADC_BASE_PTRS;
|
||||
|
||||
/*! @brief Pointers to ADC16 clocks for each instance. */
|
||||
const clock_ip_name_t s_adc16Clocks[] = ADC16_CLOCKS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static uint32_t ADC16_GetInstance(ADC_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_ADC16_COUNT; instance++)
|
||||
{
|
||||
if (s_adc16Bases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < FSL_FEATURE_SOC_ADC16_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void ADC16_Init(ADC_Type *base, const adc16_config_t *config)
|
||||
{
|
||||
assert(NULL != config);
|
||||
|
||||
uint32_t tmp32;
|
||||
|
||||
/* Enable the clock. */
|
||||
CLOCK_EnableClock(s_adc16Clocks[ADC16_GetInstance(base)]);
|
||||
|
||||
/* ADCx_CFG1. */
|
||||
tmp32 = ADC_CFG1_ADICLK(config->clockSource) | ADC_CFG1_MODE(config->resolution);
|
||||
if (kADC16_LongSampleDisabled != config->longSampleMode)
|
||||
{
|
||||
tmp32 |= ADC_CFG1_ADLSMP_MASK;
|
||||
}
|
||||
tmp32 |= ADC_CFG1_ADIV(config->clockDivider);
|
||||
if (config->enableLowPower)
|
||||
{
|
||||
tmp32 |= ADC_CFG1_ADLPC_MASK;
|
||||
}
|
||||
base->CFG1 = tmp32;
|
||||
|
||||
/* ADCx_CFG2. */
|
||||
tmp32 = base->CFG2 & ~(ADC_CFG2_ADACKEN_MASK | ADC_CFG2_ADHSC_MASK | ADC_CFG2_ADLSTS_MASK);
|
||||
if (kADC16_LongSampleDisabled != config->longSampleMode)
|
||||
{
|
||||
tmp32 |= ADC_CFG2_ADLSTS(config->longSampleMode);
|
||||
}
|
||||
if (config->enableHighSpeed)
|
||||
{
|
||||
tmp32 |= ADC_CFG2_ADHSC_MASK;
|
||||
}
|
||||
if (config->enableAsynchronousClock)
|
||||
{
|
||||
tmp32 |= ADC_CFG2_ADACKEN_MASK;
|
||||
}
|
||||
base->CFG2 = tmp32;
|
||||
|
||||
/* ADCx_SC2. */
|
||||
tmp32 = base->SC2 & ~(ADC_SC2_REFSEL_MASK);
|
||||
tmp32 |= ADC_SC2_REFSEL(config->referenceVoltageSource);
|
||||
base->SC2 = tmp32;
|
||||
|
||||
/* ADCx_SC3. */
|
||||
if (config->enableContinuousConversion)
|
||||
{
|
||||
base->SC3 |= ADC_SC3_ADCO_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->SC3 &= ~ADC_SC3_ADCO_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
void ADC16_Deinit(ADC_Type *base)
|
||||
{
|
||||
/* Disable the clock. */
|
||||
CLOCK_DisableClock(s_adc16Clocks[ADC16_GetInstance(base)]);
|
||||
}
|
||||
|
||||
void ADC16_GetDefaultConfig(adc16_config_t *config)
|
||||
{
|
||||
assert(NULL != config);
|
||||
|
||||
config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref;
|
||||
config->clockSource = kADC16_ClockSourceAsynchronousClock;
|
||||
config->enableAsynchronousClock = true;
|
||||
config->clockDivider = kADC16_ClockDivider8;
|
||||
config->resolution = kADC16_ResolutionSE12Bit;
|
||||
config->longSampleMode = kADC16_LongSampleDisabled;
|
||||
config->enableHighSpeed = false;
|
||||
config->enableLowPower = false;
|
||||
config->enableContinuousConversion = false;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
|
||||
status_t ADC16_DoAutoCalibration(ADC_Type *base)
|
||||
{
|
||||
bool bHWTrigger = false;
|
||||
uint32_t tmp32;
|
||||
status_t status = kStatus_Success;
|
||||
|
||||
/* The calibration would be failed when in hardwar mode.
|
||||
* Remember the hardware trigger state here and restore it later if the hardware trigger is enabled.*/
|
||||
if (0U != (ADC_SC2_ADTRG_MASK & base->SC2))
|
||||
{
|
||||
bHWTrigger = true;
|
||||
base->SC2 &= ~ADC_SC2_ADTRG_MASK;
|
||||
}
|
||||
|
||||
/* Clear the CALF and launch the calibration. */
|
||||
base->SC3 |= ADC_SC3_CAL_MASK | ADC_SC3_CALF_MASK;
|
||||
while (0U == (kADC16_ChannelConversionDoneFlag & ADC16_GetChannelStatusFlags(base, 0U)))
|
||||
{
|
||||
/* Check the CALF when the calibration is active. */
|
||||
if (0U != (kADC16_CalibrationFailedFlag & ADC16_GetStatusFlags(base)))
|
||||
{
|
||||
status = kStatus_Fail;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the hardware trigger setting if it was enabled before. */
|
||||
if (bHWTrigger)
|
||||
{
|
||||
base->SC2 |= ADC_SC2_ADTRG_MASK;
|
||||
}
|
||||
/* Check the CALF at the end of calibration. */
|
||||
if (0U != (kADC16_CalibrationFailedFlag & ADC16_GetStatusFlags(base)))
|
||||
{
|
||||
status = kStatus_Fail;
|
||||
}
|
||||
if (kStatus_Success != status) /* Check if the calibration process is succeed. */
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Calculate the calibration values. */
|
||||
tmp32 = base->CLP0 + base->CLP1 + base->CLP2 + base->CLP3 + base->CLP4 + base->CLPS;
|
||||
tmp32 = 0x8000U | (tmp32 >> 1U);
|
||||
base->PG = tmp32;
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
|
||||
tmp32 = base->CLM0 + base->CLM1 + base->CLM2 + base->CLM3 + base->CLM4 + base->CLMS;
|
||||
tmp32 = 0x8000U | (tmp32 >> 1U);
|
||||
base->MG = tmp32;
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT
|
||||
void ADC16_SetChannelMuxMode(ADC_Type *base, adc16_channel_mux_mode_t mode)
|
||||
{
|
||||
if (kADC16_ChannelMuxA == mode)
|
||||
{
|
||||
base->CFG2 &= ~ADC_CFG2_MUXSEL_MASK;
|
||||
}
|
||||
else /* kADC16_ChannelMuxB. */
|
||||
{
|
||||
base->CFG2 |= ADC_CFG2_MUXSEL_MASK;
|
||||
}
|
||||
}
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */
|
||||
|
||||
void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config)
|
||||
{
|
||||
uint32_t tmp32 = base->SC2 & ~(ADC_SC2_ACFE_MASK | ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK);
|
||||
|
||||
if (!config) /* Pass "NULL" to disable the feature. */
|
||||
{
|
||||
base->SC2 = tmp32;
|
||||
return;
|
||||
}
|
||||
/* Enable the feature. */
|
||||
tmp32 |= ADC_SC2_ACFE_MASK;
|
||||
|
||||
/* Select the hardware compare working mode. */
|
||||
switch (config->hardwareCompareMode)
|
||||
{
|
||||
case kADC16_HardwareCompareMode0:
|
||||
break;
|
||||
case kADC16_HardwareCompareMode1:
|
||||
tmp32 |= ADC_SC2_ACFGT_MASK;
|
||||
break;
|
||||
case kADC16_HardwareCompareMode2:
|
||||
tmp32 |= ADC_SC2_ACREN_MASK;
|
||||
break;
|
||||
case kADC16_HardwareCompareMode3:
|
||||
tmp32 |= ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
base->SC2 = tmp32;
|
||||
|
||||
/* Load the compare values. */
|
||||
base->CV1 = ADC_CV1_CV(config->value1);
|
||||
base->CV2 = ADC_CV2_CV(config->value2);
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE
|
||||
void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode)
|
||||
{
|
||||
uint32_t tmp32 = base->SC3 & ~(ADC_SC3_AVGE_MASK | ADC_SC3_AVGS_MASK);
|
||||
|
||||
if (kADC16_HardwareAverageDisabled != mode)
|
||||
{
|
||||
tmp32 |= ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(mode);
|
||||
}
|
||||
base->SC3 = tmp32;
|
||||
}
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA
|
||||
void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config)
|
||||
{
|
||||
uint32_t tmp32;
|
||||
|
||||
if (!config) /* Passing "NULL" is to disable the feature. */
|
||||
{
|
||||
base->PGA = 0U;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable the PGA and set the gain value. */
|
||||
tmp32 = ADC_PGA_PGAEN_MASK | ADC_PGA_PGAG(config->pgaGain);
|
||||
|
||||
/* Configure the misc features for PGA. */
|
||||
if (config->enableRunInNormalMode)
|
||||
{
|
||||
tmp32 |= ADC_PGA_PGALPb_MASK;
|
||||
}
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_PGA_CHOPPING) && FSL_FEATURE_ADC16_HAS_PGA_CHOPPING
|
||||
if (config->disablePgaChopping)
|
||||
{
|
||||
tmp32 |= ADC_PGA_PGACHPb_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_PGA_CHOPPING */
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT) && FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT
|
||||
if (config->enableRunInOffsetMeasurement)
|
||||
{
|
||||
tmp32 |= ADC_PGA_PGAOFSM_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT */
|
||||
base->PGA = tmp32;
|
||||
}
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_PGA */
|
||||
|
||||
uint32_t ADC16_GetStatusFlags(ADC_Type *base)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
if (0U != (base->SC2 & ADC_SC2_ADACT_MASK))
|
||||
{
|
||||
ret |= kADC16_ActiveFlag;
|
||||
}
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
|
||||
if (0U != (base->SC3 & ADC_SC3_CALF_MASK))
|
||||
{
|
||||
ret |= kADC16_CalibrationFailedFlag;
|
||||
}
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ADC16_ClearStatusFlags(ADC_Type *base, uint32_t mask)
|
||||
{
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
|
||||
if (0U != (mask & kADC16_CalibrationFailedFlag))
|
||||
{
|
||||
base->SC3 |= ADC_SC3_CALF_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
|
||||
}
|
||||
|
||||
void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config)
|
||||
{
|
||||
assert(channelGroup < ADC_SC1_COUNT);
|
||||
assert(NULL != config);
|
||||
|
||||
uint32_t sc1 = ADC_SC1_ADCH(config->channelNumber); /* Set the channel number. */
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
|
||||
/* Enable the differential conversion. */
|
||||
if (config->enableDifferentialConversion)
|
||||
{
|
||||
sc1 |= ADC_SC1_DIFF_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
|
||||
/* Enable the interrupt when the conversion is done. */
|
||||
if (config->enableInterruptOnConversionCompleted)
|
||||
{
|
||||
sc1 |= ADC_SC1_AIEN_MASK;
|
||||
}
|
||||
base->SC1[channelGroup] = sc1;
|
||||
}
|
||||
|
||||
uint32_t ADC16_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup)
|
||||
{
|
||||
assert(channelGroup < ADC_SC1_COUNT);
|
||||
|
||||
uint32_t ret = 0U;
|
||||
|
||||
if (0U != (base->SC1[channelGroup] & ADC_SC1_COCO_MASK))
|
||||
{
|
||||
ret |= kADC16_ChannelConversionDoneFlag;
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,527 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FSL_ADC16_H_
|
||||
#define _FSL_ADC16_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup adc16
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief ADC16 driver version 2.0.0. */
|
||||
#define FSL_ADC16_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief Channel status flags.
|
||||
*/
|
||||
enum _adc16_channel_status_flags
|
||||
{
|
||||
kADC16_ChannelConversionDoneFlag = ADC_SC1_COCO_MASK, /*!< Conversion done. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief Converter status flags.
|
||||
*/
|
||||
enum _adc16_status_flags
|
||||
{
|
||||
kADC16_ActiveFlag = ADC_SC2_ADACT_MASK, /*!< Converter is active. */
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
|
||||
kADC16_CalibrationFailedFlag = ADC_SC3_CALF_MASK, /*!< Calibration is failed. */
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
|
||||
};
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT
|
||||
/*!
|
||||
* @brief Channel multiplexer mode for each channel.
|
||||
*
|
||||
* For some ADC16 channels, there are two pin selections in channel multiplexer. For example, ADC0_SE4a and ADC0_SE4b
|
||||
* are the different channels but share the same channel number.
|
||||
*/
|
||||
typedef enum _adc_channel_mux_mode
|
||||
{
|
||||
kADC16_ChannelMuxA = 0U, /*!< For channel with channel mux a. */
|
||||
kADC16_ChannelMuxB = 1U, /*!< For channel with channel mux b. */
|
||||
} adc16_channel_mux_mode_t;
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */
|
||||
|
||||
/*!
|
||||
* @brief Clock divider for the converter.
|
||||
*/
|
||||
typedef enum _adc16_clock_divider
|
||||
{
|
||||
kADC16_ClockDivider1 = 0U, /*!< For divider 1 from the input clock to the module. */
|
||||
kADC16_ClockDivider2 = 1U, /*!< For divider 2 from the input clock to the module. */
|
||||
kADC16_ClockDivider4 = 2U, /*!< For divider 4 from the input clock to the module. */
|
||||
kADC16_ClockDivider8 = 3U, /*!< For divider 8 from the input clock to the module. */
|
||||
} adc16_clock_divider_t;
|
||||
|
||||
/*!
|
||||
*@brief Converter's resolution.
|
||||
*/
|
||||
typedef enum _adc16_resolution
|
||||
{
|
||||
/* This group of enumeration is for internal use which is related to register setting. */
|
||||
kADC16_Resolution8or9Bit = 0U, /*!< Single End 8-bit or Differential Sample 9-bit. */
|
||||
kADC16_Resolution12or13Bit = 1U, /*!< Single End 12-bit or Differential Sample 13-bit. */
|
||||
kADC16_Resolution10or11Bit = 2U, /*!< Single End 10-bit or Differential Sample 11-bit. */
|
||||
|
||||
/* This group of enumeration is for public user. */
|
||||
kADC16_ResolutionSE8Bit = kADC16_Resolution8or9Bit, /*!< Single End 8-bit. */
|
||||
kADC16_ResolutionSE12Bit = kADC16_Resolution12or13Bit, /*!< Single End 12-bit. */
|
||||
kADC16_ResolutionSE10Bit = kADC16_Resolution10or11Bit, /*!< Single End 10-bit. */
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
|
||||
kADC16_ResolutionDF9Bit = kADC16_Resolution8or9Bit, /*!< Differential Sample 9-bit. */
|
||||
kADC16_ResolutionDF13Bit = kADC16_Resolution12or13Bit, /*!< Differential Sample 13-bit. */
|
||||
kADC16_ResolutionDF11Bit = kADC16_Resolution10or11Bit, /*!< Differential Sample 11-bit. */
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_MAX_RESOLUTION) && (FSL_FEATURE_ADC16_MAX_RESOLUTION >= 16U)
|
||||
/* 16-bit is supported by default. */
|
||||
kADC16_Resolution16Bit = 3U, /*!< Single End 16-bit or Differential Sample 16-bit. */
|
||||
kADC16_ResolutionSE16Bit = kADC16_Resolution16Bit, /*!< Single End 16-bit. */
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
|
||||
kADC16_ResolutionDF16Bit = kADC16_Resolution16Bit, /*!< Differential Sample 16-bit. */
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
|
||||
#endif /* FSL_FEATURE_ADC16_MAX_RESOLUTION >= 16U */
|
||||
} adc16_resolution_t;
|
||||
|
||||
/*!
|
||||
* @brief Clock source.
|
||||
*/
|
||||
typedef enum _adc16_clock_source
|
||||
{
|
||||
kADC16_ClockSourceAlt0 = 0U, /*!< Selection 0 of the clock source. */
|
||||
kADC16_ClockSourceAlt1 = 1U, /*!< Selection 1 of the clock source. */
|
||||
kADC16_ClockSourceAlt2 = 2U, /*!< Selection 2 of the clock source. */
|
||||
kADC16_ClockSourceAlt3 = 3U, /*!< Selection 3 of the clock source. */
|
||||
|
||||
/* Chip defined clock source */
|
||||
kADC16_ClockSourceAsynchronousClock = kADC16_ClockSourceAlt3, /*!< Using internal asynchronous clock. */
|
||||
} adc16_clock_source_t;
|
||||
|
||||
/*!
|
||||
* @brief Long sample mode.
|
||||
*/
|
||||
typedef enum _adc16_long_sample_mode
|
||||
{
|
||||
kADC16_LongSampleCycle24 = 0U, /*!< 20 extra ADCK cycles, 24 ADCK cycles total. */
|
||||
kADC16_LongSampleCycle16 = 1U, /*!< 12 extra ADCK cycles, 16 ADCK cycles total. */
|
||||
kADC16_LongSampleCycle10 = 2U, /*!< 6 extra ADCK cycles, 10 ADCK cycles total. */
|
||||
kADC16_LongSampleCycle6 = 3U, /*!< 2 extra ADCK cycles, 6 ADCK cycles total. */
|
||||
kADC16_LongSampleDisabled = 4U, /*!< Disable the long sample feature. */
|
||||
} adc16_long_sample_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief Reference voltage source.
|
||||
*/
|
||||
typedef enum _adc16_reference_voltage_source
|
||||
{
|
||||
kADC16_ReferenceVoltageSourceVref = 0U, /*!< For external pins pair of VrefH and VrefL. */
|
||||
kADC16_ReferenceVoltageSourceValt = 1U, /*!< For alternate reference pair of ValtH and ValtL. */
|
||||
} adc16_reference_voltage_source_t;
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE
|
||||
/*!
|
||||
* @brief Hardware average mode.
|
||||
*/
|
||||
typedef enum _adc16_hardware_average_mode
|
||||
{
|
||||
kADC16_HardwareAverageCount4 = 0U, /*!< For hardware average with 4 samples. */
|
||||
kADC16_HardwareAverageCount8 = 1U, /*!< For hardware average with 8 samples. */
|
||||
kADC16_HardwareAverageCount16 = 2U, /*!< For hardware average with 16 samples. */
|
||||
kADC16_HardwareAverageCount32 = 3U, /*!< For hardware average with 32 samples. */
|
||||
kADC16_HardwareAverageDisabled = 4U, /*!< Disable the hardware average feature.*/
|
||||
} adc16_hardware_average_mode_t;
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */
|
||||
|
||||
/*!
|
||||
* @brief Hardware compare mode.
|
||||
*/
|
||||
typedef enum _adc16_hardware_compare_mode
|
||||
{
|
||||
kADC16_HardwareCompareMode0 = 0U, /*!< x < value1. */
|
||||
kADC16_HardwareCompareMode1 = 1U, /*!< x > value1. */
|
||||
kADC16_HardwareCompareMode2 = 2U, /*!< if value1 <= value2, then x < value1 || x > value2;
|
||||
else, value1 > x > value2. */
|
||||
kADC16_HardwareCompareMode3 = 3U, /*!< if value1 <= value2, then value1 <= x <= value2;
|
||||
else x >= value1 || x <= value2. */
|
||||
} adc16_hardware_compare_mode_t;
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA
|
||||
/*!
|
||||
* @brief PGA's Gain mode.
|
||||
*/
|
||||
typedef enum _adc16_pga_gain
|
||||
{
|
||||
kADC16_PGAGainValueOf1 = 0U, /*!< For amplifier gain of 1. */
|
||||
kADC16_PGAGainValueOf2 = 1U, /*!< For amplifier gain of 2. */
|
||||
kADC16_PGAGainValueOf4 = 2U, /*!< For amplifier gain of 4. */
|
||||
kADC16_PGAGainValueOf8 = 3U, /*!< For amplifier gain of 8. */
|
||||
kADC16_PGAGainValueOf16 = 4U, /*!< For amplifier gain of 16. */
|
||||
kADC16_PGAGainValueOf32 = 5U, /*!< For amplifier gain of 32. */
|
||||
kADC16_PGAGainValueOf64 = 6U, /*!< For amplifier gain of 64. */
|
||||
} adc16_pga_gain_t;
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_PGA */
|
||||
|
||||
/*!
|
||||
* @brief ADC16 converter configuration .
|
||||
*/
|
||||
typedef struct _adc16_config
|
||||
{
|
||||
adc16_reference_voltage_source_t referenceVoltageSource; /*!< Select the reference voltage source. */
|
||||
adc16_clock_source_t clockSource; /*!< Select the input clock source to converter. */
|
||||
bool enableAsynchronousClock; /*!< Enable the asynchronous clock output. */
|
||||
adc16_clock_divider_t clockDivider; /*!< Select the divider of input clock source. */
|
||||
adc16_resolution_t resolution; /*!< Select the sample resolution mode. */
|
||||
adc16_long_sample_mode_t longSampleMode; /*!< Select the long sample mode. */
|
||||
bool enableHighSpeed; /*!< Enable the high-speed mode. */
|
||||
bool enableLowPower; /*!< Enable low power. */
|
||||
bool enableContinuousConversion; /*!< Enable continuous conversion mode. */
|
||||
} adc16_config_t;
|
||||
|
||||
/*!
|
||||
* @brief ADC16 Hardware compare configuration.
|
||||
*/
|
||||
typedef struct _adc16_hardware_compare_config
|
||||
{
|
||||
adc16_hardware_compare_mode_t hardwareCompareMode; /*!< Select the hardware compare mode.
|
||||
See "adc16_hardware_compare_mode_t". */
|
||||
int16_t value1; /*!< Setting value1 for hardware compare mode. */
|
||||
int16_t value2; /*!< Setting value2 for hardware compare mode. */
|
||||
} adc16_hardware_compare_config_t;
|
||||
|
||||
/*!
|
||||
* @brief ADC16 channel conversion configuration.
|
||||
*/
|
||||
typedef struct _adc16_channel_config
|
||||
{
|
||||
uint32_t channelNumber; /*!< Setting the conversion channel number. The available range is 0-31.
|
||||
See channel connection information for each chip in Reference
|
||||
Manual document. */
|
||||
bool enableInterruptOnConversionCompleted; /*!< Generate a interrupt request once the conversion is completed. */
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
|
||||
bool enableDifferentialConversion; /*!< Using Differential sample mode. */
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
|
||||
} adc16_channel_config_t;
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA
|
||||
/*!
|
||||
* @brief ADC16 programmable gain amplifier configuration.
|
||||
*/
|
||||
typedef struct _adc16_pga_config
|
||||
{
|
||||
adc16_pga_gain_t pgaGain; /*!< Setting PGA gain. */
|
||||
bool enableRunInNormalMode; /*!< Enable PGA working in normal mode, or low power mode by default. */
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_PGA_CHOPPING) && FSL_FEATURE_ADC16_HAS_PGA_CHOPPING
|
||||
bool disablePgaChopping; /*!< Disable the PGA chopping function.
|
||||
The PGA employs chopping to remove/reduce offset and 1/f noise and offers
|
||||
an offset measurement configuration that aids the offset calibration. */
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_PGA_CHOPPING */
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT) && FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT
|
||||
bool enableRunInOffsetMeasurement; /*!< Enable the PGA working in offset measurement mode.
|
||||
When this feature is enabled, the PGA disconnects itself from the external
|
||||
inputs and auto-configures into offset measurement mode. With this field
|
||||
set, run the ADC in the recommended settings and enable the maximum hardware
|
||||
averaging to get the PGA offset number. The output is the
|
||||
(PGA offset * (64+1)) for the given PGA setting. */
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT */
|
||||
} adc16_pga_config_t;
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_PGA */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @name Initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the ADC16 module.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
* @param config Pointer to configuration structure. See "adc16_config_t".
|
||||
*/
|
||||
void ADC16_Init(ADC_Type *base, const adc16_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief De-initializes the ADC16 module.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
*/
|
||||
void ADC16_Deinit(ADC_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Gets an available pre-defined settings for converter's configuration.
|
||||
*
|
||||
* This function initializes the converter configuration structure with an available settings. The default values are:
|
||||
* @code
|
||||
* config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref;
|
||||
* config->clockSource = kADC16_ClockSourceAsynchronousClock;
|
||||
* config->enableAsynchronousClock = true;
|
||||
* config->clockDivider = kADC16_ClockDivider8;
|
||||
* config->resolution = kADC16_ResolutionSE12Bit;
|
||||
* config->longSampleMode = kADC16_LongSampleDisabled;
|
||||
* config->enableHighSpeed = false;
|
||||
* config->enableLowPower = false;
|
||||
* config->enableContinuousConversion = false;
|
||||
* @endcode
|
||||
* @param config Pointer to configuration structure.
|
||||
*/
|
||||
void ADC16_GetDefaultConfig(adc16_config_t *config);
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
|
||||
/*!
|
||||
* @brief Automates the hardware calibration.
|
||||
*
|
||||
* This auto calibration helps to adjust the plus/minus side gain automatically on the converter's working situation.
|
||||
* Execute the calibration before using the converter. Note that the hardware trigger should be used
|
||||
* during calibration.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
*
|
||||
* @return Execution status.
|
||||
* @retval kStatus_Success Calibration is done successfully.
|
||||
* @retval kStatus_Fail Calibration is failed.
|
||||
*/
|
||||
status_t ADC16_DoAutoCalibration(ADC_Type *base);
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION) && FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION
|
||||
/*!
|
||||
* @brief Sets the offset value for the conversion result.
|
||||
*
|
||||
* This offset value takes effect on the conversion result. If the offset value is not zero, the reading result
|
||||
* is subtracted by it. Note, the hardware calibration fills the offset value automatically.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
* @param value Setting offset value.
|
||||
*/
|
||||
static inline void ADC16_SetOffsetValue(ADC_Type *base, int16_t value)
|
||||
{
|
||||
base->OFS = (uint32_t)(value);
|
||||
}
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION */
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Advanced Feature
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_DMA) && FSL_FEATURE_ADC16_HAS_DMA
|
||||
/*!
|
||||
* @brief Enables generating the DMA trigger when conversion is completed.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
* @param enable Switcher of DMA feature. "true" means to enable, "false" means not.
|
||||
*/
|
||||
static inline void ADC16_EnableDMA(ADC_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->SC2 |= ADC_SC2_DMAEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->SC2 &= ~ADC_SC2_DMAEN_MASK;
|
||||
}
|
||||
}
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_DMA */
|
||||
|
||||
/*!
|
||||
* @brief Enables the hardware trigger mode.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
* @param enable Switcher of hardware trigger feature. "true" means to enable, "false" means not.
|
||||
*/
|
||||
static inline void ADC16_EnableHardwareTrigger(ADC_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->SC2 |= ADC_SC2_ADTRG_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->SC2 &= ~ADC_SC2_ADTRG_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT
|
||||
/*!
|
||||
* @brief Sets the channel mux mode.
|
||||
*
|
||||
* Some sample pins share the same channel index. The channel mux mode decides which pin is used for an
|
||||
* indicated channel.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
* @param mode Setting channel mux mode. See "adc16_channel_mux_mode_t".
|
||||
*/
|
||||
void ADC16_SetChannelMuxMode(ADC_Type *base, adc16_channel_mux_mode_t mode);
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */
|
||||
|
||||
/*!
|
||||
* @brief Configures the hardware compare mode.
|
||||
*
|
||||
* The hardware compare mode provides a way to process the conversion result automatically by hardware. Only the result
|
||||
* in
|
||||
* compare range is available. To compare the range, see "adc16_hardware_compare_mode_t", or the reference
|
||||
* manual document for more detailed information.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
* @param config Pointer to "adc16_hardware_compare_config_t" structure. Passing "NULL" is to disable the feature.
|
||||
*/
|
||||
void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config);
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE
|
||||
/*!
|
||||
* @brief Sets the hardware average mode.
|
||||
*
|
||||
* Hardware average mode provides a way to process the conversion result automatically by hardware. The multiple
|
||||
* conversion results are accumulated and averaged internally. This aids reading results.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
* @param mode Setting hardware average mode. See "adc16_hardware_average_mode_t".
|
||||
*/
|
||||
void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode);
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */
|
||||
|
||||
#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA
|
||||
/*!
|
||||
* @brief Configures the PGA for converter's front end.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
* @param config Pointer to "adc16_pga_config_t" structure. Passing "NULL" is to disable the feature.
|
||||
*/
|
||||
void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config);
|
||||
#endif /* FSL_FEATURE_ADC16_HAS_PGA */
|
||||
|
||||
/*!
|
||||
* @brief Gets the status flags of the converter.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
*
|
||||
* @return Flags' mask if indicated flags are asserted. See "_adc16_status_flags".
|
||||
*/
|
||||
uint32_t ADC16_GetStatusFlags(ADC_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Clears the status flags of the converter.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
* @param mask Mask value for the cleared flags. See "_adc16_status_flags".
|
||||
*/
|
||||
void ADC16_ClearStatusFlags(ADC_Type *base, uint32_t mask);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Conversion Channel
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Configures the conversion channel.
|
||||
*
|
||||
* This operation triggers the conversion if in software trigger mode. When in hardware trigger mode, this API
|
||||
* configures the channel while the external trigger source helps to trigger the conversion.
|
||||
*
|
||||
* Note that the "Channel Group" has a detailed description.
|
||||
* To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC can have more than one
|
||||
* group of status and control register, one for each conversion. The channel group parameter indicates which group of
|
||||
* registers are used channel group 0 is for Group A registers and channel group 1 is for Group B registers. The
|
||||
* channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of
|
||||
* the channel groups is actively controlling ADC conversions. Channel group 0 is used for both software and hardware
|
||||
* trigger modes of operation. Channel groups 1 and greater indicate potentially multiple channel group registers for
|
||||
* use only in hardware trigger mode. See the chip configuration information in the MCU reference manual about the
|
||||
* number of SC1n registers (channel groups) specific to this device. None of the channel groups 1 or greater are used
|
||||
* for software trigger operation and therefore writes to these channel groups do not initiate a new conversion.
|
||||
* Updating channel group 0 while a different channel group is actively controlling a conversion is allowed and
|
||||
* vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a
|
||||
* conversion aborts the current conversion.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
* @param channelGroup Channel group index.
|
||||
* @param config Pointer to "adc16_channel_config_t" structure for conversion channel.
|
||||
*/
|
||||
void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Gets the conversion value.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
* @param channelGroup Channel group index.
|
||||
*
|
||||
* @return Conversion value.
|
||||
*/
|
||||
static inline uint32_t ADC16_GetChannelConversionValue(ADC_Type *base, uint32_t channelGroup)
|
||||
{
|
||||
assert(channelGroup < ADC_R_COUNT);
|
||||
|
||||
return base->R[channelGroup];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the status flags of channel.
|
||||
*
|
||||
* @param base ADC16 peripheral base address.
|
||||
* @param channelGroup Channel group index.
|
||||
*
|
||||
* @return Flags' mask if indicated flags are asserted. See "_adc16_channel_status_flags".
|
||||
*/
|
||||
uint32_t ADC16_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
#endif /* _FSL_ADC16_H_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,279 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_cmp.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Get instance number for CMP module.
|
||||
*
|
||||
* @param base CMP peripheral base address
|
||||
*/
|
||||
static uint32_t CMP_GetInstance(CMP_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/*! @brief Pointers to CMP bases for each instance. */
|
||||
static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS;
|
||||
/*! @brief Pointers to CMP clocks for each instance. */
|
||||
const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Codes
|
||||
******************************************************************************/
|
||||
static uint32_t CMP_GetInstance(CMP_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_CMP_COUNT; instance++)
|
||||
{
|
||||
if (s_cmpBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < FSL_FEATURE_SOC_CMP_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void CMP_Init(CMP_Type *base, const cmp_config_t *config)
|
||||
{
|
||||
assert(NULL != config);
|
||||
|
||||
uint8_t tmp8;
|
||||
|
||||
/* Enable the clock. */
|
||||
CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]);
|
||||
|
||||
/* Configure. */
|
||||
CMP_Enable(base, false); /* Disable the CMP module during configuring. */
|
||||
/* CMPx_CR1. */
|
||||
tmp8 = base->CR1 & ~(CMP_CR1_PMODE_MASK | CMP_CR1_INV_MASK | CMP_CR1_COS_MASK | CMP_CR1_OPE_MASK);
|
||||
if (config->enableHighSpeed)
|
||||
{
|
||||
tmp8 |= CMP_CR1_PMODE_MASK;
|
||||
}
|
||||
if (config->enableInvertOutput)
|
||||
{
|
||||
tmp8 |= CMP_CR1_INV_MASK;
|
||||
}
|
||||
if (config->useUnfilteredOutput)
|
||||
{
|
||||
tmp8 |= CMP_CR1_COS_MASK;
|
||||
}
|
||||
if (config->enablePinOut)
|
||||
{
|
||||
tmp8 |= CMP_CR1_OPE_MASK;
|
||||
}
|
||||
#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
|
||||
if (config->enableTriggerMode)
|
||||
{
|
||||
tmp8 |= CMP_CR1_TRIGM_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp8 &= ~CMP_CR1_TRIGM_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
|
||||
base->CR1 = tmp8;
|
||||
|
||||
/* CMPx_CR0. */
|
||||
tmp8 = base->CR0 & ~CMP_CR0_HYSTCTR_MASK;
|
||||
tmp8 |= CMP_CR0_HYSTCTR(config->hysteresisMode);
|
||||
base->CR0 = tmp8;
|
||||
|
||||
CMP_Enable(base, config->enableCmp); /* Enable the CMP module after configured or not. */
|
||||
}
|
||||
|
||||
void CMP_Deinit(CMP_Type *base)
|
||||
{
|
||||
/* Disable the CMP module. */
|
||||
CMP_Enable(base, false);
|
||||
|
||||
/* Disable the clock. */
|
||||
CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]);
|
||||
}
|
||||
|
||||
void CMP_GetDefaultConfig(cmp_config_t *config)
|
||||
{
|
||||
assert(NULL != config);
|
||||
|
||||
config->enableCmp = true; /* Enable the CMP module after initialization. */
|
||||
config->hysteresisMode = kCMP_HysteresisLevel0;
|
||||
config->enableHighSpeed = false;
|
||||
config->enableInvertOutput = false;
|
||||
config->useUnfilteredOutput = false;
|
||||
config->enablePinOut = false;
|
||||
#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
|
||||
config->enableTriggerMode = false;
|
||||
#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
|
||||
}
|
||||
|
||||
void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel)
|
||||
{
|
||||
uint8_t tmp8 = base->MUXCR;
|
||||
|
||||
tmp8 &= ~(CMP_MUXCR_PSEL_MASK | CMP_MUXCR_MSEL_MASK);
|
||||
tmp8 |= CMP_MUXCR_PSEL(positiveChannel) | CMP_MUXCR_MSEL(negativeChannel);
|
||||
base->MUXCR = tmp8;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA
|
||||
void CMP_EnableDMA(CMP_Type *base, bool enable)
|
||||
{
|
||||
uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */
|
||||
|
||||
if (enable)
|
||||
{
|
||||
tmp8 |= CMP_SCR_DMAEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp8 &= ~CMP_SCR_DMAEN_MASK;
|
||||
}
|
||||
base->SCR = tmp8;
|
||||
}
|
||||
#endif /* FSL_FEATURE_CMP_HAS_DMA */
|
||||
|
||||
void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config)
|
||||
{
|
||||
assert(NULL != config);
|
||||
|
||||
uint8_t tmp8;
|
||||
|
||||
#if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT
|
||||
/* Choose the clock source for sampling. */
|
||||
if (config->enableSample)
|
||||
{
|
||||
base->CR1 |= CMP_CR1_SE_MASK; /* Choose the external SAMPLE clock. */
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CR1 &= ~CMP_CR1_SE_MASK; /* Choose the internal divided bus clock. */
|
||||
}
|
||||
#endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */
|
||||
/* Set the filter count. */
|
||||
tmp8 = base->CR0 & ~CMP_CR0_FILTER_CNT_MASK;
|
||||
tmp8 |= CMP_CR0_FILTER_CNT(config->filterCount);
|
||||
base->CR0 = tmp8;
|
||||
/* Set the filter period. It is used as the divider to bus clock. */
|
||||
base->FPR = CMP_FPR_FILT_PER(config->filterPeriod);
|
||||
}
|
||||
|
||||
void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config)
|
||||
{
|
||||
uint8_t tmp8 = 0U;
|
||||
|
||||
if (NULL == config)
|
||||
{
|
||||
/* Passing "NULL" as input parameter means no available configuration. So the DAC feature is disabled.*/
|
||||
base->DACCR = 0U;
|
||||
return;
|
||||
}
|
||||
/* CMPx_DACCR. */
|
||||
tmp8 |= CMP_DACCR_DACEN_MASK; /* Enable the internal DAC. */
|
||||
if (kCMP_VrefSourceVin2 == config->referenceVoltageSource)
|
||||
{
|
||||
tmp8 |= CMP_DACCR_VRSEL_MASK;
|
||||
}
|
||||
tmp8 |= CMP_DACCR_VOSEL(config->DACValue);
|
||||
|
||||
base->DACCR = tmp8;
|
||||
}
|
||||
|
||||
void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask)
|
||||
{
|
||||
uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */
|
||||
|
||||
if (0U != (kCMP_OutputRisingInterruptEnable & mask))
|
||||
{
|
||||
tmp8 |= CMP_SCR_IER_MASK;
|
||||
}
|
||||
if (0U != (kCMP_OutputFallingInterruptEnable & mask))
|
||||
{
|
||||
tmp8 |= CMP_SCR_IEF_MASK;
|
||||
}
|
||||
base->SCR = tmp8;
|
||||
}
|
||||
|
||||
void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask)
|
||||
{
|
||||
uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */
|
||||
|
||||
if (0U != (kCMP_OutputRisingInterruptEnable & mask))
|
||||
{
|
||||
tmp8 &= ~CMP_SCR_IER_MASK;
|
||||
}
|
||||
if (0U != (kCMP_OutputFallingInterruptEnable & mask))
|
||||
{
|
||||
tmp8 &= ~CMP_SCR_IEF_MASK;
|
||||
}
|
||||
base->SCR = tmp8;
|
||||
}
|
||||
|
||||
uint32_t CMP_GetStatusFlags(CMP_Type *base)
|
||||
{
|
||||
uint32_t ret32 = 0U;
|
||||
|
||||
if (0U != (CMP_SCR_CFR_MASK & base->SCR))
|
||||
{
|
||||
ret32 |= kCMP_OutputRisingEventFlag;
|
||||
}
|
||||
if (0U != (CMP_SCR_CFF_MASK & base->SCR))
|
||||
{
|
||||
ret32 |= kCMP_OutputFallingEventFlag;
|
||||
}
|
||||
if (0U != (CMP_SCR_COUT_MASK & base->SCR))
|
||||
{
|
||||
ret32 |= kCMP_OutputAssertEventFlag;
|
||||
}
|
||||
return ret32;
|
||||
}
|
||||
|
||||
void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask)
|
||||
{
|
||||
uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */
|
||||
|
||||
if (0U != (kCMP_OutputRisingEventFlag & mask))
|
||||
{
|
||||
tmp8 |= CMP_SCR_CFR_MASK;
|
||||
}
|
||||
if (0U != (kCMP_OutputFallingEventFlag & mask))
|
||||
{
|
||||
tmp8 |= CMP_SCR_CFF_MASK;
|
||||
}
|
||||
base->SCR = tmp8;
|
||||
}
|
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FSL_CMP_H_
|
||||
#define _FSL_CMP_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup cmp
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief CMP driver version 2.0.0. */
|
||||
#define FSL_CMP_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief Interrupt enable/disable mask.
|
||||
*/
|
||||
enum _cmp_interrupt_enable
|
||||
{
|
||||
kCMP_OutputRisingInterruptEnable = CMP_SCR_IER_MASK, /*!< Comparator interrupt enable rising. */
|
||||
kCMP_OutputFallingInterruptEnable = CMP_SCR_IEF_MASK, /*!< Comparator interrupt enable falling. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief Status flags' mask.
|
||||
*/
|
||||
enum _cmp_status_flags
|
||||
{
|
||||
kCMP_OutputRisingEventFlag = CMP_SCR_CFR_MASK, /*!< Rising-edge on compare output has occurred. */
|
||||
kCMP_OutputFallingEventFlag = CMP_SCR_CFF_MASK, /*!< Falling-edge on compare output has occurred. */
|
||||
kCMP_OutputAssertEventFlag = CMP_SCR_COUT_MASK, /*!< Return the current value of the analog comparator output. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief CMP Hysteresis mode.
|
||||
*/
|
||||
typedef enum _cmp_hysteresis_mode
|
||||
{
|
||||
kCMP_HysteresisLevel0 = 0U, /*!< Hysteresis level 0. */
|
||||
kCMP_HysteresisLevel1 = 1U, /*!< Hysteresis level 1. */
|
||||
kCMP_HysteresisLevel2 = 2U, /*!< Hysteresis level 2. */
|
||||
kCMP_HysteresisLevel3 = 3U, /*!< Hysteresis level 3. */
|
||||
} cmp_hysteresis_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief CMP Voltage Reference source.
|
||||
*/
|
||||
typedef enum _cmp_reference_voltage_source
|
||||
{
|
||||
kCMP_VrefSourceVin1 = 0U, /*!< Vin1 is selected as resistor ladder network supply reference Vin. */
|
||||
kCMP_VrefSourceVin2 = 1U, /*!< Vin2 is selected as resistor ladder network supply reference Vin. */
|
||||
} cmp_reference_voltage_source_t;
|
||||
|
||||
/*!
|
||||
* @brief Configure the comparator.
|
||||
*/
|
||||
typedef struct _cmp_config
|
||||
{
|
||||
bool enableCmp; /*!< Enable the CMP module. */
|
||||
cmp_hysteresis_mode_t hysteresisMode; /*!< CMP Hysteresis mode. */
|
||||
bool enableHighSpeed; /*!< Enable High Speed (HS) comparison mode. */
|
||||
bool enableInvertOutput; /*!< Enable inverted comparator output. */
|
||||
bool useUnfilteredOutput; /*!< Set compare output(COUT) to equal COUTA(true) or COUT(false). */
|
||||
bool enablePinOut; /*!< The comparator output is available on the associated pin. */
|
||||
#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
|
||||
bool enableTriggerMode; /*!< Enable the trigger mode. */
|
||||
#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
|
||||
} cmp_config_t;
|
||||
|
||||
/*!
|
||||
* @brief Configure the filter.
|
||||
*/
|
||||
typedef struct _cmp_filter_config
|
||||
{
|
||||
#if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT
|
||||
bool enableSample; /*!< Using external SAMPLE as sampling clock input, or using divided bus clock. */
|
||||
#endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */
|
||||
uint8_t filterCount; /*!< Filter Sample Count. Available range is 1-7, 0 would cause the filter disabled.*/
|
||||
uint8_t filterPeriod; /*!< Filter Sample Period. The divider to bus clock. Available range is 0-255. */
|
||||
} cmp_filter_config_t;
|
||||
|
||||
/*!
|
||||
* @brief Configure the internal DAC.
|
||||
*/
|
||||
typedef struct _cmp_dac_config
|
||||
{
|
||||
cmp_reference_voltage_source_t referenceVoltageSource; /*!< Supply voltage reference source. */
|
||||
uint8_t DACValue; /*!< Value for DAC Output Voltage. Available range is 0-63.*/
|
||||
} cmp_dac_config_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @name Initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the CMP.
|
||||
*
|
||||
* This function initializes the CMP module. The operations included are:
|
||||
* - Enabling the clock for CMP module.
|
||||
* - Configuring the comparator.
|
||||
* - Enabling the CMP module.
|
||||
* Note: For some devices, multiple CMP instance share the same clock gate. In this case, to enable the clock for
|
||||
* any instance enables all the CMPs. Check the chip reference manual for the clock assignment of the CMP.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
* @param config Pointer to configuration structure.
|
||||
*/
|
||||
void CMP_Init(CMP_Type *base, const cmp_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief De-initializes the CMP module.
|
||||
*
|
||||
* This function de-initializes the CMP module. The operations included are:
|
||||
* - Disabling the CMP module.
|
||||
* - Disabling the clock for CMP module.
|
||||
*
|
||||
* This function disables the clock for the CMP.
|
||||
* Note: For some devices, multiple CMP instance shares the same clock gate. In this case, before disabling the
|
||||
* clock for the CMP, ensure that all the CMP instances are not used.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
*/
|
||||
void CMP_Deinit(CMP_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Enables/disables the CMP module.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
* @param enable Enable the module or not.
|
||||
*/
|
||||
static inline void CMP_Enable(CMP_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->CR1 |= CMP_CR1_EN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CR1 &= ~CMP_CR1_EN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Initializes the CMP user configuration structure.
|
||||
*
|
||||
* This function initializes the user configure structure to these default values:
|
||||
* @code
|
||||
* config->enableCmp = true;
|
||||
* config->hysteresisMode = kCMP_HysteresisLevel0;
|
||||
* config->enableHighSpeed = false;
|
||||
* config->enableInvertOutput = false;
|
||||
* config->useUnfilteredOutput = false;
|
||||
* config->enablePinOut = false;
|
||||
* config->enableTriggerMode = false;
|
||||
* @endcode
|
||||
* @param config Pointer to the configuration structure.
|
||||
*/
|
||||
void CMP_GetDefaultConfig(cmp_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Sets the input channels for the comparator.
|
||||
*
|
||||
* This function sets the input channels for the comparator.
|
||||
* Note that two input channels cannot be set as same in the application. When the user selects the same input
|
||||
* from the analog mux to the positive and negative port, the comparator is disabled automatically.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
* @param positiveChannel Positive side input channel number. Available range is 0-7.
|
||||
* @param negativeChannel Negative side input channel number. Available range is 0-7.
|
||||
*/
|
||||
void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Advanced Features
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA
|
||||
/*!
|
||||
* @brief Enables/disables the DMA request for rising/falling events.
|
||||
*
|
||||
* This function enables/disables the DMA request for rising/falling events. Either event triggers the generation of
|
||||
* the DMA
|
||||
* request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from the CMP
|
||||
* if the
|
||||
* DMA is disabled.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
* @param enable Enable the feature or not.
|
||||
*/
|
||||
void CMP_EnableDMA(CMP_Type *base, bool enable);
|
||||
#endif /* FSL_FEATURE_CMP_HAS_DMA */
|
||||
|
||||
#if defined(FSL_FEATURE_CMP_HAS_WINDOW_MODE) && FSL_FEATURE_CMP_HAS_WINDOW_MODE
|
||||
/*!
|
||||
* @brief Enables/disables the window mode.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
* @param enable Enable the feature or not.
|
||||
*/
|
||||
static inline void CMP_EnableWindowMode(CMP_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->CR1 |= CMP_CR1_WE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CR1 &= ~CMP_CR1_WE_MASK;
|
||||
}
|
||||
}
|
||||
#endif /* FSL_FEATURE_CMP_HAS_WINDOW_MODE */
|
||||
|
||||
#if defined(FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE) && FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE
|
||||
/*!
|
||||
* @brief Enables/disables the pass through mode.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
* @param enable Enable the feature or not.
|
||||
*/
|
||||
static inline void CMP_EnablePassThroughMode(CMP_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->MUXCR |= CMP_MUXCR_PSTM_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->MUXCR &= ~CMP_MUXCR_PSTM_MASK;
|
||||
}
|
||||
}
|
||||
#endif /* FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE */
|
||||
|
||||
/*!
|
||||
* @brief Configures the filter.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
* @param config Pointer to configuration structure.
|
||||
*/
|
||||
void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Configures the internal DAC.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
* @param config Pointer to configuration structure. "NULL" is for disabling the feature.
|
||||
*/
|
||||
void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Enables the interrupts.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
* @param mask Mask value for interrupts. See "_cmp_interrupt_enable".
|
||||
*/
|
||||
void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask);
|
||||
|
||||
/*!
|
||||
* @brief Disables the interrupts.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
* @param mask Mask value for interrupts. See "_cmp_interrupt_enable".
|
||||
*/
|
||||
void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Results
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Gets the status flags.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
*
|
||||
* @return Mask value for the asserted flags. See "_cmp_status_flags".
|
||||
*/
|
||||
uint32_t CMP_GetStatusFlags(CMP_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Clears the status flags.
|
||||
*
|
||||
* @param base CMP peripheral base address.
|
||||
* @param mask Mask value for the flags. See "_cmp_status_flags".
|
||||
*/
|
||||
void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask);
|
||||
|
||||
/* @} */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
#endif /* _FSL_CMP_H_ */
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_cmt.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* The standard intermediate frequency (IF). */
|
||||
#define CMT_INTERMEDIATEFREQUENCY_8MHZ (8000000U)
|
||||
/* CMT data modulate mask. */
|
||||
#define CMT_MODULATE_COUNT_WIDTH (8U)
|
||||
/* CMT diver 1. */
|
||||
#define CMT_CMTDIV_ONE (1)
|
||||
/* CMT diver 2. */
|
||||
#define CMT_CMTDIV_TWO (2)
|
||||
/* CMT diver 4. */
|
||||
#define CMT_CMTDIV_FOUR (4)
|
||||
/* CMT diver 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
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Get instance number for CMT module.
|
||||
*
|
||||
* @param base CMT peripheral base address.
|
||||
*/
|
||||
static uint32_t CMT_GetInstance(CMT_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Pointers to cmt clocks for each instance. */
|
||||
const clock_ip_name_t s_cmtClock[FSL_FEATURE_SOC_CMT_COUNT] = CMT_CLOCKS;
|
||||
|
||||
/*! @brief Pointers to cmt bases for each instance. */
|
||||
static CMT_Type *const s_cmtBases[] = CMT_BASE_PTRS;
|
||||
|
||||
/*! @brief Pointers to cmt IRQ number for each instance. */
|
||||
const IRQn_Type s_cmtIrqs[] = CMT_IRQS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Codes
|
||||
******************************************************************************/
|
||||
|
||||
static uint32_t CMT_GetInstance(CMT_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_CMT_COUNT; instance++)
|
||||
{
|
||||
if (s_cmtBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < FSL_FEATURE_SOC_CMT_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void CMT_GetDefaultConfig(cmt_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
/* Default infrared output is enabled and set with high active, the divider is set to 1. */
|
||||
config->isInterruptEnabled = false;
|
||||
config->isIroEnabled = true;
|
||||
config->iroPolarity = kCMT_IROActiveHigh;
|
||||
config->divider = kCMT_SecondClkDiv1;
|
||||
}
|
||||
|
||||
void CMT_Init(CMT_Type *base, const cmt_config_t *config, uint32_t busClock_Hz)
|
||||
{
|
||||
assert(config);
|
||||
assert(busClock_Hz >= CMT_INTERMEDIATEFREQUENCY_8MHZ);
|
||||
|
||||
uint8_t divider;
|
||||
|
||||
/* Ungate clock. */
|
||||
CLOCK_EnableClock(s_cmtClock[CMT_GetInstance(base)]);
|
||||
|
||||
/* Sets clock divider. The divider set in pps should be set
|
||||
to make sycClock_Hz/divder = 8MHz */
|
||||
base->PPS = CMT_PPS_PPSDIV(busClock_Hz / CMT_INTERMEDIATEFREQUENCY_8MHZ - 1);
|
||||
divider = base->MSC;
|
||||
divider &= ~CMT_MSC_CMTDIV_MASK;
|
||||
divider |= CMT_MSC_CMTDIV(config->divider);
|
||||
base->MSC = divider;
|
||||
|
||||
/* Set the IRO signal. */
|
||||
base->OC = CMT_OC_CMTPOL(config->iroPolarity) | CMT_OC_IROPEN(config->isIroEnabled);
|
||||
|
||||
/* Set interrupt. */
|
||||
if (config->isInterruptEnabled)
|
||||
{
|
||||
CMT_EnableInterrupts(base, kCMT_EndOfCycleInterruptEnable);
|
||||
EnableIRQ(s_cmtIrqs[CMT_GetInstance(base)]);
|
||||
}
|
||||
}
|
||||
|
||||
void CMT_Deinit(CMT_Type *base)
|
||||
{
|
||||
/*Disable the CMT modulator. */
|
||||
base->MSC = 0;
|
||||
|
||||
/* Disable the interrupt. */
|
||||
CMT_DisableInterrupts(base, kCMT_EndOfCycleInterruptEnable);
|
||||
DisableIRQ(s_cmtIrqs[CMT_GetInstance(base)]);
|
||||
|
||||
/* Gate the clock. */
|
||||
CLOCK_DisableClock(s_cmtClock[CMT_GetInstance(base)]);
|
||||
}
|
||||
|
||||
void CMT_SetMode(CMT_Type *base, cmt_mode_t mode, cmt_modulate_config_t *modulateConfig)
|
||||
{
|
||||
uint8_t mscReg;
|
||||
|
||||
/* Set the mode. */
|
||||
if (mode != kCMT_DirectIROCtl)
|
||||
{
|
||||
assert(modulateConfig);
|
||||
|
||||
/* Set carrier generator. */
|
||||
CMT_SetCarrirGenerateCountOne(base, modulateConfig->highCount1, modulateConfig->lowCount1);
|
||||
if (mode == kCMT_FSKMode)
|
||||
{
|
||||
CMT_SetCarrirGenerateCountTwo(base, modulateConfig->highCount2, modulateConfig->lowCount2);
|
||||
}
|
||||
|
||||
/* Set carrier modulator. */
|
||||
CMT_SetModulateMarkSpace(base, modulateConfig->markCount, modulateConfig->spaceCount);
|
||||
}
|
||||
|
||||
/* Set the CMT mode. */
|
||||
mscReg = base->MSC;
|
||||
mscReg &= ~CMT_MODE_BIT_MASK;
|
||||
mscReg |= mode;
|
||||
|
||||
base->MSC = mscReg;
|
||||
}
|
||||
|
||||
cmt_mode_t CMT_GetMode(CMT_Type *base)
|
||||
{
|
||||
uint8_t mode = base->MSC;
|
||||
|
||||
if (!(mode & CMT_MSC_MCGEN_MASK))
|
||||
{ /* Carrier modulator disabled and the IRO signal is in direct software control. */
|
||||
return kCMT_DirectIROCtl;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Carrier modulator is enabled. */
|
||||
if (mode & CMT_MSC_BASE_MASK)
|
||||
{
|
||||
/* Base band mode. */
|
||||
return kCMT_BasebandMode;
|
||||
}
|
||||
else if (mode & CMT_MSC_FSK_MASK)
|
||||
{
|
||||
/* FSK mode. */
|
||||
return kCMT_FSKMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Time mode. */
|
||||
return kCMT_TimeMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CMT_GetCMTFrequency(CMT_Type *base, uint32_t busClock_Hz)
|
||||
{
|
||||
uint32_t frequency;
|
||||
uint32_t divider;
|
||||
|
||||
/* Get intermediate frequency. */
|
||||
frequency = busClock_Hz / ((base->PPS & CMT_PPS_PPSDIV_MASK) + 1);
|
||||
|
||||
/* Get the second divider. */
|
||||
divider = ((base->MSC & CMT_MSC_CMTDIV_MASK) >> CMT_MSC_CMTDIV_SHIFT);
|
||||
/* Get CMT frequency. */
|
||||
switch ((cmt_second_clkdiv_t)divider)
|
||||
{
|
||||
case kCMT_SecondClkDiv1:
|
||||
frequency = frequency / CMT_CMTDIV_ONE;
|
||||
break;
|
||||
case kCMT_SecondClkDiv2:
|
||||
frequency = frequency / CMT_CMTDIV_TWO;
|
||||
break;
|
||||
case kCMT_SecondClkDiv4:
|
||||
frequency = frequency / CMT_CMTDIV_FOUR;
|
||||
break;
|
||||
case kCMT_SecondClkDiv8:
|
||||
frequency = frequency / CMT_CMTDIV_EIGHT;
|
||||
break;
|
||||
default:
|
||||
frequency = frequency / CMT_CMTDIV_ONE;
|
||||
break;
|
||||
}
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
void CMT_SetModulateMarkSpace(CMT_Type *base, uint32_t markCount, uint32_t spaceCount)
|
||||
{
|
||||
/* Set modulate mark. */
|
||||
base->CMD1 = (markCount >> CMT_MODULATE_COUNT_WIDTH) & CMT_CMD1_MB_MASK;
|
||||
base->CMD2 = (markCount & CMT_CMD2_MB_MASK);
|
||||
/* Set modulate space. */
|
||||
base->CMD3 = (spaceCount >> CMT_MODULATE_COUNT_WIDTH) & CMT_CMD3_SB_MASK;
|
||||
base->CMD4 = spaceCount & CMT_CMD4_SB_MASK;
|
||||
}
|
||||
|
||||
void CMT_SetIroState(CMT_Type *base, cmt_infrared_output_state_t state)
|
||||
{
|
||||
uint8_t ocReg = base->OC;
|
||||
|
||||
ocReg &= ~CMT_OC_IROL_MASK;
|
||||
ocReg |= CMT_OC_IROL(state);
|
||||
|
||||
/* Set the infrared output signal control. */
|
||||
base->OC = ocReg;
|
||||
}
|
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_CMT_H_
|
||||
#define _FSL_CMT_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup cmt
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief CMT driver version 2.0.0. */
|
||||
#define FSL_CMT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief The modes of CMT.
|
||||
*/
|
||||
typedef enum _cmt_mode
|
||||
{
|
||||
kCMT_DirectIROCtl = 0x00U, /*!< Carrier modulator is disabled and the IRO signal is directly in software control */
|
||||
kCMT_TimeMode = 0x01U, /*!< Carrier modulator is enabled in time mode. */
|
||||
kCMT_FSKMode = 0x05U, /*!< Carrier modulator is enabled in FSK mode. */
|
||||
kCMT_BasebandMode = 0x09U /*!< Carrier modulator is enabled in baseband mode. */
|
||||
} cmt_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief The CMT clock divide primary prescaler.
|
||||
* The primary clock divider is used to divider the bus clock to
|
||||
* get the intermediate frequency to approximately equal to 8 MHZ.
|
||||
* When the bus clock is 8 MHZ, set primary prescaler to "kCMT_PrimaryClkDiv1".
|
||||
*/
|
||||
typedef enum _cmt_primary_clkdiv
|
||||
{
|
||||
kCMT_PrimaryClkDiv1 = 0U, /*!< The intermediate frequency is the bus clock divided by 1. */
|
||||
kCMT_PrimaryClkDiv2 = 1U, /*!< The intermediate frequency is the bus clock divided by 2. */
|
||||
kCMT_PrimaryClkDiv3 = 2U, /*!< The intermediate frequency is the bus clock divided by 3. */
|
||||
kCMT_PrimaryClkDiv4 = 3U, /*!< The intermediate frequency is the bus clock divided by 4. */
|
||||
kCMT_PrimaryClkDiv5 = 4U, /*!< The intermediate frequency is the bus clock divided by 5. */
|
||||
kCMT_PrimaryClkDiv6 = 5U, /*!< The intermediate frequency is the bus clock divided by 6. */
|
||||
kCMT_PrimaryClkDiv7 = 6U, /*!< The intermediate frequency is the bus clock divided by 7. */
|
||||
kCMT_PrimaryClkDiv8 = 7U, /*!< The intermediate frequency is the bus clock divided by 8. */
|
||||
kCMT_PrimaryClkDiv9 = 8U, /*!< The intermediate frequency is the bus clock divided by 9. */
|
||||
kCMT_PrimaryClkDiv10 = 9U, /*!< The intermediate frequency is the bus clock divided by 10. */
|
||||
kCMT_PrimaryClkDiv11 = 10U, /*!< The intermediate frequency is the bus clock divided by 11. */
|
||||
kCMT_PrimaryClkDiv12 = 11U, /*!< The intermediate frequency is the bus clock divided by 12. */
|
||||
kCMT_PrimaryClkDiv13 = 12U, /*!< The intermediate frequency is the bus clock divided by 13. */
|
||||
kCMT_PrimaryClkDiv14 = 13U, /*!< The intermediate frequency is the bus clock divided by 14. */
|
||||
kCMT_PrimaryClkDiv15 = 14U, /*!< The intermediate frequency is the bus clock divided by 15. */
|
||||
kCMT_PrimaryClkDiv16 = 15U /*!< The intermediate frequency is the bus clock divided by 16. */
|
||||
} cmt_primary_clkdiv_t;
|
||||
|
||||
/*!
|
||||
* @brief The CMT clock divide secondary prescaler.
|
||||
* The second prescaler can be used to divide the 8 MHZ CMT clock
|
||||
* by 1, 2, 4, or 8 according to the specification.
|
||||
*/
|
||||
typedef enum _cmt_second_clkdiv
|
||||
{
|
||||
kCMT_SecondClkDiv1 = 0U, /*!< The CMT clock is the intermediate frequency frequency divided by 1. */
|
||||
kCMT_SecondClkDiv2 = 1U, /*!< The CMT clock is the intermediate frequency frequency divided by 2. */
|
||||
kCMT_SecondClkDiv4 = 2U, /*!< The CMT clock is the intermediate frequency frequency divided by 4. */
|
||||
kCMT_SecondClkDiv8 = 3U /*!< The CMT clock is the intermediate frequency frequency divided by 8. */
|
||||
} cmt_second_clkdiv_t;
|
||||
|
||||
/*!
|
||||
* @brief The CMT infrared output polarity.
|
||||
*/
|
||||
typedef enum _cmt_infrared_output_polarity
|
||||
{
|
||||
kCMT_IROActiveLow = 0U, /*!< The CMT infrared output signal polarity is active-low. */
|
||||
kCMT_IROActiveHigh = 1U /*!< The CMT infrared output signal polarity is active-high. */
|
||||
} cmt_infrared_output_polarity_t;
|
||||
|
||||
/*!
|
||||
* @brief The CMT infrared output signal state control.
|
||||
*/
|
||||
typedef enum _cmt_infrared_output_state
|
||||
{
|
||||
kCMT_IROCtlLow = 0U, /*!< The CMT Infrared output signal state is controlled to low. */
|
||||
kCMT_IROCtlHigh = 1U /*!< The CMT Infrared output signal state is controlled to high. */
|
||||
} cmt_infrared_output_state_t;
|
||||
|
||||
/*!
|
||||
* @brief CMT interrupt configuration structure, default settings all disabled.
|
||||
*
|
||||
* This structure contains the settings for all of the CMT interrupt configurations.
|
||||
*/
|
||||
enum _cmt_interrupt_enable
|
||||
{
|
||||
kCMT_EndOfCycleInterruptEnable = CMT_MSC_EOCIE_MASK, /*!< CMT end of cycle interrupt. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief CMT carrier generator and modulator configure structure
|
||||
*
|
||||
*/
|
||||
typedef struct _cmt_modulate_config
|
||||
{
|
||||
uint8_t highCount1; /*!< The high 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 lowCount2; /*!< The low time for carrier generator second register for FSK mode. */
|
||||
uint16_t markCount; /*!< The mark time for the modulator gate. */
|
||||
uint16_t spaceCount; /*!< The space time for the modulator gate. */
|
||||
} cmt_modulate_config_t;
|
||||
|
||||
/*! @brief CMT basic configuration structure. */
|
||||
typedef struct _cmt_config
|
||||
{
|
||||
bool isInterruptEnabled; /*!< Timer interrupt 0-disable, 1-enable. */
|
||||
bool isIroEnabled; /*!< The IRO output 0-disabled, 1-enabled. */
|
||||
cmt_infrared_output_polarity_t iroPolarity; /*!< The IRO polarity. */
|
||||
cmt_second_clkdiv_t divider; /*!< The CMT clock divide prescaler. */
|
||||
} cmt_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Initialization and deinitialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Gets the CMT default configuration structure. The purpose
|
||||
* of this API is to get the default configuration structure for the CMT_Init().
|
||||
* Use the initialized structure unchanged in CMT_Init(), or modify
|
||||
* some fields of the structure before calling the CMT_Init().
|
||||
*
|
||||
* @param config The CMT configuration structure pointer.
|
||||
*/
|
||||
void CMT_GetDefaultConfig(cmt_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the CMT module.
|
||||
*
|
||||
* This function ungates the module clock and sets the CMT internal clock,
|
||||
* interrupt, and infrared output signal for the CMT module.
|
||||
*
|
||||
* @param base CMT peripheral base address.
|
||||
* @param config The CMT basic configuration structure.
|
||||
* @param busClock_Hz The CMT module input clock - bus clock frequency.
|
||||
*/
|
||||
void CMT_Init(CMT_Type *base, const cmt_config_t *config, uint32_t busClock_Hz);
|
||||
|
||||
/*!
|
||||
* @brief Disables the CMT module and gate control.
|
||||
*
|
||||
* This function disables CMT modulator, interrupts, and gates the
|
||||
* CMT clock control. CMT_Init must be called to use the CMT again.
|
||||
*
|
||||
* @param base CMT peripheral base address.
|
||||
*/
|
||||
void CMT_Deinit(CMT_Type *base);
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Basic Control Operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Selects the mode for CMT.
|
||||
*
|
||||
* @param base CMT peripheral base address.
|
||||
* @param mode The CMT feature mode enumeration. See "cmt_mode_t".
|
||||
* @param modulateConfig The carrier generation and modulator configuration.
|
||||
*/
|
||||
void CMT_SetMode(CMT_Type *base, cmt_mode_t mode, cmt_modulate_config_t *modulateConfig);
|
||||
|
||||
/*!
|
||||
* @brief Gets the mode of the CMT module.
|
||||
*
|
||||
* @param base CMT peripheral base address.
|
||||
* @return The CMT mode.
|
||||
* kCMT_DirectIROCtl Carrier modulator is disabled, the IRO signal is directly in software control.
|
||||
* kCMT_TimeMode Carrier modulator is enabled in time mode.
|
||||
* kCMT_FSKMode Carrier modulator is enabled in FSK mode.
|
||||
* kCMT_BasebandMode Carrier modulator is enabled in baseband mode.
|
||||
*/
|
||||
cmt_mode_t CMT_GetMode(CMT_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Gets the actual CMT clock frequency.
|
||||
*
|
||||
* @param base CMT peripheral base address.
|
||||
* @param busClock_Hz CMT module input clock - bus clock frequency.
|
||||
* @return The CMT clock frequency.
|
||||
*/
|
||||
uint32_t CMT_GetCMTFrequency(CMT_Type *base, uint32_t busClock_Hz);
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* CMT carrier generator counter to control the period and the duty cycle of the
|
||||
* output carrier signal.
|
||||
* 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).
|
||||
*
|
||||
* @param base CMT peripheral base address.
|
||||
* @param highCount The number of CMT clocks for carrier generator signal high time,
|
||||
* integer in the range of 1 ~ 0xFF.
|
||||
* @param lowCount The number of CMT clocks for carrier generator signal low time,
|
||||
* integer in the range of 1 ~ 0xFF.
|
||||
*/
|
||||
static inline void CMT_SetCarrirGenerateCountOne(CMT_Type *base, uint32_t highCount, uint32_t lowCount)
|
||||
{
|
||||
assert(highCount <= CMT_CGH1_PH_MASK);
|
||||
assert(highCount);
|
||||
assert(lowCount <= CMT_CGL1_PL_MASK);
|
||||
assert(lowCount);
|
||||
|
||||
base->CGH1 = highCount;
|
||||
base->CGL1 = lowCount;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* data set CMT carrier generator counter to control the period and the duty cycle
|
||||
* of the output carrier signal.
|
||||
* 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).
|
||||
*
|
||||
* @param base CMT peripheral base address.
|
||||
* @param highCount The number of CMT clocks for carrier generator signal high time,
|
||||
* integer in the range of 1 ~ 0xFF.
|
||||
* @param lowCount The number of CMT clocks for carrier generator signal low time,
|
||||
* integer in the range of 1 ~ 0xFF.
|
||||
*/
|
||||
static inline void CMT_SetCarrirGenerateCountTwo(CMT_Type *base, uint32_t highCount, uint32_t lowCount)
|
||||
{
|
||||
assert(highCount <= CMT_CGH2_SH_MASK);
|
||||
assert(highCount);
|
||||
assert(lowCount <= CMT_CGL2_SL_MASK);
|
||||
assert(lowCount);
|
||||
|
||||
base->CGH2 = highCount;
|
||||
base->CGL2 = lowCount;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the modulation mark and space time period for the CMT modulator.
|
||||
*
|
||||
* This function sets the mark time period of the CMT modulator counter
|
||||
* to control the mark time of the output modulated signal from the carrier generator output signal.
|
||||
* If the CMT clock frequency is Fcmt and the carrier out signal frequency is fcg:
|
||||
* - In Time and Baseband mode: The mark period of the generated signal equals (markCount + 1) / (Fcmt/8).
|
||||
* The space period of the generated signal equals spaceCount / (Fcmt/8).
|
||||
* - In FSK mode: The mark period of the generated signal equals (markCount + 1)/fcg.
|
||||
* The space period of the generated signal equals spaceCount / fcg.
|
||||
*
|
||||
* @param base Base address for current CMT instance.
|
||||
* @param markCount The number of clock period for CMT modulator signal mark period,
|
||||
* in the range of 0 ~ 0xFFFF.
|
||||
* @param spaceCount The number of clock period for CMT modulator signal space period,
|
||||
* in the range of the 0 ~ 0xFFFF.
|
||||
*/
|
||||
void CMT_SetModulateMarkSpace(CMT_Type *base, uint32_t markCount, uint32_t spaceCount);
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables the extended space operation.
|
||||
*
|
||||
* This function is used to make the space period longer
|
||||
* for time, baseband, and FSK modes.
|
||||
*
|
||||
* @param base CMT peripheral base address.
|
||||
* @param enable True enable the extended space, false disable the extended space.
|
||||
*/
|
||||
static inline void CMT_EnableExtendedSpace(CMT_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->MSC |= CMT_MSC_EXSPC_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->MSC &= ~CMT_MSC_EXSPC_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets IRO - infrared output signal state.
|
||||
*
|
||||
* Changes the states of the IRO signal when the kCMT_DirectIROMode mode is set
|
||||
* and the IRO signal is enabled.
|
||||
*
|
||||
* @param base CMT peripheral base address.
|
||||
* @param state The control of the IRO signal. See "cmt_infrared_output_state_t"
|
||||
*/
|
||||
void CMT_SetIroState(CMT_Type *base, cmt_infrared_output_state_t state);
|
||||
|
||||
/*!
|
||||
* @brief Enables the CMT interrupt.
|
||||
*
|
||||
* This function enables the CMT interrupts according to the provided maskIf enabled.
|
||||
* 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
|
||||
* to reload the new mark/space values into the CMT modulator data registers
|
||||
* and verify the modulator mark and space.
|
||||
* For example, to enable the end of cycle, do the following:
|
||||
* @code
|
||||
* CMT_EnableInterrupts(CMT, kCMT_EndOfCycleInterruptEnable);
|
||||
* @endcode
|
||||
* @param base CMT peripheral base address.
|
||||
* @param mask The interrupts to enable. Logical OR of @ref _cmt_interrupt_enable.
|
||||
*/
|
||||
static inline void CMT_EnableInterrupts(CMT_Type *base, uint32_t mask)
|
||||
{
|
||||
base->MSC |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the CMT interrupt.
|
||||
*
|
||||
* This function disables the CMT interrupts according to the provided maskIf enabled.
|
||||
* The CMT only has the end of the cycle interrupt.
|
||||
* For example, to disable the end of cycle, do the following:
|
||||
* @code
|
||||
* CMT_DisableInterrupts(CMT, kCMT_EndOfCycleInterruptEnable);
|
||||
* @endcode
|
||||
*
|
||||
* @param base CMT peripheral base address.
|
||||
* @param mask The interrupts to enable. Logical OR of @ref _cmt_interrupt_enable.
|
||||
*/
|
||||
static inline void CMT_DisableInterrupts(CMT_Type *base, uint32_t mask)
|
||||
{
|
||||
base->MSC &= ~mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the end of the cycle status flag.
|
||||
*
|
||||
* The flag is set:
|
||||
* - When the modulator is not currently active and carrier and modulator
|
||||
* are set to start the initial CMT transmission.
|
||||
* - At the end of each modulation cycle when the counter is reloaded and
|
||||
* the carrier and modulator are enabled.
|
||||
* @param base CMT peripheral base address.
|
||||
* @return Current status of the end of cycle status flag
|
||||
* @arg non-zero: End-of-cycle has occurred.
|
||||
* @arg zero: End-of-cycle has not yet occurred since the flag last cleared.
|
||||
*/
|
||||
static inline uint32_t CMT_GetStatusFlags(CMT_Type *base)
|
||||
{
|
||||
return base->MSC & CMT_MSC_EOCF_MASK;
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_CMT_H_*/
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_common.h"
|
||||
/* This is not needed for mbed */
|
||||
#if 0
|
||||
#include "fsl_debug_console.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#if (defined(__CC_ARM)) || (defined(__ICCARM__))
|
||||
void __aeabi_assert(const char *failedExpr, const char *file, int line)
|
||||
{
|
||||
PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" \n", failedExpr, file, line);
|
||||
for (;;)
|
||||
{
|
||||
__asm("bkpt #0");
|
||||
}
|
||||
}
|
||||
#elif(defined(__GNUC__))
|
||||
void __assert_func(const char *file, int line, const char *func, const char *failedExpr)
|
||||
{
|
||||
PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" function name \"%s\" \n", failedExpr, file, line, func);
|
||||
for (;;)
|
||||
{
|
||||
__asm("bkpt #0");
|
||||
}
|
||||
}
|
||||
#endif /* (defined(__CC_ARM)) || (defined (__ICCARM__)) */
|
||||
#endif /* NDEBUG */
|
||||
#endif
|
||||
void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler)
|
||||
{
|
||||
/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */
|
||||
#if defined(__CC_ARM)
|
||||
extern uint32_t Image$$VECTOR_ROM$$Base[];
|
||||
extern uint32_t Image$$VECTOR_RAM$$Base[];
|
||||
extern uint32_t Image$$RW_m_data$$Base[];
|
||||
|
||||
#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base
|
||||
#define __VECTOR_RAM Image$$VECTOR_RAM$$Base
|
||||
#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base))
|
||||
#elif defined(__ICCARM__)
|
||||
extern uint32_t __RAM_VECTOR_TABLE_SIZE[];
|
||||
extern uint32_t __VECTOR_TABLE[];
|
||||
extern uint32_t __VECTOR_RAM[];
|
||||
#elif defined(__GNUC__)
|
||||
extern uint32_t __VECTOR_TABLE[];
|
||||
extern uint32_t __VECTOR_RAM[];
|
||||
extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[];
|
||||
uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES);
|
||||
#endif /* defined(__CC_ARM) */
|
||||
uint32_t n;
|
||||
|
||||
__disable_irq();
|
||||
if (SCB->VTOR != (uint32_t)__VECTOR_RAM)
|
||||
{
|
||||
/* Copy the vector table from ROM to RAM */
|
||||
for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++)
|
||||
{
|
||||
__VECTOR_RAM[n] = __VECTOR_TABLE[n];
|
||||
}
|
||||
/* Point the VTOR to the position of vector table */
|
||||
SCB->VTOR = (uint32_t)__VECTOR_RAM;
|
||||
}
|
||||
|
||||
/* make sure the __VECTOR_RAM is noncachable */
|
||||
__VECTOR_RAM[irq + 16] = irqHandler;
|
||||
|
||||
__enable_irq();
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FSL_COMMON_H_
|
||||
#define _FSL_COMMON_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "fsl_device_registers.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup ksdk_common
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Construct a status code value from a group and code number. */
|
||||
#define MAKE_STATUS(group, code) ((((group)*100) + (code)))
|
||||
|
||||
/*! @brief Construct the version number for drivers. */
|
||||
#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
|
||||
|
||||
/* Debug console type definition. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console base on UART. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console base on LPUART. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console base on LPSCI. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console base on USBCDC. */
|
||||
|
||||
/*! @brief Status group numbers. */
|
||||
enum _status_groups
|
||||
{
|
||||
kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */
|
||||
kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */
|
||||
kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */
|
||||
kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */
|
||||
kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */
|
||||
kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */
|
||||
kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */
|
||||
kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */
|
||||
kStatusGroup_UART = 10, /*!< Group number for UART status codes. */
|
||||
kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */
|
||||
kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */
|
||||
kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */
|
||||
kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/
|
||||
kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/
|
||||
kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/
|
||||
kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */
|
||||
kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */
|
||||
kStatusGroup_SAI = 19, /*!< Group number for SAI status code */
|
||||
kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */
|
||||
kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */
|
||||
kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */
|
||||
kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */
|
||||
kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */
|
||||
kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */
|
||||
kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */
|
||||
kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */
|
||||
kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */
|
||||
kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */
|
||||
kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */
|
||||
kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */
|
||||
kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */
|
||||
kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */
|
||||
kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */
|
||||
kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */
|
||||
kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */
|
||||
kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */
|
||||
kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */
|
||||
kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */
|
||||
kStatusGroup_ApplicationRangeStart = 100, /*!< Starting number for application groups. */
|
||||
};
|
||||
|
||||
/*! @brief Generic status return codes. */
|
||||
enum _generic_status
|
||||
{
|
||||
kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0),
|
||||
kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1),
|
||||
kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2),
|
||||
kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3),
|
||||
kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4),
|
||||
kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5),
|
||||
kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6),
|
||||
};
|
||||
|
||||
/*! @brief Type used for all status and error return values. */
|
||||
typedef int32_t status_t;
|
||||
|
||||
/*
|
||||
* The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
|
||||
* defined in previous of this file.
|
||||
*/
|
||||
#include "fsl_clock.h"
|
||||
|
||||
/*! @name Min/max macros */
|
||||
/* @{ */
|
||||
#if !defined(MIN)
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#if !defined(MAX)
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
/* @} */
|
||||
|
||||
/*! @brief Computes the number of elements in an array. */
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
/*! @name UINT16_MAX/UINT32_MAX value */
|
||||
/* @{ */
|
||||
#if !defined(UINT16_MAX)
|
||||
#define UINT16_MAX ((uint16_t)-1)
|
||||
#endif
|
||||
|
||||
#if !defined(UINT32_MAX)
|
||||
#define UINT32_MAX ((uint32_t)-1)
|
||||
#endif
|
||||
/* @} */
|
||||
|
||||
/*! @name Timer utilities */
|
||||
/* @{ */
|
||||
/*! Macro to convert a microsecond period to raw count value */
|
||||
#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)((uint64_t)us * clockFreqInHz / 1000000U)
|
||||
/*! Macro to convert a raw count value to microsecond */
|
||||
#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000000U / clockFreqInHz)
|
||||
|
||||
/*! Macro to convert a millisecond period to raw count value */
|
||||
#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)ms * clockFreqInHz / 1000U)
|
||||
/*! Macro to convert a raw count value to millisecond */
|
||||
#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000U / clockFreqInHz)
|
||||
/* @} */
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Enable specific interrupt.
|
||||
*
|
||||
* Enable the interrupt not routed from intmux.
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
*/
|
||||
static inline void EnableIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
#if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0)
|
||||
if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX)
|
||||
#endif
|
||||
{
|
||||
NVIC_EnableIRQ(interrupt);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disable specific interrupt.
|
||||
*
|
||||
* Disable the interrupt not routed from intmux.
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
*/
|
||||
static inline void DisableIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
#if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0)
|
||||
if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX)
|
||||
#endif
|
||||
{
|
||||
NVIC_DisableIRQ(interrupt);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disable the global IRQ
|
||||
*
|
||||
* Disable the global interrupt and return the current primask register. User is required to provided the primask
|
||||
* register for the EnableGlobalIRQ().
|
||||
*
|
||||
* @return Current primask value.
|
||||
*/
|
||||
static inline uint32_t DisableGlobalIRQ(void)
|
||||
{
|
||||
uint32_t regPrimask = __get_PRIMASK();
|
||||
|
||||
__disable_irq();
|
||||
|
||||
return regPrimask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enaable the global IRQ
|
||||
*
|
||||
* Set the primask register with the provided primask value but not just enable the primask. The idea is for the
|
||||
* convinience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to
|
||||
* use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair.
|
||||
*
|
||||
* @param primask value of primask register to be restored. The primask value is supposed to be provided by the
|
||||
* DisableGlobalIRQ().
|
||||
*/
|
||||
static inline void EnableGlobalIRQ(uint32_t primask)
|
||||
{
|
||||
__set_PRIMASK(primask);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief install IRQ handler
|
||||
*
|
||||
* @param irq IRQ number
|
||||
* @param irqHandler IRQ handler address
|
||||
*/
|
||||
void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @} */
|
||||
|
||||
#endif /* _FSL_COMMON_H_ */
|
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "fsl_crc.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#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 */
|
||||
#define CRC_DRIVER_DEFAULT_POLYNOMIAL 0x1021U
|
||||
/*< CRC-16-CCIT polynomial x**16 + x**12 + x**5 + x**0 */
|
||||
#define CRC_DRIVER_DEFAULT_SEED 0xFFFFU
|
||||
/*< Default initial checksum */
|
||||
#define CRC_DRIVER_DEFAULT_REFLECT_IN false
|
||||
/*< Default is no transpose */
|
||||
#define CRC_DRIVER_DEFAULT_REFLECT_OUT false
|
||||
/*< Default is transpose bytes */
|
||||
#define CRC_DRIVER_DEFAULT_COMPLEMENT_CHECKSUM false
|
||||
/*< Default is without complement of CRC data register read data */
|
||||
#define CRC_DRIVER_DEFAULT_CRC_BITS kCrcBits16
|
||||
/*< Default is 16-bit CRC protocol */
|
||||
#define CRC_DRIVER_DEFAULT_CRC_RESULT kCrcFinalChecksum
|
||||
/*< Default is resutl type is final checksum */
|
||||
#endif /* CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT */
|
||||
|
||||
/*! @brief CRC type of transpose of read write data */
|
||||
typedef enum _crc_transpose_type
|
||||
{
|
||||
kCrcTransposeNone = 0U, /*! No transpose */
|
||||
kCrcTransposeBits = 1U, /*! Tranpose bits in bytes */
|
||||
kCrcTransposeBitsAndBytes = 2U, /*! Transpose bytes and bits in bytes */
|
||||
kCrcTransposeBytes = 3U, /*! Transpose bytes */
|
||||
} crc_transpose_type_t;
|
||||
|
||||
/*!
|
||||
* @brief CRC module configuration.
|
||||
*
|
||||
* This structure holds the configuration for the CRC module.
|
||||
*/
|
||||
typedef struct _crc_module_config
|
||||
{
|
||||
uint32_t polynomial; /*!< CRC Polynomial, MSBit first.@n
|
||||
Example polynomial: 0x1021 = 1_0000_0010_0001 = x^12+x^5+1 */
|
||||
uint32_t seed; /*!< Starting checksum value */
|
||||
crc_transpose_type_t readTranspose; /*!< Type of transpose when reading CRC result. */
|
||||
crc_transpose_type_t writeTranspose; /*!< Type of transpose when writing CRC input data. */
|
||||
bool complementChecksum; /*!< True if the result shall be complement of the actual checksum. */
|
||||
crc_bits_t crcBits; /*!< Selects 16- or 32- bit CRC protocol. */
|
||||
} crc_module_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Returns transpose type for CRC protocol reflect in parameter.
|
||||
*
|
||||
* This functions helps to set writeTranspose member of crc_config_t structure. Reflect in is CRC protocol 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)
|
||||
{
|
||||
return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeBytes);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Returns transpose type for CRC protocol reflect out parameter.
|
||||
*
|
||||
* This functions helps to set readTranspose member of crc_config_t structure. Reflect out is CRC protocol 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)
|
||||
{
|
||||
return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeNone);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Starts checksum computation.
|
||||
*
|
||||
* Configures the CRC module for the specified CRC protocol. @n
|
||||
* Starts the checksum computation by writing the seed value
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @param config Pointer to protocol configuration structure.
|
||||
*/
|
||||
static void crc_ConfigureAndStart(CRC_Type *base, const crc_module_config_t *config)
|
||||
{
|
||||
uint32_t crcControl;
|
||||
|
||||
/* pre-compute value for CRC control registger based on user configuraton without WAS field */
|
||||
crcControl = 0 | CRC_CTRL_TOT(config->writeTranspose) | CRC_CTRL_TOTR(config->readTranspose) |
|
||||
CRC_CTRL_FXOR(config->complementChecksum) | CRC_CTRL_TCRC(config->crcBits);
|
||||
|
||||
/* make sure the control register is clear - WAS is deasserted, and protocol is set */
|
||||
base->CTRL = crcControl;
|
||||
|
||||
/* write polynomial register */
|
||||
base->GPOLY = config->polynomial;
|
||||
|
||||
/* write pre-computed control register value along with WAS to start checksum computation */
|
||||
base->CTRL = crcControl | CRC_CTRL_WAS(true);
|
||||
|
||||
/* write seed (initial checksum) */
|
||||
base->DATA = config->seed;
|
||||
|
||||
/* deassert WAS by writing pre-computed CRC control register value */
|
||||
base->CTRL = crcControl;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Starts final checksum computation.
|
||||
*
|
||||
* Configures the CRC module for the specified CRC protocol. @n
|
||||
* Starts final checksum computation by writing the seed value.
|
||||
* @note CRC_Get16bitResult() or CRC_Get32bitResult() return final checksum
|
||||
* (output reflection and xor functions are applied).
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @param protocolConfig Pointer to protocol configuration structure.
|
||||
*/
|
||||
static void crc_SetProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig)
|
||||
{
|
||||
crc_module_config_t moduleConfig;
|
||||
/* convert protocol to CRC peripheral module configuration, prepare for final checksum */
|
||||
moduleConfig.polynomial = protocolConfig->polynomial;
|
||||
moduleConfig.seed = protocolConfig->seed;
|
||||
moduleConfig.readTranspose = crc_GetTransposeTypeFromReflectOut(protocolConfig->reflectOut);
|
||||
moduleConfig.writeTranspose = crc_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn);
|
||||
moduleConfig.complementChecksum = protocolConfig->complementChecksum;
|
||||
moduleConfig.crcBits = protocolConfig->crcBits;
|
||||
|
||||
crc_ConfigureAndStart(base, &moduleConfig);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Starts intermediate checksum computation.
|
||||
*
|
||||
* Configures the CRC module for the specified CRC protocol. @n
|
||||
* Starts intermediate checksum computation by writing the seed value.
|
||||
* @note CRC_Get16bitResult() or CRC_Get32bitResult() return intermediate checksum (raw data register value).
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @param protocolConfig Pointer to protocol configuration structure.
|
||||
*/
|
||||
static void crc_SetRawProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig)
|
||||
{
|
||||
crc_module_config_t moduleConfig;
|
||||
/* convert protocol to CRC peripheral module configuration, prepare for intermediate checksum */
|
||||
moduleConfig.polynomial = protocolConfig->polynomial;
|
||||
moduleConfig.seed = protocolConfig->seed;
|
||||
moduleConfig.readTranspose =
|
||||
kCrcTransposeNone; /* intermediate checksum does no transpose of data register read value */
|
||||
moduleConfig.writeTranspose = crc_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn);
|
||||
moduleConfig.complementChecksum = false; /* intermediate checksum does no xor of data register read value */
|
||||
moduleConfig.crcBits = protocolConfig->crcBits;
|
||||
|
||||
crc_ConfigureAndStart(base, &moduleConfig);
|
||||
}
|
||||
|
||||
void CRC_Init(CRC_Type *base, const crc_config_t *config)
|
||||
{
|
||||
/* ungate clock */
|
||||
CLOCK_EnableClock(kCLOCK_Crc0);
|
||||
/* configure CRC module and write the seed */
|
||||
if (config->crcResult == kCrcFinalChecksum)
|
||||
{
|
||||
crc_SetProtocolConfig(base, config);
|
||||
}
|
||||
else
|
||||
{
|
||||
crc_SetRawProtocolConfig(base, config);
|
||||
}
|
||||
}
|
||||
|
||||
void CRC_GetDefaultConfig(crc_config_t *config)
|
||||
{
|
||||
static const crc_config_t crc16ccit = {
|
||||
CRC_DRIVER_DEFAULT_POLYNOMIAL, CRC_DRIVER_DEFAULT_SEED,
|
||||
CRC_DRIVER_DEFAULT_REFLECT_IN, CRC_DRIVER_DEFAULT_REFLECT_OUT,
|
||||
CRC_DRIVER_DEFAULT_COMPLEMENT_CHECKSUM, CRC_DRIVER_DEFAULT_CRC_BITS,
|
||||
CRC_DRIVER_DEFAULT_CRC_RESULT,
|
||||
};
|
||||
|
||||
*config = crc16ccit;
|
||||
}
|
||||
|
||||
void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize)
|
||||
{
|
||||
const uint32_t *data32;
|
||||
|
||||
/* 8-bit reads and writes till source address is aligned 4 bytes */
|
||||
while ((dataSize) && ((uint32_t)data & 3U))
|
||||
{
|
||||
base->ACCESS8BIT.DATALL = *data;
|
||||
data++;
|
||||
dataSize--;
|
||||
}
|
||||
|
||||
/* use 32-bit reads and writes as long as possible */
|
||||
data32 = (const uint32_t *)data;
|
||||
while (dataSize >= sizeof(uint32_t))
|
||||
{
|
||||
base->DATA = *data32;
|
||||
data32++;
|
||||
dataSize -= sizeof(uint32_t);
|
||||
}
|
||||
|
||||
data = (const uint8_t *)data32;
|
||||
|
||||
/* 8-bit reads and writes till end of data buffer */
|
||||
while (dataSize)
|
||||
{
|
||||
base->ACCESS8BIT.DATALL = *data;
|
||||
data++;
|
||||
dataSize--;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t CRC_Get16bitResult(CRC_Type *base)
|
||||
{
|
||||
uint32_t retval;
|
||||
uint32_t totr; /* type of transpose read bitfield */
|
||||
|
||||
retval = base->DATA;
|
||||
totr = (base->CTRL & CRC_CTRL_TOTR_MASK) >> CRC_CTRL_TOTR_SHIFT;
|
||||
|
||||
/* check transpose type to get 16-bit out of 32-bit register */
|
||||
if (totr >= 2U)
|
||||
{
|
||||
/* transpose of bytes for read is set, the result CRC is in CRC_DATA[HU:HL] */
|
||||
retval &= 0xFFFF0000U;
|
||||
retval = retval >> 16U;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no transpose of bytes for read, the result CRC is in CRC_DATA[LU:LL] */
|
||||
retval &= 0x0000FFFFU;
|
||||
}
|
||||
return (uint16_t)retval;
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FSL_CRC_H_
|
||||
#define _FSL_CRC_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup crc_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief CRC driver version. Version 2.0.0. */
|
||||
#define FSL_CRC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
/*! @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
|
||||
/*! @brief Default configuration structure filled by CRC_GetDefaultConfig(). Use CRC16-CCIT-FALSE as defeault. */
|
||||
#define CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT 1
|
||||
#endif
|
||||
|
||||
/*! @brief CRC bit width */
|
||||
typedef enum _crc_bits
|
||||
{
|
||||
kCrcBits16 = 0U, /*!< Generate 16-bit CRC code */
|
||||
kCrcBits32 = 1U /*!< Generate 32-bit CRC code */
|
||||
} crc_bits_t;
|
||||
|
||||
/*! @brief CRC result type */
|
||||
typedef enum _crc_result
|
||||
{
|
||||
kCrcFinalChecksum = 0U, /*!< CRC data register read value is the final checksum.
|
||||
Reflect out and final xor protocol features are applied. */
|
||||
kCrcIntermediateChecksum = 1U /*!< CRC data register read value is intermediate checksum (raw value).
|
||||
Reflect out and final xor protocol feature are not applied.
|
||||
Intermediate checksum can be used as a seed for CRC_Init()
|
||||
to continue adding data to this checksum. */
|
||||
} crc_result_t;
|
||||
|
||||
/*!
|
||||
* @brief CRC protocol configuration.
|
||||
*
|
||||
* This structure holds the configuration for the CRC protocol.
|
||||
*
|
||||
*/
|
||||
typedef struct _crc_config
|
||||
{
|
||||
uint32_t polynomial; /*!< CRC Polynomial, MSBit first.
|
||||
Example polynomial: 0x1021 = 1_0000_0010_0001 = x^12+x^5+1 */
|
||||
uint32_t seed; /*!< Starting checksum value */
|
||||
bool reflectIn; /*!< Reflect bits on input. */
|
||||
bool reflectOut; /*!< Reflect bits on output. */
|
||||
bool complementChecksum; /*!< True if the result shall be complement of the actual checksum. */
|
||||
crc_bits_t crcBits; /*!< Selects 16- or 32- bit CRC protocol. */
|
||||
crc_result_t crcResult; /*!< Selects final or intermediate checksum return from CRC_Get16bitResult() or
|
||||
CRC_Get32bitResult() */
|
||||
} crc_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Enables and configures the CRC peripheral module.
|
||||
*
|
||||
* This functions 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.
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @param config CRC module configuration structure
|
||||
*/
|
||||
void CRC_Init(CRC_Type *base, const crc_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Disables the CRC peripheral module.
|
||||
*
|
||||
* This functions disables the clock gate in the Kinetis SIM module for the CRC peripheral.
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
*/
|
||||
static inline void CRC_Deinit(CRC_Type *base)
|
||||
{
|
||||
/* gate clock */
|
||||
CLOCK_DisableClock(kCLOCK_Crc0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Loads default values to CRC protocol configuration structure.
|
||||
*
|
||||
* Loads default values to CRC protocol configuration structure. The default values are:
|
||||
* @code
|
||||
* config->polynomial = 0x1021;
|
||||
* config->seed = 0xFFFF;
|
||||
* config->reflectIn = false;
|
||||
* config->reflectOut = false;
|
||||
* config->complementChecksum = false;
|
||||
* config->crcBits = kCrcBits16;
|
||||
* config->crcResult = kCrcFinalChecksum;
|
||||
* @endcode
|
||||
*
|
||||
* @param config CRC protocol configuration structure
|
||||
*/
|
||||
void CRC_GetDefaultConfig(crc_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Writes data to the CRC module.
|
||||
*
|
||||
* Writes input data buffer bytes to CRC data register.
|
||||
* The configured type of transpose is applied.
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @param data Input data stream, MSByte in data[0].
|
||||
* @param dataSize Size in bytes of the input data buffer.
|
||||
*/
|
||||
void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize);
|
||||
|
||||
/*!
|
||||
* @brief Reads 32-bit checksum from the CRC module.
|
||||
*
|
||||
* Reads CRC data register (intermediate or final checksum).
|
||||
* The configured type of transpose and complement are applied.
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @return intermediate or final 32-bit checksum, after configured transpose and complement operations.
|
||||
*/
|
||||
static inline uint32_t CRC_Get32bitResult(CRC_Type *base)
|
||||
{
|
||||
return base->DATA;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reads 16-bit checksum from the CRC module.
|
||||
*
|
||||
* Reads CRC data register (intermediate or final checksum).
|
||||
* The configured type of transpose and complement are applied.
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @return intermediate or final 16-bit checksum, after configured transpose and complement operations.
|
||||
*/
|
||||
uint16_t CRC_Get16bitResult(CRC_Type *base);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
*@}
|
||||
*/
|
||||
|
||||
#endif /* _FSL_CRC_H_ */
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_dac.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Get instance number for DAC module.
|
||||
*
|
||||
* @param base DAC peripheral base address
|
||||
*/
|
||||
static uint32_t DAC_GetInstance(DAC_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/*! @brief Pointers to DAC bases for each instance. */
|
||||
static DAC_Type *const s_dacBases[] = DAC_BASE_PTRS;
|
||||
/*! @brief Pointers to DAC clocks for each instance. */
|
||||
const clock_ip_name_t s_dacClocks[] = DAC_CLOCKS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Codes
|
||||
******************************************************************************/
|
||||
static uint32_t DAC_GetInstance(DAC_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_DAC_COUNT; instance++)
|
||||
{
|
||||
if (s_dacBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < FSL_FEATURE_SOC_DAC_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void DAC_Init(DAC_Type *base, const dac_config_t *config)
|
||||
{
|
||||
assert(NULL != config);
|
||||
|
||||
uint8_t tmp8;
|
||||
|
||||
/* Enable the clock. */
|
||||
CLOCK_EnableClock(s_dacClocks[DAC_GetInstance(base)]);
|
||||
|
||||
/* Configure. */
|
||||
/* DACx_C0. */
|
||||
tmp8 = base->C0 & ~(DAC_C0_DACRFS_MASK | DAC_C0_LPEN_MASK);
|
||||
if (kDAC_ReferenceVoltageSourceVref2 == config->referenceVoltageSource)
|
||||
{
|
||||
tmp8 |= DAC_C0_DACRFS_MASK;
|
||||
}
|
||||
if (config->enableLowPowerMode)
|
||||
{
|
||||
tmp8 |= DAC_C0_LPEN_MASK;
|
||||
}
|
||||
base->C0 = tmp8;
|
||||
|
||||
DAC_Enable(base, true);
|
||||
}
|
||||
|
||||
void DAC_Deinit(DAC_Type *base)
|
||||
{
|
||||
DAC_Enable(base, false);
|
||||
|
||||
/* Disable the clock. */
|
||||
CLOCK_DisableClock(s_dacClocks[DAC_GetInstance(base)]);
|
||||
}
|
||||
|
||||
void DAC_GetDefaultConfig(dac_config_t *config)
|
||||
{
|
||||
assert(NULL != config);
|
||||
|
||||
config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2;
|
||||
config->enableLowPowerMode = false;
|
||||
}
|
||||
|
||||
void DAC_SetBufferConfig(DAC_Type *base, const dac_buffer_config_t *config)
|
||||
{
|
||||
assert(NULL != config);
|
||||
|
||||
uint8_t tmp8;
|
||||
|
||||
/* DACx_C0. */
|
||||
tmp8 = base->C0 & ~(DAC_C0_DACTRGSEL_MASK);
|
||||
if (kDAC_BufferTriggerBySoftwareMode == config->triggerMode)
|
||||
{
|
||||
tmp8 |= DAC_C0_DACTRGSEL_MASK;
|
||||
}
|
||||
base->C0 = tmp8;
|
||||
|
||||
/* DACx_C1. */
|
||||
tmp8 = base->C1 &
|
||||
~(
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION
|
||||
DAC_C1_DACBFWM_MASK |
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
|
||||
DAC_C1_DACBFMD_MASK);
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION
|
||||
tmp8 |= DAC_C1_DACBFWM(config->watermark);
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
|
||||
tmp8 |= DAC_C1_DACBFMD(config->workMode);
|
||||
base->C1 = tmp8;
|
||||
|
||||
/* DACx_C2. */
|
||||
tmp8 = base->C2 & ~DAC_C2_DACBFUP_MASK;
|
||||
tmp8 |= DAC_C2_DACBFUP(config->upperLimit);
|
||||
base->C2 = tmp8;
|
||||
}
|
||||
|
||||
void DAC_GetDefaultBufferConfig(dac_buffer_config_t *config)
|
||||
{
|
||||
assert(NULL != config);
|
||||
|
||||
config->triggerMode = kDAC_BufferTriggerBySoftwareMode;
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION
|
||||
config->watermark = kDAC_BufferWatermark1Word;
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
|
||||
config->workMode = kDAC_BufferWorkAsNormalMode;
|
||||
config->upperLimit = DAC_DATL_COUNT - 1U;
|
||||
}
|
||||
|
||||
void DAC_SetBufferValue(DAC_Type *base, uint8_t index, uint16_t value)
|
||||
{
|
||||
assert(index < DAC_DATL_COUNT);
|
||||
|
||||
base->DAT[index].DATL = (uint8_t)(0xFFU & value); /* Low 8-bit. */
|
||||
base->DAT[index].DATH = (uint8_t)((0xF00U & value) >> 8); /* High 4-bit. */
|
||||
}
|
||||
|
||||
void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index)
|
||||
{
|
||||
assert(index < DAC_DATL_COUNT);
|
||||
|
||||
uint8_t tmp8 = base->C2 & ~DAC_C2_DACBFRP_MASK;
|
||||
|
||||
tmp8 |= DAC_C2_DACBFRP(index);
|
||||
base->C2 = tmp8;
|
||||
}
|
||||
|
||||
void DAC_EnableBufferInterrupts(DAC_Type *base, uint32_t mask)
|
||||
{
|
||||
mask &= (
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
|
||||
DAC_C0_DACBWIEN_MASK |
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
|
||||
DAC_C0_DACBTIEN_MASK | DAC_C0_DACBBIEN_MASK);
|
||||
base->C0 |= ((uint8_t)mask); /* Write 1 to enable. */
|
||||
}
|
||||
|
||||
void DAC_DisableBufferInterrupts(DAC_Type *base, uint32_t mask)
|
||||
{
|
||||
mask &= (
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
|
||||
DAC_C0_DACBWIEN_MASK |
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
|
||||
DAC_C0_DACBTIEN_MASK | DAC_C0_DACBBIEN_MASK);
|
||||
base->C0 &= (uint8_t)(~((uint8_t)mask)); /* Write 0 to disable. */
|
||||
}
|
||||
|
||||
uint32_t DAC_GetBufferStatusFlags(DAC_Type *base)
|
||||
{
|
||||
return (uint32_t)(base->SR & (
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
|
||||
DAC_SR_DACBFWMF_MASK |
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
|
||||
DAC_SR_DACBFRPTF_MASK | DAC_SR_DACBFRPBF_MASK));
|
||||
}
|
||||
|
||||
void DAC_ClearBufferStatusFlags(DAC_Type *base, uint32_t mask)
|
||||
{
|
||||
mask &= (
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
|
||||
DAC_SR_DACBFWMF_MASK |
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
|
||||
DAC_SR_DACBFRPTF_MASK | DAC_SR_DACBFRPBF_MASK);
|
||||
base->SR &= (uint8_t)(~((uint8_t)mask)); /* Write 0 to clear flags. */
|
||||
}
|
|
@ -0,0 +1,379 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FSL_DAC_H_
|
||||
#define _FSL_DAC_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup dac
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief DAC driver version 2.0.0. */
|
||||
#define FSL_DAC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief DAC buffer flags.
|
||||
*/
|
||||
enum _dac_buffer_status_flags
|
||||
{
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
|
||||
kDAC_BufferWatermarkFlag = DAC_SR_DACBFWMF_MASK, /*!< DAC Buffer Watermark Flag. */
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
|
||||
kDAC_BufferReadPointerTopPositionFlag = DAC_SR_DACBFRPTF_MASK, /*!< DAC Buffer Read Pointer Top Position Flag. */
|
||||
kDAC_BufferReadPointerBottomPositionFlag = DAC_SR_DACBFRPBF_MASK, /*!< DAC Buffer Read Pointer Bottom Position
|
||||
Flag. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief DAC buffer interrupts.
|
||||
*/
|
||||
enum _dac_buffer_interrupt_enable
|
||||
{
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
|
||||
kDAC_BufferWatermarkInterruptEnable = DAC_C0_DACBWIEN_MASK, /*!< DAC Buffer Watermark Interrupt Enable. */
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
|
||||
kDAC_BufferReadPointerTopInterruptEnable = DAC_C0_DACBTIEN_MASK, /*!< DAC Buffer Read Pointer Top Flag Interrupt
|
||||
Enable. */
|
||||
kDAC_BufferReadPointerBottomInterruptEnable = DAC_C0_DACBBIEN_MASK, /*!< DAC Buffer Read Pointer Bottom Flag
|
||||
Interrupt Enable */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief DAC reference voltage source.
|
||||
*/
|
||||
typedef enum _dac_reference_voltage_source
|
||||
{
|
||||
kDAC_ReferenceVoltageSourceVref1 = 0U, /*!< The DAC selects DACREF_1 as the reference voltage. */
|
||||
kDAC_ReferenceVoltageSourceVref2 = 1U, /*!< The DAC selects DACREF_2 as the reference voltage. */
|
||||
} dac_reference_voltage_source_t;
|
||||
|
||||
/*!
|
||||
* @brief DAC buffer trigger mode.
|
||||
*/
|
||||
typedef enum _dac_buffer_trigger_mode
|
||||
{
|
||||
kDAC_BufferTriggerByHardwareMode = 0U, /*!< The DAC hardware trigger is selected. */
|
||||
kDAC_BufferTriggerBySoftwareMode = 1U, /*!< The DAC software trigger is selected. */
|
||||
} dac_buffer_trigger_mode_t;
|
||||
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION
|
||||
/*!
|
||||
* @brief DAC buffer watermark.
|
||||
*/
|
||||
typedef enum _dac_buffer_watermark
|
||||
{
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD
|
||||
kDAC_BufferWatermark1Word = 0U, /*!< 1 word away from the upper limit. */
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD */
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_2_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_2_WORD
|
||||
kDAC_BufferWatermark2Word = 1U, /*!< 2 words away from the upper limit. */
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_2_WORD */
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_3_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_3_WORD
|
||||
kDAC_BufferWatermark3Word = 2U, /*!< 3 words away from the upper limit. */
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_3_WORD */
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_4_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_4_WORD
|
||||
kDAC_BufferWatermark4Word = 3U, /*!< 4 words away from the upper limit. */
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_4_WORD */
|
||||
} dac_buffer_watermark_t;
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
|
||||
|
||||
/*!
|
||||
* @brief DAC buffer work mode.
|
||||
*/
|
||||
typedef enum _dac_buffer_work_mode
|
||||
{
|
||||
kDAC_BufferWorkAsNormalMode = 0U, /*!< Normal mode. */
|
||||
#if defined(FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE) && FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE
|
||||
kDAC_BufferWorkAsSwingMode, /*!< Swing mode. */
|
||||
#endif /* FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE */
|
||||
kDAC_BufferWorkAsOneTimeScanMode, /*!< One-Time Scan mode. */
|
||||
#if defined(FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE) && FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE
|
||||
kDAC_BufferWorkAsFIFOMode, /*!< FIFO mode. */
|
||||
#endif /* FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE */
|
||||
} dac_buffer_work_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief DAC module configuration.
|
||||
*/
|
||||
typedef struct _dac_config
|
||||
{
|
||||
dac_reference_voltage_source_t referenceVoltageSource; /*!< Select the DAC reference voltage source. */
|
||||
bool enableLowPowerMode; /*!< Enable the low power mode. */
|
||||
} dac_config_t;
|
||||
|
||||
/*!
|
||||
* @brief DAC buffer configuration.
|
||||
*/
|
||||
typedef struct _dac_buffer_config
|
||||
{
|
||||
dac_buffer_trigger_mode_t triggerMode; /*!< Select the buffer's trigger mode. */
|
||||
#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION
|
||||
dac_buffer_watermark_t watermark; /*!< Select the buffer's watermark. */
|
||||
#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
|
||||
dac_buffer_work_mode_t workMode; /*!< Select the buffer's work mode. */
|
||||
uint8_t upperLimit; /*!< Set the upper limit for buffer index.
|
||||
Normally, 0-15 is available for buffer with 16 item. */
|
||||
} dac_buffer_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the DAC module.
|
||||
*
|
||||
* This function initializes the DAC module, including:
|
||||
* - Enabling the clock for DAC module.
|
||||
* - Configuring the DAC converter with a user configuration.
|
||||
* - Enabling the DAC module.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param config Pointer to the configuration structure. See "dac_config_t".
|
||||
*/
|
||||
void DAC_Init(DAC_Type *base, const dac_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief De-initializes the DAC module.
|
||||
*
|
||||
* This function de-initializes the DAC module, including:
|
||||
* - Disabling the DAC module.
|
||||
* - Disabling the clock for the DAC module.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
*/
|
||||
void DAC_Deinit(DAC_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the DAC user configuration structure.
|
||||
*
|
||||
* This function initializes the user configuration structure to a default value. The default values are:
|
||||
* @code
|
||||
* config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2;
|
||||
* config->enableLowPowerMode = false;
|
||||
* @endcode
|
||||
* @param config Pointer to the configuration structure. See "dac_config_t".
|
||||
*/
|
||||
void DAC_GetDefaultConfig(dac_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Enables the DAC module.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param enable Enables the feature or not.
|
||||
*/
|
||||
static inline void DAC_Enable(DAC_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->C0 |= DAC_C0_DACEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->C0 &= ~DAC_C0_DACEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Buffer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables the DAC buffer.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param enable Enables the feature or not.
|
||||
*/
|
||||
static inline void DAC_EnableBuffer(DAC_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->C1 |= DAC_C1_DACBFEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->C1 &= ~DAC_C1_DACBFEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Configures the CMP buffer.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param config Pointer to the configuration structure. See "dac_buffer_config_t".
|
||||
*/
|
||||
void DAC_SetBufferConfig(DAC_Type *base, const dac_buffer_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the DAC buffer configuration structure.
|
||||
*
|
||||
* This function initializes the DAC buffer configuration structure to a default value. The default values are:
|
||||
* @code
|
||||
* config->triggerMode = kDAC_BufferTriggerBySoftwareMode;
|
||||
* config->watermark = kDAC_BufferWatermark1Word;
|
||||
* config->workMode = kDAC_BufferWorkAsNormalMode;
|
||||
* config->upperLimit = DAC_DATL_COUNT - 1U;
|
||||
* @endcode
|
||||
* @param config Pointer to the configuration structure. See "dac_buffer_config_t".
|
||||
*/
|
||||
void DAC_GetDefaultBufferConfig(dac_buffer_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Enables the DMA for DAC buffer.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param enable Enables the feature or not.
|
||||
*/
|
||||
static inline void DAC_EnableBufferDMA(DAC_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->C1 |= DAC_C1_DMAEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->C1 &= ~DAC_C1_DMAEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the value for items in the buffer.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param index Setting index for items in the buffer. The available index should not exceed the size of the DAC buffer.
|
||||
* @param value Setting value for items in the buffer. 12-bits are available.
|
||||
*/
|
||||
void DAC_SetBufferValue(DAC_Type *base, uint8_t index, uint16_t value);
|
||||
|
||||
/*!
|
||||
* @brief Triggers the buffer by software and updates the read pointer of the DAC buffer.
|
||||
*
|
||||
* This function triggers the function by software. The read pointer of the DAC buffer is updated with one step
|
||||
* after this function is called. Changing the read pointer depends on the buffer's work mode.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
*/
|
||||
static inline void DAC_DoSoftwareTriggerBuffer(DAC_Type *base)
|
||||
{
|
||||
base->C0 |= DAC_C0_DACSWTRG_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the current read pointer of the DAC buffer.
|
||||
*
|
||||
* This function gets the current read pointer of the DAC buffer.
|
||||
* The current output value depends on the item indexed by the read pointer. It is updated
|
||||
* by software trigger or hardware trigger.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
*
|
||||
* @return Current read pointer of DAC buffer.
|
||||
*/
|
||||
static inline uint8_t DAC_GetBufferReadPointer(DAC_Type *base)
|
||||
{
|
||||
return ((base->C2 & DAC_C2_DACBFRP_MASK) >> DAC_C2_DACBFRP_SHIFT);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the current read pointer of the DAC buffer.
|
||||
*
|
||||
* This function sets the current read pointer of the DAC buffer.
|
||||
* The current output value depends on the item indexed by the read pointer. It is updated by
|
||||
* software trigger or hardware trigger. After the read pointer changes, the DAC output value also changes.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param index Setting index value for the pointer.
|
||||
*/
|
||||
void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index);
|
||||
|
||||
/*!
|
||||
* @brief Enables interrupts for the DAC buffer.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param mask Mask value for interrupts. See "_dac_buffer_interrupt_enable".
|
||||
*/
|
||||
void DAC_EnableBufferInterrupts(DAC_Type *base, uint32_t mask);
|
||||
|
||||
/*!
|
||||
* @brief Disables interrupts for the DAC buffer.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param mask Mask value for interrupts. See "_dac_buffer_interrupt_enable".
|
||||
*/
|
||||
void DAC_DisableBufferInterrupts(DAC_Type *base, uint32_t mask);
|
||||
|
||||
/*!
|
||||
* @brief Gets the flags of events for the DAC buffer.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
*
|
||||
* @return Mask value for the asserted flags. See "_dac_buffer_status_flags".
|
||||
*/
|
||||
uint32_t DAC_GetBufferStatusFlags(DAC_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Clears the flags of events for the DAC buffer.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param mask Mask value for flags. See "_dac_buffer_status_flags_t".
|
||||
*/
|
||||
void DAC_ClearBufferStatusFlags(DAC_Type *base, uint32_t mask);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
#endif /* _FSL_DAC_H_ */
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_dmamux.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Get instance number for DMAMUX.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
*/
|
||||
static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Array to map DMAMUX instance number to base pointer. */
|
||||
static DMAMUX_Type *const s_dmamuxBases[] = DMAMUX_BASE_PTRS;
|
||||
|
||||
/*! @brief Array to map DMAMUX instance number to clock name. */
|
||||
static const clock_ip_name_t s_dmamuxClockName[] = DMAMUX_CLOCKS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_DMAMUX_COUNT; instance++)
|
||||
{
|
||||
if (s_dmamuxBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < FSL_FEATURE_SOC_DMAMUX_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void DMAMUX_Init(DMAMUX_Type *base)
|
||||
{
|
||||
CLOCK_EnableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]);
|
||||
}
|
||||
|
||||
void DMAMUX_Deinit(DMAMUX_Type *base)
|
||||
{
|
||||
CLOCK_DisableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]);
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FSL_DMAMUX_H_
|
||||
#define _FSL_DMAMUX_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup dmamux
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief DMAMUX driver version 2.0.0. */
|
||||
#define FSL_DMAMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*!
|
||||
* @name DMAMUX Initialize and De-initialize
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes DMAMUX peripheral.
|
||||
*
|
||||
* This function ungate the DMAMUX clock.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
*
|
||||
*/
|
||||
void DMAMUX_Init(DMAMUX_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes DMAMUX peripheral.
|
||||
*
|
||||
* This function gate the DMAMUX clock.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
*/
|
||||
void DMAMUX_Deinit(DMAMUX_Type *base);
|
||||
|
||||
/* @} */
|
||||
/*!
|
||||
* @name DMAMUX Channel Operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enable DMAMUX channel.
|
||||
*
|
||||
* This function enable DMAMUX channel to work.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
* @param channel DMAMUX channel number.
|
||||
*/
|
||||
static inline void DMAMUX_EnableChannel(DMAMUX_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->CHCFG[channel] |= DMAMUX_CHCFG_ENBL_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disable DMAMUX channel.
|
||||
*
|
||||
* This function disable DMAMUX channel.
|
||||
*
|
||||
* @note User must disable DMAMUX channel before configure it.
|
||||
* @param base DMAMUX peripheral base address.
|
||||
* @param channel DMAMUX channel number.
|
||||
*/
|
||||
static inline void DMAMUX_DisableChannel(DMAMUX_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->CHCFG[channel] &= ~DMAMUX_CHCFG_ENBL_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Configure DMAMUX channel source.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
* @param channel DMAMUX channel number.
|
||||
* @param source Channel source which is used to trigger DMA transfer.
|
||||
*/
|
||||
static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint8_t source)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->CHCFG[channel] = ((base->CHCFG[channel] & ~DMAMUX_CHCFG_SOURCE_MASK) | DMAMUX_CHCFG_SOURCE(source));
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_DMAMUX_HAS_TRIG) && FSL_FEATURE_DMAMUX_HAS_TRIG > 0U
|
||||
/*!
|
||||
* @brief Enable DMAMUX period trigger.
|
||||
*
|
||||
* This function enable DMAMUX period trigger feature.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
* @param channel DMAMUX channel number.
|
||||
*/
|
||||
static inline void DMAMUX_EnablePeriodTrigger(DMAMUX_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->CHCFG[channel] |= DMAMUX_CHCFG_TRIG_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disable DMAMUX period trigger.
|
||||
*
|
||||
* This function disable DMAMUX period trigger.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
* @param channel DMAMUX channel number.
|
||||
*/
|
||||
static inline void DMAMUX_DisablePeriodTrigger(DMAMUX_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->CHCFG[channel] &= ~DMAMUX_CHCFG_TRIG_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_DMAMUX_HAS_TRIG */
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* @} */
|
||||
|
||||
#endif /* _FSL_DMAMUX_H_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_DSPI_EDMA_H_
|
||||
#define _FSL_DSPI_EDMA_H_
|
||||
|
||||
#include "fsl_dspi.h"
|
||||
#include "fsl_edma.h"
|
||||
/*!
|
||||
* @addtogroup dspi_edma_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Definitions
|
||||
**********************************************************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Forward declaration of the DSPI eDMA master handle typedefs.
|
||||
*/
|
||||
typedef struct _dspi_master_edma_handle dspi_master_edma_handle_t;
|
||||
|
||||
/*!
|
||||
* @brief Forward declaration of the DSPI eDMA slave handle typedefs.
|
||||
*/
|
||||
typedef struct _dspi_slave_edma_handle dspi_slave_edma_handle_t;
|
||||
|
||||
/*!
|
||||
* @brief Completion callback function pointer type.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle Pointer to the handle for the DSPI master.
|
||||
* @param status Success or error code describing whether the transfer completed.
|
||||
* @param userData Arbitrary pointer-dataSized value passed from the application.
|
||||
*/
|
||||
typedef void (*dspi_master_edma_transfer_callback_t)(SPI_Type *base,
|
||||
dspi_master_edma_handle_t *handle,
|
||||
status_t status,
|
||||
void *userData);
|
||||
/*!
|
||||
* @brief Completion callback function pointer type.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle Pointer to the handle for the DSPI slave.
|
||||
* @param status Success or error code describing whether the transfer completed.
|
||||
* @param userData Arbitrary pointer-dataSized value passed from the application.
|
||||
*/
|
||||
typedef void (*dspi_slave_edma_transfer_callback_t)(SPI_Type *base,
|
||||
dspi_slave_edma_handle_t *handle,
|
||||
status_t status,
|
||||
void *userData);
|
||||
|
||||
/*! @brief DSPI master eDMA transfer handle structure used for transactional API. */
|
||||
struct _dspi_master_edma_handle
|
||||
{
|
||||
uint32_t bitsPerFrame; /*!< Desired number of bits per frame. */
|
||||
volatile uint32_t command; /*!< Desired data command. */
|
||||
volatile uint32_t lastCommand; /*!< Desired last data command. */
|
||||
|
||||
uint8_t fifoSize; /*!< FIFO dataSize. */
|
||||
|
||||
volatile bool isPcsActiveAfterTransfer; /*!< Is PCS signal keep active after the last frame transfer.*/
|
||||
volatile bool isThereExtraByte; /*!< Is there extra byte.*/
|
||||
|
||||
uint8_t *volatile txData; /*!< Send buffer. */
|
||||
uint8_t *volatile rxData; /*!< Receive buffer. */
|
||||
volatile size_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/
|
||||
volatile size_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/
|
||||
size_t totalByteCount; /*!< Number of transfer bytes*/
|
||||
|
||||
uint32_t rxBuffIfNull; /*!< Used if there is not rxData 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. */
|
||||
void *userData; /*!< Callback user data. */
|
||||
|
||||
edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/
|
||||
edma_handle_t *edmaTxDataToIntermediaryHandle; /*!<edma_handle_t handle point used for TxData to Intermediary*/
|
||||
edma_handle_t *edmaIntermediaryToTxRegHandle; /*!<edma_handle_t handle point used for Intermediary to TxReg*/
|
||||
|
||||
edma_tcd_t dspiSoftwareTCD[2]; /*!<SoftwareTCD , internal used*/
|
||||
};
|
||||
|
||||
/*! @brief DSPI slave eDMA transfer handle structure used for transactional API.*/
|
||||
struct _dspi_slave_edma_handle
|
||||
{
|
||||
uint32_t bitsPerFrame; /*!< Desired number of bits per frame. */
|
||||
volatile bool isThereExtraByte; /*!< Is there extra byte.*/
|
||||
|
||||
uint8_t *volatile txData; /*!< Send buffer. */
|
||||
uint8_t *volatile rxData; /*!< Receive buffer. */
|
||||
volatile size_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/
|
||||
volatile size_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/
|
||||
size_t totalByteCount; /*!< Number of transfer bytes*/
|
||||
|
||||
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 txLastData; /*!< Used if there is an extra byte when 16bits per frame for DMA purpose.*/
|
||||
|
||||
volatile uint8_t state; /*!< DSPI transfer state.*/
|
||||
|
||||
uint32_t errorCount; /*!< Error count for slave transfer.*/
|
||||
|
||||
dspi_slave_edma_transfer_callback_t callback; /*!< Completion callback. */
|
||||
void *userData; /*!< Callback user data. */
|
||||
|
||||
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_tcd_t dspiSoftwareTCD[2]; /*!<SoftwareTCD , internal used*/
|
||||
};
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* API
|
||||
**********************************************************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /*_cplusplus*/
|
||||
|
||||
/*Transactional APIs*/
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* specified DSPI instance, user need only 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.
|
||||
* (1)For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and
|
||||
* TX DMAMUX source for edmaIntermediaryToTxRegHandle.
|
||||
* (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 handle DSPI handle pointer to dspi_master_edma_handle_t.
|
||||
* @param callback DSPI callback.
|
||||
* @param userData callback function parameter.
|
||||
* @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
|
||||
* @param edmaTxDataToIntermediaryHandle edmaTxDataToIntermediaryHandle pointer to edma_handle_t.
|
||||
* @param edmaIntermediaryToTxRegHandle edmaIntermediaryToTxRegHandle pointer to edma_handle_t.
|
||||
*/
|
||||
void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base,
|
||||
dspi_master_edma_handle_t *handle,
|
||||
dspi_master_edma_transfer_callback_t callback,
|
||||
void *userData,
|
||||
edma_handle_t *edmaRxRegToRxDataHandle,
|
||||
edma_handle_t *edmaTxDataToIntermediaryHandle,
|
||||
edma_handle_t *edmaIntermediaryToTxRegHandle);
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* have been transfer, the callback function is called.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle pointer to dspi_master_edma_handle_t structure which stores the transfer state.
|
||||
* @param transfer pointer to dspi_transfer_t structure.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* This function aborts a transfer which using eDMA.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle pointer to dspi_master_edma_handle_t structure which stores the transfer state.
|
||||
*/
|
||||
void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Gets the master eDMA transfer count.
|
||||
*
|
||||
* This function get the master eDMA transfer count.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle pointer to dspi_master_edma_handle_t structure which stores the transfer state.
|
||||
* @param count Number of bytes transferred so far by the non-blocking transaction.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, size_t *count);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the DSPI slave eDMA handle.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* TX DMAMUX source for edmaTxDataToTxRegHandle.
|
||||
* (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 handle DSPI handle pointer to dspi_slave_edma_handle_t.
|
||||
* @param callback DSPI callback.
|
||||
* @param userData callback function parameter.
|
||||
* @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
|
||||
* @param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t.
|
||||
*/
|
||||
void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base,
|
||||
dspi_slave_edma_handle_t *handle,
|
||||
dspi_slave_edma_transfer_callback_t callback,
|
||||
void *userData,
|
||||
edma_handle_t *edmaRxRegToRxDataHandle,
|
||||
edma_handle_t *edmaTxDataToTxRegHandle);
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* have been transfer, the callback function is called.
|
||||
* Note that slave EDMA transfer cannot support the situation that transfer_size is 1 when the bitsPerFrame is greater
|
||||
* than 8 .
|
||||
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle pointer to dspi_slave_edma_handle_t structure which stores the transfer state.
|
||||
* @param transfer pointer to dspi_transfer_t structure.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* This function aborts a transfer which using eDMA.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle pointer to dspi_slave_edma_handle_t structure which stores the transfer state.
|
||||
*/
|
||||
void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Gets the slave eDMA transfer count.
|
||||
*
|
||||
* This function gets the slave eDMA transfer count.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle pointer to dspi_slave_edma_handle_t structure which stores the transfer state.
|
||||
* @param count Number of bytes transferred so far by the non-blocking transaction.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
status_t DSPI_SlaveTransferGetCountEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, size_t *count);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /*_cplusplus*/
|
||||
/*!
|
||||
*@}
|
||||
*/
|
||||
|
||||
#endif /*_FSL_DSPI_EDMA_H_*/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,879 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FSL_EDMA_H_
|
||||
#define _FSL_EDMA_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup edma_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief eDMA driver version */
|
||||
#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
|
||||
/*@}*/
|
||||
|
||||
/*! @brief Compute the offset unit from DCHPRI3 */
|
||||
#define DMA_DCHPRI_INDEX(channel) (((channel) & ~0x03U) | (3 - ((channel)&0x03U)))
|
||||
|
||||
/*! @brief Get the pointer of DCHPRIn */
|
||||
#define DMA_DCHPRIn(base, channel) ((volatile uint8_t *)&(base->DCHPRI3))[DMA_DCHPRI_INDEX(channel)]
|
||||
|
||||
/*! @brief eDMA transfer configuration */
|
||||
typedef enum _edma_transfer_size
|
||||
{
|
||||
kEDMA_TransferSize1Bytes = 0x0U, /*!< Source/Destination data transfer size is 1 byte every time */
|
||||
kEDMA_TransferSize2Bytes = 0x1U, /*!< Source/Destination data transfer size is 2 bytes every time */
|
||||
kEDMA_TransferSize4Bytes = 0x2U, /*!< Source/Destination data transfer size is 4 bytes every time */
|
||||
kEDMA_TransferSize16Bytes = 0x4U, /*!< Source/Destination data transfer size is 16 bytes every time */
|
||||
kEDMA_TransferSize32Bytes = 0x5U, /*!< Source/Destination data transfer size is 32 bytes every time */
|
||||
} edma_transfer_size_t;
|
||||
|
||||
/*! @brief eDMA modulo configuration */
|
||||
typedef enum _edma_modulo
|
||||
{
|
||||
kEDMA_ModuloDisable = 0x0U, /*!< Disable modulo */
|
||||
kEDMA_Modulo2bytes, /*!< Circular buffer size is 2 bytes. */
|
||||
kEDMA_Modulo4bytes, /*!< Circular buffer size is 4 bytes. */
|
||||
kEDMA_Modulo8bytes, /*!< Circular buffer size is 8 bytes. */
|
||||
kEDMA_Modulo16bytes, /*!< Circular buffer size is 16 bytes. */
|
||||
kEDMA_Modulo32bytes, /*!< Circular buffer size is 32 bytes. */
|
||||
kEDMA_Modulo64bytes, /*!< Circular buffer size is 64 bytes. */
|
||||
kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */
|
||||
kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */
|
||||
kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */
|
||||
kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1K bytes. */
|
||||
kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2K bytes. */
|
||||
kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4K bytes. */
|
||||
kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8K bytes. */
|
||||
kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16K bytes. */
|
||||
kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32K bytes. */
|
||||
kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64K bytes. */
|
||||
kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128K bytes. */
|
||||
kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256K bytes. */
|
||||
kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512K bytes. */
|
||||
kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1M bytes. */
|
||||
kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2M bytes. */
|
||||
kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4M bytes. */
|
||||
kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8M bytes. */
|
||||
kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16M bytes. */
|
||||
kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32M bytes. */
|
||||
kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64M bytes. */
|
||||
kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128M bytes. */
|
||||
kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256M bytes. */
|
||||
kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512M bytes. */
|
||||
kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1G bytes. */
|
||||
kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2G bytes. */
|
||||
} edma_modulo_t;
|
||||
|
||||
/*! @brief Bandwidth control */
|
||||
typedef enum _edma_bandwidth
|
||||
{
|
||||
kEDMA_BandwidthStallNone = 0x0U, /*!< No eDMA engine stalls. */
|
||||
kEDMA_BandwidthStall4Cycle = 0x2U, /*!< eDMA engine stalls for 4 cycles after each read/write. */
|
||||
kEDMA_BandwidthStall8Cycle = 0x3U, /*!< eDMA engine stalls for 8 cycles after each read/write. */
|
||||
} edma_bandwidth_t;
|
||||
|
||||
/*! @brief Channel link type */
|
||||
typedef enum _edma_channel_link_type
|
||||
{
|
||||
kEDMA_LinkNone = 0x0U, /*!< No channel link */
|
||||
kEDMA_MinorLink, /*!< Channel link after each minor loop */
|
||||
kEDMA_MajorLink, /*!< Channel link while major loop count exhausted */
|
||||
} edma_channel_link_type_t;
|
||||
|
||||
/*!@brief eDMA channel status flags. */
|
||||
enum _edma_channel_status_flags
|
||||
{
|
||||
kEDMA_DoneFlag = 0x1U, /*!< DONE flag, set while transfer finished, CITER value exhausted*/
|
||||
kEDMA_ErrorFlag = 0x2U, /*!< eDMA error flag, an error occurred in a transfer */
|
||||
kEDMA_InterruptFlag = 0x4U, /*!< eDMA interrupt flag, set while an interrupt occurred of this channel */
|
||||
};
|
||||
|
||||
/*! @brief eDMA channel error status flags. */
|
||||
enum _edma_error_status_flags
|
||||
{
|
||||
kEDMA_DestinationBusErrorFlag = DMA_ES_DBE_MASK, /*!< Bus error on destination address */
|
||||
kEDMA_SourceBusErrorFlag = DMA_ES_SBE_MASK, /*!< Bus error on the source address */
|
||||
kEDMA_ScatterGatherErrorFlag = DMA_ES_SGE_MASK, /*!< Error on the Scatter/Gather address, not 32byte aligned. */
|
||||
kEDMA_NbytesErrorFlag = DMA_ES_NCE_MASK, /*!< NBYTES/CITER configuration error */
|
||||
kEDMA_DestinationOffsetErrorFlag = DMA_ES_DOE_MASK, /*!< Destination offset not aligned with destination size */
|
||||
kEDMA_DestinationAddressErrorFlag = DMA_ES_DAE_MASK, /*!< Destination address not aligned with destination size */
|
||||
kEDMA_SourceOffsetErrorFlag = DMA_ES_SOE_MASK, /*!< Source offset not aligned with source size */
|
||||
kEDMA_SourceAddressErrorFlag = DMA_ES_SAE_MASK, /*!< Source address not aligned with source size*/
|
||||
kEDMA_ErrorChannelFlag = DMA_ES_ERRCHN_MASK, /*!< Error channel number of the cancelled channel number */
|
||||
kEDMA_ChannelPriorityErrorFlag = DMA_ES_CPE_MASK, /*!< Channel priority is not unique. */
|
||||
kEDMA_TransferCanceledFlag = DMA_ES_ECX_MASK, /*!< Transfer cancelled */
|
||||
#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. */
|
||||
#endif
|
||||
kEDMA_ValidFlag = DMA_ES_VLD_MASK, /*!< No error occurred, this bit will be 0, otherwise be 1 */
|
||||
};
|
||||
|
||||
/*! @brief eDMA interrupt source */
|
||||
typedef enum _edma_interrupt_enable
|
||||
{
|
||||
kEDMA_ErrorInterruptEnable = 0x1U, /*!< Enable interrupt while channel error occurs. */
|
||||
kEDMA_MajorInterruptEnable = DMA_CSR_INTMAJOR_MASK, /*!< Enable interrupt while major count exhausted. */
|
||||
kEDMA_HalfInterruptEnable = DMA_CSR_INTHALF_MASK, /*!< Enable interrupt while major count to half value. */
|
||||
} edma_interrupt_enable_t;
|
||||
|
||||
/*! @brief eDMA transfer type */
|
||||
typedef enum _edma_transfer_type
|
||||
{
|
||||
kEDMA_MemoryToMemory = 0x0U, /*!< Transfer from memory to memory */
|
||||
kEDMA_PeripheralToMemory, /*!< Transfer from peripheral to memory */
|
||||
kEDMA_MemoryToPeripheral, /*!< Transfer from memory to peripheral */
|
||||
} edma_transfer_type_t;
|
||||
|
||||
/*! @brief eDMA transfer status */
|
||||
enum _edma_transfer_status
|
||||
{
|
||||
kStatus_EDMA_QueueFull = MAKE_STATUS(kStatusGroup_EDMA, 0), /*!< TCD queue is full. */
|
||||
kStatus_EDMA_Busy = MAKE_STATUS(kStatusGroup_EDMA, 1), /*!< Channel is busy and can't handle the
|
||||
transfer request. */
|
||||
};
|
||||
|
||||
/*! @brief eDMA global configuration structure.*/
|
||||
typedef struct _edma_config
|
||||
{
|
||||
bool enableContinuousLinkMode; /*!< Enable (true) continuous link mode. Upon minor loop completion, the channel
|
||||
activates again if that channel has a minor loop channel link enabled and
|
||||
the link channel is itself. */
|
||||
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.*/
|
||||
bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method, or fixed priority
|
||||
arbitration is used for channel selection */
|
||||
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. */
|
||||
} edma_config_t;
|
||||
|
||||
/*!
|
||||
* @brief eDMA transfer configuration
|
||||
*
|
||||
* This structure configures the source/destination transfer attribute.
|
||||
* This figure shows the eDMA's transfer model:
|
||||
* _________________________________________________
|
||||
* | Transfer Size | |
|
||||
* Minor Loop |_______________| Major loop Count 1 |
|
||||
* Bytes | Transfer Size | |
|
||||
* ____________|_______________|____________________|--> Minor loop complete
|
||||
* ____________________________________
|
||||
* | | |
|
||||
* |_______________| Major Loop Count 2 |
|
||||
* | | |
|
||||
* |_______________|____________________|--> Minor loop Complete
|
||||
*
|
||||
* ---------------------------------------------------------> Transfer complete
|
||||
*/
|
||||
typedef struct _edma_transfer_config
|
||||
{
|
||||
uint32_t srcAddr; /*!< Source data address. */
|
||||
uint32_t destAddr; /*!< Destination data address. */
|
||||
edma_transfer_size_t srcTransferSize; /*!< Source data transfer size. */
|
||||
edma_transfer_size_t destTransferSize; /*!< Destination data transfer size. */
|
||||
int16_t srcOffset; /*!< Sign-extended offset applied to the current source address to
|
||||
form the next-state value as each source read is completed. */
|
||||
int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to
|
||||
form the next-state value as each destination write is completed. */
|
||||
uint16_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/
|
||||
uint32_t majorLoopCounts; /*!< Major loop iteration count. */
|
||||
} edma_transfer_config_t;
|
||||
|
||||
/*! @brief eDMA channel priority configuration */
|
||||
typedef struct _edma_channel_Preemption_config
|
||||
{
|
||||
bool enableChannelPreemption; /*!< If true: channel can be suspended by other channel with higher priority */
|
||||
bool enablePreemptAbility; /*!< If true: channel can suspend other channel with low priority */
|
||||
uint8_t channelPriority; /*!< Channel priority */
|
||||
} edma_channel_Preemption_config_t;
|
||||
|
||||
/*! @brief eDMA minor offset configuration */
|
||||
typedef struct _edma_minor_offset_config
|
||||
{
|
||||
bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */
|
||||
bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */
|
||||
uint32_t minorOffset; /*!< Offset for minor loop mapping. */
|
||||
} edma_minor_offset_config_t;
|
||||
|
||||
/*!
|
||||
* @brief eDMA TCD.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
typedef struct _edma_tcd
|
||||
{
|
||||
__IO uint32_t SADDR; /*!< SADDR register, used to save source address */
|
||||
__IO uint16_t SOFF; /*!< SOFF register, save offset bytes every transfer */
|
||||
__IO uint16_t ATTR; /*!< ATTR register, source/destination transfer size and modulo */
|
||||
__IO uint32_t NBYTES; /*!< Nbytes register, minor loop length in bytes */
|
||||
__IO uint32_t SLAST; /*!< SLAST register */
|
||||
__IO uint32_t DADDR; /*!< DADDR register, used for destination address */
|
||||
__IO uint16_t DOFF; /*!< DOFF register, used for destination offset */
|
||||
__IO uint16_t CITER; /*!< CITER register, current minor loop numbers, for unfinished minor loop.*/
|
||||
__IO uint32_t DLAST_SGA; /*!< DLASTSGA register, next stcd address used in scatter-gather mode */
|
||||
__IO uint16_t CSR; /*!< CSR register, for TCD control status */
|
||||
__IO uint16_t BITER; /*!< BITER register, begin minor loop count. */
|
||||
} edma_tcd_t;
|
||||
|
||||
/*! @brief Callback for eDMA */
|
||||
struct _edma_handle;
|
||||
|
||||
/*! @brief Define Callback function for eDMA. */
|
||||
typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds);
|
||||
|
||||
/*! @brief eDMA transfer handle structure */
|
||||
typedef struct _edma_handle
|
||||
{
|
||||
edma_callback callback; /*!< Callback function for major count exhausted. */
|
||||
void *userData; /*!< Callback function parameter. */
|
||||
DMA_Type *base; /*!< eDMA peripheral base address. */
|
||||
edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */
|
||||
uint8_t channel; /*!< eDMA channel number. */
|
||||
volatile int8_t header; /*!< The first TCD index. */
|
||||
volatile int8_t tail; /*!< The last TCD index. */
|
||||
volatile int8_t tcdUsed; /*!< The number of used TCD slots. */
|
||||
volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */
|
||||
uint8_t flags; /*!< The status of the current channel. */
|
||||
} edma_handle_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* APIs
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*!
|
||||
* @name eDMA initialization and De-initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes eDMA peripheral.
|
||||
*
|
||||
* This function ungates the eDMA clock and configure eDMA peripheral according
|
||||
* to the configuration structure.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param config Pointer to configuration structure, see "edma_config_t".
|
||||
* @note This function enable the minor loop map feature.
|
||||
*/
|
||||
void EDMA_Init(DMA_Type *base, const edma_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes eDMA peripheral.
|
||||
*
|
||||
* This function gates the eDMA clock.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
*/
|
||||
void EDMA_Deinit(DMA_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Gets the eDMA default configuration structure.
|
||||
*
|
||||
* This function sets the configuration structure to a default value.
|
||||
* The default configuration is set to the following value:
|
||||
* @code
|
||||
* config.enableContinuousLinkMode = false;
|
||||
* config.enableHaltOnError = true;
|
||||
* config.enableRoundRobinArbitration = false;
|
||||
* config.enableDebugMode = false;
|
||||
* @endcode
|
||||
*
|
||||
* @param config Pointer to eDMA configuration structure.
|
||||
*/
|
||||
void EDMA_GetDefaultConfig(edma_config_t *config);
|
||||
|
||||
/* @} */
|
||||
/*!
|
||||
* @name eDMA Channel Operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Sets all TCD registers to a default value.
|
||||
*
|
||||
* This function sets TCD registers for this channel to default value.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
* @note This function must not be called while the channel transfer is on-going,
|
||||
* or it will case unpredicated results.
|
||||
* @note This function will enable auto stop request feature.
|
||||
*/
|
||||
void EDMA_ResetChannel(DMA_Type *base, uint32_t channel);
|
||||
|
||||
/*!
|
||||
* @brief Configures the eDMA transfer attribute.
|
||||
*
|
||||
* This function configure the transfer attribute, including source address, destination address,
|
||||
* transfer size, address offset, and so on. It also configures the scatter gather feature if the
|
||||
* user supplies the TCD address.
|
||||
* Example:
|
||||
* @code
|
||||
* edma_transfer_t config;
|
||||
* edma_tcd_t tcd;
|
||||
* config.srcAddr = ..;
|
||||
* config.destAddr = ..;
|
||||
* ...
|
||||
* EDMA_SetTransferConfig(DMA0, channel, &config, &stcd);
|
||||
* @endcode
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
* @param config Pointer to eDMA transfer configuration structure.
|
||||
* @param nextTcd Point to TCD structure. It can be NULL if user
|
||||
* do not want to enable scatter/gather feature.
|
||||
* @note If nextTcd is not NULL, it means scatter gather feature will be enabled.
|
||||
* And DREQ bit will be cleared in the previous transfer configuration which
|
||||
* will be set in eDMA_ResetChannel.
|
||||
*/
|
||||
void EDMA_SetTransferConfig(DMA_Type *base,
|
||||
uint32_t channel,
|
||||
const edma_transfer_config_t *config,
|
||||
edma_tcd_t *nextTcd);
|
||||
|
||||
/*!
|
||||
* @brief Configures the eDMA minor offset feature.
|
||||
*
|
||||
* Minor offset means signed-extended value added to source address or destination
|
||||
* address after each minor loop.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
* @param config Pointer to Minor offset configuration structure.
|
||||
*/
|
||||
void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Configures the eDMA channel preemption feature.
|
||||
*
|
||||
* This function configures the channel preemption attribute and the priority of the channel.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number
|
||||
* @param config Pointer to channel preemption configuration structure.
|
||||
*/
|
||||
static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base,
|
||||
uint32_t channel,
|
||||
const edma_channel_Preemption_config_t *config)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL);
|
||||
assert(config != NULL);
|
||||
|
||||
DMA_DCHPRIn(base, channel) =
|
||||
(DMA_DCHPRI0_DPA(!config->enablePreemptAbility) | DMA_DCHPRI0_ECP(config->enableChannelPreemption) |
|
||||
DMA_DCHPRI0_CHPRI(config->channelPriority));
|
||||
}
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* 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 channel eDMA channel number.
|
||||
* @param type Channel link type, it can be one of:
|
||||
* @arg kEDMA_LinkNone
|
||||
* @arg kEDMA_MinorLink
|
||||
* @arg kEDMA_MajorLink
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* In general, 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
|
||||
* each read/write access to control the bus request bandwidth seen by the crossbar switch.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
* @param bandWidth Bandwidth setting, it can be one of:
|
||||
* @arg kEDMABandwidthStallNone
|
||||
* @arg kEDMABandwidthStall4Cycle
|
||||
* @arg kEDMABandwidthStall8Cycle
|
||||
*/
|
||||
void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth);
|
||||
|
||||
/*!
|
||||
* @brief Sets the source modulo and destination modulo for eDMA transfer.
|
||||
*
|
||||
* 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
|
||||
* queue easily.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
* @param srcModulo Source modulo value.
|
||||
* @param destModulo Destination modulo value.
|
||||
*/
|
||||
void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo);
|
||||
|
||||
#if defined(FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT) && FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT
|
||||
/*!
|
||||
* @brief Enables an async request for the eDMA transfer.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
* @param enable The command for enable(ture) or disable(false).
|
||||
*/
|
||||
static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->EARS = (base->EARS & (~(1U << channel))) | ((uint32_t)enable << channel);
|
||||
}
|
||||
#endif /* FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT */
|
||||
|
||||
/*!
|
||||
* @brief Enables an auto stop request for the eDMA transfer.
|
||||
*
|
||||
* If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
* @param enable The command for enable (true) or disable (false).
|
||||
*/
|
||||
static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->TCD[channel].CSR = (base->TCD[channel].CSR & (~DMA_CSR_DREQ_MASK)) | DMA_CSR_DREQ(enable);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables the interrupt source for the eDMA transfer.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
* @param mask The mask of interrupt source to be set. User need to use
|
||||
* the defined edma_interrupt_enable_t type.
|
||||
*/
|
||||
void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask);
|
||||
|
||||
/*!
|
||||
* @brief Disables the interrupt source for the eDMA transfer.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
* @param mask The mask of interrupt source to be set. Use
|
||||
* the defined edma_interrupt_enable_t type.
|
||||
*/
|
||||
void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask);
|
||||
|
||||
/* @} */
|
||||
/*!
|
||||
* @name eDMA TCD Operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Sets all fields to default values for the TCD structure.
|
||||
*
|
||||
* This function sets all fields for this TCD structure to default value.
|
||||
*
|
||||
* @param tcd Pointer to the TCD structure.
|
||||
* @note This function will enable auto stop request feature.
|
||||
*/
|
||||
void EDMA_TcdReset(edma_tcd_t *tcd);
|
||||
|
||||
/*!
|
||||
* @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.
|
||||
* STCD is used in scatter-gather mode.
|
||||
* 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
|
||||
* user supplies the next TCD address.
|
||||
* Example:
|
||||
* @code
|
||||
* edma_transfer_t config = {
|
||||
* ...
|
||||
* }
|
||||
* edma_tcd_t tcd __aligned(32);
|
||||
* edma_tcd_t nextTcd __aligned(32);
|
||||
* EDMA_TcdSetTransferConfig(&tcd, &config, &nextTcd);
|
||||
* @endcode
|
||||
*
|
||||
* @param tcd Pointer to the TCD structure.
|
||||
* @param config Pointer to eDMA transfer configuration structure.
|
||||
* @param nextTcd Pointer to the next TCD structure. It can be NULL if user
|
||||
* do not want to enable scatter/gather feature.
|
||||
* @note TCD address should be 32 bytes aligned, or it will cause eDMA error.
|
||||
* @note If nextTcd is not NULL, it means scatter gather feature will be enabled.
|
||||
* And DREQ bit will be cleared in the previous transfer configuration which
|
||||
* will be set in EDMA_TcdReset.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* Minor offset is a signed-extended value added to the source address or destination
|
||||
* address after each minor loop.
|
||||
*
|
||||
* @param tcd Point to the TCD structure.
|
||||
* @param config Pointer to Minor offset configuration structure.
|
||||
*/
|
||||
void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Sets the channel link for eDMA TCD.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @note User should ensure that DONE flag is cleared before call this interface, or the configuration will be invalid.
|
||||
* @param tcd Point to the TCD structure.
|
||||
* @param type Channel link type, it can be one of:
|
||||
* @arg kEDMA_LinkNone
|
||||
* @arg kEDMA_MinorLink
|
||||
* @arg kEDMA_MajorLink
|
||||
* @param linkedChannel The linked channel number.
|
||||
*/
|
||||
void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint32_t linkedChannel);
|
||||
|
||||
/*!
|
||||
* @brief Sets the bandwidth for the eDMA TCD.
|
||||
*
|
||||
* In general, 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
|
||||
* each read/write access to control the bus request bandwidth seen by the crossbar switch.
|
||||
* @param tcd Point to the TCD structure.
|
||||
* @param bandWidth Bandwidth setting, it can be one of:
|
||||
* @arg kEDMABandwidthStallNone
|
||||
* @arg kEDMABandwidthStall4Cycle
|
||||
* @arg kEDMABandwidthStall8Cycle
|
||||
*/
|
||||
static inline void EDMA_TcdSetBandWidth(edma_tcd_t *tcd, edma_bandwidth_t bandWidth)
|
||||
{
|
||||
assert(tcd != NULL);
|
||||
assert(((uint32_t)tcd & 0x1FU) == 0);
|
||||
|
||||
tcd->CSR = (tcd->CSR & (~DMA_CSR_BWC_MASK)) | DMA_CSR_BWC(bandWidth);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the source modulo and destination modulo for eDMA TCD.
|
||||
*
|
||||
* 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
|
||||
* queue easily.
|
||||
*
|
||||
* @param tcd Point to the TCD structure.
|
||||
* @param srcModulo Source modulo value.
|
||||
* @param destModulo Destination modulo value.
|
||||
*/
|
||||
void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo);
|
||||
|
||||
/*!
|
||||
* @brief Sets the auto stop request for the eDMA TCD.
|
||||
*
|
||||
* If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request.
|
||||
*
|
||||
* @param tcd Point to the TCD structure.
|
||||
* @param enable The command for enable(ture) or disable(false).
|
||||
*/
|
||||
static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable)
|
||||
{
|
||||
assert(tcd != NULL);
|
||||
assert(((uint32_t)tcd & 0x1FU) == 0);
|
||||
|
||||
tcd->CSR = (tcd->CSR & (~DMA_CSR_DREQ_MASK)) | DMA_CSR_DREQ(enable);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables the interrupt source for the eDMA TCD.
|
||||
*
|
||||
* @param tcd Point to the TCD structure.
|
||||
* @param mask The mask of interrupt source to be set. User need to use
|
||||
* the defined edma_interrupt_enable_t type.
|
||||
*/
|
||||
void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask);
|
||||
|
||||
/*!
|
||||
* @brief Disables the interrupt source for the eDMA TCD.
|
||||
*
|
||||
* @param tcd Point to the TCD structure.
|
||||
* @param mask The mask of interrupt source to be set. User need to use
|
||||
* the defined edma_interrupt_enable_t type.
|
||||
*/
|
||||
void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask);
|
||||
|
||||
/*! @} */
|
||||
/*!
|
||||
* @name eDMA Channel Transfer Operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables the eDMA hardware channel request.
|
||||
*
|
||||
* This function enables the hardware channel request.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
*/
|
||||
static inline void EDMA_EnableChannelRequest(DMA_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->SERQ = DMA_SERQ_SERQ(channel);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the eDMA hardware channel request.
|
||||
*
|
||||
* This function disables the hardware channel request.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
*/
|
||||
static inline void EDMA_DisableChannelRequest(DMA_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->CERQ = DMA_CERQ_CERQ(channel);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Starts the eDMA transfer by software trigger.
|
||||
*
|
||||
* This function starts a minor loop transfer.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
*/
|
||||
static inline void EDMA_TriggerChannelStart(DMA_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->SSRT = DMA_SSRT_SSRT(channel);
|
||||
}
|
||||
|
||||
/*! @} */
|
||||
/*!
|
||||
* @name eDMA Channel Status Operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Gets the Remaining bytes from the eDMA current channel TCD.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
* @return Bytes have not been transferred yet for the current TCD.
|
||||
* @note This function can only be used to get unfinished bytes of transfer without
|
||||
* the next TCD, or it might be inaccuracy.
|
||||
*/
|
||||
uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel);
|
||||
|
||||
/*!
|
||||
* @brief Gets the eDMA channel error status flags.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @return The mask of error status flags. User need to use the
|
||||
* _edma_error_status_flags type to decode the return variables.
|
||||
*/
|
||||
static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base)
|
||||
{
|
||||
return base->ES;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the eDMA channel status flags.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
* @return The mask of channel status flags. User need to use the
|
||||
* _edma_channel_status_flags type to decode the return variables.
|
||||
*/
|
||||
uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel);
|
||||
|
||||
/*!
|
||||
* @brief Clears the eDMA channel status flags.
|
||||
*
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
* @param mask The mask of channel status to be cleared. User need to use
|
||||
* the defined _edma_channel_status_flags type.
|
||||
*/
|
||||
void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask);
|
||||
|
||||
/*! @} */
|
||||
/*!
|
||||
* @name eDMA Transactional Operation
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Creates the eDMA handle.
|
||||
*
|
||||
* This function is called if using transaction API for eDMA. This function
|
||||
* initializes the internal state of eDMA handle.
|
||||
*
|
||||
* @param handle eDMA handle pointer. The eDMA handle stores callback function and
|
||||
* parameters.
|
||||
* @param base eDMA peripheral base address.
|
||||
* @param channel eDMA channel number.
|
||||
*/
|
||||
void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel);
|
||||
|
||||
/*!
|
||||
* @brief Installs the TCDs memory pool into eDMA handle.
|
||||
*
|
||||
* This function is called after the EDMA_CreateHandle to use scatter/gather feature.
|
||||
*
|
||||
* @param handle eDMA handle pointer.
|
||||
* @param tcdPool Memory pool to store TCDs. It must be 32 bytes aligned.
|
||||
* @param tcdSize The number of TCD slots.
|
||||
*/
|
||||
void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize);
|
||||
|
||||
/*!
|
||||
* @brief Installs a callback function for the eDMA transfer.
|
||||
*
|
||||
* This callback is called in eDMA IRQ handler. Use the callback to do something after
|
||||
* the current major loop transfer completes.
|
||||
*
|
||||
* @param handle eDMA handle pointer.
|
||||
* @param callback eDMA callback function pointer.
|
||||
* @param userData Parameter for callback function.
|
||||
*/
|
||||
void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData);
|
||||
|
||||
/*!
|
||||
* @brief Prepares the eDMA transfer structure.
|
||||
*
|
||||
* This function prepares the transfer configuration structure according to the user input.
|
||||
*
|
||||
* @param config The user configuration structure of type edma_transfer_t.
|
||||
* @param srcAddr eDMA transfer source address.
|
||||
* @param srcWidth eDMA transfer source address width(bytes).
|
||||
* @param destAddr eDMA transfer destination address.
|
||||
* @param destWidth eDMA transfer destination address width(bytes).
|
||||
* @param bytesEachRequest eDMA transfer bytes per channel request.
|
||||
* @param transferBytes eDMA transfer bytes to be transferred.
|
||||
* @param type eDMA transfer type.
|
||||
* @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
|
||||
* source address error(SAE).
|
||||
*/
|
||||
void EDMA_PrepareTransfer(edma_transfer_config_t *config,
|
||||
void *srcAddr,
|
||||
uint32_t srcWidth,
|
||||
void *destAddr,
|
||||
uint32_t destWidth,
|
||||
uint32_t bytesEachRequest,
|
||||
uint32_t transferBytes,
|
||||
edma_transfer_type_t type);
|
||||
|
||||
/*!
|
||||
* @brief Submits the eDMA transfer request.
|
||||
*
|
||||
* 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
|
||||
* a TCD and enables scatter/gather feature to process it in the next time.
|
||||
*
|
||||
* @param handle eDMA handle pointer.
|
||||
* @param config Pointer to eDMA transfer configuration structure.
|
||||
* @retval kStatus_EDMA_Success It means submit transfer request succeed.
|
||||
* @retval kStatus_EDMA_QueueFull It means TCD queue is full. Submit transfer request is not allowed.
|
||||
* @retval kStatus_EDMA_Busy It means the given channel is busy, need to submit request later.
|
||||
*/
|
||||
status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief eDMA start transfer.
|
||||
*
|
||||
* This function enables the channel request. User can call this function after submitting the transfer request
|
||||
* or before submitting the transfer request.
|
||||
*
|
||||
* @param handle eDMA handle pointer.
|
||||
*/
|
||||
void EDMA_StartTransfer(edma_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief eDMA stop transfer.
|
||||
*
|
||||
* This function disables the channel request to pause the transfer. User can call EDMA_StartTransfer()
|
||||
* again to resume the transfer.
|
||||
*
|
||||
* @param handle eDMA handle pointer.
|
||||
*/
|
||||
void EDMA_StopTransfer(edma_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief eDMA abort transfer.
|
||||
*
|
||||
* This function disables the channel request and clear transfer status bits.
|
||||
* User can submit another transfer after calling this API.
|
||||
*
|
||||
* @param handle DMA handle pointer.
|
||||
*/
|
||||
void EDMA_AbortTransfer(edma_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief eDMA IRQ handler for current major loop transfer complete.
|
||||
*
|
||||
* This function clears the channel major interrupt flag and call
|
||||
* the callback function if it is not NULL.
|
||||
*
|
||||
* @param handle eDMA handle pointer.
|
||||
*/
|
||||
void EDMA_HandleIRQ(edma_handle_t *handle);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* @} */
|
||||
|
||||
#endif /*_FSL_EDMA_H_*/
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_ewm.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
void EWM_Init(EWM_Type *base, const ewm_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
uint32_t value = 0U;
|
||||
|
||||
CLOCK_EnableClock(kCLOCK_Ewm0);
|
||||
value = EWM_CTRL_EWMEN(config->enableEwm) | EWM_CTRL_ASSIN(config->setInputAssertLogic) |
|
||||
EWM_CTRL_INEN(config->enableEwmInput) | EWM_CTRL_INTEN(config->enableInterrupt);
|
||||
#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
|
||||
base->CLKPRESCALER = config->prescaler;
|
||||
#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */
|
||||
|
||||
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
|
||||
base->CLKCTRL = config->clockSource;
|
||||
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/
|
||||
|
||||
base->CMPL = config->compareLowValue;
|
||||
base->CMPH = config->compareHighValue;
|
||||
base->CTRL = value;
|
||||
}
|
||||
|
||||
void EWM_Deinit(EWM_Type *base)
|
||||
{
|
||||
EWM_DisableInterrupts(base, kEWM_InterruptEnable);
|
||||
CLOCK_DisableClock(kCLOCK_Ewm0);
|
||||
}
|
||||
|
||||
void EWM_GetDefaultConfig(ewm_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
config->enableEwm = true;
|
||||
config->enableEwmInput = false;
|
||||
config->setInputAssertLogic = false;
|
||||
config->enableInterrupt = false;
|
||||
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
|
||||
config->clockSource = kEWM_LpoClockSource0;
|
||||
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/
|
||||
#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
|
||||
config->prescaler = 0U;
|
||||
#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */
|
||||
config->compareLowValue = 0U;
|
||||
config->compareHighValue = 0xFEU;
|
||||
}
|
||||
|
||||
void EWM_Refresh(EWM_Type *base)
|
||||
{
|
||||
uint32_t primaskValue = 0U;
|
||||
|
||||
/* Disable the global interrupt to protect refresh sequence */
|
||||
primaskValue = DisableGlobalIRQ();
|
||||
base->SERV = (uint8_t)0xB4U;
|
||||
base->SERV = (uint8_t)0x2CU;
|
||||
EnableGlobalIRQ(primaskValue);
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_EWM_H_
|
||||
#define _FSL_EWM_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup ewm_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
*******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief EWM driver version 2.0.1. */
|
||||
#define FSL_EWM_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief Describes ewm clock source. */
|
||||
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
|
||||
typedef enum _ewm_lpo_clock_source
|
||||
{
|
||||
kEWM_LpoClockSource0 = 0U, /*!< ewm clock sourced from lpo_clk[0]*/
|
||||
kEWM_LpoClockSource1 = 1U, /*!< ewm clock sourced from lpo_clk[1]*/
|
||||
kEWM_LpoClockSource2 = 2U, /*!< ewm clock sourced from lpo_clk[2]*/
|
||||
kEWM_LpoClockSource3 = 3U, /*!< ewm clock sourced from lpo_clk[3]*/
|
||||
} ewm_lpo_clock_source_t;
|
||||
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */
|
||||
|
||||
/*!
|
||||
* @brief Data structure for EWM configuration.
|
||||
*
|
||||
* This structure is used to configure the EWM.
|
||||
*/
|
||||
typedef struct _ewm_config
|
||||
{
|
||||
bool enableEwm; /*!< Enable EWM module */
|
||||
bool enableEwmInput; /*!< Enable EWM_in input */
|
||||
bool setInputAssertLogic; /*!< EWM_in signal assertion state */
|
||||
bool enableInterrupt; /*!< Enable EWM interrupt */
|
||||
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
|
||||
ewm_lpo_clock_source_t clockSource; /*!< Clock source select */
|
||||
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */
|
||||
#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
|
||||
uint8_t prescaler; /*!< Clock prescaler value */
|
||||
#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */
|
||||
uint8_t compareLowValue; /*!< Compare low register value */
|
||||
uint8_t compareHighValue; /*!< Compare high register value */
|
||||
} ewm_config_t;
|
||||
|
||||
/*!
|
||||
* @brief EWM interrupt configuration structure, default settings all disabled.
|
||||
*
|
||||
* This structure contains the settings for all of the EWM interrupt configurations.
|
||||
*/
|
||||
enum _ewm_interrupt_enable_t
|
||||
{
|
||||
kEWM_InterruptEnable = EWM_CTRL_INTEN_MASK, /*!< Enable EWM to generate an interrupt*/
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief EWM status flags.
|
||||
*
|
||||
* This structure contains the constants for the EWM status flags for use in the EWM functions.
|
||||
*/
|
||||
enum _ewm_status_flags_t
|
||||
{
|
||||
kEWM_RunningFlag = EWM_CTRL_EWMEN_MASK, /*!< Running flag, set when ewm is enabled*/
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
*******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*!
|
||||
* @name EWM Initialization and De-initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the EWM peripheral.
|
||||
*
|
||||
* This function is used to initialize the EWM. After calling, the EWM
|
||||
* runs immediately according to the configuration.
|
||||
* Note that except for 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.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ewm_config_t config;
|
||||
* EWM_GetDefaultConfig(&config);
|
||||
* config.compareHighValue = 0xAAU;
|
||||
* EWM_Init(ewm_base,&config);
|
||||
* @endcode
|
||||
*
|
||||
* @param base EWM peripheral base address
|
||||
* @param config The configuration of EWM
|
||||
*/
|
||||
void EWM_Init(EWM_Type *base, const ewm_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the EWM peripheral.
|
||||
*
|
||||
* This function is used to shut down the EWM.
|
||||
*
|
||||
* @param base EWM peripheral base address
|
||||
*/
|
||||
void EWM_Deinit(EWM_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the EWM configuration structure.
|
||||
*
|
||||
* This function initializes the EWM configure structure to default values. The default
|
||||
* values are:
|
||||
* @code
|
||||
* ewmConfig->enableEwm = true;
|
||||
* ewmConfig->enableEwmInput = false;
|
||||
* ewmConfig->setInputAssertLogic = false;
|
||||
* ewmConfig->enableInterrupt = false;
|
||||
* ewmConfig->ewm_lpo_clock_source_t = kEWM_LpoClockSource0;
|
||||
* ewmConfig->prescaler = 0;
|
||||
* ewmConfig->compareLowValue = 0;
|
||||
* ewmConfig->compareHighValue = 0xFEU;
|
||||
* @endcode
|
||||
*
|
||||
* @param config Pointer to EWM configuration structure.
|
||||
* @see ewm_config_t
|
||||
*/
|
||||
void EWM_GetDefaultConfig(ewm_config_t *config);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name EWM functional Operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables the EWM interrupt.
|
||||
*
|
||||
* This function enables the EWM interrupt.
|
||||
*
|
||||
* @param base EWM peripheral base address
|
||||
* @param mask The interrupts to enable
|
||||
* The parameter can be combination of the following source if defined:
|
||||
* @arg kEWM_InterruptEnable
|
||||
*/
|
||||
static inline void EWM_EnableInterrupts(EWM_Type *base, uint32_t mask)
|
||||
{
|
||||
base->CTRL |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the EWM interrupt.
|
||||
*
|
||||
* This function enables the EWM interrupt.
|
||||
*
|
||||
* @param base EWM peripheral base address
|
||||
* @param mask The interrupts to disable
|
||||
* The parameter can be combination of the following source if defined:
|
||||
* @arg kEWM_InterruptEnable
|
||||
*/
|
||||
static inline void EWM_DisableInterrupts(EWM_Type *base, uint32_t mask)
|
||||
{
|
||||
base->CTRL &= ~mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets EWM all status flags.
|
||||
*
|
||||
* This function gets all status flags.
|
||||
*
|
||||
* Example for getting Running Flag:
|
||||
* @code
|
||||
* uint32_t status;
|
||||
* status = EWM_GetStatusFlags(ewm_base) & kEWM_RunningFlag;
|
||||
* @endcode
|
||||
* @param base EWM peripheral base address
|
||||
* @return State of the status flag: asserted (true) or not-asserted (false).@see _ewm_status_flags_t
|
||||
* - true: related status flag has been set.
|
||||
* - false: related status flag is not set.
|
||||
*/
|
||||
static inline uint32_t EWM_GetStatusFlags(EWM_Type *base)
|
||||
{
|
||||
return (base->CTRL & EWM_CTRL_EWMEN_MASK);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Service EWM.
|
||||
*
|
||||
* This function reset EWM counter to zero.
|
||||
*
|
||||
* @param base EWM peripheral base address
|
||||
*/
|
||||
void EWM_Refresh(EWM_Type *base);
|
||||
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_EWM_H_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_flexbus.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Gets the instance from the base address
|
||||
*
|
||||
* @param base FLEXBUS peripheral base address
|
||||
*
|
||||
* @return The FLEXBUS instance
|
||||
*/
|
||||
static uint32_t FLEXBUS_GetInstance(FB_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Pointers to FLEXBUS bases for each instance. */
|
||||
static FB_Type *const s_flexbusBases[] = FB_BASE_PTRS;
|
||||
|
||||
/*! @brief Pointers to FLEXBUS clocks for each instance. */
|
||||
static const clock_ip_name_t s_flexbusClocks[] = FLEXBUS_CLOCKS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
static uint32_t FLEXBUS_GetInstance(FB_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_FB_COUNT; instance++)
|
||||
{
|
||||
if (s_flexbusBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < FSL_FEATURE_SOC_FB_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void FLEXBUS_Init(FB_Type *base, const flexbus_config_t *config)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(config->chip < FB_CSAR_COUNT);
|
||||
assert(config->waitStates <= 0x3FU);
|
||||
|
||||
uint32_t chip = 0;
|
||||
uint32_t reg_value = 0;
|
||||
|
||||
/* Ungate clock for FLEXBUS */
|
||||
CLOCK_EnableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]);
|
||||
|
||||
/* Reset all the register to default state */
|
||||
for (chip = 0; chip < FB_CSAR_COUNT; chip++)
|
||||
{
|
||||
/* Reset CSMR register, all chips not valid (disabled) */
|
||||
base->CS[chip].CSMR = 0x0000U;
|
||||
/* Set default base address */
|
||||
base->CS[chip].CSAR &= (~FB_CSAR_BA_MASK);
|
||||
/* Reset FB_CSCRx register */
|
||||
base->CS[chip].CSCR = 0x0000U;
|
||||
}
|
||||
/* Set FB_CSPMCR register */
|
||||
/* FlexBus signal group 1 multiplex control */
|
||||
reg_value |= kFLEXBUS_MultiplexGroup1_FB_ALE << FB_CSPMCR_GROUP1_SHIFT;
|
||||
/* FlexBus signal group 2 multiplex control */
|
||||
reg_value |= kFLEXBUS_MultiplexGroup2_FB_CS4 << FB_CSPMCR_GROUP2_SHIFT;
|
||||
/* FlexBus signal group 3 multiplex control */
|
||||
reg_value |= kFLEXBUS_MultiplexGroup3_FB_CS5 << FB_CSPMCR_GROUP3_SHIFT;
|
||||
/* FlexBus signal group 4 multiplex control */
|
||||
reg_value |= kFLEXBUS_MultiplexGroup4_FB_TBST << FB_CSPMCR_GROUP4_SHIFT;
|
||||
/* FlexBus signal group 5 multiplex control */
|
||||
reg_value |= kFLEXBUS_MultiplexGroup5_FB_TA << FB_CSPMCR_GROUP5_SHIFT;
|
||||
/* Write to CSPMCR register */
|
||||
base->CSPMCR = reg_value;
|
||||
|
||||
/* Update chip value */
|
||||
chip = config->chip;
|
||||
|
||||
/* Base address */
|
||||
reg_value = config->chipBaseAddress;
|
||||
/* Write to CSAR register */
|
||||
base->CS[chip].CSAR = reg_value;
|
||||
/* Chip-select validation */
|
||||
reg_value = 0x1U << FB_CSMR_V_SHIFT;
|
||||
/* Write protect */
|
||||
reg_value |= (uint32_t)(config->writeProtect) << FB_CSMR_WP_SHIFT;
|
||||
/* Base address mask */
|
||||
reg_value |= config->chipBaseAddressMask << FB_CSMR_BAM_SHIFT;
|
||||
/* Write to CSMR register */
|
||||
base->CS[chip].CSMR = reg_value;
|
||||
/* Burst write */
|
||||
reg_value = (uint32_t)(config->burstWrite) << FB_CSCR_BSTW_SHIFT;
|
||||
/* Burst read */
|
||||
reg_value |= (uint32_t)(config->burstRead) << FB_CSCR_BSTR_SHIFT;
|
||||
/* Byte-enable mode */
|
||||
reg_value |= (uint32_t)(config->byteEnableMode) << FB_CSCR_BEM_SHIFT;
|
||||
/* Port size */
|
||||
reg_value |= (uint32_t)config->portSize << FB_CSCR_PS_SHIFT;
|
||||
/* The internal transfer acknowledge for accesses */
|
||||
reg_value |= (uint32_t)(config->autoAcknowledge) << FB_CSCR_AA_SHIFT;
|
||||
/* Byte-Lane shift */
|
||||
reg_value |= (uint32_t)config->byteLaneShift << FB_CSCR_BLS_SHIFT;
|
||||
/* The number of wait states */
|
||||
reg_value |= (uint32_t)config->waitStates << FB_CSCR_WS_SHIFT;
|
||||
/* Write address hold or deselect */
|
||||
reg_value |= (uint32_t)config->writeAddressHold << FB_CSCR_WRAH_SHIFT;
|
||||
/* Read address hold or deselect */
|
||||
reg_value |= (uint32_t)config->readAddressHold << FB_CSCR_RDAH_SHIFT;
|
||||
/* Address setup */
|
||||
reg_value |= (uint32_t)config->addressSetup << FB_CSCR_ASET_SHIFT;
|
||||
/* Extended transfer start/extended address latch */
|
||||
reg_value |= (uint32_t)(config->extendTransferAddress) << FB_CSCR_EXTS_SHIFT;
|
||||
/* Secondary wait state */
|
||||
reg_value |= (uint32_t)(config->secondaryWaitStates) << FB_CSCR_SWSEN_SHIFT;
|
||||
/* Write to CSCR register */
|
||||
base->CS[chip].CSCR = reg_value;
|
||||
/* FlexBus signal group 1 multiplex control */
|
||||
reg_value = (uint32_t)config->group1MultiplexControl << FB_CSPMCR_GROUP1_SHIFT;
|
||||
/* FlexBus signal group 2 multiplex control */
|
||||
reg_value |= (uint32_t)config->group2MultiplexControl << FB_CSPMCR_GROUP2_SHIFT;
|
||||
/* FlexBus signal group 3 multiplex control */
|
||||
reg_value |= (uint32_t)config->group3MultiplexControl << FB_CSPMCR_GROUP3_SHIFT;
|
||||
/* FlexBus signal group 4 multiplex control */
|
||||
reg_value |= (uint32_t)config->group4MultiplexControl << FB_CSPMCR_GROUP4_SHIFT;
|
||||
/* FlexBus signal group 5 multiplex control */
|
||||
reg_value |= (uint32_t)config->group5MultiplexControl << FB_CSPMCR_GROUP5_SHIFT;
|
||||
/* Write to CSPMCR register */
|
||||
base->CSPMCR = reg_value;
|
||||
}
|
||||
|
||||
void FLEXBUS_Deinit(FB_Type *base)
|
||||
{
|
||||
/* Gate clock for FLEXBUS */
|
||||
CLOCK_EnableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]);
|
||||
}
|
||||
|
||||
void FLEXBUS_GetDefaultConfig(flexbus_config_t *config)
|
||||
{
|
||||
config->chip = 0; /* Chip 0 FlexBus for validation */
|
||||
config->writeProtect = 0; /* Write accesses are allowed */
|
||||
config->burstWrite = 0; /* Burst-Write disable */
|
||||
config->burstRead = 0; /* Burst-Read disable */
|
||||
config->byteEnableMode = 0; /* Byte-Enable mode is asserted for data write only */
|
||||
config->autoAcknowledge = true; /* Auto-Acknowledge enable */
|
||||
config->extendTransferAddress = 0; /* Extend transfer start/extend address latch disable */
|
||||
config->secondaryWaitStates = 0; /* Secondary wait state disable */
|
||||
config->byteLaneShift = kFLEXBUS_NotShifted; /* Byte-Lane shift disable */
|
||||
config->writeAddressHold = kFLEXBUS_Hold1Cycle; /* Write address hold 1 cycles */
|
||||
config->readAddressHold = kFLEXBUS_Hold1Or0Cycles; /* Read address hold 0 cycles */
|
||||
config->addressSetup =
|
||||
kFLEXBUS_FirstRisingEdge; /* Assert ~FB_CSn on the first rising clock edge after the address is asserted */
|
||||
config->portSize = kFLEXBUS_1Byte; /* 1 byte port size of transfer */
|
||||
config->group1MultiplexControl = kFLEXBUS_MultiplexGroup1_FB_ALE; /* FB_ALE */
|
||||
config->group2MultiplexControl = kFLEXBUS_MultiplexGroup2_FB_CS4; /* FB_CS4 */
|
||||
config->group3MultiplexControl = kFLEXBUS_MultiplexGroup3_FB_CS5; /* FB_CS5 */
|
||||
config->group4MultiplexControl = kFLEXBUS_MultiplexGroup4_FB_TBST; /* FB_TBST */
|
||||
config->group5MultiplexControl = kFLEXBUS_MultiplexGroup5_FB_TA; /* FB_TA */
|
||||
}
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FSL_FLEXBUS_H_
|
||||
#define _FSL_FLEXBUS_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup flexbus
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
#define FSL_FLEXBUS_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief Defines port size for FlexBus peripheral.
|
||||
*/
|
||||
typedef enum _flexbus_port_size
|
||||
{
|
||||
kFLEXBUS_4Bytes = 0x00U, /*!< 32-bit port size */
|
||||
kFLEXBUS_1Byte = 0x01U, /*!< 8-bit port size */
|
||||
kFLEXBUS_2Bytes = 0x02U /*!< 16-bit port size */
|
||||
} flexbus_port_size_t;
|
||||
|
||||
/*!
|
||||
* @brief Defines number of cycles to hold address and attributes for FlexBus peripheral.
|
||||
*/
|
||||
typedef enum _flexbus_write_address_hold
|
||||
{
|
||||
kFLEXBUS_Hold1Cycle = 0x00U, /*!< Hold address and attributes one cycles after FB_CSn negates on writes */
|
||||
kFLEXBUS_Hold2Cycles = 0x01U, /*!< Hold address and attributes two cycles after FB_CSn negates on writes */
|
||||
kFLEXBUS_Hold3Cycles = 0x02U, /*!< Hold address and attributes three cycles after FB_CSn negates on writes */
|
||||
kFLEXBUS_Hold4Cycles = 0x03U /*!< Hold address and attributes four cycles after FB_CSn negates on writes */
|
||||
} flexbus_write_address_hold_t;
|
||||
|
||||
/*!
|
||||
* @brief Defines number of cycles to hold address and attributes for FlexBus peripheral.
|
||||
*/
|
||||
typedef enum _flexbus_read_address_hold
|
||||
{
|
||||
kFLEXBUS_Hold1Or0Cycles = 0x00U, /*!< Hold address and attributes 1 or 0 cycles on reads */
|
||||
kFLEXBUS_Hold2Or1Cycles = 0x01U, /*!< Hold address and attributes 2 or 1 cycles on reads */
|
||||
kFLEXBUS_Hold3Or2Cycle = 0x02U, /*!< Hold address and attributes 3 or 2 cycles on reads */
|
||||
kFLEXBUS_Hold4Or3Cycle = 0x03U /*!< Hold address and attributes 4 or 3 cycles on reads */
|
||||
} flexbus_read_address_hold_t;
|
||||
|
||||
/*!
|
||||
* @brief Address setup for FlexBus peripheral.
|
||||
*/
|
||||
typedef enum _flexbus_address_setup
|
||||
{
|
||||
kFLEXBUS_FirstRisingEdge = 0x00U, /*!< Assert FB_CSn on first rising clock edge after address is asserted */
|
||||
kFLEXBUS_SecondRisingEdge = 0x01U, /*!< Assert FB_CSn on second rising clock edge after address is asserted */
|
||||
kFLEXBUS_ThirdRisingEdge = 0x02U, /*!< Assert FB_CSn on third rising clock edge after address is asserted */
|
||||
kFLEXBUS_FourthRisingEdge = 0x03U, /*!< Assert FB_CSn on fourth rising clock edge after address is asserted */
|
||||
} flexbus_address_setup_t;
|
||||
|
||||
/*!
|
||||
* @brief Defines byte-lane shift for FlexBus peripheral.
|
||||
*/
|
||||
typedef enum _flexbus_bytelane_shift
|
||||
{
|
||||
kFLEXBUS_NotShifted = 0x00U, /*!< Not shifted. Data is left-justified on FB_AD */
|
||||
kFLEXBUS_Shifted = 0x01U, /*!< Shifted. Data is right justified on FB_AD */
|
||||
} flexbus_bytelane_shift_t;
|
||||
|
||||
/*!
|
||||
* @brief Defines multiplex group1 valid signals.
|
||||
*/
|
||||
typedef enum _flexbus_multiplex_group1_signal
|
||||
{
|
||||
kFLEXBUS_MultiplexGroup1_FB_ALE = 0x00U, /*!< FB_ALE */
|
||||
kFLEXBUS_MultiplexGroup1_FB_CS1 = 0x01U, /*!< FB_CS1 */
|
||||
kFLEXBUS_MultiplexGroup1_FB_TS = 0x02U, /*!< FB_TS */
|
||||
} flexbus_multiplex_group1_t;
|
||||
|
||||
/*!
|
||||
* @brief Defines multiplex group2 valid signals.
|
||||
*/
|
||||
typedef enum _flexbus_multiplex_group2_signal
|
||||
{
|
||||
kFLEXBUS_MultiplexGroup2_FB_CS4 = 0x00U, /*!< FB_CS4 */
|
||||
kFLEXBUS_MultiplexGroup2_FB_TSIZ0 = 0x01U, /*!< FB_TSIZ0 */
|
||||
kFLEXBUS_MultiplexGroup2_FB_BE_31_24 = 0x02U, /*!< FB_BE_31_24 */
|
||||
} flexbus_multiplex_group2_t;
|
||||
|
||||
/*!
|
||||
* @brief Defines multiplex group3 valid signals.
|
||||
*/
|
||||
typedef enum _flexbus_multiplex_group3_signal
|
||||
{
|
||||
kFLEXBUS_MultiplexGroup3_FB_CS5 = 0x00U, /*!< FB_CS5 */
|
||||
kFLEXBUS_MultiplexGroup3_FB_TSIZ1 = 0x01U, /*!< FB_TSIZ1 */
|
||||
kFLEXBUS_MultiplexGroup3_FB_BE_23_16 = 0x02U, /*!< FB_BE_23_16 */
|
||||
} flexbus_multiplex_group3_t;
|
||||
|
||||
/*!
|
||||
* @brief Defines multiplex group4 valid signals.
|
||||
*/
|
||||
typedef enum _flexbus_multiplex_group4_signal
|
||||
{
|
||||
kFLEXBUS_MultiplexGroup4_FB_TBST = 0x00U, /*!< FB_TBST */
|
||||
kFLEXBUS_MultiplexGroup4_FB_CS2 = 0x01U, /*!< FB_CS2 */
|
||||
kFLEXBUS_MultiplexGroup4_FB_BE_15_8 = 0x02U, /*!< FB_BE_15_8 */
|
||||
} flexbus_multiplex_group4_t;
|
||||
|
||||
/*!
|
||||
* @brief Defines multiplex group5 valid signals.
|
||||
*/
|
||||
typedef enum _flexbus_multiplex_group5_signal
|
||||
{
|
||||
kFLEXBUS_MultiplexGroup5_FB_TA = 0x00U, /*!< FB_TA */
|
||||
kFLEXBUS_MultiplexGroup5_FB_CS3 = 0x01U, /*!< FB_CS3 */
|
||||
kFLEXBUS_MultiplexGroup5_FB_BE_7_0 = 0x02U, /*!< FB_BE_7_0 */
|
||||
} flexbus_multiplex_group5_t;
|
||||
|
||||
/*!
|
||||
* @brief Configuration structure that the user needs to set.
|
||||
*/
|
||||
typedef struct _flexbus_config
|
||||
{
|
||||
uint8_t chip; /*!< Chip FlexBus for validation */
|
||||
uint8_t waitStates; /*!< Value of wait states */
|
||||
uint32_t chipBaseAddress; /*!< Chip base address for using FlexBus */
|
||||
uint32_t chipBaseAddressMask; /*!< Chip base address mask */
|
||||
bool writeProtect; /*!< Write protected */
|
||||
bool burstWrite; /*!< Burst-Write enable */
|
||||
bool burstRead; /*!< Burst-Read enable */
|
||||
bool byteEnableMode; /*!< Byte-enable mode support */
|
||||
bool autoAcknowledge; /*!< Auto acknowledge setting */
|
||||
bool extendTransferAddress; /*!< Extend transfer start/extend address latch enable */
|
||||
bool secondaryWaitStates; /*!< Secondary wait states number */
|
||||
flexbus_port_size_t portSize; /*!< Port size of transfer */
|
||||
flexbus_bytelane_shift_t byteLaneShift; /*!< Byte-lane shift enable */
|
||||
flexbus_write_address_hold_t writeAddressHold; /*!< Write address hold or deselect option */
|
||||
flexbus_read_address_hold_t readAddressHold; /*!< Read address hold or deselect option */
|
||||
flexbus_address_setup_t addressSetup; /*!< Address setup setting */
|
||||
flexbus_multiplex_group1_t group1MultiplexControl; /*!< FlexBus Signal Group 1 Multiplex control */
|
||||
flexbus_multiplex_group2_t group2MultiplexControl; /*!< FlexBus Signal Group 2 Multiplex control */
|
||||
flexbus_multiplex_group3_t group3MultiplexControl; /*!< FlexBus Signal Group 3 Multiplex control */
|
||||
flexbus_multiplex_group4_t group4MultiplexControl; /*!< FlexBus Signal Group 4 Multiplex control */
|
||||
flexbus_multiplex_group5_t group5MultiplexControl; /*!< FlexBus Signal Group 5 Multiplex control */
|
||||
} flexbus_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*!
|
||||
* @name FlexBus functional operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes and configures the 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.
|
||||
* NOTE: In this function, certain parameters, depending on external memories, must
|
||||
* be set before using FLEXBUS_Init() function.
|
||||
* 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
|
||||
* in these parameters:
|
||||
@code
|
||||
flexbus_config_t flexbusConfig;
|
||||
FLEXBUS_GetDefaultConfig(&flexbusConfig);
|
||||
flexbusConfig.waitStates = 2U;
|
||||
flexbusConfig.chipBaseAddress = 0x60000000U;
|
||||
flexbusConfig.chipBaseAddressMask = 7U;
|
||||
FLEXBUS_Init(FB, &flexbusConfig);
|
||||
@endcode
|
||||
*
|
||||
* @param base FlexBus peripheral address.
|
||||
* @param config Pointer to the configure structure
|
||||
*/
|
||||
void FLEXBUS_Init(FB_Type *base, const flexbus_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief De-initializes a FlexBus instance.
|
||||
*
|
||||
* This function disables the clock gate of the FlexBus module clock.
|
||||
*
|
||||
* @param base FlexBus peripheral address.
|
||||
*/
|
||||
void FLEXBUS_Deinit(FB_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the FlexBus configuration structure.
|
||||
*
|
||||
* This function initializes the FlexBus configuration structure to default value. The default
|
||||
* values are:
|
||||
@code
|
||||
fbConfig->chip = 0;
|
||||
fbConfig->writeProtect = 0;
|
||||
fbConfig->burstWrite = 0;
|
||||
fbConfig->burstRead = 0;
|
||||
fbConfig->byteEnableMode = 0;
|
||||
fbConfig->autoAcknowledge = true;
|
||||
fbConfig->extendTransferAddress = 0;
|
||||
fbConfig->secondaryWaitStates = 0;
|
||||
fbConfig->byteLaneShift = kFLEXBUS_NotShifted;
|
||||
fbConfig->writeAddressHold = kFLEXBUS_Hold1Cycle;
|
||||
fbConfig->readAddressHold = kFLEXBUS_Hold1Or0Cycles;
|
||||
fbConfig->addressSetup = kFLEXBUS_FirstRisingEdge;
|
||||
fbConfig->portSize = kFLEXBUS_1Byte;
|
||||
fbConfig->group1MultiplexControl = kFLEXBUS_MultiplexGroup1_FB_ALE;
|
||||
fbConfig->group2MultiplexControl = kFLEXBUS_MultiplexGroup2_FB_CS4 ;
|
||||
fbConfig->group3MultiplexControl = kFLEXBUS_MultiplexGroup3_FB_CS5;
|
||||
fbConfig->group4MultiplexControl = kFLEXBUS_MultiplexGroup4_FB_TBST;
|
||||
fbConfig->group5MultiplexControl = kFLEXBUS_MultiplexGroup5_FB_TA;
|
||||
@endcode
|
||||
* @param config Pointer to the initialization structure.
|
||||
* @see FLEXBUS_Init
|
||||
*/
|
||||
void FLEXBUS_GetDefaultConfig(flexbus_config_t *config);
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_FLEXBUS_H_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_flexcan_edma.h"
|
||||
#include "fsl_dmamux.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitons
|
||||
******************************************************************************/
|
||||
|
||||
/*<! Structure definition for flexcan_edma_private_handle_t. The structure is private. */
|
||||
typedef struct _flexcan_edma_private_handle
|
||||
{
|
||||
CAN_Type *base;
|
||||
flexcan_edma_handle_t *handle;
|
||||
} flexcan_edma_private_handle_t;
|
||||
|
||||
/* FlexCAN EDMA transfer handle. */
|
||||
enum _flexcan_edma_tansfer_state
|
||||
{
|
||||
KFLEXCAN_RxFifoIdle = 0U, /* Rx Fifo idle. */
|
||||
KFLEXCAN_RxFifoBusy = 1U, /* Rx Fifo busy. */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*<! Private handle only used for internally. */
|
||||
static flexcan_edma_private_handle_t s_edmaPrivateHandle[FSL_FEATURE_SOC_FLEXCAN_COUNT];
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief FlexCAN EDMA receive finished callback function.
|
||||
*
|
||||
* This function is called when FlexCAN Rx FIFO EDMA receive finished.
|
||||
* It disables the FlexCAN Rx FIFO EDMA request and sends
|
||||
* @ref kStatus_FLEXCAN_RxFifoIdle to FlexCAN EDMA callback.
|
||||
*
|
||||
* @param handle The EDMA handle.
|
||||
* @param param Callback function parameter.
|
||||
*/
|
||||
static void FLEXCAN_ReceiveFifoEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
|
||||
|
||||
/*!
|
||||
* @brief Get the FlexCAN instance from peripheral base address.
|
||||
*
|
||||
* @param base FlexCAN peripheral base address.
|
||||
* @return FlexCAN instance.
|
||||
*/
|
||||
extern uint32_t FLEXCAN_GetInstance(CAN_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
static void FLEXCAN_ReceiveFifoEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
|
||||
{
|
||||
handle = handle;
|
||||
tcds = tcds;
|
||||
|
||||
flexcan_edma_private_handle_t *flexcanPrivateHandle = (flexcan_edma_private_handle_t *)param;
|
||||
|
||||
if (transferDone)
|
||||
{
|
||||
/* Disable transfer. */
|
||||
FLEXCAN_TransferAbortReceiveFifoEDMA(flexcanPrivateHandle->base, flexcanPrivateHandle->handle);
|
||||
|
||||
if (flexcanPrivateHandle->handle->callback)
|
||||
{
|
||||
flexcanPrivateHandle->handle->callback(flexcanPrivateHandle->base, flexcanPrivateHandle->handle,
|
||||
kStatus_FLEXCAN_RxFifoIdle, flexcanPrivateHandle->handle->userData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FLEXCAN_TransferCreateHandleEDMA(CAN_Type *base,
|
||||
flexcan_edma_handle_t *handle,
|
||||
flexcan_edma_transfer_callback_t callback,
|
||||
void *userData,
|
||||
edma_handle_t *rxFifoEdmaHandle)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
uint32_t instance = FLEXCAN_GetInstance(base);
|
||||
s_edmaPrivateHandle[instance].base = base;
|
||||
s_edmaPrivateHandle[instance].handle = handle;
|
||||
|
||||
memset(handle, 0, sizeof(flexcan_edma_handle_t));
|
||||
|
||||
handle->rxFifoState = KFLEXCAN_RxFifoIdle;
|
||||
handle->rxFifoEdmaHandle = rxFifoEdmaHandle;
|
||||
|
||||
/* Register Callback. */
|
||||
handle->callback = callback;
|
||||
handle->userData = userData;
|
||||
|
||||
/* Configure Rx FIFO DMA. */
|
||||
EDMA_SetCallback(handle->rxFifoEdmaHandle, FLEXCAN_ReceiveFifoEDMACallback, &s_edmaPrivateHandle[instance]);
|
||||
}
|
||||
|
||||
status_t FLEXCAN_TransferReceiveFifoEDMA(CAN_Type *base, flexcan_edma_handle_t *handle, flexcan_fifo_transfer_t *xfer)
|
||||
{
|
||||
assert(handle->rxFifoEdmaHandle);
|
||||
|
||||
edma_transfer_config_t dmaXferConfig;
|
||||
status_t status;
|
||||
|
||||
/* If previous Rx FIFO receive not finished. */
|
||||
if (KFLEXCAN_RxFifoBusy == handle->rxFifoState)
|
||||
{
|
||||
status = kStatus_FLEXCAN_RxFifoBusy;
|
||||
}
|
||||
else
|
||||
{
|
||||
handle->rxFifoState = KFLEXCAN_RxFifoBusy;
|
||||
|
||||
/* Prepare transfer. */
|
||||
EDMA_PrepareTransfer(&dmaXferConfig, (void *)FLEXCAN_GetRxFifoHeadAddr(base), sizeof(flexcan_frame_t),
|
||||
(void *)xfer->frame, sizeof(uint32_t), sizeof(flexcan_frame_t), sizeof(flexcan_frame_t),
|
||||
kEDMA_PeripheralToMemory);
|
||||
/* Submit transfer. */
|
||||
EDMA_SubmitTransfer(handle->rxFifoEdmaHandle, &dmaXferConfig);
|
||||
EDMA_StartTransfer(handle->rxFifoEdmaHandle);
|
||||
|
||||
/* Enable FlexCAN Rx FIFO EDMA. */
|
||||
FLEXCAN_EnableRxFifoDMA(base, true);
|
||||
|
||||
status = kStatus_Success;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void FLEXCAN_TransferAbortReceiveFifoEDMA(CAN_Type *base, flexcan_edma_handle_t *handle)
|
||||
{
|
||||
assert(handle->rxFifoEdmaHandle);
|
||||
|
||||
/* Disable FlexCAN Rx FIFO EDMA. */
|
||||
FLEXCAN_EnableRxFifoDMA(base, false);
|
||||
|
||||
/* Stop transfer. */
|
||||
EDMA_AbortTransfer(handle->rxFifoEdmaHandle);
|
||||
|
||||
handle->rxFifoState = KFLEXCAN_RxFifoIdle;
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_FLEXCAN_EDMA_H_
|
||||
#define _FSL_FLEXCAN_EDMA_H_
|
||||
|
||||
#include "fsl_flexcan.h"
|
||||
#include "fsl_dmamux.h"
|
||||
#include "fsl_edma.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup flexcan_edma_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* Forward declaration of the handle typedef. */
|
||||
typedef struct _flexcan_edma_handle flexcan_edma_handle_t;
|
||||
|
||||
/*! @brief FlexCAN transfer callback function. */
|
||||
typedef void (*flexcan_edma_transfer_callback_t)(CAN_Type *base,
|
||||
flexcan_edma_handle_t *handle,
|
||||
status_t status,
|
||||
void *userData);
|
||||
|
||||
/*!
|
||||
* @brief FlexCAN eDMA handle
|
||||
*/
|
||||
struct _flexcan_edma_handle
|
||||
{
|
||||
flexcan_edma_transfer_callback_t callback; /*!< Callback function. */
|
||||
void *userData; /*!< FlexCAN callback function parameter.*/
|
||||
edma_handle_t *rxFifoEdmaHandle; /*!< The EDMA Rx FIFO channel used. */
|
||||
volatile uint8_t rxFifoState; /*!< Rx FIFO transfer state. */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name eDMA transactional
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the FlexCAN handle, which is used in transactional functions.
|
||||
*
|
||||
* @param base FlexCAN peripheral base address.
|
||||
* @param handle Pointer to flexcan_edma_handle_t structure.
|
||||
* @param callback The callback function.
|
||||
* @param userData The parameter of the callback function.
|
||||
* @param rxFifoEdmaHandle User-requested DMA handle for Rx FIFO DMA transfer.
|
||||
*/
|
||||
void FLEXCAN_TransferCreateHandleEDMA(CAN_Type *base,
|
||||
flexcan_edma_handle_t *handle,
|
||||
flexcan_edma_transfer_callback_t callback,
|
||||
void *userData,
|
||||
edma_handle_t *rxFifoEdmaHandle);
|
||||
|
||||
/*!
|
||||
* @brief Receives the CAN Message from the Rx FIFO using eDMA.
|
||||
*
|
||||
* This function receives the CAN Message using eDMA. This is a non-blocking function, which returns
|
||||
* right away. After the CAN Message is received, the receive callback function is called.
|
||||
*
|
||||
* @param base FlexCAN peripheral base address.
|
||||
* @param handle Pointer to flexcan_edma_handle_t structure.
|
||||
* @param xfer FlexCAN Rx FIFO EDMA transfer structure, see #flexcan_fifo_transfer_t.
|
||||
* @retval kStatus_Success if succeed, others failed.
|
||||
* @retval kStatus_FLEXCAN_RxFifoBusy Previous transfer ongoing.
|
||||
*/
|
||||
status_t FLEXCAN_TransferReceiveFifoEDMA(CAN_Type *base, flexcan_edma_handle_t *handle, flexcan_fifo_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Aborts the receive process which used eDMA.
|
||||
*
|
||||
* This function aborts the receive process which used eDMA.
|
||||
*
|
||||
* @param base FlexCAN peripheral base address.
|
||||
* @param handle Pointer to flexcan_edma_handle_t structure.
|
||||
*/
|
||||
void FLEXCAN_TransferAbortReceiveFifoEDMA(CAN_Type *base, flexcan_edma_handle_t *handle);
|
||||
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_FLEXCAN_EDMA_H_ */
|
|
@ -0,0 +1,876 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_ftm.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Gets the instance from the base address
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
*
|
||||
* @return The FTM instance
|
||||
*/
|
||||
static uint32_t FTM_GetInstance(FTM_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Sets the FTM register PWM synchronization method
|
||||
*
|
||||
* This function will set the necessary bits for the PWM synchronization mode that
|
||||
* user wishes to use.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param syncMethod Syncronization methods to use to update buffered registers. This is a logical
|
||||
* OR of members of the enumeration ::ftm_pwm_sync_method_t
|
||||
*/
|
||||
static void FTM_SetPwmSync(FTM_Type *base, uint32_t syncMethod);
|
||||
|
||||
/*!
|
||||
* @brief Sets the reload points used as loading points for register update
|
||||
*
|
||||
* This function will set the necessary bits based on what the user wishes to use as loading
|
||||
* points for FTM register update. When using this it is not required to use PWM synchnronization.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param reloadPoints FTM reload points. This is a logical OR of members of the
|
||||
* enumeration ::ftm_reload_point_t
|
||||
*/
|
||||
static void FTM_SetReloadPoints(FTM_Type *base, uint32_t reloadPoints);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/*! @brief Pointers to FTM bases for each instance. */
|
||||
static FTM_Type *const s_ftmBases[] = FTM_BASE_PTRS;
|
||||
|
||||
/*! @brief Pointers to FTM clocks for each instance. */
|
||||
static const clock_ip_name_t s_ftmClocks[] = FTM_CLOCKS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static uint32_t FTM_GetInstance(FTM_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
uint32_t ftmArrayCount = (sizeof(s_ftmBases) / sizeof(s_ftmBases[0]));
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < ftmArrayCount; instance++)
|
||||
{
|
||||
if (s_ftmBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < ftmArrayCount);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void FTM_SetPwmSync(FTM_Type *base, uint32_t syncMethod)
|
||||
{
|
||||
uint8_t chnlNumber = 0;
|
||||
uint32_t reg = 0, syncReg = 0;
|
||||
|
||||
syncReg = base->SYNC;
|
||||
/* Enable PWM synchronization of output mask register */
|
||||
syncReg |= FTM_SYNC_SYNCHOM_MASK;
|
||||
|
||||
reg = base->COMBINE;
|
||||
for (chnlNumber = 0; chnlNumber < (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2); chnlNumber++)
|
||||
{
|
||||
/* Enable PWM synchronization of registers C(n)V and C(n+1)V */
|
||||
reg |= (1U << (FTM_COMBINE_SYNCEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlNumber)));
|
||||
}
|
||||
base->COMBINE = reg;
|
||||
|
||||
reg = base->SYNCONF;
|
||||
|
||||
/* Use enhanced PWM synchronization method. Use PWM sync to update register values */
|
||||
reg |= (FTM_SYNCONF_SYNCMODE_MASK | FTM_SYNCONF_CNTINC_MASK | FTM_SYNCONF_INVC_MASK | FTM_SYNCONF_SWOC_MASK);
|
||||
|
||||
if (syncMethod & FTM_SYNC_SWSYNC_MASK)
|
||||
{
|
||||
/* Enable needed bits for software trigger to update registers with its buffer value */
|
||||
reg |= (FTM_SYNCONF_SWRSTCNT_MASK | FTM_SYNCONF_SWWRBUF_MASK | FTM_SYNCONF_SWINVC_MASK |
|
||||
FTM_SYNCONF_SWSOC_MASK | FTM_SYNCONF_SWOM_MASK);
|
||||
}
|
||||
|
||||
if (syncMethod & (FTM_SYNC_TRIG0_MASK | FTM_SYNC_TRIG1_MASK | FTM_SYNC_TRIG2_MASK))
|
||||
{
|
||||
/* Enable needed bits for hardware trigger to update registers with its buffer value */
|
||||
reg |= (FTM_SYNCONF_HWRSTCNT_MASK | FTM_SYNCONF_HWWRBUF_MASK | FTM_SYNCONF_HWINVC_MASK |
|
||||
FTM_SYNCONF_HWSOC_MASK | FTM_SYNCONF_HWOM_MASK);
|
||||
|
||||
/* Enable the appropriate hardware trigger that is used for PWM sync */
|
||||
if (syncMethod & FTM_SYNC_TRIG0_MASK)
|
||||
{
|
||||
syncReg |= FTM_SYNC_TRIG0_MASK;
|
||||
}
|
||||
if (syncMethod & FTM_SYNC_TRIG1_MASK)
|
||||
{
|
||||
syncReg |= FTM_SYNC_TRIG1_MASK;
|
||||
}
|
||||
if (syncMethod & FTM_SYNC_TRIG2_MASK)
|
||||
{
|
||||
syncReg |= FTM_SYNC_TRIG2_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write back values to the SYNC register */
|
||||
base->SYNC = syncReg;
|
||||
|
||||
/* Write the PWM synch values to the SYNCONF register */
|
||||
base->SYNCONF = reg;
|
||||
}
|
||||
|
||||
static void FTM_SetReloadPoints(FTM_Type *base, uint32_t reloadPoints)
|
||||
{
|
||||
uint32_t chnlNumber = 0;
|
||||
uint32_t reg = 0;
|
||||
|
||||
/* Need CNTINC bit to be 1 for CNTIN register to update with its buffer value on reload */
|
||||
base->SYNCONF |= FTM_SYNCONF_CNTINC_MASK;
|
||||
|
||||
reg = base->COMBINE;
|
||||
for (chnlNumber = 0; chnlNumber < (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2); chnlNumber++)
|
||||
{
|
||||
/* Need SYNCEN bit to be 1 for CnV reg to update with its buffer value on reload */
|
||||
reg |= (1U << (FTM_COMBINE_SYNCEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlNumber)));
|
||||
}
|
||||
base->COMBINE = reg;
|
||||
|
||||
/* Set the reload points */
|
||||
reg = base->PWMLOAD;
|
||||
|
||||
/* Enable the selected channel match reload points */
|
||||
reg &= ~((1U << FSL_FEATURE_FTM_CHANNEL_COUNTn(base)) - 1);
|
||||
reg |= (reloadPoints & ((1U << FSL_FEATURE_FTM_CHANNEL_COUNTn(base)) - 1));
|
||||
|
||||
#if defined(FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD) && (FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD)
|
||||
/* Enable half cycle match as a reload point */
|
||||
if (reloadPoints & kFTM_HalfCycMatch)
|
||||
{
|
||||
reg |= FTM_PWMLOAD_HCSEL_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg &= ~FTM_PWMLOAD_HCSEL_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD */
|
||||
|
||||
base->PWMLOAD = reg;
|
||||
|
||||
/* These reload points are used when counter is in up-down counting mode */
|
||||
reg = base->SYNC;
|
||||
if (reloadPoints & kFTM_CntMax)
|
||||
{
|
||||
/* Reload when counter turns from up to down */
|
||||
reg |= FTM_SYNC_CNTMAX_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg &= ~FTM_SYNC_CNTMAX_MASK;
|
||||
}
|
||||
|
||||
if (reloadPoints & kFTM_CntMin)
|
||||
{
|
||||
/* Reload when counter turns from down to up */
|
||||
reg |= FTM_SYNC_CNTMIN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg &= ~FTM_SYNC_CNTMIN_MASK;
|
||||
}
|
||||
base->SYNC = reg;
|
||||
}
|
||||
|
||||
status_t FTM_Init(FTM_Type *base, const ftm_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
uint32_t reg;
|
||||
|
||||
if (!(config->pwmSyncMode &
|
||||
(FTM_SYNC_TRIG0_MASK | FTM_SYNC_TRIG1_MASK | FTM_SYNC_TRIG2_MASK | FTM_SYNC_SWSYNC_MASK)))
|
||||
{
|
||||
/* Invalid PWM sync mode */
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
/* Ungate the FTM clock*/
|
||||
CLOCK_EnableClock(s_ftmClocks[FTM_GetInstance(base)]);
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Configure the update mechanism for buffered registers */
|
||||
FTM_SetPwmSync(base, config->pwmSyncMode);
|
||||
|
||||
if (config->reloadPoints)
|
||||
{
|
||||
/* Setup intermediate register reload points */
|
||||
FTM_SetReloadPoints(base, config->reloadPoints);
|
||||
}
|
||||
|
||||
/* Set the clock prescale factor */
|
||||
base->SC = FTM_SC_PS(config->prescale);
|
||||
|
||||
/* Setup the counter operation */
|
||||
base->CONF = (FTM_CONF_BDMMODE(config->bdmMode) | FTM_CONF_GTBEEN(config->useGlobalTimeBase));
|
||||
|
||||
/* Initial state of channel output */
|
||||
base->OUTINIT = config->chnlInitState;
|
||||
|
||||
/* Channel polarity */
|
||||
base->POL = config->chnlPolarity;
|
||||
|
||||
/* Set the external trigger sources */
|
||||
base->EXTTRIG = config->extTriggers;
|
||||
#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER) && (FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER)
|
||||
if (config->extTriggers & kFTM_ReloadInitTrigger)
|
||||
{
|
||||
base->CONF |= FTM_CONF_ITRIGR_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CONF &= ~FTM_CONF_ITRIGR_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER */
|
||||
|
||||
/* FTM deadtime insertion control */
|
||||
base->DEADTIME = (FTM_DEADTIME_DTPS(config->deadTimePrescale) | FTM_DEADTIME_DTVAL(config->deadTimeValue));
|
||||
|
||||
/* FTM fault filter value */
|
||||
reg = base->FLTCTRL;
|
||||
reg &= ~FTM_FLTCTRL_FFVAL_MASK;
|
||||
reg |= FTM_FLTCTRL_FFVAL(config->faultFilterValue);
|
||||
base->FLTCTRL = reg;
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
void FTM_Deinit(FTM_Type *base)
|
||||
{
|
||||
/* Set clock source to none to disable counter */
|
||||
base->SC &= ~(FTM_SC_CLKS_MASK);
|
||||
|
||||
/* Gate the FTM clock */
|
||||
CLOCK_DisableClock(s_ftmClocks[FTM_GetInstance(base)]);
|
||||
}
|
||||
|
||||
void FTM_GetDefaultConfig(ftm_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
/* Divide FTM clock by 1 */
|
||||
config->prescale = kFTM_Prescale_Divide_1;
|
||||
/* FTM behavior in BDM mode */
|
||||
config->bdmMode = kFTM_BdmMode_0;
|
||||
/* Software trigger will be used to update registers */
|
||||
config->pwmSyncMode = kFTM_SoftwareTrigger;
|
||||
/* No intermediate register load */
|
||||
config->reloadPoints = 0;
|
||||
/* Fault control disabled for all channels */
|
||||
config->faultMode = kFTM_Fault_Disable;
|
||||
/* Disable the fault filter */
|
||||
config->faultFilterValue = 0;
|
||||
/* Divide the system clock by 1 */
|
||||
config->deadTimePrescale = kFTM_Deadtime_Prescale_1;
|
||||
/* No counts are inserted */
|
||||
config->deadTimeValue = 0;
|
||||
/* No external trigger */
|
||||
config->extTriggers = 0;
|
||||
/* Initialization value is 0 for all channels */
|
||||
config->chnlInitState = 0;
|
||||
/* Active high polarity for all channels */
|
||||
config->chnlPolarity = 0;
|
||||
/* Use internal FTM counter as timebase */
|
||||
config->useGlobalTimeBase = false;
|
||||
}
|
||||
|
||||
status_t FTM_SetupPwm(FTM_Type *base,
|
||||
const ftm_chnl_pwm_signal_param_t *chnlParams,
|
||||
uint8_t numOfChnls,
|
||||
ftm_pwm_mode_t mode,
|
||||
uint32_t pwmFreq_Hz,
|
||||
uint32_t srcClock_Hz)
|
||||
{
|
||||
assert(chnlParams);
|
||||
|
||||
uint32_t mod, reg;
|
||||
uint32_t ftmClock = (srcClock_Hz / (1U << (base->SC & FTM_SC_PS_MASK)));
|
||||
uint16_t cnv, cnvFirstEdge;
|
||||
uint8_t i;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case kFTM_EdgeAlignedPwm:
|
||||
case kFTM_CombinedPwm:
|
||||
base->SC &= ~FTM_SC_CPWMS_MASK;
|
||||
mod = (ftmClock / pwmFreq_Hz) - 1;
|
||||
break;
|
||||
case kFTM_CenterAlignedPwm:
|
||||
base->SC |= FTM_SC_CPWMS_MASK;
|
||||
mod = ftmClock / (pwmFreq_Hz * 2);
|
||||
break;
|
||||
default:
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
/* Return an error in case we overflow the registers, probably would require changing
|
||||
* clock source to get the desired frequency */
|
||||
if (mod > 65535U)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
/* Set the PWM period */
|
||||
base->MOD = mod;
|
||||
|
||||
/* Setup each FTM channel */
|
||||
for (i = 0; i < numOfChnls; i++)
|
||||
{
|
||||
/* Return error if requested dutycycle is greater than the max allowed */
|
||||
if (chnlParams->dutyCyclePercent > 100)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
if ((mode == kFTM_EdgeAlignedPwm) || (mode == kFTM_CenterAlignedPwm))
|
||||
{
|
||||
/* Clear the current mode and edge level bits */
|
||||
reg = base->CONTROLS[chnlParams->chnlNumber].CnSC;
|
||||
reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
|
||||
|
||||
/* Setup the active level */
|
||||
reg |= (FTM_CnSC_ELSA(chnlParams->level) | FTM_CnSC_ELSB(chnlParams->level));
|
||||
|
||||
/* Edge-aligned mode needs MSB to be 1, don't care for Center-aligned mode */
|
||||
reg |= FTM_CnSC_MSB(1U);
|
||||
|
||||
/* Update the mode and edge level */
|
||||
base->CONTROLS[chnlParams->chnlNumber].CnSC = reg;
|
||||
|
||||
if (chnlParams->dutyCyclePercent == 0)
|
||||
{
|
||||
/* Signal stays low */
|
||||
cnv = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cnv = (mod * chnlParams->dutyCyclePercent) / 100;
|
||||
/* For 100% duty cycle */
|
||||
if (cnv >= mod)
|
||||
{
|
||||
cnv = mod + 1;
|
||||
}
|
||||
}
|
||||
|
||||
base->CONTROLS[chnlParams->chnlNumber].CnV = cnv;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This check is added for combined mode as the channel number should be the pair number */
|
||||
if (chnlParams->chnlNumber >= (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2))
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
/* Return error if requested value is greater than the max allowed */
|
||||
if (chnlParams->firstEdgeDelayPercent > 100)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
/* Configure delay of the first edge */
|
||||
if (chnlParams->firstEdgeDelayPercent == 0)
|
||||
{
|
||||
/* No delay for the first edge */
|
||||
cnvFirstEdge = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cnvFirstEdge = (mod * chnlParams->firstEdgeDelayPercent) / 100;
|
||||
}
|
||||
|
||||
/* Configure dutycycle */
|
||||
if (chnlParams->dutyCyclePercent == 0)
|
||||
{
|
||||
/* Signal stays low */
|
||||
cnv = 0;
|
||||
cnvFirstEdge = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cnv = (mod * chnlParams->dutyCyclePercent) / 100;
|
||||
/* For 100% duty cycle */
|
||||
if (cnv >= mod)
|
||||
{
|
||||
cnv = mod + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the current mode and edge level bits for channel n */
|
||||
reg = base->CONTROLS[chnlParams->chnlNumber * 2].CnSC;
|
||||
reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
|
||||
|
||||
/* Setup the active level for channel n */
|
||||
reg |= (FTM_CnSC_ELSA(chnlParams->level) | FTM_CnSC_ELSB(chnlParams->level));
|
||||
|
||||
/* Update the mode and edge level for channel n */
|
||||
base->CONTROLS[chnlParams->chnlNumber * 2].CnSC = reg;
|
||||
|
||||
/* Clear the current mode and edge level bits for channel n + 1 */
|
||||
reg = base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC;
|
||||
reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
|
||||
|
||||
/* Setup the active level for channel n + 1 */
|
||||
reg |= (FTM_CnSC_ELSA(chnlParams->level) | FTM_CnSC_ELSB(chnlParams->level));
|
||||
|
||||
/* Update the mode and edge level for channel n + 1*/
|
||||
base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC = reg;
|
||||
|
||||
/* Set the channel pair values */
|
||||
base->CONTROLS[chnlParams->chnlNumber * 2].CnV = cnvFirstEdge;
|
||||
base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv;
|
||||
|
||||
/* Set the combine bit for the channel pair */
|
||||
base->COMBINE |=
|
||||
(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlParams->chnlNumber)));
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
|
||||
/* Set to output mode */
|
||||
FTM_SetPwmOutputEnable(base, chnlParams->chnlNumber, true);
|
||||
#endif
|
||||
|
||||
chnlParams++;
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
void FTM_UpdatePwmDutycycle(FTM_Type *base,
|
||||
ftm_chnl_t chnlNumber,
|
||||
ftm_pwm_mode_t currentPwmMode,
|
||||
uint8_t dutyCyclePercent)
|
||||
{
|
||||
uint16_t cnv, cnvFirstEdge = 0, mod;
|
||||
|
||||
mod = base->MOD;
|
||||
if ((currentPwmMode == kFTM_EdgeAlignedPwm) || (currentPwmMode == kFTM_CenterAlignedPwm))
|
||||
{
|
||||
cnv = (mod * dutyCyclePercent) / 100;
|
||||
/* For 100% duty cycle */
|
||||
if (cnv >= mod)
|
||||
{
|
||||
cnv = mod + 1;
|
||||
}
|
||||
base->CONTROLS[chnlNumber].CnV = cnv;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This check is added for combined mode as the channel number should be the pair number */
|
||||
if (chnlNumber >= (FSL_FEATURE_FTM_CHANNEL_COUNTn(base) / 2))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cnv = (mod * dutyCyclePercent) / 100;
|
||||
cnvFirstEdge = base->CONTROLS[chnlNumber * 2].CnV;
|
||||
/* For 100% duty cycle */
|
||||
if (cnv >= mod)
|
||||
{
|
||||
cnv = mod + 1;
|
||||
}
|
||||
base->CONTROLS[(chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv;
|
||||
}
|
||||
}
|
||||
|
||||
void FTM_UpdateChnlEdgeLevelSelect(FTM_Type *base, ftm_chnl_t chnlNumber, uint8_t level)
|
||||
{
|
||||
uint32_t reg = base->CONTROLS[chnlNumber].CnSC;
|
||||
|
||||
/* Clear the field and write the new level value */
|
||||
reg &= ~(FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
|
||||
reg |= ((uint32_t)level << FTM_CnSC_ELSA_SHIFT) & (FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
|
||||
|
||||
base->CONTROLS[chnlNumber].CnSC = reg;
|
||||
}
|
||||
|
||||
void FTM_SetupInputCapture(FTM_Type *base,
|
||||
ftm_chnl_t chnlNumber,
|
||||
ftm_input_capture_edge_t captureMode,
|
||||
uint32_t filterValue)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = base->CONTROLS[chnlNumber].CnSC;
|
||||
reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
|
||||
reg |= captureMode;
|
||||
|
||||
/* Set the requested input capture mode */
|
||||
base->CONTROLS[chnlNumber].CnSC = reg;
|
||||
/* Input filter available only for channels 0, 1, 2, 3 */
|
||||
if (chnlNumber < kFTM_Chnl_4)
|
||||
{
|
||||
reg = base->FILTER;
|
||||
reg &= ~(FTM_FILTER_CH0FVAL_MASK << (FTM_FILTER_CH1FVAL_SHIFT * chnlNumber));
|
||||
reg |= (filterValue << (FTM_FILTER_CH1FVAL_SHIFT * chnlNumber));
|
||||
base->FILTER = reg;
|
||||
}
|
||||
#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
|
||||
/* Set to input mode */
|
||||
FTM_SetPwmOutputEnable(base, chnlNumber, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FTM_SetupOutputCompare(FTM_Type *base,
|
||||
ftm_chnl_t chnlNumber,
|
||||
ftm_output_compare_mode_t compareMode,
|
||||
uint32_t compareValue)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
/* Set output on match to the requested level */
|
||||
base->CONTROLS[chnlNumber].CnV = compareValue;
|
||||
|
||||
reg = base->CONTROLS[chnlNumber].CnSC;
|
||||
reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
|
||||
reg |= compareMode;
|
||||
/* Setup the channel output behaviour when a match occurs with the compare value */
|
||||
base->CONTROLS[chnlNumber].CnSC = reg;
|
||||
|
||||
#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
|
||||
/* Set to output mode */
|
||||
FTM_SetPwmOutputEnable(base, chnlNumber, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FTM_SetupDualEdgeCapture(FTM_Type *base,
|
||||
ftm_chnl_t chnlPairNumber,
|
||||
const ftm_dual_edge_capture_param_t *edgeParam,
|
||||
uint32_t filterValue)
|
||||
{
|
||||
assert(edgeParam);
|
||||
|
||||
uint32_t reg;
|
||||
|
||||
reg = base->COMBINE;
|
||||
/* Clear the combine bit for the channel pair */
|
||||
reg &= ~(1U << (FTM_COMBINE_COMBINE0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
|
||||
/* Enable the DECAPEN bit */
|
||||
reg |= (1U << (FTM_COMBINE_DECAPEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
|
||||
reg |= (1U << (FTM_COMBINE_DECAP0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
|
||||
base->COMBINE = reg;
|
||||
|
||||
/* Setup the edge detection from channel n and n + 1 */
|
||||
reg = base->CONTROLS[chnlPairNumber * 2].CnSC;
|
||||
reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
|
||||
reg |= ((uint32_t)edgeParam->mode | (uint32_t)edgeParam->currChanEdgeMode);
|
||||
base->CONTROLS[chnlPairNumber * 2].CnSC = reg;
|
||||
|
||||
reg = base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC;
|
||||
reg &= ~(FTM_CnSC_MSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK);
|
||||
reg |= ((uint32_t)edgeParam->mode | (uint32_t)edgeParam->nextChanEdgeMode);
|
||||
base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC = reg;
|
||||
|
||||
/* Input filter available only for channels 0, 1, 2, 3 */
|
||||
if (chnlPairNumber < kFTM_Chnl_4)
|
||||
{
|
||||
reg = base->FILTER;
|
||||
reg &= ~(FTM_FILTER_CH0FVAL_MASK << (FTM_FILTER_CH1FVAL_SHIFT * chnlPairNumber));
|
||||
reg |= (filterValue << (FTM_FILTER_CH1FVAL_SHIFT * chnlPairNumber));
|
||||
base->FILTER = reg;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT)
|
||||
/* Set to input mode */
|
||||
FTM_SetPwmOutputEnable(base, chnlPairNumber, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FTM_SetupQuadDecode(FTM_Type *base,
|
||||
const ftm_phase_params_t *phaseAParams,
|
||||
const ftm_phase_params_t *phaseBParams,
|
||||
ftm_quad_decode_mode_t quadMode)
|
||||
{
|
||||
assert(phaseAParams);
|
||||
assert(phaseBParams);
|
||||
|
||||
uint32_t reg;
|
||||
|
||||
/* Set Phase A filter value if phase filter is enabled */
|
||||
if (phaseAParams->enablePhaseFilter)
|
||||
{
|
||||
reg = base->FILTER;
|
||||
reg &= ~(FTM_FILTER_CH0FVAL_MASK);
|
||||
reg |= FTM_FILTER_CH0FVAL(phaseAParams->phaseFilterVal);
|
||||
base->FILTER = reg;
|
||||
}
|
||||
|
||||
/* Set Phase B filter value if phase filter is enabled */
|
||||
if (phaseBParams->enablePhaseFilter)
|
||||
{
|
||||
reg = base->FILTER;
|
||||
reg &= ~(FTM_FILTER_CH1FVAL_MASK);
|
||||
reg |= FTM_FILTER_CH1FVAL(phaseBParams->phaseFilterVal);
|
||||
base->FILTER = reg;
|
||||
}
|
||||
|
||||
/* Set Quadrature decode properties */
|
||||
reg = base->QDCTRL;
|
||||
reg &= ~(FTM_QDCTRL_QUADMODE_MASK | FTM_QDCTRL_PHAFLTREN_MASK | FTM_QDCTRL_PHBFLTREN_MASK | FTM_QDCTRL_PHAPOL_MASK |
|
||||
FTM_QDCTRL_PHBPOL_MASK);
|
||||
reg |= (FTM_QDCTRL_QUADMODE(quadMode) | FTM_QDCTRL_PHAFLTREN(phaseAParams->enablePhaseFilter) |
|
||||
FTM_QDCTRL_PHBFLTREN(phaseBParams->enablePhaseFilter) | FTM_QDCTRL_PHAPOL(phaseAParams->phasePolarity) |
|
||||
FTM_QDCTRL_PHBPOL(phaseBParams->phasePolarity));
|
||||
base->QDCTRL = reg;
|
||||
/* Enable Quad decode */
|
||||
base->QDCTRL |= FTM_QDCTRL_QUADEN_MASK;
|
||||
}
|
||||
|
||||
void FTM_SetupFault(FTM_Type *base, ftm_fault_input_t faultNumber, const ftm_fault_param_t *faultParams)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = base->FLTCTRL;
|
||||
if (faultParams->enableFaultInput)
|
||||
{
|
||||
/* Enable the fault input */
|
||||
reg |= (FTM_FLTCTRL_FAULT0EN_MASK << faultNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the fault input */
|
||||
reg &= ~(FTM_FLTCTRL_FAULT0EN_MASK << faultNumber);
|
||||
}
|
||||
|
||||
if (faultParams->useFaultFilter)
|
||||
{
|
||||
/* Enable the fault filter */
|
||||
reg |= (FTM_FLTCTRL_FFLTR0EN_MASK << (FTM_FLTCTRL_FFLTR0EN_SHIFT + faultNumber));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the fault filter */
|
||||
reg &= ~(FTM_FLTCTRL_FFLTR0EN_MASK << (FTM_FLTCTRL_FFLTR0EN_SHIFT + faultNumber));
|
||||
}
|
||||
base->FLTCTRL = reg;
|
||||
|
||||
if (faultParams->faultLevel)
|
||||
{
|
||||
/* Active low polarity for the fault input pin */
|
||||
base->FLTPOL |= (1U << faultNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Active high polarity for the fault input pin */
|
||||
base->FLTPOL &= ~(1U << faultNumber);
|
||||
}
|
||||
}
|
||||
|
||||
void FTM_EnableInterrupts(FTM_Type *base, uint32_t mask)
|
||||
{
|
||||
uint32_t chnlInts = (mask & 0xFFU);
|
||||
uint8_t chnlNumber = 0;
|
||||
|
||||
/* Enable the timer overflow interrupt */
|
||||
if (mask & kFTM_TimeOverflowInterruptEnable)
|
||||
{
|
||||
base->SC |= FTM_SC_TOIE_MASK;
|
||||
}
|
||||
|
||||
/* Enable the fault interrupt */
|
||||
if (mask & kFTM_FaultInterruptEnable)
|
||||
{
|
||||
base->MODE |= FTM_MODE_FAULTIE_MASK;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
|
||||
/* Enable the reload interrupt available only on certain SoC's */
|
||||
if (mask & kFTM_ReloadInterruptEnable)
|
||||
{
|
||||
base->SC |= FTM_SC_RIE_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Enable the channel interrupts */
|
||||
while (chnlInts)
|
||||
{
|
||||
if (chnlInts & 0x1)
|
||||
{
|
||||
base->CONTROLS[chnlNumber].CnSC |= FTM_CnSC_CHIE_MASK;
|
||||
}
|
||||
chnlNumber++;
|
||||
chnlInts = chnlInts >> 1U;
|
||||
}
|
||||
}
|
||||
|
||||
void FTM_DisableInterrupts(FTM_Type *base, uint32_t mask)
|
||||
{
|
||||
uint32_t chnlInts = (mask & 0xFF);
|
||||
uint8_t chnlNumber = 0;
|
||||
|
||||
/* Disable the timer overflow interrupt */
|
||||
if (mask & kFTM_TimeOverflowInterruptEnable)
|
||||
{
|
||||
base->SC &= ~FTM_SC_TOIE_MASK;
|
||||
}
|
||||
/* Disable the fault interrupt */
|
||||
if (mask & kFTM_FaultInterruptEnable)
|
||||
{
|
||||
base->MODE &= ~FTM_MODE_FAULTIE_MASK;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
|
||||
/* Disable the reload interrupt available only on certain SoC's */
|
||||
if (mask & kFTM_ReloadInterruptEnable)
|
||||
{
|
||||
base->SC &= ~FTM_SC_RIE_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Disable the channel interrupts */
|
||||
while (chnlInts)
|
||||
{
|
||||
if (chnlInts & 0x1)
|
||||
{
|
||||
base->CONTROLS[chnlNumber].CnSC &= ~FTM_CnSC_CHIE_MASK;
|
||||
}
|
||||
chnlNumber++;
|
||||
chnlInts = chnlInts >> 1U;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t FTM_GetEnabledInterrupts(FTM_Type *base)
|
||||
{
|
||||
uint32_t enabledInterrupts = 0;
|
||||
int8_t chnlCount = FSL_FEATURE_FTM_CHANNEL_COUNTn(base);
|
||||
|
||||
/* The CHANNEL_COUNT macro returns -1 if it cannot match the FTM instance */
|
||||
assert(chnlCount != -1);
|
||||
|
||||
/* Check if timer overflow interrupt is enabled */
|
||||
if (base->SC & FTM_SC_TOIE_MASK)
|
||||
{
|
||||
enabledInterrupts |= kFTM_TimeOverflowInterruptEnable;
|
||||
}
|
||||
/* Check if fault interrupt is enabled */
|
||||
if (base->MODE & FTM_MODE_FAULTIE_MASK)
|
||||
{
|
||||
enabledInterrupts |= kFTM_FaultInterruptEnable;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
|
||||
/* Check if the reload interrupt is enabled */
|
||||
if (base->SC & FTM_SC_RIE_MASK)
|
||||
{
|
||||
enabledInterrupts |= kFTM_ReloadInterruptEnable;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if the channel interrupts are enabled */
|
||||
while (chnlCount > 0)
|
||||
{
|
||||
chnlCount--;
|
||||
if (base->CONTROLS[chnlCount].CnSC & FTM_CnSC_CHIE_MASK)
|
||||
{
|
||||
enabledInterrupts |= (1U << chnlCount);
|
||||
}
|
||||
}
|
||||
|
||||
return enabledInterrupts;
|
||||
}
|
||||
|
||||
uint32_t FTM_GetStatusFlags(FTM_Type *base)
|
||||
{
|
||||
uint32_t statusFlags = 0;
|
||||
|
||||
/* Check the timer flag */
|
||||
if (base->SC & FTM_SC_TOF_MASK)
|
||||
{
|
||||
statusFlags |= kFTM_TimeOverflowFlag;
|
||||
}
|
||||
/* Check fault flag */
|
||||
if (base->FMS & FTM_FMS_FAULTF_MASK)
|
||||
{
|
||||
statusFlags |= kFTM_FaultFlag;
|
||||
}
|
||||
/* Check channel trigger flag */
|
||||
if (base->EXTTRIG & FTM_EXTTRIG_TRIGF_MASK)
|
||||
{
|
||||
statusFlags |= kFTM_ChnlTriggerFlag;
|
||||
}
|
||||
#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
|
||||
/* Check reload flag */
|
||||
if (base->SC & FTM_SC_RF_MASK)
|
||||
{
|
||||
statusFlags |= kFTM_ReloadFlag;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Lower 8 bits contain the channel status flags */
|
||||
statusFlags |= (base->STATUS & 0xFFU);
|
||||
|
||||
return statusFlags;
|
||||
}
|
||||
|
||||
void FTM_ClearStatusFlags(FTM_Type *base, uint32_t mask)
|
||||
{
|
||||
/* Clear the timer overflow flag by writing a 0 to the bit while it is set */
|
||||
if (mask & kFTM_TimeOverflowFlag)
|
||||
{
|
||||
base->SC &= ~FTM_SC_TOF_MASK;
|
||||
}
|
||||
/* Clear fault flag by writing a 0 to the bit while it is set */
|
||||
if (mask & kFTM_FaultFlag)
|
||||
{
|
||||
base->FMS &= ~FTM_FMS_FAULTF_MASK;
|
||||
}
|
||||
/* Clear channel trigger flag */
|
||||
if (mask & kFTM_ChnlTriggerFlag)
|
||||
{
|
||||
base->EXTTRIG &= ~FTM_EXTTRIG_TRIGF_MASK;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT) && (FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT)
|
||||
/* Check reload flag by writing a 0 to the bit while it is set */
|
||||
if (mask & kFTM_ReloadFlag)
|
||||
{
|
||||
base->SC &= ~FTM_SC_RF_MASK;
|
||||
}
|
||||
#endif
|
||||
/* Clear the channel status flags by writing a 0 to the bit */
|
||||
base->STATUS &= ~(mask & 0xFFU);
|
||||
}
|
|
@ -0,0 +1,862 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_FTM_H_
|
||||
#define _FSL_FTM_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup ftm_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
#define FSL_FTM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief List of FTM channels
|
||||
* @note Actual number of available channels is SoC dependent
|
||||
*/
|
||||
typedef enum _ftm_chnl
|
||||
{
|
||||
kFTM_Chnl_0 = 0U, /*!< FTM channel number 0*/
|
||||
kFTM_Chnl_1, /*!< FTM channel number 1 */
|
||||
kFTM_Chnl_2, /*!< FTM channel number 2 */
|
||||
kFTM_Chnl_3, /*!< FTM channel number 3 */
|
||||
kFTM_Chnl_4, /*!< FTM channel number 4 */
|
||||
kFTM_Chnl_5, /*!< FTM channel number 5 */
|
||||
kFTM_Chnl_6, /*!< FTM channel number 6 */
|
||||
kFTM_Chnl_7 /*!< FTM channel number 7 */
|
||||
} ftm_chnl_t;
|
||||
|
||||
/*! @brief List of FTM faults */
|
||||
typedef enum _ftm_fault_input
|
||||
{
|
||||
kFTM_Fault_0 = 0U, /*!< FTM fault 0 input pin */
|
||||
kFTM_Fault_1, /*!< FTM fault 1 input pin */
|
||||
kFTM_Fault_2, /*!< FTM fault 2 input pin */
|
||||
kFTM_Fault_3 /*!< FTM fault 3 input pin */
|
||||
} ftm_fault_input_t;
|
||||
|
||||
/*! @brief FTM PWM operation modes */
|
||||
typedef enum _ftm_pwm_mode
|
||||
{
|
||||
kFTM_EdgeAlignedPwm = 0U, /*!< Edge-aligned PWM */
|
||||
kFTM_CenterAlignedPwm, /*!< Center-aligned PWM */
|
||||
kFTM_CombinedPwm /*!< Combined PWM */
|
||||
} ftm_pwm_mode_t;
|
||||
|
||||
/*! @brief FTM PWM output pulse mode: high-true, low-true or no output */
|
||||
typedef enum _ftm_pwm_level_select
|
||||
{
|
||||
kFTM_NoPwmSignal = 0U, /*!< No PWM output on pin */
|
||||
kFTM_LowTrue, /*!< Low true pulses */
|
||||
kFTM_HighTrue /*!< High true pulses */
|
||||
} ftm_pwm_level_select_t;
|
||||
|
||||
/*! @brief Options to configure a FTM channel's PWM signal */
|
||||
typedef struct _ftm_chnl_pwm_signal_param
|
||||
{
|
||||
ftm_chnl_t chnlNumber; /*!< The channel/channel pair number.
|
||||
In combined mode, this represents the channel pair number. */
|
||||
ftm_pwm_level_select_t level; /*!< PWM output active level select. */
|
||||
uint8_t dutyCyclePercent; /*!< PWM pulse width, value should be between 0 to 100
|
||||
0 = inactive signal(0% duty cycle)...
|
||||
100 = always active signal (100% duty cycle).*/
|
||||
uint8_t firstEdgeDelayPercent; /*!< Used only in combined PWM mode to generate an asymmetrical PWM.
|
||||
Specifies the delay to the first edge in a PWM period.
|
||||
If unsure leave as 0; Should be specified as a
|
||||
percentage of the PWM period */
|
||||
} ftm_chnl_pwm_signal_param_t;
|
||||
|
||||
/*! @brief FlexTimer output compare mode */
|
||||
typedef enum _ftm_output_compare_mode
|
||||
{
|
||||
kFTM_NoOutputSignal = (1U << FTM_CnSC_MSA_SHIFT), /*!< No channel output when counter reaches CnV */
|
||||
kFTM_ToggleOnMatch = ((1U << FTM_CnSC_MSA_SHIFT) | (1U << FTM_CnSC_ELSA_SHIFT)), /*!< Toggle output */
|
||||
kFTM_ClearOnMatch = ((1U << FTM_CnSC_MSA_SHIFT) | (2U << FTM_CnSC_ELSA_SHIFT)), /*!< Clear output */
|
||||
kFTM_SetOnMatch = ((1U << FTM_CnSC_MSA_SHIFT) | (3U << FTM_CnSC_ELSA_SHIFT)) /*!< Set output */
|
||||
} ftm_output_compare_mode_t;
|
||||
|
||||
/*! @brief FlexTimer input capture edge */
|
||||
typedef enum _ftm_input_capture_edge
|
||||
{
|
||||
kFTM_RisingEdge = (1U << FTM_CnSC_ELSA_SHIFT), /*!< Capture on rising edge only*/
|
||||
kFTM_FallingEdge = (2U << FTM_CnSC_ELSA_SHIFT), /*!< Capture on falling edge only*/
|
||||
kFTM_RiseAndFallEdge = (3U << FTM_CnSC_ELSA_SHIFT) /*!< Capture on rising or falling edge */
|
||||
} ftm_input_capture_edge_t;
|
||||
|
||||
/*! @brief FlexTimer dual edge capture modes */
|
||||
typedef enum _ftm_dual_edge_capture_mode
|
||||
{
|
||||
kFTM_OneShot = 0U, /*!< One-shot capture mode */
|
||||
kFTM_Continuous = (1U << FTM_CnSC_MSA_SHIFT) /*!< Continuous capture mode */
|
||||
} ftm_dual_edge_capture_mode_t;
|
||||
|
||||
/*! @brief FlexTimer dual edge capture parameters */
|
||||
typedef struct _ftm_dual_edge_capture_param
|
||||
{
|
||||
ftm_dual_edge_capture_mode_t mode; /*!< Dual Edge Capture mode */
|
||||
ftm_input_capture_edge_t currChanEdgeMode; /*!< Input capture edge select for channel n */
|
||||
ftm_input_capture_edge_t nextChanEdgeMode; /*!< Input capture edge select for channel n+1 */
|
||||
} ftm_dual_edge_capture_param_t;
|
||||
|
||||
/*! @brief FlexTimer quadrature decode modes */
|
||||
typedef enum _ftm_quad_decode_mode
|
||||
{
|
||||
kFTM_QuadPhaseEncode = 0U, /*!< Phase A and Phase B encoding mode */
|
||||
kFTM_QuadCountAndDir /*!< Count and direction encoding mode */
|
||||
} ftm_quad_decode_mode_t;
|
||||
|
||||
/*! @brief FlexTimer quadrature phase polarities */
|
||||
typedef enum _ftm_phase_polarity
|
||||
{
|
||||
kFTM_QuadPhaseNormal = 0U, /*!< Phase input signal is not inverted */
|
||||
kFTM_QuadPhaseInvert /*!< Phase input signal is inverted */
|
||||
} ftm_phase_polarity_t;
|
||||
|
||||
/*! @brief FlexTimer quadrature decode phase parameters */
|
||||
typedef struct _ftm_phase_param
|
||||
{
|
||||
bool enablePhaseFilter; /*!< True: enable phase filter; false: disable filter */
|
||||
uint32_t phaseFilterVal; /*!< Filter value, used only if phase filter is enabled */
|
||||
ftm_phase_polarity_t phasePolarity; /*!< Phase polarity */
|
||||
} ftm_phase_params_t;
|
||||
|
||||
/*! @brief Structure is used to hold the parameters to configure a FTM fault */
|
||||
typedef struct _ftm_fault_param
|
||||
{
|
||||
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;
|
||||
False: Fault polarity is active high */
|
||||
bool useFaultFilter; /*!< True: Use the filtered fault signal;
|
||||
False: Use the direct path from fault input */
|
||||
} ftm_fault_param_t;
|
||||
|
||||
/*! @brief FlexTimer pre-scaler factor for the dead time insertion*/
|
||||
typedef enum _ftm_deadtime_prescale
|
||||
{
|
||||
kFTM_Deadtime_Prescale_1 = 1U, /*!< Divide by 1 */
|
||||
kFTM_Deadtime_Prescale_4, /*!< Divide by 4 */
|
||||
kFTM_Deadtime_Prescale_16 /*!< Divide by 16 */
|
||||
} ftm_deadtime_prescale_t;
|
||||
|
||||
/*! @brief FlexTimer clock source selection*/
|
||||
typedef enum _ftm_clock_source
|
||||
{
|
||||
kFTM_SystemClock = 1U, /*!< System clock selected */
|
||||
kFTM_FixedClock, /*!< Fixed frequency clock */
|
||||
kFTM_ExternalClock /*!< External clock */
|
||||
} ftm_clock_source_t;
|
||||
|
||||
/*! @brief FlexTimer pre-scaler factor selection for the clock source*/
|
||||
typedef enum _ftm_clock_prescale
|
||||
{
|
||||
kFTM_Prescale_Divide_1 = 0U, /*!< Divide by 1 */
|
||||
kFTM_Prescale_Divide_2, /*!< Divide by 2 */
|
||||
kFTM_Prescale_Divide_4, /*!< Divide by 4 */
|
||||
kFTM_Prescale_Divide_8, /*!< Divide by 8 */
|
||||
kFTM_Prescale_Divide_16, /*!< Divide by 16 */
|
||||
kFTM_Prescale_Divide_32, /*!< Divide by 32 */
|
||||
kFTM_Prescale_Divide_64, /*!< Divide by 64 */
|
||||
kFTM_Prescale_Divide_128 /*!< Divide by 128 */
|
||||
} ftm_clock_prescale_t;
|
||||
|
||||
/*! @brief Options for the FlexTimer behaviour in BDM Mode */
|
||||
typedef enum _ftm_bdm_mode
|
||||
{
|
||||
kFTM_BdmMode_0 = 0U,
|
||||
/*!< FTM counter stopped, CH(n)F bit can be set, FTM channels in functional mode, writes to MOD,CNTIN and C(n)V
|
||||
registers bypass the register buffers */
|
||||
kFTM_BdmMode_1,
|
||||
/*!< FTM counter stopped, CH(n)F bit is not set, FTM channels outputs are forced to their safe value , writes to
|
||||
MOD,CNTIN and C(n)V registers bypass the register buffers */
|
||||
kFTM_BdmMode_2,
|
||||
/*!< FTM counter stopped, CH(n)F bit is not set, FTM channels outputs are frozen when chip enters in BDM mode,
|
||||
writes to MOD,CNTIN and C(n)V registers bypass the register buffers */
|
||||
kFTM_BdmMode_3
|
||||
/*!< FTM counter in functional mode, CH(n)F bit can be set, FTM channels in functional mode, writes to MOD,CNTIN and
|
||||
C(n)V registers is in fully functional mode */
|
||||
} ftm_bdm_mode_t;
|
||||
|
||||
/*! @brief Options for the FTM fault control mode */
|
||||
typedef enum _ftm_fault_mode
|
||||
{
|
||||
kFTM_Fault_Disable = 0U, /*!< Fault control is disabled for all channels */
|
||||
kFTM_Fault_EvenChnls, /*!< Enabled for even channels only(0,2,4,6) with manual fault clearing */
|
||||
kFTM_Fault_AllChnlsMan, /*!< Enabled for all channels with manual fault clearing */
|
||||
kFTM_Fault_AllChnlsAuto /*!< Enabled for all channels with automatic fault clearing */
|
||||
} ftm_fault_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief FTM external trigger options
|
||||
* @note Actual available external trigger sources are SoC-specific
|
||||
*/
|
||||
typedef enum _ftm_external_trigger
|
||||
{
|
||||
kFTM_Chnl0Trigger = (1U << 4), /*!< Generate trigger when counter equals chnl 0 CnV reg */
|
||||
kFTM_Chnl1Trigger = (1U << 5), /*!< Generate trigger when counter equals chnl 1 CnV reg */
|
||||
kFTM_Chnl2Trigger = (1U << 0), /*!< Generate trigger when counter equals chnl 2 CnV reg */
|
||||
kFTM_Chnl3Trigger = (1U << 1), /*!< Generate trigger when counter equals chnl 3 CnV reg */
|
||||
kFTM_Chnl4Trigger = (1U << 2), /*!< Generate trigger when counter equals chnl 4 CnV reg */
|
||||
kFTM_Chnl5Trigger = (1U << 3), /*!< Generate trigger when counter equals chnl 5 CnV reg */
|
||||
kFTM_Chnl6Trigger =
|
||||
(1U << 8), /*!< Available on certain SoC's, generate trigger when counter equals chnl 6 CnV reg */
|
||||
kFTM_Chnl7Trigger =
|
||||
(1U << 9), /*!< Available on certain SoC's, generate trigger when counter equals chnl 7 CnV reg */
|
||||
kFTM_InitTrigger = (1U << 6), /*!< Generate Trigger when counter is updated with CNTIN */
|
||||
kFTM_ReloadInitTrigger = (1U << 7) /*!< Available on certain SoC's, trigger on reload point */
|
||||
} ftm_external_trigger_t;
|
||||
|
||||
/*! @brief FlexTimer PWM sync options to update registers with buffer */
|
||||
typedef enum _ftm_pwm_sync_method
|
||||
{
|
||||
kFTM_SoftwareTrigger = FTM_SYNC_SWSYNC_MASK, /*!< Software triggers PWM sync */
|
||||
kFTM_HardwareTrigger_0 = FTM_SYNC_TRIG0_MASK, /*!< Hardware trigger 0 causes PWM sync */
|
||||
kFTM_HardwareTrigger_1 = FTM_SYNC_TRIG1_MASK, /*!< Hardware trigger 1 causes PWM sync */
|
||||
kFTM_HardwareTrigger_2 = FTM_SYNC_TRIG2_MASK /*!< Hardware trigger 2 causes PWM sync */
|
||||
} ftm_pwm_sync_method_t;
|
||||
|
||||
/*!
|
||||
* @brief FTM options available as loading point for register reload
|
||||
* @note Actual available reload points are SoC-specific
|
||||
*/
|
||||
typedef enum _ftm_reload_point
|
||||
{
|
||||
kFTM_Chnl0Match = (1U << 0), /*!< Channel 0 match included as a reload point */
|
||||
kFTM_Chnl1Match = (1U << 1), /*!< Channel 1 match included as a reload point */
|
||||
kFTM_Chnl2Match = (1U << 2), /*!< Channel 2 match included as a reload point */
|
||||
kFTM_Chnl3Match = (1U << 3), /*!< Channel 3 match included as a reload point */
|
||||
kFTM_Chnl4Match = (1U << 4), /*!< Channel 4 match included as a reload point */
|
||||
kFTM_Chnl5Match = (1U << 5), /*!< Channel 5 match included as a reload point */
|
||||
kFTM_Chnl6Match = (1U << 6), /*!< Channel 6 match included as a reload point */
|
||||
kFTM_Chnl7Match = (1U << 7), /*!< Channel 7 match included as a reload point */
|
||||
kFTM_CntMax = (1U << 8), /*!< Use in up-down count mode only, reload when counter reaches the maximum value */
|
||||
kFTM_CntMin = (1U << 9), /*!< Use in up-down count mode only, reload when counter reaches the minimum value */
|
||||
kFTM_HalfCycMatch = (1U << 10) /*!< Available on certain SoC's, half cycle match reload point */
|
||||
} ftm_reload_point_t;
|
||||
|
||||
/*!
|
||||
* @brief List of FTM interrupts
|
||||
* @note Actual available interrupts are SoC-specific
|
||||
*/
|
||||
typedef enum _ftm_interrupt_enable
|
||||
{
|
||||
kFTM_Chnl0InterruptEnable = (1U << 0), /*!< Channel 0 interrupt */
|
||||
kFTM_Chnl1InterruptEnable = (1U << 1), /*!< Channel 1 interrupt */
|
||||
kFTM_Chnl2InterruptEnable = (1U << 2), /*!< Channel 2 interrupt */
|
||||
kFTM_Chnl3InterruptEnable = (1U << 3), /*!< Channel 3 interrupt */
|
||||
kFTM_Chnl4InterruptEnable = (1U << 4), /*!< Channel 4 interrupt */
|
||||
kFTM_Chnl5InterruptEnable = (1U << 5), /*!< Channel 5 interrupt */
|
||||
kFTM_Chnl6InterruptEnable = (1U << 6), /*!< Channel 6 interrupt */
|
||||
kFTM_Chnl7InterruptEnable = (1U << 7), /*!< Channel 7 interrupt */
|
||||
kFTM_FaultInterruptEnable = (1U << 8), /*!< Fault interrupt */
|
||||
kFTM_TimeOverflowInterruptEnable = (1U << 9), /*!< Time overflow interrupt */
|
||||
kFTM_ReloadInterruptEnable = (1U << 10) /*!< Reload interrupt; Available only on certain SoC's */
|
||||
} ftm_interrupt_enable_t;
|
||||
|
||||
/*!
|
||||
* @brief List of FTM flags
|
||||
* @note Actual available flags are SoC-specific
|
||||
*/
|
||||
typedef enum _ftm_status_flags
|
||||
{
|
||||
kFTM_Chnl0Flag = (1U << 0), /*!< Channel 0 Flag */
|
||||
kFTM_Chnl1Flag = (1U << 1), /*!< Channel 1 Flag */
|
||||
kFTM_Chnl2Flag = (1U << 2), /*!< Channel 2 Flag */
|
||||
kFTM_Chnl3Flag = (1U << 3), /*!< Channel 3 Flag */
|
||||
kFTM_Chnl4Flag = (1U << 4), /*!< Channel 4 Flag */
|
||||
kFTM_Chnl5Flag = (1U << 5), /*!< Channel 5 Flag */
|
||||
kFTM_Chnl6Flag = (1U << 6), /*!< Channel 6 Flag */
|
||||
kFTM_Chnl7Flag = (1U << 7), /*!< Channel 7 Flag */
|
||||
kFTM_FaultFlag = (1U << 8), /*!< Fault Flag */
|
||||
kFTM_TimeOverflowFlag = (1U << 9), /*!< Time overflow Flag */
|
||||
kFTM_ChnlTriggerFlag = (1U << 10), /*!< Channel trigger Flag */
|
||||
kFTM_ReloadFlag = (1U << 11) /*!< Reload Flag; Available only on certain SoC's */
|
||||
} ftm_status_flags_t;
|
||||
|
||||
/*!
|
||||
* @brief FTM configuration structure
|
||||
*
|
||||
* This structure holds the configuration settings for the FTM peripheral. To initialize this
|
||||
* structure to reasonable defaults, call the FTM_GetDefaultConfig() function and pass a
|
||||
* pointer to the configuration structure instance.
|
||||
*
|
||||
* The configuration structure can be made constant so as to reside in flash.
|
||||
*/
|
||||
typedef struct _ftm_config
|
||||
{
|
||||
ftm_clock_prescale_t prescale; /*!< FTM clock prescale value */
|
||||
ftm_bdm_mode_t bdmMode; /*!< FTM behavior in BDM mode */
|
||||
uint32_t pwmSyncMode; /*!< Synchronization methods to use to update buffered registers; Multiple
|
||||
update modes can be used by providing an OR'ed list of options
|
||||
available in enumeration ::ftm_pwm_sync_method_t. */
|
||||
uint32_t reloadPoints; /*!< FTM reload points; When using this, the PWM
|
||||
synchronization is not required. Multiple reload points can be used by providing
|
||||
an OR'ed list of options available in
|
||||
enumeration ::ftm_reload_point_t. */
|
||||
ftm_fault_mode_t faultMode; /*!< FTM fault control mode */
|
||||
uint8_t faultFilterValue; /*!< Fault input filter value */
|
||||
ftm_deadtime_prescale_t deadTimePrescale; /*!< The dead time prescalar value */
|
||||
uint8_t deadTimeValue; /*!< The dead time value */
|
||||
uint32_t extTriggers; /*!< External triggers to enable. Multiple trigger sources can be
|
||||
enabled by providing an OR'ed list of options available in
|
||||
enumeration ::ftm_external_trigger_t. */
|
||||
uint8_t chnlInitState; /*!< Defines the initialization value of the channels in OUTINT register */
|
||||
uint8_t chnlPolarity; /*!< Defines the output polarity of the channels in POL register */
|
||||
bool useGlobalTimeBase; /*!< True: Use of an external global time base is enabled;
|
||||
False: disabled */
|
||||
} ftm_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Initialization and deinitialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @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.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param config Pointer to the user configuration structure.
|
||||
*
|
||||
* @return kStatus_Success indicates success; Else indicates failure.
|
||||
*/
|
||||
status_t FTM_Init(FTM_Type *base, const ftm_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Gates the FTM clock.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
*/
|
||||
void FTM_Deinit(FTM_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Fills in the FTM configuration structure with the default settings.
|
||||
*
|
||||
* The default values are:
|
||||
* @code
|
||||
* config->prescale = kFTM_Prescale_Divide_1;
|
||||
* config->bdmMode = kFTM_BdmMode_0;
|
||||
* config->pwmSyncMode = kFTM_SoftwareTrigger;
|
||||
* config->reloadPoints = 0;
|
||||
* config->faultMode = kFTM_Fault_Disable;
|
||||
* config->faultFilterValue = 0;
|
||||
* config->deadTimePrescale = kFTM_Deadtime_Prescale_1;
|
||||
* config->deadTimeValue = 0;
|
||||
* config->extTriggers = 0;
|
||||
* config->chnlInitState = 0;
|
||||
* config->chnlPolarity = 0;
|
||||
* config->useGlobalTimeBase = false;
|
||||
* @endcode
|
||||
* @param config Pointer to the user configuration structure.
|
||||
*/
|
||||
void FTM_GetDefaultConfig(ftm_config_t *config);
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Channel mode operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Configures the PWM signal parameters.
|
||||
*
|
||||
* Call this function to configure the PWM signal period, mode, duty cycle, and edge. Use this
|
||||
* function to configure all FTM channels that are used to output a PWM signal.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlParams Array of PWM channel parameters to configure the channel(s)
|
||||
* @param numOfChnls Number of channels to configure; This should be the size of the array passed in
|
||||
* @param mode PWM operation mode, options available in enumeration ::ftm_pwm_mode_t
|
||||
* @param pwmFreq_Hz PWM signal frequency in Hz
|
||||
* @param srcClock_Hz FTM counter clock in Hz
|
||||
*
|
||||
* @return kStatus_Success if the PWM setup was successful
|
||||
* kStatus_Error on failure
|
||||
*/
|
||||
status_t FTM_SetupPwm(FTM_Type *base,
|
||||
const ftm_chnl_pwm_signal_param_t *chnlParams,
|
||||
uint8_t numOfChnls,
|
||||
ftm_pwm_mode_t mode,
|
||||
uint32_t pwmFreq_Hz,
|
||||
uint32_t srcClock_Hz);
|
||||
|
||||
/*!
|
||||
* @brief Updates the duty cycle of an active PWM signal.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlNumber The channel/channel pair number. In combined mode, this represents
|
||||
* the channel pair number
|
||||
* @param currentPwmMode The current PWM mode set during PWM setup
|
||||
* @param dutyCyclePercent New PWM pulse width; The value should be between 0 to 100
|
||||
* 0=inactive signal(0% duty cycle)...
|
||||
* 100=active signal (100% duty cycle)
|
||||
*/
|
||||
void FTM_UpdatePwmDutycycle(FTM_Type *base,
|
||||
ftm_chnl_t chnlNumber,
|
||||
ftm_pwm_mode_t currentPwmMode,
|
||||
uint8_t dutyCyclePercent);
|
||||
|
||||
/*!
|
||||
* @brief Updates the edge level selection for a channel.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlNumber The channel number
|
||||
* @param level The level to be set to the ELSnB:ELSnA field; Valid values are 00, 01, 10, 11.
|
||||
* See the Kinetis SoC reference manual for details about this field.
|
||||
*/
|
||||
void FTM_UpdateChnlEdgeLevelSelect(FTM_Type *base, ftm_chnl_t chnlNumber, uint8_t level);
|
||||
|
||||
/*!
|
||||
* @brief Enables capturing an input signal on the channel using the function parameters.
|
||||
*
|
||||
* When the edge specified in the captureMode argument occurs on the channel, the FTM counter is
|
||||
* captured into the CnV register. The user has to read the CnV register separately to get this
|
||||
* value. The filter function is disabled if the filterVal argument passed in is 0. The filter
|
||||
* function is available only for channels 0, 1, 2, 3.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlNumber The channel number
|
||||
* @param captureMode Specifies which edge to capture
|
||||
* @param filterValue Filter value, specify 0 to disable filter. Available only for channels 0-3.
|
||||
*/
|
||||
void FTM_SetupInputCapture(FTM_Type *base,
|
||||
ftm_chnl_t chnlNumber,
|
||||
ftm_input_capture_edge_t captureMode,
|
||||
uint32_t filterValue);
|
||||
|
||||
/*!
|
||||
* @brief Configures the FTM to generate timed pulses.
|
||||
*
|
||||
* When the FTM counter matches the value of compareVal argument (this is written into CnV reg),
|
||||
* the channel output is changed based on what is specified in the compareMode argument.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlNumber The channel number
|
||||
* @param compareMode Action to take on the channel output when the compare condition is met
|
||||
* @param compareValue Value to be programmed in the CnV register.
|
||||
*/
|
||||
void FTM_SetupOutputCompare(FTM_Type *base,
|
||||
ftm_chnl_t chnlNumber,
|
||||
ftm_output_compare_mode_t compareMode,
|
||||
uint32_t compareValue);
|
||||
|
||||
/*!
|
||||
* @brief Configures the dual edge capture mode of the FTM.
|
||||
*
|
||||
* This function sets up the dual edge capture mode on a channel pair. The capture edge for the
|
||||
* channel pair and the capture mode (one-shot or continuous) is specified in the parameter
|
||||
* argument. The filter function is disabled if the filterVal argument passed is zero. The filter
|
||||
* function is available only on channels 0 and 2. The user has to read the channel CnV registers
|
||||
* separately to get the capture values.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
|
||||
* @param edgeParam Sets up the dual edge capture function
|
||||
* @param filterValue Filter value, specify 0 to disable filter. Available only for channel pair 0 and 1.
|
||||
*/
|
||||
void FTM_SetupDualEdgeCapture(FTM_Type *base,
|
||||
ftm_chnl_t chnlPairNumber,
|
||||
const ftm_dual_edge_capture_param_t *edgeParam,
|
||||
uint32_t filterValue);
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @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.
|
||||
*
|
||||
* FTM can have up to 4 fault inputs. This function sets up fault parameters, fault level, and a filter.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param faultNumber FTM fault to configure.
|
||||
* @param faultParams Parameters passed in to set up the fault
|
||||
*/
|
||||
void FTM_SetupFault(FTM_Type *base, ftm_fault_input_t faultNumber, const ftm_fault_param_t *faultParams);
|
||||
|
||||
/*!
|
||||
* @name Interrupt Interface
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables the selected FTM interrupts.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param mask The interrupts to enable. This is a logical OR of members of the
|
||||
* enumeration ::ftm_interrupt_enable_t
|
||||
*/
|
||||
void FTM_EnableInterrupts(FTM_Type *base, uint32_t mask);
|
||||
|
||||
/*!
|
||||
* @brief Disables the selected FTM interrupts.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param mask The interrupts to enable. This is a logical OR of members of the
|
||||
* enumeration ::ftm_interrupt_enable_t
|
||||
*/
|
||||
void FTM_DisableInterrupts(FTM_Type *base, uint32_t mask);
|
||||
|
||||
/*!
|
||||
* @brief Gets the enabled FTM interrupts.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
*
|
||||
* @return The enabled interrupts. This is the logical OR of members of the
|
||||
* enumeration ::ftm_interrupt_enable_t
|
||||
*/
|
||||
uint32_t FTM_GetEnabledInterrupts(FTM_Type *base);
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Status Interface
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Gets the FTM status flags.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
*
|
||||
* @return The status flags. This is the logical OR of members of the
|
||||
* enumeration ::ftm_status_flags_t
|
||||
*/
|
||||
uint32_t FTM_GetStatusFlags(FTM_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Clears the FTM status flags.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param mask The status flags to clear. This is a logical OR of members of the
|
||||
* enumeration ::ftm_status_flags_t
|
||||
*/
|
||||
void FTM_ClearStatusFlags(FTM_Type *base, uint32_t mask);
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Timer Start and Stop
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Starts the FTM counter.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param clockSource FTM clock source; After the clock source is set, the counter starts running.
|
||||
*/
|
||||
static inline void FTM_StartTimer(FTM_Type *base, ftm_clock_source_t clockSource)
|
||||
{
|
||||
uint32_t reg = base->SC;
|
||||
|
||||
reg &= ~(FTM_SC_CLKS_MASK);
|
||||
reg |= FTM_SC_CLKS(clockSource);
|
||||
base->SC = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Stops the FTM counter.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
*/
|
||||
static inline void FTM_StopTimer(FTM_Type *base)
|
||||
{
|
||||
/* Set clock source to none to disable counter */
|
||||
base->SC &= ~(FTM_SC_CLKS_MASK);
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Software output control
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables the channel software output control.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlNumber Channel to be enabled or disabled
|
||||
* @param value true: channel output is affected by software output control
|
||||
false: channel output is unaffected by software output control
|
||||
*/
|
||||
static inline void FTM_SetSoftwareCtrlEnable(FTM_Type *base, ftm_chnl_t chnlNumber, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
base->SWOCTRL |= (1U << chnlNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
base->SWOCTRL &= ~(1U << chnlNumber);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the channel software output control value.
|
||||
*
|
||||
* @param base FTM peripheral base address.
|
||||
* @param chnlNumber Channel to be configured
|
||||
* @param value true to set 1, false to set 0
|
||||
*/
|
||||
static inline void FTM_SetSoftwareCtrlVal(FTM_Type *base, ftm_chnl_t chnlNumber, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
base->SWOCTRL |= (1U << (chnlNumber + FTM_SWOCTRL_CH0OCV_SHIFT));
|
||||
}
|
||||
else
|
||||
{
|
||||
base->SWOCTRL &= ~(1U << (chnlNumber + FTM_SWOCTRL_CH0OCV_SHIFT));
|
||||
}
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables the FTM global time base signal generation to other FTMs.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
static inline void FTM_SetGlobalTimeBaseOutputEnable(FTM_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->CONF |= FTM_CONF_GTBEOUT_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CONF &= ~FTM_CONF_GTBEOUT_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the FTM peripheral timer channel output mask.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlNumber Channel to be configured
|
||||
* @param mask true: masked, channel is forced to its inactive state; false: unmasked
|
||||
*/
|
||||
static inline void FTM_SetOutputMask(FTM_Type *base, ftm_chnl_t chnlNumber, bool mask)
|
||||
{
|
||||
if (mask)
|
||||
{
|
||||
base->OUTMASK |= (1U << chnlNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
base->OUTMASK &= ~(1U << chnlNumber);
|
||||
}
|
||||
}
|
||||
|
||||
#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.
|
||||
*
|
||||
* To enable the PWM channel output call this function with val=true. For input mode,
|
||||
* call this function with val=false.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlNumber Channel to be configured
|
||||
* @param value true: enable output; false: output is disabled, used in input mode
|
||||
*/
|
||||
static inline void FTM_SetPwmOutputEnable(FTM_Type *base, ftm_chnl_t chnlNumber, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
base->SC |= (1U << (chnlNumber + FTM_SC_PWMEN0_SHIFT));
|
||||
}
|
||||
else
|
||||
{
|
||||
base->SC &= ~(1U << (chnlNumber + FTM_SC_PWMEN0_SHIFT));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Channel pair operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief This function enables/disables the fault control in a channel pair.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
|
||||
* @param value true: Enable fault control for this channel pair; false: No fault control
|
||||
*/
|
||||
static inline void FTM_SetFaultControlEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
base->COMBINE |= (1U << (FTM_COMBINE_FAULTEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
|
||||
}
|
||||
else
|
||||
{
|
||||
base->COMBINE &= ~(1U << (FTM_COMBINE_FAULTEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief This function enables/disables the dead time insertion in a channel pair.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
|
||||
* @param value true: Insert dead time in this channel pair; false: No dead time inserted
|
||||
*/
|
||||
static inline void FTM_SetDeadTimeEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
base->COMBINE |= (1U << (FTM_COMBINE_DTEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
|
||||
}
|
||||
else
|
||||
{
|
||||
base->COMBINE &= ~(1U << (FTM_COMBINE_DTEN0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief This function enables/disables complementary mode in a channel pair.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
|
||||
* @param value true: enable complementary mode; false: disable complementary mode
|
||||
*/
|
||||
static inline void FTM_SetComplementaryEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
base->COMBINE |= (1U << (FTM_COMBINE_COMP0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
|
||||
}
|
||||
else
|
||||
{
|
||||
base->COMBINE &= ~(1U << (FTM_COMBINE_COMP0_SHIFT + (FTM_COMBINE_COMBINE1_SHIFT * chnlPairNumber)));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief This function enables/disables inverting control in a channel pair.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param chnlPairNumber The FTM channel pair number; options are 0, 1, 2, 3
|
||||
* @param value true: enable inverting; false: disable inverting
|
||||
*/
|
||||
static inline void FTM_SetInvertEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
base->INVCTRL |= (1U << chnlPairNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
base->INVCTRL &= ~(1U << chnlPairNumber);
|
||||
}
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables the FTM software trigger for PWM synchronization.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param enable true: software trigger is selected, false: software trigger is not selected
|
||||
*/
|
||||
static inline void FTM_SetSoftwareTrigger(FTM_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->SYNC |= FTM_SYNC_SWSYNC_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->SYNC &= ~FTM_SYNC_SWSYNC_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables the FTM write protection.
|
||||
*
|
||||
* @param base FTM peripheral base address
|
||||
* @param enable true: Write-protection is enabled, false: Write-protection is disabled
|
||||
*/
|
||||
static inline void FTM_SetWriteProtection(FTM_Type *base, bool enable)
|
||||
{
|
||||
/* Configure write protection */
|
||||
if (enable)
|
||||
{
|
||||
base->FMS |= FTM_FMS_WPEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->MODE |= FTM_MODE_WPDIS_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_FTM_H_*/
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_gpio.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
static PORT_Type *const s_portBases[] = PORT_BASE_PTRS;
|
||||
static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Gets the GPIO instance according to the GPIO base
|
||||
*
|
||||
* @param base GPIO peripheral base pointer(PTA, PTB, PTC, etc.)
|
||||
* @retval GPIO instance
|
||||
*/
|
||||
static uint32_t GPIO_GetInstance(GPIO_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
static uint32_t GPIO_GetInstance(GPIO_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_GPIO_COUNT; instance++)
|
||||
{
|
||||
if (s_gpioBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < FSL_FEATURE_SOC_GPIO_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
if (config->pinDirection == kGPIO_DigitalInput)
|
||||
{
|
||||
base->PDDR &= ~(1U << pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO_WritePinOutput(base, pin, config->outputLogic);
|
||||
base->PDDR |= (1U << pin);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base)
|
||||
{
|
||||
uint8_t instance;
|
||||
PORT_Type *portBase;
|
||||
instance = GPIO_GetInstance(base);
|
||||
portBase = s_portBases[instance];
|
||||
return portBase->ISFR;
|
||||
}
|
||||
|
||||
void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
uint8_t instance;
|
||||
PORT_Type *portBase;
|
||||
instance = GPIO_GetInstance(base);
|
||||
portBase = s_portBases[instance];
|
||||
portBase->ISFR = mask;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
static FGPIO_Type *const s_fgpioBases[] = FGPIO_BASE_PTRS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Gets the FGPIO instance according to the GPIO base
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer(PTA, PTB, PTC, etc.)
|
||||
* @retval FGPIO instance
|
||||
*/
|
||||
static uint32_t FGPIO_GetInstance(FGPIO_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
static uint32_t FGPIO_GetInstance(FGPIO_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_FGPIO_COUNT; instance++)
|
||||
{
|
||||
if (s_fgpioBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < FSL_FEATURE_SOC_FGPIO_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
if (config->pinDirection == kGPIO_DigitalInput)
|
||||
{
|
||||
base->PDDR &= ~(1U << pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
FGPIO_WritePinOutput(base, pin, config->outputLogic);
|
||||
base->PDDR |= (1U << pin);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base)
|
||||
{
|
||||
uint8_t instance;
|
||||
instance = FGPIO_GetInstance(base);
|
||||
PORT_Type *portBase;
|
||||
portBase = s_portBases[instance];
|
||||
return portBase->ISFR;
|
||||
}
|
||||
|
||||
void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
uint8_t instance;
|
||||
instance = FGPIO_GetInstance(base);
|
||||
PORT_Type *portBase;
|
||||
portBase = s_portBases[instance];
|
||||
portBase->ISFR = mask;
|
||||
}
|
||||
|
||||
#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */
|
|
@ -0,0 +1,390 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SDRVL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FSL_GPIO_H_
|
||||
#define _FSL_GPIO_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup gpio
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief GPIO driver version 2.1.0. */
|
||||
#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief GPIO direction definition*/
|
||||
typedef enum _gpio_pin_direction
|
||||
{
|
||||
kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/
|
||||
kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/
|
||||
} gpio_pin_direction_t;
|
||||
|
||||
/*!
|
||||
* @brief The GPIO pin configuration structure.
|
||||
*
|
||||
* Every pin can only be configured as either output pin or input pin at a time.
|
||||
* If configured as a input pin, then leave the outputConfig unused
|
||||
* Note : In some cases, the corresponding port property should be configured in advance
|
||||
* with the PORT_SetPinConfig()
|
||||
*/
|
||||
typedef struct _gpio_pin_config
|
||||
{
|
||||
gpio_pin_direction_t pinDirection; /*!< gpio direction, input or output */
|
||||
/* Output configurations, please ignore if configured as a input one */
|
||||
uint8_t outputLogic; /*!< Set default output logic, no use in input */
|
||||
} gpio_pin_config_t;
|
||||
|
||||
/*! @} */
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @addtogroup gpio_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @name GPIO Configuration */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes a GPIO pin used by the board.
|
||||
*
|
||||
* To initialize the GPIO, define a pin configuration, either input or output, in the user file.
|
||||
* Then, call the GPIO_PinInit() function.
|
||||
*
|
||||
* This is an example to define an input pin or output pin configuration:
|
||||
* @code
|
||||
* // Define a digital input pin configuration,
|
||||
* gpio_pin_config_t config =
|
||||
* {
|
||||
* kGPIO_DigitalInput,
|
||||
* 0,
|
||||
* }
|
||||
* //Define a digital output pin configuration,
|
||||
* gpio_pin_config_t config =
|
||||
* {
|
||||
* kGPIO_DigitalOutput,
|
||||
* 0,
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param pin GPIO port pin number
|
||||
* @param config GPIO pin configuration pointer
|
||||
*/
|
||||
void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*! @name GPIO Output Operations */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple GPIO pins to the logic 1 or 0.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param pin GPIO pin's number
|
||||
* @param output GPIO pin output logic level.
|
||||
* - 0: corresponding pin output low logic level.
|
||||
* - 1: corresponding pin output high logic level.
|
||||
*/
|
||||
static inline void GPIO_WritePinOutput(GPIO_Type *base, uint32_t pin, uint8_t output)
|
||||
{
|
||||
if (output == 0U)
|
||||
{
|
||||
base->PCOR = 1 << pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->PSOR = 1 << pin;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple GPIO pins to the logic 1.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask GPIO pins' numbers macro
|
||||
*/
|
||||
static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->PSOR = mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple GPIO pins to the logic 0.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask GPIO pins' numbers macro
|
||||
*/
|
||||
static inline void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->PCOR = mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reverses current output logic of the multiple GPIO pins.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask GPIO pins' numbers macro
|
||||
*/
|
||||
static inline void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->PTOR = mask;
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
/*! @name GPIO Input Operations */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Reads the current input value of the whole GPIO port.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param pin GPIO pin's number
|
||||
* @retval GPIO port input value
|
||||
* - 0: corresponding pin input low logic level.
|
||||
* - 1: corresponding pin input high logic level.
|
||||
*/
|
||||
static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin)
|
||||
{
|
||||
return (((base->PDIR) >> pin) & 0x01U);
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
/*! @name GPIO Interrupt */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Reads whole GPIO port interrupt status flag.
|
||||
*
|
||||
* If a pin is configured to generate the DMA request, the corresponding flag
|
||||
* is cleared automatically at the completion of the requested DMA transfer.
|
||||
* Otherwise, the flag remains set until a logic one is written to that flag.
|
||||
* If configured for a level sensitive interrupt that remains asserted, the flag
|
||||
* is set again immediately.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @retval Current GPIO port interrupt status flag, for example, 0x00010001 means the
|
||||
* pin 0 and 17 have the interrupt.
|
||||
*/
|
||||
uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Clears multiple GPIO pins' interrupt status flag.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask GPIO pins' numbers macro
|
||||
*/
|
||||
void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask);
|
||||
|
||||
/*@}*/
|
||||
/*! @} */
|
||||
|
||||
/*!
|
||||
* @addtogroup fgpio_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* Introduce the FGPIO feature.
|
||||
*
|
||||
* The FGPIO features are only support on some of Kinetis chips. The FGPIO registers are aliased to the IOPORT
|
||||
* interface. Accesses via the IOPORT interface occur in parallel with any instruction fetches and will therefore
|
||||
* complete in a single cycle. This aliased Fast GPIO memory map is called FGPIO.
|
||||
*/
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
|
||||
|
||||
/*! @name FGPIO Configuration */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes a FGPIO pin used by the board.
|
||||
*
|
||||
* To initialize the FGPIO driver, define a pin configuration, either input or output, in the user file.
|
||||
* Then, call the FGPIO_PinInit() function.
|
||||
*
|
||||
* This is an example to define an input pin or output pin configuration:
|
||||
* @code
|
||||
* // Define a digital input pin configuration,
|
||||
* gpio_pin_config_t config =
|
||||
* {
|
||||
* kGPIO_DigitalInput,
|
||||
* 0,
|
||||
* }
|
||||
* //Define a digital output pin configuration,
|
||||
* gpio_pin_config_t config =
|
||||
* {
|
||||
* kGPIO_DigitalOutput,
|
||||
* 0,
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param pin FGPIO port pin number
|
||||
* @param config FGPIO pin configuration pointer
|
||||
*/
|
||||
void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*! @name FGPIO Output Operations */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple FGPIO pins to the logic 1 or 0.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param pin FGPIO pin's number
|
||||
* @param output FGPIOpin output logic level.
|
||||
* - 0: corresponding pin output low logic level.
|
||||
* - 1: corresponding pin output high logic level.
|
||||
*/
|
||||
static inline void FGPIO_WritePinOutput(FGPIO_Type *base, uint32_t pin, uint8_t output)
|
||||
{
|
||||
if (output == 0U)
|
||||
{
|
||||
base->PCOR = 1 << pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->PSOR = 1 << pin;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple FGPIO pins to the logic 1.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask FGPIO pins' numbers macro
|
||||
*/
|
||||
static inline void FGPIO_SetPinsOutput(FGPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->PSOR = mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple FGPIO pins to the logic 0.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask FGPIO pins' numbers macro
|
||||
*/
|
||||
static inline void FGPIO_ClearPinsOutput(FGPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->PCOR = mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reverses current output logic of the multiple FGPIO pins.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask FGPIO pins' numbers macro
|
||||
*/
|
||||
static inline void FGPIO_TogglePinsOutput(FGPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->PTOR = mask;
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
/*! @name FGPIO Input Operations */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Reads the current input value of the whole FGPIO port.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param pin FGPIO pin's number
|
||||
* @retval FGPIO port input value
|
||||
* - 0: corresponding pin input low logic level.
|
||||
* - 1: corresponding pin input high logic level.
|
||||
*/
|
||||
static inline uint32_t FGPIO_ReadPinInput(FGPIO_Type *base, uint32_t pin)
|
||||
{
|
||||
return (((base->PDIR) >> pin) & 0x01U);
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
/*! @name FGPIO Interrupt */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Reads the whole FGPIO port interrupt status flag.
|
||||
*
|
||||
* If a pin is configured to generate the DMA request, the corresponding flag
|
||||
* is cleared automatically at the completion of the requested DMA transfer.
|
||||
* Otherwise, the flag remains set until a logic one is written to that flag.
|
||||
* If configured for a level sensitive interrupt that remains asserted, the flag
|
||||
* is set again immediately.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @retval Current FGPIO port interrupt status flags, for example, 0x00010001 means the
|
||||
* pin 0 and 17 have the interrupt.
|
||||
*/
|
||||
uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Clears the multiple FGPIO pins' interrupt status flag.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask FGPIO pins' numbers macro
|
||||
*/
|
||||
void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask);
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _FSL_GPIO_H_*/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,781 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_I2C_H_
|
||||
#define _FSL_I2C_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup i2c_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief I2C driver version 2.0.0. */
|
||||
#define FSL_I2C_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
#if (defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT || \
|
||||
defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT)
|
||||
#define I2C_HAS_STOP_DETECT
|
||||
#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT / FSL_FEATURE_I2C_HAS_STOP_DETECT */
|
||||
|
||||
/*! @brief I2C status return codes. */
|
||||
enum _i2c_status
|
||||
{
|
||||
kStatus_I2C_Busy = MAKE_STATUS(kStatusGroup_I2C, 0), /*!< I2C is busy with current transfer. */
|
||||
kStatus_I2C_Idle = MAKE_STATUS(kStatusGroup_I2C, 1), /*!< Bus is Idle. */
|
||||
kStatus_I2C_Nak = MAKE_STATUS(kStatusGroup_I2C, 2), /*!< NAK received during transfer. */
|
||||
kStatus_I2C_ArbitrationLost = MAKE_STATUS(kStatusGroup_I2C, 3), /*!< Arbitration lost during transfer. */
|
||||
kStatus_I2C_Timeout = MAKE_STATUS(kStatusGroup_I2C, 4), /*!< Wait event timeout. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief I2C peripheral flags
|
||||
*
|
||||
* The following status register flags can be cleared:
|
||||
* - #kI2C_ArbitrationLostFlag
|
||||
* - #kI2C_IntPendingFlag
|
||||
* - #kI2C_StartDetectFlag
|
||||
* - #kI2C_StopDetectFlag
|
||||
*
|
||||
* @note These enumerations are meant to be OR'd together to form a bit mask.
|
||||
*
|
||||
*/
|
||||
enum _i2c_flags
|
||||
{
|
||||
kI2C_ReceiveNakFlag = I2C_S_RXAK_MASK, /*!< I2C receive NAK flag. */
|
||||
kI2C_IntPendingFlag = I2C_S_IICIF_MASK, /*!< I2C interrupt pending flag. */
|
||||
kI2C_TransferDirectionFlag = I2C_S_SRW_MASK, /*!< I2C transfer direction flag. */
|
||||
kI2C_RangeAddressMatchFlag = I2C_S_RAM_MASK, /*!< I2C range address match flag. */
|
||||
kI2C_ArbitrationLostFlag = I2C_S_ARBL_MASK, /*!< I2C arbitration lost flag. */
|
||||
kI2C_BusBusyFlag = I2C_S_BUSY_MASK, /*!< I2C bus busy flag. */
|
||||
kI2C_AddressMatchFlag = I2C_S_IAAS_MASK, /*!< I2C address match flag. */
|
||||
kI2C_TransferCompleteFlag = I2C_S_TCF_MASK, /*!< I2C transfer complete flag. */
|
||||
#ifdef I2C_HAS_STOP_DETECT
|
||||
kI2C_StopDetectFlag = I2C_FLT_STOPF_MASK << 8, /*!< I2C stop detect flag. */
|
||||
#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT / FSL_FEATURE_I2C_HAS_STOP_DETECT */
|
||||
|
||||
#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
|
||||
kI2C_StartDetectFlag = I2C_FLT_STARTF_MASK << 8, /*!< I2C start detect flag. */
|
||||
#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
|
||||
};
|
||||
|
||||
/*! @brief I2C feature interrupt source. */
|
||||
enum _i2c_interrupt_enable
|
||||
{
|
||||
kI2C_GlobalInterruptEnable = I2C_C1_IICIE_MASK, /*!< I2C global interrupt. */
|
||||
|
||||
#if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
|
||||
kI2C_StopDetectInterruptEnable = I2C_FLT_STOPIE_MASK, /*!< I2C stop detect interrupt. */
|
||||
#endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */
|
||||
|
||||
#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
|
||||
kI2C_StartStopDetectInterruptEnable = I2C_FLT_SSIE_MASK, /*!< I2C start&stop detect interrupt. */
|
||||
#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
|
||||
};
|
||||
|
||||
/*! @brief Direction of master and slave transfers. */
|
||||
typedef enum _i2c_direction
|
||||
{
|
||||
kI2C_Write = 0x0U, /*!< Master transmit to slave. */
|
||||
kI2C_Read = 0x1U, /*!< Master receive from slave. */
|
||||
} i2c_direction_t;
|
||||
|
||||
/*! @brief Addressing mode. */
|
||||
typedef enum _i2c_slave_address_mode
|
||||
{
|
||||
kI2C_Address7bit = 0x0U, /*!< 7-bit addressing mode. */
|
||||
kI2C_RangeMatch = 0X2U, /*!< Range address match addressing mode. */
|
||||
} i2c_slave_address_mode_t;
|
||||
|
||||
/*! @brief I2C transfer control flag. */
|
||||
enum _i2c_master_transfer_flags
|
||||
{
|
||||
kI2C_TransferDefaultFlag = 0x0U, /*!< Transfer starts with a start signal, stops with a stop signal. */
|
||||
kI2C_TransferNoStartFlag = 0x1U, /*!< Transfer starts without a start signal. */
|
||||
kI2C_TransferRepeatedStartFlag = 0x2U, /*!< Transfer starts with a repeated start signal. */
|
||||
kI2C_TransferNoStopFlag = 0x4U, /*!< Transfer ends without a stop signal. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief Set of events sent to the callback for nonblocking slave transfers.
|
||||
*
|
||||
* These event enumerations are used for two related purposes. First, a bit mask created by OR'ing together
|
||||
* events is passed to I2C_SlaveTransferNonBlocking() in order to specify which events to enable.
|
||||
* Then, when the slave callback is invoked, it is passed the current event through its @a transfer
|
||||
* parameter.
|
||||
*
|
||||
* @note These enumerations are meant to be OR'd together to form a bit mask of events.
|
||||
*/
|
||||
typedef enum _i2c_slave_transfer_event
|
||||
{
|
||||
kI2C_SlaveAddressMatchEvent = 0x01U, /*!< Received the slave address after a start or repeated start. */
|
||||
kI2C_SlaveTransmitEvent = 0x02U, /*!< Callback is requested to provide data to transmit
|
||||
(slave-transmitter role). */
|
||||
kI2C_SlaveReceiveEvent = 0x04U, /*!< Callback is requested to provide a buffer in which to place received
|
||||
data (slave-receiver role). */
|
||||
kI2C_SlaveTransmitAckEvent = 0x08U, /*!< Callback needs to either transmit an ACK or NACK. */
|
||||
#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
|
||||
kI2C_SlaveRepeatedStartEvent = 0x10U, /*!< A repeated start was detected. */
|
||||
#endif
|
||||
kI2C_SlaveCompletionEvent = 0x20U, /*!< A stop was detected or finished transfer, completing the transfer. */
|
||||
|
||||
/*! Bit mask of all available events. */
|
||||
kI2C_SlaveAllEvents = kI2C_SlaveAddressMatchEvent | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent |
|
||||
#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
|
||||
kI2C_SlaveRepeatedStartEvent |
|
||||
#endif
|
||||
kI2C_SlaveCompletionEvent,
|
||||
} i2c_slave_transfer_event_t;
|
||||
|
||||
/*! @brief I2C master user configuration. */
|
||||
typedef struct _i2c_master_config
|
||||
{
|
||||
bool enableMaster; /*!< Enables the I2C peripheral at initialization time. */
|
||||
#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION
|
||||
bool enableHighDrive; /*!< Controls the drive capability of the I2C pads. */
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF
|
||||
bool enableStopHold; /*!< Controls the stop hold enable. */
|
||||
#endif
|
||||
uint32_t baudRate_Bps; /*!< Baud rate configuration of I2C peripheral. */
|
||||
uint8_t glitchFilterWidth; /*!< Controls the width of the glitch. */
|
||||
} i2c_master_config_t;
|
||||
|
||||
/*! @brief I2C slave user configuration. */
|
||||
typedef struct _i2c_slave_config
|
||||
{
|
||||
bool enableSlave; /*!< Enables the I2C peripheral at initialization time. */
|
||||
bool enableGeneralCall; /*!< Enable general call addressing mode. */
|
||||
bool enableWakeUp; /*!< Enables/disables waking up MCU from low power mode. */
|
||||
#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION
|
||||
bool enableHighDrive; /*!< Controls the drive capability of the I2C pads. */
|
||||
#endif
|
||||
bool enableBaudRateCtl; /*!< Enables/disables independent slave baud rate on SCL in very fast I2C modes. */
|
||||
uint16_t slaveAddress; /*!< Slave address configuration. */
|
||||
uint16_t upperAddress; /*!< Maximum boundary slave address used in range matching mode. */
|
||||
i2c_slave_address_mode_t addressingMode; /*!< Addressing mode configuration of i2c_slave_address_mode_config_t. */
|
||||
} i2c_slave_config_t;
|
||||
|
||||
/*! @brief I2C master handle typedef. */
|
||||
typedef struct _i2c_master_handle i2c_master_handle_t;
|
||||
|
||||
/*! @brief I2C master transfer callback typedef. */
|
||||
typedef void (*i2c_master_transfer_callback_t)(I2C_Type *base,
|
||||
i2c_master_handle_t *handle,
|
||||
status_t status,
|
||||
void *userData);
|
||||
|
||||
/*! @brief I2C slave handle typedef. */
|
||||
typedef struct _i2c_slave_handle i2c_slave_handle_t;
|
||||
|
||||
/*! @brief I2C master transfer structure. */
|
||||
typedef struct _i2c_master_transfer
|
||||
{
|
||||
uint32_t flags; /*!< Transfer flag which controls the transfer. */
|
||||
uint8_t slaveAddress; /*!< 7-bit slave address. */
|
||||
i2c_direction_t direction; /*!< Transfer direction, read or write. */
|
||||
uint32_t subaddress; /*!< Sub address. Transferred MSB first. */
|
||||
uint8_t subaddressSize; /*!< Size of command buffer. */
|
||||
uint8_t *volatile data; /*!< Transfer buffer. */
|
||||
volatile size_t dataSize; /*!< Transfer size. */
|
||||
} i2c_master_transfer_t;
|
||||
|
||||
/*! @brief I2C master handle structure. */
|
||||
struct _i2c_master_handle
|
||||
{
|
||||
i2c_master_transfer_t transfer; /*!< I2C master transfer copy. */
|
||||
size_t transferSize; /*!< Total bytes to be transferred. */
|
||||
uint8_t state; /*!< Transfer state maintained during transfer. */
|
||||
i2c_master_transfer_callback_t completionCallback; /*!< Callback function called when transfer finished. */
|
||||
void *userData; /*!< Callback parameter passed to callback function. */
|
||||
};
|
||||
|
||||
/*! @brief I2C slave transfer structure. */
|
||||
typedef struct _i2c_slave_transfer
|
||||
{
|
||||
i2c_slave_transfer_event_t event; /*!< Reason the callback is being invoked. */
|
||||
uint8_t *volatile data; /*!< Transfer buffer. */
|
||||
volatile size_t dataSize; /*!< Transfer size. */
|
||||
status_t completionStatus; /*!< Success or error code describing how the transfer completed. Only applies for
|
||||
#kI2C_SlaveCompletionEvent. */
|
||||
size_t transferredCount; /*!< Number of bytes actually transferred since start or last repeated start. */
|
||||
} i2c_slave_transfer_t;
|
||||
|
||||
/*! @brief I2C slave transfer callback typedef. */
|
||||
typedef void (*i2c_slave_transfer_callback_t)(I2C_Type *base, i2c_slave_transfer_t *xfer, void *userData);
|
||||
|
||||
/*! @brief I2C slave handle structure. */
|
||||
struct _i2c_slave_handle
|
||||
{
|
||||
bool isBusy; /*!< Whether transfer is busy. */
|
||||
i2c_slave_transfer_t transfer; /*!< I2C slave transfer copy. */
|
||||
uint32_t eventMask; /*!< Mask of enabled events. */
|
||||
i2c_slave_transfer_callback_t callback; /*!< Callback function called at transfer event. */
|
||||
void *userData; /*!< Callback parameter passed to callback. */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /*_cplusplus. */
|
||||
|
||||
/*!
|
||||
* @name Initialization and deinitialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock
|
||||
* and configure the I2C with master configuration.
|
||||
*
|
||||
* @note This API should be called at the beginning of the application to use
|
||||
* the I2C driver, or any operation to the I2C module could cause hard fault
|
||||
* because clock is not enabled. The configuration structure can be filled by user
|
||||
* from scratch, or be set with default values by I2C_MasterGetDefaultConfig().
|
||||
* After calling this API, the master is ready to transfer.
|
||||
* Example:
|
||||
* @code
|
||||
* i2c_master_config_t config = {
|
||||
* .enableMaster = true,
|
||||
* .enableStopHold = false,
|
||||
* .highDrive = false,
|
||||
* .baudRate_Bps = 100000,
|
||||
* .glitchFilterWidth = 0
|
||||
* };
|
||||
* I2C_MasterInit(I2C0, &config, 12000000U);
|
||||
* @endcode
|
||||
*
|
||||
* @param base I2C base pointer
|
||||
* @param masterConfig pointer to master configuration structure
|
||||
* @param srcClock_Hz I2C peripheral clock frequency in Hz
|
||||
*/
|
||||
void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock
|
||||
* and initializes the I2C with slave configuration.
|
||||
*
|
||||
* @note This API should be called at the beginning of the application to use
|
||||
* the I2C driver, or any operation to the I2C module can cause a hard fault
|
||||
* because the clock is not enabled. The configuration structure can partly be set
|
||||
* with default values by I2C_SlaveGetDefaultConfig(), or can be filled by the user.
|
||||
* Example
|
||||
* @code
|
||||
* i2c_slave_config_t config = {
|
||||
* .enableSlave = true,
|
||||
* .enableGeneralCall = false,
|
||||
* .addressingMode = kI2C_Address7bit,
|
||||
* .slaveAddress = 0x1DU,
|
||||
* .enableWakeUp = false,
|
||||
* .enablehighDrive = false,
|
||||
* .enableBaudRateCtl = false
|
||||
* };
|
||||
* I2C_SlaveInit(I2C0, &config);
|
||||
* @endcode
|
||||
*
|
||||
* @param base I2C base pointer
|
||||
* @param slaveConfig pointer to slave configuration structure
|
||||
*/
|
||||
void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig);
|
||||
|
||||
/*!
|
||||
* @brief De-initializes the I2C master peripheral. Call this API to gate the I2C clock.
|
||||
* The I2C master module can't work unless the I2C_MasterInit is called.
|
||||
* @param base I2C base pointer
|
||||
*/
|
||||
void I2C_MasterDeinit(I2C_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief De-initializes the I2C slave peripheral. Calling this API gates the I2C clock.
|
||||
* The I2C slave module can't work unless the I2C_SlaveInit is called to enable the clock.
|
||||
* @param base I2C base pointer
|
||||
*/
|
||||
void I2C_SlaveDeinit(I2C_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Sets the I2C master configuration structure to default values.
|
||||
*
|
||||
* The purpose of this API is to get the configuration structure initialized for use in the I2C_MasterConfigure().
|
||||
* Use the initialized structure unchanged in I2C_MasterConfigure(), or modify some fields of
|
||||
* the structure before calling I2C_MasterConfigure().
|
||||
* Example:
|
||||
* @code
|
||||
* i2c_master_config_t config;
|
||||
* I2C_MasterGetDefaultConfig(&config);
|
||||
* @endcode
|
||||
* @param masterConfig Pointer to the master configuration structure.
|
||||
*/
|
||||
void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig);
|
||||
|
||||
/*!
|
||||
* @brief Sets the I2C slave configuration structure to default values.
|
||||
*
|
||||
* The purpose of this API is to get the configuration structure initialized for use in I2C_SlaveConfigure().
|
||||
* Modify fields of the structure before calling the I2C_SlaveConfigure().
|
||||
* Example:
|
||||
* @code
|
||||
* i2c_slave_config_t config;
|
||||
* I2C_SlaveGetDefaultConfig(&config);
|
||||
* @endcode
|
||||
* @param slaveConfig Pointer to the slave configuration structure.
|
||||
*/
|
||||
void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig);
|
||||
|
||||
/*!
|
||||
* @brief Enables or disabless the I2C peripheral operation.
|
||||
*
|
||||
* @param base I2C base pointer
|
||||
* @param enable pass true to enable module, false to disable module
|
||||
*/
|
||||
static inline void I2C_Enable(I2C_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->C1 |= I2C_C1_IICEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->C1 &= ~I2C_C1_IICEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Status
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Gets the I2C status flags.
|
||||
*
|
||||
* @param base I2C base pointer
|
||||
* @return status flag, use status flag to AND #_i2c_flags could get the related status.
|
||||
*/
|
||||
uint32_t I2C_MasterGetStatusFlags(I2C_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Gets the I2C status flags.
|
||||
*
|
||||
* @param base I2C base pointer
|
||||
* @return status flag, use status flag to AND #_i2c_flags could get the related status.
|
||||
*/
|
||||
static inline uint32_t I2C_SlaveGetStatusFlags(I2C_Type *base)
|
||||
{
|
||||
return I2C_MasterGetStatusFlags(base);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the I2C status flag state.
|
||||
*
|
||||
* The following status register flags can be cleared: kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag
|
||||
*
|
||||
* @param base I2C base pointer
|
||||
* @param statusMask The status flag mask, defined in type i2c_status_flag_t.
|
||||
* The parameter could be any combination of the following values:
|
||||
* @arg kI2C_StartDetectFlag (if available)
|
||||
* @arg kI2C_StopDetectFlag (if available)
|
||||
* @arg kI2C_ArbitrationLostFlag
|
||||
* @arg kI2C_IntPendingFlagFlag
|
||||
*/
|
||||
static inline void I2C_MasterClearStatusFlags(I2C_Type *base, uint32_t statusMask)
|
||||
{
|
||||
/* Must clear the STARTF / STOPF bits prior to clearing IICIF */
|
||||
#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
|
||||
if (statusMask & kI2C_StartDetectFlag)
|
||||
{
|
||||
/* Shift the odd-ball flags back into place. */
|
||||
base->FLT |= (uint8_t)(statusMask >> 8U);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef I2C_HAS_STOP_DETECT
|
||||
if (statusMask & kI2C_StopDetectFlag)
|
||||
{
|
||||
/* Shift the odd-ball flags back into place. */
|
||||
base->FLT |= (uint8_t)(statusMask >> 8U);
|
||||
}
|
||||
#endif
|
||||
|
||||
base->S = (uint8_t)statusMask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the I2C status flag state.
|
||||
*
|
||||
* The following status register flags can be cleared: kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag
|
||||
*
|
||||
* @param base I2C base pointer
|
||||
* @param statusMask The status flag mask, defined in type i2c_status_flag_t.
|
||||
* The parameter could be any combination of the following values:
|
||||
* @arg kI2C_StartDetectFlag (if available)
|
||||
* @arg kI2C_StopDetectFlag (if available)
|
||||
* @arg kI2C_ArbitrationLostFlag
|
||||
* @arg kI2C_IntPendingFlagFlag
|
||||
*/
|
||||
static inline void I2C_SlaveClearStatusFlags(I2C_Type *base, uint32_t statusMask)
|
||||
{
|
||||
I2C_MasterClearStatusFlags(base, statusMask);
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Interrupts
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables I2C interrupt requests.
|
||||
*
|
||||
* @param base I2C base pointer
|
||||
* @param mask interrupt source
|
||||
* The parameter can be combination of the following source if defined:
|
||||
* @arg kI2C_GlobalInterruptEnable
|
||||
* @arg kI2C_StopDetectInterruptEnable/kI2C_StartDetectInterruptEnable
|
||||
* @arg kI2C_SdaTimeoutInterruptEnable
|
||||
*/
|
||||
void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask);
|
||||
|
||||
/*!
|
||||
* @brief Disables I2C interrupt requests.
|
||||
*
|
||||
* @param base I2C base pointer
|
||||
* @param mask interrupt source
|
||||
* The parameter can be combination of the following source if defined:
|
||||
* @arg kI2C_GlobalInterruptEnable
|
||||
* @arg kI2C_StopDetectInterruptEnable/kI2C_StartDetectInterruptEnable
|
||||
* @arg kI2C_SdaTimeoutInterruptEnable
|
||||
*/
|
||||
void I2C_DisableInterrupts(I2C_Type *base, uint32_t mask);
|
||||
|
||||
/*!
|
||||
* @name DMA Control
|
||||
* @{
|
||||
*/
|
||||
#if defined(FSL_FEATURE_I2C_HAS_DMA_SUPPORT) && FSL_FEATURE_I2C_HAS_DMA_SUPPORT
|
||||
/*!
|
||||
* @brief Enables/disables the I2C DMA interrupt.
|
||||
*
|
||||
* @param base I2C base pointer
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
static inline void I2C_EnableDMA(I2C_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->C1 |= I2C_C1_DMAEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->C1 &= ~I2C_C1_DMAEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FSL_FEATURE_I2C_HAS_DMA_SUPPORT */
|
||||
|
||||
/*!
|
||||
* @brief Gets the I2C tx/rx data register address. This API is used to provide a transfer address
|
||||
* for I2C DMA transfer configuration.
|
||||
*
|
||||
* @param base I2C base pointer
|
||||
* @return data register address
|
||||
*/
|
||||
static inline uint32_t I2C_GetDataRegAddr(I2C_Type *base)
|
||||
{
|
||||
return (uint32_t)(&(base->D));
|
||||
}
|
||||
|
||||
/* @} */
|
||||
/*!
|
||||
* @name Bus Operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Sets the I2C master transfer baud rate.
|
||||
*
|
||||
* @param base I2C base pointer
|
||||
* @param baudRate_Bps the baud rate value in bps
|
||||
* @param srcClock_Hz Source clock
|
||||
*/
|
||||
void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
|
||||
|
||||
/*!
|
||||
* @brief Sends a START on the I2C bus.
|
||||
*
|
||||
* This function is used to initiate a new master mode transfer by sending the START signal.
|
||||
* The slave address is sent following the I2C START signal.
|
||||
*
|
||||
* @param base I2C peripheral base pointer
|
||||
* @param address 7-bit slave device address.
|
||||
* @param direction Master transfer directions(transmit/receive).
|
||||
* @retval kStatus_Success Successfully send the start signal.
|
||||
* @retval kStatus_I2C_Busy Current bus is busy.
|
||||
*/
|
||||
status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction);
|
||||
|
||||
/*!
|
||||
* @brief Sends a STOP signal on the I2C bus.
|
||||
*
|
||||
* @retval kStatus_Success Successfully send the stop signal.
|
||||
* @retval kStatus_I2C_Timeout Send stop signal failed, timeout.
|
||||
*/
|
||||
status_t I2C_MasterStop(I2C_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Sends a REPEATED START on the I2C bus.
|
||||
*
|
||||
* @param base I2C peripheral base pointer
|
||||
* @param address 7-bit slave device address.
|
||||
* @param direction Master transfer directions(transmit/receive).
|
||||
* @retval kStatus_Success Successfully send the start signal.
|
||||
* @retval kStatus_I2C_Busy Current bus is busy but not occupied by current I2C master.
|
||||
*/
|
||||
status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction);
|
||||
|
||||
/*!
|
||||
* @brief Performs a polling send transaction on the I2C bus without a STOP signal.
|
||||
*
|
||||
* @param base The I2C peripheral base pointer.
|
||||
* @param txBuff The pointer to the data to be transferred.
|
||||
* @param txSize The length in bytes of the data to be transferred.
|
||||
* @retval kStatus_Success Successfully complete the data transmission.
|
||||
* @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
|
||||
* @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer.
|
||||
*/
|
||||
status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize);
|
||||
|
||||
/*!
|
||||
* @brief Performs a polling receive transaction on the I2C bus with a STOP signal.
|
||||
*
|
||||
* @note The I2C_MasterReadBlocking function stops the bus before reading the final byte.
|
||||
* Without stopping the bus prior for the final read, the bus issues another read, resulting
|
||||
* in garbage data being read into the data register.
|
||||
*
|
||||
* @param base I2C peripheral base pointer.
|
||||
* @param rxBuff The pointer to the data to store the received data.
|
||||
* @param rxSize The length in bytes of the data to be received.
|
||||
* @retval kStatus_Success Successfully complete the data transmission.
|
||||
* @retval kStatus_I2C_Timeout Send stop signal failed, timeout.
|
||||
*/
|
||||
status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize);
|
||||
|
||||
/*!
|
||||
* @brief Performs a polling send transaction on the I2C bus.
|
||||
*
|
||||
* @param base The I2C peripheral base pointer.
|
||||
* @param txBuff The pointer to the data to be transferred.
|
||||
* @param txSize The length in bytes of the data to be transferred.
|
||||
* @retval kStatus_Success Successfully complete the data transmission.
|
||||
* @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
|
||||
* @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer.
|
||||
*/
|
||||
status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize);
|
||||
|
||||
/*!
|
||||
* @brief Performs a polling receive transaction on the I2C bus.
|
||||
*
|
||||
* @param base I2C peripheral base pointer.
|
||||
* @param rxBuff The pointer to the data to store the received data.
|
||||
* @param rxSize The length in bytes of the data to be received.
|
||||
*/
|
||||
void I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize);
|
||||
|
||||
/*!
|
||||
* @brief Performs a master polling transfer on the I2C bus.
|
||||
*
|
||||
* @note The API does not return until the transfer succeeds or fails due
|
||||
* to arbitration lost or receiving a NAK.
|
||||
*
|
||||
* @param base I2C peripheral base address.
|
||||
* @param xfer Pointer to the transfer structure.
|
||||
* @retval kStatus_Success Successfully complete the data transmission.
|
||||
* @retval kStatus_I2C_Busy Previous transmission still not finished.
|
||||
* @retval kStatus_I2C_Timeout Transfer error, wait signal timeout.
|
||||
* @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
|
||||
* @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer.
|
||||
*/
|
||||
status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Transactional
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the I2C handle which is used in transactional functions.
|
||||
*
|
||||
* @param base I2C base pointer.
|
||||
* @param handle pointer to i2c_master_handle_t structure to store the transfer state.
|
||||
* @param callback pointer to user callback function.
|
||||
* @param userData user paramater passed to the callback function.
|
||||
*/
|
||||
void I2C_MasterTransferCreateHandle(I2C_Type *base,
|
||||
i2c_master_handle_t *handle,
|
||||
i2c_master_transfer_callback_t callback,
|
||||
void *userData);
|
||||
|
||||
/*!
|
||||
* @brief Performs a master interrupt non-blocking transfer on the I2C bus.
|
||||
*
|
||||
* @note Calling the API will return immediately after transfer initiates, user needs
|
||||
* to call I2C_MasterGetTransferCount to poll the transfer status to check whether
|
||||
* the transfer is finished, if the return status is not kStatus_I2C_Busy, the transfer
|
||||
* is finished.
|
||||
*
|
||||
* @param base I2C base pointer.
|
||||
* @param handle pointer to i2c_master_handle_t structure which stores the transfer state.
|
||||
* @param xfer pointer to i2c_master_transfer_t structure.
|
||||
* @retval kStatus_Success Sucessully start the data transmission.
|
||||
* @retval kStatus_I2C_Busy Previous transmission still not finished.
|
||||
* @retval kStatus_I2C_Timeout Transfer error, wait signal timeout.
|
||||
*/
|
||||
status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Gets the master transfer status during a interrupt non-blocking transfer.
|
||||
*
|
||||
* @param base I2C base pointer.
|
||||
* @param handle pointer to i2c_master_handle_t structure which stores the transfer state.
|
||||
* @param count Number of bytes transferred so far by the non-blocking transaction.
|
||||
* @retval kStatus_InvalidArgument count is Invalid.
|
||||
* @retval kStatus_Success Successfully return the count.
|
||||
*/
|
||||
status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count);
|
||||
|
||||
/*!
|
||||
* @brief Aborts an interrupt non-blocking transfer early.
|
||||
*
|
||||
* @note This API can be called at any time when an interrupt non-blocking transfer initiates
|
||||
* to abort the transfer early.
|
||||
*
|
||||
* @param base I2C base pointer.
|
||||
* @param handle pointer to i2c_master_handle_t structure which stores the transfer state
|
||||
*/
|
||||
void I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Master interrupt handler.
|
||||
*
|
||||
* @param base I2C base pointer.
|
||||
* @param i2cHandle pointer to i2c_master_handle_t structure.
|
||||
*/
|
||||
void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the I2C handle which is used in transactional functions.
|
||||
*
|
||||
* @param base I2C base pointer.
|
||||
* @param handle pointer to i2c_slave_handle_t structure to store the transfer state.
|
||||
* @param callback pointer to user callback function.
|
||||
* @param userData user parameter passed to the callback function.
|
||||
*/
|
||||
void I2C_SlaveTransferCreateHandle(I2C_Type *base,
|
||||
i2c_slave_handle_t *handle,
|
||||
i2c_slave_transfer_callback_t callback,
|
||||
void *userData);
|
||||
|
||||
/*!
|
||||
* @brief Starts accepting slave transfers.
|
||||
*
|
||||
* Call this API after calling the I2C_SlaveInit() and I2C_SlaveTransferCreateHandle() to start processing
|
||||
* transactions driven by an I2C master. The slave monitors the I2C bus and passes events to the
|
||||
* callback that was passed into the call to I2C_SlaveTransferCreateHandle(). The callback is always invoked
|
||||
* from the interrupt context.
|
||||
*
|
||||
* The set of events received by the callback is customizable. To do so, set the @a eventMask parameter to
|
||||
* the OR'd combination of #i2c_slave_transfer_event_t enumerators for the events you wish to receive.
|
||||
* The #kI2C_SlaveTransmitEvent and #kLPI2C_SlaveReceiveEvent events are always enabled and do not need
|
||||
* to be included in the mask. Alternatively, pass 0 to get a default set of only the transmit and
|
||||
* receive events that are always enabled. In addition, the #kI2C_SlaveAllEvents constant is provided as
|
||||
* a convenient way to enable all events.
|
||||
*
|
||||
* @param base The I2C peripheral base address.
|
||||
* @param handle Pointer to #i2c_slave_handle_t structure which stores the transfer state.
|
||||
* @param eventMask Bit mask formed by OR'ing together #i2c_slave_transfer_event_t enumerators to specify
|
||||
* which events to send to the callback. Other accepted values are 0 to get a default set of
|
||||
* only the transmit and receive events, and #kI2C_SlaveAllEvents to enable all events.
|
||||
*
|
||||
* @retval #kStatus_Success Slave transfers were successfully started.
|
||||
* @retval #kStatus_I2C_Busy Slave transfers have already been started on this handle.
|
||||
*/
|
||||
status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask);
|
||||
|
||||
/*!
|
||||
* @brief Aborts the slave transfer.
|
||||
*
|
||||
* @note This API can be called at any time to stop slave for handling the bus events.
|
||||
*
|
||||
* @param base I2C base pointer.
|
||||
* @param handle pointer to i2c_slave_handle_t structure which stores the transfer state.
|
||||
*/
|
||||
void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Gets the slave transfer remaining bytes during a interrupt non-blocking transfer.
|
||||
*
|
||||
* @param base I2C base pointer.
|
||||
* @param handle pointer to i2c_slave_handle_t structure.
|
||||
* @param count Number of bytes transferred so far by the non-blocking transaction.
|
||||
* @retval kStatus_InvalidArgument count is Invalid.
|
||||
* @retval kStatus_Success Successfully return the count.
|
||||
*/
|
||||
status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count);
|
||||
|
||||
/*!
|
||||
* @brief Slave interrupt handler.
|
||||
*
|
||||
* @param base I2C base pointer.
|
||||
* @param i2cHandle pointer to i2c_slave_handle_t structure which stores the transfer state
|
||||
*/
|
||||
void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle);
|
||||
|
||||
/* @} */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /*_cplusplus. */
|
||||
/*@}*/
|
||||
|
||||
#endif /* _FSL_I2C_H_*/
|
|
@ -0,0 +1,526 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_i2c_edma.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*<! @breif Structure definition for i2c_master_edma_private_handle_t. The structure is private. */
|
||||
typedef struct _i2c_master_edma_private_handle
|
||||
{
|
||||
I2C_Type *base;
|
||||
i2c_master_edma_handle_t *handle;
|
||||
} i2c_master_edma_private_handle_t;
|
||||
|
||||
/*! @brief i2c master DMA transfer state. */
|
||||
enum _i2c_master_dma_transfer_states
|
||||
{
|
||||
kIdleState = 0x0U, /*!< I2C bus idle. */
|
||||
kTransferDataState = 0x1U, /*!< 7-bit address check state. */
|
||||
};
|
||||
|
||||
/*! @brief Common sets of flags used by the driver. */
|
||||
enum _i2c_flag_constants
|
||||
{
|
||||
/*! All flags which are cleared by the driver upon starting a transfer. */
|
||||
#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
|
||||
kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StartDetectFlag | kI2C_StopDetectFlag,
|
||||
#elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
|
||||
kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StopDetectFlag,
|
||||
#else
|
||||
kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief EDMA callback for I2C master EDMA driver.
|
||||
*
|
||||
* @param handle EDMA handler for I2C master EDMA driver
|
||||
* @param userData user param passed to the callback function
|
||||
*/
|
||||
static void I2C_MasterTransferCallbackEDMA(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds);
|
||||
|
||||
/*!
|
||||
* @brief Check and clear status operation.
|
||||
*
|
||||
* @param base I2C peripheral base address.
|
||||
* @param status current i2c hardware status.
|
||||
* @retval kStatus_Success No error found.
|
||||
* @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
|
||||
* @retval kStatus_I2C_Nak Received Nak error.
|
||||
*/
|
||||
static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status);
|
||||
|
||||
/*!
|
||||
* @brief EDMA config for I2C master driver.
|
||||
*
|
||||
* @param base I2C peripheral base address.
|
||||
* @param handle pointer to i2c_master_edma_handle_t structure which stores the transfer state
|
||||
*/
|
||||
static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Set up master transfer, send slave address and sub address(if any), wait until the
|
||||
* wait until address sent status return.
|
||||
*
|
||||
* @param base I2C peripheral base address.
|
||||
* @param handle pointer to i2c_master_edma_handle_t structure which stores the transfer state
|
||||
* @param xfer pointer to i2c_master_transfer_t structure
|
||||
*/
|
||||
static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
|
||||
i2c_master_edma_handle_t *handle,
|
||||
i2c_master_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Get the I2C instance from peripheral base address.
|
||||
*
|
||||
* @param base I2C peripheral base address.
|
||||
* @return I2C instance.
|
||||
*/
|
||||
extern uint32_t I2C_GetInstance(I2C_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*<! Private handle only used for internally. */
|
||||
static i2c_master_edma_private_handle_t s_edmaPrivateHandle[FSL_FEATURE_SOC_I2C_COUNT];
|
||||
|
||||
/*******************************************************************************
|
||||
* Codes
|
||||
******************************************************************************/
|
||||
|
||||
static void I2C_MasterTransferCallbackEDMA(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
|
||||
{
|
||||
i2c_master_edma_private_handle_t *i2cPrivateHandle = (i2c_master_edma_private_handle_t *)userData;
|
||||
status_t result = kStatus_Success;
|
||||
|
||||
/* Disable DMA. */
|
||||
I2C_EnableDMA(i2cPrivateHandle->base, false);
|
||||
|
||||
/* Send stop if kI2C_TransferNoStop flag is not asserted. */
|
||||
if (!(i2cPrivateHandle->handle->transfer.flags & kI2C_TransferNoStopFlag))
|
||||
{
|
||||
if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read)
|
||||
{
|
||||
/* Change to send NAK at the last byte. */
|
||||
i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK;
|
||||
|
||||
/* Wait the last data to be received. */
|
||||
while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag))
|
||||
{
|
||||
}
|
||||
|
||||
/* Send stop signal. */
|
||||
result = I2C_MasterStop(i2cPrivateHandle->base);
|
||||
|
||||
/* Read the last data byte. */
|
||||
*(i2cPrivateHandle->handle->transfer.data + i2cPrivateHandle->handle->transfer.dataSize - 1) =
|
||||
i2cPrivateHandle->base->D;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wait the last data to be sent. */
|
||||
while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag))
|
||||
{
|
||||
}
|
||||
|
||||
/* Send stop signal. */
|
||||
result = I2C_MasterStop(i2cPrivateHandle->base);
|
||||
}
|
||||
}
|
||||
|
||||
i2cPrivateHandle->handle->state = kIdleState;
|
||||
|
||||
if (i2cPrivateHandle->handle->completionCallback)
|
||||
{
|
||||
i2cPrivateHandle->handle->completionCallback(i2cPrivateHandle->base, i2cPrivateHandle->handle, result,
|
||||
i2cPrivateHandle->handle->userData);
|
||||
}
|
||||
}
|
||||
|
||||
static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status)
|
||||
{
|
||||
status_t result = kStatus_Success;
|
||||
|
||||
/* Check arbitration lost. */
|
||||
if (status & kI2C_ArbitrationLostFlag)
|
||||
{
|
||||
/* Clear arbitration lost flag. */
|
||||
base->S = kI2C_ArbitrationLostFlag;
|
||||
result = kStatus_I2C_ArbitrationLost;
|
||||
}
|
||||
/* Check NAK */
|
||||
else if (status & kI2C_ReceiveNakFlag)
|
||||
{
|
||||
result = kStatus_I2C_Nak;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
|
||||
i2c_master_edma_handle_t *handle,
|
||||
i2c_master_transfer_t *xfer)
|
||||
{
|
||||
assert(handle);
|
||||
assert(xfer);
|
||||
|
||||
status_t result = kStatus_Success;
|
||||
uint16_t timeout = UINT16_MAX;
|
||||
|
||||
if (handle->state != kIdleState)
|
||||
{
|
||||
return kStatus_I2C_Busy;
|
||||
}
|
||||
else
|
||||
{
|
||||
i2c_direction_t direction = xfer->direction;
|
||||
|
||||
/* Init the handle member. */
|
||||
handle->transfer = *xfer;
|
||||
|
||||
/* Save total transfer size. */
|
||||
handle->transferSize = xfer->dataSize;
|
||||
|
||||
handle->state = kTransferDataState;
|
||||
|
||||
/* Wait until ready to complete. */
|
||||
while ((!(base->S & kI2C_TransferCompleteFlag)) && (--timeout))
|
||||
{
|
||||
}
|
||||
|
||||
/* Failed to start the transfer. */
|
||||
if (timeout == 0)
|
||||
{
|
||||
return kStatus_I2C_Timeout;
|
||||
}
|
||||
/* Clear all status before transfer. */
|
||||
I2C_MasterClearStatusFlags(base, kClearFlags);
|
||||
|
||||
/* Change to send write address when it's a read operation with command. */
|
||||
if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read))
|
||||
{
|
||||
direction = kI2C_Write;
|
||||
}
|
||||
|
||||
/* If repeated start is requested, send repeated start. */
|
||||
if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag)
|
||||
{
|
||||
result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction);
|
||||
}
|
||||
else /* For normal transfer, send start. */
|
||||
{
|
||||
result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction);
|
||||
}
|
||||
|
||||
/* Send subaddress. */
|
||||
if (handle->transfer.subaddressSize)
|
||||
{
|
||||
do
|
||||
{
|
||||
/* Wait until data transfer complete. */
|
||||
while (!(base->S & kI2C_IntPendingFlag))
|
||||
{
|
||||
}
|
||||
|
||||
/* Clear interrupt pending flag. */
|
||||
base->S = kI2C_IntPendingFlag;
|
||||
|
||||
handle->transfer.subaddressSize--;
|
||||
base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize));
|
||||
|
||||
/* Check if there's transfer error. */
|
||||
result = I2C_CheckAndClearError(base, base->S);
|
||||
|
||||
if (result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
} while ((handle->transfer.subaddressSize > 0) && (result == kStatus_Success));
|
||||
|
||||
if (handle->transfer.direction == kI2C_Read)
|
||||
{
|
||||
/* Wait until data transfer complete. */
|
||||
while (!(base->S & kI2C_IntPendingFlag))
|
||||
{
|
||||
}
|
||||
|
||||
/* Clear pending flag. */
|
||||
base->S = kI2C_IntPendingFlag;
|
||||
|
||||
/* Send repeated start and slave address. */
|
||||
result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read);
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Wait until data transfer complete. */
|
||||
while (!(base->S & kI2C_IntPendingFlag))
|
||||
{
|
||||
}
|
||||
|
||||
/* Clear pending flag. */
|
||||
base->S = kI2C_IntPendingFlag;
|
||||
|
||||
/* Check if there's transfer error. */
|
||||
result = I2C_CheckAndClearError(base, base->S);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_t *handle)
|
||||
{
|
||||
edma_transfer_config_t transfer_config;
|
||||
|
||||
if (handle->transfer.direction == kI2C_Read)
|
||||
{
|
||||
transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base);
|
||||
transfer_config.destAddr = (uint32_t)(handle->transfer.data);
|
||||
|
||||
/* Send stop if kI2C_TransferNoStop flag is not asserted. */
|
||||
if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
|
||||
{
|
||||
transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
transfer_config.majorLoopCounts = handle->transfer.dataSize;
|
||||
}
|
||||
|
||||
transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes;
|
||||
transfer_config.srcOffset = 0;
|
||||
transfer_config.destTransferSize = kEDMA_TransferSize1Bytes;
|
||||
transfer_config.destOffset = 1;
|
||||
transfer_config.minorLoopBytes = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
transfer_config.srcAddr = (uint32_t)(handle->transfer.data + 1);
|
||||
transfer_config.destAddr = (uint32_t)I2C_GetDataRegAddr(base);
|
||||
transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1);
|
||||
transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes;
|
||||
transfer_config.srcOffset = 1;
|
||||
transfer_config.destTransferSize = kEDMA_TransferSize1Bytes;
|
||||
transfer_config.destOffset = 0;
|
||||
transfer_config.minorLoopBytes = 1;
|
||||
}
|
||||
|
||||
EDMA_SubmitTransfer(handle->dmaHandle, &transfer_config);
|
||||
EDMA_StartTransfer(handle->dmaHandle);
|
||||
}
|
||||
|
||||
void I2C_MasterCreateEDMAHandle(I2C_Type *base,
|
||||
i2c_master_edma_handle_t *handle,
|
||||
i2c_master_edma_transfer_callback_t callback,
|
||||
void *userData,
|
||||
edma_handle_t *edmaHandle)
|
||||
{
|
||||
assert(handle);
|
||||
assert(edmaHandle);
|
||||
|
||||
uint32_t instance = I2C_GetInstance(base);
|
||||
|
||||
/* Zero handle. */
|
||||
memset(handle, 0, sizeof(*handle));
|
||||
|
||||
/* Set the user callback and userData. */
|
||||
handle->completionCallback = callback;
|
||||
handle->userData = userData;
|
||||
|
||||
/* Set the base for the handle. */
|
||||
base = base;
|
||||
|
||||
/* Set the handle for EDMA. */
|
||||
handle->dmaHandle = edmaHandle;
|
||||
|
||||
s_edmaPrivateHandle[instance].base = base;
|
||||
s_edmaPrivateHandle[instance].handle = handle;
|
||||
|
||||
EDMA_SetCallback(edmaHandle, (edma_callback)I2C_MasterTransferCallbackEDMA, &s_edmaPrivateHandle[instance]);
|
||||
}
|
||||
|
||||
status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, i2c_master_transfer_t *xfer)
|
||||
{
|
||||
assert(handle);
|
||||
assert(xfer);
|
||||
|
||||
status_t result;
|
||||
uint8_t tmpReg;
|
||||
volatile uint8_t dummy = 0;
|
||||
|
||||
/* Add this to avoid build warning. */
|
||||
dummy++;
|
||||
|
||||
/* Disable dma xfer. */
|
||||
I2C_EnableDMA(base, false);
|
||||
|
||||
/* Send address and command buffer(if there is), until senddata phase or receive data phase. */
|
||||
result = I2C_InitTransferStateMachineEDMA(base, handle, xfer);
|
||||
|
||||
if (result)
|
||||
{
|
||||
/* Send stop if received Nak. */
|
||||
if (result == kStatus_I2C_Nak)
|
||||
{
|
||||
if (I2C_MasterStop(base) != kStatus_Success)
|
||||
{
|
||||
result = kStatus_I2C_Timeout;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the state to idle state. */
|
||||
handle->state = kIdleState;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Configure dma transfer. */
|
||||
/* For i2c send, need to send 1 byte first to trigger the dma, for i2c read,
|
||||
need to send stop before reading the last byte, so the dma transfer size should
|
||||
be (xSize - 1). */
|
||||
if (handle->transfer.dataSize > 1)
|
||||
{
|
||||
I2C_MasterTransferEDMAConfig(base, handle);
|
||||
if (handle->transfer.direction == kI2C_Read)
|
||||
{
|
||||
/* Change direction for receive. */
|
||||
base->C1 &= ~I2C_C1_TX_MASK;
|
||||
|
||||
/* Read dummy to release the bus. */
|
||||
dummy = base->D;
|
||||
|
||||
/* Enabe dma transfer. */
|
||||
I2C_EnableDMA(base, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enabe dma transfer. */
|
||||
I2C_EnableDMA(base, true);
|
||||
|
||||
/* Send the first data. */
|
||||
base->D = *handle->transfer.data;
|
||||
}
|
||||
}
|
||||
else /* If transfer size is 1, use polling method. */
|
||||
{
|
||||
if (handle->transfer.direction == kI2C_Read)
|
||||
{
|
||||
tmpReg = base->C1;
|
||||
|
||||
/* Change direction to Rx. */
|
||||
tmpReg &= ~I2C_C1_TX_MASK;
|
||||
|
||||
/* Configure send NAK */
|
||||
tmpReg |= I2C_C1_TXAK_MASK;
|
||||
|
||||
base->C1 = tmpReg;
|
||||
|
||||
/* Read dummy to release the bus. */
|
||||
dummy = base->D;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->D = *handle->transfer.data;
|
||||
}
|
||||
|
||||
/* Wait until data transfer complete. */
|
||||
while (!(base->S & kI2C_IntPendingFlag))
|
||||
{
|
||||
}
|
||||
|
||||
/* Clear pending flag. */
|
||||
base->S = kI2C_IntPendingFlag;
|
||||
|
||||
/* Send stop if kI2C_TransferNoStop flag is not asserted. */
|
||||
if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
|
||||
{
|
||||
result = I2C_MasterStop(base);
|
||||
}
|
||||
|
||||
/* Read the last byte of data. */
|
||||
if (handle->transfer.direction == kI2C_Read)
|
||||
{
|
||||
*handle->transfer.data = base->D;
|
||||
}
|
||||
|
||||
/* Reset the state to idle. */
|
||||
handle->state = kIdleState;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, size_t *count)
|
||||
{
|
||||
assert(handle->dmaHandle);
|
||||
|
||||
if (!count)
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
if (kIdleState != handle->state)
|
||||
{
|
||||
*count = (handle->transferSize - EDMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel));
|
||||
}
|
||||
else
|
||||
{
|
||||
*count = handle->transferSize;
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
void I2C_MasterTransferAbortEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle)
|
||||
{
|
||||
EDMA_AbortTransfer(handle->dmaHandle);
|
||||
|
||||
/* Disable dma transfer. */
|
||||
I2C_EnableDMA(base, false);
|
||||
|
||||
/* Reset the state to idle. */
|
||||
handle->state = kIdleState;
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_I2C_DMA_H_
|
||||
#define _FSL_I2C_DMA_H_
|
||||
|
||||
#include "fsl_i2c.h"
|
||||
#include "fsl_dmamux.h"
|
||||
#include "fsl_edma.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup i2c_edma_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief I2C master edma handle typedef. */
|
||||
typedef struct _i2c_master_edma_handle i2c_master_edma_handle_t;
|
||||
|
||||
/*! @brief I2C master edma transfer callback typedef. */
|
||||
typedef void (*i2c_master_edma_transfer_callback_t)(I2C_Type *base,
|
||||
i2c_master_edma_handle_t *handle,
|
||||
status_t status,
|
||||
void *userData);
|
||||
|
||||
/*! @brief I2C master edma transfer structure. */
|
||||
struct _i2c_master_edma_handle
|
||||
{
|
||||
i2c_master_transfer_t transfer; /*!< I2C master transfer struct. */
|
||||
size_t transferSize; /*!< Total bytes to be transferred. */
|
||||
uint8_t state; /*!< I2C master transfer status. */
|
||||
edma_handle_t *dmaHandle; /*!< The eDMA handler used. */
|
||||
i2c_master_edma_transfer_callback_t
|
||||
completionCallback; /*!< Callback function called after edma transfer finished. */
|
||||
void *userData; /*!< Callback parameter passed to callback function. */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /*_cplusplus. */
|
||||
|
||||
/*!
|
||||
* @name I2C Block EDMA Transfer Operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Init the I2C handle which is used in transcational functions.
|
||||
*
|
||||
* @param base I2C peripheral base address.
|
||||
* @param handle pointer to i2c_master_edma_handle_t structure.
|
||||
* @param callback pointer to user callback function.
|
||||
* @param userData user param passed to the callback function.
|
||||
* @param edmaHandle EDMA handle pointer.
|
||||
*/
|
||||
void I2C_MasterCreateEDMAHandle(I2C_Type *base,
|
||||
i2c_master_edma_handle_t *handle,
|
||||
i2c_master_edma_transfer_callback_t callback,
|
||||
void *userData,
|
||||
edma_handle_t *edmaHandle);
|
||||
|
||||
/*!
|
||||
* @brief Performs a master edma non-blocking transfer on the I2C bus.
|
||||
*
|
||||
* @param base I2C peripheral base address.
|
||||
* @param handle pointer to i2c_master_edma_handle_t structure.
|
||||
* @param xfer pointer to transfer structure of i2c_master_transfer_t.
|
||||
* @retval kStatus_Success Sucessully complete the data transmission.
|
||||
* @retval kStatus_I2C_Busy Previous transmission still not finished.
|
||||
* @retval kStatus_I2C_Timeout Transfer error, wait signal timeout.
|
||||
* @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
|
||||
* @retval kStataus_I2C_Nak Transfer error, receive Nak during transfer.
|
||||
*/
|
||||
status_t I2C_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.
|
||||
*
|
||||
* @param base I2C peripheral base address.
|
||||
* @param handle pointer to i2c_master_edma_handle_t structure.
|
||||
* @param count Number of bytes transferred so far by the non-blocking transaction.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param base I2C peripheral base address.
|
||||
* @param handle pointer to i2c_master_edma_handle_t structure.
|
||||
*/
|
||||
void I2C_MasterTransferAbortEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle);
|
||||
|
||||
/* @} */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /*_cplusplus. */
|
||||
/*@}*/
|
||||
#endif /*_FSL_I2C_DMA_H_*/
|
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_llwu.h"
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN)
|
||||
void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_external_pin_mode_t pinMode)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
volatile uint32_t *regBase;
|
||||
uint32_t regOffset;
|
||||
uint32_t reg;
|
||||
|
||||
switch (pinIndex >> 4U)
|
||||
{
|
||||
case 0U:
|
||||
regBase = &base->PE1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
case 1U:
|
||||
regBase = &base->PE2;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
regBase = NULL;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
volatile uint8_t *regBase;
|
||||
uint8_t regOffset;
|
||||
uint8_t reg;
|
||||
switch (pinIndex >> 2U)
|
||||
{
|
||||
case 0U:
|
||||
regBase = &base->PE1;
|
||||
break;
|
||||
case 1U:
|
||||
regBase = &base->PE2;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
|
||||
case 2U:
|
||||
regBase = &base->PE3;
|
||||
break;
|
||||
#endif
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 12))
|
||||
case 3U:
|
||||
regBase = &base->PE4;
|
||||
break;
|
||||
#endif
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
case 4U:
|
||||
regBase = &base->PE5;
|
||||
break;
|
||||
#endif
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 20))
|
||||
case 5U:
|
||||
regBase = &base->PE6;
|
||||
break;
|
||||
#endif
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
|
||||
case 6U:
|
||||
regBase = &base->PE7;
|
||||
break;
|
||||
#endif
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 28))
|
||||
case 7U:
|
||||
regBase = &base->PE8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
regBase = NULL;
|
||||
break;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH == 32 */
|
||||
|
||||
if (regBase)
|
||||
{
|
||||
reg = *regBase;
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
regOffset = ((pinIndex & 0x0FU) << 1U);
|
||||
#else
|
||||
regOffset = ((pinIndex & 0x03U) << 1U);
|
||||
#endif
|
||||
reg &= ~(0x3U << regOffset);
|
||||
reg |= ((uint32_t)pinMode << regOffset);
|
||||
*regBase = reg;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
return (bool)(base->PF & (1U << pinIndex));
|
||||
#else
|
||||
volatile uint8_t *regBase;
|
||||
|
||||
switch (pinIndex >> 3U)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF)
|
||||
case 0U:
|
||||
regBase = &base->PF1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
|
||||
case 1U:
|
||||
regBase = &base->PF2;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
case 2U:
|
||||
regBase = &base->PF3;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
|
||||
case 3U:
|
||||
regBase = &base->PF4;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#else
|
||||
case 0U:
|
||||
regBase = &base->F1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
|
||||
case 1U:
|
||||
regBase = &base->F2;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
case 2U:
|
||||
regBase = &base->F3;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
|
||||
case 3U:
|
||||
regBase = &base->F4;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PF */
|
||||
default:
|
||||
regBase = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (regBase)
|
||||
{
|
||||
return (bool)(*regBase & (1U << pinIndex % 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
|
||||
}
|
||||
|
||||
void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
base->PF = (1U << pinIndex);
|
||||
#else
|
||||
volatile uint8_t *regBase;
|
||||
switch (pinIndex >> 3U)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF)
|
||||
case 0U:
|
||||
regBase = &base->PF1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
|
||||
case 1U:
|
||||
regBase = &base->PF2;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
case 2U:
|
||||
regBase = &base->PF3;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
|
||||
case 3U:
|
||||
regBase = &base->PF4;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#else
|
||||
case 0U:
|
||||
regBase = &base->F1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
|
||||
case 1U:
|
||||
regBase = &base->F2;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
case 2U:
|
||||
regBase = &base->F3;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
|
||||
case 3U:
|
||||
regBase = &base->F4;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PF */
|
||||
default:
|
||||
regBase = NULL;
|
||||
break;
|
||||
}
|
||||
if (regBase)
|
||||
{
|
||||
*regBase = (1U << pinIndex % 8U);
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER)
|
||||
void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_pin_filter_mode_t filterMode)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
uint32_t reg;
|
||||
|
||||
reg = base->FILT;
|
||||
reg &= ~((LLWU_FILT_FILTSEL1_MASK | LLWU_FILT_FILTE1_MASK) << (filterIndex * 8U - 1U));
|
||||
reg |= (((filterMode.pinIndex << LLWU_FILT_FILTSEL1_SHIFT) | (filterMode.filterMode << LLWU_FILT_FILTE1_SHIFT)
|
||||
/* Clear the Filter Detect Flag */
|
||||
| LLWU_FILT_FILTF1_MASK)
|
||||
<< (filterIndex * 8U - 1U));
|
||||
base->FILT = reg;
|
||||
#else
|
||||
volatile uint8_t *regBase;
|
||||
uint8_t reg;
|
||||
|
||||
switch (filterIndex)
|
||||
{
|
||||
case 1:
|
||||
regBase = &base->FILT1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1))
|
||||
case 2:
|
||||
regBase = &base->FILT2;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2))
|
||||
case 3:
|
||||
regBase = &base->FILT3;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3))
|
||||
case 4:
|
||||
regBase = &base->FILT4;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
default:
|
||||
regBase = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (regBase)
|
||||
{
|
||||
reg = *regBase;
|
||||
reg &= ~(LLWU_FILT1_FILTSEL_MASK | LLWU_FILT1_FILTE_MASK);
|
||||
reg |= ((uint32_t)filterMode.pinIndex << LLWU_FILT1_FILTSEL_SHIFT);
|
||||
reg |= ((uint32_t)filterMode.filterMode << LLWU_FILT1_FILTE_SHIFT);
|
||||
/* Clear the Filter Detect Flag */
|
||||
reg |= LLWU_FILT1_FILTF_MASK;
|
||||
*regBase = reg;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
|
||||
}
|
||||
|
||||
bool LLWU_GetPinFilterFlag(LLWU_Type *base, uint32_t filterIndex)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
return (bool)(base->FILT & (1U << (filterIndex * 8U - 1)));
|
||||
#else
|
||||
bool status = false;
|
||||
|
||||
switch (filterIndex)
|
||||
{
|
||||
case 1:
|
||||
status = (base->FILT1 & LLWU_FILT1_FILTF_MASK);
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1))
|
||||
case 2:
|
||||
status = (base->FILT2 & LLWU_FILT2_FILTF_MASK);
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2))
|
||||
case 3:
|
||||
status = (base->FILT3 & LLWU_FILT3_FILTF_MASK);
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3))
|
||||
case 4:
|
||||
status = (base->FILT4 & LLWU_FILT4_FILTF_MASK);
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
|
||||
}
|
||||
|
||||
void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
uint32_t reg;
|
||||
|
||||
reg = base->FILT;
|
||||
switch (filterIndex)
|
||||
{
|
||||
case 1:
|
||||
reg |= LLWU_FILT_FILTF1_MASK;
|
||||
break;
|
||||
case 2:
|
||||
reg |= LLWU_FILT_FILTF2_MASK;
|
||||
break;
|
||||
case 3:
|
||||
reg |= LLWU_FILT_FILTF3_MASK;
|
||||
break;
|
||||
case 4:
|
||||
reg |= LLWU_FILT_FILTF4_MASK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
base->FILT = reg;
|
||||
#else
|
||||
volatile uint8_t *regBase;
|
||||
uint8_t reg;
|
||||
|
||||
switch (filterIndex)
|
||||
{
|
||||
case 1:
|
||||
regBase = &base->FILT1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1))
|
||||
case 2:
|
||||
regBase = &base->FILT2;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2))
|
||||
case 3:
|
||||
regBase = &base->FILT3;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3))
|
||||
case 4:
|
||||
regBase = &base->FILT4;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
default:
|
||||
regBase = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (regBase)
|
||||
{
|
||||
reg = *regBase;
|
||||
reg |= LLWU_FILT1_FILTF_MASK;
|
||||
*regBase = reg;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_RESET_ENABLE) && FSL_FEATURE_LLWU_HAS_RESET_ENABLE)
|
||||
void LLWU_SetResetPinMode(LLWU_Type *base, bool pinEnable, bool enableInLowLeakageMode)
|
||||
{
|
||||
uint8_t reg;
|
||||
|
||||
reg = base->RST;
|
||||
reg &= ~(LLWU_RST_LLRSTE_MASK | LLWU_RST_RSTFILT_MASK);
|
||||
reg |=
|
||||
(((uint32_t)pinEnable << LLWU_RST_LLRSTE_SHIFT) | ((uint32_t)enableInLowLeakageMode << LLWU_RST_RSTFILT_SHIFT));
|
||||
base->RST = reg;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_RESET_ENABLE */
|
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_LLWU_H_
|
||||
#define _FSL_LLWU_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*! @addtogroup llwu */
|
||||
/*! @{ */
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief LLWU driver version 2.0.1. */
|
||||
#define FSL_LLWU_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief External input pin control modes
|
||||
*/
|
||||
typedef enum _llwu_external_pin_mode
|
||||
{
|
||||
kLLWU_ExternalPinDisable = 0U, /*!< Pin disabled as wakeup input. */
|
||||
kLLWU_ExternalPinRisingEdge = 1U, /*!< Pin enabled with rising edge detection. */
|
||||
kLLWU_ExternalPinFallingEdge = 2U, /*!< Pin enabled with falling edge detection.*/
|
||||
kLLWU_ExternalPinAnyEdge = 3U /*!< Pin enabled with any change detection. */
|
||||
} llwu_external_pin_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief Digital filter control modes
|
||||
*/
|
||||
typedef enum _llwu_pin_filter_mode
|
||||
{
|
||||
kLLWU_PinFilterDisable = 0U, /*!< Filter disabled. */
|
||||
kLLWU_PinFilterRisingEdge = 1U, /*!< Filter positive edge detection.*/
|
||||
kLLWU_PinFilterFallingEdge = 2U, /*!< Filter negative edge detection.*/
|
||||
kLLWU_PinFilterAnyEdge = 3U /*!< Filter any edge detection. */
|
||||
} llwu_pin_filter_mode_t;
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_VERID) && FSL_FEATURE_LLWU_HAS_VERID)
|
||||
/*!
|
||||
* @brief IP version ID definition.
|
||||
*/
|
||||
typedef struct _llwu_version_id
|
||||
{
|
||||
uint16_t feature; /*!< Feature Specification Number. */
|
||||
uint8_t minor; /*!< Minor version number. */
|
||||
uint8_t major; /*!< Major version number. */
|
||||
} llwu_version_id_t;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_VERID */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PARAM) && FSL_FEATURE_LLWU_HAS_PARAM)
|
||||
/*!
|
||||
* @brief IP parameter definition.
|
||||
*/
|
||||
typedef struct _llwu_param
|
||||
{
|
||||
uint8_t filters; /*!< Number of pin filter. */
|
||||
uint8_t dmas; /*!< Number of wakeup DMA. */
|
||||
uint8_t modules; /*!< Number of wakeup module. */
|
||||
uint8_t pins; /*!< Number of wake up pin. */
|
||||
} llwu_param_t;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PARAM */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER)
|
||||
/*!
|
||||
* @brief External input pin filter control structure
|
||||
*/
|
||||
typedef struct _llwu_external_pin_filter_mode
|
||||
{
|
||||
uint32_t pinIndex; /*!< Pin number */
|
||||
llwu_pin_filter_mode_t filterMode; /*!< Filter mode */
|
||||
} llwu_external_pin_filter_mode_t;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Low-Leakage Wakeup Unit Control APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_VERID) && FSL_FEATURE_LLWU_HAS_VERID)
|
||||
/*!
|
||||
* @brief Gets the LLWU version ID.
|
||||
*
|
||||
* This function gets the LLWU version ID, including major version number,
|
||||
* minor version number, and feature specification number.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param versionId Pointer to version ID structure.
|
||||
*/
|
||||
static inline void LLWU_GetVersionId(LLWU_Type *base, llwu_version_id_t *versionId)
|
||||
{
|
||||
*((uint32_t *)versionId) = base->VERID;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_VERID */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PARAM) && FSL_FEATURE_LLWU_HAS_PARAM)
|
||||
/*!
|
||||
* @brief Gets the LLWU parameter.
|
||||
*
|
||||
* This function gets the LLWU parameter, including wakeup pin number, module
|
||||
* number, DMA number, and pin filter number.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param param Pointer to LLWU param structure.
|
||||
*/
|
||||
static inline void LLWU_GetParam(LLWU_Type *base, llwu_param_t *param)
|
||||
{
|
||||
*((uint32_t *)param) = base->PARAM;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PARAM */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN)
|
||||
/*!
|
||||
* @brief Sets the external input pin source mode.
|
||||
*
|
||||
* This function sets the external input pin source mode that is used
|
||||
* as a wake up source.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param pinIndex pin index which to be enabled as external wakeup source, start from 1.
|
||||
* @param pinMode pin configuration mode defined in llwu_external_pin_modes_t
|
||||
*/
|
||||
void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_external_pin_mode_t pinMode);
|
||||
|
||||
/*!
|
||||
* @brief Gets the external wakeup source flag.
|
||||
*
|
||||
* This function checks the external pin flag to detect whether the MCU is
|
||||
* woke up by the specific pin.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param pinIndex pin index, start from 1.
|
||||
* @return true if the specific pin is wake up source.
|
||||
*/
|
||||
bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex);
|
||||
|
||||
/*!
|
||||
* @brief Clears the external wakeup source flag.
|
||||
*
|
||||
* This function clears the external wakeup source flag for a specific pin.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param pinIndex pin index, start from 1.
|
||||
*/
|
||||
void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex);
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE) && FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE)
|
||||
/*!
|
||||
* @brief Enables/disables the internal module source.
|
||||
*
|
||||
* This function enables/disables the internal module source mode that is used
|
||||
* as a wake up source.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param moduleIndex module index which to be enabled as internal wakeup source, start from 1.
|
||||
* @param enable enable or disable setting
|
||||
*/
|
||||
static inline void LLWU_EnableInternalModuleInterruptWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->ME |= 1U << moduleIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->ME &= ~(1U << moduleIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the external wakeup source flag.
|
||||
*
|
||||
* This function checks the external pin flag to detect whether the system is
|
||||
* woke up by the specific pin.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param moduleIndex module index, start from 1.
|
||||
* @return true if the specific pin is wake up source.
|
||||
*/
|
||||
static inline bool LLWU_GetInternalWakeupModuleFlag(LLWU_Type *base, uint32_t moduleIndex)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
return (bool)(base->MF & (1U << moduleIndex));
|
||||
#else
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF)
|
||||
return (bool)(base->MF5 & (1U << moduleIndex));
|
||||
#else
|
||||
return (bool)(base->F5 & (1U << moduleIndex));
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PF */
|
||||
#else
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF)
|
||||
return (bool)(base->PF3 & (1U << moduleIndex));
|
||||
#else
|
||||
return (bool)(base->F3 & (1U << moduleIndex));
|
||||
#endif
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG) && FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG)
|
||||
/*!
|
||||
* @brief Enables/disables the internal module DMA wakeup source.
|
||||
*
|
||||
* This function enables/disables the internal DMA that is used as a wake up source.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param moduleIndex Internal module index which used as DMA request source, start from 1.
|
||||
* @param enable Enable or disable DMA request source
|
||||
*/
|
||||
static inline void LLWU_EnableInternalModuleDmaRequestWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->DE |= 1U << moduleIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->DE &= ~(1U << moduleIndex);
|
||||
}
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER)
|
||||
/*!
|
||||
* @brief Sets the pin filter configuration.
|
||||
*
|
||||
* This function sets the pin filter configuration.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param filterIndex pin filter index which used to enable/disable the digital filter, start from 1.
|
||||
* @param filterMode filter mode configuration
|
||||
*/
|
||||
void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_pin_filter_mode_t filterMode);
|
||||
|
||||
/*!
|
||||
* @brief Gets the pin filter configuration.
|
||||
*
|
||||
* This function gets the pin filter flag.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param filterIndex pin filter index, start from 1.
|
||||
* @return true if the flag is a source of existing a low-leakage power mode.
|
||||
*/
|
||||
bool LLWU_GetPinFilterFlag(LLWU_Type *base, uint32_t filterIndex);
|
||||
|
||||
/*!
|
||||
* @brief Clear the pin filter configuration.
|
||||
*
|
||||
* This function clear the pin filter flag.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param filterIndex pin filter index which to be clear the flag, start from 1.
|
||||
*/
|
||||
void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex);
|
||||
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_RESET_ENABLE) && FSL_FEATURE_LLWU_HAS_RESET_ENABLE)
|
||||
/*!
|
||||
* @brief Sets the reset pin mode.
|
||||
*
|
||||
* This function sets how the reset pin is used as a low leakage mode exit source.
|
||||
*
|
||||
* @param pinEnable Enable reset pin filter
|
||||
* @param pinFilterEnable Specify whether pin filter is enabled in Low-Leakage power mode.
|
||||
*/
|
||||
void LLWU_SetResetPinMode(LLWU_Type *base, bool pinEnable, bool enableInLowLeakageMode);
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_RESET_ENABLE */
|
||||
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
#endif /* _FSL_LLWU_H_*/
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_lptmr.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Gets the instance from the base address to be used to gate or ungate the module clock
|
||||
*
|
||||
* @param base LPTMR peripheral base address
|
||||
*
|
||||
* @return The LPTMR instance
|
||||
*/
|
||||
static uint32_t LPTMR_GetInstance(LPTMR_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/*! @brief Pointers to LPTMR bases for each instance. */
|
||||
static LPTMR_Type *const s_lptmrBases[] = LPTMR_BASE_PTRS;
|
||||
|
||||
/*! @brief Pointers to LPTMR clocks for each instance. */
|
||||
static const clock_ip_name_t s_lptmrClocks[] = LPTMR_CLOCKS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static uint32_t LPTMR_GetInstance(LPTMR_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_LPTMR_COUNT; instance++)
|
||||
{
|
||||
if (s_lptmrBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < FSL_FEATURE_SOC_LPTMR_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
/* Ungate the LPTMR clock*/
|
||||
CLOCK_EnableClock(s_lptmrClocks[LPTMR_GetInstance(base)]);
|
||||
|
||||
/* Configure the timers operation mode and input pin setup */
|
||||
base->CSR = (LPTMR_CSR_TMS(config->timerMode) | LPTMR_CSR_TFC(config->enableFreeRunning) |
|
||||
LPTMR_CSR_TPP(config->pinPolarity) | LPTMR_CSR_TPS(config->pinSelect));
|
||||
|
||||
/* Configure the prescale value and clock source */
|
||||
base->PSR = (LPTMR_PSR_PRESCALE(config->value) | LPTMR_PSR_PBYP(config->bypassPrescaler) |
|
||||
LPTMR_PSR_PCS(config->prescalerClockSource));
|
||||
}
|
||||
|
||||
void LPTMR_Deinit(LPTMR_Type *base)
|
||||
{
|
||||
/* Disable the LPTMR and reset the internal logic */
|
||||
base->CSR &= ~LPTMR_CSR_TEN_MASK;
|
||||
/* Gate the LPTMR clock*/
|
||||
CLOCK_DisableClock(s_lptmrClocks[LPTMR_GetInstance(base)]);
|
||||
}
|
||||
|
||||
void LPTMR_GetDefaultConfig(lptmr_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
/* Use time counter mode */
|
||||
config->timerMode = kLPTMR_TimerModeTimeCounter;
|
||||
/* Use input 0 as source in pulse counter mode */
|
||||
config->pinSelect = kLPTMR_PinSelectInput_0;
|
||||
/* Pulse input pin polarity is active-high */
|
||||
config->pinPolarity = kLPTMR_PinPolarityActiveHigh;
|
||||
/* Counter resets whenever TCF flag is set */
|
||||
config->enableFreeRunning = false;
|
||||
/* Bypass the prescaler */
|
||||
config->bypassPrescaler = true;
|
||||
/* LPTMR clock source */
|
||||
config->prescalerClockSource = kLPTMR_PrescalerClock_1;
|
||||
/* Divide the prescaler clock by 2 */
|
||||
config->value = kLPTMR_Prescale_Glitch_0;
|
||||
}
|
|
@ -0,0 +1,351 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_LPTMR_H_
|
||||
#define _FSL_LPTMR_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup lptmr_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
#define FSL_LPTMR_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
|
||||
/*@}*/
|
||||
|
||||
/*! @brief LPTMR pin selection, used in pulse counter mode.*/
|
||||
typedef enum _lptmr_pin_select
|
||||
{
|
||||
kLPTMR_PinSelectInput_0 = 0x0U, /*!< Pulse counter input 0 is selected */
|
||||
kLPTMR_PinSelectInput_1 = 0x1U, /*!< Pulse counter input 1 is selected */
|
||||
kLPTMR_PinSelectInput_2 = 0x2U, /*!< Pulse counter input 2 is selected */
|
||||
kLPTMR_PinSelectInput_3 = 0x3U /*!< Pulse counter input 3 is selected */
|
||||
} lptmr_pin_select_t;
|
||||
|
||||
/*! @brief LPTMR pin polarity, used in pulse counter mode.*/
|
||||
typedef enum _lptmr_pin_polarity
|
||||
{
|
||||
kLPTMR_PinPolarityActiveHigh = 0x0U, /*!< Pulse Counter input source is active-high */
|
||||
kLPTMR_PinPolarityActiveLow = 0x1U /*!< Pulse Counter input source is active-low */
|
||||
} lptmr_pin_polarity_t;
|
||||
|
||||
/*! @brief LPTMR timer mode selection.*/
|
||||
typedef enum _lptmr_timer_mode
|
||||
{
|
||||
kLPTMR_TimerModeTimeCounter = 0x0U, /*!< Time Counter mode */
|
||||
kLPTMR_TimerModePulseCounter = 0x1U /*!< Pulse Counter mode */
|
||||
} lptmr_timer_mode_t;
|
||||
|
||||
/*! @brief LPTMR prescaler/glitch filter values*/
|
||||
typedef enum _lptmr_prescaler_glitch_value
|
||||
{
|
||||
kLPTMR_Prescale_Glitch_0 = 0x0U, /*!< Prescaler divide 2, glitch filter does not support this setting */
|
||||
kLPTMR_Prescale_Glitch_1 = 0x1U, /*!< Prescaler divide 4, glitch filter 2 */
|
||||
kLPTMR_Prescale_Glitch_2 = 0x2U, /*!< Prescaler divide 8, glitch filter 4 */
|
||||
kLPTMR_Prescale_Glitch_3 = 0x3U, /*!< Prescaler divide 16, glitch filter 8 */
|
||||
kLPTMR_Prescale_Glitch_4 = 0x4U, /*!< Prescaler divide 32, glitch filter 16 */
|
||||
kLPTMR_Prescale_Glitch_5 = 0x5U, /*!< Prescaler divide 64, glitch filter 32 */
|
||||
kLPTMR_Prescale_Glitch_6 = 0x6U, /*!< Prescaler divide 128, glitch filter 64 */
|
||||
kLPTMR_Prescale_Glitch_7 = 0x7U, /*!< Prescaler divide 256, glitch filter 128 */
|
||||
kLPTMR_Prescale_Glitch_8 = 0x8U, /*!< Prescaler divide 512, glitch filter 256 */
|
||||
kLPTMR_Prescale_Glitch_9 = 0x9U, /*!< Prescaler divide 1024, glitch filter 512*/
|
||||
kLPTMR_Prescale_Glitch_10 = 0xAU, /*!< Prescaler divide 2048 glitch filter 1024 */
|
||||
kLPTMR_Prescale_Glitch_11 = 0xBU, /*!< Prescaler divide 4096, glitch filter 2048 */
|
||||
kLPTMR_Prescale_Glitch_12 = 0xCU, /*!< Prescaler divide 8192, glitch filter 4096 */
|
||||
kLPTMR_Prescale_Glitch_13 = 0xDU, /*!< Prescaler divide 16384, glitch filter 8192 */
|
||||
kLPTMR_Prescale_Glitch_14 = 0xEU, /*!< Prescaler divide 32768, glitch filter 16384 */
|
||||
kLPTMR_Prescale_Glitch_15 = 0xFU /*!< Prescaler divide 65536, glitch filter 32768 */
|
||||
} lptmr_prescaler_glitch_value_t;
|
||||
|
||||
/*!
|
||||
* @brief LPTMR prescaler/glitch filter clock select.
|
||||
* @note Clock connections are SoC-specific
|
||||
*/
|
||||
typedef enum _lptmr_prescaler_clock_select
|
||||
{
|
||||
kLPTMR_PrescalerClock_0 = 0x0U, /*!< Prescaler/glitch filter clock 0 selected. */
|
||||
kLPTMR_PrescalerClock_1 = 0x1U, /*!< Prescaler/glitch filter clock 1 selected. */
|
||||
kLPTMR_PrescalerClock_2 = 0x2U, /*!< Prescaler/glitch filter clock 2 selected. */
|
||||
kLPTMR_PrescalerClock_3 = 0x3U, /*!< Prescaler/glitch filter clock 3 selected. */
|
||||
} lptmr_prescaler_clock_select_t;
|
||||
|
||||
/*! @brief List of LPTMR interrupts */
|
||||
typedef enum _lptmr_interrupt_enable
|
||||
{
|
||||
kLPTMR_TimerInterruptEnable = LPTMR_CSR_TIE_MASK, /*!< Timer interrupt enable */
|
||||
} lptmr_interrupt_enable_t;
|
||||
|
||||
/*! @brief List of LPTMR status flags */
|
||||
typedef enum _lptmr_status_flags
|
||||
{
|
||||
kLPTMR_TimerCompareFlag = LPTMR_CSR_TCF_MASK, /*!< Timer compare flag */
|
||||
} lptmr_status_flags_t;
|
||||
|
||||
/*!
|
||||
* @brief LPTMR config structure
|
||||
*
|
||||
* This structure holds the configuration settings for the LPTMR peripheral. To initialize this
|
||||
* structure to reasonable defaults, call the LPTMR_GetDefaultConfig() function and pass a
|
||||
* pointer to your config structure instance.
|
||||
*
|
||||
* The config struct can be made const so it resides in flash
|
||||
*/
|
||||
typedef struct _lptmr_config
|
||||
{
|
||||
lptmr_timer_mode_t timerMode; /*!< Time counter mode or pulse counter mode */
|
||||
lptmr_pin_select_t pinSelect; /*!< LPTMR pulse input pin select; used only in pulse counter mode */
|
||||
lptmr_pin_polarity_t pinPolarity; /*!< LPTMR pulse input pin polarity; used only in pulse counter mode */
|
||||
bool enableFreeRunning; /*!< true: enable free running, counter is reset on overflow
|
||||
false: counter is reset when the compare flag is set */
|
||||
bool bypassPrescaler; /*!< true: bypass prescaler; false: use clock from prescaler */
|
||||
lptmr_prescaler_clock_select_t prescalerClockSource; /*!< LPTMR clock source */
|
||||
lptmr_prescaler_glitch_value_t value; /*!< Prescaler or glitch filter value */
|
||||
} lptmr_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Initialization and deinitialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Ungate the LPTMR clock and configures the peripheral for basic operation.
|
||||
*
|
||||
* @note This API should be called at the beginning of the application using the LPTMR driver.
|
||||
*
|
||||
* @param base LPTMR peripheral base address
|
||||
* @param config Pointer to user's LPTMR config structure.
|
||||
*/
|
||||
void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Gate the LPTMR clock
|
||||
*
|
||||
* @param base LPTMR peripheral base address
|
||||
*/
|
||||
void LPTMR_Deinit(LPTMR_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Fill in the LPTMR config struct with the default settings
|
||||
*
|
||||
* The default values are:
|
||||
* @code
|
||||
* config->timerMode = kLPTMR_TimerModeTimeCounter;
|
||||
* config->pinSelect = kLPTMR_PinSelectInput_0;
|
||||
* config->pinPolarity = kLPTMR_PinPolarityActiveHigh;
|
||||
* config->enableFreeRunning = false;
|
||||
* config->bypassPrescaler = true;
|
||||
* config->prescalerClockSource = kLPTMR_PrescalerClock_1;
|
||||
* config->value = kLPTMR_Prescale_Glitch_0;
|
||||
* @endcode
|
||||
* @param config Pointer to user's LPTMR config structure.
|
||||
*/
|
||||
void LPTMR_GetDefaultConfig(lptmr_config_t *config);
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Interrupt Interface
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables the selected LPTMR interrupts.
|
||||
*
|
||||
* @param base LPTMR peripheral base address
|
||||
* @param mask The interrupts to enable. This is a logical OR of members of the
|
||||
* enumeration ::lptmr_interrupt_enable_t
|
||||
*/
|
||||
static inline void LPTMR_EnableInterrupts(LPTMR_Type *base, uint32_t mask)
|
||||
{
|
||||
base->CSR |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the selected LPTMR interrupts.
|
||||
*
|
||||
* @param base LPTMR peripheral base address
|
||||
* @param mask The interrupts to disable. This is a logical OR of members of the
|
||||
* enumeration ::lptmr_interrupt_enable_t
|
||||
*/
|
||||
static inline void LPTMR_DisableInterrupts(LPTMR_Type *base, uint32_t mask)
|
||||
{
|
||||
base->CSR &= ~mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the enabled LPTMR interrupts.
|
||||
*
|
||||
* @param base LPTMR peripheral base address
|
||||
*
|
||||
* @return The enabled interrupts. This is the logical OR of members of the
|
||||
* enumeration ::lptmr_interrupt_enable_t
|
||||
*/
|
||||
static inline uint32_t LPTMR_GetEnabledInterrupts(LPTMR_Type *base)
|
||||
{
|
||||
return (base->CSR & LPTMR_CSR_TIE_MASK);
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Status Interface
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Gets the LPTMR status flags
|
||||
*
|
||||
* @param base LPTMR peripheral base address
|
||||
*
|
||||
* @return The status flags. This is the logical OR of members of the
|
||||
* enumeration ::lptmr_status_flags_t
|
||||
*/
|
||||
static inline uint32_t LPTMR_GetStatusFlags(LPTMR_Type *base)
|
||||
{
|
||||
return (base->CSR & LPTMR_CSR_TCF_MASK);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the LPTMR status flags
|
||||
*
|
||||
* @param base LPTMR peripheral base address
|
||||
* @param mask The status flags to clear. This is a logical OR of members of the
|
||||
* enumeration ::lptmr_status_flags_t
|
||||
*/
|
||||
static inline void LPTMR_ClearStatusFlags(LPTMR_Type *base, uint32_t mask)
|
||||
{
|
||||
base->CSR |= mask;
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Read and Write the timer period
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Sets the timer period in units of count.
|
||||
*
|
||||
* Timers counts from 0 till it equals the count value set here. The count value is written to
|
||||
* the CMR register.
|
||||
*
|
||||
* @note
|
||||
* 1. The TCF flag is set with the CNR equals the count provided here and then increments.
|
||||
* 2. User can call the utility macros provided in fsl_common.h to convert to ticks
|
||||
*
|
||||
* @param base LPTMR peripheral base address
|
||||
* @param ticks Timer period in units of ticks
|
||||
*/
|
||||
static inline void LPTMR_SetTimerPeriod(LPTMR_Type *base, uint16_t ticks)
|
||||
{
|
||||
base->CMR = ticks;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reads the current timer counting value.
|
||||
*
|
||||
* This function returns the real-time timer counting value, in a range from 0 to a
|
||||
* timer period.
|
||||
*
|
||||
* @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec
|
||||
*
|
||||
* @param base LPTMR peripheral base address
|
||||
*
|
||||
* @return Current counter value in ticks
|
||||
*/
|
||||
static inline uint16_t LPTMR_GetCurrentTimerCount(LPTMR_Type *base)
|
||||
{
|
||||
/* Must first write any value to the CNR. This will synchronize and register the current value
|
||||
* of the CNR into a temporary register which can then be read
|
||||
*/
|
||||
base->CNR = 0U;
|
||||
return (uint16_t)base->CNR;
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Timer Start and Stop
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Starts the timer counting.
|
||||
*
|
||||
* After calling this function, the timer counts up to the CMR register value.
|
||||
* Each time the timer reaches CMR value and then increments, it generates a
|
||||
* trigger pulse and sets the timeout interrupt flag. An interrupt will also be
|
||||
* triggered if the timer interrupt is enabled.
|
||||
*
|
||||
* @param base LPTMR peripheral base address
|
||||
*/
|
||||
static inline void LPTMR_StartTimer(LPTMR_Type *base)
|
||||
{
|
||||
base->CSR |= LPTMR_CSR_TEN_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Stops the timer counting.
|
||||
*
|
||||
* This function stops the timer counting and resets the timer's counter register
|
||||
*
|
||||
* @param base LPTMR peripheral base address
|
||||
*/
|
||||
static inline void LPTMR_StopTimer(LPTMR_Type *base)
|
||||
{
|
||||
base->CSR &= ~LPTMR_CSR_TEN_MASK;
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_LPTMR_H_ */
|
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_mpu.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* Defines the register numbers of the region descriptor configure. */
|
||||
#define MPU_REGIONDESCRIPTOR_WROD_REGNUM (4U)
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
const clock_ip_name_t g_mpuClock[FSL_FEATURE_SOC_MPU_COUNT] = MPU_CLOCKS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Codes
|
||||
******************************************************************************/
|
||||
|
||||
void MPU_Init(MPU_Type *base, const mpu_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
uint8_t count;
|
||||
|
||||
/* Un-gate MPU clock */
|
||||
CLOCK_EnableClock(g_mpuClock[0]);
|
||||
|
||||
/* Initializes the regions. */
|
||||
for (count = 1; count < FSL_FEATURE_MPU_DESCRIPTOR_COUNT; count++)
|
||||
{
|
||||
base->WORD[count][3] = 0; /* VLD/VID+PID. */
|
||||
base->WORD[count][0] = 0; /* Start address. */
|
||||
base->WORD[count][1] = 0; /* End address. */
|
||||
base->WORD[count][2] = 0; /* Access rights. */
|
||||
base->RGDAAC[count] = 0; /* Alternate access rights. */
|
||||
}
|
||||
|
||||
/* MPU configure. */
|
||||
while (config)
|
||||
{
|
||||
MPU_SetRegionConfig(base, &(config->regionConfig));
|
||||
config = config->next;
|
||||
}
|
||||
/* Enable MPU. */
|
||||
MPU_Enable(base, true);
|
||||
}
|
||||
|
||||
void MPU_Deinit(MPU_Type *base)
|
||||
{
|
||||
/* Disable MPU. */
|
||||
MPU_Enable(base, false);
|
||||
|
||||
/* Gate the clock. */
|
||||
CLOCK_DisableClock(g_mpuClock[0]);
|
||||
}
|
||||
|
||||
void MPU_GetHardwareInfo(MPU_Type *base, mpu_hardware_info_t *hardwareInform)
|
||||
{
|
||||
assert(hardwareInform);
|
||||
|
||||
uint32_t cesReg = base->CESR;
|
||||
|
||||
hardwareInform->hardwareRevisionLevel = (cesReg & MPU_CESR_HRL_MASK) >> MPU_CESR_HRL_SHIFT;
|
||||
hardwareInform->slavePortsNumbers = (cesReg & MPU_CESR_NSP_MASK) >> MPU_CESR_NSP_SHIFT;
|
||||
hardwareInform->regionsNumbers = (mpu_region_total_num_t)((cesReg & MPU_CESR_NRGD_MASK) >> MPU_CESR_NRGD_SHIFT);
|
||||
}
|
||||
|
||||
void MPU_SetRegionConfig(MPU_Type *base, const mpu_region_config_t *regionConfig)
|
||||
{
|
||||
assert(regionConfig);
|
||||
|
||||
uint32_t wordReg = 0;
|
||||
uint8_t count;
|
||||
uint8_t number = regionConfig->regionNum;
|
||||
|
||||
/* The start and end address of the region descriptor. */
|
||||
base->WORD[number][0] = regionConfig->startAddress;
|
||||
base->WORD[number][1] = regionConfig->endAddress;
|
||||
|
||||
/* The region descriptor access rights control. */
|
||||
for (count = 0; count < MPU_REGIONDESCRIPTOR_WROD_REGNUM; count++)
|
||||
{
|
||||
wordReg |= MPU_WORD_LOW_MASTER(count, (((uint32_t)regionConfig->accessRights1[count].superAccessRights << 3U) |
|
||||
(uint8_t)regionConfig->accessRights1[count].userAccessRights)) |
|
||||
MPU_WORD_HIGH_MASTER(count, ((uint32_t)regionConfig->accessRights2[count].readEnable << 1U |
|
||||
(uint8_t)regionConfig->accessRights2[count].writeEnable));
|
||||
|
||||
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
|
||||
wordReg |= MPU_WORD_MASTER_PE(count, regionConfig->accessRights1[count].processIdentifierEnable);
|
||||
#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */
|
||||
}
|
||||
|
||||
/* Set region descriptor access rights. */
|
||||
base->WORD[number][2] = wordReg;
|
||||
|
||||
wordReg = MPU_WORD_VLD(1);
|
||||
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
|
||||
wordReg |= MPU_WORD_PID(regionConfig->processIdentifier) | MPU_WORD_PIDMASK(regionConfig->processIdMask);
|
||||
#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */
|
||||
|
||||
base->WORD[number][3] = wordReg;
|
||||
}
|
||||
|
||||
void MPU_SetRegionAddr(MPU_Type *base, mpu_region_num_t regionNum, uint32_t startAddr, uint32_t endAddr)
|
||||
{
|
||||
base->WORD[regionNum][0] = startAddr;
|
||||
base->WORD[regionNum][1] = endAddr;
|
||||
}
|
||||
|
||||
void MPU_SetRegionLowMasterAccessRights(MPU_Type *base,
|
||||
mpu_region_num_t regionNum,
|
||||
mpu_master_t masterNum,
|
||||
const mpu_low_masters_access_rights_t *accessRights)
|
||||
{
|
||||
assert(accessRights);
|
||||
#if FSL_FEATURE_MPU_HAS_MASTER4
|
||||
assert(masterNum < kMPU_Master4);
|
||||
#endif
|
||||
uint32_t mask = MPU_WORD_LOW_MASTER_MASK(masterNum);
|
||||
uint32_t right = base->RGDAAC[regionNum];
|
||||
|
||||
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
|
||||
mask |= MPU_LOW_MASTER_PE_MASK(masterNum);
|
||||
#endif
|
||||
|
||||
/* Build rights control value. */
|
||||
right &= ~mask;
|
||||
right |= MPU_WORD_LOW_MASTER(masterNum,
|
||||
((uint32_t)(accessRights->superAccessRights << 3U) | accessRights->userAccessRights));
|
||||
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
|
||||
right |= MPU_WORD_MASTER_PE(masterNum, accessRights->processIdentifierEnable);
|
||||
#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */
|
||||
|
||||
/* Set low master region access rights. */
|
||||
base->RGDAAC[regionNum] = right;
|
||||
}
|
||||
|
||||
void MPU_SetRegionHighMasterAccessRights(MPU_Type *base,
|
||||
mpu_region_num_t regionNum,
|
||||
mpu_master_t masterNum,
|
||||
const mpu_high_masters_access_rights_t *accessRights)
|
||||
{
|
||||
assert(accessRights);
|
||||
#if FSL_FEATURE_MPU_HAS_MASTER3
|
||||
assert(masterNum > kMPU_Master3);
|
||||
#endif
|
||||
uint32_t mask = MPU_WORD_HIGH_MASTER_MASK(masterNum);
|
||||
uint32_t right = base->RGDAAC[regionNum];
|
||||
|
||||
/* Build rights control value. */
|
||||
right &= ~mask;
|
||||
right |= MPU_WORD_HIGH_MASTER((masterNum - (uint8_t)kMPU_RegionNum04),
|
||||
(((uint32_t)accessRights->readEnable << 1U) | accessRights->writeEnable));
|
||||
/* Set low master region access rights. */
|
||||
base->RGDAAC[regionNum] = right;
|
||||
}
|
||||
|
||||
bool MPU_GetSlavePortErrorStatus(MPU_Type *base, mpu_slave_t slaveNum)
|
||||
{
|
||||
uint8_t sperr;
|
||||
|
||||
sperr = ((base->CESR & MPU_CESR_SPERR_MASK) >> MPU_CESR_SPERR_SHIFT) & (0x1U << slaveNum);
|
||||
|
||||
return (sperr != 0) ? true : false;
|
||||
}
|
||||
|
||||
void MPU_GetDetailErrorAccessInfo(MPU_Type *base, mpu_slave_t slaveNum, mpu_access_err_info_t *errInform)
|
||||
{
|
||||
assert(errInform);
|
||||
|
||||
uint16_t value;
|
||||
|
||||
/* Error address. */
|
||||
errInform->address = base->SP[slaveNum].EAR;
|
||||
|
||||
/* Error detail information. */
|
||||
value = (base->SP[slaveNum].EDR & MPU_EDR_EACD_MASK) >> MPU_EDR_EACD_SHIFT;
|
||||
if (!value)
|
||||
{
|
||||
errInform->accessControl = kMPU_NoRegionHit;
|
||||
}
|
||||
else if (!(value & (uint16_t)(value - 1)))
|
||||
{
|
||||
errInform->accessControl = kMPU_NoneOverlappRegion;
|
||||
}
|
||||
else
|
||||
{
|
||||
errInform->accessControl = kMPU_OverlappRegion;
|
||||
}
|
||||
|
||||
value = base->SP[slaveNum].EDR;
|
||||
errInform->master = (mpu_master_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->accessType = (mpu_err_access_type_t)((value & MPU_EDR_ERW_MASK) >> MPU_EDR_ERW_SHIFT);
|
||||
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
|
||||
errInform->processorIdentification = (uint8_t)((value & MPU_EDR_EPID_MASK) >> MPU_EDR_EPID_SHIFT);
|
||||
#endif
|
||||
|
||||
/*!< Clears error slave port bit. */
|
||||
value = (base->CESR & ~MPU_CESR_SPERR_MASK) | (0x1U << slaveNum);
|
||||
base->CESR = value;
|
||||
}
|
|
@ -0,0 +1,495 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_MPU_H_
|
||||
#define _FSL_MPU_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup mpu
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief MPU driver version 2.0.0. */
|
||||
#define FSL_MPU_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief MPU low master bit shift. */
|
||||
#define MPU_WORD_LOW_MASTER_SHIFT(n) (n * 6)
|
||||
|
||||
/*! @brief MPU low master bit mask. */
|
||||
#define MPU_WORD_LOW_MASTER_MASK(n) (0x1Fu << MPU_WORD_LOW_MASTER_SHIFT(n))
|
||||
|
||||
/*! @brief MPU low master bit width. */
|
||||
#define MPU_WORD_LOW_MASTER_WIDTH 5
|
||||
|
||||
/*! @brief MPU low master priority setting. */
|
||||
#define MPU_WORD_LOW_MASTER(n, x) \
|
||||
(((uint32_t)(((uint32_t)(x)) << MPU_WORD_LOW_MASTER_SHIFT(n))) & MPU_WORD_LOW_MASTER_MASK(n))
|
||||
|
||||
/*! @brief MPU low master process enable bit shift. */
|
||||
#define MPU_LOW_MASTER_PE_SHIFT(n) (n * 6 + 5)
|
||||
|
||||
/*! @brief MPU low master process enable bit mask. */
|
||||
#define MPU_LOW_MASTER_PE_MASK(n) (0x1u << MPU_LOW_MASTER_PE_SHIFT(n))
|
||||
|
||||
/*! @brief MPU low master process enable width. */
|
||||
#define MPU_WORD_MASTER_PE_WIDTH 1
|
||||
|
||||
/*! @brief MPU low master process enable setting. */
|
||||
#define MPU_WORD_MASTER_PE(n, x) \
|
||||
(((uint32_t)(((uint32_t)(x)) << MPU_LOW_MASTER_PE_SHIFT(n))) & MPU_LOW_MASTER_PE_MASK(n))
|
||||
|
||||
/*! @brief MPU high master bit shift. */
|
||||
#define MPU_WORD_HIGH_MASTER_SHIFT(n) (n * 2 + 24)
|
||||
|
||||
/*! @brief MPU high master bit mask. */
|
||||
#define MPU_WORD_HIGH_MASTER_MASK(n) (0x03u << MPU_WORD_HIGH_MASTER_SHIFT(n))
|
||||
|
||||
/*! @brief MPU high master bit width. */
|
||||
#define MPU_WORD_HIGH_MASTER_WIDTH 2
|
||||
|
||||
/*! @brief MPU high master priority setting. */
|
||||
#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. */
|
||||
typedef enum _mpu_region_total_num
|
||||
{
|
||||
kMPU_8Regions = 0x0U, /*!< MPU supports 8 regions. */
|
||||
kMPU_12Regions = 0x1U, /*!< MPU supports 12 regions. */
|
||||
kMPU_16Regions = 0x2U /*!< MPU supports 16 regions. */
|
||||
} mpu_region_total_num_t;
|
||||
|
||||
/*! @brief MPU slave port number. */
|
||||
typedef enum _mpu_slave
|
||||
{
|
||||
kMPU_Slave0 = 4U, /*!< MPU slave port 0. */
|
||||
kMPU_Slave1 = 3U, /*!< MPU slave port 1. */
|
||||
kMPU_Slave2 = 2U, /*!< MPU slave port 2. */
|
||||
kMPU_Slave3 = 1U, /*!< MPU slave port 3. */
|
||||
kMPU_Slave4 = 0U /*!< MPU slave port 4. */
|
||||
} mpu_slave_t;
|
||||
|
||||
/*! @brief MPU error access control detail. */
|
||||
typedef enum _mpu_err_access_control
|
||||
{
|
||||
kMPU_NoRegionHit = 0U, /*!< No region hit error. */
|
||||
kMPU_NoneOverlappRegion = 1U, /*!< Access single region error. */
|
||||
kMPU_OverlappRegion = 2U /*!< Access overlapping region error. */
|
||||
} mpu_err_access_control_t;
|
||||
|
||||
/*! @brief MPU error access type. */
|
||||
typedef enum _mpu_err_access_type
|
||||
{
|
||||
kMPU_ErrTypeRead = 0U, /*!< MPU error access type --- read. */
|
||||
kMPU_ErrTypeWrite = 1U /*!< MPU error access type --- write. */
|
||||
} mpu_err_access_type_t;
|
||||
|
||||
/*! @brief MPU access error attributes.*/
|
||||
typedef enum _mpu_err_attributes
|
||||
{
|
||||
kMPU_InstructionAccessInUserMode = 0U, /*!< Access instruction error in user mode. */
|
||||
kMPU_DataAccessInUserMode = 1U, /*!< Access data error in user mode. */
|
||||
kMPU_InstructionAccessInSupervisorMode = 2U, /*!< Access instruction error in supervisor mode. */
|
||||
kMPU_DataAccessInSupervisorMode = 3U /*!< Access data error in supervisor mode. */
|
||||
} mpu_err_attributes_t;
|
||||
|
||||
/*! @brief MPU access rights in supervisor mode for master port 0 ~ port 3. */
|
||||
typedef enum _mpu_supervisor_access_rights
|
||||
{
|
||||
kMPU_SupervisorReadWriteExecute = 0U, /*!< Read write and execute operations are allowed in supervisor mode. */
|
||||
kMPU_SupervisorReadExecute = 1U, /*!< Read and execute operations are allowed in supervisor mode. */
|
||||
kMPU_SupervisorReadWrite = 2U, /*!< Read write operations are allowed in supervisor mode. */
|
||||
kMPU_SupervisorEqualToUsermode = 3U /*!< Access permission equal to user mode. */
|
||||
} mpu_supervisor_access_rights_t;
|
||||
|
||||
/*! @brief MPU access rights in user mode for master port 0 ~ port 3. */
|
||||
typedef enum _mpu_user_access_rights
|
||||
{
|
||||
kMPU_UserNoAccessRights = 0U, /*!< No access allowed in user mode. */
|
||||
kMPU_UserExecute = 1U, /*!< Execute operation is allowed in user mode. */
|
||||
kMPU_UserWrite = 2U, /*!< Write operation is allowed in user mode. */
|
||||
kMPU_UserWriteExecute = 3U, /*!< Write and execute operations are allowed in user mode. */
|
||||
kMPU_UserRead = 4U, /*!< Read is allowed in user mode. */
|
||||
kMPU_UserReadExecute = 5U, /*!< Read and execute operations are allowed in user mode. */
|
||||
kMPU_UserReadWrite = 6U, /*!< Read and write operations are allowed in user mode. */
|
||||
kMPU_UserReadWriteExecute = 7U /*!< Read write and execute operations are allowed in user mode. */
|
||||
} mpu_user_access_rights_t;
|
||||
|
||||
/*! @brief MPU hardware basic information. */
|
||||
typedef struct _mpu_hardware_info
|
||||
{
|
||||
uint8_t hardwareRevisionLevel; /*!< Specifies the MPU's hardware and definition reversion level. */
|
||||
uint8_t slavePortsNumbers; /*!< Specifies the number of slave ports connected to MPU. */
|
||||
mpu_region_total_num_t regionsNumbers; /*!< Indicates the number of region descriptors implemented. */
|
||||
} mpu_hardware_info_t;
|
||||
|
||||
/*! @brief MPU detail error access information. */
|
||||
typedef struct _mpu_access_err_info
|
||||
{
|
||||
mpu_master_t master; /*!< Access error master. */
|
||||
mpu_err_attributes_t attributes; /*!< Access error attributes. */
|
||||
mpu_err_access_type_t accessType; /*!< Access error type. */
|
||||
mpu_err_access_control_t accessControl; /*!< Access error control. */
|
||||
uint32_t address; /*!< Access error address. */
|
||||
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
|
||||
uint8_t processorIdentification; /*!< Access error processor identification. */
|
||||
#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */
|
||||
} mpu_access_err_info_t;
|
||||
|
||||
/*! @brief MPU access rights for low master master port 0 ~ port 3. */
|
||||
typedef struct _mpu_low_masters_access_rights
|
||||
{
|
||||
mpu_supervisor_access_rights_t superAccessRights; /*!< Master access rights in supervisor mode. */
|
||||
mpu_user_access_rights_t userAccessRights; /*!< Master access rights in user mode. */
|
||||
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
|
||||
bool processIdentifierEnable; /*!< Enables or disables process identifier. */
|
||||
#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */
|
||||
} mpu_low_masters_access_rights_t;
|
||||
|
||||
/*! @brief MPU access rights mode for high master port 4 ~ port 7. */
|
||||
typedef struct _mpu_high_masters_access_rights
|
||||
{
|
||||
bool writeEnable; /*!< Enables or disables write permission. */
|
||||
bool readEnable; /*!< Enables or disables read permission. */
|
||||
} mpu_high_masters_access_rights_t;
|
||||
|
||||
/*!
|
||||
* @brief MPU region configuration structure.
|
||||
*
|
||||
* This structure is used to configure the regionNum region.
|
||||
* The accessRights1[0] ~ accessRights1[3] are used to configure the four low master
|
||||
* numbers: master 0 ~ master 3. The accessRights2[0] ~ accessRights2[3] are
|
||||
* used to configure the four high master numbers: master 4 ~ master 7.
|
||||
* The master port assignment is the chip configuration. Normally, the core is the
|
||||
* master 0, debugger is the master 1.
|
||||
* Note: 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.
|
||||
* 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
|
||||
* the permission fields associated with the other masters. This protection guarantee
|
||||
* 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
|
||||
* the region configuration when regionNum is kMPU_RegionNum00.
|
||||
*/
|
||||
typedef struct _mpu_region_config
|
||||
{
|
||||
mpu_region_num_t regionNum; /*!< MPU region number. */
|
||||
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. */
|
||||
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. */
|
||||
mpu_low_masters_access_rights_t accessRights1[4]; /*!< Low masters access permission. */
|
||||
mpu_high_masters_access_rights_t accessRights2[4]; /*!< High masters access permission. */
|
||||
#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER
|
||||
uint8_t processIdentifier; /*!< Process identifier used when "processIdentifierEnable" set with true. */
|
||||
uint8_t
|
||||
processIdMask; /*!< Process identifier mask. The setting bit will ignore the same bit in process identifier. */
|
||||
#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */
|
||||
} mpu_region_config_t;
|
||||
|
||||
/*!
|
||||
* @brief The configuration structure for the MPU initialization.
|
||||
*
|
||||
* This structure is used when calling the MPU_Init function.
|
||||
*/
|
||||
typedef struct _mpu_config
|
||||
{
|
||||
mpu_region_config_t regionConfig; /*!< region access permission. */
|
||||
struct _mpu_config *next; /*!< pointer to the next structure. */
|
||||
} mpu_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* _cplusplus */
|
||||
|
||||
/*!
|
||||
* @name Initialization and deinitialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the MPU with the user configuration structure.
|
||||
*
|
||||
* This function configures the MPU module with the user-defined configuration.
|
||||
*
|
||||
* @param base MPU peripheral base address.
|
||||
* @param config The pointer to the configuration structure.
|
||||
*/
|
||||
void MPU_Init(MPU_Type *base, const mpu_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the MPU regions.
|
||||
*
|
||||
* @param base MPU peripheral base address.
|
||||
*/
|
||||
void MPU_Deinit(MPU_Type *base);
|
||||
|
||||
/* @}*/
|
||||
|
||||
/*!
|
||||
* @name Basic Control Operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables/disables the MPU globally.
|
||||
*
|
||||
* Call this API to enable or disable the MPU module.
|
||||
*
|
||||
* @param base MPU peripheral base address.
|
||||
* @param enable True enable MPU, false disable MPU.
|
||||
*/
|
||||
static inline void MPU_Enable(MPU_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
/* Enable the MPU globally. */
|
||||
base->CESR |= MPU_CESR_VLD_MASK;
|
||||
}
|
||||
else
|
||||
{ /* Disable the MPU globally. */
|
||||
base->CESR &= ~MPU_CESR_VLD_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables/disables the MPU for a special region.
|
||||
*
|
||||
* When MPU is enabled, call this API to disable an unused region
|
||||
* of an enabled MPU. Call this API to minimize the power dissipation.
|
||||
*
|
||||
* @param base MPU peripheral base address.
|
||||
* @param number MPU region number.
|
||||
* @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)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
/* Enable the #number region MPU. */
|
||||
base->WORD[number][3] |= MPU_WORD_VLD_MASK;
|
||||
}
|
||||
else
|
||||
{ /* Disable the #number region MPU. */
|
||||
base->WORD[number][3] &= ~MPU_WORD_VLD_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the MPU basic hardware information.
|
||||
*
|
||||
* @param base MPU peripheral base address.
|
||||
* @param hardwareInform The pointer to the MPU hardware information structure. See "mpu_hardware_info_t".
|
||||
*/
|
||||
void MPU_GetHardwareInfo(MPU_Type *base, mpu_hardware_info_t *hardwareInform);
|
||||
|
||||
/*!
|
||||
* @brief Sets the MPU region.
|
||||
*
|
||||
* Note: Due to the MPU protection, the kMPU_RegionNum00 does not allow writes from the
|
||||
* core to affect the start and end address nor the permissions associated with
|
||||
* the debugger. It can only write the permission fields associated
|
||||
* with the other masters.
|
||||
*
|
||||
* @param base MPU peripheral base address.
|
||||
* @param regionConfig The pointer to the MPU user configuration structure. See "mpu_region_config_t".
|
||||
*/
|
||||
void MPU_SetRegionConfig(MPU_Type *base, const mpu_region_config_t *regionConfig);
|
||||
|
||||
/*!
|
||||
* @brief Sets the region start and end address.
|
||||
*
|
||||
* 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.
|
||||
* 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.
|
||||
* Note: Due to the MPU protection, the startAddr and endAddr can't be
|
||||
* changed by the core when regionNum is "kMPU_RegionNum00".
|
||||
*
|
||||
* @param base MPU peripheral base address.
|
||||
* @param regionNum MPU region number.
|
||||
* @param startAddr Region start address.
|
||||
* @param endAddr Region end address.
|
||||
*/
|
||||
void MPU_SetRegionAddr(MPU_Type *base, mpu_region_num_t regionNum, uint32_t startAddr, uint32_t endAddr);
|
||||
|
||||
/*!
|
||||
* @brief Sets the MPU region access rights for low master port 0 ~ port 3.
|
||||
* This can be used to change the region access rights for any master port for any region.
|
||||
*
|
||||
* @param base MPU peripheral base address.
|
||||
* @param regionNum MPU region number.
|
||||
* @param masterNum MPU master number. Should range from kMPU_Master0 ~ kMPU_Master3.
|
||||
* @param accessRights The pointer to the MPU access rights configuration. See "mpu_low_masters_access_rights_t".
|
||||
*/
|
||||
void MPU_SetRegionLowMasterAccessRights(MPU_Type *base,
|
||||
mpu_region_num_t regionNum,
|
||||
mpu_master_t masterNum,
|
||||
const mpu_low_masters_access_rights_t *accessRights);
|
||||
|
||||
/*!
|
||||
* @brief Sets the MPU region access rights for high master port 4 ~ port 7.
|
||||
* This can be used to change the region access rights for any master port for any region.
|
||||
*
|
||||
* @param base MPU peripheral base address.
|
||||
* @param regionNum MPU region number.
|
||||
* @param masterNum MPU master number. Should range from kMPU_Master4 ~ kMPU_Master7.
|
||||
* @param accessRights The pointer to the MPU access rights configuration. See "mpu_high_masters_access_rights_t".
|
||||
*/
|
||||
void MPU_SetRegionHighMasterAccessRights(MPU_Type *base,
|
||||
mpu_region_num_t regionNum,
|
||||
mpu_master_t masterNum,
|
||||
const mpu_high_masters_access_rights_t *accessRights);
|
||||
|
||||
/*!
|
||||
* @brief Gets the numbers of slave ports where errors occur.
|
||||
*
|
||||
* @param base MPU peripheral base address.
|
||||
* @param slaveNum MPU slave port number.
|
||||
* @return The slave ports error status.
|
||||
* true - error happens in this slave port.
|
||||
* false - error didn't happen in this slave port.
|
||||
*/
|
||||
bool MPU_GetSlavePortErrorStatus(MPU_Type *base, mpu_slave_t slaveNum);
|
||||
|
||||
/*!
|
||||
* @brief Gets the MPU detailed error access information.
|
||||
*
|
||||
* @param base MPU peripheral base address.
|
||||
* @param slaveNum MPU slave port number.
|
||||
* @param errInform The pointer to the MPU access error information. See "mpu_access_err_info_t".
|
||||
*/
|
||||
void MPU_GetDetailErrorAccessInfo(MPU_Type *base, mpu_slave_t slaveNum, mpu_access_err_info_t *errInform);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_MPU_H_ */
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_pdb.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Get instance number for PDB module.
|
||||
*
|
||||
* @param base PDB peripheral base address
|
||||
*/
|
||||
static uint32_t PDB_GetInstance(PDB_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/*! @brief Pointers to PDB bases for each instance. */
|
||||
static PDB_Type *const s_pdbBases[] = PDB_BASE_PTRS;
|
||||
/*! @brief Pointers to PDB clocks for each instance. */
|
||||
const clock_ip_name_t s_pdbClocks[] = PDB_CLOCKS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Codes
|
||||
******************************************************************************/
|
||||
static uint32_t PDB_GetInstance(PDB_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_PDB_COUNT; instance++)
|
||||
{
|
||||
if (s_pdbBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < FSL_FEATURE_SOC_PDB_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void PDB_Init(PDB_Type *base, const pdb_config_t *config)
|
||||
{
|
||||
assert(NULL != config);
|
||||
|
||||
uint32_t tmp32;
|
||||
|
||||
/* Enable the clock. */
|
||||
CLOCK_EnableClock(s_pdbClocks[PDB_GetInstance(base)]);
|
||||
|
||||
/* Configure. */
|
||||
/* PDBx_SC. */
|
||||
tmp32 = base->SC &
|
||||
~(PDB_SC_LDMOD_MASK | PDB_SC_PRESCALER_MASK | PDB_SC_TRGSEL_MASK | PDB_SC_MULT_MASK | PDB_SC_CONT_MASK);
|
||||
|
||||
tmp32 |= PDB_SC_LDMOD(config->loadValueMode) | PDB_SC_PRESCALER(config->prescalerDivider) |
|
||||
PDB_SC_TRGSEL(config->triggerInputSource) | PDB_SC_MULT(config->dividerMultiplicationFactor);
|
||||
if (config->enableContinuousMode)
|
||||
{
|
||||
tmp32 |= PDB_SC_CONT_MASK;
|
||||
}
|
||||
base->SC = tmp32;
|
||||
|
||||
PDB_Enable(base, true); /* Enable the PDB module. */
|
||||
}
|
||||
|
||||
void PDB_Deinit(PDB_Type *base)
|
||||
{
|
||||
PDB_Enable(base, false); /* Disable the PDB module. */
|
||||
|
||||
/* Disable the clock. */
|
||||
CLOCK_DisableClock(s_pdbClocks[PDB_GetInstance(base)]);
|
||||
}
|
||||
|
||||
void PDB_GetDefaultConfig(pdb_config_t *config)
|
||||
{
|
||||
assert(NULL != config);
|
||||
|
||||
config->loadValueMode = kPDB_LoadValueImmediately;
|
||||
config->prescalerDivider = kPDB_PrescalerDivider1;
|
||||
config->dividerMultiplicationFactor = kPDB_DividerMultiplicationFactor1;
|
||||
config->triggerInputSource = kPDB_TriggerSoftware;
|
||||
config->enableContinuousMode = false;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_PDB_HAS_DAC) && FSL_FEATURE_PDB_HAS_DAC
|
||||
void PDB_SetDACTriggerConfig(PDB_Type *base, uint32_t channel, pdb_dac_trigger_config_t *config)
|
||||
{
|
||||
assert(channel < PDB_INTC_COUNT);
|
||||
assert(NULL != config);
|
||||
|
||||
uint32_t tmp32 = 0U;
|
||||
|
||||
/* PDBx_DACINTC. */
|
||||
if (config->enableExternalTriggerInput)
|
||||
{
|
||||
tmp32 |= PDB_INTC_EXT_MASK;
|
||||
}
|
||||
if (config->enableIntervalTrigger)
|
||||
{
|
||||
tmp32 |= PDB_INTC_TOE_MASK;
|
||||
}
|
||||
base->DAC[channel].INTC = tmp32;
|
||||
}
|
||||
#endif /* FSL_FEATURE_PDB_HAS_DAC */
|
|
@ -0,0 +1,576 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FSL_PDB_H_
|
||||
#define _FSL_PDB_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup pdb
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief PDB driver version 2.0.1. */
|
||||
#define FSL_PDB_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief PDB flags.
|
||||
*/
|
||||
enum _pdb_status_flags
|
||||
{
|
||||
kPDB_LoadOKFlag = PDB_SC_LDOK_MASK, /*!< This flag is automatically cleared when the values in buffers are
|
||||
loaded into the internal registers after the LDOK bit is set or the
|
||||
PDBEN is cleared. */
|
||||
kPDB_DelayEventFlag = PDB_SC_PDBIF_MASK, /*!< PDB timer delay event flag. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief PDB ADC PreTrigger channel flags.
|
||||
*/
|
||||
enum _pdb_adc_pretrigger_flags
|
||||
{
|
||||
/* PDB PreTrigger channel match flags. */
|
||||
kPDB_ADCPreTriggerChannel0Flag = PDB_S_CF(1U << 0), /*!< Pre-Trigger 0 flag. */
|
||||
kPDB_ADCPreTriggerChannel1Flag = PDB_S_CF(1U << 1), /*!< Pre-Trigger 1 flag. */
|
||||
#if (PDB_DLY_COUNT > 2)
|
||||
kPDB_ADCPreTriggerChannel2Flag = PDB_S_CF(1U << 2), /*!< Pre-Trigger 2 flag. */
|
||||
kPDB_ADCPreTriggerChannel3Flag = PDB_S_CF(1U << 3), /*!< Pre-Trigger 3 flag. */
|
||||
#endif /* PDB_DLY_COUNT > 2 */
|
||||
#if (PDB_DLY_COUNT > 4)
|
||||
kPDB_ADCPreTriggerChannel4Flag = PDB_S_CF(1U << 4), /*!< Pre-Trigger 4 flag. */
|
||||
kPDB_ADCPreTriggerChannel5Flag = PDB_S_CF(1U << 5), /*!< Pre-Trigger 5 flag. */
|
||||
kPDB_ADCPreTriggerChannel6Flag = PDB_S_CF(1U << 6), /*!< Pre-Trigger 6 flag. */
|
||||
kPDB_ADCPreTriggerChannel7Flag = PDB_S_CF(1U << 7), /*!< Pre-Trigger 7 flag. */
|
||||
#endif /* PDB_DLY_COUNT > 4 */
|
||||
|
||||
/* PDB PreTrigger channel error flags. */
|
||||
kPDB_ADCPreTriggerChannel0ErrorFlag = PDB_S_ERR(1U << 0), /*!< Pre-Trigger 0 Error. */
|
||||
kPDB_ADCPreTriggerChannel1ErrorFlag = PDB_S_ERR(1U << 1), /*!< Pre-Trigger 1 Error. */
|
||||
#if (PDB_DLY_COUNT > 2)
|
||||
kPDB_ADCPreTriggerChannel2ErrorFlag = PDB_S_ERR(1U << 2), /*!< Pre-Trigger 2 Error. */
|
||||
kPDB_ADCPreTriggerChannel3ErrorFlag = PDB_S_ERR(1U << 3), /*!< Pre-Trigger 3 Error. */
|
||||
#endif /* PDB_DLY_COUNT > 2 */
|
||||
#if (PDB_DLY_COUNT > 4)
|
||||
kPDB_ADCPreTriggerChannel4ErrorFlag = PDB_S_ERR(1U << 4), /*!< Pre-Trigger 4 Error. */
|
||||
kPDB_ADCPreTriggerChannel5ErrorFlag = PDB_S_ERR(1U << 5), /*!< Pre-Trigger 5 Error. */
|
||||
kPDB_ADCPreTriggerChannel6ErrorFlag = PDB_S_ERR(1U << 6), /*!< Pre-Trigger 6 Error. */
|
||||
kPDB_ADCPreTriggerChannel7ErrorFlag = PDB_S_ERR(1U << 7), /*!< Pre-Trigger 7 Error. */
|
||||
#endif /* PDB_DLY_COUNT > 4 */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief PDB buffer interrupts.
|
||||
*/
|
||||
enum _pdb_interrupt_enable
|
||||
{
|
||||
kPDB_SequenceErrorInterruptEnable = PDB_SC_PDBEIE_MASK, /*!< PDB sequence error interrupt enable. */
|
||||
kPDB_DelayInterruptEnable = PDB_SC_PDBIE_MASK, /*!< PDB delay interrupt enable. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief PDB load value mode.
|
||||
*
|
||||
* Selects the mode to load the internal values after doing the load operation (write 1 to PDBx_SC[LDOK]).
|
||||
* These values are for:
|
||||
* - PDB counter (PDBx_MOD, PDBx_IDLY)
|
||||
* - ADC trigger (PDBx_CHnDLYm)
|
||||
* - DAC trigger (PDBx_DACINTx)
|
||||
* - CMP trigger (PDBx_POyDLY)
|
||||
*/
|
||||
typedef enum _pdb_load_value_mode
|
||||
{
|
||||
kPDB_LoadValueImmediately = 0U, /*!< Load immediately after 1 is written to LDOK. */
|
||||
kPDB_LoadValueOnCounterOverflow = 1U, /*!< Load when the PDB counter overflows (reaches the MOD
|
||||
register value). */
|
||||
kPDB_LoadValueOnTriggerInput = 2U, /*!< Load a trigger input event is detected. */
|
||||
kPDB_LoadValueOnCounterOverflowOrTriggerInput = 3U, /*!< Load either when the PDB counter overflows or a trigger
|
||||
input is detected. */
|
||||
} pdb_load_value_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief Prescaler divider.
|
||||
*
|
||||
* Counting uses the peripheral clock divided by multiplication factor selected by times of MULT.
|
||||
*/
|
||||
typedef enum _pdb_prescaler_divider
|
||||
{
|
||||
kPDB_PrescalerDivider1 = 0U, /*!< Divider x1. */
|
||||
kPDB_PrescalerDivider2 = 1U, /*!< Divider x2. */
|
||||
kPDB_PrescalerDivider4 = 2U, /*!< Divider x4. */
|
||||
kPDB_PrescalerDivider8 = 3U, /*!< Divider x8. */
|
||||
kPDB_PrescalerDivider16 = 4U, /*!< Divider x16. */
|
||||
kPDB_PrescalerDivider32 = 5U, /*!< Divider x32. */
|
||||
kPDB_PrescalerDivider64 = 6U, /*!< Divider x64. */
|
||||
kPDB_PrescalerDivider128 = 7U, /*!< Divider x128. */
|
||||
} pdb_prescaler_divider_t;
|
||||
|
||||
/*!
|
||||
* @brief Multiplication factor select for prescaler.
|
||||
*
|
||||
* Selects the multiplication factor of the prescaler divider for the counter clock.
|
||||
*/
|
||||
typedef enum _pdb_divider_multiplication_factor
|
||||
{
|
||||
kPDB_DividerMultiplicationFactor1 = 0U, /*!< Multiplication factor is 1. */
|
||||
kPDB_DividerMultiplicationFactor10 = 1U, /*!< Multiplication factor is 10. */
|
||||
kPDB_DividerMultiplicationFactor20 = 2U, /*!< Multiplication factor is 20. */
|
||||
kPDB_DividerMultiplicationFactor40 = 3U, /*!< Multiplication factor is 40. */
|
||||
} pdb_divider_multiplication_factor_t;
|
||||
|
||||
/*!
|
||||
* @brief Trigger input source
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
typedef enum _pdb_trigger_input_source
|
||||
{
|
||||
kPDB_TriggerInput0 = 0U, /*!< Trigger-In 0. */
|
||||
kPDB_TriggerInput1 = 1U, /*!< Trigger-In 1. */
|
||||
kPDB_TriggerInput2 = 2U, /*!< Trigger-In 2. */
|
||||
kPDB_TriggerInput3 = 3U, /*!< Trigger-In 3. */
|
||||
kPDB_TriggerInput4 = 4U, /*!< Trigger-In 4. */
|
||||
kPDB_TriggerInput5 = 5U, /*!< Trigger-In 5. */
|
||||
kPDB_TriggerInput6 = 6U, /*!< Trigger-In 6. */
|
||||
kPDB_TriggerInput7 = 7U, /*!< Trigger-In 7. */
|
||||
kPDB_TriggerInput8 = 8U, /*!< Trigger-In 8. */
|
||||
kPDB_TriggerInput9 = 9U, /*!< Trigger-In 9. */
|
||||
kPDB_TriggerInput10 = 10U, /*!< Trigger-In 10. */
|
||||
kPDB_TriggerInput11 = 11U, /*!< Trigger-In 11. */
|
||||
kPDB_TriggerInput12 = 12U, /*!< Trigger-In 12. */
|
||||
kPDB_TriggerInput13 = 13U, /*!< Trigger-In 13. */
|
||||
kPDB_TriggerInput14 = 14U, /*!< Trigger-In 14. */
|
||||
kPDB_TriggerSoftware = 15U, /*!< Trigger-In 15. */
|
||||
} pdb_trigger_input_source_t;
|
||||
|
||||
/*!
|
||||
* @brief PDB module configuration.
|
||||
*/
|
||||
typedef struct _pdb_config
|
||||
{
|
||||
pdb_load_value_mode_t loadValueMode; /*!< Select the load value mode. */
|
||||
pdb_prescaler_divider_t prescalerDivider; /*!< Select the prescaler divider. */
|
||||
pdb_divider_multiplication_factor_t dividerMultiplicationFactor; /*!< Multiplication factor select for prescaler. */
|
||||
pdb_trigger_input_source_t triggerInputSource; /*!< Select the trigger input source. */
|
||||
bool enableContinuousMode; /*!< Enable the PDB operation in Continuous mode.*/
|
||||
} pdb_config_t;
|
||||
|
||||
/*!
|
||||
* @brief PDB ADC Pre-Trigger configuration.
|
||||
*/
|
||||
typedef struct _pdb_adc_pretrigger_config
|
||||
{
|
||||
uint32_t enablePreTriggerMask; /*!< PDB Channel Pre-Trigger Enable. */
|
||||
uint32_t enableOutputMask; /*!< PDB Channel Pre-Trigger Output Select.
|
||||
PDB channel's corresponding pre-trigger asserts when the counter
|
||||
reaches the channel delay register. */
|
||||
uint32_t enableBackToBackOperationMask; /*!< PDB Channel Pre-Trigger Back-to-Back Operation Enable.
|
||||
Back-to-back operation enables the ADC conversions complete to trigger
|
||||
the next PDB channel pre-trigger and trigger output, so that the ADC
|
||||
conversions can be triggered on next set of configuration and results
|
||||
registers.*/
|
||||
} pdb_adc_pretrigger_config_t;
|
||||
|
||||
/*!
|
||||
* @brief PDB DAC trigger configuration.
|
||||
*/
|
||||
typedef struct _pdb_dac_trigger_config
|
||||
{
|
||||
bool enableExternalTriggerInput; /*!< Enables the external trigger for DAC interval counter. */
|
||||
bool enableIntervalTrigger; /*!< Enables the DAC interval trigger. */
|
||||
} pdb_dac_trigger_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the PDB module.
|
||||
*
|
||||
* This function is to make the initialization for PDB module. The operations includes are:
|
||||
* - Enable the clock for PDB instance.
|
||||
* - Configure the PDB module.
|
||||
* - Enable the PDB module.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param config Pointer to configuration structure. See "pdb_config_t".
|
||||
*/
|
||||
void PDB_Init(PDB_Type *base, const pdb_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief De-initializes the PDB module.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
*/
|
||||
void PDB_Deinit(PDB_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the PDB user configure structure.
|
||||
*
|
||||
* This function initializes the user configure structure to default value. the default value are:
|
||||
* @code
|
||||
* config->loadValueMode = kPDB_LoadValueImmediately;
|
||||
* config->prescalerDivider = kPDB_PrescalerDivider1;
|
||||
* config->dividerMultiplicationFactor = kPDB_DividerMultiplicationFactor1;
|
||||
* config->triggerInputSource = kPDB_TriggerSoftware;
|
||||
* config->enableContinuousMode = false;
|
||||
* @endcode
|
||||
* @param config Pointer to configuration structure. See "pdb_config_t".
|
||||
*/
|
||||
void PDB_GetDefaultConfig(pdb_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Enables the PDB module.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param enable Enable the module or not.
|
||||
*/
|
||||
static inline void PDB_Enable(PDB_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->SC |= PDB_SC_PDBEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->SC &= ~PDB_SC_PDBEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Basic Counter
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Triggers the PDB counter by software.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
*/
|
||||
static inline void PDB_DoSoftwareTrigger(PDB_Type *base)
|
||||
{
|
||||
base->SC |= PDB_SC_SWTRIG_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Loads the counter values.
|
||||
*
|
||||
* This function is to load the counter values from their internal buffer.
|
||||
* See "pdb_load_value_mode_t" about PDB's load mode.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
*/
|
||||
static inline void PDB_DoLoadValues(PDB_Type *base)
|
||||
{
|
||||
base->SC |= PDB_SC_LDOK_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables the DMA for the PDB module.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param enable Enable the feature or not.
|
||||
*/
|
||||
static inline void PDB_EnableDMA(PDB_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->SC |= PDB_SC_DMAEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->SC &= ~PDB_SC_DMAEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables the interrupts for the PDB module.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param mask Mask value for interrupts. See "_pdb_interrupt_enable".
|
||||
*/
|
||||
static inline void PDB_EnableInterrupts(PDB_Type *base, uint32_t mask)
|
||||
{
|
||||
assert(0U == (mask & ~(PDB_SC_PDBEIE_MASK | PDB_SC_PDBIE_MASK)));
|
||||
|
||||
base->SC |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the interrupts for the PDB module.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param mask Mask value for interrupts. See "_pdb_interrupt_enable".
|
||||
*/
|
||||
static inline void PDB_DisableInterrupts(PDB_Type *base, uint32_t mask)
|
||||
{
|
||||
assert(0U == (mask & ~(PDB_SC_PDBEIE_MASK | PDB_SC_PDBIE_MASK)));
|
||||
|
||||
base->SC &= ~mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the status flags of the PDB module.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
*
|
||||
* @return Mask value for asserted flags. See "_pdb_status_flags".
|
||||
*/
|
||||
static inline uint32_t PDB_GetStatusFlags(PDB_Type *base)
|
||||
{
|
||||
return base->SC & (PDB_SC_PDBIF_MASK | PDB_SC_LDOK_MASK);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the status flags of the PDB module.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param mask Mask value of flags. See "_pdb_status_flags".
|
||||
*/
|
||||
static inline void PDB_ClearStatusFlags(PDB_Type *base, uint32_t mask)
|
||||
{
|
||||
assert(0U == (mask & ~PDB_SC_PDBIF_MASK));
|
||||
|
||||
base->SC &= ~mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Specifies the period of the counter.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param value Setting value for the modulus. 16-bit is available.
|
||||
*/
|
||||
static inline void PDB_SetModulusValue(PDB_Type *base, uint32_t value)
|
||||
{
|
||||
base->MOD = PDB_MOD_MOD(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the PDB counter's current value.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
*
|
||||
* @return PDB counter's current value.
|
||||
*/
|
||||
static inline uint32_t PDB_GetCounterValue(PDB_Type *base)
|
||||
{
|
||||
return base->CNT;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the value for PDB counter delay event.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param value Setting value for PDB counter delay event. 16-bit is available.
|
||||
*/
|
||||
static inline void PDB_SetCounterDelayValue(PDB_Type *base, uint32_t value)
|
||||
{
|
||||
base->IDLY = PDB_IDLY_IDLY(value);
|
||||
}
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name ADC Pre-Trigger
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Configures the ADC PreTrigger in PDB module.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param channel Channel index for ADC instance.
|
||||
* @param config Pointer to 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)
|
||||
{
|
||||
assert(channel < PDB_C1_COUNT);
|
||||
assert(NULL != config);
|
||||
|
||||
base->CH[channel].C1 = PDB_C1_BB(config->enableBackToBackOperationMask) | PDB_C1_TOS(config->enableOutputMask) |
|
||||
PDB_C1_EN(config->enableOutputMask);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the value for 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
|
||||
* corresponding pre-trigger. The pre-trigger asserts when the PDB counter is equal to the setting value here.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param channel Channel 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.
|
||||
*/
|
||||
static inline void PDB_SetADCPreTriggerDelayValue(PDB_Type *base, uint32_t channel, uint32_t preChannel, uint32_t value)
|
||||
{
|
||||
assert(channel < PDB_C1_COUNT);
|
||||
assert(preChannel < PDB_DLY_COUNT);
|
||||
|
||||
base->CH[channel].DLY[preChannel] = PDB_DLY_DLY(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the ADC Pre-Trigger's status flags.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param channel Channel index for ADC instance.
|
||||
*
|
||||
* @return Mask value for asserted flags. See "_pdb_adc_pretrigger_flags".
|
||||
*/
|
||||
static inline uint32_t PDB_GetADCPreTriggerStatusFlags(PDB_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < PDB_C1_COUNT);
|
||||
|
||||
return base->CH[channel].S;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the ADC Pre-Trigger's status flags.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param channel Channel index for ADC instance.
|
||||
* @param mask Mask value for flags. See "_pdb_adc_pretrigger_flags".
|
||||
*/
|
||||
static inline void PDB_ClearADCPreTriggerStatusFlags(PDB_Type *base, uint32_t channel, uint32_t mask)
|
||||
{
|
||||
assert(channel < PDB_C1_COUNT);
|
||||
|
||||
base->CH[channel].S &= ~mask;
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(FSL_FEATURE_PDB_HAS_DAC) && FSL_FEATURE_PDB_HAS_DAC
|
||||
/*!
|
||||
* @name DAC Interval Trigger
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Configures the DAC trigger in PDB module.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param channel Channel index for DAC instance.
|
||||
* @param config Pointer to configuration structure. See "pdb_dac_trigger_config_t".
|
||||
*/
|
||||
void PDB_SetDACTriggerConfig(PDB_Type *base, uint32_t channel, pdb_dac_trigger_config_t *config);
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* buffer when the DAC interval counter is equal to the setting value here.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param channel Channel index for DAC instance.
|
||||
* @param value Setting value for the DAC interval event.
|
||||
*/
|
||||
static inline void PDB_SetDACTriggerIntervalValue(PDB_Type *base, uint32_t channel, uint32_t value)
|
||||
{
|
||||
assert(channel < PDB_INT_COUNT);
|
||||
|
||||
base->DAC[channel].INT = PDB_INT_INT(value);
|
||||
}
|
||||
|
||||
/* @} */
|
||||
#endif /* FSL_FEATURE_PDB_HAS_DAC */
|
||||
|
||||
/*!
|
||||
* @name Pulse-Out Trigger
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables the pulse out trigger channels.
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param channelMask Channel mask value for multiple pulse out trigger channel.
|
||||
* @param enable Enable the feature or not.
|
||||
*/
|
||||
static inline void PDB_EnablePulseOutTrigger(PDB_Type *base, uint32_t channelMask, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->POEN |= PDB_POEN_POEN(channelMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
base->POEN &= ~(PDB_POEN_POEN(channelMask));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets event values for pulse out trigger.
|
||||
*
|
||||
* This function is used to set event values for pulse output trigger.
|
||||
* 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
|
||||
* pulse output low value (value2).
|
||||
*
|
||||
* @param base PDB peripheral base address.
|
||||
* @param channel Channel index for pulse out trigger channel.
|
||||
* @param value1 Setting value for pulse out high.
|
||||
* @param value2 Setting value for pulse out low.
|
||||
*/
|
||||
static inline void PDB_SetPulseOutTriggerDelayValue(PDB_Type *base, uint32_t channel, uint32_t value1, uint32_t value2)
|
||||
{
|
||||
assert(channel < PDB_PODLY_COUNT);
|
||||
|
||||
base->PODLY[channel] = PDB_PODLY_DLY1(value1) | PDB_PODLY_DLY2(value2);
|
||||
}
|
||||
|
||||
/* @} */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
#endif /* _FSL_PDB_H_ */
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_pit.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Gets the instance from the base address to be used to gate or ungate the module clock
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
*
|
||||
* @return The PIT instance
|
||||
*/
|
||||
static uint32_t PIT_GetInstance(PIT_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/*! @brief Pointers to PIT bases for each instance. */
|
||||
static PIT_Type *const s_pitBases[] = PIT_BASE_PTRS;
|
||||
|
||||
/*! @brief Pointers to PIT clocks for each instance. */
|
||||
static const clock_ip_name_t s_pitClocks[] = PIT_CLOCKS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static uint32_t PIT_GetInstance(PIT_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_PIT_COUNT; instance++)
|
||||
{
|
||||
if (s_pitBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < FSL_FEATURE_SOC_PIT_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void PIT_Init(PIT_Type *base, const pit_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
/* Ungate the PIT clock*/
|
||||
CLOCK_EnableClock(s_pitClocks[PIT_GetInstance(base)]);
|
||||
|
||||
/* Enable PIT timers */
|
||||
base->MCR &= ~PIT_MCR_MDIS_MASK;
|
||||
|
||||
/* Config timer operation when in debug mode */
|
||||
if (config->enableRunInDebug)
|
||||
{
|
||||
base->MCR &= ~PIT_MCR_FRZ_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->MCR |= PIT_MCR_FRZ_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
void PIT_Deinit(PIT_Type *base)
|
||||
{
|
||||
/* Disable PIT timers */
|
||||
base->MCR |= PIT_MCR_MDIS_MASK;
|
||||
|
||||
/* Gate the PIT clock*/
|
||||
CLOCK_DisableClock(s_pitClocks[PIT_GetInstance(base)]);
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && FSL_FEATURE_PIT_HAS_LIFETIME_TIMER
|
||||
|
||||
uint64_t PIT_GetLifetimeTimerCount(PIT_Type *base)
|
||||
{
|
||||
uint32_t valueH = 0U;
|
||||
uint32_t valueL = 0U;
|
||||
|
||||
/* LTMR64H should be read before LTMR64L */
|
||||
valueH = base->LTMR64H;
|
||||
valueL = base->LTMR64L;
|
||||
|
||||
return (((uint64_t)valueH << 32U) + (uint64_t)(valueL));
|
||||
}
|
||||
|
||||
#endif /* FSL_FEATURE_PIT_HAS_LIFETIME_TIMER */
|
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_PIT_H_
|
||||
#define _FSL_PIT_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup pit_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
#define FSL_PIT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief List of PIT channels
|
||||
* @note Actual number of available channels is SoC dependent
|
||||
*/
|
||||
typedef enum _pit_chnl
|
||||
{
|
||||
kPIT_Chnl_0 = 0U, /*!< PIT channel number 0*/
|
||||
kPIT_Chnl_1, /*!< PIT channel number 1 */
|
||||
kPIT_Chnl_2, /*!< PIT channel number 2 */
|
||||
kPIT_Chnl_3, /*!< PIT channel number 3 */
|
||||
} pit_chnl_t;
|
||||
|
||||
/*! @brief List of PIT interrupts */
|
||||
typedef enum _pit_interrupt_enable
|
||||
{
|
||||
kPIT_TimerInterruptEnable = PIT_TCTRL_TIE_MASK, /*!< Timer interrupt enable*/
|
||||
} pit_interrupt_enable_t;
|
||||
|
||||
/*! @brief List of PIT status flags */
|
||||
typedef enum _pit_status_flags
|
||||
{
|
||||
kPIT_TimerFlag = PIT_TFLG_TIF_MASK, /*!< Timer flag */
|
||||
} pit_status_flags_t;
|
||||
|
||||
/*!
|
||||
* @brief PIT config structure
|
||||
*
|
||||
* This structure holds the configuration settings for the PIT peripheral. To initialize this
|
||||
* structure to reasonable defaults, call the PIT_GetDefaultConfig() function and pass a
|
||||
* pointer to your config structure instance.
|
||||
*
|
||||
* The config struct can be made const so it resides in flash
|
||||
*/
|
||||
typedef struct _pit_config
|
||||
{
|
||||
bool enableRunInDebug; /*!< true: Timers run in debug mode; false: Timers stop in debug mode */
|
||||
} pit_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Initialization and deinitialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Ungates the PIT clock, enables the PIT module and configures the peripheral for basic operation.
|
||||
*
|
||||
* @note This API should be called at the beginning of the application using the PIT driver.
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
* @param config Pointer to user's PIT config structure
|
||||
*/
|
||||
void PIT_Init(PIT_Type *base, const pit_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Gate the PIT clock and disable the PIT module
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
*/
|
||||
void PIT_Deinit(PIT_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Fill in the PIT config struct with the default settings
|
||||
*
|
||||
* The default values are:
|
||||
* @code
|
||||
* config->enableRunInDebug = false;
|
||||
* @endcode
|
||||
* @param config Pointer to user's PIT config structure.
|
||||
*/
|
||||
static inline void PIT_GetDefaultConfig(pit_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
/* Timers are stopped in Debug mode */
|
||||
config->enableRunInDebug = false;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_PIT_HAS_CHAIN_MODE) && FSL_FEATURE_PIT_HAS_CHAIN_MODE
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables chaining a timer with the previous timer.
|
||||
*
|
||||
* When a timer has a chain mode enabled, it only counts after the previous
|
||||
* timer has expired. If the timer n-1 has counted down to 0, counter n
|
||||
* decrements the value by one. Each timer is 32-bits, this allows the developers
|
||||
* to chain timers together and form a longer timer (64-bits and larger). The first timer
|
||||
* (timer 0) cannot be chained to any other timer.
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
* @param channel Timer channel number which is chained with the previous timer
|
||||
* @param enable Enable or disable chain.
|
||||
* true: Current timer is chained with the previous timer.
|
||||
* false: Timer doesn't chain with other timers.
|
||||
*/
|
||||
static inline void PIT_SetTimerChainMode(PIT_Type *base, pit_chnl_t channel, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->CHANNEL[channel].TCTRL |= PIT_TCTRL_CHN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CHANNEL[channel].TCTRL &= ~PIT_TCTRL_CHN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FSL_FEATURE_PIT_HAS_CHAIN_MODE */
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Interrupt Interface
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables the selected PIT interrupts.
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
* @param channel Timer channel number
|
||||
* @param mask The interrupts to enable. This is a logical OR of members of the
|
||||
* enumeration ::pit_interrupt_enable_t
|
||||
*/
|
||||
static inline void PIT_EnableInterrupts(PIT_Type *base, pit_chnl_t channel, uint32_t mask)
|
||||
{
|
||||
base->CHANNEL[channel].TCTRL |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the selected PIT interrupts.
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
* @param channel Timer channel number
|
||||
* @param mask The interrupts to disable. This is a logical OR of members of the
|
||||
* enumeration ::pit_interrupt_enable_t
|
||||
*/
|
||||
static inline void PIT_DisableInterrupts(PIT_Type *base, pit_chnl_t channel, uint32_t mask)
|
||||
{
|
||||
base->CHANNEL[channel].TCTRL &= ~mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the enabled PIT interrupts.
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
* @param channel Timer channel number
|
||||
*
|
||||
* @return The enabled interrupts. This is the logical OR of members of the
|
||||
* enumeration ::pit_interrupt_enable_t
|
||||
*/
|
||||
static inline uint32_t PIT_GetEnabledInterrupts(PIT_Type *base, pit_chnl_t channel)
|
||||
{
|
||||
return (base->CHANNEL[channel].TCTRL & PIT_TCTRL_TIE_MASK);
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Status Interface
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Gets the PIT status flags
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
* @param channel Timer channel number
|
||||
*
|
||||
* @return The status flags. This is the logical OR of members of the
|
||||
* enumeration ::pit_status_flags_t
|
||||
*/
|
||||
static inline uint32_t PIT_GetStatusFlags(PIT_Type *base, pit_chnl_t channel)
|
||||
{
|
||||
return (base->CHANNEL[channel].TFLG & PIT_TFLG_TIF_MASK);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the PIT status flags.
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
* @param channel Timer channel number
|
||||
* @param mask The status flags to clear. This is a logical OR of members of the
|
||||
* enumeration ::pit_status_flags_t
|
||||
*/
|
||||
static inline void PIT_ClearStatusFlags(PIT_Type *base, pit_chnl_t channel, uint32_t mask)
|
||||
{
|
||||
base->CHANNEL[channel].TFLG = mask;
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Read and Write the timer period
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Sets the timer period in units of count.
|
||||
*
|
||||
* Timers begin counting from the value set by this function until it reaches 0,
|
||||
* then it will generate an interrupt and load this regiter value again.
|
||||
* Writing a new value to this register will not restart the timer; instead the value
|
||||
* will be loaded after the timer expires.
|
||||
*
|
||||
* @note User can call the utility macros provided in fsl_common.h to convert to ticks
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
* @param channel Timer channel number
|
||||
* @param count Timer period in units of ticks
|
||||
*/
|
||||
static inline void PIT_SetTimerPeriod(PIT_Type *base, pit_chnl_t channel, uint32_t count)
|
||||
{
|
||||
base->CHANNEL[channel].LDVAL = count;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reads the current timer counting value.
|
||||
*
|
||||
* This function returns the real-time timer counting value, in a range from 0 to a
|
||||
* timer period.
|
||||
*
|
||||
* @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
* @param channel Timer channel number
|
||||
*
|
||||
* @return Current timer counting value in ticks
|
||||
*/
|
||||
static inline uint32_t PIT_GetCurrentTimerCount(PIT_Type *base, pit_chnl_t channel)
|
||||
{
|
||||
return base->CHANNEL[channel].CVAL;
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Timer Start and Stop
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Starts the timer counting.
|
||||
*
|
||||
* After calling this function, timers load period value, count down to 0 and
|
||||
* then load the respective start value again. Each time a timer reaches 0,
|
||||
* it generates a trigger pulse and sets the timeout interrupt flag.
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
* @param channel Timer channel number.
|
||||
*/
|
||||
static inline void PIT_StartTimer(PIT_Type *base, pit_chnl_t channel)
|
||||
{
|
||||
base->CHANNEL[channel].TCTRL |= PIT_TCTRL_TEN_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Stops the timer counting.
|
||||
*
|
||||
* This function stops every timer counting. Timers reload their periods
|
||||
* respectively after the next time they call the PIT_DRV_StartTimer.
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
* @param channel Timer channel number.
|
||||
*/
|
||||
static inline void PIT_StopTimer(PIT_Type *base, pit_chnl_t channel)
|
||||
{
|
||||
base->CHANNEL[channel].TCTRL &= ~PIT_TCTRL_TEN_MASK;
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && FSL_FEATURE_PIT_HAS_LIFETIME_TIMER
|
||||
|
||||
/*!
|
||||
* @brief Reads the current lifetime counter value.
|
||||
*
|
||||
* The lifetime timer is a 64-bit timer which chains timer 0 and timer 1 together.
|
||||
* Timer 0 and 1 are chained by calling the PIT_SetTimerChainMode before using this timer.
|
||||
* The period of lifetime timer is equal to the "period of timer 0 * period of timer 1".
|
||||
* For the 64-bit value, the higher 32-bit has the value of timer 1, and the lower 32-bit
|
||||
* has the value of timer 0.
|
||||
*
|
||||
* @param base PIT peripheral base address
|
||||
*
|
||||
* @return Current lifetime timer value
|
||||
*/
|
||||
uint64_t PIT_GetLifetimeTimerCount(PIT_Type *base);
|
||||
|
||||
#endif /* FSL_FEATURE_PIT_HAS_LIFETIME_TIMER */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_PIT_H_ */
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "fsl_pmc.h"
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_PARAM) && FSL_FEATURE_PMC_HAS_PARAM)
|
||||
void PMC_GetParam(PMC_Type *base, pmc_param_t *param)
|
||||
{
|
||||
uint32_t reg = base->PARAM;
|
||||
;
|
||||
param->vlpoEnable = (bool)(reg & PMC_PARAM_VLPOE_MASK);
|
||||
param->hvdEnable = (bool)(reg & PMC_PARAM_HVDE_MASK);
|
||||
}
|
||||
#endif /* FSL_FEATURE_PMC_HAS_PARAM */
|
||||
|
||||
void PMC_ConfigureLowVoltDetect(PMC_Type *base, const pmc_low_volt_detect_config_t *config)
|
||||
{
|
||||
base->LVDSC1 = (0U |
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV)
|
||||
((uint32_t)config->voltSelect << PMC_LVDSC1_LVDV_SHIFT) |
|
||||
#endif
|
||||
((uint32_t)config->enableInt << PMC_LVDSC1_LVDIE_SHIFT) |
|
||||
((uint32_t)config->enableReset << PMC_LVDSC1_LVDRE_SHIFT)
|
||||
/* Clear the Low Voltage Detect Flag with previouse power detect setting */
|
||||
| PMC_LVDSC1_LVDACK_MASK);
|
||||
}
|
||||
|
||||
void PMC_ConfigureLowVoltWarning(PMC_Type *base, const pmc_low_volt_warning_config_t *config)
|
||||
{
|
||||
base->LVDSC2 = (0U |
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV)
|
||||
((uint32_t)config->voltSelect << PMC_LVDSC2_LVWV_SHIFT) |
|
||||
#endif
|
||||
((uint32_t)config->enableInt << PMC_LVDSC2_LVWIE_SHIFT)
|
||||
/* Clear the Low Voltage Warning Flag with previouse power detect setting */
|
||||
| PMC_LVDSC2_LVWACK_MASK);
|
||||
}
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1)
|
||||
void PMC_ConfigureHighVoltDetect(PMC_Type *base, const pmc_high_volt_detect_config_t *config)
|
||||
{
|
||||
base->HVDSC1 = (((uint32_t)config->voltSelect << PMC_HVDSC1_HVDV_SHIFT) |
|
||||
((uint32_t)config->enableInt << PMC_HVDSC1_HVDIE_SHIFT) |
|
||||
((uint32_t)config->enableReset << PMC_HVDSC1_HVDRE_SHIFT)
|
||||
/* Clear the High Voltage Detect Flag with previouse power detect setting */
|
||||
| PMC_HVDSC1_HVDACK_MASK);
|
||||
}
|
||||
#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */
|
||||
|
||||
#if ((defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) || \
|
||||
(defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) || \
|
||||
(defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS))
|
||||
void PMC_ConfigureBandgapBuffer(PMC_Type *base, const pmc_bandgap_buffer_config_t *config)
|
||||
{
|
||||
base->REGSC = (0U
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE)
|
||||
| ((uint32_t)config->enable << PMC_REGSC_BGBE_SHIFT)
|
||||
#endif /* FSL_FEATURE_PMC_HAS_BGBE */
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN)
|
||||
| (((uint32_t)config->enableInLowPowerMode << PMC_REGSC_BGEN_SHIFT))
|
||||
#endif /* FSL_FEATURE_PMC_HAS_BGEN */
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS)
|
||||
| ((uint32_t)config->drive << PMC_REGSC_BGBDS_SHIFT)
|
||||
#endif /* FSL_FEATURE_PMC_HAS_BGBDS */
|
||||
);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,423 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_PMC_H_
|
||||
#define _FSL_PMC_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*! @addtogroup pmc */
|
||||
/*! @{ */
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief PMC driver version */
|
||||
#define FSL_PMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
|
||||
/*@}*/
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV)
|
||||
/*!
|
||||
* @brief Low-Voltage Detect Voltage Select
|
||||
*/
|
||||
typedef enum _pmc_low_volt_detect_volt_select
|
||||
{
|
||||
kPMC_LowVoltDetectLowTrip = 0U, /*!< Low trip point selected (VLVD = VLVDL )*/
|
||||
kPMC_LowVoltDetectHighTrip = 1U /*!< High trip point selected (VLVD = VLVDH )*/
|
||||
} pmc_low_volt_detect_volt_select_t;
|
||||
#endif
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV)
|
||||
/*!
|
||||
* @brief Low-Voltage Warning Voltage Select
|
||||
*/
|
||||
typedef enum _pmc_low_volt_warning_volt_select
|
||||
{
|
||||
kPMC_LowVoltWarningLowTrip = 0U, /*!< Low trip point selected (VLVW = VLVW1)*/
|
||||
kPMC_LowVoltWarningMid1Trip = 1U, /*!< Mid 1 trip point selected (VLVW = VLVW2)*/
|
||||
kPMC_LowVoltWarningMid2Trip = 2U, /*!< Mid 2 trip point selected (VLVW = VLVW3)*/
|
||||
kPMC_LowVoltWarningHighTrip = 3U /*!< High trip point selected (VLVW = VLVW4)*/
|
||||
} pmc_low_volt_warning_volt_select_t;
|
||||
#endif
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1)
|
||||
/*!
|
||||
* @brief High-Voltage Detect Voltage Select
|
||||
*/
|
||||
typedef enum _pmc_high_volt_detect_volt_select
|
||||
{
|
||||
kPMC_HighVoltDetectLowTrip = 0U, /*!< Low trip point selected (VHVD = VHVDL )*/
|
||||
kPMC_HighVoltDetectHighTrip = 1U /*!< High trip point selected (VHVD = VHVDH )*/
|
||||
} pmc_high_volt_detect_volt_select_t;
|
||||
#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS)
|
||||
/*!
|
||||
* @brief Bandgap Buffer Drive Select.
|
||||
*/
|
||||
typedef enum _pmc_bandgap_buffer_drive_select
|
||||
{
|
||||
kPMC_BandgapBufferDriveLow = 0U, /*!< Low drive. */
|
||||
kPMC_BandgapBufferDriveHigh = 1U /*!< High drive. */
|
||||
} pmc_bandgap_buffer_drive_select_t;
|
||||
#endif /* FSL_FEATURE_PMC_HAS_BGBDS */
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_VLPO) && FSL_FEATURE_PMC_HAS_VLPO)
|
||||
/*!
|
||||
* @brief VLPx Option
|
||||
*/
|
||||
typedef enum _pmc_vlp_freq_option
|
||||
{
|
||||
kPMC_FreqRestrict = 0U, /*!< Frequency is restricted in VLPx mode. */
|
||||
kPMC_FreqUnrestrict = 1U /*!< Frequency is unrestricted in VLPx mode. */
|
||||
} pmc_vlp_freq_mode_t;
|
||||
#endif /* FSL_FEATURE_PMC_HAS_VLPO */
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_VERID) && FSL_FEATURE_PMC_HAS_VERID)
|
||||
/*!
|
||||
@brief IP version ID definition.
|
||||
*/
|
||||
typedef struct _pmc_version_id
|
||||
{
|
||||
uint16_t feature; /*!< Feature Specification Number. */
|
||||
uint8_t minor; /*!< Minor version number. */
|
||||
uint8_t major; /*!< Major version number. */
|
||||
} pmc_version_id_t;
|
||||
#endif /* FSL_FEATURE_PMC_HAS_VERID */
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_PARAM) && FSL_FEATURE_PMC_HAS_PARAM)
|
||||
/*! @brief IP parameter definition. */
|
||||
typedef struct _pmc_param
|
||||
{
|
||||
bool vlpoEnable; /*!< VLPO enable. */
|
||||
bool hvdEnable; /*!< HVD enable. */
|
||||
} pmc_param_t;
|
||||
#endif /* FSL_FEATURE_PMC_HAS_PARAM */
|
||||
|
||||
/*!
|
||||
* @brief Low-Voltage Detect Configuration Structure
|
||||
*/
|
||||
typedef struct _pmc_low_volt_detect_config
|
||||
{
|
||||
bool enableInt; /*!< Enable interrupt when low voltage detect*/
|
||||
bool enableReset; /*!< Enable system reset when low voltage detect*/
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV)
|
||||
pmc_low_volt_detect_volt_select_t voltSelect; /*!< Low voltage detect trip point voltage selection*/
|
||||
#endif
|
||||
} pmc_low_volt_detect_config_t;
|
||||
|
||||
/*!
|
||||
* @brief Low-Voltage Warning Configuration Structure
|
||||
*/
|
||||
typedef struct _pmc_low_volt_warning_config
|
||||
{
|
||||
bool enableInt; /*!< Enable interrupt when low voltage warning*/
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV)
|
||||
pmc_low_volt_warning_volt_select_t voltSelect; /*!< Low voltage warning trip point voltage selection*/
|
||||
#endif
|
||||
} pmc_low_volt_warning_config_t;
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1)
|
||||
/*!
|
||||
* @brief High-Voltage Detect Configuration Structure
|
||||
*/
|
||||
typedef struct _pmc_high_volt_detect_config
|
||||
{
|
||||
bool enableInt; /*!< Enable interrupt when high voltage detect*/
|
||||
bool enableReset; /*!< Enable system reset when high voltage detect*/
|
||||
pmc_high_volt_detect_volt_select_t voltSelect; /*!< High voltage detect trip point voltage selection*/
|
||||
} pmc_high_volt_detect_config_t;
|
||||
#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */
|
||||
|
||||
#if ((defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) || \
|
||||
(defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) || \
|
||||
(defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS))
|
||||
/*!
|
||||
* @brief Bandgap Buffer configuration.
|
||||
*/
|
||||
typedef struct _pmc_bandgap_buffer_config
|
||||
{
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE)
|
||||
bool enable; /*!< Enable bandgap buffer. */
|
||||
#endif
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN)
|
||||
bool enableInLowPowerMode; /*!< Enable bandgap buffer in low power mode. */
|
||||
#endif /* FSL_FEATURE_PMC_HAS_BGEN */
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS)
|
||||
pmc_bandgap_buffer_drive_select_t drive; /*!< Bandgap buffer drive select. */
|
||||
#endif /* FSL_FEATURE_PMC_HAS_BGBDS */
|
||||
} pmc_bandgap_buffer_config_t;
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
/*! @name Power Management Controller Control APIs*/
|
||||
/*@{*/
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_VERID) && FSL_FEATURE_PMC_HAS_VERID)
|
||||
/*!
|
||||
* @brief Gets the PMC version ID.
|
||||
*
|
||||
* This function gets the PMC version ID, including major version number,
|
||||
* minor version number and feature specification number.
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
* @param versionId Pointer to version ID structure.
|
||||
*/
|
||||
static inline void PMC_GetVersionId(PMC_Type *base, pmc_version_id_t *versionId)
|
||||
{
|
||||
*((uint32_t *)versionId) = base->VERID;
|
||||
}
|
||||
#endif /* FSL_FEATURE_PMC_HAS_VERID */
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_PARAM) && FSL_FEATURE_PMC_HAS_PARAM)
|
||||
/*!
|
||||
* @brief Gets the PMC parameter.
|
||||
*
|
||||
* This function gets the PMC parameter, including VLPO enable and HVD enable.
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
* @param param Pointer to PMC param structure.
|
||||
*/
|
||||
void PMC_GetParam(PMC_Type *base, pmc_param_t *param);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Configure the low voltage detect setting.
|
||||
*
|
||||
* This function configures the low voltage detect setting, including the trip
|
||||
* point voltage setting, enable interrupt or not, enable system reset or not.
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
* @param config Low-Voltage detect configuration structure.
|
||||
*/
|
||||
void PMC_ConfigureLowVoltDetect(PMC_Type *base, const pmc_low_volt_detect_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Get Low-Voltage Detect Flag status
|
||||
*
|
||||
* This function reads the current LVDF status. If it returns 1, a low
|
||||
* voltage event is detected.
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
* @return Current low voltage detect flag
|
||||
* - true: Low-Voltage detected
|
||||
* - false: Low-Voltage not detected
|
||||
*/
|
||||
static inline bool PMC_GetLowVoltDetectFlag(PMC_Type *base)
|
||||
{
|
||||
return (bool)(base->LVDSC1 & PMC_LVDSC1_LVDF_MASK);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Acknowledge to clear the Low-Voltage Detect flag
|
||||
*
|
||||
* This function acknowledges the low voltage detection errors (write 1 to
|
||||
* clear LVDF).
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
*/
|
||||
static inline void PMC_ClearLowVoltDetectFlag(PMC_Type *base)
|
||||
{
|
||||
base->LVDSC1 |= PMC_LVDSC1_LVDACK_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Configure the low voltage warning setting.
|
||||
*
|
||||
* This function configures the low voltage warning setting, including the trip
|
||||
* point voltage setting and enable interrupt or not.
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
* @param config Low-Voltage warning configuration structure.
|
||||
*/
|
||||
void PMC_ConfigureLowVoltWarning(PMC_Type *base, const pmc_low_volt_warning_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Get Low-Voltage Warning Flag status
|
||||
*
|
||||
* This function polls the current LVWF status. When 1 is returned, it
|
||||
* indicates a low-voltage warning event. LVWF is set when V Supply transitions
|
||||
* below the trip point or after reset and V Supply is already below the V LVW.
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
* @return Current LVWF status
|
||||
* - true: Low-Voltage Warning Flag is set.
|
||||
* - false: the Low-Voltage Warning does not happen.
|
||||
*/
|
||||
static inline bool PMC_GetLowVoltWarningFlag(PMC_Type *base)
|
||||
{
|
||||
return (bool)(base->LVDSC2 & PMC_LVDSC2_LVWF_MASK);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Acknowledge to Low-Voltage Warning flag
|
||||
*
|
||||
* This function acknowledges the low voltage warning errors (write 1 to
|
||||
* clear LVWF).
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
*/
|
||||
static inline void PMC_ClearLowVoltWarningFlag(PMC_Type *base)
|
||||
{
|
||||
base->LVDSC2 |= PMC_LVDSC2_LVWACK_MASK;
|
||||
}
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1)
|
||||
/*!
|
||||
* @brief Configure the high voltage detect setting.
|
||||
*
|
||||
* This function configures the high voltage detect setting, including the trip
|
||||
* point voltage setting, enable interrupt or not, enable system reset or not.
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
* @param config High-Voltage detect configuration structure.
|
||||
*/
|
||||
void PMC_ConfigureHighVoltDetect(PMC_Type *base, const pmc_high_volt_detect_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Get High-Voltage Detect Flag status
|
||||
*
|
||||
* This function reads the current HVDF status. If it returns 1, a low
|
||||
* voltage event is detected.
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
* @return Current high voltage detect flag
|
||||
* - true: High-Voltage detected
|
||||
* - false: High-Voltage not detected
|
||||
*/
|
||||
static inline bool PMC_GetHighVoltDetectFlag(PMC_Type *base)
|
||||
{
|
||||
return (bool)(base->HVDSC1 & PMC_HVDSC1_HVDF_MASK);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Acknowledge to clear the High-Voltage Detect flag
|
||||
*
|
||||
* This function acknowledges the high voltage detection errors (write 1 to
|
||||
* clear HVDF).
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
*/
|
||||
static inline void PMC_ClearHighVoltDetectFlag(PMC_Type *base)
|
||||
{
|
||||
base->HVDSC1 |= PMC_HVDSC1_HVDACK_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */
|
||||
|
||||
#if ((defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) || \
|
||||
(defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) || \
|
||||
(defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS))
|
||||
/*!
|
||||
* @brief Configure the PMC bandgap
|
||||
*
|
||||
* This function configures the PMC bandgap, including the drive select and
|
||||
* behavior in low power mode.
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
* @param config Pointer to the configuration structure
|
||||
*/
|
||||
void PMC_ConfigureBandgapBuffer(PMC_Type *base, const pmc_bandgap_buffer_config_t *config);
|
||||
#endif
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_ACKISO) && FSL_FEATURE_PMC_HAS_ACKISO)
|
||||
/*!
|
||||
* @brief Gets the acknowledge Peripherals and I/O pads isolation flag.
|
||||
*
|
||||
* This function reads the Acknowledge Isolation setting that indicates
|
||||
* whether certain peripherals and the I/O pads are in a latched state as
|
||||
* a result of having been in the VLLS mode.
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
* @param base Base address for current PMC instance.
|
||||
* @return ACK isolation
|
||||
* 0 - Peripherals and I/O pads are in a normal run state.
|
||||
* 1 - Certain peripherals and I/O pads are in an isolated and
|
||||
* latched state.
|
||||
*/
|
||||
static inline bool PMC_GetPeriphIOIsolationFlag(PMC_Type *base)
|
||||
{
|
||||
return (bool)(base->REGSC & PMC_REGSC_ACKISO_MASK);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Acknowledge to Peripherals and I/O pads isolation flag.
|
||||
*
|
||||
* This function clears the ACK Isolation flag. Writing one to this setting
|
||||
* when it is set releases the I/O pads and certain peripherals to their normal
|
||||
* run mode state.
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
*/
|
||||
static inline void PMC_ClearPeriphIOIsolationFlag(PMC_Type *base)
|
||||
{
|
||||
base->REGSC |= PMC_REGSC_ACKISO_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_PMC_HAS_ACKISO */
|
||||
|
||||
#if (defined(FSL_FEATURE_PMC_HAS_REGONS) && FSL_FEATURE_PMC_HAS_REGONS)
|
||||
/*!
|
||||
* @brief Gets the Regulator regulation status.
|
||||
*
|
||||
* This function returns the regulator to a run regulation status. It provides
|
||||
* the current status of the internal voltage regulator.
|
||||
*
|
||||
* @param base PMC peripheral base address.
|
||||
* @param base Base address for current PMC instance.
|
||||
* @return Regulation status
|
||||
* 0 - Regulator is in a stop regulation or in transition to/from the regulation.
|
||||
* 1 - Regulator is in a run regulation.
|
||||
*
|
||||
*/
|
||||
static inline bool PMC_IsRegulatorInRunRegulation(PMC_Type *base)
|
||||
{
|
||||
return (bool)(base->REGSC & PMC_REGSC_REGONS_MASK);
|
||||
}
|
||||
#endif /* FSL_FEATURE_PMC_HAS_REGONS */
|
||||
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_PMC_H_*/
|
|
@ -0,0 +1,382 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SDRVL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_PORT_H_
|
||||
#define _FSL_PORT_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup port_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! Version 2.0.1. */
|
||||
#define FSL_PORT_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief Internal resistor pull feature selection */
|
||||
enum _port_pull
|
||||
{
|
||||
kPORT_PullDisable = 0U, /*!< internal pull-up/down resistor is disabled. */
|
||||
kPORT_PullDown = 2U, /*!< internal pull-down resistor is enabled. */
|
||||
kPORT_PullUp = 3U, /*!< internal pull-up resistor is enabled. */
|
||||
};
|
||||
|
||||
/*! @brief Slew rate selection */
|
||||
enum _port_slew_rate
|
||||
{
|
||||
kPORT_FastSlewRate = 0U, /*!< fast slew rate is configured. */
|
||||
kPORT_SlowSlewRate = 1U, /*!< slow slew rate is configured. */
|
||||
};
|
||||
|
||||
#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
|
||||
/*! @brief Internal resistor pull feature enable/disable */
|
||||
enum _port_open_drain_enable
|
||||
{
|
||||
kPORT_OpenDrainDisable = 0U, /*!< internal pull-down resistor is disabled. */
|
||||
kPORT_OpenDrainEnable = 1U, /*!< internal pull-up resistor is enabled. */
|
||||
};
|
||||
#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */
|
||||
|
||||
/*! @brief Passive filter feature enable/disable */
|
||||
enum _port_passive_filter_enable
|
||||
{
|
||||
kPORT_PassiveFilterDisable = 0U, /*!< fast slew rate is configured. */
|
||||
kPORT_PassiveFilterEnable = 1U, /*!< slow slew rate is configured. */
|
||||
};
|
||||
|
||||
/*! @brief Configures the drive strength. */
|
||||
enum _port_drive_strength
|
||||
{
|
||||
kPORT_LowDriveStrength = 0U, /*!< low drive strength is configured. */
|
||||
kPORT_HighDriveStrength = 1U, /*!< high drive strength is configured. */
|
||||
};
|
||||
|
||||
#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK
|
||||
/*! @brief Unlock/lock the pin control register field[15:0] */
|
||||
enum _port_lock_register
|
||||
{
|
||||
kPORT_UnlockRegister = 0U, /*!< Pin Control Register fields [15:0] are not locked. */
|
||||
kPORT_LockRegister = 1U, /*!< Pin Control Register fields [15:0] are locked. */
|
||||
};
|
||||
#endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */
|
||||
|
||||
/*! @brief Pin mux selection */
|
||||
typedef enum _port_mux
|
||||
{
|
||||
kPORT_PinDisabledOrAnalog = 0U, /*!< corresponding pin is disabled, but is used as an analog pin. */
|
||||
kPORT_MuxAsGpio = 1U, /*!< corresponding pin is configured as GPIO. */
|
||||
kPORT_MuxAlt2 = 2U, /*!< chip-specific */
|
||||
kPORT_MuxAlt3 = 3U, /*!< chip-specific */
|
||||
kPORT_MuxAlt4 = 4U, /*!< chip-specific */
|
||||
kPORT_MuxAlt5 = 5U, /*!< chip-specific */
|
||||
kPORT_MuxAlt6 = 6U, /*!< chip-specific */
|
||||
kPORT_MuxAlt7 = 7U, /*!< chip-specific */
|
||||
} port_mux_t;
|
||||
|
||||
/*! @brief Configures the interrupt generation condition. */
|
||||
typedef enum _port_interrupt
|
||||
{
|
||||
kPORT_InterruptOrDMADisabled = 0x0U, /*!< Interrupt/DMA request is disabled. */
|
||||
#if defined(FSL_FEATURE_PORT_HAS_DMA_REQUEST) && FSL_FEATURE_PORT_HAS_DMA_REQUEST
|
||||
kPORT_DMARisingEdge = 0x1U, /*!< DMA request on rising edge. */
|
||||
kPORT_DMAFallingEdge = 0x2U, /*!< DMA request on falling edge. */
|
||||
kPORT_DMAEitherEdge = 0x3U, /*!< DMA request on either edge. */
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_IRQC_FLAG) && FSL_FEATURE_PORT_HAS_IRQC_FLAG
|
||||
kPORT_FlagRisingEdge = 0x05U, /*!< Flag sets on rising edge. */
|
||||
kPORT_FlagFallingEdge = 0x06U, /*!< Flag sets on falling edge. */
|
||||
kPORT_FlagEitherEdge = 0x07U, /*!< Flag sets on either edge. */
|
||||
#endif
|
||||
kPORT_InterruptLogicZero = 0x8U, /*!< Interrupt when logic zero. */
|
||||
kPORT_InterruptRisingEdge = 0x9U, /*!< Interrupt on rising edge. */
|
||||
kPORT_InterruptFallingEdge = 0xAU, /*!< Interrupt on falling edge. */
|
||||
kPORT_InterruptEitherEdge = 0xBU, /*!< Interrupt on either edge. */
|
||||
kPORT_InterruptLogicOne = 0xCU, /*!< Interrupt when logic one. */
|
||||
#if defined(FSL_FEATURE_PORT_HAS_IRQC_TRIGGER) && FSL_FEATURE_PORT_HAS_IRQC_TRIGGER
|
||||
kPORT_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high trigger output. */
|
||||
kPORT_ActiveLowTriggerOutputEnable = 0xEU, /*!< Enable active low trigger output. */
|
||||
#endif
|
||||
} port_interrupt_t;
|
||||
|
||||
#if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER
|
||||
/*! @brief Digital filter clock source selection */
|
||||
typedef enum _port_digital_filter_clock_source
|
||||
{
|
||||
kPORT_BusClock = 0U, /*!< Digital filters are clocked by the bus clock. */
|
||||
kPORT_LpoClock = 1U, /*!< Digital filters are clocked by the 1 kHz LPO clock. */
|
||||
} port_digital_filter_clock_source_t;
|
||||
|
||||
/*! @brief PORT digital filter feature configuration definition */
|
||||
typedef struct _port_digital_filter_config
|
||||
{
|
||||
uint32_t digitalFilterWidth; /*!< Set digital filter width */
|
||||
port_digital_filter_clock_source_t clockSource; /*!< Set digital filter clockSource */
|
||||
} port_digital_filter_config_t;
|
||||
#endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */
|
||||
|
||||
/*! @brief PORT pin config structure */
|
||||
typedef struct _port_pin_config
|
||||
{
|
||||
uint16_t pullSelect : 2; /*!< no-pull/pull-down/pull-up select */
|
||||
uint16_t slewRate : 1; /*!< fast/slow slew rate Configure */
|
||||
uint16_t : 1;
|
||||
uint16_t passiveFilterEnable : 1; /*!< passive filter enable/disable */
|
||||
#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
|
||||
uint16_t openDrainEnable : 1; /*!< open drain enable/disable */
|
||||
#else
|
||||
uint16_t : 1;
|
||||
#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */
|
||||
uint16_t driveStrength : 1; /*!< fast/slow drive strength configure */
|
||||
uint16_t : 1;
|
||||
uint16_t mux : 3; /*!< pin mux Configure */
|
||||
uint16_t : 4;
|
||||
#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK
|
||||
uint16_t lockRegister : 1; /*!< lock/unlock the pcr field[15:0] */
|
||||
#else
|
||||
uint16_t : 1;
|
||||
#endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */
|
||||
} port_pin_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! @name Configuration */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Sets the port PCR register.
|
||||
*
|
||||
* This is an example to define an input pin or output pin PCR configuration:
|
||||
* @code
|
||||
* // Define a digital input pin PCR configuration
|
||||
* port_pin_config_t config = {
|
||||
* kPORT_PullUp,
|
||||
* kPORT_FastSlewRate,
|
||||
* kPORT_PassiveFilterDisable,
|
||||
* kPORT_OpenDrainDisable,
|
||||
* kPORT_LowDriveStrength,
|
||||
* kPORT_MuxAsGpio,
|
||||
* kPORT_UnLockRegister,
|
||||
* };
|
||||
* @endcode
|
||||
*
|
||||
* @param base PORT peripheral base pointer.
|
||||
* @param pin PORT pin number.
|
||||
* @param config PORT PCR register configure structure.
|
||||
*/
|
||||
static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_pin_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
uint32_t addr = (uint32_t)&base->PCR[pin];
|
||||
*(volatile uint16_t *)(addr) = *((const uint16_t *)config);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the port PCR register for multiple pins.
|
||||
*
|
||||
* This is an example to define input pins or output pins PCR configuration:
|
||||
* @code
|
||||
* // Define a digital input pin PCR configuration
|
||||
* port_pin_config_t config = {
|
||||
* kPORT_PullUp ,
|
||||
* kPORT_PullEnable,
|
||||
* kPORT_FastSlewRate,
|
||||
* kPORT_PassiveFilterDisable,
|
||||
* kPORT_OpenDrainDisable,
|
||||
* kPORT_LowDriveStrength,
|
||||
* kPORT_MuxAsGpio,
|
||||
* kPORT_UnlockRegister,
|
||||
* };
|
||||
* @endcode
|
||||
*
|
||||
* @param base PORT peripheral base pointer.
|
||||
* @param mask PORT pins' numbers macro.
|
||||
* @param config PORT PCR register configure structure.
|
||||
*/
|
||||
static inline void PORT_SetMultiplePinsConfig(PORT_Type *base, uint32_t mask, const port_pin_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
uint16_t pcrl = *((const uint16_t *)config);
|
||||
|
||||
if (mask & 0xffffU)
|
||||
{
|
||||
base->GPCLR = ((mask & 0xffffU) << 16) | pcrl;
|
||||
}
|
||||
if (mask >> 16)
|
||||
{
|
||||
base->GPCHR = (mask & 0xffff0000U) | pcrl;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Configures the pin muxing.
|
||||
*
|
||||
* @param base PORT peripheral base pointer.
|
||||
* @param pin PORT pin number.
|
||||
* @param mux pin muxing slot selection.
|
||||
* - #kPORT_PinDisabledOrAnalog: Pin disabled or work in analog function.
|
||||
* - #kPORT_MuxAsGpio : Set as GPIO.
|
||||
* - #kPORT_MuxAlt2 : chip-specific.
|
||||
* - #kPORT_MuxAlt3 : chip-specific.
|
||||
* - #kPORT_MuxAlt4 : chip-specific.
|
||||
* - #kPORT_MuxAlt5 : chip-specific.
|
||||
* - #kPORT_MuxAlt6 : chip-specific.
|
||||
* - #kPORT_MuxAlt7 : chip-specific.
|
||||
* @Note : This function is NOT recommended to use together with the PORT_SetPinsConfig, because
|
||||
* the PORT_SetPinsConfig need to configure the pin mux anyway (Otherwise the pin mux will
|
||||
* be reset to zero : kPORT_PinDisabledOrAnalog).
|
||||
* This function is recommended to use in the case you just need to reset the pin mux
|
||||
*
|
||||
*/
|
||||
static inline void PORT_SetPinMux(PORT_Type *base, uint32_t pin, port_mux_t mux)
|
||||
{
|
||||
base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(mux);
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER
|
||||
|
||||
/*!
|
||||
* @brief Enables the digital filter in one port, each bit of the 32-bit register represents one pin.
|
||||
*
|
||||
* @param base PORT peripheral base pointer.
|
||||
* @param mask PORT pins' numbers macro.
|
||||
*/
|
||||
static inline void PORT_EnablePinsDigitalFilter(PORT_Type *base, uint32_t mask, bool enable)
|
||||
{
|
||||
if (enable == true)
|
||||
{
|
||||
base->DFER |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->DFER &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the digital filter in one port, each bit of the 32-bit register represents one pin.
|
||||
*
|
||||
* @param base PORT peripheral base pointer.
|
||||
* @param config PORT digital filter configuration structure.
|
||||
*/
|
||||
static inline void PORT_SetDigitalFilterConfig(PORT_Type *base, const port_digital_filter_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
base->DFCR = PORT_DFCR_CS(config->clockSource);
|
||||
base->DFWR = PORT_DFWR_FILT(config->digitalFilterWidth);
|
||||
}
|
||||
|
||||
#endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*! @name Interrupt */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Configures the port pin interrupt/DMA request.
|
||||
*
|
||||
* @param base PORT peripheral base pointer.
|
||||
* @param pin PORT pin number.
|
||||
* @param config PORT pin interrupt configuration.
|
||||
* - #kPORT_InterruptOrDMADisabled: Interrupt/DMA request disabled.
|
||||
* - #kPORT_DMARisingEdge : DMA request on rising edge(if the DMA requests exit).
|
||||
* - #kPORT_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit).
|
||||
* - #kPORT_DMAEitherEdge : DMA request on either edge(if the DMA requests exit).
|
||||
* - #kPORT_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit).
|
||||
* - #kPORT_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit).
|
||||
* - #kPORT_FlagEitherEdge : Flag sets on either edge(if the Flag states exit).
|
||||
* - #kPORT_InterruptLogicZero : Interrupt when logic zero.
|
||||
* - #kPORT_InterruptRisingEdge : Interrupt on rising edge.
|
||||
* - #kPORT_InterruptFallingEdge: Interrupt on falling edge.
|
||||
* - #kPORT_InterruptEitherEdge : Interrupt on either edge.
|
||||
* - #kPORT_InterruptLogicOne : Interrupt when logic one.
|
||||
* - #kPORT_ActiveHighTriggerOutputEnable : Enable active high trigger output(if the trigger states exit).
|
||||
* - #kPORT_ActiveLowTriggerOutputEnable : Enable active low trigger output(if the trigger states exit).
|
||||
*/
|
||||
static inline void PORT_SetPinInterruptConfig(PORT_Type *base, uint32_t pin, port_interrupt_t config)
|
||||
{
|
||||
base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_IRQC_MASK) | PORT_PCR_IRQC(config);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reads the whole port status flag.
|
||||
*
|
||||
* If a pin is configured to generate the DMA request, the corresponding flag
|
||||
* is cleared automatically at the completion of the requested DMA transfer.
|
||||
* Otherwise, the flag remains set until a logic one is written to that flag.
|
||||
* If configured for a level sensitive interrupt that remains asserted, the flag
|
||||
* is set again immediately.
|
||||
*
|
||||
* @param base PORT peripheral base pointer.
|
||||
* @return Current port interrupt status flags, for example, 0x00010001 means the
|
||||
* pin 0 and 17 have the interrupt.
|
||||
*/
|
||||
static inline uint32_t PORT_GetPinsInterruptFlags(PORT_Type *base)
|
||||
{
|
||||
return base->ISFR;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the multiple pins' interrupt status flag.
|
||||
*
|
||||
* @param base PORT peripheral base pointer.
|
||||
* @param mask PORT pins' numbers macro.
|
||||
*/
|
||||
static inline void PORT_ClearPinsInterruptFlags(PORT_Type *base, uint32_t mask)
|
||||
{
|
||||
base->ISFR = mask;
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_PORT_H_ */
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_rcm.h"
|
||||
|
||||
void RCM_ConfigureResetPinFilter(RCM_Type *base, const rcm_reset_pin_filter_config_t *config)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32))
|
||||
uint32_t reg;
|
||||
|
||||
reg = (((uint32_t)config->enableFilterInStop << RCM_RPC_RSTFLTSS_SHIFT) | (uint32_t)config->filterInRunWait);
|
||||
if (config->filterInRunWait == kRCM_FilterBusClock)
|
||||
{
|
||||
reg |= ((uint32_t)config->busClockFilterCount << RCM_RPC_RSTFLTSEL_SHIFT);
|
||||
}
|
||||
base->RPC = reg;
|
||||
#else
|
||||
base->RPFC = ((uint8_t)(config->enableFilterInStop << RCM_RPFC_RSTFLTSS_SHIFT) | (uint8_t)config->filterInRunWait);
|
||||
if (config->filterInRunWait == kRCM_FilterBusClock)
|
||||
{
|
||||
base->RPFW = config->busClockFilterCount;
|
||||
}
|
||||
#endif /* FSL_FEATURE_RCM_REG_WIDTH */
|
||||
}
|
||||
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_BOOTROM) && FSL_FEATURE_RCM_HAS_BOOTROM)
|
||||
void RCM_SetForceBootRomSource(RCM_Type *base, rcm_boot_rom_config_t config)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = base->FM;
|
||||
reg &= ~RCM_FM_FORCEROM_MASK;
|
||||
reg |= ((uint32_t)config << RCM_FM_FORCEROM_SHIFT);
|
||||
base->FM = reg;
|
||||
}
|
||||
#endif /* #if FSL_FEATURE_RCM_HAS_BOOTROM */
|
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_RCM_H_
|
||||
#define _FSL_RCM_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*! @addtogroup rcm */
|
||||
/*! @{*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief RCM driver version 2.0.0. */
|
||||
#define FSL_RCM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief System Reset Source Name definitions
|
||||
*/
|
||||
typedef enum _rcm_reset_source
|
||||
{
|
||||
#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32))
|
||||
/* RCM register bit width is 32. */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP)
|
||||
kRCM_SourceWakeup = RCM_SRS_WAKEUP_MASK, /*!< Low-leakage wakeup reset */
|
||||
#endif
|
||||
kRCM_SourceLvd = RCM_SRS_LVD_MASK, /*!< low voltage detect reset */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC)
|
||||
kRCM_SourceLoc = RCM_SRS_LOC_MASK, /*!< Loss of clock reset */
|
||||
#endif /* FSL_FEATURE_RCM_HAS_LOC */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_LOL) && FSL_FEATURE_RCM_HAS_LOL)
|
||||
kRCM_SourceLol = RCM_SRS_LOL_MASK, /*!< Loss of lock reset */
|
||||
#endif /* FSL_FEATURE_RCM_HAS_LOL */
|
||||
kRCM_SourceWdog = RCM_SRS_WDOG_MASK, /*!< Watchdog reset */
|
||||
kRCM_SourcePin = RCM_SRS_PIN_MASK, /*!< External pin reset */
|
||||
kRCM_SourcePor = RCM_SRS_POR_MASK, /*!< Power on reset */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_JTAG) && FSL_FEATURE_RCM_HAS_JTAG)
|
||||
kRCM_SourceJtag = RCM_SRS_JTAG_MASK, /*!< JTAG generated reset */
|
||||
#endif /* FSL_FEATURE_RCM_HAS_JTAG */
|
||||
kRCM_SourceLockup = RCM_SRS_LOCKUP_MASK, /*!< Core lock up reset */
|
||||
kRCM_SourceSw = RCM_SRS_SW_MASK, /*!< Software reset */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_MDM_AP) && FSL_FEATURE_RCM_HAS_MDM_AP)
|
||||
kRCM_SourceMdmap = RCM_SRS_MDM_AP_MASK, /*!< MDM-AP system reset */
|
||||
#endif /* FSL_FEATURE_RCM_HAS_MDM_AP */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_EZPORT) && FSL_FEATURE_RCM_HAS_EZPORT)
|
||||
kRCM_SourceEzpt = RCM_SRS_EZPT_MASK, /*!< EzPort reset */
|
||||
#endif /* FSL_FEATURE_RCM_HAS_EZPORT */
|
||||
kRCM_SourceSackerr = RCM_SRS_SACKERR_MASK, /*!< Parameter could get all reset flags */
|
||||
|
||||
#else /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */
|
||||
/* RCM register bit width is 8. */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP)
|
||||
kRCM_SourceWakeup = RCM_SRS0_WAKEUP_MASK, /*!< Low-leakage wakeup reset */
|
||||
#endif
|
||||
kRCM_SourceLvd = RCM_SRS0_LVD_MASK, /*!< low voltage detect reset */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC)
|
||||
kRCM_SourceLoc = RCM_SRS0_LOC_MASK, /*!< Loss of clock reset */
|
||||
#endif /* FSL_FEATURE_RCM_HAS_LOC */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_LOL) && FSL_FEATURE_RCM_HAS_LOL)
|
||||
kRCM_SourceLol = RCM_SRS0_LOL_MASK, /*!< Loss of lock reset */
|
||||
#endif /* FSL_FEATURE_RCM_HAS_LOL */
|
||||
kRCM_SourceWdog = RCM_SRS0_WDOG_MASK, /*!< Watchdog reset */
|
||||
kRCM_SourcePin = RCM_SRS0_PIN_MASK, /*!< External pin reset */
|
||||
kRCM_SourcePor = RCM_SRS0_POR_MASK, /*!< Power on reset */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_JTAG) && FSL_FEATURE_RCM_HAS_JTAG)
|
||||
kRCM_SourceJtag = RCM_SRS1_JTAG_MASK << 8U, /*!< JTAG generated reset */
|
||||
#endif /* FSL_FEATURE_RCM_HAS_JTAG */
|
||||
kRCM_SourceLockup = RCM_SRS1_LOCKUP_MASK << 8U, /*!< Core lock up reset */
|
||||
kRCM_SourceSw = RCM_SRS1_SW_MASK, /*!< Software reset */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_MDM_AP) && FSL_FEATURE_RCM_HAS_MDM_AP)
|
||||
kRCM_SourceMdmap = RCM_SRS1_MDM_AP_MASK << 8U, /*!< MDM-AP system reset */
|
||||
#endif /* FSL_FEATURE_RCM_HAS_MDM_AP */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_EZPORT) && FSL_FEATURE_RCM_HAS_EZPORT)
|
||||
kRCM_SourceEzpt = RCM_SRS1_EZPT_MASK << 8U, /*!< EzPort reset */
|
||||
#endif /* FSL_FEATURE_RCM_HAS_EZPORT */
|
||||
kRCM_SourceSackerr = RCM_SRS1_SACKERR_MASK << 8U, /*!< Parameter could get all reset flags */
|
||||
#endif /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */
|
||||
kRCM_SourceAll = 0xffffffffU,
|
||||
} rcm_reset_source_t;
|
||||
|
||||
/*!
|
||||
* @brief Reset pin filter select in Run and Wait modes
|
||||
*/
|
||||
typedef enum _rcm_run_wait_filter_mode
|
||||
{
|
||||
kRCM_FilterDisable = 0U, /*!< All filtering disabled */
|
||||
kRCM_FilterBusClock = 1U, /*!< Bus clock filter enabled */
|
||||
kRCM_FilterLpoClock = 2U /*!< LPO clock filter enabled */
|
||||
} rcm_run_wait_filter_mode_t;
|
||||
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_BOOTROM) && FSL_FEATURE_RCM_HAS_BOOTROM)
|
||||
/*!
|
||||
* @brief Boot from ROM configuration.
|
||||
*/
|
||||
typedef enum _rcm_boot_rom_config
|
||||
{
|
||||
kRCM_BootFlash = 0U, /*!< Boot from flash */
|
||||
kRCM_BootRomCfg0 = 1U, /*!< Boot from boot ROM due to BOOTCFG0 */
|
||||
kRCM_BootRomFopt = 2U, /*!< Boot from boot ROM due to FOPT[7] */
|
||||
kRCM_BootRomBoth = 3U /*!< Boot from boot ROM due to both BOOTCFG0 and FOPT[7] */
|
||||
} rcm_boot_rom_config_t;
|
||||
#endif /* FSL_FEATURE_RCM_HAS_BOOTROM */
|
||||
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_SRIE) && FSL_FEATURE_RCM_HAS_SRIE)
|
||||
/*!
|
||||
* @brief Max delay time from interrupt asserts to system reset.
|
||||
*/
|
||||
typedef enum _rcm_reset_delay
|
||||
{
|
||||
kRCM_ResetDelay8Lpo = 0U, /*!< Delay 8 LPO cycles. */
|
||||
kRCM_ResetDelay32Lpo = 1U, /*!< Delay 32 LPO cycles. */
|
||||
kRCM_ResetDelay128Lpo = 2U, /*!< Delay 128 LPO cycles. */
|
||||
kRCM_ResetDelay512Lpo = 3U /*!< Delay 512 LPO cycles. */
|
||||
} rcm_reset_delay_t;
|
||||
|
||||
/*!
|
||||
* @brief System reset interrupt enable bit definitions.
|
||||
*/
|
||||
typedef enum _rcm_interrupt_enable
|
||||
{
|
||||
kRCM_IntNone = 0U, /*!< No interrupt enabled. */
|
||||
kRCM_IntLossOfClk = RCM_SRIE_LOC_MASK, /*!< Loss of clock interrupt. */
|
||||
kRCM_IntLossOfLock = RCM_SRIE_LOL_MASK, /*!< Loss of lock interrupt. */
|
||||
kRCM_IntWatchDog = RCM_SRIE_WDOG_MASK, /*!< Watch dog interrupt. */
|
||||
kRCM_IntExternalPin = RCM_SRIE_PIN_MASK, /*!< External pin interrupt. */
|
||||
kRCM_IntGlobal = RCM_SRIE_GIE_MASK, /*!< Global interrupts. */
|
||||
kRCM_IntCoreLockup = RCM_SRIE_LOCKUP_MASK, /*!< Core lock up interrupt */
|
||||
kRCM_IntSoftware = RCM_SRIE_SW_MASK, /*!< software interrupt */
|
||||
kRCM_IntStopModeAckErr = RCM_SRIE_SACKERR_MASK, /*!< Stop mode ACK error interrupt. */
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_CORE1) && FSL_FEATURE_RCM_HAS_CORE1)
|
||||
kRCM_IntCore1 = RCM_SRIE_CORE1_MASK, /*!< Core 1 interrupt. */
|
||||
#endif
|
||||
kRCM_IntAll = RCM_SRIE_LOC_MASK /*!< Enable all interrupts. */
|
||||
|
|
||||
RCM_SRIE_LOL_MASK | RCM_SRIE_WDOG_MASK | RCM_SRIE_PIN_MASK | RCM_SRIE_GIE_MASK |
|
||||
RCM_SRIE_LOCKUP_MASK | RCM_SRIE_SW_MASK | RCM_SRIE_SACKERR_MASK
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_CORE1) && FSL_FEATURE_RCM_HAS_CORE1)
|
||||
|
|
||||
RCM_SRIE_CORE1_MASK
|
||||
#endif
|
||||
} rcm_interrupt_enable_t;
|
||||
#endif /* FSL_FEATURE_RCM_HAS_SRIE */
|
||||
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_VERID) && FSL_FEATURE_RCM_HAS_VERID)
|
||||
/*!
|
||||
* @brief IP version ID definition.
|
||||
*/
|
||||
typedef struct _rcm_version_id
|
||||
{
|
||||
uint16_t feature; /*!< Feature Specification Number. */
|
||||
uint8_t minor; /*!< Minor version number. */
|
||||
uint8_t major; /*!< Major version number. */
|
||||
} rcm_version_id_t;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Reset pin filter configuration
|
||||
*/
|
||||
typedef struct _rcm_reset_pin_filter_config
|
||||
{
|
||||
bool enableFilterInStop; /*!< Reset pin filter select in stop mode. */
|
||||
rcm_run_wait_filter_mode_t filterInRunWait; /*!< Reset pin filter in run/wait mode. */
|
||||
uint8_t busClockFilterCount; /*!< Reset pin bus clock filter width. */
|
||||
} rcm_reset_pin_filter_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
/*! @name Reset Control Module APIs*/
|
||||
/*@{*/
|
||||
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_VERID) && FSL_FEATURE_RCM_HAS_VERID)
|
||||
/*!
|
||||
* @brief Gets the RCM version ID.
|
||||
*
|
||||
* This function gets the RCM version ID including the major version number,
|
||||
* the minor version number, and the feature specification number.
|
||||
*
|
||||
* @param base RCM peripheral base address.
|
||||
* @param versionId Pointer to version ID structure.
|
||||
*/
|
||||
static inline void RCM_GetVersionId(RCM_Type *base, rcm_version_id_t *versionId)
|
||||
{
|
||||
*((uint32_t *)versionId) = base->VERID;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_PARAM) && FSL_FEATURE_RCM_HAS_PARAM)
|
||||
/*!
|
||||
* @brief Gets the reset source implemented status.
|
||||
*
|
||||
* This function gets the RCM parameter that indicates whether the corresponding reset source is implemented.
|
||||
* Use source masks defined in the rcm_reset_source_t to get the desired source status.
|
||||
*
|
||||
* Example:
|
||||
@code
|
||||
uint32_t status;
|
||||
|
||||
// To test whether the MCU is reset using Watchdog.
|
||||
status = RCM_GetResetSourceImplementedStatus(RCM) & (kRCM_SourceWdog | kRCM_SourcePin);
|
||||
@endcode
|
||||
*
|
||||
* @param base RCM peripheral base address.
|
||||
* @return All reset source implemented status bit map.
|
||||
*/
|
||||
static inline uint32_t RCM_GetResetSourceImplementedStatus(RCM_Type *base)
|
||||
{
|
||||
return base->PARAM;
|
||||
}
|
||||
#endif /* FSL_FEATURE_RCM_HAS_PARAM */
|
||||
|
||||
/*!
|
||||
* @brief Gets the reset source status which caused a previous reset.
|
||||
*
|
||||
* This function gets the current reset source status. Use source masks
|
||||
* defined in the rcm_reset_source_t to get the desired source status.
|
||||
*
|
||||
* Example:
|
||||
@code
|
||||
uint32_t resetStatus;
|
||||
|
||||
// To get all reset source statuses.
|
||||
resetStatus = RCM_GetPreviousResetSources(RCM) & kRCM_SourceAll;
|
||||
|
||||
// To test whether the MCU is reset using Watchdog.
|
||||
resetStatus = RCM_GetPreviousResetSources(RCM) & kRCM_SourceWdog;
|
||||
|
||||
// To test multiple reset sources.
|
||||
resetStatus = RCM_GetPreviousResetSources(RCM) & (kRCM_SourceWdog | kRCM_SourcePin);
|
||||
@endcode
|
||||
*
|
||||
* @param base RCM peripheral base address.
|
||||
* @return All reset source status bit map.
|
||||
*/
|
||||
static inline uint32_t RCM_GetPreviousResetSources(RCM_Type *base)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32))
|
||||
return base->SRS;
|
||||
#else
|
||||
return (uint32_t)((uint32_t)base->SRS0 | ((uint32_t)base->SRS1 << 8U));
|
||||
#endif /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */
|
||||
}
|
||||
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_SSRS) && FSL_FEATURE_RCM_HAS_SSRS)
|
||||
/*!
|
||||
* @brief Gets the sticky reset source status.
|
||||
*
|
||||
* This function gets the current reset source status that has not been cleared
|
||||
* by software for some specific source.
|
||||
*
|
||||
* Example:
|
||||
@code
|
||||
uint32_t resetStatus;
|
||||
|
||||
// To get all reset source statuses.
|
||||
resetStatus = RCM_GetStickyResetSources(RCM) & kRCM_SourceAll;
|
||||
|
||||
// To test whether the MCU is reset using Watchdog.
|
||||
resetStatus = RCM_GetStickyResetSources(RCM) & kRCM_SourceWdog;
|
||||
|
||||
// To test multiple reset sources.
|
||||
resetStatus = RCM_GetStickyResetSources(RCM) & (kRCM_SourceWdog | kRCM_SourcePin);
|
||||
@endcode
|
||||
*
|
||||
* @param base RCM peripheral base address.
|
||||
* @return All reset source status bit map.
|
||||
*/
|
||||
static inline uint32_t RCM_GetStickyResetSources(RCM_Type *base)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32))
|
||||
return base->SSRS;
|
||||
#else
|
||||
return (base->SSRS0 | ((uint32_t)base->SSRS1 << 8U));
|
||||
#endif /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the sticky reset source status.
|
||||
*
|
||||
* This function clears the sticky system reset flags indicated by source masks.
|
||||
*
|
||||
* Example:
|
||||
@code
|
||||
// Clears multiple reset sources.
|
||||
RCM_ClearStickyResetSources(kRCM_SourceWdog | kRCM_SourcePin);
|
||||
@endcode
|
||||
*
|
||||
* @param base RCM peripheral base address.
|
||||
* @param sourceMasks reset source status bit map
|
||||
*/
|
||||
static inline void RCM_ClearStickyResetSources(RCM_Type *base, uint32_t sourceMasks)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32))
|
||||
base->SSRS = sourceMasks;
|
||||
#else
|
||||
base->SSRS0 = (sourceMasks & 0xffU);
|
||||
base->SSRS1 = ((sourceMasks >> 8U) & 0xffU);
|
||||
#endif /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */
|
||||
}
|
||||
#endif /* FSL_FEATURE_RCM_HAS_SSRS */
|
||||
|
||||
/*!
|
||||
* @brief Configures the reset pin filter.
|
||||
*
|
||||
* This function sets the reset pin filter including the filter source, filter
|
||||
* width, and so on.
|
||||
*
|
||||
* @param base RCM peripheral base address.
|
||||
* @param config Pointer to the configuration structure.
|
||||
*/
|
||||
void RCM_ConfigureResetPinFilter(RCM_Type *base, const rcm_reset_pin_filter_config_t *config);
|
||||
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_EZPMS) && FSL_FEATURE_RCM_HAS_EZPMS)
|
||||
/*!
|
||||
* @brief Gets the EZP_MS_B pin assert status.
|
||||
*
|
||||
* This function gets the easy port mode status (EZP_MS_B) pin assert status.
|
||||
*
|
||||
* @param base RCM peripheral base address.
|
||||
* @return status true - asserted, false - reasserted
|
||||
*/
|
||||
static inline bool RCM_GetEasyPortModePinStatus(RCM_Type *base)
|
||||
{
|
||||
return (bool)(base->MR & RCM_MR_EZP_MS_MASK);
|
||||
}
|
||||
#endif /* FSL_FEATURE_RCM_HAS_EZPMS */
|
||||
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_BOOTROM) && FSL_FEATURE_RCM_HAS_BOOTROM)
|
||||
/*!
|
||||
* @brief Gets the ROM boot source.
|
||||
*
|
||||
* This function gets the ROM boot source during the last chip reset.
|
||||
*
|
||||
* @param base RCM peripheral base address.
|
||||
* @return The ROM boot source.
|
||||
*/
|
||||
static inline rcm_boot_rom_config_t RCM_GetBootRomSource(RCM_Type *base)
|
||||
{
|
||||
return (rcm_boot_rom_config_t)((base->MR & RCM_MR_BOOTROM_MASK) >> RCM_MR_BOOTROM_SHIFT);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the ROM boot source flag.
|
||||
*
|
||||
* This function clears the ROM boot source flag.
|
||||
*
|
||||
* @param base Register base address of RCM
|
||||
*/
|
||||
static inline void RCM_ClearBootRomSource(RCM_Type *base)
|
||||
{
|
||||
base->MR |= RCM_MR_BOOTROM_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Forces the boot from ROM.
|
||||
*
|
||||
* This function forces booting from ROM during all subsequent system resets.
|
||||
*
|
||||
* @param base RCM peripheral base address.
|
||||
* @param config Boot configuration.
|
||||
*/
|
||||
void RCM_SetForceBootRomSource(RCM_Type *base, rcm_boot_rom_config_t config);
|
||||
#endif /* FSL_FEATURE_RCM_HAS_BOOTROM */
|
||||
|
||||
#if (defined(FSL_FEATURE_RCM_HAS_SRIE) && FSL_FEATURE_RCM_HAS_SRIE)
|
||||
/*!
|
||||
* @brief Sets the system reset interrupt configuration.
|
||||
*
|
||||
* For graceful shutdown, the RCM supports delaying the assertion of the system
|
||||
* reset for a period of time when the reset interrupt is generated. This function
|
||||
* can be used to enable the interrupt and the delay period. The interrupts
|
||||
* are passed in as bit mask. See rcm_int_t for details. For example, to
|
||||
* delay a reset for 512 LPO cycles after the WDOG timeout or loss-of-clock occurs,
|
||||
* configure as follows:
|
||||
* RCM_SetSystemResetInterruptConfig(kRCM_IntWatchDog | kRCM_IntLossOfClk, kRCM_ResetDelay512Lpo);
|
||||
*
|
||||
* @param base RCM peripheral base address.
|
||||
* @param intMask Bit mask of the system reset interrupts to enable. See
|
||||
* rcm_interrupt_enable_t for details.
|
||||
* @param Delay Bit mask of the system reset interrupts to enable.
|
||||
*/
|
||||
static inline void RCM_SetSystemResetInterruptConfig(RCM_Type *base, uint32_t intMask, rcm_reset_delay_t delay)
|
||||
{
|
||||
base->SRIE = (intMask | delay);
|
||||
}
|
||||
#endif /* FSL_FEATURE_RCM_HAS_SRIE */
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_RCM_H_ */
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_rnga.h"
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_RNG_COUNT) && FSL_FEATURE_SOC_RNG_COUNT
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* RNG_CR - RNGA Control Register
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief RNG_CR - RNGA Control Register (RW)
|
||||
*
|
||||
* Reset value: 0x00000000U
|
||||
*
|
||||
* Controls the operation of RNGA.
|
||||
*/
|
||||
/*!
|
||||
* @name Constants and macros for entire RNG_CR register
|
||||
*/
|
||||
/*@{*/
|
||||
#define RNG_CR_REG(base) ((base)->CR)
|
||||
#define RNG_RD_CR(base) (RNG_CR_REG(base))
|
||||
#define RNG_WR_CR(base, value) (RNG_CR_REG(base) = (value))
|
||||
#define RNG_RMW_CR(base, mask, value) (RNG_WR_CR(base, (RNG_RD_CR(base) & ~(mask)) | (value)))
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @name Register RNG_CR, field GO[0] (RW)
|
||||
*
|
||||
* Specifies whether random-data generation and loading (into OR[RANDOUT]) is
|
||||
* enabled.This field is sticky. You must reset RNGA to stop RNGA from loading
|
||||
* OR[RANDOUT] with data.
|
||||
*
|
||||
* Values:
|
||||
* - 0b0 - Disabled
|
||||
* - 0b1 - Enabled
|
||||
*/
|
||||
/*@{*/
|
||||
/*! @brief Read current value of the RNG_CR_GO field. */
|
||||
#define RNG_RD_CR_GO(base) ((RNG_CR_REG(base) & RNG_CR_GO_MASK) >> RNG_CR_GO_SHIFT)
|
||||
|
||||
/*! @brief Set the GO field to a new value. */
|
||||
#define RNG_WR_CR_GO(base, value) (RNG_RMW_CR(base, RNG_CR_GO_MASK, RNG_CR_GO(value)))
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @name Register RNG_CR, field SLP[4] (RW)
|
||||
*
|
||||
* Specifies whether RNGA is in Sleep or Normal mode. You can also enter Sleep
|
||||
* mode by asserting the DOZE signal.
|
||||
*
|
||||
* Values:
|
||||
* - 0b0 - Normal mode
|
||||
* - 0b1 - Sleep (low-power) mode
|
||||
*/
|
||||
/*@{*/
|
||||
/*! @brief Read current value of the RNG_CR_SLP field. */
|
||||
#define RNG_RD_CR_SLP(base) ((RNG_CR_REG(base) & RNG_CR_SLP_MASK) >> RNG_CR_SLP_SHIFT)
|
||||
|
||||
/*! @brief Set the SLP field to a new value. */
|
||||
#define RNG_WR_CR_SLP(base, value) (RNG_RMW_CR(base, RNG_CR_SLP_MASK, RNG_CR_SLP(value)))
|
||||
/*@}*/
|
||||
|
||||
/*******************************************************************************
|
||||
* RNG_SR - RNGA Status Register
|
||||
******************************************************************************/
|
||||
#define RNG_SR_REG(base) ((base)->SR)
|
||||
|
||||
/*!
|
||||
* @name Register RNG_SR, field OREG_LVL[15:8] (RO)
|
||||
*
|
||||
* Indicates the number of random-data words that are in OR[RANDOUT], which
|
||||
* indicates whether OR[RANDOUT] is valid.If you read OR[RANDOUT] when SR[OREG_LVL]
|
||||
* is not 0, then the contents of a random number contained in OR[RANDOUT] are
|
||||
* returned, and RNGA writes 0 to both OR[RANDOUT] and SR[OREG_LVL].
|
||||
*
|
||||
* Values:
|
||||
* - 0b00000000 - No words (empty)
|
||||
* - 0b00000001 - One word (valid)
|
||||
*/
|
||||
/*@{*/
|
||||
/*! @brief Read current value of the RNG_SR_OREG_LVL field. */
|
||||
#define RNG_RD_SR_OREG_LVL(base) ((RNG_SR_REG(base) & RNG_SR_OREG_LVL_MASK) >> RNG_SR_OREG_LVL_SHIFT)
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @name Register RNG_SR, field SLP[4] (RO)
|
||||
*
|
||||
* Specifies whether RNGA is in Sleep or Normal mode. You can also enter Sleep
|
||||
* mode by asserting the DOZE signal.
|
||||
*
|
||||
* Values:
|
||||
* - 0b0 - Normal mode
|
||||
* - 0b1 - Sleep (low-power) mode
|
||||
*/
|
||||
/*@{*/
|
||||
/*! @brief Read current value of the RNG_SR_SLP field. */
|
||||
#define RNG_RD_SR_SLP(base) ((RNG_SR_REG(base) & RNG_SR_SLP_MASK) >> RNG_SR_SLP_SHIFT)
|
||||
/*@}*/
|
||||
|
||||
/*******************************************************************************
|
||||
* RNG_OR - RNGA Output Register
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief RNG_OR - RNGA Output Register (RO)
|
||||
*
|
||||
* Reset value: 0x00000000U
|
||||
*
|
||||
* Stores a random-data word generated by RNGA.
|
||||
*/
|
||||
/*!
|
||||
* @name Constants and macros for entire RNG_OR register
|
||||
*/
|
||||
/*@{*/
|
||||
#define RNG_OR_REG(base) ((base)->OR)
|
||||
#define RNG_RD_OR(base) (RNG_OR_REG(base))
|
||||
/*@}*/
|
||||
|
||||
/*******************************************************************************
|
||||
* RNG_ER - RNGA Entropy Register
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief RNG_ER - RNGA Entropy Register (WORZ)
|
||||
*
|
||||
* Reset value: 0x00000000U
|
||||
*
|
||||
* Specifies an entropy value that RNGA uses in addition to its ring oscillators
|
||||
* to seed its pseudorandom algorithm. This is a write-only register; reads
|
||||
* return all zeros.
|
||||
*/
|
||||
/*!
|
||||
* @name Constants and macros for entire RNG_ER register
|
||||
*/
|
||||
/*@{*/
|
||||
#define RNG_ER_REG(base) ((base)->ER)
|
||||
#define RNG_RD_ER(base) (RNG_ER_REG(base))
|
||||
#define RNG_WR_ER(base, value) (RNG_ER_REG(base) = (value))
|
||||
/*@}*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
*******************************************************************************/
|
||||
|
||||
static uint32_t rnga_ReadEntropy(RNG_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
void RNGA_Init(RNG_Type *base)
|
||||
{
|
||||
/* Enable the clock gate. */
|
||||
CLOCK_EnableClock(kCLOCK_Rnga0);
|
||||
CLOCK_DisableClock(kCLOCK_Rnga0); /* To solve the release version on twrkm43z75m */
|
||||
CLOCK_EnableClock(kCLOCK_Rnga0);
|
||||
|
||||
/* Reset the registers for RNGA module to reset state. */
|
||||
RNG_WR_CR(base, 0);
|
||||
/* Enables the RNGA random data generation and loading.*/
|
||||
RNG_WR_CR_GO(base, 1);
|
||||
}
|
||||
|
||||
void RNGA_Deinit(RNG_Type *base)
|
||||
{
|
||||
/* Disable the clock for RNGA module.*/
|
||||
CLOCK_DisableClock(kCLOCK_Rnga0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get a random data from RNGA.
|
||||
*
|
||||
* @param base RNGA base address
|
||||
*/
|
||||
static uint32_t rnga_ReadEntropy(RNG_Type *base)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
if (RNGA_GetMode(base) == kRNGA_ModeNormal) /* Is in normal mode.*/
|
||||
{
|
||||
/* Wait for valid random-data.*/
|
||||
while (RNG_RD_SR_OREG_LVL(base) == 0)
|
||||
{
|
||||
}
|
||||
data = RNG_RD_OR(base);
|
||||
}
|
||||
/* Get random-data word generated by RNGA.*/
|
||||
return data;
|
||||
}
|
||||
|
||||
status_t RNGA_GetRandomData(RNG_Type *base, void *data, size_t data_size)
|
||||
{
|
||||
status_t result = kStatus_Success;
|
||||
uint32_t random_32;
|
||||
uint8_t *random_p;
|
||||
uint32_t random_size;
|
||||
uint8_t *data_p = (uint8_t *)data;
|
||||
uint32_t i;
|
||||
|
||||
/* Check input parameters.*/
|
||||
if (base && data && data_size)
|
||||
{
|
||||
do
|
||||
{
|
||||
/* Read Entropy.*/
|
||||
random_32 = rnga_ReadEntropy(base);
|
||||
|
||||
random_p = (uint8_t *)&random_32;
|
||||
|
||||
if (data_size < sizeof(random_32))
|
||||
{
|
||||
random_size = data_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
random_size = sizeof(random_32);
|
||||
}
|
||||
|
||||
for (i = 0; i < random_size; i++)
|
||||
{
|
||||
*data_p++ = *random_p++;
|
||||
}
|
||||
|
||||
data_size -= random_size;
|
||||
} while (data_size > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void RNGA_SetMode(RNG_Type *base, rnga_mode_t mode)
|
||||
{
|
||||
RNG_WR_CR_SLP(base, (uint32_t)mode);
|
||||
}
|
||||
|
||||
rnga_mode_t RNGA_GetMode(RNG_Type *base)
|
||||
{
|
||||
return (rnga_mode_t)RNG_RD_SR_SLP(base);
|
||||
}
|
||||
|
||||
void RNGA_Seed(RNG_Type *base, uint32_t seed)
|
||||
{
|
||||
/* Write to RNGA Entropy Register.*/
|
||||
RNG_WR_ER(base, seed);
|
||||
}
|
||||
|
||||
#endif /* FSL_FEATURE_SOC_RNG_COUNT */
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_RNGA_DRIVER_H_
|
||||
#define _FSL_RNGA_DRIVER_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_RNG_COUNT) && FSL_FEATURE_SOC_RNG_COUNT
|
||||
/*!
|
||||
* @addtogroup rnga_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
*******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief RNGA driver version 2.0.1. */
|
||||
#define FSL_RNGA_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief RNGA working mode */
|
||||
typedef enum _rnga_mode
|
||||
{
|
||||
kRNGA_ModeNormal = 0U, /*!< Normal Mode. The ring-oscillator clocks are active; RNGA generates entropy
|
||||
(randomness) from the clocks and stores it in shift registers.*/
|
||||
kRNGA_ModeSleep = 1U, /*!< Sleep Mode. The ring-oscillator clocks are inactive; RNGA does not generate entropy.*/
|
||||
} rnga_mode_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
*******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Initializes the RNGA.
|
||||
*
|
||||
* This function initializes the RNGA.
|
||||
* When called, the RNGA entropy generation starts immediately.
|
||||
*
|
||||
* @param base RNGA base address
|
||||
*/
|
||||
void RNGA_Init(RNG_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Shuts down the RNGA.
|
||||
*
|
||||
* This function shuts down the RNGA.
|
||||
*
|
||||
* @param base RNGA base address
|
||||
*/
|
||||
void RNGA_Deinit(RNG_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Gets random data.
|
||||
*
|
||||
* This function gets random data from the RNGA.
|
||||
*
|
||||
* @param base RNGA base address
|
||||
* @param data pointer to user buffer to be filled by random data
|
||||
* @param data_size size of data in bytes
|
||||
* @return RNGA status
|
||||
*/
|
||||
status_t RNGA_GetRandomData(RNG_Type *base, void *data, size_t data_size);
|
||||
|
||||
/*!
|
||||
* @brief Feeds the RNGA module.
|
||||
*
|
||||
* This function inputs an entropy value that the RNGA uses to seed its
|
||||
* pseudo-random algorithm.
|
||||
*
|
||||
* @param base RNGA base address
|
||||
* @param seed input seed value
|
||||
*/
|
||||
void RNGA_Seed(RNG_Type *base, uint32_t seed);
|
||||
|
||||
/*!
|
||||
* @brief Sets the RNGA in normal mode or sleep mode.
|
||||
*
|
||||
* This function sets the RNGA in sleep mode or normal mode.
|
||||
*
|
||||
* @param base RNGA base address
|
||||
* @param mode normal mode or sleep mode
|
||||
*/
|
||||
void RNGA_SetMode(RNG_Type *base, rnga_mode_t mode);
|
||||
|
||||
/*!
|
||||
* @brief Gets the RNGA working mode.
|
||||
*
|
||||
* This function gets the RNGA working mode.
|
||||
*
|
||||
* @param base RNGA base address
|
||||
* @return normal mode or sleep mode
|
||||
*/
|
||||
rnga_mode_t RNGA_GetMode(RNG_Type *base);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* FSL_FEATURE_SOC_RNG_COUNT */
|
||||
#endif /* _FSL_RNGA_H_*/
|
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_rtc.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
#define SECONDS_IN_A_DAY (86400U)
|
||||
#define SECONDS_IN_A_HOUR (3600U)
|
||||
#define SECONDS_IN_A_MINUTE (60U)
|
||||
#define DAYS_IN_A_YEAR (365U)
|
||||
#define YEAR_RANGE_START (1970U)
|
||||
#define YEAR_RANGE_END (2099U)
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Checks whether the date and time passed in is valid
|
||||
*
|
||||
* @param datetime Pointer to structure where the date and time details are stored
|
||||
*
|
||||
* @return Returns false if the date & time details are out of range; true if in range
|
||||
*/
|
||||
static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime);
|
||||
|
||||
/*!
|
||||
* @brief Converts time data from datetime to seconds
|
||||
*
|
||||
* @param datetime Pointer to datetime structure where the date and time details are stored
|
||||
*
|
||||
* @return The result of the conversion in seconds
|
||||
*/
|
||||
static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime);
|
||||
|
||||
/*!
|
||||
* @brief Converts time data from seconds to a datetime structure
|
||||
*
|
||||
* @param seconds Seconds value that needs to be converted to datetime format
|
||||
* @param datetime Pointer to the datetime structure where the result of the conversion is stored
|
||||
*/
|
||||
static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime)
|
||||
{
|
||||
/* Table of days in a month for a non leap year. First entry in the table is not used,
|
||||
* valid months start from 1
|
||||
*/
|
||||
uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U};
|
||||
|
||||
/* Check year, month, hour, minute, seconds */
|
||||
if ((datetime->year < YEAR_RANGE_START) || (datetime->year > YEAR_RANGE_END) || (datetime->month > 12U) ||
|
||||
(datetime->month < 1U) || (datetime->hour >= 24U) || (datetime->minute >= 60U) || (datetime->second >= 60U))
|
||||
{
|
||||
/* If not correct then error*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Adjust the days in February for a leap year */
|
||||
if (!(datetime->year & 3U))
|
||||
{
|
||||
daysPerMonth[2] = 29U;
|
||||
}
|
||||
|
||||
/* Check the validity of the day */
|
||||
if (datetime->day > daysPerMonth[datetime->month])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime)
|
||||
{
|
||||
/* Number of days from begin of the non Leap-year*/
|
||||
uint16_t monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U};
|
||||
uint32_t seconds;
|
||||
|
||||
/* Compute number of days from 1970 till given year*/
|
||||
seconds = (datetime->year - 1970U) * DAYS_IN_A_YEAR;
|
||||
/* Add leap year days */
|
||||
seconds += ((datetime->year / 4) - (1970U / 4));
|
||||
/* Add number of days till given month*/
|
||||
seconds += monthDays[datetime->month];
|
||||
/* Add days in given month. We subtract the current day as it is
|
||||
* represented in the hours, minutes and seconds field*/
|
||||
seconds += (datetime->day - 1);
|
||||
/* For leap year if month less than or equal to Febraury, decrement day counter*/
|
||||
if ((!(datetime->year & 3U)) && (datetime->month <= 2U))
|
||||
{
|
||||
seconds--;
|
||||
}
|
||||
|
||||
seconds = (seconds * SECONDS_IN_A_DAY) + (datetime->hour * SECONDS_IN_A_HOUR) +
|
||||
(datetime->minute * SECONDS_IN_A_MINUTE) + datetime->second;
|
||||
|
||||
return seconds;
|
||||
}
|
||||
|
||||
static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime)
|
||||
{
|
||||
uint32_t x;
|
||||
uint32_t secondsRemaining, days;
|
||||
uint16_t daysInYear;
|
||||
/* Table of days in a month for a non leap year. First entry in the table is not used,
|
||||
* valid months start from 1
|
||||
*/
|
||||
uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U};
|
||||
|
||||
/* Start with the seconds value that is passed in to be converted to date time format */
|
||||
secondsRemaining = seconds;
|
||||
|
||||
/* Calcuate the number of days, we add 1 for the current day which is represented in the
|
||||
* hours and seconds field
|
||||
*/
|
||||
days = secondsRemaining / SECONDS_IN_A_DAY + 1;
|
||||
|
||||
/* Update seconds left*/
|
||||
secondsRemaining = secondsRemaining % SECONDS_IN_A_DAY;
|
||||
|
||||
/* Calculate the datetime hour, minute and second fields */
|
||||
datetime->hour = secondsRemaining / SECONDS_IN_A_HOUR;
|
||||
secondsRemaining = secondsRemaining % SECONDS_IN_A_HOUR;
|
||||
datetime->minute = secondsRemaining / 60U;
|
||||
datetime->second = secondsRemaining % SECONDS_IN_A_MINUTE;
|
||||
|
||||
/* Calculate year */
|
||||
daysInYear = DAYS_IN_A_YEAR;
|
||||
datetime->year = YEAR_RANGE_START;
|
||||
while (days > daysInYear)
|
||||
{
|
||||
/* Decrease day count by a year and increment year by 1 */
|
||||
days -= daysInYear;
|
||||
datetime->year++;
|
||||
|
||||
/* Adjust the number of days for a leap year */
|
||||
if (datetime->year & 3U)
|
||||
{
|
||||
daysInYear = DAYS_IN_A_YEAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
daysInYear = DAYS_IN_A_YEAR + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust the days in February for a leap year */
|
||||
if (!(datetime->year & 3U))
|
||||
{
|
||||
daysPerMonth[2] = 29U;
|
||||
}
|
||||
|
||||
for (x = 1U; x <= 12U; x++)
|
||||
{
|
||||
if (days <= daysPerMonth[x])
|
||||
{
|
||||
datetime->month = x;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
days -= daysPerMonth[x];
|
||||
}
|
||||
}
|
||||
|
||||
datetime->day = days;
|
||||
}
|
||||
|
||||
void RTC_Init(RTC_Type *base, const rtc_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
uint32_t reg;
|
||||
|
||||
CLOCK_EnableClock(kCLOCK_Rtc0);
|
||||
|
||||
/* Issue a software reset if timer is invalid */
|
||||
if (RTC_GetStatusFlags(RTC) & kRTC_TimeInvalidFlag)
|
||||
{
|
||||
RTC_Reset(RTC);
|
||||
}
|
||||
|
||||
reg = base->CR;
|
||||
/* Setup the update mode and supervisor access mode */
|
||||
reg &= ~(RTC_CR_UM_MASK | RTC_CR_SUP_MASK);
|
||||
reg |= RTC_CR_UM(config->updateMode) | RTC_CR_SUP(config->supervisorAccess);
|
||||
#if defined(FSL_FEATURE_RTC_HAS_WAKEUP_PIN) && FSL_FEATURE_RTC_HAS_WAKEUP_PIN
|
||||
/* Setup the wakeup pin select */
|
||||
reg &= ~(RTC_CR_WPS_MASK);
|
||||
reg |= RTC_CR_WPS(config->wakeupSelect);
|
||||
#endif /* FSL_FEATURE_RTC_HAS_WAKEUP_PIN */
|
||||
base->CR = reg;
|
||||
|
||||
/* Configure the RTC time compensation register */
|
||||
base->TCR = (RTC_TCR_CIR(config->compensationInterval) | RTC_TCR_TCR(config->compensationTime));
|
||||
}
|
||||
|
||||
void RTC_GetDefaultConfig(rtc_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
/* Wakeup pin will assert if the RTC interrupt asserts or if the wakeup pin is turned on */
|
||||
config->wakeupSelect = false;
|
||||
/* Registers cannot be written when locked */
|
||||
config->updateMode = false;
|
||||
/* Non-supervisor mode write accesses are not supported and will generate a bus error */
|
||||
config->supervisorAccess = false;
|
||||
/* Compensation interval used by the crystal compensation logic */
|
||||
config->compensationInterval = 0;
|
||||
/* Compensation time used by the crystal compensation logic */
|
||||
config->compensationTime = 0;
|
||||
}
|
||||
|
||||
status_t RTC_SetDatetime(RTC_Type *base, const rtc_datetime_t *datetime)
|
||||
{
|
||||
assert(datetime);
|
||||
|
||||
/* Return error if the time provided is not valid */
|
||||
if (!(RTC_CheckDatetimeFormat(datetime)))
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
/* Set time in seconds */
|
||||
base->TSR = RTC_ConvertDatetimeToSeconds(datetime);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime)
|
||||
{
|
||||
assert(datetime);
|
||||
|
||||
uint32_t seconds = 0;
|
||||
|
||||
seconds = base->TSR;
|
||||
RTC_ConvertSecondsToDatetime(seconds, datetime);
|
||||
}
|
||||
|
||||
status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime)
|
||||
{
|
||||
assert(alarmTime);
|
||||
|
||||
uint32_t alarmSeconds = 0;
|
||||
uint32_t currSeconds = 0;
|
||||
|
||||
/* Return error if the alarm time provided is not valid */
|
||||
if (!(RTC_CheckDatetimeFormat(alarmTime)))
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
alarmSeconds = RTC_ConvertDatetimeToSeconds(alarmTime);
|
||||
|
||||
/* Get the current time */
|
||||
currSeconds = base->TSR;
|
||||
|
||||
/* Return error if the alarm time has passed */
|
||||
if (alarmSeconds < currSeconds)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
/* Set alarm in seconds*/
|
||||
base->TAR = alarmSeconds;
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime)
|
||||
{
|
||||
assert(datetime);
|
||||
|
||||
uint32_t alarmSeconds = 0;
|
||||
|
||||
/* Get alarm in seconds */
|
||||
alarmSeconds = base->TAR;
|
||||
|
||||
RTC_ConvertSecondsToDatetime(alarmSeconds, datetime);
|
||||
}
|
||||
|
||||
void RTC_ClearStatusFlags(RTC_Type *base, uint32_t mask)
|
||||
{
|
||||
/* The alarm flag is cleared by writing to the TAR register */
|
||||
if (mask & kRTC_AlarmFlag)
|
||||
{
|
||||
base->TAR = 0U;
|
||||
}
|
||||
|
||||
/* The timer overflow flag is cleared by initializing the TSR register.
|
||||
* The time counter should be disabled for this write to be successful
|
||||
*/
|
||||
if (mask & kRTC_TimeOverflowFlag)
|
||||
{
|
||||
base->TSR = 1U;
|
||||
}
|
||||
|
||||
/* The timer overflow flag is cleared by initializing the TSR register.
|
||||
* The time counter should be disabled for this write to be successful
|
||||
*/
|
||||
if (mask & kRTC_TimeInvalidFlag)
|
||||
{
|
||||
base->TSR = 1U;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC)
|
||||
|
||||
void RTC_GetMonotonicCounter(RTC_Type *base, uint64_t *counter)
|
||||
{
|
||||
*counter = (((uint64_t)base->MCHR << 32) | ((uint64_t)base->MCLR));
|
||||
}
|
||||
|
||||
void RTC_SetMonotonicCounter(RTC_Type *base, uint64_t counter)
|
||||
{
|
||||
/* Prepare to initialize the register with the new value written */
|
||||
base->MER &= ~RTC_MER_MCE_MASK;
|
||||
|
||||
base->MCHR = (uint32_t)((counter) >> 32);
|
||||
base->MCLR = (uint32_t)(counter);
|
||||
}
|
||||
|
||||
status_t RTC_IncrementMonotonicCounter(RTC_Type *base)
|
||||
{
|
||||
if (base->SR & (RTC_SR_MOF_MASK | RTC_SR_TIF_MASK))
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
/* Prepare to switch to increment mode */
|
||||
base->MER |= RTC_MER_MCE_MASK;
|
||||
/* Write anything so the counter increments*/
|
||||
base->MCLR = 1U;
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
#endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */
|
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_RTC_H_
|
||||
#define _FSL_RTC_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup rtc_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
#define FSL_RTC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
|
||||
/*@}*/
|
||||
|
||||
/*! @brief List of RTC interrupts */
|
||||
typedef enum _rtc_interrupt_enable
|
||||
{
|
||||
kRTC_TimeInvalidInterruptEnable = RTC_IER_TIIE_MASK, /*!< Time invalid interrupt.*/
|
||||
kRTC_TimeOverflowInterruptEnable = RTC_IER_TOIE_MASK, /*!< Time overflow interrupt.*/
|
||||
kRTC_AlarmInterruptEnable = RTC_IER_TAIE_MASK, /*!< Alarm interrupt.*/
|
||||
kRTC_SecondsInterruptEnable = RTC_IER_TSIE_MASK /*!< Seconds interrupt.*/
|
||||
} rtc_interrupt_enable_t;
|
||||
|
||||
/*! @brief List of RTC flags */
|
||||
typedef enum _rtc_status_flags
|
||||
{
|
||||
kRTC_TimeInvalidFlag = RTC_SR_TIF_MASK, /*!< Time invalid flag */
|
||||
kRTC_TimeOverflowFlag = RTC_SR_TOF_MASK, /*!< Time overflow flag */
|
||||
kRTC_AlarmFlag = RTC_SR_TAF_MASK /*!< Alarm flag*/
|
||||
} rtc_status_flags_t;
|
||||
|
||||
/*! @brief List of RTC Oscillator capacitor load settings */
|
||||
typedef enum _rtc_osc_cap_load
|
||||
{
|
||||
kRTC_Capacitor_2p = RTC_CR_SC2P_MASK, /*!< 2pF capacitor load */
|
||||
kRTC_Capacitor_4p = RTC_CR_SC4P_MASK, /*!< 4pF capacitor load */
|
||||
kRTC_Capacitor_8p = RTC_CR_SC8P_MASK, /*!< 8pF capacitor load */
|
||||
kRTC_Capacitor_16p = RTC_CR_SC16P_MASK /*!< 16pF capacitor load */
|
||||
} rtc_osc_cap_load_t;
|
||||
|
||||
/*! @brief Structure is used to hold the date and time */
|
||||
typedef struct _rtc_datetime
|
||||
{
|
||||
uint16_t year; /*!< Range from 1970 to 2099.*/
|
||||
uint8_t month; /*!< Range from 1 to 12.*/
|
||||
uint8_t day; /*!< Range from 1 to 31 (depending on month).*/
|
||||
uint8_t hour; /*!< Range from 0 to 23.*/
|
||||
uint8_t minute; /*!< Range from 0 to 59.*/
|
||||
uint8_t second; /*!< Range from 0 to 59.*/
|
||||
} rtc_datetime_t;
|
||||
|
||||
/*!
|
||||
* @brief RTC config structure
|
||||
*
|
||||
* This structure holds the configuration settings for the RTC peripheral. To initialize this
|
||||
* structure to reasonable defaults, call the RTC_GetDefaultConfig() function and pass a
|
||||
* pointer to your config structure instance.
|
||||
*
|
||||
* The config struct can be made const so it resides in flash
|
||||
*/
|
||||
typedef struct _rtc_config
|
||||
{
|
||||
bool wakeupSelect; /*!< true: Wakeup pin outputs the 32KHz clock;
|
||||
false:Wakeup pin used to wakeup the chip */
|
||||
bool updateMode; /*!< true: Registers can be written even when locked under certain
|
||||
conditions, false: No writes allowed when registers are locked */
|
||||
bool supervisorAccess; /*!< true: Non-supervisor accesses are allowed;
|
||||
false: Non-supervisor accesses are not supported */
|
||||
uint32_t compensationInterval; /*!< Compensation interval that is written to the CIR field in RTC TCR Register */
|
||||
uint32_t compensationTime; /*!< Compensation time that is written to the TCR field in RTC TCR Register */
|
||||
} rtc_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Initialization and deinitialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Ungates the RTC clock and configures the peripheral for basic operation.
|
||||
*
|
||||
* This function will issue a software reset if the timer invalid flag is set.
|
||||
*
|
||||
* @note This API should be called at the beginning of the application using the RTC driver.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
* @param config Pointer to user's RTC config structure.
|
||||
*/
|
||||
void RTC_Init(RTC_Type *base, const rtc_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Stop the timer and gate the RTC clock
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
*/
|
||||
static inline void RTC_Deinit(RTC_Type *base)
|
||||
{
|
||||
/* Stop the RTC timer */
|
||||
base->SR &= ~RTC_SR_TCE_MASK;
|
||||
|
||||
/* Gate the module clock */
|
||||
CLOCK_DisableClock(kCLOCK_Rtc0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Fill in the RTC config struct with the default settings
|
||||
*
|
||||
* The default values are:
|
||||
* @code
|
||||
* config->wakeupSelect = false;
|
||||
* config->updateMode = false;
|
||||
* config->supervisorAccess = false;
|
||||
* config->compensationInterval = 0;
|
||||
* config->compensationTime = 0;
|
||||
* @endcode
|
||||
* @param config Pointer to user's RTC config structure.
|
||||
*/
|
||||
void RTC_GetDefaultConfig(rtc_config_t *config);
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Current Time & Alarm
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Sets the RTC date and time according to the given time structure.
|
||||
*
|
||||
* The RTC counter must be stopped prior to calling this function as writes to the RTC
|
||||
* seconds register will fail if the RTC counter is running.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
* @param datetime Pointer to structure where the date and time details to set are stored
|
||||
*
|
||||
* @return kStatus_Success: Success in setting the time and starting the RTC
|
||||
* kStatus_InvalidArgument: Error because the datetime format is incorrect
|
||||
*/
|
||||
status_t RTC_SetDatetime(RTC_Type *base, const rtc_datetime_t *datetime);
|
||||
|
||||
/*!
|
||||
* @brief Gets the RTC time and stores it in the given time structure.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
* @param datetime Pointer to structure where the date and time details are stored.
|
||||
*/
|
||||
void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime);
|
||||
|
||||
/*!
|
||||
* @brief Sets the RTC alarm time
|
||||
*
|
||||
* The function checks whether the specified alarm time is greater than the present
|
||||
* time. If not, the function does not set the alarm and returns an error.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
* @param alarmTime Pointer to structure where the alarm time is stored.
|
||||
*
|
||||
* @return kStatus_Success: success in setting the RTC alarm
|
||||
* kStatus_InvalidArgument: Error because the alarm datetime format is incorrect
|
||||
* kStatus_Fail: Error because the alarm time has already passed
|
||||
*/
|
||||
status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime);
|
||||
|
||||
/*!
|
||||
* @brief Returns the RTC alarm time.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
* @param datetime Pointer to structure where the alarm date and time details are stored.
|
||||
*/
|
||||
void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime);
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Interrupt Interface
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables the selected RTC interrupts.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
* @param mask The interrupts to enable. This is a logical OR of members of the
|
||||
* enumeration ::rtc_interrupt_enable_t
|
||||
*/
|
||||
static inline void RTC_EnableInterrupts(RTC_Type *base, uint32_t mask)
|
||||
{
|
||||
base->IER |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the selected RTC interrupts.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
* @param mask The interrupts to enable. This is a logical OR of members of the
|
||||
* enumeration ::rtc_interrupt_enable_t
|
||||
*/
|
||||
static inline void RTC_DisableInterrupts(RTC_Type *base, uint32_t mask)
|
||||
{
|
||||
base->IER &= ~mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the enabled RTC interrupts.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
*
|
||||
* @return The enabled interrupts. This is the logical OR of members of the
|
||||
* enumeration ::rtc_interrupt_enable_t
|
||||
*/
|
||||
static inline uint32_t RTC_GetEnabledInterrupts(RTC_Type *base)
|
||||
{
|
||||
return (base->IER & (RTC_IER_TIIE_MASK | RTC_IER_TOIE_MASK | RTC_IER_TAIE_MASK | RTC_IER_TSIE_MASK));
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Status Interface
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Gets the RTC status flags
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
*
|
||||
* @return The status flags. This is the logical OR of members of the
|
||||
* enumeration ::rtc_status_flags_t
|
||||
*/
|
||||
static inline uint32_t RTC_GetStatusFlags(RTC_Type *base)
|
||||
{
|
||||
return (base->SR & (RTC_SR_TIF_MASK | RTC_SR_TOF_MASK | RTC_SR_TAF_MASK));
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the RTC status flags.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
* @param mask The status flags to clear. This is a logical OR of members of the
|
||||
* enumeration ::rtc_status_flags_t
|
||||
*/
|
||||
void RTC_ClearStatusFlags(RTC_Type *base, uint32_t mask);
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name Timer Start and Stop
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Starts the RTC time counter.
|
||||
*
|
||||
* After calling this function, the timer counter increments once a second provided SR[TOF] or
|
||||
* SR[TIF] are not set.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
*/
|
||||
static inline void RTC_StartTimer(RTC_Type *base)
|
||||
{
|
||||
base->SR |= RTC_SR_TCE_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Stops the RTC time counter.
|
||||
*
|
||||
* RTC's seconds register can be written to only when the timer is stopped.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
*/
|
||||
static inline void RTC_StopTimer(RTC_Type *base)
|
||||
{
|
||||
base->SR &= ~RTC_SR_TCE_MASK;
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @brief This function sets the specified capacitor configuration for the RTC oscillator.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
* @param capLoad Oscillator loads to enable. This is a logical OR of members of the
|
||||
* enumeration ::rtc_osc_cap_load_t
|
||||
*/
|
||||
static inline void RTC_SetOscCapLoad(RTC_Type *base, uint32_t capLoad)
|
||||
{
|
||||
uint32_t reg = base->CR;
|
||||
|
||||
reg &= ~(RTC_CR_SC2P_MASK | RTC_CR_SC4P_MASK | RTC_CR_SC8P_MASK | RTC_CR_SC16P_MASK);
|
||||
reg |= capLoad;
|
||||
|
||||
base->CR = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Performs a software reset on the RTC module.
|
||||
*
|
||||
* This resets all RTC registers except for the SWR bit and the RTC_WAR and RTC_RAR
|
||||
* registers. The SWR bit is cleared by software explicitly clearing it.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
*/
|
||||
static inline void RTC_Reset(RTC_Type *base)
|
||||
{
|
||||
base->CR |= RTC_CR_SWR_MASK;
|
||||
base->CR &= ~RTC_CR_SWR_MASK;
|
||||
|
||||
/* Set TSR register to 0x1 to avoid the timer invalid (TIF) bit being set in the SR register */
|
||||
base->TSR = 1U;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC)
|
||||
|
||||
/*!
|
||||
* @name Monotonic counter functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Reads the values of the Monotonic Counter High and Monotonic Counter Low and returns
|
||||
* them as a single value.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
* @param counter Pointer to variable where the value is stored.
|
||||
*/
|
||||
void RTC_GetMonotonicCounter(RTC_Type *base, uint64_t *counter);
|
||||
|
||||
/*!
|
||||
* @brief Writes values Monotonic Counter High and Monotonic Counter Low by decomposing
|
||||
* the given single value.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
* @param counter Counter value
|
||||
*/
|
||||
void RTC_SetMonotonicCounter(RTC_Type *base, uint64_t counter);
|
||||
|
||||
/*!
|
||||
* @brief Increments the Monotonic Counter by one.
|
||||
*
|
||||
* Increments the Monotonic Counter (registers RTC_MCLR and RTC_MCHR accordingly) by setting
|
||||
* the monotonic counter enable (MER[MCE]) and then writing to the RTC_MCLR register. A write to the
|
||||
* monotonic counter low that causes it to overflow also increments the monotonic counter high.
|
||||
*
|
||||
* @param base RTC peripheral base address
|
||||
*
|
||||
* @return kStatus_Success: success
|
||||
* kStatus_Fail: error occurred, either time invalid or monotonic overflow flag was found
|
||||
*/
|
||||
status_t RTC_IncrementMonotonicCounter(RTC_Type *base);
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_RTC_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,850 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FSL_SAI_H_
|
||||
#define _FSL_SAI_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup sai
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
#define FSL_SAI_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0 */
|
||||
/*@}*/
|
||||
|
||||
/*! @brief SAI return status*/
|
||||
enum _sai_status_t
|
||||
{
|
||||
kStatus_SAI_TxBusy = MAKE_STATUS(kStatusGroup_SAI, 0), /*!< SAI Tx is busy. */
|
||||
kStatus_SAI_RxBusy = MAKE_STATUS(kStatusGroup_SAI, 1), /*!< SAI Rx is busy. */
|
||||
kStatus_SAI_TxError = MAKE_STATUS(kStatusGroup_SAI, 2), /*!< SAI Tx FIFO error. */
|
||||
kStatus_SAI_RxError = MAKE_STATUS(kStatusGroup_SAI, 3), /*!< SAI Rx FIFO error. */
|
||||
kStatus_SAI_QueueFull = MAKE_STATUS(kStatusGroup_SAI, 4), /*!< SAI transfer queue is full. */
|
||||
kStatus_SAI_TxIdle = MAKE_STATUS(kStatusGroup_SAI, 5), /*!< SAI Tx is idle */
|
||||
kStatus_SAI_RxIdle = MAKE_STATUS(kStatusGroup_SAI, 6) /*!< SAI Rx is idle */
|
||||
};
|
||||
|
||||
/*! @brief Define the SAI bus type */
|
||||
typedef enum _sai_protocol
|
||||
{
|
||||
kSAI_BusLeftJustified = 0x0U, /*!< Uses left justified format.*/
|
||||
kSAI_BusRightJustified, /*!< Uses right justified format. */
|
||||
kSAI_BusI2S, /*!< Uses I2S format. */
|
||||
kSAI_BusPCMA, /*!< Uses I2S PCM A format.*/
|
||||
kSAI_BusPCMB /*!< Uses I2S PCM B format. */
|
||||
} sai_protocol_t;
|
||||
|
||||
/*! @brief Master or slave mode */
|
||||
typedef enum _sai_master_slave
|
||||
{
|
||||
kSAI_Master = 0x0U, /*!< Master mode */
|
||||
kSAI_Slave = 0x1U /*!< Slave mode */
|
||||
} sai_master_slave_t;
|
||||
|
||||
/*! @brief Mono or stereo audio format */
|
||||
typedef enum _sai_mono_stereo
|
||||
{
|
||||
kSAI_Stereo = 0x0U, /*!< Stereo sound. */
|
||||
kSAI_MonoLeft, /*!< Only left channel have sound. */
|
||||
kSAI_MonoRight /*!< Only Right channel have sound. */
|
||||
} sai_mono_stereo_t;
|
||||
|
||||
/*! @brief Synchronous or asynchronous mode */
|
||||
typedef enum _sai_sync_mode
|
||||
{
|
||||
kSAI_ModeAsync = 0x0U, /*!< Asynchronous mode */
|
||||
kSAI_ModeSync, /*!< Synchronous mode (with receiver or transmit) */
|
||||
kSAI_ModeSyncWithOtherTx, /*!< Synchronous with another SAI transmit */
|
||||
kSAI_ModeSyncWithOtherRx /*!< Synchronous with another SAI receiver */
|
||||
} sai_sync_mode_t;
|
||||
|
||||
/*! @brief Mater clock source */
|
||||
typedef enum _sai_mclk_source
|
||||
{
|
||||
kSAI_MclkSourceSysclk = 0x0U, /*!< Master clock from the system clock */
|
||||
kSAI_MclkSourceSelect1, /*!< Master clock from source 1 */
|
||||
kSAI_MclkSourceSelect2, /*!< Master clock from source 2 */
|
||||
kSAI_MclkSourceSelect3 /*!< Master clock from source 3 */
|
||||
} sai_mclk_source_t;
|
||||
|
||||
/*! @brief Bit clock source */
|
||||
typedef enum _sai_bclk_source
|
||||
{
|
||||
kSAI_BclkSourceBusclk = 0x0U, /*!< Bit clock using bus clock */
|
||||
kSAI_BclkSourceMclkDiv, /*!< Bit clock using master clock divider */
|
||||
kSAI_BclkSourceOtherSai0, /*!< Bit clock from other SAI device */
|
||||
kSAI_BclkSourceOtherSai1 /*!< Bit clock from other SAI device */
|
||||
} sai_bclk_source_t;
|
||||
|
||||
/*! @brief The SAI interrupt enable flag */
|
||||
enum _sai_interrupt_enable_t
|
||||
{
|
||||
kSAI_WordStartInterruptEnable =
|
||||
I2S_TCSR_WSIE_MASK, /*!< Word start flag, means the first word in a frame detected */
|
||||
kSAI_SyncErrorInterruptEnable = I2S_TCSR_SEIE_MASK, /*!< Sync error flag, means the sync error is detected */
|
||||
kSAI_FIFOWarningInterruptEnable = I2S_TCSR_FWIE_MASK, /*!< FIFO warning flag, means the FIFO is empty */
|
||||
kSAI_FIFOErrorInterruptEnable = I2S_TCSR_FEIE_MASK, /*!< FIFO error flag */
|
||||
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
|
||||
kSAI_FIFORequestInterruptEnable = I2S_TCSR_FRIE_MASK, /*!< FIFO request, means reached watermark */
|
||||
#endif /* FSL_FEATURE_SAI_FIFO_COUNT */
|
||||
};
|
||||
|
||||
/*! @brief The DMA request sources */
|
||||
enum _sai_dma_enable_t
|
||||
{
|
||||
kSAI_FIFOWarningDMAEnable = I2S_TCSR_FWDE_MASK, /*!< FIFO warning caused by the DMA request */
|
||||
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
|
||||
kSAI_FIFORequestDMAEnable = I2S_TCSR_FRDE_MASK, /*!< FIFO request caused by the DMA request */
|
||||
#endif /* FSL_FEATURE_SAI_FIFO_COUNT */
|
||||
};
|
||||
|
||||
/*! @brief The SAI status flag */
|
||||
enum _sai_flags
|
||||
{
|
||||
kSAI_WordStartFlag = I2S_TCSR_WSF_MASK, /*!< Word start flag, means the first word in a frame detected */
|
||||
kSAI_SyncErrorFlag = I2S_TCSR_SEF_MASK, /*!< Sync error flag, means the sync error is detected */
|
||||
kSAI_FIFOErrorFlag = I2S_TCSR_FEF_MASK, /*!< FIFO error flag */
|
||||
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
|
||||
kSAI_FIFORequestFlag = I2S_TCSR_FRF_MASK, /*!< FIFO request flag. */
|
||||
#endif /* FSL_FEATURE_SAI_FIFO_COUNT */
|
||||
kSAI_FIFOWarningFlag = I2S_TCSR_FWF_MASK, /*!< FIFO warning flag */
|
||||
};
|
||||
|
||||
/*! @brief The reset type */
|
||||
typedef enum _sai_reset_type
|
||||
{
|
||||
kSAI_ResetTypeSoftware = I2S_TCSR_SR_MASK, /*!< Software reset, reset the logic state */
|
||||
kSAI_ResetTypeFIFO = I2S_TCSR_FR_MASK, /*!< FIFO reset, reset the FIFO read and write pointer */
|
||||
kSAI_ResetAll = I2S_TCSR_SR_MASK | I2S_TCSR_FR_MASK /*!< All reset. */
|
||||
} sai_reset_type_t;
|
||||
|
||||
#if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING
|
||||
/*!
|
||||
* @brief The SAI packing mode
|
||||
* The mode includes 8 bit and 16 bit packing.
|
||||
*/
|
||||
typedef enum _sai_fifo_packing
|
||||
{
|
||||
kSAI_FifoPackingDisabled = 0x0U, /*!< Packing disabled */
|
||||
kSAI_FifoPacking8bit = 0x2U, /*!< 8 bit packing enabled */
|
||||
kSAI_FifoPacking16bit = 0x3U /*!< 16bit packing enabled */
|
||||
} sai_fifo_packing_t;
|
||||
#endif /* FSL_FEATURE_SAI_HAS_FIFO_PACKING */
|
||||
|
||||
/*! @brief SAI user configure structure */
|
||||
typedef struct _sai_config
|
||||
{
|
||||
sai_protocol_t protocol; /*!< Audio bus protocol in SAI */
|
||||
sai_sync_mode_t syncMode; /*!< SAI sync mode, control Tx/Rx clock sync */
|
||||
#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
|
||||
bool mclkOutputEnable; /*!< Master clock output enable, true means master clock divider enabled */
|
||||
#endif /* FSL_FEATURE_SAI_HAS_MCR */
|
||||
sai_mclk_source_t mclkSource; /*!< Master Clock source */
|
||||
sai_bclk_source_t bclkSource; /*!< Bit Clock source */
|
||||
sai_master_slave_t masterSlave; /*!< Master or slave */
|
||||
} sai_config_t;
|
||||
|
||||
/*!@brief SAI transfer queue size, user can refine it according to use case. */
|
||||
#define SAI_XFER_QUEUE_SIZE (4)
|
||||
|
||||
/*! @brief Audio sample rate */
|
||||
typedef enum _sai_sample_rate
|
||||
{
|
||||
kSAI_SampleRate8KHz = 8000U, /*!< Sample rate 8000Hz */
|
||||
kSAI_SampleRate11025Hz = 11025U, /*!< Sample rate 11025Hz */
|
||||
kSAI_SampleRate12KHz = 12000U, /*!< Sample rate 12000Hz */
|
||||
kSAI_SampleRate16KHz = 16000U, /*!< Sample rate 16000Hz */
|
||||
kSAI_SampleRate22050Hz = 22050U, /*!< Sample rate 22050Hz */
|
||||
kSAI_SampleRate24KHz = 24000U, /*!< Sample rate 24000Hz */
|
||||
kSAI_SampleRate32KHz = 32000U, /*!< Sample rate 32000Hz */
|
||||
kSAI_SampleRate44100Hz = 44100U, /*!< Sample rate 44100Hz */
|
||||
kSAI_SampleRate48KHz = 48000U, /*!< Sample rate 48000Hz */
|
||||
kSAI_SampleRate96KHz = 96000U /*!< Sample rate 96000Hz */
|
||||
} sai_sample_rate_t;
|
||||
|
||||
/*! @brief Audio word width */
|
||||
typedef enum _sai_word_width
|
||||
{
|
||||
kSAI_WordWidth8bits = 8U, /*!< Audio data width 8 bits */
|
||||
kSAI_WordWidth16bits = 16U, /*!< Audio data width 16 bits */
|
||||
kSAI_WordWidth24bits = 24U, /*!< Audio data width 24 bits */
|
||||
kSAI_WordWidth32bits = 32U /*!< Audio data width 32 bits */
|
||||
} sai_word_width_t;
|
||||
|
||||
/*! @brief sai transfer format */
|
||||
typedef struct _sai_transfer_format
|
||||
{
|
||||
uint32_t sampleRate_Hz; /*!< Sample rate of audio data */
|
||||
uint32_t bitWidth; /*!< Data length of audio data, usually 8/16/24/32bits */
|
||||
sai_mono_stereo_t stereo; /*!< Mono or stereo */
|
||||
uint32_t masterClockHz; /*!< Master clock frequency in Hz */
|
||||
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
|
||||
uint8_t watermark; /*!< Watermark value */
|
||||
#endif /* FSL_FEATURE_SAI_FIFO_COUNT */
|
||||
uint8_t channel; /*!< Data channel used in transfer.*/
|
||||
sai_protocol_t protocol; /*!< Which audio protocol used */
|
||||
} sai_transfer_format_t;
|
||||
|
||||
/*! @brief SAI transfer structure */
|
||||
typedef struct _sai_transfer
|
||||
{
|
||||
uint8_t *data; /*!< Data start address to transfer. */
|
||||
size_t dataSize; /*!< Transfer size. */
|
||||
} sai_transfer_t;
|
||||
|
||||
typedef struct _sai_handle sai_handle_t;
|
||||
|
||||
/*! @brief SAI transfer callback prototype */
|
||||
typedef void (*sai_transfer_callback_t)(I2S_Type *base, sai_handle_t *handle, status_t status, void *userData);
|
||||
|
||||
/*! @brief SAI handle structure */
|
||||
struct _sai_handle
|
||||
{
|
||||
uint32_t state; /*!< Transfer status */
|
||||
sai_transfer_callback_t callback; /*!< Callback function called at transfer event*/
|
||||
void *userData; /*!< Callback parameter passed to callback function*/
|
||||
uint8_t bitWidth; /*!< Bit width for transfer, 8/16/24/32bits */
|
||||
uint8_t channel; /*!< Transfer channel */
|
||||
sai_transfer_t saiQueue[SAI_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer */
|
||||
size_t transferSize[SAI_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */
|
||||
volatile uint8_t queueUser; /*!< Index for user to queue transfer */
|
||||
volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */
|
||||
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
|
||||
uint8_t watermark; /*!< Watermark value */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /*_cplusplus*/
|
||||
|
||||
/*!
|
||||
* @name Initialization and deinitialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the SAI Tx peripheral.
|
||||
*
|
||||
* Ungates the SAI clock, resets the module, and configures SAI Tx with a configuration structure.
|
||||
* The configuration structure can be custom filled or set with default values by
|
||||
* SAI_TxGetDefaultConfig().
|
||||
*
|
||||
* @note This API should be called at the beginning of the application to use
|
||||
* the SAI driver. Otherwise, accessing the SAIM module can cause a hard fault
|
||||
* because the clock is not enabled.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param config SAI configure structure.
|
||||
*/
|
||||
void SAI_TxInit(I2S_Type *base, const sai_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the the SAI Rx peripheral.
|
||||
*
|
||||
* Ungates the SAI clock, resets the module, and configures the SAI Rx with a configuration structure.
|
||||
* The configuration structure can be custom filled or set with default values by
|
||||
* SAI_RxGetDefaultConfig().
|
||||
*
|
||||
* @note This API should be called at the beginning of the application to use
|
||||
* the SAI driver. Otherwise, accessing the SAI module can cause a hard fault
|
||||
* because the clock is not enabled.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param config SAI configure structure.
|
||||
*/
|
||||
void SAI_RxInit(I2S_Type *base, const sai_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Sets the SAI Tx configuration structure to default values.
|
||||
*
|
||||
* This API initializes the configuration structure for use in SAI_TxConfig().
|
||||
* The initialized structure can remain unchanged in SAI_TxConfig(), or it can be modified
|
||||
* before calling SAI_TxConfig().
|
||||
* Example:
|
||||
@code
|
||||
sai_config_t config;
|
||||
SAI_TxGetDefaultConfig(&config);
|
||||
@endcode
|
||||
*
|
||||
* @param config pointer to master configuration structure
|
||||
*/
|
||||
void SAI_TxGetDefaultConfig(sai_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Sets the SAI Rx configuration structure to default values.
|
||||
*
|
||||
* This API initializes the configuration structure for use in SAI_RxConfig().
|
||||
* The initialized structure can remain unchanged in SAI_RxConfig() or it can be modified
|
||||
* before calling SAI_RxConfig().
|
||||
* Example:
|
||||
@code
|
||||
sai_config_t config;
|
||||
SAI_RxGetDefaultConfig(&config);
|
||||
@endcode
|
||||
*
|
||||
* @param config pointer to master configuration structure
|
||||
*/
|
||||
void SAI_RxGetDefaultConfig(sai_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief De-initializes the SAI peripheral.
|
||||
*
|
||||
* This API gates the SAI clock. The SAI module can't operate unless SAI_TxInit
|
||||
* or SAI_RxInit is called to enable the clock.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
*/
|
||||
void SAI_Deinit(I2S_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Resets the SAI Tx.
|
||||
*
|
||||
* This function enables the software reset and FIFO reset of SAI Tx. After reset, clear the reset bit.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
*/
|
||||
void SAI_TxReset(I2S_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Resets the SAI Rx.
|
||||
*
|
||||
* This function enables the software reset and FIFO reset of SAI Rx. After reset, clear the reset bit.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
*/
|
||||
void SAI_RxReset(I2S_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Enables/disables SAI Tx.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param enable True means enable SAI Tx, false means disable.
|
||||
*/
|
||||
void SAI_TxEnable(I2S_Type *base, bool enable);
|
||||
|
||||
/*!
|
||||
* @brief Enables/disables SAI Rx.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param enable True means enable SAI Rx, false means disable.
|
||||
*/
|
||||
void SAI_RxEnable(I2S_Type *base, bool enable);
|
||||
|
||||
/*! @} */
|
||||
|
||||
/*!
|
||||
* @name Status
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Gets the SAI Tx status flag state.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @return SAI Tx status flag value. Use the Status Mask to get the status value needed.
|
||||
*/
|
||||
static inline uint32_t SAI_TxGetStatusFlag(I2S_Type *base)
|
||||
{
|
||||
return base->TCSR;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the SAI Tx status flag state.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param mask State mask. It can be a combination of the following source if defined:
|
||||
* @arg kSAI_WordStartFlag
|
||||
* @arg kSAI_SyncErrorFlag
|
||||
* @arg kSAI_FIFOErrorFlag
|
||||
*/
|
||||
static inline void SAI_TxClearStatusFlags(I2S_Type *base, uint32_t mask)
|
||||
{
|
||||
base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | mask);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the SAI Tx status flag state.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @return SAI Rx status flag value. Use the Status Mask to get the status value needed.
|
||||
*/
|
||||
static inline uint32_t SAI_RxGetStatusFlag(I2S_Type *base)
|
||||
{
|
||||
return base->RCSR;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clears the SAI Rx status flag state.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param mask State mask. It can be a combination of the following source if defined:
|
||||
* @arg kSAI_WordStartFlag
|
||||
* @arg kSAI_SyncErrorFlag
|
||||
* @arg kSAI_FIFOErrorFlag
|
||||
*/
|
||||
static inline void SAI_RxClearStatusFlags(I2S_Type *base, uint32_t mask)
|
||||
{
|
||||
base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | mask);
|
||||
}
|
||||
|
||||
/*! @} */
|
||||
|
||||
/*!
|
||||
* @name Interrupts
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables SAI Tx interrupt requests.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param mask interrupt source
|
||||
* The parameter can be a combination of the following source if defined:
|
||||
* @arg kSAI_WordStartInterruptEnable
|
||||
* @arg kSAI_SyncErrorInterruptEnable
|
||||
* @arg kSAI_FIFOWarningInterruptEnable
|
||||
* @arg kSAI_FIFORequestInterruptEnable
|
||||
* @arg kSAI_FIFOErrorInterruptEnable
|
||||
*/
|
||||
static inline void SAI_TxEnableInterrupts(I2S_Type *base, uint32_t mask)
|
||||
{
|
||||
base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | mask);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables SAI Rx interrupt requests.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param mask interrupt source
|
||||
* The parameter can be a combination of the following source if defined:
|
||||
* @arg kSAI_WordStartInterruptEnable
|
||||
* @arg kSAI_SyncErrorInterruptEnable
|
||||
* @arg kSAI_FIFOWarningInterruptEnable
|
||||
* @arg kSAI_FIFORequestInterruptEnable
|
||||
* @arg kSAI_FIFOErrorInterruptEnable
|
||||
*/
|
||||
static inline void SAI_RxEnableInterrupts(I2S_Type *base, uint32_t mask)
|
||||
{
|
||||
base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | mask);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables SAI Tx interrupt requests.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param mask interrupt source
|
||||
* The parameter can be a combination of the following source if defined:
|
||||
* @arg kSAI_WordStartInterruptEnable
|
||||
* @arg kSAI_SyncErrorInterruptEnable
|
||||
* @arg kSAI_FIFOWarningInterruptEnable
|
||||
* @arg kSAI_FIFORequestInterruptEnable
|
||||
* @arg kSAI_FIFOErrorInterruptEnable
|
||||
*/
|
||||
static inline void SAI_TxDisableInterrupts(I2S_Type *base, uint32_t mask)
|
||||
{
|
||||
base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~mask));
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables SAI Rx interrupt requests.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param mask interrupt source
|
||||
* The parameter can be a combination of the following source if defined:
|
||||
* @arg kSAI_WordStartInterruptEnable
|
||||
* @arg kSAI_SyncErrorInterruptEnable
|
||||
* @arg kSAI_FIFOWarningInterruptEnable
|
||||
* @arg kSAI_FIFORequestInterruptEnable
|
||||
* @arg kSAI_FIFOErrorInterruptEnable
|
||||
*/
|
||||
static inline void SAI_RxDisableInterrupts(I2S_Type *base, uint32_t mask)
|
||||
{
|
||||
base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~mask));
|
||||
}
|
||||
|
||||
/*! @} */
|
||||
|
||||
/*!
|
||||
* @name DMA Control
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables/disables SAI Tx DMA requests.
|
||||
* @param base SAI base pointer
|
||||
* @param mask DMA source
|
||||
* The parameter can be combination of the following source if defined:
|
||||
* @arg kSAI_FIFOWarningDMAEnable
|
||||
* @arg kSAI_FIFORequestDMAEnable
|
||||
* @param enable True means enable DMA, false means disable DMA.
|
||||
*/
|
||||
static inline void SAI_TxEnableDMA(I2S_Type *base, uint32_t mask, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~mask));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables/disables SAI Rx DMA requests.
|
||||
* @param base SAI base pointer
|
||||
* @param mask DMA source
|
||||
* The parameter can be a combination of the following source if defined:
|
||||
* @arg kSAI_FIFOWarningDMAEnable
|
||||
* @arg kSAI_FIFORequestDMAEnable
|
||||
* @param enable True means enable DMA, false means disable DMA.
|
||||
*/
|
||||
static inline void SAI_RxEnableDMA(I2S_Type *base, uint32_t mask, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~mask));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the SAI Tx data register address.
|
||||
*
|
||||
* This API is used to provide a transfer address for SAI DMA transfer configuration.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param channel Which data channel used.
|
||||
* @return data register address.
|
||||
*/
|
||||
static inline uint32_t SAI_TxGetDataRegisterAddress(I2S_Type *base, uint32_t channel)
|
||||
{
|
||||
return (uint32_t)(&(base->TDR)[channel]);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the SAI Rx data register address.
|
||||
*
|
||||
* This API is used to provide a transfer address for SAI DMA transfer configuration.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param channel Which data channel used.
|
||||
* @return data register address.
|
||||
*/
|
||||
static inline uint32_t SAI_RxGetDataRegisterAddress(I2S_Type *base, uint32_t channel)
|
||||
{
|
||||
return (uint32_t)(&(base->RDR)[channel]);
|
||||
}
|
||||
|
||||
/*! @} */
|
||||
|
||||
/*!
|
||||
* @name Bus Operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Configures the SAI Tx audio format.
|
||||
*
|
||||
* The audio format can be changed at run-time. This function configures the sample rate and audio data
|
||||
* format to be transferred.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param format Pointer to SAI audio data format structure.
|
||||
* @param mclkSourceClockHz SAI master clock source frequency in Hz.
|
||||
* @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master
|
||||
* clock, this value should equals to masterClockHz in format.
|
||||
*/
|
||||
void SAI_TxSetFormat(I2S_Type *base,
|
||||
sai_transfer_format_t *format,
|
||||
uint32_t mclkSourceClockHz,
|
||||
uint32_t bclkSourceClockHz);
|
||||
|
||||
/*!
|
||||
* @brief Configures the SAI Rx audio format.
|
||||
*
|
||||
* The audio format can be changed at run-time. This function configures the sample rate and audio data
|
||||
* format to be transferred.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param format Pointer to SAI audio data format structure.
|
||||
* @param mclkSourceClockHz SAI master clock source frequency in Hz.
|
||||
* @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master
|
||||
* clock, this value should equals to masterClockHz in format.
|
||||
*/
|
||||
void SAI_RxSetFormat(I2S_Type *base,
|
||||
sai_transfer_format_t *format,
|
||||
uint32_t mclkSourceClockHz,
|
||||
uint32_t bclkSourceClockHz);
|
||||
|
||||
/*!
|
||||
* @brief Sends data using a blocking method.
|
||||
*
|
||||
* @note This function blocks by polling until data is ready to be sent.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param channel Data channel used.
|
||||
* @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
|
||||
* @param buffer Pointer to the data to be written.
|
||||
* @param size Bytes to be written.
|
||||
*/
|
||||
void SAI_WriteBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size);
|
||||
|
||||
/*!
|
||||
* @brief Writes data into SAI FIFO.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param channel Data channel used.
|
||||
* @param data Data needs to be written.
|
||||
*/
|
||||
static inline void SAI_WriteData(I2S_Type *base, uint32_t channel, uint32_t data)
|
||||
{
|
||||
base->TDR[channel] = data;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Receives data using a blocking method.
|
||||
*
|
||||
* @note This function blocks by polling until data is ready to be sent.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param channel Data channel used.
|
||||
* @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
|
||||
* @param buffer Pointer to the data to be read.
|
||||
* @param size Bytes to be read.
|
||||
*/
|
||||
void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size);
|
||||
|
||||
/*!
|
||||
* @brief Reads data from SAI FIFO.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param channel Data channel used.
|
||||
* @return Data in SAI FIFO.
|
||||
*/
|
||||
static inline uint32_t SAI_ReadData(I2S_Type *base, uint32_t channel)
|
||||
{
|
||||
return base->RDR[channel];
|
||||
}
|
||||
|
||||
/*! @} */
|
||||
|
||||
/*!
|
||||
* @name Transactional
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the SAI Tx handle.
|
||||
*
|
||||
* This function initializes the Tx handle for SAI Tx transactional APIs. Call
|
||||
* this function one time to get the handle initialized.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param handle SAI handle pointer.
|
||||
* @param callback pointer to user callback function
|
||||
* @param userData user parameter passed to the callback function
|
||||
*/
|
||||
void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the SAI Rx handle.
|
||||
*
|
||||
* This function initializes the Rx handle for SAI Rx transactional APIs. Call
|
||||
* this function one time to get the handle initialized.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle SAI handle pointer.
|
||||
* @param callback pointer to user callback function
|
||||
* @param userData user parameter passed to the callback function
|
||||
*/
|
||||
void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData);
|
||||
|
||||
/*!
|
||||
* @brief Configures the SAI Tx audio format.
|
||||
*
|
||||
* The audio format can be changed at run-time. This function configures the sample rate and audio data
|
||||
* format to be transferred.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle SAI handle pointer.
|
||||
* @param format Pointer to SAI audio data format structure.
|
||||
* @param mclkSourceClockHz SAI master clock source frequency in Hz.
|
||||
* @param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is a master
|
||||
* clock, this value should equal to masterClockHz in format.
|
||||
* @return Status of this function. Return value is one of status_t.
|
||||
*/
|
||||
status_t SAI_TransferTxSetFormat(I2S_Type *base,
|
||||
sai_handle_t *handle,
|
||||
sai_transfer_format_t *format,
|
||||
uint32_t mclkSourceClockHz,
|
||||
uint32_t bclkSourceClockHz);
|
||||
|
||||
/*!
|
||||
* @brief Configures the SAI Rx audio format.
|
||||
*
|
||||
* The audio format can be changed at run-time. This function configures the sample rate and audio data
|
||||
* format to be transferred.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle SAI handle pointer.
|
||||
* @param format Pointer to SAI audio data format structure.
|
||||
* @param mclkSourceClockHz SAI master clock source frequency in Hz.
|
||||
* @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master
|
||||
* clock, this value should equals to masterClockHz in format.
|
||||
* @return Status of this function. Return value is one of status_t.
|
||||
*/
|
||||
status_t SAI_TransferRxSetFormat(I2S_Type *base,
|
||||
sai_handle_t *handle,
|
||||
sai_transfer_format_t *format,
|
||||
uint32_t mclkSourceClockHz,
|
||||
uint32_t bclkSourceClockHz);
|
||||
|
||||
/*!
|
||||
* @brief Performs an interrupt non-blocking send transfer on SAI.
|
||||
*
|
||||
* @note This API returns immediately after the transfer initiates.
|
||||
* Call the SAI_TxGetTransferStatusIRQ to poll the transfer status and check whether
|
||||
* the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer
|
||||
* is finished.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param handle pointer to sai_handle_t structure which stores the transfer state
|
||||
* @param xfer pointer to sai_transfer_t structure
|
||||
* @retval kStatus_Success Successfully started the data receive.
|
||||
* @retval kStatus_SAI_TxBusy Previous receive still not finished.
|
||||
* @retval kStatus_InvalidArgument The input parameter is invalid.
|
||||
*/
|
||||
status_t SAI_TransferSendNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Performs an interrupt non-blocking receive transfer on SAI.
|
||||
*
|
||||
* @note This API returns immediately after the transfer initiates.
|
||||
* Call the SAI_RxGetTransferStatusIRQ to poll the transfer status and check whether
|
||||
* the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer
|
||||
* is finished.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param handle pointer to sai_handle_t structure which stores the transfer state
|
||||
* @param xfer pointer to sai_transfer_t structure
|
||||
* @retval kStatus_Success Successfully started the data receive.
|
||||
* @retval kStatus_SAI_RxBusy Previous receive still not finished.
|
||||
* @retval kStatus_InvalidArgument The input parameter is invalid.
|
||||
*/
|
||||
status_t SAI_TransferReceiveNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Gets a set byte count.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle pointer to sai_handle_t structure which stores the transfer state.
|
||||
* @param count Bytes count sent.
|
||||
* @retval kStatus_Success Succeed get the transfer count.
|
||||
* @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
|
||||
*/
|
||||
status_t SAI_TransferGetSendCount(I2S_Type *base, sai_handle_t *handle, size_t *count);
|
||||
|
||||
/*!
|
||||
* @brief Gets a received byte count.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle pointer to sai_handle_t structure which stores the transfer state.
|
||||
* @param count Bytes count received.
|
||||
* @retval kStatus_Success Succeed get the transfer count.
|
||||
* @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
|
||||
*/
|
||||
status_t SAI_TransferGetReceiveCount(I2S_Type *base, sai_handle_t *handle, size_t *count);
|
||||
|
||||
/*!
|
||||
* @brief Aborts the current send.
|
||||
*
|
||||
* @note This API can be called any time when an interrupt non-blocking transfer initiates
|
||||
* to abort the transfer early.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle pointer to sai_handle_t structure which stores the transfer state.
|
||||
*/
|
||||
void SAI_TransferAbortSend(I2S_Type *base, sai_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Aborts the the current IRQ receive.
|
||||
*
|
||||
* @note This API can be called any time when an interrupt non-blocking transfer initiates
|
||||
* to abort the transfer early.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param handle pointer to sai_handle_t structure which stores the transfer state.
|
||||
*/
|
||||
void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Tx interrupt handler.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle pointer to sai_handle_t structure.
|
||||
*/
|
||||
void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Tx interrupt handler.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle pointer to sai_handle_t structure.
|
||||
*/
|
||||
void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle);
|
||||
|
||||
/*! @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /*_cplusplus*/
|
||||
|
||||
/*! @} */
|
||||
|
||||
#endif /* _FSL_SAI_H_ */
|
|
@ -0,0 +1,379 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_sai_edma.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitations
|
||||
******************************************************************************/
|
||||
/* Used for 32byte aligned */
|
||||
#define STCD_ADDR(address) (edma_tcd_t *)(((uint32_t)address + 32) & ~0x1FU)
|
||||
|
||||
/*<! Structure definition for uart_edma_private_handle_t. The structure is private. */
|
||||
typedef struct _sai_edma_private_handle
|
||||
{
|
||||
I2S_Type *base;
|
||||
sai_edma_handle_t *handle;
|
||||
} sai_edma_private_handle_t;
|
||||
|
||||
enum _sai_edma_transfer_state
|
||||
{
|
||||
kSAI_Busy = 0x0U, /*!< SAI is busy */
|
||||
kSAI_Idle, /*!< Transfer is done. */
|
||||
};
|
||||
|
||||
/*<! Private handle only used for internally. */
|
||||
static sai_edma_private_handle_t s_edmaPrivateHandle[FSL_FEATURE_SOC_I2S_COUNT][2];
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Get the instance number for SAI.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
*/
|
||||
extern uint32_t SAI_GetInstance(I2S_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief SAI EDMA callback for send.
|
||||
*
|
||||
* @param handle pointer to sai_edma_handle_t structure which stores the transfer state.
|
||||
* @param userData Parameter for user callback.
|
||||
* @param done If the DMA transfer finished.
|
||||
* @param tcds The TCD index.
|
||||
*/
|
||||
static void SAI_TxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds);
|
||||
|
||||
/*!
|
||||
* @brief SAI EDMA callback for receive.
|
||||
*
|
||||
* @param handle pointer to sai_edma_handle_t structure which stores the transfer state.
|
||||
* @param userData Parameter for user callback.
|
||||
* @param done If the DMA transfer finished.
|
||||
* @param tcds The TCD index.
|
||||
*/
|
||||
static void SAI_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static void SAI_TxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds)
|
||||
{
|
||||
sai_edma_private_handle_t *privHandle = (sai_edma_private_handle_t *)userData;
|
||||
sai_edma_handle_t *saiHandle = privHandle->handle;
|
||||
|
||||
/* If finished a blcok, call the callback function */
|
||||
memset(&saiHandle->saiQueue[saiHandle->queueDriver], 0, sizeof(sai_transfer_t));
|
||||
saiHandle->queueDriver = (saiHandle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE;
|
||||
if (saiHandle->callback)
|
||||
{
|
||||
(saiHandle->callback)(privHandle->base, saiHandle, kStatus_SAI_TxIdle, saiHandle->userData);
|
||||
}
|
||||
|
||||
/* If all data finished, just stop the transfer */
|
||||
if (saiHandle->saiQueue[saiHandle->queueDriver].data == NULL)
|
||||
{
|
||||
SAI_TransferAbortSendEDMA(privHandle->base, saiHandle);
|
||||
}
|
||||
}
|
||||
|
||||
static void SAI_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds)
|
||||
{
|
||||
sai_edma_private_handle_t *privHandle = (sai_edma_private_handle_t *)userData;
|
||||
sai_edma_handle_t *saiHandle = privHandle->handle;
|
||||
|
||||
/* If finished a blcok, call the callback function */
|
||||
memset(&saiHandle->saiQueue[saiHandle->queueDriver], 0, sizeof(sai_transfer_t));
|
||||
saiHandle->queueDriver = (saiHandle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE;
|
||||
if (saiHandle->callback)
|
||||
{
|
||||
(saiHandle->callback)(privHandle->base, saiHandle, kStatus_SAI_RxIdle, saiHandle->userData);
|
||||
}
|
||||
|
||||
/* If all data finished, just stop the transfer */
|
||||
if (saiHandle->saiQueue[saiHandle->queueDriver].data == NULL)
|
||||
{
|
||||
SAI_TransferAbortReceiveEDMA(privHandle->base, saiHandle);
|
||||
}
|
||||
}
|
||||
|
||||
void SAI_TransferTxCreateHandleEDMA(
|
||||
I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle)
|
||||
{
|
||||
assert(handle && dmaHandle);
|
||||
|
||||
uint32_t instance = SAI_GetInstance(base);
|
||||
|
||||
/* Set sai base to handle */
|
||||
handle->dmaHandle = dmaHandle;
|
||||
handle->callback = callback;
|
||||
handle->userData = userData;
|
||||
|
||||
/* Set SAI state to idle */
|
||||
handle->state = kSAI_Idle;
|
||||
|
||||
s_edmaPrivateHandle[instance][0].base = base;
|
||||
s_edmaPrivateHandle[instance][0].handle = handle;
|
||||
|
||||
/* Need to use scatter gather */
|
||||
EDMA_InstallTCDMemory(dmaHandle, STCD_ADDR(handle->tcd), SAI_XFER_QUEUE_SIZE);
|
||||
|
||||
/* Install callback for Tx dma channel */
|
||||
EDMA_SetCallback(dmaHandle, SAI_TxEDMACallback, &s_edmaPrivateHandle[instance][0]);
|
||||
}
|
||||
|
||||
void SAI_TransferRxCreateHandleEDMA(
|
||||
I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle)
|
||||
{
|
||||
assert(handle && dmaHandle);
|
||||
|
||||
uint32_t instance = SAI_GetInstance(base);
|
||||
|
||||
/* Set sai base to handle */
|
||||
handle->dmaHandle = dmaHandle;
|
||||
handle->callback = callback;
|
||||
handle->userData = userData;
|
||||
|
||||
/* Set SAI state to idle */
|
||||
handle->state = kSAI_Idle;
|
||||
|
||||
s_edmaPrivateHandle[instance][1].base = base;
|
||||
s_edmaPrivateHandle[instance][1].handle = handle;
|
||||
|
||||
/* Need to use scatter gather */
|
||||
EDMA_InstallTCDMemory(dmaHandle, STCD_ADDR(handle->tcd), SAI_XFER_QUEUE_SIZE);
|
||||
|
||||
/* Install callback for Tx dma channel */
|
||||
EDMA_SetCallback(dmaHandle, SAI_RxEDMACallback, &s_edmaPrivateHandle[instance][1]);
|
||||
}
|
||||
|
||||
void SAI_TransferTxSetFormatEDMA(I2S_Type *base,
|
||||
sai_edma_handle_t *handle,
|
||||
sai_transfer_format_t *format,
|
||||
uint32_t mclkSourceClockHz,
|
||||
uint32_t bclkSourceClockHz)
|
||||
{
|
||||
assert(handle && format);
|
||||
|
||||
/* Configure the audio format to SAI registers */
|
||||
SAI_TxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz);
|
||||
|
||||
/* Get the tranfer size from format, this should be used in EDMA configuration */
|
||||
handle->bytesPerFrame = format->bitWidth / 8U;
|
||||
|
||||
/* Update the data channel SAI used */
|
||||
handle->channel = format->channel;
|
||||
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
|
||||
handle->count = FSL_FEATURE_SAI_FIFO_COUNT - format->watermark;
|
||||
#else
|
||||
handle->count = 1U;
|
||||
#endif /* FSL_FEATURE_SAI_FIFO_COUNT */
|
||||
}
|
||||
|
||||
void SAI_TransferRxSetFormatEDMA(I2S_Type *base,
|
||||
sai_edma_handle_t *handle,
|
||||
sai_transfer_format_t *format,
|
||||
uint32_t mclkSourceClockHz,
|
||||
uint32_t bclkSourceClockHz)
|
||||
{
|
||||
assert(handle && format);
|
||||
|
||||
/* Configure the audio format to SAI registers */
|
||||
SAI_RxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz);
|
||||
|
||||
/* Get the tranfer size from format, this should be used in EDMA configuration */
|
||||
handle->bytesPerFrame = format->bitWidth / 8U;
|
||||
|
||||
/* Update the data channel SAI used */
|
||||
handle->channel = format->channel;
|
||||
|
||||
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
|
||||
handle->count = format->watermark;
|
||||
#else
|
||||
handle->count = 1U;
|
||||
#endif /* FSL_FEATURE_SAI_FIFO_COUNT */
|
||||
}
|
||||
|
||||
status_t SAI_TransferSendEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer)
|
||||
{
|
||||
assert(handle && xfer);
|
||||
|
||||
edma_transfer_config_t config = {0};
|
||||
uint32_t destAddr = SAI_TxGetDataRegisterAddress(base, handle->channel);
|
||||
|
||||
/* Check if input parameter invalid */
|
||||
if ((xfer->data == NULL) || (xfer->dataSize == 0U))
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
if (handle->saiQueue[handle->queueUser].data)
|
||||
{
|
||||
return kStatus_SAI_QueueFull;
|
||||
}
|
||||
|
||||
/* Change the state of handle */
|
||||
handle->state = kSAI_Busy;
|
||||
|
||||
/* Update the queue state */
|
||||
handle->transferSize[handle->queueUser] = xfer->dataSize;
|
||||
handle->saiQueue[handle->queueUser].data = xfer->data;
|
||||
handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize;
|
||||
handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE;
|
||||
|
||||
/* Prepare edma configure */
|
||||
EDMA_PrepareTransfer(&config, xfer->data, handle->bytesPerFrame, (void *)destAddr, handle->bytesPerFrame,
|
||||
handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_MemoryToPeripheral);
|
||||
|
||||
EDMA_SubmitTransfer(handle->dmaHandle, &config);
|
||||
|
||||
/* Start DMA transfer */
|
||||
EDMA_StartTransfer(handle->dmaHandle);
|
||||
|
||||
/* Enable DMA enable bit */
|
||||
SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, true);
|
||||
|
||||
/* Enable SAI Tx clock */
|
||||
SAI_TxEnable(base, true);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t SAI_TransferReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer)
|
||||
{
|
||||
assert(handle && xfer);
|
||||
|
||||
edma_transfer_config_t config = {0};
|
||||
uint32_t srcAddr = SAI_RxGetDataRegisterAddress(base, handle->channel);
|
||||
|
||||
/* Check if input parameter invalid */
|
||||
if ((xfer->data == NULL) || (xfer->dataSize == 0U))
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
if (handle->saiQueue[handle->queueUser].data)
|
||||
{
|
||||
return kStatus_SAI_QueueFull;
|
||||
}
|
||||
|
||||
/* Change the state of handle */
|
||||
handle->state = kSAI_Busy;
|
||||
|
||||
/* Update queue state */
|
||||
handle->transferSize[handle->queueUser] = xfer->dataSize;
|
||||
handle->saiQueue[handle->queueUser].data = xfer->data;
|
||||
handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize;
|
||||
handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE;
|
||||
|
||||
/* Prepare edma configure */
|
||||
EDMA_PrepareTransfer(&config, (void *)srcAddr, handle->bytesPerFrame, xfer->data, handle->bytesPerFrame,
|
||||
handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_PeripheralToMemory);
|
||||
|
||||
EDMA_SubmitTransfer(handle->dmaHandle, &config);
|
||||
|
||||
/* Start DMA transfer */
|
||||
EDMA_StartTransfer(handle->dmaHandle);
|
||||
|
||||
/* Enable DMA enable bit */
|
||||
SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, true);
|
||||
|
||||
/* Enable SAI Rx clock */
|
||||
SAI_RxEnable(base, true);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
void SAI_TransferAbortSendEDMA(I2S_Type *base, sai_edma_handle_t *handle)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
/* Disable dma */
|
||||
EDMA_AbortTransfer(handle->dmaHandle);
|
||||
|
||||
/* Disable DMA enable bit */
|
||||
SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, false);
|
||||
|
||||
/* Set the handle state */
|
||||
handle->state = kSAI_Idle;
|
||||
}
|
||||
|
||||
void SAI_TransferAbortReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
/* Disable dma */
|
||||
EDMA_AbortTransfer(handle->dmaHandle);
|
||||
|
||||
/* Disable DMA enable bit */
|
||||
SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, false);
|
||||
|
||||
/* Set the handle state */
|
||||
handle->state = kSAI_Idle;
|
||||
}
|
||||
|
||||
status_t SAI_TransferGetSendCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
status_t status = kStatus_Success;
|
||||
|
||||
if (handle->state != kSAI_Busy)
|
||||
{
|
||||
status = kStatus_NoTransferInProgress;
|
||||
}
|
||||
else
|
||||
{
|
||||
*count = (handle->transferSize[handle->queueDriver] -
|
||||
EDMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel));
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t SAI_TransferGetReceiveCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
status_t status = kStatus_Success;
|
||||
|
||||
if (handle->state != kSAI_Busy)
|
||||
{
|
||||
status = kStatus_NoTransferInProgress;
|
||||
}
|
||||
else
|
||||
{
|
||||
*count = (handle->transferSize[handle->queueDriver] -
|
||||
EDMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel));
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _FSL_SAI_EDMA_H_
|
||||
#define _FSL_SAI_EDMA_H_
|
||||
|
||||
#include "fsl_sai.h"
|
||||
#include "fsl_edma.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup sai_edma
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
typedef struct _sai_edma_handle sai_edma_handle_t;
|
||||
|
||||
/*! @brief SAI eDMA transfer callback function for finish and error */
|
||||
typedef void (*sai_edma_callback_t)(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData);
|
||||
|
||||
/*! @brief SAI DMA transfer handle, users should not touch the content of the handle.*/
|
||||
struct _sai_edma_handle
|
||||
{
|
||||
edma_handle_t *dmaHandle; /*!< DMA handler for SAI send */
|
||||
uint8_t bytesPerFrame; /*!< Bytes in a frame */
|
||||
uint8_t channel; /*!< Which data channel */
|
||||
uint8_t count; /*!< The transfer data count in a DMA request */
|
||||
uint32_t state; /*!< Internal state for SAI eDMA transfer */
|
||||
sai_edma_callback_t callback; /*!< Callback for users while transfer finish or error occurs */
|
||||
void *userData; /*!< User callback parameter */
|
||||
edma_tcd_t tcd[SAI_XFER_QUEUE_SIZE + 1U]; /*!< TCD pool for eDMA 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 */
|
||||
volatile uint8_t queueUser; /*!< Index for user to queue transfer. */
|
||||
volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* APIs
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name eDMA Transactional
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the SAI eDMA handle.
|
||||
*
|
||||
* This function initializes the SAI master DMA handle, which can be used for other SAI master transactional APIs.
|
||||
* Usually, for a specified SAI instance, call this API once to get the initialized handle.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle SAI eDMA handle pointer.
|
||||
* @param base SAI peripheral base address.
|
||||
* @param callback Pointer to user callback function.
|
||||
* @param userData User parameter passed to the callback function.
|
||||
* @param dmaHandle eDMA handle pointer, this handle shall be static allocated by users.
|
||||
*/
|
||||
void SAI_TransferTxCreateHandleEDMA(
|
||||
I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the SAI Rx eDMA handle.
|
||||
*
|
||||
* This function initializes the SAI slave DMA handle, which can be used for other SAI master transactional APIs.
|
||||
* Usually, for a specified SAI instance, call this API once to get the initialized handle.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle SAI eDMA handle pointer.
|
||||
* @param base SAI peripheral base address.
|
||||
* @param callback Pointer to user callback function.
|
||||
* @param userData User parameter passed to the callback function.
|
||||
* @param dmaHandle eDMA handle pointer, this handle shall be static allocated by users.
|
||||
*/
|
||||
void SAI_TransferRxCreateHandleEDMA(
|
||||
I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle);
|
||||
|
||||
/*!
|
||||
* @brief Configures the SAI Tx audio format.
|
||||
*
|
||||
* The audio format can be changed at run-time. This function configures the sample rate and audio data
|
||||
* format to be transferred. This function also sets the eDMA parameter according to formatting requirements.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle SAI eDMA handle pointer.
|
||||
* @param format Pointer to SAI audio data format structure.
|
||||
* @param mclkSourceClockHz SAI master clock source frequency in Hz.
|
||||
* @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master
|
||||
* clock, this value should equals to masterClockHz in format.
|
||||
* @retval kStatus_Success Audio format set successfully.
|
||||
* @retval kStatus_InvalidArgument The input argument is invalid.
|
||||
*/
|
||||
void SAI_TransferTxSetFormatEDMA(I2S_Type *base,
|
||||
sai_edma_handle_t *handle,
|
||||
sai_transfer_format_t *format,
|
||||
uint32_t mclkSourceClockHz,
|
||||
uint32_t bclkSourceClockHz);
|
||||
|
||||
/*!
|
||||
* @brief Configures the SAI Rx audio format.
|
||||
*
|
||||
* The audio format can be changed at run-time. This function configures the sample rate and audio data
|
||||
* format to be transferred. This function also sets the eDMA parameter according to formatting requirements.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle SAI eDMA handle pointer.
|
||||
* @param format Pointer to SAI audio data format structure.
|
||||
* @param mclkSourceClockHz SAI master clock source frequency in Hz.
|
||||
* @param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is the master
|
||||
* clock, this value should equal to masterClockHz in format.
|
||||
* @retval kStatus_Success Audio format set successfully.
|
||||
* @retval kStatus_InvalidArgument The input argument is invalid.
|
||||
*/
|
||||
void SAI_TransferRxSetFormatEDMA(I2S_Type *base,
|
||||
sai_edma_handle_t *handle,
|
||||
sai_transfer_format_t *format,
|
||||
uint32_t mclkSourceClockHz,
|
||||
uint32_t bclkSourceClockHz);
|
||||
|
||||
/*!
|
||||
* @brief Performs a non-blocking SAI transfer using DMA.
|
||||
*
|
||||
* @note This interface returns immediately after the transfer initiates. Call
|
||||
* SAI_GetTransferStatus to poll the transfer status and check whether the SAI transfer is finished.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle SAI eDMA handle pointer.
|
||||
* @param xfer Pointer to the DMA transfer structure.
|
||||
* @retval kStatus_Success Start a SAI eDMA send successfully.
|
||||
* @retval kStatus_InvalidArgument The input argument is invalid.
|
||||
* @retval kStatus_TxBusy SAI is busy sending data.
|
||||
*/
|
||||
status_t SAI_TransferSendEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Performs a non-blocking SAI receive using eDMA.
|
||||
*
|
||||
* @note This interface returns immediately after the transfer initiates. Call
|
||||
* the SAI_GetReceiveRemainingBytes to poll the transfer status and check whether the SAI transfer is finished.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param handle SAI eDMA handle pointer.
|
||||
* @param xfer Pointer to DMA transfer structure.
|
||||
* @retval kStatus_Success Start a SAI eDMA receive successfully.
|
||||
* @retval kStatus_InvalidArgument The input argument is invalid.
|
||||
* @retval kStatus_RxBusy SAI is busy receiving data.
|
||||
*/
|
||||
status_t SAI_TransferReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Aborts a SAI transfer using eDMA.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle SAI eDMA handle pointer.
|
||||
*/
|
||||
void SAI_TransferAbortSendEDMA(I2S_Type *base, sai_edma_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Aborts a SAI receive using eDMA.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param handle SAI eDMA handle pointer.
|
||||
*/
|
||||
void SAI_TransferAbortReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Gets byte count sent by SAI.
|
||||
*
|
||||
* @param base SAI base pointer.
|
||||
* @param handle SAI eDMA handle pointer.
|
||||
* @param count Bytes count sent by SAI.
|
||||
* @retval kStatus_Success Succeed get the transfer count.
|
||||
* @retval kStatus_NoTransferInProgress There is no non-blocking transaction in progress.
|
||||
*/
|
||||
status_t SAI_TransferGetSendCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count);
|
||||
|
||||
/*!
|
||||
* @brief Gets byte count received by SAI.
|
||||
*
|
||||
* @param base SAI base pointer
|
||||
* @param handle SAI eDMA handle pointer.
|
||||
* @param count Bytes count received by SAI.
|
||||
* @retval kStatus_Success Succeed get the transfer count.
|
||||
* @retval kStatus_NoTransferInProgress There is no non-blocking transaction in progress.
|
||||
*/
|
||||
status_t SAI_TransferGetReceiveCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count);
|
||||
|
||||
/*! @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_sim.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Codes
|
||||
******************************************************************************/
|
||||
#if (defined(FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) && FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR)
|
||||
void SIM_SetUsbVoltRegulatorEnableMode(uint32_t mask)
|
||||
{
|
||||
SIM->SOPT1CFG |= (SIM_SOPT1CFG_URWE_MASK | SIM_SOPT1CFG_UVSWE_MASK | SIM_SOPT1CFG_USSWE_MASK);
|
||||
|
||||
SIM->SOPT1 = (SIM->SOPT1 & ~kSIM_UsbVoltRegEnableInAllModes) | mask;
|
||||
}
|
||||
#endif /* FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR */
|
||||
|
||||
void SIM_GetUniqueId(sim_uid_t *uid)
|
||||
{
|
||||
#if defined(SIM_UIDH)
|
||||
uid->H = SIM->UIDH;
|
||||
#endif
|
||||
uid->MH = SIM->UIDMH;
|
||||
uid->ML = SIM->UIDML;
|
||||
uid->L = SIM->UIDL;
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FSL_SIM_H_
|
||||
#define _FSL_SIM_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*! @addtogroup sim */
|
||||
/*! @{*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
*******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
#define FSL_SIM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Driver version 2.0.0 */
|
||||
/*@}*/
|
||||
|
||||
#if (defined(FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) && FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR)
|
||||
/*!@brief USB voltage regulator enable setting. */
|
||||
enum _sim_usb_volt_reg_enable_mode
|
||||
{
|
||||
kSIM_UsbVoltRegEnable = SIM_SOPT1_USBREGEN_MASK, /*!< Enable voltage regulator. */
|
||||
kSIM_UsbVoltRegEnableInLowPower = SIM_SOPT1_USBVSTBY_MASK, /*!< Enable voltage regulator in VLPR/VLPW modes. */
|
||||
kSIM_UsbVoltRegEnableInStop = SIM_SOPT1_USBSSTBY_MASK, /*!< Enable voltage regulator in STOP/VLPS/LLS/VLLS modes. */
|
||||
kSIM_UsbVoltRegEnableInAllModes = SIM_SOPT1_USBREGEN_MASK | SIM_SOPT1_USBSSTBY_MASK |
|
||||
SIM_SOPT1_USBVSTBY_MASK /*!< Enable voltage regulator in all power modes. */
|
||||
};
|
||||
#endif /* (defined(FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) && FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) */
|
||||
|
||||
/*!@brief Unique ID. */
|
||||
typedef struct _sim_uid
|
||||
{
|
||||
#if defined(SIM_UIDH)
|
||||
uint32_t H; /*!< UIDH. */
|
||||
#endif
|
||||
uint32_t MH; /*!< UIDMH. */
|
||||
uint32_t ML; /*!< UIDML. */
|
||||
uint32_t L; /*!< UIDL. */
|
||||
} sim_uid_t;
|
||||
|
||||
/*!@brief Flash enable mode. */
|
||||
enum _sim_flash_mode
|
||||
{
|
||||
kSIM_FlashDisableInWait = SIM_FCFG1_FLASHDOZE_MASK, /*!< Disable flash in wait mode. */
|
||||
kSIM_FlashDisable = SIM_FCFG1_FLASHDIS_MASK /*!< Disable flash in normal mode. */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
#if (defined(FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) && FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR)
|
||||
/*!
|
||||
* @brief Sets the USB voltage regulator setting.
|
||||
*
|
||||
* This function configures whether the USB voltage regulator is enabled in
|
||||
* normal RUN mode, STOP/VLPS/LLS/VLLS modes and VLPR/VLPW modes. The configurations
|
||||
* are passed in as mask value of \ref _sim_usb_volt_reg_enable_mode. For example, enable
|
||||
* USB voltage regulator in RUN/VLPR/VLPW modes and disable in STOP/VLPS/LLS/VLLS mode,
|
||||
* please use:
|
||||
*
|
||||
* SIM_SetUsbVoltRegulatorEnableMode(kSIM_UsbVoltRegEnable | kSIM_UsbVoltRegEnableInLowPower);
|
||||
*
|
||||
* @param mask USB voltage regulator enable setting.
|
||||
*/
|
||||
void SIM_SetUsbVoltRegulatorEnableMode(uint32_t mask);
|
||||
#endif /* FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR */
|
||||
|
||||
/*!
|
||||
* @brief Get the unique identification register value.
|
||||
*
|
||||
* @param uid Pointer to the structure to save the UID value.
|
||||
*/
|
||||
void SIM_GetUniqueId(sim_uid_t *uid);
|
||||
|
||||
/*!
|
||||
* @brief Set the flash enable mode.
|
||||
*
|
||||
* @param mode The mode to set, see \ref _sim_flash_mode for mode details.
|
||||
*/
|
||||
static inline void SIM_SetFlashMode(uint8_t mode)
|
||||
{
|
||||
SIM->FCFG1 = mode;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_SIM_H_ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue