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
Mahadevan Mahesh-R9AADQ 2016-03-11 18:44:43 -06:00 committed by Mahadevan Mahesh
parent acb896b3cb
commit 2c9c632aad
129 changed files with 66807 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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")
}

View File

@ -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

View File

@ -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 };

View File

@ -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

View File

@ -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

View File

@ -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];
}

View File

@ -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

View File

@ -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
******************************************************************************/

View File

@ -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)));
}

View File

@ -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_ */

View File

@ -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

View File

@ -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}
};

View File

@ -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

View File

@ -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() */

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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
}

View File

@ -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

View File

@ -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}
};

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_*/

View File

@ -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();
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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. */
}

View File

@ -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_ */

View File

@ -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)]);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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 */
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_*/

View File

@ -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 */

View File

@ -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

View File

@ -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_*/

View File

@ -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;
}

View File

@ -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_*/

View File

@ -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 */

View File

@ -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_*/

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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

View File

@ -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_*/

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_*/

View File

@ -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 */

View File

@ -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

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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