Freescale: Remove KL27Z files

Mbed OS 6 does not support the KL27Z target
pull/13950/head
Hugues Kamba 2020-11-23 17:02:03 +00:00
parent f2278567d0
commit 6a6864b6df
98 changed files with 0 additions and 46495 deletions

View File

@ -1,100 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
OSC32KCLK = 0,
} RTCName;
/* LPUART */
typedef enum {
LPUART_0 = 0,
LPUART_1 = 1,
} UARTName;
#define STDIO_UART_TX USBTX
#define STDIO_UART_RX USBRX
#define STDIO_UART LPUART_0
typedef enum {
I2C_0 = 0,
I2C_1 = 1,
} I2CName;
#define TPM_SHIFT 8
typedef enum {
PWM_1 = (0 << TPM_SHIFT) | (0), // TPM0 CH0
PWM_2 = (0 << TPM_SHIFT) | (1), // TPM0 CH1
PWM_3 = (0 << TPM_SHIFT) | (2), // TPM0 CH2
PWM_4 = (0 << TPM_SHIFT) | (3), // TPM0 CH3
PWM_5 = (0 << TPM_SHIFT) | (4), // TPM0 CH4
PWM_6 = (0 << TPM_SHIFT) | (5), // TPM0 CH5
PWM_7 = (1 << TPM_SHIFT) | (0), // TPM1 CH0
PWM_8 = (1 << TPM_SHIFT) | (1) // TPM1 CH1
} PWMName;
#define ADC_INSTANCE_SHIFT 8
#define ADC_B_CHANNEL_SHIFT 5
typedef enum {
ADC0_SE0 = (0 << ADC_INSTANCE_SHIFT) | 0,
ADC0_SE1 = (0 << ADC_INSTANCE_SHIFT) | 1,
ADC0_SE2 = (0 << ADC_INSTANCE_SHIFT) | 2,
ADC0_SE3 = (0 << ADC_INSTANCE_SHIFT) | 3,
ADC0_SE4a = (0 << ADC_INSTANCE_SHIFT) | 4,
ADC0_SE5a = (0 << ADC_INSTANCE_SHIFT) | 5,
ADC0_SE6a = (0 << ADC_INSTANCE_SHIFT) | 6,
ADC0_SE7a = (0 << ADC_INSTANCE_SHIFT) | 7,
ADC0_SE4b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 4,
ADC0_SE5b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 5,
ADC0_SE6b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 6,
ADC0_SE7b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 7,
ADC0_SE8 = (0 << ADC_INSTANCE_SHIFT) | 8,
ADC0_SE9 = (0 << ADC_INSTANCE_SHIFT) | 9,
ADC0_SE11 = (0 << ADC_INSTANCE_SHIFT) | 11,
ADC0_SE12 = (0 << ADC_INSTANCE_SHIFT) | 12,
ADC0_SE13 = (0 << ADC_INSTANCE_SHIFT) | 13,
ADC0_SE14 = (0 << ADC_INSTANCE_SHIFT) | 14,
ADC0_SE15 = (0 << ADC_INSTANCE_SHIFT) | 15,
ADC0_SE16 = (0 << ADC_INSTANCE_SHIFT) | 16,
ADC0_SE17 = (0 << ADC_INSTANCE_SHIFT) | 17,
ADC0_SE18 = (0 << ADC_INSTANCE_SHIFT) | 18,
ADC0_SE21 = (0 << ADC_INSTANCE_SHIFT) | 21,
ADC0_SE22 = (0 << ADC_INSTANCE_SHIFT) | 22,
ADC0_SE23 = (0 << ADC_INSTANCE_SHIFT) | 23,
} ADCName;
typedef enum {
SPI_0 = 0,
SPI_1 = 1,
} SPIName;
typedef enum {
DAC = 0,
} DACName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,186 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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[] = {
{PTE17, ADC0_SE5a, 0},
{PTE18, ADC0_SE2, 0},
{PTE16, ADC0_SE1, 0},
{PTE20, ADC0_SE0, 0},
{PTE21, ADC0_SE4a, 0},
{PTE22, ADC0_SE3, 0},
{PTE23, ADC0_SE7a, 0},
{PTE29, ADC0_SE4b, 0},
{PTE30, ADC0_SE23, 0},
{PTB0 , ADC0_SE8 , 0},
{PTB1 , ADC0_SE9 , 0},
{PTB2 , ADC0_SE12, 0},
{PTB3 , ADC0_SE13, 0},
{PTC0 , ADC0_SE14, 0},
{PTC1 , ADC0_SE15, 0},
{PTC2, ADC0_SE11, 0},
{PTD1, ADC0_SE5b, 0},
{PTD5, ADC0_SE6b, 0},
//{PTD6, ADC0_SE7b, 0},
{NC , NC , 0}
};
/************I2C***************/
const PinMap PinMap_I2C_SDA[] = {
{PTE18 , I2C_0 , 4},
{PTE25 , I2C_0 , 5},
{PTB1 , I2C_0 , 2},
{PTB3 , I2C_0 , 2},
{PTC9 , I2C_0 , 2},
{PTE0 , I2C_1 , 6},
{PTA4 , I2C_1 , 2},
{PTC2 , I2C_1 , 2},
{PTC11 , I2C_1 , 2},
{PTD6 , I2C_1 , 4},
{NC , NC , 0}
};
const PinMap PinMap_I2C_SCL[] = {
{PTE24 , I2C_0 , 5},
{PTB0 , I2C_0 , 2},
{PTB2 , I2C_0 , 2},
{PTC8 , I2C_0 , 2},
{PTE1 , I2C_1 , 6},
{PTA3 , I2C_1 , 2},
{PTC1 , I2C_1 , 2},
{PTC10 , I2C_1 , 2},
{PTD7 , I2C_1 , 4},
{NC , NC , 0}
};
/************LPUART***************/
const PinMap PinMap_UART_TX[] = {
{PTE20 , LPUART_0 , 4},
{PTA2 , LPUART_0 , 2},
{PTB17 , LPUART_0 , 3},
{PTD7 , LPUART_0 , 3},
{PTE0 , LPUART_1 , 3},
{PTE30 , LPUART_1 , 5},
{PTA19 , LPUART_1 , 3},
{PTC4 , LPUART_1 , 3},
{NC , NC , 0}
};
const PinMap PinMap_UART_RX[] = {
{PTE21 , LPUART_0, 4},
{PTA1 , LPUART_0, 2},
{PTB16 , LPUART_0, 3},
{PTD6 , LPUART_0, 3},
{PTE1 , LPUART_1, 3},
{PTA18 , LPUART_1, 3},
{PTC3 , LPUART_1, 3},
{NC , NC , 0}
};
/************SPI***************/
const PinMap PinMap_SPI_SCLK[] = {
{PTE17 , SPI_0, 2},
{PTC5 , SPI_0, 2},
{PTD1 , SPI_0, 2},
{PTC3 , SPI_1, 2},
{PTD5 , SPI_1, 2},
{NC , NC , 0}
};
const PinMap PinMap_SPI_MOSI[] = {
{PTE18 , SPI_0, 2},
{PTC6 , SPI_0, 2},
{PTC7 , SPI_0, 5},
{PTD2 , SPI_0, 2},
{PTD3 , SPI_0, 5},
{PTE1 , SPI_1, 2},
{PTB0 , SPI_1, 4},
{PTB1 , SPI_1, 5},
{PTB16 , SPI_1, 2},
{PTB17 , SPI_1, 5},
{PTD6 , SPI_1, 2},
{PTD7 , SPI_1, 5},
{NC , NC , 0}
};
const PinMap PinMap_SPI_MISO[] = {
{PTE18 , SPI_0, 5},
{PTC6 , SPI_0, 5},
{PTC7 , SPI_0, 2},
{PTD2 , SPI_0, 5},
{PTD3 , SPI_0, 2},
{PTE0 , SPI_1, 2},
{PTE1 , SPI_1, 5},
{PTB0 , SPI_1, 5},
{PTB1 , SPI_1, 4},
{PTB16 , SPI_1, 5},
{PTB17 , SPI_1, 2},
{PTD6 , SPI_1, 5},
{PTD7 , SPI_1, 2},
{NC , NC , 0}
};
const PinMap PinMap_SPI_SSEL[] = {
{PTE16 , SPI_0, 2},
{PTC4 , SPI_0, 2},
{PTD0 , SPI_0, 2},
{PTC4 , SPI_1, 5},
{PTD4 , SPI_1, 2},
{NC , NC , 0}
};
/************PWM***************/
const PinMap PinMap_PWM[] = {
{PTE29, PWM_3 , 3},
{PTE30, PWM_4 , 3},
{PTE31, PWM_5 , 3},
{PTE24, PWM_1 , 3},
{PTE25, PWM_2 , 3},
{PTA0 , PWM_6 , 3},
{PTA3 , PWM_1 , 3},
{PTA4 , PWM_2 , 3},
{PTA5 , PWM_3 , 3},
{PTC1 , PWM_1 , 4},
{PTC2 , PWM_2 , 4},
{PTC3 , PWM_3 , 4},
{PTC4 , PWM_4 , 4},
{PTC8 , PWM_5 , 3},
{PTC9 , PWM_6 , 3},
{PTD0 , PWM_1 , 4},
{PTD1 , PWM_2 , 4},
{PTD2 , PWM_3 , 4},
{PTD3 , PWM_4 , 4},
{PTD4 , PWM_5 , 4},
{PTD5 , PWM_6 , 4},
{PTE20, PWM_7 , 3},
{PTE21, PWM_8 , 3},
{PTA12, PWM_7 , 3},
{PTA13, PWM_8 , 3},
{PTB0, PWM_7 , 3},
{PTB1, PWM_8 , 3},
{NC , NC , 0}
};

View File

@ -1,155 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PINNAMES_H
#define MBED_PINNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PIN_INPUT,
PIN_OUTPUT
} PinDirection;
#define GPIO_PORT_SHIFT 12
typedef enum {
PTA0 = (0 << GPIO_PORT_SHIFT | 0 ),
PTA1 = (0 << GPIO_PORT_SHIFT | 1 ),
PTA2 = (0 << GPIO_PORT_SHIFT | 2 ),
PTA3 = (0 << GPIO_PORT_SHIFT | 3 ),
PTA4 = (0 << GPIO_PORT_SHIFT | 4 ),
PTA5 = (0 << GPIO_PORT_SHIFT | 5 ),
PTA12 = (0 << GPIO_PORT_SHIFT | 12),
PTA13 = (0 << GPIO_PORT_SHIFT | 13),
PTA18 = (0 << GPIO_PORT_SHIFT | 18),
PTA19 = (0 << GPIO_PORT_SHIFT | 19),
PTA20 = (0 << GPIO_PORT_SHIFT | 20),
PTB0 = (1 << GPIO_PORT_SHIFT | 0 ),
PTB1 = (1 << GPIO_PORT_SHIFT | 1 ),
PTB2 = (1 << GPIO_PORT_SHIFT | 2 ),
PTB3 = (1 << GPIO_PORT_SHIFT | 3 ),
PTB16 = (1 << GPIO_PORT_SHIFT | 16),
PTB17 = (1 << GPIO_PORT_SHIFT | 17),
PTB18 = (1 << GPIO_PORT_SHIFT | 18),
PTB19 = (1 << GPIO_PORT_SHIFT | 19),
PTC0 = (2 << GPIO_PORT_SHIFT | 0 ),
PTC1 = (2 << GPIO_PORT_SHIFT | 1 ),
PTC2 = (2 << GPIO_PORT_SHIFT | 2 ),
PTC3 = (2 << GPIO_PORT_SHIFT | 3 ),
PTC4 = (2 << GPIO_PORT_SHIFT | 4 ),
PTC5 = (2 << GPIO_PORT_SHIFT | 5 ),
PTC6 = (2 << GPIO_PORT_SHIFT | 6 ),
PTC7 = (2 << GPIO_PORT_SHIFT | 7 ),
PTC8 = (2 << GPIO_PORT_SHIFT | 8 ),
PTC9 = (2 << GPIO_PORT_SHIFT | 9 ),
PTC10 = (2 << GPIO_PORT_SHIFT | 10),
PTC11 = (2 << GPIO_PORT_SHIFT | 11),
PTD0 = (3 << GPIO_PORT_SHIFT | 0 ),
PTD1 = (3 << GPIO_PORT_SHIFT | 1 ),
PTD2 = (3 << GPIO_PORT_SHIFT | 2 ),
PTD3 = (3 << GPIO_PORT_SHIFT | 3 ),
PTD4 = (3 << GPIO_PORT_SHIFT | 4 ),
PTD5 = (3 << GPIO_PORT_SHIFT | 5 ),
PTD6 = (3 << GPIO_PORT_SHIFT | 6 ),
PTD7 = (3 << GPIO_PORT_SHIFT | 7 ),
PTE0 = (4 << GPIO_PORT_SHIFT | 0 ),
PTE1 = (4 << GPIO_PORT_SHIFT | 1 ),
PTE16 = (4 << GPIO_PORT_SHIFT | 16),
PTE17 = (4 << GPIO_PORT_SHIFT | 17),
PTE18 = (4 << GPIO_PORT_SHIFT | 18),
PTE19 = (4 << GPIO_PORT_SHIFT | 19),
PTE20 = (4 << GPIO_PORT_SHIFT | 20),
PTE21 = (4 << GPIO_PORT_SHIFT | 21),
PTE22 = (4 << GPIO_PORT_SHIFT | 22),
PTE23 = (4 << GPIO_PORT_SHIFT | 23),
PTE24 = (4 << GPIO_PORT_SHIFT | 24),
PTE25 = (4 << GPIO_PORT_SHIFT | 25),
PTE29 = (4 << GPIO_PORT_SHIFT | 29),
PTE30 = (4 << GPIO_PORT_SHIFT | 30),
PTE31 = (4 << GPIO_PORT_SHIFT | 31),
LED_RED = PTB18,
LED_GREEN = PTB19,
LED_BLUE = PTA13,
// mbed original LED naming
LED1 = LED_RED,
LED2 = LED_GREEN,
LED3 = LED_BLUE,
LED4 = LED_RED,
//Push buttons
SW1 = PTA4,
SW3 = PTC1,
// Standardized button names
BUTTON1 = SW1,
BUTTON2 = SW3,
// USB Pins
USBTX = PTA2,
USBRX = PTA1,
// Arduino Headers
D0 = PTA1,
D1 = PTA2,
D2 = PTA12,
D3 = PTE25,
D4 = PTA13,
D5 = PTE24,
D6 = PTC9,
D7 = PTC8,
D8 = PTE31,
D9 = PTA5,
D10 = PTC4,
D11 = PTC6,
D12 = PTC7,
D13 = PTC5,
D14 = PTD6,
D15 = PTD7,
I2C_SCL = D15,
I2C_SDA = D14,
A0 = PTE16,
A1 = PTC0,
A2 = PTE20,
A3 = PTE21,
A4 = PTB1,
A5 = PTB0,
// Not connected
NC = (int)0xFFFFFFFF
} PinName;
typedef enum {
PullNone = 0,
PullDown = 1,
PullUp = 2,
PullDefault = PullUp
} PinMode;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,40 +0,0 @@
// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches.
// Check the 'features' section of the target description in 'targets.json' for more details.
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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_ID_LENGTH 24
#include "objects.h"
#endif

View File

@ -1,149 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_common.h"
#include "fsl_smc.h"
#include "fsl_clock_config.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Clock configuration structure. */
typedef struct _clock_config
{
mcglite_config_t mcgliteConfig; /*!< MCG configuration. */
sim_clock_config_t simConfig; /*!< SIM configuration. */
osc_config_t oscConfig; /*!< OSC configuration. */
uint32_t coreClock; /*!< core clock frequency. */
} clock_config_t;
/*******************************************************************************
* Variables
******************************************************************************/
/* System clock frequency. */
extern uint32_t SystemCoreClock;
/* Configuration for enter VLPR mode. Core clock = 2MHz. */
const clock_config_t g_defaultClockConfigVlpr = {
.mcgliteConfig =
{
.outSrc = kMCGLITE_ClkSrcLirc,
.irclkEnableMode = kMCGLITE_IrclkEnable,
.ircs = kMCGLITE_Lirc2M,
.fcrdiv = kMCGLITE_LircDivBy1,
.lircDiv2 = kMCGLITE_LircDivBy1,
.hircEnableInNotHircMode = false,
},
.simConfig =
{
.clkdiv1 = 0x00010000U, /* SIM_CLKDIV1. */
},
.oscConfig = {.freq = BOARD_XTAL0_CLK_HZ,
.capLoad = 0U,
.workMode = kOSC_ModeOscLowPower,
.oscerConfig =
{
.enableMode = kOSC_ErClkEnable,
#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER)
.erclkDiv = 0U,
#endif
}},
.coreClock = 2000000U, /* Core clock frequency */
};
/* Configuration for enter RUN mode. Core clock = 48000000Hz. */
const clock_config_t g_defaultClockConfigRun = {
.mcgliteConfig =
{
.outSrc = kMCGLITE_ClkSrcHirc,
.irclkEnableMode = kMCGLITE_IrclkEnable,
.ircs = kMCGLITE_Lirc8M,
.fcrdiv = kMCGLITE_LircDivBy1,
.lircDiv2 = kMCGLITE_LircDivBy1,
.hircEnableInNotHircMode = true,
},
.simConfig =
{
.clkdiv1 = 0x00010000U, /* SIM_CLKDIV1. */
},
.oscConfig = {.freq = BOARD_XTAL0_CLK_HZ,
.capLoad = 0U,
.workMode = kOSC_ModeOscLowPower,
.oscerConfig =
{
.enableMode = kOSC_ErClkEnable,
#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER)
.erclkDiv = 0U,
#endif
}},
.coreClock = 48000000U, /* Core clock frequency */
};
/*******************************************************************************
* Code
******************************************************************************/
/*
* How to setup clock using clock driver functions:
*
* 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock
* and flash clock are in allowed range during clock mode switch.
*
* 2. Call CLOCK_SetMcgliteConfig to set MCG_Lite configuration.
*
* 3. Call CLOCK_SetSimConfig to set the clock configuration in SIM.
*/
void BOARD_BootClockVLPR(void)
{
CLOCK_SetSimSafeDivs();
CLOCK_SetMcgliteConfig(&g_defaultClockConfigVlpr.mcgliteConfig);
CLOCK_SetSimConfig(&g_defaultClockConfigVlpr.simConfig);
SystemCoreClock = g_defaultClockConfigVlpr.coreClock;
SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll);
SMC_SetPowerModeVlpr(SMC);
while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr)
{
}
}
void BOARD_BootClockRUN(void)
{
CLOCK_SetSimSafeDivs();
CLOCK_SetMcgliteConfig(&g_defaultClockConfigRun.mcgliteConfig);
CLOCK_SetSimConfig(&g_defaultClockConfigRun.simConfig);
SystemCoreClock = g_defaultClockConfigRun.coreClock;
}

View File

@ -1,53 +0,0 @@
/*
* 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 32768U
#define BOARD_XTAL32K_CLK_HZ 0U
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
void BOARD_BootClockVLPR(void);
void BOARD_BootClockRUN(void);
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
#endif /* _CLOCK_CONFIG_H_ */

View File

@ -1,67 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 "pinmap.h"
#include "fsl_rtc.h"
#include "fsl_clock_config.h"
// called before main - implement here if board needs it otherwise, let
// the application override this if necessary
void mbed_sdk_init()
{
rtc_config_t rtc_basic_config;
uint32_t u32cTPR_counter = 0;
BOARD_BootClockRUN();
/* Set the TPM clock source to be IRC48M, do not change as TPM2 is used for the usticker */
CLOCK_SetTpmClock(1U);
CLOCK_EnableClock(kCLOCK_Rtc0);
/* Check if the Rtc oscillator is enabled */
if ((RTC->CR & RTC_CR_OSCE_MASK) == 0u) {
/*Init the RTC with default configuration*/
RTC_GetDefaultConfig(&rtc_basic_config);
/* Setup the 32K RTC OSC */
RTC_Init(RTC, &rtc_basic_config);
/* Enable the RTC 32KHz oscillator */
RTC->CR |= RTC_CR_OSCE_MASK;
/* Start the RTC time counter */
RTC_StartTimer(RTC);
/* Verify TPR register reaches 4096 counts */
while (u32cTPR_counter < 4096) {
u32cTPR_counter = RTC->TPR;
}
/* 32kHz Oscillator is ready. */
RTC_Deinit(RTC);
}
CLOCK_DisableClock(kCLOCK_Rtc0);
}
// 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);
}

View File

@ -1,118 +0,0 @@
#! armcc -E
/*
** ###################################################################
** Processors: MKL27Z64VDA4
** MKL27Z64VFM4
** MKL27Z64VFT4
** MKL27Z64VLH4
** MKL27Z64VMP4
**
** Compiler: Keil ARM C/C++ Compiler
** Reference manual: KL27P64M48SF2RM, Rev. 1, Sep 2014
** Version: rev. 1.4, 2014-09-22
** Build: b151009
**
** Abstract:
** Linker file for the Keil ARM C/C++ Compiler
**
** Copyright (c) 2016 Freescale Semiconductor, Inc.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
**
** o Redistributions of source code must retain the above copyright notice, this list
** of conditions and the following disclaimer.
**
** o Redistributions in binary form must reproduce the above copyright notice, this
** list of conditions and the following disclaimer in the documentation and/or
** other materials provided with the distribution.
**
** o Neither the name of Freescale Semiconductor, Inc. nor the names of its
** contributors may be used to endorse or promote products derived from this
** software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** http: www.freescale.com
** mail: support@freescale.com
**
** ###################################################################
*/
#define __ram_vector_table__ 1
#if (defined(__ram_vector_table__))
#define __ram_vector_table_size__ 0x00000200
#else
#define __ram_vector_table_size__ 0x00000000
#endif
#define m_interrupts_start 0x00000000
#define m_interrupts_size 0x00000200
#define m_flash_config_start 0x00000400
#define m_flash_config_size 0x00000010
#define m_text_start 0x00000410
#define m_text_size 0x0000FBF0
#define m_interrupts_ram_start 0x1FFFF000
#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 (0x00004000 - m_interrupts_ram_size)
#if !defined(MBED_CONF_TARGET_BOOT_STACK_SIZE)
# if defined(MBED_BOOT_STACK_SIZE)
# define MBED_CONF_TARGET_BOOT_STACK_SIZE MBED_BOOT_STACK_SIZE
# else
# define MBED_CONF_TARGET_BOOT_STACK_SIZE 0x400
# endif
#endif
/* Sizes */
#if (defined(__stack_size__))
#define Stack_Size __stack_size__
#else
#define Stack_Size MBED_CONF_TARGET_BOOT_STACK_SIZE
#endif
LR_IROM1 m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region
VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address
* (RESET,+FIRST)
}
ER_m_flash_config m_flash_config_start FIXED m_flash_config_size { ; load address = execution address
* (FlashConfig)
}
ER_IROM1 m_text_start m_text_size { ; load address = execution address
* (InRoot$$Sections)
.ANY (+RO)
}
#if (defined(__ram_vector_table__))
VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size {
}
#else
VECTOR_RAM m_interrupts_start EMPTY 0 {
}
#endif
RW_m_data m_data_start m_data_size { ; RW data
.ANY (+RW +ZI)
}
RW_IRAM1 +0 {
}
ARM_LIB_HEAP AlignExpr(+0, 16) EMPTY (m_data_start + m_data_size - Stack_Size - AlignExpr(ImageLimit(RW_IRAM1), 16)) { ; Heap region growing up
}
ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down
}
}

View File

@ -1,445 +0,0 @@
; * ---------------------------------------------------------------------------------------
; * @file: startup_MKL27Z644.s
; * @purpose: CMSIS Cortex-M0P Core Device Startup File
; * MKL27Z644
; * @version: 1.4
; * @date: 2014-9-22
; * @build: b151105
; * ---------------------------------------------------------------------------------------
; *
; * 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.
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
IMPORT |Image$$ARM_LIB_STACK$$ZI$$Limit|
__Vectors DCD |Image$$ARM_LIB_STACK$$ZI$$Limit| ;Top of Stack
DCD Reset_Handler ;Reset Handler
DCD NMI_Handler ;NMI Handler
DCD HardFault_Handler ;Hard Fault Handler
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD SVC_Handler ;SVCall Handler
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD PendSV_Handler ;PendSV Handler
DCD SysTick_Handler ;SysTick Handler
;External Interrupts
DCD DMA0_IRQHandler ;DMA channel 0 transfer complete
DCD DMA1_IRQHandler ;DMA channel 1 transfer complete
DCD DMA2_IRQHandler ;DMA channel 2 transfer complete
DCD DMA3_IRQHandler ;DMA channel 3 transfer complete
DCD Reserved20_IRQHandler ;Reserved interrupt
DCD FTFA_IRQHandler ;Command complete and read collision
DCD PMC_IRQHandler ;Low-voltage detect, low-voltage warning
DCD LLWU_IRQHandler ;Low leakage wakeup
DCD I2C0_IRQHandler ;I2C0 interrupt
DCD I2C1_IRQHandler ;I2C1 interrupt
DCD SPI0_IRQHandler ;SPI0 single interrupt vector for all sources
DCD SPI1_IRQHandler ;SPI1 single interrupt vector for all sources
DCD LPUART0_IRQHandler ;LPUART0 status and error
DCD LPUART1_IRQHandler ;LPUART1 status and error
DCD UART2_FLEXIO_IRQHandler ;UART2 or FLEXIO
DCD ADC0_IRQHandler ;ADC0 interrupt
DCD CMP0_IRQHandler ;CMP0 interrupt
DCD TPM0_IRQHandler ;TPM0 single interrupt vector for all sources
DCD TPM1_IRQHandler ;TPM1 single interrupt vector for all sources
DCD TPM2_IRQHandler ;TPM2 single interrupt vector for all sources
DCD RTC_IRQHandler ;RTC alarm
DCD RTC_Seconds_IRQHandler ;RTC seconds
DCD PIT_IRQHandler ;PIT interrupt
DCD Reserved39_IRQHandler ;Reserved interrupt
DCD USB0_IRQHandler ;USB0 interrupt
DCD Reserved41_IRQHandler ;Reserved interrupt
DCD Reserved42_IRQHandler ;Reserved interrupt
DCD Reserved43_IRQHandler ;Reserved interrupt
DCD LPTMR0_IRQHandler ;LPTMR0 interrupt
DCD Reserved45_IRQHandler ;Reserved interrupt
DCD PORTA_IRQHandler ;PORTA Pin detect
DCD PORTBCDE_IRQHandler ;Single interrupt vector for PORTB,PORTC,PORTD,PORTE
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
; <h> Flash Configuration
; <i> 16-byte flash configuration field that stores default protection settings (loaded on reset)
; <i> and security information that allows the MCU to restrict access to the FTFL module.
; <h> Backdoor Comparison Key
; <o0> Backdoor Comparison Key 0. <0x0-0xFF:2>
; <o1> Backdoor Comparison Key 1. <0x0-0xFF:2>
; <o2> Backdoor Comparison Key 2. <0x0-0xFF:2>
; <o3> Backdoor Comparison Key 3. <0x0-0xFF:2>
; <o4> Backdoor Comparison Key 4. <0x0-0xFF:2>
; <o5> Backdoor Comparison Key 5. <0x0-0xFF:2>
; <o6> Backdoor Comparison Key 6. <0x0-0xFF:2>
; <o7> Backdoor Comparison Key 7. <0x0-0xFF:2>
BackDoorK0 EQU 0xFF
BackDoorK1 EQU 0xFF
BackDoorK2 EQU 0xFF
BackDoorK3 EQU 0xFF
BackDoorK4 EQU 0xFF
BackDoorK5 EQU 0xFF
BackDoorK6 EQU 0xFF
BackDoorK7 EQU 0xFF
; </h>
; <h> Program flash protection bytes (FPROT)
; <i> Each program flash region can be protected from program and erase operation by setting the associated PROT bit.
; <i> Each bit protects a 1/32 region of the program flash memory.
; <h> FPROT0
; <i> Program Flash Region Protect Register 0
; <i> 1/32 - 8/32 region
; <o.0> FPROT0.0
; <o.1> FPROT0.1
; <o.2> FPROT0.2
; <o.3> FPROT0.3
; <o.4> FPROT0.4
; <o.5> FPROT0.5
; <o.6> FPROT0.6
; <o.7> FPROT0.7
nFPROT0 EQU 0x00
FPROT0 EQU nFPROT0:EOR:0xFF
; </h>
; <h> FPROT1
; <i> Program Flash Region Protect Register 1
; <i> 9/32 - 16/32 region
; <o.0> FPROT1.0
; <o.1> FPROT1.1
; <o.2> FPROT1.2
; <o.3> FPROT1.3
; <o.4> FPROT1.4
; <o.5> FPROT1.5
; <o.6> FPROT1.6
; <o.7> FPROT1.7
nFPROT1 EQU 0x00
FPROT1 EQU nFPROT1:EOR:0xFF
; </h>
; <h> FPROT2
; <i> Program Flash Region Protect Register 2
; <i> 17/32 - 24/32 region
; <o.0> FPROT2.0
; <o.1> FPROT2.1
; <o.2> FPROT2.2
; <o.3> FPROT2.3
; <o.4> FPROT2.4
; <o.5> FPROT2.5
; <o.6> FPROT2.6
; <o.7> FPROT2.7
nFPROT2 EQU 0x00
FPROT2 EQU nFPROT2:EOR:0xFF
; </h>
; <h> FPROT3
; <i> Program Flash Region Protect Register 3
; <i> 25/32 - 32/32 region
; <o.0> FPROT3.0
; <o.1> FPROT3.1
; <o.2> FPROT3.2
; <o.3> FPROT3.3
; <o.4> FPROT3.4
; <o.5> FPROT3.5
; <o.6> FPROT3.6
; <o.7> FPROT3.7
nFPROT3 EQU 0x00
FPROT3 EQU nFPROT3:EOR:0xFF
; </h>
; </h>
; <h> Flash nonvolatile option byte (FOPT)
; <i> Allows the user to customize the operation of the MCU at boot time.
; <o.0> LPBOOT0
; <0=> Core and system clock divider (OUTDIV1) is 0x7 (divide by 8) when LPBOOT1=0 or 0x1 (divide by 2) when LPBOOT1=1.
; <1=> Core and system clock divider (OUTDIV1) is 0x3 (divide by 4) when LPBOOT1=0 or 0x0 (divide by 1) when LPBOOT1=1.
; <o.1> BOOTPIN_OPT
; <0=> Force Boot from ROM if BOOTCFG0 asserted, where BOOTCFG0 is the boot config function which is muxed with NMI pin
; <1=> Boot source configured by FOPT (BOOTSRC_SEL) bits
; <o.2> NMI_DIS
; <0=> NMI interrupts are always blocked
; <1=> NMI_b pin/interrupts reset default to enabled
; <o.3> RESET_PIN_CFG
; <0=> RESET pin is disabled following a POR and cannot be enabled as reset function
; <1=> RESET_b pin is dedicated
; <o.4> LPBOOT1
; <0=> Core and system clock divider (OUTDIV1) is 0x7 (divide by 8) when LPBOOT0=0 or 0x3 (divide by 4) when LPBOOT0=1.
; <1=> Core and system clock divider (OUTDIV1) is 0x1 (divide by 2) when LPBOOT0=0 or 0x0 (divide by 1) when LPBOOT0=1.
; <o.5> FAST_INIT
; <0=> Slower initialization
; <1=> Fast Initialization
; <o.6..7> BOOTSRC_SEL
; <0=> Boot from Flash
; <2=> Boot from ROM
; <3=> Boot from ROM
; <i> Boot source selection
FOPT EQU 0x3D
; </h>
; <h> Flash security byte (FSEC)
; <i> WARNING: If SEC field is configured as "MCU security status is secure" and MEEN field is configured as "Mass erase is disabled",
; <i> MCU's security status cannot be set back to unsecure state since Mass erase via the debugger is blocked !!!
; <o.0..1> SEC
; <2=> MCU security status is unsecure
; <3=> MCU security status is secure
; <i> Flash Security
; <o.2..3> FSLACC
; <2=> Freescale factory access denied
; <3=> Freescale factory access granted
; <i> Freescale Failure Analysis Access Code
; <o.4..5> MEEN
; <2=> Mass erase is disabled
; <3=> Mass erase is enabled
; <o.6..7> KEYEN
; <2=> Backdoor key access enabled
; <3=> Backdoor key access disabled
; <i> Backdoor Key Security Enable
FSEC EQU 0xFE
; </h>
; </h>
IF :LNOT::DEF:RAM_TARGET
AREA FlashConfig, DATA, READONLY
__FlashConfig
DCB BackDoorK0, BackDoorK1, BackDoorK2, BackDoorK3
DCB BackDoorK4, BackDoorK5, BackDoorK6, BackDoorK7
DCB FPROT0 , FPROT1 , FPROT2 , FPROT3
DCB FSEC , FOPT , 0xFF , 0xFF
ENDIF
AREA |.text|, CODE, READONLY
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
IF :LNOT::DEF:RAM_TARGET
REQUIRE FlashConfig
ENDIF
CPSID I ; Mask interrupts
LDR R0, =0xE000ED08
LDR R1, =__Vectors
STR R1, [R0]
LDR R0, =SystemInit
BLX R0
CPSIE i ; Unmask interrupts
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler\
PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
SVC_Handler\
PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
PendSV_Handler\
PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler\
PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
DMA0_IRQHandler\
PROC
EXPORT DMA0_IRQHandler [WEAK]
LDR R0, =DMA0_DriverIRQHandler
BX R0
ENDP
DMA1_IRQHandler\
PROC
EXPORT DMA1_IRQHandler [WEAK]
LDR R0, =DMA1_DriverIRQHandler
BX R0
ENDP
DMA2_IRQHandler\
PROC
EXPORT DMA2_IRQHandler [WEAK]
LDR R0, =DMA2_DriverIRQHandler
BX R0
ENDP
DMA3_IRQHandler\
PROC
EXPORT DMA3_IRQHandler [WEAK]
LDR R0, =DMA3_DriverIRQHandler
BX R0
ENDP
I2C0_IRQHandler\
PROC
EXPORT I2C0_IRQHandler [WEAK]
LDR R0, =I2C0_DriverIRQHandler
BX R0
ENDP
I2C1_IRQHandler\
PROC
EXPORT I2C1_IRQHandler [WEAK]
LDR R0, =I2C1_DriverIRQHandler
BX R0
ENDP
SPI0_IRQHandler\
PROC
EXPORT SPI0_IRQHandler [WEAK]
LDR R0, =SPI0_DriverIRQHandler
BX R0
ENDP
SPI1_IRQHandler\
PROC
EXPORT SPI1_IRQHandler [WEAK]
LDR R0, =SPI1_DriverIRQHandler
BX R0
ENDP
LPUART0_IRQHandler\
PROC
EXPORT LPUART0_IRQHandler [WEAK]
LDR R0, =LPUART0_DriverIRQHandler
BX R0
ENDP
LPUART1_IRQHandler\
PROC
EXPORT LPUART1_IRQHandler [WEAK]
LDR R0, =LPUART1_DriverIRQHandler
BX R0
ENDP
UART2_FLEXIO_IRQHandler\
PROC
EXPORT UART2_FLEXIO_IRQHandler [WEAK]
LDR R0, =UART2_FLEXIO_DriverIRQHandler
BX R0
ENDP
Default_Handler\
PROC
EXPORT DMA0_DriverIRQHandler [WEAK]
EXPORT DMA1_DriverIRQHandler [WEAK]
EXPORT DMA2_DriverIRQHandler [WEAK]
EXPORT DMA3_DriverIRQHandler [WEAK]
EXPORT Reserved20_IRQHandler [WEAK]
EXPORT FTFA_IRQHandler [WEAK]
EXPORT PMC_IRQHandler [WEAK]
EXPORT LLWU_IRQHandler [WEAK]
EXPORT I2C0_DriverIRQHandler [WEAK]
EXPORT I2C1_DriverIRQHandler [WEAK]
EXPORT SPI0_DriverIRQHandler [WEAK]
EXPORT SPI1_DriverIRQHandler [WEAK]
EXPORT LPUART0_DriverIRQHandler [WEAK]
EXPORT LPUART1_DriverIRQHandler [WEAK]
EXPORT UART2_FLEXIO_DriverIRQHandler [WEAK]
EXPORT ADC0_IRQHandler [WEAK]
EXPORT CMP0_IRQHandler [WEAK]
EXPORT TPM0_IRQHandler [WEAK]
EXPORT TPM1_IRQHandler [WEAK]
EXPORT TPM2_IRQHandler [WEAK]
EXPORT RTC_IRQHandler [WEAK]
EXPORT RTC_Seconds_IRQHandler [WEAK]
EXPORT PIT_IRQHandler [WEAK]
EXPORT Reserved39_IRQHandler [WEAK]
EXPORT USB0_IRQHandler [WEAK]
EXPORT Reserved41_IRQHandler [WEAK]
EXPORT Reserved42_IRQHandler [WEAK]
EXPORT Reserved43_IRQHandler [WEAK]
EXPORT LPTMR0_IRQHandler [WEAK]
EXPORT Reserved45_IRQHandler [WEAK]
EXPORT PORTA_IRQHandler [WEAK]
EXPORT PORTBCDE_IRQHandler [WEAK]
EXPORT DefaultISR [WEAK]
DMA0_DriverIRQHandler
DMA1_DriverIRQHandler
DMA2_DriverIRQHandler
DMA3_DriverIRQHandler
Reserved20_IRQHandler
FTFA_IRQHandler
PMC_IRQHandler
LLWU_IRQHandler
I2C0_DriverIRQHandler
I2C1_DriverIRQHandler
SPI0_DriverIRQHandler
SPI1_DriverIRQHandler
LPUART0_DriverIRQHandler
LPUART1_DriverIRQHandler
UART2_FLEXIO_DriverIRQHandler
ADC0_IRQHandler
CMP0_IRQHandler
TPM0_IRQHandler
TPM1_IRQHandler
TPM2_IRQHandler
RTC_IRQHandler
RTC_Seconds_IRQHandler
PIT_IRQHandler
Reserved39_IRQHandler
USB0_IRQHandler
Reserved41_IRQHandler
Reserved42_IRQHandler
Reserved43_IRQHandler
LPTMR0_IRQHandler
Reserved45_IRQHandler
PORTA_IRQHandler
PORTBCDE_IRQHandler
DefaultISR
LDR R0, =DefaultISR
BX R0
ENDP
ALIGN
END

View File

@ -1,278 +0,0 @@
/*
** ###################################################################
** Processors: MKL27Z64VDA4
** MKL27Z64VFM4
** MKL27Z64VFT4
** MKL27Z64VLH4
** MKL27Z64VMP4
**
** Compiler: GNU C Compiler
** Reference manual: KL27P64M48SF2RM, Rev. 1, Sep 2014
** Version: rev. 1.4, 2014-09-22
** 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;
#if !defined(MBED_CONF_TARGET_BOOT_STACK_SIZE)
#define MBED_CONF_TARGET_BOOT_STACK_SIZE 0x400
#endif
__stack_size__ = MBED_CONF_TARGET_BOOT_STACK_SIZE;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;
M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x0200 : 0x0;
/* Specify the memory areas */
MEMORY
{
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000200
m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0000FBF0
m_data (RW) : ORIGIN = 0x1FFFF000, LENGTH = 0x00004000
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into internal flash */
.interrupts :
{
__VECTOR_TABLE = .;
. = ALIGN(8);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(8);
} > m_interrupts
.flash_config :
{
. = ALIGN(8);
KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */
. = ALIGN(8);
} > m_flash_config
/* The program code and other data goes into internal flash */
.text :
{
. = ALIGN(8);
*(.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(8);
} > m_text
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > m_text
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > m_text
.ctors :
{
__CTOR_LIST__ = .;
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
} > m_text
.dtors :
{
__DTOR_LIST__ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
} > m_text
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} > m_text
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} > m_text
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} > m_text
__etext = .; /* define a global symbol at end of code */
__DATA_ROM = .; /* Symbol is used by startup for data initialization */
/* reserve MTB memory at the beginning of m_data */
.mtb : /* MTB buffer address as defined by the hardware */
{
. = ALIGN(8);
_mtb_start = .;
KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */
. = ALIGN(8);
_mtb_end = .;
} > m_data
.interrupts_ram :
{
. = ALIGN(8);
__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(8);
__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(8);
__DATA_RAM = .;
__data_start__ = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
KEEP(*(.jcr*))
. = ALIGN(8);
__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(8);
__START_BSS = .;
__bss_start__ = .;
*(.bss)
*(.bss*)
. = ALIGN(512);
USB_RAM_START = .;
. += USB_RAM_GAP;
*(COMMON)
. = ALIGN(8);
__bss_end__ = .;
__END_BSS = .;
} > m_data
.heap :
{
. = ALIGN(8);
__end__ = .;
PROVIDE(end = .);
__HeapBase = .;
. = ORIGIN(m_data) + LENGTH(m_data) - STACK_SIZE;
__HeapLimit = .;
__heap_limit = .; /* Add for _sbrk */
} > m_data
.stack :
{
. = ALIGN(8);
. += STACK_SIZE;
} > m_data
m_usb_bdt USB_RAM_START (NOLOAD) :
{
*(m_usb_bdt)
USB_RAM_BDT_END = .;
}
m_usb_global USB_RAM_BDT_END (NOLOAD) :
{
*(m_usb_global)
}
/* Initializes stack on the end of block */
__StackTop = ORIGIN(m_data) + LENGTH(m_data);
__StackLimit = __StackTop - STACK_SIZE;
PROVIDE(__stack = __StackTop);
.ARM.attributes 0 : { *(.ARM.attributes) }
ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap")
}

View File

@ -1,382 +0,0 @@
/* ---------------------------------------------------------------------------------------*/
/* @file: startup_MKL27Z644.s */
/* @purpose: CMSIS Cortex-M0P Core Device Startup File */
/* MKL27Z644 */
/* @version: 1.4 */
/* @date: 2014-9-22 */
/* @build: b151111 */
/* ---------------------------------------------------------------------------------------*/
/* */
/* 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 armv6-m
.section .isr_vector, "a"
.align 2
.globl __isr_vector
__isr_vector:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler*/
.long HardFault_Handler /* Hard Fault Handler*/
.long 0 /* Reserved*/
.long 0 /* Reserved*/
.long 0 /* Reserved*/
.long 0 /* Reserved*/
.long 0 /* Reserved*/
.long 0 /* Reserved*/
.long 0 /* Reserved*/
.long SVC_Handler /* SVCall Handler*/
.long 0 /* Reserved*/
.long 0 /* Reserved*/
.long PendSV_Handler /* PendSV Handler*/
.long SysTick_Handler /* SysTick Handler*/
/* External Interrupts*/
.long DMA0_IRQHandler /* DMA channel 0 transfer complete*/
.long DMA1_IRQHandler /* DMA channel 1 transfer complete*/
.long DMA2_IRQHandler /* DMA channel 2 transfer complete*/
.long DMA3_IRQHandler /* DMA channel 3 transfer complete*/
.long Reserved20_IRQHandler /* Reserved interrupt*/
.long FTFA_IRQHandler /* Command complete and read collision*/
.long PMC_IRQHandler /* Low-voltage detect, low-voltage warning*/
.long LLWU_IRQHandler /* Low leakage wakeup*/
.long I2C0_IRQHandler /* I2C0 interrupt*/
.long I2C1_IRQHandler /* I2C1 interrupt*/
.long SPI0_IRQHandler /* SPI0 single interrupt vector for all sources*/
.long SPI1_IRQHandler /* SPI1 single interrupt vector for all sources*/
.long LPUART0_IRQHandler /* LPUART0 status and error*/
.long LPUART1_IRQHandler /* LPUART1 status and error*/
.long UART2_FLEXIO_IRQHandler /* UART2 or FLEXIO*/
.long ADC0_IRQHandler /* ADC0 interrupt*/
.long CMP0_IRQHandler /* CMP0 interrupt*/
.long TPM0_IRQHandler /* TPM0 single interrupt vector for all sources*/
.long TPM1_IRQHandler /* TPM1 single interrupt vector for all sources*/
.long TPM2_IRQHandler /* TPM2 single interrupt vector for all sources*/
.long RTC_IRQHandler /* RTC alarm*/
.long RTC_Seconds_IRQHandler /* RTC seconds*/
.long PIT_IRQHandler /* PIT interrupt*/
.long Reserved39_IRQHandler /* Reserved interrupt*/
.long USB0_IRQHandler /* USB0 interrupt*/
.long Reserved41_IRQHandler /* Reserved interrupt*/
.long Reserved42_IRQHandler /* Reserved interrupt*/
.long Reserved43_IRQHandler /* Reserved interrupt*/
.long LPTMR0_IRQHandler /* LPTMR0 interrupt*/
.long Reserved45_IRQHandler /* Reserved interrupt*/
.long PORTA_IRQHandler /* PORTA Pin detect*/
.long PORTBCDE_IRQHandler /* Single interrupt vector for PORTB,PORTC,PORTD,PORTE*/
.size __isr_vector, . - __isr_vector
/* Flash Configuration */
.section .FlashConfig, "a"
.long 0xFFFFFFFF
.long 0xFFFFFFFF
.long 0xFFFFFFFF
.long 0xFFFF3DFE
.text
.thumb
/* Reset Handler */
.thumb_func
.align 2
.globl Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
cpsid i /* Mask interrupts */
.equ VTOR, 0xE000ED08
ldr r0, =VTOR
ldr r1, =__isr_vector
str r1, [r0]
#ifndef __NO_SYSTEM_INIT
ldr r0,=SystemInit
blx r0
#endif
/* Loop to copy data from read only memory to RAM. The ranges
* of copy from/to are specified by following symbols evaluated in
* linker script.
* __etext: End of code section, i.e., begin of data sections to copy from.
* __data_start__/__data_end__: RAM address range that data should be
* copied to. Both must be aligned to 4 bytes boundary. */
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
subs r3, r2
ble .LC0
.LC1:
subs r3, 4
ldr r0, [r1,r3]
str r0, [r2,r3]
bgt .LC1
.LC0:
#ifdef __STARTUP_CLEAR_BSS
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* Loop to zero out BSS section, which uses following symbols
* in linker script:
* __bss_start__: start of BSS section. Must align to 4
* __bss_end__: end of BSS section. Must align to 4
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
subs r2, r1
ble .LC3
movs r0, 0
.LC2:
str r0, [r1, r2]
subs r2, 4
bge .LC2
.LC3:
#endif
cpsie i /* Unmask interrupts */
#ifndef __START
#define __START _start
#endif
#ifndef __ATOLLIC__
ldr r0,=__START
blx r0
#else
ldr r0,=__libc_init_array
blx r0
ldr r0,=main
bx r0
#endif
.pool
.size Reset_Handler, . - Reset_Handler
.align 1
.thumb_func
.weak DefaultISR
.type DefaultISR, %function
DefaultISR:
ldr r0, =DefaultISR
bx r0
.size DefaultISR, . - DefaultISR
.align 1
.thumb_func
.weak NMI_Handler
.type NMI_Handler, %function
NMI_Handler:
ldr r0,=NMI_Handler
bx r0
.size NMI_Handler, . - NMI_Handler
.align 1
.thumb_func
.weak HardFault_Handler
.type HardFault_Handler, %function
HardFault_Handler:
ldr r0,=HardFault_Handler
bx r0
.size HardFault_Handler, . - HardFault_Handler
.align 1
.thumb_func
.weak SVC_Handler
.type SVC_Handler, %function
SVC_Handler:
ldr r0,=SVC_Handler
bx r0
.size SVC_Handler, . - SVC_Handler
.align 1
.thumb_func
.weak PendSV_Handler
.type PendSV_Handler, %function
PendSV_Handler:
ldr r0,=PendSV_Handler
bx r0
.size PendSV_Handler, . - PendSV_Handler
.align 1
.thumb_func
.weak SysTick_Handler
.type SysTick_Handler, %function
SysTick_Handler:
ldr r0,=SysTick_Handler
bx r0
.size SysTick_Handler, . - SysTick_Handler
.align 1
.thumb_func
.weak DMA0_IRQHandler
.type DMA0_IRQHandler, %function
DMA0_IRQHandler:
ldr r0,=DMA0_DriverIRQHandler
bx r0
.size DMA0_IRQHandler, . - DMA0_IRQHandler
.align 1
.thumb_func
.weak DMA1_IRQHandler
.type DMA1_IRQHandler, %function
DMA1_IRQHandler:
ldr r0,=DMA1_DriverIRQHandler
bx r0
.size DMA1_IRQHandler, . - DMA1_IRQHandler
.align 1
.thumb_func
.weak DMA2_IRQHandler
.type DMA2_IRQHandler, %function
DMA2_IRQHandler:
ldr r0,=DMA2_DriverIRQHandler
bx r0
.size DMA2_IRQHandler, . - DMA2_IRQHandler
.align 1
.thumb_func
.weak DMA3_IRQHandler
.type DMA3_IRQHandler, %function
DMA3_IRQHandler:
ldr r0,=DMA3_DriverIRQHandler
bx r0
.size DMA3_IRQHandler, . - DMA3_IRQHandler
.align 1
.thumb_func
.weak I2C0_IRQHandler
.type I2C0_IRQHandler, %function
I2C0_IRQHandler:
ldr r0,=I2C0_DriverIRQHandler
bx r0
.size I2C0_IRQHandler, . - I2C0_IRQHandler
.align 1
.thumb_func
.weak I2C1_IRQHandler
.type I2C1_IRQHandler, %function
I2C1_IRQHandler:
ldr r0,=I2C1_DriverIRQHandler
bx r0
.size I2C1_IRQHandler, . - I2C1_IRQHandler
.align 1
.thumb_func
.weak SPI0_IRQHandler
.type SPI0_IRQHandler, %function
SPI0_IRQHandler:
ldr r0,=SPI0_DriverIRQHandler
bx r0
.size SPI0_IRQHandler, . - SPI0_IRQHandler
.align 1
.thumb_func
.weak SPI1_IRQHandler
.type SPI1_IRQHandler, %function
SPI1_IRQHandler:
ldr r0,=SPI1_DriverIRQHandler
bx r0
.size SPI1_IRQHandler, . - SPI1_IRQHandler
.align 1
.thumb_func
.weak LPUART0_IRQHandler
.type LPUART0_IRQHandler, %function
LPUART0_IRQHandler:
ldr r0,=LPUART0_DriverIRQHandler
bx r0
.size LPUART0_IRQHandler, . - LPUART0_IRQHandler
.align 1
.thumb_func
.weak LPUART1_IRQHandler
.type LPUART1_IRQHandler, %function
LPUART1_IRQHandler:
ldr r0,=LPUART1_DriverIRQHandler
bx r0
.size LPUART1_IRQHandler, . - LPUART1_IRQHandler
.align 1
.thumb_func
.weak UART2_FLEXIO_IRQHandler
.type UART2_FLEXIO_IRQHandler, %function
UART2_FLEXIO_IRQHandler:
ldr r0,=UART2_FLEXIO_DriverIRQHandler
bx r0
.size UART2_FLEXIO_IRQHandler, . - UART2_FLEXIO_IRQHandler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, DefaultISR
.endm
/* Exception Handlers */
def_irq_handler DMA0_DriverIRQHandler
def_irq_handler DMA1_DriverIRQHandler
def_irq_handler DMA2_DriverIRQHandler
def_irq_handler DMA3_DriverIRQHandler
def_irq_handler Reserved20_IRQHandler
def_irq_handler FTFA_IRQHandler
def_irq_handler PMC_IRQHandler
def_irq_handler LLWU_IRQHandler
def_irq_handler I2C0_DriverIRQHandler
def_irq_handler I2C1_DriverIRQHandler
def_irq_handler SPI0_DriverIRQHandler
def_irq_handler SPI1_DriverIRQHandler
def_irq_handler LPUART0_DriverIRQHandler
def_irq_handler LPUART1_DriverIRQHandler
def_irq_handler UART2_FLEXIO_DriverIRQHandler
def_irq_handler ADC0_IRQHandler
def_irq_handler CMP0_IRQHandler
def_irq_handler TPM0_IRQHandler
def_irq_handler TPM1_IRQHandler
def_irq_handler TPM2_IRQHandler
def_irq_handler RTC_IRQHandler
def_irq_handler RTC_Seconds_IRQHandler
def_irq_handler PIT_IRQHandler
def_irq_handler Reserved39_IRQHandler
def_irq_handler USB0_IRQHandler
def_irq_handler Reserved41_IRQHandler
def_irq_handler Reserved42_IRQHandler
def_irq_handler Reserved43_IRQHandler
def_irq_handler LPTMR0_IRQHandler
def_irq_handler Reserved45_IRQHandler
def_irq_handler PORTA_IRQHandler
def_irq_handler PORTBCDE_IRQHandler
.end

View File

@ -1,118 +0,0 @@
/*
** ###################################################################
** Processors: MKL27Z64VDA4
** MKL27Z64VFM4
** MKL27Z64VFT4
** MKL27Z64VLH4
** MKL27Z64VMP4
**
** Compiler: IAR ANSI C/C++ Compiler for ARM
** Reference manual: KL27P64M48SF2RM, Rev. 1, Sep 2014
** Version: rev. 1.4, 2014-09-22
** 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;
if (!isdefinedsymbol(MBED_CONF_TARGET_BOOT_STACK_SIZE)) {
define symbol MBED_CONF_TARGET_BOOT_STACK_SIZE = 0x400;
}
define symbol __stack_size__=MBED_CONF_TARGET_BOOT_STACK_SIZE;
define symbol __heap_size__=0x1000;
define symbol __ram_vector_table_size__ = isdefinedsymbol(__ram_vector_table__) ? 0x00000200 : 0;
define symbol __ram_vector_table_offset__ = isdefinedsymbol(__ram_vector_table__) ? 0x000001FF : 0;
define symbol m_interrupts_start = 0x00000000;
define symbol m_interrupts_end = 0x000001FF;
define symbol m_flash_config_start = 0x00000400;
define symbol m_flash_config_end = 0x0000040F;
define symbol m_text_start = 0x00000410;
define symbol m_text_end = 0x0000FFFF;
define symbol m_interrupts_ram_start = 0x1FFFF000;
define symbol m_interrupts_ram_end = 0x1FFFF000 + __ram_vector_table_offset__;
define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__;
define symbol m_data_end = 0x20002FFF;
/* Sizes */
if (isdefinedsymbol(__stack_size__)) {
define symbol __size_cstack__ = __stack_size__;
} else {
define symbol __size_cstack__ = 0x0400;
}
if (isdefinedsymbol(__heap_size__)) {
define symbol __size_heap__ = __heap_size__;
} else {
define symbol __size_heap__ = 0x0400;
}
define exported symbol __VECTOR_TABLE = m_interrupts_start;
define exported symbol __VECTOR_RAM = isdefinedsymbol(__ram_vector_table__) ? m_interrupts_ram_start : m_interrupts_start;
define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__;
define memory mem with size = 4G;
define region m_flash_config_region = mem:[from m_flash_config_start to m_flash_config_end];
define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end]
| mem:[from m_text_start to m_text_end];
define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__];
define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end];
define region m_interrupts_ram_region = mem:[from m_interrupts_ram_start to m_interrupts_ram_end];
define block CSTACK with alignment = 8, size = __size_cstack__ { };
define block HEAP with alignment = 8, size = __size_heap__ { };
define block RW { readwrite };
define block ZI { zi };
initialize by copy { readwrite, section .textrw };
do not initialize { section .noinit };
place at address mem: m_interrupts_start { readonly section .intvec };
place in m_flash_config_region { section FlashConfig };
place in TEXT_region { readonly };
place in DATA_region { block RW };
place in DATA_region { block ZI };
place in DATA_region { last block HEAP };
place in CSTACK_region { block CSTACK };
place in m_interrupts_ram_region { section m_interrupts_ram };

View File

@ -1,317 +0,0 @@
; ---------------------------------------------------------------------------------------
; @file: startup_MKL27Z644.s
; @purpose: CMSIS Cortex-M0P Core Device Startup File
; MKL27Z644
; @version: 1.4
; @date: 2014-9-22
; @build: b151105
; ---------------------------------------------------------------------------------------
;
; 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 0 ;Reserved
DCD 0 ;Reserved
DCD 0 ;Reserved
__vector_table_0x1c
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD SVC_Handler ;SVCall Handler
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD PendSV_Handler ;PendSV Handler
DCD SysTick_Handler ;SysTick Handler
;External Interrupts
DCD DMA0_IRQHandler ;DMA channel 0 transfer complete
DCD DMA1_IRQHandler ;DMA channel 1 transfer complete
DCD DMA2_IRQHandler ;DMA channel 2 transfer complete
DCD DMA3_IRQHandler ;DMA channel 3 transfer complete
DCD Reserved20_IRQHandler ;Reserved interrupt
DCD FTFA_IRQHandler ;Command complete and read collision
DCD PMC_IRQHandler ;Low-voltage detect, low-voltage warning
DCD LLWU_IRQHandler ;Low leakage wakeup
DCD I2C0_IRQHandler ;I2C0 interrupt
DCD I2C1_IRQHandler ;I2C1 interrupt
DCD SPI0_IRQHandler ;SPI0 single interrupt vector for all sources
DCD SPI1_IRQHandler ;SPI1 single interrupt vector for all sources
DCD LPUART0_IRQHandler ;LPUART0 status and error
DCD LPUART1_IRQHandler ;LPUART1 status and error
DCD UART2_FLEXIO_IRQHandler ;UART2 or FLEXIO
DCD ADC0_IRQHandler ;ADC0 interrupt
DCD CMP0_IRQHandler ;CMP0 interrupt
DCD TPM0_IRQHandler ;TPM0 single interrupt vector for all sources
DCD TPM1_IRQHandler ;TPM1 single interrupt vector for all sources
DCD TPM2_IRQHandler ;TPM2 single interrupt vector for all sources
DCD RTC_IRQHandler ;RTC alarm
DCD RTC_Seconds_IRQHandler ;RTC seconds
DCD PIT_IRQHandler ;PIT interrupt
DCD Reserved39_IRQHandler ;Reserved interrupt
DCD USB0_IRQHandler ;USB0 interrupt
DCD Reserved41_IRQHandler ;Reserved interrupt
DCD Reserved42_IRQHandler ;Reserved interrupt
DCD Reserved43_IRQHandler ;Reserved interrupt
DCD LPTMR0_IRQHandler ;LPTMR0 interrupt
DCD Reserved45_IRQHandler ;Reserved interrupt
DCD PORTA_IRQHandler ;PORTA Pin detect
DCD PORTBCDE_IRQHandler ;Single interrupt vector for PORTB,PORTC,PORTD,PORTE
__Vectors_End
SECTION FlashConfig:CODE
__FlashConfig
DCD 0xFFFFFFFF
DCD 0xFFFFFFFF
DCD 0xFFFFFFFF
DCD 0xFFFF3DFE
__FlashConfig_End
__Vectors EQU __vector_table
__Vectors_Size EQU __Vectors_End - __Vectors
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Default interrupt handlers.
;;
THUMB
PUBWEAK Reset_Handler
SECTION .text:CODE:REORDER:NOROOT(2)
Reset_Handler
CPSID I ; Mask interrupts
LDR R0, =0xE000ED08
LDR R1, =__vector_table
STR R1, [R0]
LDR R0, =SystemInit
BLX R0
CPSIE I ; Unmask interrupts
LDR R0, =__iar_program_start
BX R0
PUBWEAK NMI_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
NMI_Handler
B .
PUBWEAK HardFault_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
HardFault_Handler
B .
PUBWEAK SVC_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
SVC_Handler
B .
PUBWEAK PendSV_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
PendSV_Handler
B .
PUBWEAK SysTick_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
SysTick_Handler
B .
PUBWEAK DMA0_IRQHandler
PUBWEAK DMA0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
DMA0_IRQHandler
LDR R0, =DMA0_DriverIRQHandler
BX R0
PUBWEAK DMA1_IRQHandler
PUBWEAK DMA1_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
DMA1_IRQHandler
LDR R0, =DMA1_DriverIRQHandler
BX R0
PUBWEAK DMA2_IRQHandler
PUBWEAK DMA2_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
DMA2_IRQHandler
LDR R0, =DMA2_DriverIRQHandler
BX R0
PUBWEAK DMA3_IRQHandler
PUBWEAK DMA3_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
DMA3_IRQHandler
LDR R0, =DMA3_DriverIRQHandler
BX R0
PUBWEAK Reserved20_IRQHandler
PUBWEAK FTFA_IRQHandler
PUBWEAK PMC_IRQHandler
PUBWEAK LLWU_IRQHandler
PUBWEAK I2C0_IRQHandler
PUBWEAK I2C0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
I2C0_IRQHandler
LDR R0, =I2C0_DriverIRQHandler
BX R0
PUBWEAK I2C1_IRQHandler
PUBWEAK I2C1_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
I2C1_IRQHandler
LDR R0, =I2C1_DriverIRQHandler
BX R0
PUBWEAK SPI0_IRQHandler
PUBWEAK SPI0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
SPI0_IRQHandler
LDR R0, =SPI0_DriverIRQHandler
BX R0
PUBWEAK SPI1_IRQHandler
PUBWEAK SPI1_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
SPI1_IRQHandler
LDR R0, =SPI1_DriverIRQHandler
BX R0
PUBWEAK LPUART0_IRQHandler
PUBWEAK LPUART0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
LPUART0_IRQHandler
LDR R0, =LPUART0_DriverIRQHandler
BX R0
PUBWEAK LPUART1_IRQHandler
PUBWEAK LPUART1_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
LPUART1_IRQHandler
LDR R0, =LPUART1_DriverIRQHandler
BX R0
PUBWEAK UART2_FLEXIO_IRQHandler
PUBWEAK UART2_FLEXIO_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
UART2_FLEXIO_IRQHandler
LDR R0, =UART2_FLEXIO_DriverIRQHandler
BX R0
PUBWEAK ADC0_IRQHandler
PUBWEAK CMP0_IRQHandler
PUBWEAK TPM0_IRQHandler
PUBWEAK TPM1_IRQHandler
PUBWEAK TPM2_IRQHandler
PUBWEAK RTC_IRQHandler
PUBWEAK RTC_Seconds_IRQHandler
PUBWEAK PIT_IRQHandler
PUBWEAK Reserved39_IRQHandler
PUBWEAK USB0_IRQHandler
PUBWEAK Reserved41_IRQHandler
PUBWEAK Reserved42_IRQHandler
PUBWEAK Reserved43_IRQHandler
PUBWEAK LPTMR0_IRQHandler
PUBWEAK Reserved45_IRQHandler
PUBWEAK PORTA_IRQHandler
PUBWEAK PORTBCDE_IRQHandler
PUBWEAK DefaultISR
SECTION .text:CODE:REORDER:NOROOT(2)
DMA0_DriverIRQHandler
DMA1_DriverIRQHandler
DMA2_DriverIRQHandler
DMA3_DriverIRQHandler
Reserved20_IRQHandler
FTFA_IRQHandler
PMC_IRQHandler
LLWU_IRQHandler
I2C0_DriverIRQHandler
I2C1_DriverIRQHandler
SPI0_DriverIRQHandler
SPI1_DriverIRQHandler
LPUART0_DriverIRQHandler
LPUART1_DriverIRQHandler
UART2_FLEXIO_DriverIRQHandler
ADC0_IRQHandler
CMP0_IRQHandler
TPM0_IRQHandler
TPM1_IRQHandler
TPM2_IRQHandler
RTC_IRQHandler
RTC_Seconds_IRQHandler
PIT_IRQHandler
Reserved39_IRQHandler
USB0_IRQHandler
Reserved41_IRQHandler
Reserved42_IRQHandler
Reserved43_IRQHandler
LPTMR0_IRQHandler
Reserved45_IRQHandler
PORTA_IRQHandler
PORTBCDE_IRQHandler
DefaultISR
LDR R0, =DefaultISR
BX R0
END

View File

@ -1,26 +0,0 @@
/*
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*
* 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

@ -1,45 +0,0 @@
/* mbed Microcontroller Library
*******************************************************************************
* 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
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
extern uint32_t Image$$VECTOR_RAM$$Base[];
#define __VECTOR_RAM Image$$VECTOR_RAM$$Base
#else
extern uint32_t __VECTOR_RAM[];
#endif
/* Symbols defined by the linker script */
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
#define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM
#endif

View File

@ -1,59 +0,0 @@
/*
* 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_MKL27Z32VDA4) || defined(CPU_MKL27Z64VDA4) || defined(CPU_MKL27Z32VFM4) || \
defined(CPU_MKL27Z64VFM4) || defined(CPU_MKL27Z32VFT4) || defined(CPU_MKL27Z64VFT4) || \
defined(CPU_MKL27Z32VLH4) || defined(CPU_MKL27Z64VLH4) || defined(CPU_MKL27Z32VMP4) || \
defined(CPU_MKL27Z64VMP4))
#define KL27Z644_SERIES
/* CMSIS-style register definitions */
#include "MKL27Z644.h"
/* CPU specific feature definitions */
#include "MKL27Z644_features.h"
#else
#error "No valid CPU defined!"
#endif
#endif /* __FSL_DEVICE_REGISTERS_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View File

@ -1,155 +0,0 @@
/*
** ###################################################################
** Processors: MKL27Z32VDA4
** MKL27Z32VFM4
** MKL27Z32VFT4
** MKL27Z32VLH4
** MKL27Z32VMP4
** MKL27Z64VDA4
** MKL27Z64VFM4
** MKL27Z64VFT4
** MKL27Z64VLH4
** MKL27Z64VMP4
**
** Compilers: Keil ARM C/C++ Compiler
** Freescale C/C++ for Embedded ARM
** GNU C Compiler
** IAR ANSI C/C++ Compiler for ARM
**
** Reference manual: KL27P64M48SF2RM, Rev. 1, Sep 2014
** Version: rev. 1.4, 2014-09-22
** Build: b151217
**
** Abstract:
** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device.
**
** Copyright (c) 2015 Freescale Semiconductor, Inc.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
**
** o Redistributions of source code must retain the above copyright notice, this list
** of conditions and the following disclaimer.
**
** o Redistributions in binary form must reproduce the above copyright notice, this
** list of conditions and the following disclaimer in the documentation and/or
** other materials provided with the distribution.
**
** o Neither the name of Freescale Semiconductor, Inc. nor the names of its
** contributors may be used to endorse or promote products derived from this
** software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** http: www.freescale.com
** mail: support@freescale.com
**
** Revisions:
** - rev. 1.0 (2014-05-12)
** Initial version.
** - rev. 1.1 (2014-07-10)
** UART0 - UART0 module renamed to UART2.
** - rev. 1.2 (2014-08-12)
** CRC - CRC register renamed to DATA.
** - rev. 1.3 (2014-09-02)
** USB - USB0_CTL0 was renamed to USB0_OTGCTL register.
** USB - USB0_CTL1 was renamed to USB0_CTL register.
** USB - Two new bitfields (STOP_ACK_DLY_EN, AHB_DLY_EN) was added to the USB0_KEEP_ALIVE_CTRL register.
** - rev. 1.4 (2014-09-22)
** FLEXIO - Offsets of the SHIFTBUFBIS registers were interchanged with offsets of the SHIFTBUFBBS registers.
** SIM - Changed bitfield value MCGIRCLK to LIRC_CLK of bitfield CLKOUTSEL in SOPT2 register.
** SIM - Removed bitfield DIEID in SDID register.
** UART2 - Removed ED register.
** UART2 - Removed MODEM register.
** UART2 - Removed IR register.
** UART2 - Removed PFIFO register.
** UART2 - Removed CFIFO register.
** UART2 - Removed SFIFO register.
** UART2 - Removed TWFIFO register.
** UART2 - Removed TCFIFO register.
** UART2 - Removed RWFIFO register.
** UART2 - Removed RCFIFO register.
** USB - Removed bitfield REG_EN in CLK_RECOVER_IRC_EN register.
** USB - Renamed USBEN bitfield of USB0_CTL was renamed to USBENSOFEN.
**
** ###################################################################
*/
/*!
* @file MKL27Z644
* @version 1.4
* @date 2014-09-22
* @brief Device specific configuration file for MKL27Z644 (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 (ACK_ISOLATION)
if(PMC->REGSC & PMC_REGSC_ACKISO_MASK) {
PMC->REGSC |= PMC_REGSC_ACKISO_MASK; /* VLLSx recovery */
}
#endif
#if (DISABLE_WDOG)
/* SIM->COPC: ?=0,COPCLKSEL=0,COPDBGEN=0,COPSTPEN=0,COPT=0,COPCLKS=0,COPW=0 */
SIM->COPC = (uint32_t)0x00u;
#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->S & MCG_S_CLKST_MASK) == 0x00U) {
/* High internal reference clock is selected */
MCGOUTClock = CPU_INT_FAST_CLK_HZ; /* Fast internal reference clock selected */
} else if ((MCG->S & MCG_S_CLKST_MASK) == 0x04U) {
/* Internal reference clock is selected */
Divider = (uint16_t)(0x01LU << ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT));
MCGOUTClock = (uint32_t) (CPU_INT_SLOW_CLK_HZ / Divider); /* Slow internal reference clock 8MHz selected */
} else if ((MCG->S & MCG_S_CLKST_MASK) == 0x08U) {
/* External reference clock is selected */
MCGOUTClock = CPU_XTAL_CLK_HZ;
} else {
/* Reserved value */
return;
} /* (!((MCG->S & MCG_S_CLKST_MASK) == 0x08U)) */
SystemCoreClock = (MCGOUTClock / (0x01U + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT)));
}

View File

@ -1,166 +0,0 @@
/*
** ###################################################################
** Processors: MKL27Z32VDA4
** MKL27Z32VFM4
** MKL27Z32VFT4
** MKL27Z32VLH4
** MKL27Z32VMP4
** MKL27Z64VDA4
** MKL27Z64VFM4
** MKL27Z64VFT4
** MKL27Z64VLH4
** MKL27Z64VMP4
**
** Compilers: Keil ARM C/C++ Compiler
** Freescale C/C++ for Embedded ARM
** GNU C Compiler
** IAR ANSI C/C++ Compiler for ARM
**
** Reference manual: KL27P64M48SF2RM, Rev. 1, Sep 2014
** Version: rev. 1.4, 2014-09-22
** Build: b151217
**
** Abstract:
** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device.
**
** Copyright (c) 2015 Freescale Semiconductor, Inc.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
**
** o Redistributions of source code must retain the above copyright notice, this list
** of conditions and the following disclaimer.
**
** o Redistributions in binary form must reproduce the above copyright notice, this
** list of conditions and the following disclaimer in the documentation and/or
** other materials provided with the distribution.
**
** o Neither the name of Freescale Semiconductor, Inc. nor the names of its
** contributors may be used to endorse or promote products derived from this
** software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** http: www.freescale.com
** mail: support@freescale.com
**
** Revisions:
** - rev. 1.0 (2014-05-12)
** Initial version.
** - rev. 1.1 (2014-07-10)
** UART0 - UART0 module renamed to UART2.
** - rev. 1.2 (2014-08-12)
** CRC - CRC register renamed to DATA.
** - rev. 1.3 (2014-09-02)
** USB - USB0_CTL0 was renamed to USB0_OTGCTL register.
** USB - USB0_CTL1 was renamed to USB0_CTL register.
** USB - Two new bitfields (STOP_ACK_DLY_EN, AHB_DLY_EN) was added to the USB0_KEEP_ALIVE_CTRL register.
** - rev. 1.4 (2014-09-22)
** FLEXIO - Offsets of the SHIFTBUFBIS registers were interchanged with offsets of the SHIFTBUFBBS registers.
** SIM - Changed bitfield value MCGIRCLK to LIRC_CLK of bitfield CLKOUTSEL in SOPT2 register.
** SIM - Removed bitfield DIEID in SDID register.
** UART2 - Removed ED register.
** UART2 - Removed MODEM register.
** UART2 - Removed IR register.
** UART2 - Removed PFIFO register.
** UART2 - Removed CFIFO register.
** UART2 - Removed SFIFO register.
** UART2 - Removed TWFIFO register.
** UART2 - Removed TCFIFO register.
** UART2 - Removed RWFIFO register.
** UART2 - Removed RCFIFO register.
** USB - Removed bitfield REG_EN in CLK_RECOVER_IRC_EN register.
** USB - Renamed USBEN bitfield of USB0_CTL was renamed to USBENSOFEN.
**
** ###################################################################
*/
/*!
* @file MKL27Z644
* @version 1.4
* @date 2014-09-22
* @brief Device specific configuration file for MKL27Z644 (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_MKL27Z644_H_
#define _SYSTEM_MKL27Z644_H_ /**< Symbol preventing repeated inclusion */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#ifndef DISABLE_WDOG
#define DISABLE_WDOG 1
#endif
#ifndef ACK_ISOLATION
#define ACK_ISOLATION 1
#endif
/* Define clock source values */
#define CPU_XTAL_CLK_HZ 32768u /* Value of the external crystal or oscillator clock frequency in Hz */
#define CPU_INT_FAST_CLK_HZ 48000000u /* Value of the fast internal oscillator clock frequency in Hz */
#define CPU_INT_IRC_CLK_HZ 48000000u /* Value of the 48M internal oscillator clock frequency in Hz */
/* Low power mode enable */
/* SMC_PMPROT: AVLP=1,AVLLS=1 */
#define SYSTEM_SMC_PMPROT_VALUE 0x2Au /* SMC_PMPROT */
#define DEFAULT_SYSTEM_CLOCK 8000000u /* Default System clock value */
#define CPU_INT_SLOW_CLK_HZ 8000000u /* Value of the slow internal oscillator clock frequency in Hz */
/**
* @brief System clock frequency (core clock)
*
* The system clock frequency supplied to the SysTick timer and the processor
* core clock. This variable can be used by the user application to setup the
* SysTick timer or configure other parameters. It may also be used by debugger to
* query the frequency of the debug timer or configure the trace clock speed
* SystemCoreClock is initialized with a correct predefined value.
*/
extern uint32_t SystemCoreClock;
/**
* @brief Setup the microcontroller system.
*
* Typically this function configures the oscillator (PLL) that is part of the
* microcontroller device. For systems with variable clock speed it also updates
* the variable SystemCoreClock. SystemInit is called from startup_device file.
*/
void SystemInit (void);
/**
* @brief Updates the SystemCoreClock variable.
*
* It must be called whenever the core clock is changed during program
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
* the current core clock.
*/
void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* _SYSTEM_MKL27Z644_H_ */

View File

@ -1,363 +0,0 @@
/*
* 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

@ -1,527 +0,0 @@
/*
* 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

@ -1,521 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2019, NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_clock.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.clock"
#endif
#if (defined(OSC) && !(defined(OSC0)))
#define OSC0 OSC
#endif
#define MCG_HIRC_FREQ (48000000U)
#define MCG_LIRC_FREQ1 (2000000U)
#define MCG_LIRC_FREQ2 (8000000U)
#define MCG_S_CLKST_VAL ((MCG->S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT)
#define MCG_SC_FCRDIV_VAL ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT)
#define MCG_MC_LIRC_DIV2_VAL ((MCG->MC & MCG_MC_LIRC_DIV2_MASK) >> MCG_MC_LIRC_DIV2_SHIFT)
#define MCG_C2_IRCS_VAL ((MCG->C2 & MCG_C2_IRCS_MASK) >> MCG_C2_IRCS_SHIFT)
#define SIM_CLKDIV1_OUTDIV1_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT)
#define SIM_CLKDIV1_OUTDIV4_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT)
#define SIM_SOPT1_OSC32KSEL_VAL ((SIM->SOPT1 & SIM_SOPT1_OSC32KSEL_MASK) >> SIM_SOPT1_OSC32KSEL_SHIFT)
/*******************************************************************************
* Variables
******************************************************************************/
/* External XTAL0 (OSC0) clock frequency. */
volatile uint32_t g_xtal0Freq;
/* External XTAL32K clock frequency. */
volatile uint32_t g_xtal32Freq;
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get the current MCG_Lite LIRC_CLK frequency in Hz.
*
* This function will return the LIRC_CLK value in frequency(Hz) based
* on current MCG_Lite configurations and settings. It is an internal function.
*
* @return MCG_Lite LIRC_CLK frequency.
*/
static uint32_t CLOCK_GetLircClkFreq(void);
/*!
* @brief Get RANGE value based on OSC frequency.
*
* To setup external crystal oscillator, must set the register bits RANGE base
* on the crystal frequency. This function returns the RANGE base on the input
* frequency. This is an internal function.
*
* @return RANGE value.
*/
static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq);
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t CLOCK_GetLircClkFreq(void)
{
static const uint32_t lircFreqs[] = {MCG_LIRC_FREQ1, MCG_LIRC_FREQ2};
/* Check whether the LIRC is enabled. */
if ((MCG->C1 & MCG_C1_IRCLKEN_MASK) || (kMCGLITE_ClkSrcLirc == MCG_S_CLKST_VAL))
{
return lircFreqs[MCG_C2_IRCS_VAL];
}
else
{
return 0U;
}
}
static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq)
{
uint8_t range;
if (freq <= 39063U)
{
range = 0U;
}
else if (freq <= 8000000U)
{
range = 1U;
}
else
{
range = 2U;
}
return range;
}
/*!
* brief Get the OSC0 external reference clock frequency (OSC0ERCLK).
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetOsc0ErClkFreq(void)
{
if (OSC0->CR & OSC_CR_ERCLKEN_MASK)
{
/* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. */
assert(g_xtal0Freq);
return g_xtal0Freq;
}
else
{
return 0U;
}
}
/*!
* brief Get the external reference 32K clock frequency (ERCLK32K).
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetEr32kClkFreq(void)
{
uint32_t freq;
switch (SIM_SOPT1_OSC32KSEL_VAL)
{
case 0U: /* OSC 32k clock */
freq = (CLOCK_GetOsc0ErClkFreq() == 32768U) ? 32768U : 0U;
break;
case 2U: /* RTC 32k clock */
/* Please call CLOCK_SetXtal32Freq base on board setting before using XTAL32K/RTC_CLKIN clock. */
assert(g_xtal32Freq);
freq = g_xtal32Freq;
break;
case 3U: /* LPO clock */
freq = LPO_CLK_FREQ;
break;
default:
freq = 0U;
break;
}
return freq;
}
/*!
* brief Get the platform clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetPlatClkFreq(void)
{
return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1);
}
/*!
* brief Get the flash clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetFlashClkFreq(void)
{
uint32_t freq;
freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1);
freq /= (SIM_CLKDIV1_OUTDIV4_VAL + 1);
return freq;
}
/*!
* brief Get the bus clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetBusClkFreq(void)
{
uint32_t freq;
freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1);
freq /= (SIM_CLKDIV1_OUTDIV4_VAL + 1);
return freq;
}
/*!
* brief Get the core clock or system clock frequency.
*
* return Clock frequency in Hz.
*/
uint32_t CLOCK_GetCoreSysClkFreq(void)
{
return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1);
}
/*!
* brief Gets the clock frequency for a specific clock name.
*
* This function checks the current clock configurations and then calculates
* the clock frequency for a specific clock name defined in clock_name_t.
* The MCG must be properly configured before using this function.
*
* param clockName Clock names defined in clock_name_t
* return Clock frequency value in Hertz
*/
uint32_t CLOCK_GetFreq(clock_name_t clockName)
{
uint32_t freq;
switch (clockName)
{
case kCLOCK_CoreSysClk:
case kCLOCK_PlatClk:
freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1);
break;
case kCLOCK_BusClk:
case kCLOCK_FlashClk:
freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1);
freq /= (SIM_CLKDIV1_OUTDIV4_VAL + 1);
break;
case kCLOCK_Er32kClk:
freq = CLOCK_GetEr32kClkFreq();
break;
case kCLOCK_Osc0ErClk:
freq = CLOCK_GetOsc0ErClkFreq();
break;
case kCLOCK_McgInternalRefClk:
freq = CLOCK_GetInternalRefClkFreq();
break;
case kCLOCK_McgPeriphClk:
case kCLOCK_McgIrc48MClk:
freq = CLOCK_GetPeriphClkFreq();
break;
case kCLOCK_LpoClk:
freq = LPO_CLK_FREQ;
break;
default:
freq = 0U;
break;
}
return freq;
}
/*!
* brief Set the clock configure in SIM module.
*
* This function sets system layer clock settings in SIM module.
*
* param config Pointer to the configure structure.
*/
void CLOCK_SetSimConfig(sim_clock_config_t const *config)
{
SIM->CLKDIV1 = config->clkdiv1;
CLOCK_SetEr32kClock(config->er32kSrc);
}
/*! brief Enable USB FS clock.
*
* param src USB FS clock source.
* param freq The frequency specified by src.
* retval true The clock is set successfully.
* retval false The clock source is invalid to get proper USB FS clock.
*/
bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq)
{
bool ret = true;
CLOCK_DisableClock(kCLOCK_Usbfs0);
if (kCLOCK_UsbSrcExt == src)
{
SIM->SOPT2 &= ~SIM_SOPT2_USBSRC_MASK;
}
else
{
SIM->SOPT2 |= SIM_SOPT2_USBSRC_MASK;
}
CLOCK_EnableClock(kCLOCK_Usbfs0);
if (kCLOCK_UsbSrcIrc48M == src)
{
USB0->CLK_RECOVER_IRC_EN = 0x03U;
USB0->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK;
}
return ret;
}
/*!
* brief Gets the MCG internal reference clock (MCGIRCLK) frequency.
*
* This function gets the MCG_Lite internal reference clock frequency in Hz based
* on the current MCG register value.
*
* return The frequency of MCGIRCLK.
*/
uint32_t CLOCK_GetInternalRefClkFreq(void)
{
uint8_t divider1 = MCG_SC_FCRDIV_VAL;
uint8_t divider2 = MCG_MC_LIRC_DIV2_VAL;
/* LIRC internal reference clock is selected*/
return CLOCK_GetLircClkFreq() >> (divider1 + divider2);
}
/*
* brief Gets the current MCGPCLK frequency.
*
* This function gets the MCGPCLK frequency in Hz based on the current MCG_Lite
* register settings.
*
* return The frequency of MCGPCLK.
*/
uint32_t CLOCK_GetPeriphClkFreq(void)
{
/* Check whether the HIRC is enabled. */
if ((MCG->MC & MCG_MC_HIRCEN_MASK) || (kMCGLITE_ClkSrcHirc == MCG_S_CLKST_VAL))
{
return MCG_HIRC_FREQ;
}
else
{
return 0U;
}
}
/*!
* brief Gets the MCG_Lite output clock (MCGOUTCLK) frequency.
*
* This function gets the MCG_Lite output clock frequency in Hz based on the current
* MCG_Lite register value.
*
* return The frequency of MCGOUTCLK.
*/
uint32_t CLOCK_GetOutClkFreq(void)
{
uint32_t freq;
switch (MCG_S_CLKST_VAL)
{
case kMCGLITE_ClkSrcHirc:
freq = MCG_HIRC_FREQ;
break;
case kMCGLITE_ClkSrcLirc:
freq = CLOCK_GetLircClkFreq() >> MCG_SC_FCRDIV_VAL;
break;
case kMCGLITE_ClkSrcExt:
/* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. */
assert(g_xtal0Freq);
freq = g_xtal0Freq;
break;
default:
freq = 0U;
break;
}
return freq;
}
/*!
* brief Gets the current MCG_Lite mode.
*
* This function checks the MCG_Lite registers and determines the current MCG_Lite mode.
*
* return The current MCG_Lite mode or error code.
*/
mcglite_mode_t CLOCK_GetMode(void)
{
mcglite_mode_t mode;
switch (MCG_S_CLKST_VAL)
{
case kMCGLITE_ClkSrcHirc: /* HIRC */
mode = kMCGLITE_ModeHirc48M;
break;
case kMCGLITE_ClkSrcLirc: /* LIRC */
if (kMCGLITE_Lirc2M == MCG_C2_IRCS_VAL)
{
mode = kMCGLITE_ModeLirc2M;
}
else
{
mode = kMCGLITE_ModeLirc8M;
}
break;
case kMCGLITE_ClkSrcExt: /* EXT */
mode = kMCGLITE_ModeExt;
break;
default:
mode = kMCGLITE_ModeError;
break;
}
return mode;
}
/*!
* brief Sets the MCG_Lite configuration.
*
* This function configures the MCG_Lite, includes the output clock source, MCGIRCLK
* settings, HIRC settings, and so on. See ref mcglite_config_t for details.
*
* param targetConfig Pointer to the target MCG_Lite mode configuration structure.
* return Error code.
*/
status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig)
{
assert(targetConfig);
/*
* If switch between LIRC8M and LIRC2M, need to switch to HIRC mode first,
* because could not switch directly.
*/
if ((kMCGLITE_ClkSrcLirc == MCG_S_CLKST_VAL) && (kMCGLITE_ClkSrcLirc == targetConfig->outSrc) &&
(MCG_C2_IRCS_VAL != targetConfig->ircs))
{
MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCGLITE_ClkSrcHirc);
while (kMCGLITE_ClkSrcHirc != MCG_S_CLKST_VAL)
{
}
}
/* Set configuration now. */
MCG->SC = MCG_SC_FCRDIV(targetConfig->fcrdiv);
MCG->MC = MCG_MC_HIRCEN(targetConfig->hircEnableInNotHircMode) | MCG_MC_LIRC_DIV2(targetConfig->lircDiv2);
MCG->C2 = (MCG->C2 & ~MCG_C2_IRCS_MASK) | MCG_C2_IRCS(targetConfig->ircs);
MCG->C1 = MCG_C1_CLKS(targetConfig->outSrc) | targetConfig->irclkEnableMode;
/*
* If external oscillator used and MCG_Lite is set to EXT mode, need to
* wait for the OSC stable.
*/
if ((MCG->C2 & MCG_C2_EREFS0_MASK) && (kMCGLITE_ClkSrcExt == targetConfig->outSrc))
{
while (!(MCG->S & MCG_S_OSCINIT0_MASK))
{
}
}
/* Wait for clock source change completed. */
while (targetConfig->outSrc != MCG_S_CLKST_VAL)
{
}
return kStatus_Success;
}
/*!
* brief Initializes the OSC0.
*
* This function initializes the OSC0 according to the board configuration.
*
* param config Pointer to the OSC0 configuration structure.
*/
void CLOCK_InitOsc0(osc_config_t const *config)
{
uint8_t range = CLOCK_GetOscRangeFromFreq(config->freq);
OSC_SetCapLoad(OSC0, config->capLoad);
OSC_SetExtRefClkConfig(OSC0, &config->oscerConfig);
MCG->C2 = ((MCG->C2 & MCG_C2_IRCS_MASK) | MCG_C2_RANGE0(range) | (uint8_t)config->workMode);
if ((kOSC_ModeExt != config->workMode) && (OSC0->CR & OSC_CR_ERCLKEN_MASK))
{
/* Wait for stable. */
while (!(MCG->S & MCG_S_OSCINIT0_MASK))
{
}
}
}
/*!
* brief Deinitializes the OSC0.
*
* This function deinitializes the OSC0.
*/
void CLOCK_DeinitOsc0(void)
{
OSC0->CR = 0U;
MCG->C2 &= MCG_C2_IRCS_MASK;
}
/*!
* brief Delay at least for several microseconds.
* Please note that, this API will calculate the microsecond period with the maximum devices
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* param delay_us Delay time in unit of microsecond.
*/
__attribute__((weak)) void SDK_DelayAtLeastUs(uint32_t delay_us)
{
assert(0U != delay_us);
uint32_t count = (uint32_t)USEC_TO_COUNT(delay_us, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
/*
* Calculate the real delay count depend on the excute instructions cycles,
* users can change the divider value to adapt to the real IDE optimise level.
*/
count = (count / 4U);
for (; count > 0UL; count--)
{
__NOP();
}
}

View File

@ -1,810 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016 - 2019, NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_CLOCK_H_
#define _FSL_CLOCK_H_
#include "fsl_common.h"
/*! @addtogroup clock */
/*! @{ */
/*! @file */
/*******************************************************************************
* Configurations
******************************************************************************/
/*! @brief Configure whether driver controls clock
*
* When set to 0, peripheral drivers will enable clock in initialize function
* and disable clock in de-initialize function. When set to 1, peripheral
* driver will not control the clock, application could control the clock out of
* the driver.
*
* @note All drivers share this feature switcher. If it is set to 1, application
* should handle clock enable and disable for all drivers.
*/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief CLOCK driver version 2.2.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
/*@}*/
/* Definition for delay API in clock driver, users can redefine it to the real application. */
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (48000000UL)
#endif
/*! @brief External XTAL0 (OSC0) clock frequency.
*
* The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the
* function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
* if XTAL0 is 8 MHz:
* @code
* CLOCK_InitOsc0(...); // Set up the OSC0
* CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to clock driver.
* @endcode
*
* This is important for the multicore platforms where one core needs to set up the
* OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq
* to get a valid clock frequency.
*/
extern volatile uint32_t g_xtal0Freq;
/*! @brief The external XTAL32/EXTAL32/RTC_CLKIN clock frequency.
*
* The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz. When the clock is set up, use the
* function CLOCK_SetXtal32Freq to set the value in the clock driver.
*
* This is important for the multicore platforms where one core needs to set up
* the clock. All other cores need to call the CLOCK_SetXtal32Freq
* to get a valid clock frequency.
*/
extern volatile uint32_t g_xtal32Freq;
/*! @brief Clock ip name array for DMAMUX. */
#define DMAMUX_CLOCKS \
{ \
kCLOCK_Dmamux0 \
}
/*! @brief Clock ip name array for RTC. */
#define RTC_CLOCKS \
{ \
kCLOCK_Rtc0 \
}
/*! @brief Clock ip name array for SPI. */
#define SPI_CLOCKS \
{ \
kCLOCK_Spi0, kCLOCK_Spi1 \
}
/*! @brief Clock ip name array for PIT. */
#define PIT_CLOCKS \
{ \
kCLOCK_Pit0 \
}
/*! @brief Clock ip name array for PORT. */
#define PORT_CLOCKS \
{ \
kCLOCK_PortA, kCLOCK_PortB, kCLOCK_PortC, kCLOCK_PortD, kCLOCK_PortE \
}
/*! @brief Clock ip name array for LPUART. */
#define LPUART_CLOCKS \
{ \
kCLOCK_Lpuart0, kCLOCK_Lpuart1 \
}
/*! @brief Clock ip name array for LPTMR. */
#define LPTMR_CLOCKS \
{ \
kCLOCK_Lptmr0 \
}
/*! @brief Clock ip name array for ADC16. */
#define ADC16_CLOCKS \
{ \
kCLOCK_Adc0 \
}
/*! @brief Clock ip name array for FLEXIO. */
#define FLEXIO_CLOCKS \
{ \
kCLOCK_Flexio0 \
}
/*! @brief Clock ip name array for VREF. */
#define VREF_CLOCKS \
{ \
kCLOCK_Vref0 \
}
/*! @brief Clock ip name array for DMA. */
#define DMA_CLOCKS \
{ \
kCLOCK_Dma0 \
}
/*! @brief Clock ip name array for UART. */
#define UART_CLOCKS \
{ \
kCLOCK_IpInvalid, kCLOCK_IpInvalid, kCLOCK_Uart2 \
}
/*! @brief Clock ip name array for TPM. */
#define TPM_CLOCKS \
{ \
kCLOCK_Tpm0, kCLOCK_Tpm1, kCLOCK_Tpm2 \
}
/*! @brief Clock ip name array for CRC. */
#define CRC_CLOCKS \
{ \
kCLOCK_Crc0 \
}
/*! @brief Clock ip name array for I2C. */
#define I2C_CLOCKS \
{ \
kCLOCK_I2c0, kCLOCK_I2c1 \
}
/*! @brief Clock ip name array for FTF. */
#define FTF_CLOCKS \
{ \
kCLOCK_Ftf0 \
}
/*! @brief Clock ip name array for CMP. */
#define CMP_CLOCKS \
{ \
kCLOCK_Cmp0 \
}
/*!
* @brief LPO clock frequency.
*/
#define LPO_CLK_FREQ 1000U
/*! @brief Peripherals clock source definition. */
#define SYS_CLK kCLOCK_CoreSysClk
#define BUS_CLK kCLOCK_BusClk
#define I2C0_CLK_SRC SYS_CLK
#define I2C1_CLK_SRC SYS_CLK
#define SPI0_CLK_SRC BUS_CLK
#define SPI1_CLK_SRC SYS_CLK
#define UART2_CLK_SRC BUS_CLK
/*! @brief Clock name used to get clock frequency. */
typedef enum _clock_name
{
/* ----------------------------- System layer clock -------------------------------*/
kCLOCK_CoreSysClk, /*!< Core/system clock */
kCLOCK_PlatClk, /*!< Platform clock */
kCLOCK_BusClk, /*!< Bus clock */
kCLOCK_FlexBusClk, /*!< FlexBus clock */
kCLOCK_FlashClk, /*!< Flash clock */
kCLOCK_FastPeriphClk, /*!< Fast peripheral clock */
kCLOCK_PllFllSelClk, /*!< The clock after SIM[PLLFLLSEL]. */
/* ---------------------------------- OSC clock -----------------------------------*/
kCLOCK_Er32kClk, /*!< External reference 32K clock (ERCLK32K) */
kCLOCK_Osc0ErClk, /*!< OSC0 external reference clock (OSC0ERCLK) */
kCLOCK_Osc1ErClk, /*!< OSC1 external reference clock (OSC1ERCLK) */
kCLOCK_Osc0ErClkUndiv, /*!< OSC0 external reference undivided clock(OSC0ERCLK_UNDIV). */
/* ----------------------------- MCG and MCG-Lite clock ---------------------------*/
kCLOCK_McgFixedFreqClk, /*!< MCG fixed frequency clock (MCGFFCLK) */
kCLOCK_McgInternalRefClk, /*!< MCG internal reference clock (MCGIRCLK) */
kCLOCK_McgFllClk, /*!< MCGFLLCLK */
kCLOCK_McgPll0Clk, /*!< MCGPLL0CLK */
kCLOCK_McgPll1Clk, /*!< MCGPLL1CLK */
kCLOCK_McgExtPllClk, /*!< EXT_PLLCLK */
kCLOCK_McgPeriphClk, /*!< MCG peripheral clock (MCGPCLK) */
kCLOCK_McgIrc48MClk, /*!< MCG IRC48M clock */
/* --------------------------------- Other clock ----------------------------------*/
kCLOCK_LpoClk, /*!< LPO clock */
} clock_name_t;
/*! @brief USB clock source definition. */
typedef enum _clock_usb_src
{
kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U), /*!< Use IRC48M. */
kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */
} clock_usb_src_t;
/*------------------------------------------------------------------------------
clock_gate_t definition:
31 16 0
-----------------------------------------------------------------
| SIM_SCGC register offset | control bit offset in SCGC |
-----------------------------------------------------------------
For example, the SDHC clock gate is controlled by SIM_SCGC3[17], the
SIM_SCGC3 offset in SIM is 0x1030, then kCLOCK_GateSdhc0 is defined as
kCLOCK_GateSdhc0 = (0x1030 << 16) | 17;
------------------------------------------------------------------------------*/
#define CLK_GATE_REG_OFFSET_SHIFT 16U
#define CLK_GATE_REG_OFFSET_MASK 0xFFFF0000U
#define CLK_GATE_BIT_SHIFT_SHIFT 0U
#define CLK_GATE_BIT_SHIFT_MASK 0x0000FFFFU
#define CLK_GATE_DEFINE(reg_offset, bit_shift) \
((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \
(((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK))
#define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT)
#define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT)
/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
typedef enum _clock_ip_name
{
kCLOCK_IpInvalid = 0U,
kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U),
kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U),
kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U),
kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U),
kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U),
kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U),
kCLOCK_Spi0 = CLK_GATE_DEFINE(0x1034U, 22U),
kCLOCK_Spi1 = CLK_GATE_DEFINE(0x1034U, 23U),
kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U),
kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U),
kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U),
kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U),
kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U),
kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U),
kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x1038U, 20U),
kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x1038U, 21U),
kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x1038U, 31U),
kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U),
kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U),
kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U),
kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U),
kCLOCK_Tpm0 = CLK_GATE_DEFINE(0x103CU, 24U),
kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x103CU, 25U),
kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x103CU, 26U),
kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U),
kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U),
kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 8U),
} clock_ip_name_t;
/*!@brief SIM configuration structure for clock setting. */
typedef struct _sim_clock_config
{
uint8_t er32kSrc; /*!< ERCLK32K source selection. */
uint32_t clkdiv1; /*!< SIM_CLKDIV1. */
} sim_clock_config_t;
/*! @brief Oscillator capacitor load setting.*/
enum _osc_cap_load
{
kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */
kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */
kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */
kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */
};
/*! @brief OSCERCLK enable mode. */
enum _oscer_enable_mode
{
kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */
kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */
};
/*! @brief The OSC configuration for OSCERCLK. */
typedef struct _oscer_config
{
uint8_t enableMode; /*!< OSCERCLK enable mode. OR'ed value of \ref _oscer_enable_mode. */
} oscer_config_t;
/*! @brief The OSC work mode. */
typedef enum _osc_mode
{
kOSC_ModeExt = 0U, /*!< Use external clock. */
kOSC_ModeOscLowPower = MCG_C2_EREFS0_MASK, /*!< Oscillator low power. */
kOSC_ModeOscHighGain = MCG_C2_EREFS0_MASK | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */
} osc_mode_t;
/*!
* @brief OSC Initialization Configuration Structure
*
* Defines the configuration data structure to initialize the OSC.
* When porting to a new board, set the following members
* according to the board settings:
* 1. freq: The external frequency.
* 2. workMode: The OSC module mode.
*/
typedef struct _osc_config
{
uint32_t freq; /*!< External clock frequency. */
uint8_t capLoad; /*!< Capacitor load setting. */
osc_mode_t workMode; /*!< OSC work mode setting. */
oscer_config_t oscerConfig; /*!< Configuration for OSCERCLK. */
} osc_config_t;
/*! @brief MCG_Lite clock source selection. */
typedef enum _mcglite_clkout_src
{
kMCGLITE_ClkSrcHirc, /*!< MCGOUTCLK source is HIRC */
kMCGLITE_ClkSrcLirc, /*!< MCGOUTCLK source is LIRC */
kMCGLITE_ClkSrcExt, /*!< MCGOUTCLK source is external clock source */
kMCGLITE_ClkSrcReserved
} mcglite_clkout_src_t;
/*! @brief MCG_Lite LIRC select. */
typedef enum _mcglite_lirc_mode
{
kMCGLITE_Lirc2M, /*!< Slow internal reference(LIRC) 2 MHz clock selected */
kMCGLITE_Lirc8M, /*!< Slow internal reference(LIRC) 8 MHz clock selected */
} mcglite_lirc_mode_t;
/*! @brief MCG_Lite divider factor selection for clock source*/
typedef enum _mcglite_lirc_div
{
kMCGLITE_LircDivBy1 = 0U, /*!< Divider is 1 */
kMCGLITE_LircDivBy2, /*!< Divider is 2 */
kMCGLITE_LircDivBy4, /*!< Divider is 4 */
kMCGLITE_LircDivBy8, /*!< Divider is 8 */
kMCGLITE_LircDivBy16, /*!< Divider is 16 */
kMCGLITE_LircDivBy32, /*!< Divider is 32 */
kMCGLITE_LircDivBy64, /*!< Divider is 64 */
kMCGLITE_LircDivBy128 /*!< Divider is 128 */
} mcglite_lirc_div_t;
/*! @brief MCG_Lite clock mode definitions */
typedef enum _mcglite_mode
{
kMCGLITE_ModeHirc48M, /*!< Clock mode is HIRC 48 M */
kMCGLITE_ModeLirc8M, /*!< Clock mode is LIRC 8 M */
kMCGLITE_ModeLirc2M, /*!< Clock mode is LIRC 2 M */
kMCGLITE_ModeExt, /*!< Clock mode is EXT */
kMCGLITE_ModeError /*!< Unknown mode */
} mcglite_mode_t;
/*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */
enum _mcglite_irclk_enable_mode
{
kMCGLITE_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */
kMCGLITE_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */
};
/*! @brief MCG_Lite configure structure for mode change. */
typedef struct _mcglite_config
{
mcglite_clkout_src_t outSrc; /*!< MCGOUT clock select. */
uint8_t irclkEnableMode; /*!< MCGIRCLK enable mode, OR'ed value of _mcglite_irclk_enable_mode. */
mcglite_lirc_mode_t ircs; /*!< MCG_C2[IRCS]. */
mcglite_lirc_div_t fcrdiv; /*!< MCG_SC[FCRDIV]. */
mcglite_lirc_div_t lircDiv2; /*!< MCG_MC[LIRC_DIV2]. */
bool hircEnableInNotHircMode; /*!< HIRC enable when not in HIRC mode. */
} mcglite_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*!
* @brief Enable the clock for specific IP.
*
* @param name Which clock to enable, see \ref clock_ip_name_t.
*/
static inline void CLOCK_EnableClock(clock_ip_name_t name)
{
uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
(*(volatile uint32_t *)regAddr) |= (1U << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
}
/*!
* @brief Disable the clock for specific IP.
*
* @param name Which clock to disable, see \ref clock_ip_name_t.
*/
static inline void CLOCK_DisableClock(clock_ip_name_t name)
{
uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
(*(volatile uint32_t *)regAddr) &= ~(1U << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
}
/*!
* @brief Set ERCLK32K source.
*
* @param src The value to set ERCLK32K clock source.
*/
static inline void CLOCK_SetEr32kClock(uint32_t src)
{
SIM->SOPT1 = ((SIM->SOPT1 & ~SIM_SOPT1_OSC32KSEL_MASK) | SIM_SOPT1_OSC32KSEL(src));
}
/*!
* @brief Set LPUART0 clock source.
*
* @param src The value to set LPUART0 clock source.
*/
static inline void CLOCK_SetLpuart0Clock(uint32_t src)
{
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_LPUART0SRC_MASK) | SIM_SOPT2_LPUART0SRC(src));
}
/*!
* @brief Set LPUART1 clock source.
*
* @param src The value to set LPUART1 clock source.
*/
static inline void CLOCK_SetLpuart1Clock(uint32_t src)
{
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_LPUART1SRC_MASK) | SIM_SOPT2_LPUART1SRC(src));
}
/*!
* @brief Set TPM clock source.
*
* @param src The value to set TPM clock source.
*/
static inline void CLOCK_SetTpmClock(uint32_t src)
{
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TPMSRC_MASK) | SIM_SOPT2_TPMSRC(src));
}
/*!
* @brief Set FLEXIO clock source.
*
* @param src The value to set FLEXIO clock source.
*/
static inline void CLOCK_SetFlexio0Clock(uint32_t src)
{
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_FLEXIOSRC_MASK) | SIM_SOPT2_FLEXIOSRC(src));
}
/*! @brief Enable USB FS clock.
*
* @param src USB FS clock source.
* @param freq The frequency specified by src.
* @retval true The clock is set successfully.
* @retval false The clock source is invalid to get proper USB FS clock.
*/
bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq);
/*! @brief Disable USB FS clock.
*
* Disable USB FS clock.
*/
static inline void CLOCK_DisableUsbfs0Clock(void)
{
CLOCK_DisableClock(kCLOCK_Usbfs0);
}
/*!
* @brief Set CLKOUT source.
*
* @param src The value to set CLKOUT source.
*/
static inline void CLOCK_SetClkOutClock(uint32_t src)
{
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_CLKOUTSEL_MASK) | SIM_SOPT2_CLKOUTSEL(src));
}
/*!
* @brief Set RTC_CLKOUT source.
*
* @param src The value to set RTC_CLKOUT source.
*/
static inline void CLOCK_SetRtcClkOutClock(uint32_t src)
{
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_RTCCLKOUTSEL_MASK) | SIM_SOPT2_RTCCLKOUTSEL(src));
}
/*!
* @brief System clock divider
*
* Set the SIM_CLKDIV1[OUTDIV1], SIM_CLKDIV1[OUTDIV4].
*
* @param outdiv1 Clock 1 output divider value.
*
* @param outdiv4 Clock 4 output divider value.
*/
static inline void CLOCK_SetOutDiv(uint32_t outdiv1, uint32_t outdiv4)
{
SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV4(outdiv4);
}
/*!
* @brief Gets the clock frequency for a specific clock name.
*
* This function checks the current clock configurations and then calculates
* the clock frequency for a specific clock name defined in clock_name_t.
* The MCG must be properly configured before using this function.
*
* @param clockName Clock names defined in clock_name_t
* @return Clock frequency value in Hertz
*/
uint32_t CLOCK_GetFreq(clock_name_t clockName);
/*!
* @brief Get the core clock or system clock frequency.
*
* @return Clock frequency in Hz.
*/
uint32_t CLOCK_GetCoreSysClkFreq(void);
/*!
* @brief Get the platform clock frequency.
*
* @return Clock frequency in Hz.
*/
uint32_t CLOCK_GetPlatClkFreq(void);
/*!
* @brief Get the bus clock frequency.
*
* @return Clock frequency in Hz.
*/
uint32_t CLOCK_GetBusClkFreq(void);
/*!
* @brief Get the flash clock frequency.
*
* @return Clock frequency in Hz.
*/
uint32_t CLOCK_GetFlashClkFreq(void);
/*!
* @brief Get the external reference 32K clock frequency (ERCLK32K).
*
* @return Clock frequency in Hz.
*/
uint32_t CLOCK_GetEr32kClkFreq(void);
/*!
* @brief Get the OSC0 external reference clock frequency (OSC0ERCLK).
*
* @return Clock frequency in Hz.
*/
uint32_t CLOCK_GetOsc0ErClkFreq(void);
/*!
* @brief Set the clock configure in SIM module.
*
* This function sets system layer clock settings in SIM module.
*
* @param config Pointer to the configure structure.
*/
void CLOCK_SetSimConfig(sim_clock_config_t const *config);
/*!
* @brief Set the system clock dividers in SIM to safe value.
*
* The system level clocks (core clock, bus clock, flexbus clock and flash clock)
* must be in allowed ranges. During MCG clock mode switch, the MCG output clock
* changes then the system level clocks may be out of range. This function could
* be used before MCG mode change, to make sure system level clocks are in allowed
* range.
*
* @param config Pointer to the configure structure.
*/
static inline void CLOCK_SetSimSafeDivs(void)
{
SIM->CLKDIV1 = 0x10030000U;
}
/*!
* @name MCG_Lite clock frequency
* @{
*/
/*!
* @brief Gets the MCG_Lite output clock (MCGOUTCLK) frequency.
*
* This function gets the MCG_Lite output clock frequency in Hz based on the current
* MCG_Lite register value.
*
* @return The frequency of MCGOUTCLK.
*/
uint32_t CLOCK_GetOutClkFreq(void);
/*!
* @brief Gets the MCG internal reference clock (MCGIRCLK) frequency.
*
* This function gets the MCG_Lite internal reference clock frequency in Hz based
* on the current MCG register value.
*
* @return The frequency of MCGIRCLK.
*/
uint32_t CLOCK_GetInternalRefClkFreq(void);
/*!
* @brief Gets the current MCGPCLK frequency.
*
* This function gets the MCGPCLK frequency in Hz based on the current MCG_Lite
* register settings.
*
* @return The frequency of MCGPCLK.
*/
uint32_t CLOCK_GetPeriphClkFreq(void);
/*! @}*/
/*!
* @name MCG_Lite mode.
* @{
*/
/*!
* @brief Gets the current MCG_Lite mode.
*
* This function checks the MCG_Lite registers and determines the current MCG_Lite mode.
*
* @return The current MCG_Lite mode or error code.
*/
mcglite_mode_t CLOCK_GetMode(void);
/*!
* @brief Sets the MCG_Lite configuration.
*
* This function configures the MCG_Lite, includes the output clock source, MCGIRCLK
* settings, HIRC settings, and so on. See @ref mcglite_config_t for details.
*
* @param targetConfig Pointer to the target MCG_Lite mode configuration structure.
* @return Error code.
*/
status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig);
/*! @}*/
/*!
* @name OSC configuration
* @{
*/
/*!
* @brief Configures the OSC external reference clock (OSCERCLK).
*
* This function configures the OSC external reference clock (OSCERCLK).
* This is an example to enable the OSCERCLK in normal mode and stop mode, and set
* the output divider to 1.
*
@code
oscer_config_t config =
{
.enableMode = kOSC_ErClkEnable | kOSC_ErClkEnableInStop,
.erclkDiv = 1U,
};
OSC_SetExtRefClkConfig(OSC, &config);
@endcode
*
* @param base OSC peripheral address.
* @param config Pointer to the configuration structure.
*/
static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *config)
{
uint8_t reg = base->CR;
reg &= ~(OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK);
reg |= config->enableMode;
base->CR = reg;
}
/*!
* @brief Sets the capacitor load configuration for the oscillator.
*
* This function sets the specified capacitor configuration for the oscillator.
* This should be done in the early system level initialization function call
* based on the system configuration.
*
* @param base OSC peripheral address.
* @param capLoad OR'ed value for the capacitor load option.See \ref _osc_cap_load.
*
* Example:
@code
// To enable only 2 pF and 8 pF capacitor load, please use like this.
OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P);
@endcode
*/
static inline void OSC_SetCapLoad(OSC_Type *base, uint8_t capLoad)
{
uint8_t reg = base->CR;
reg &= ~(OSC_CR_SC2P_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK | OSC_CR_SC16P_MASK);
reg |= capLoad;
base->CR = reg;
}
/*!
* @brief Initializes the OSC0.
*
* This function initializes the OSC0 according to the board configuration.
*
* @param config Pointer to the OSC0 configuration structure.
*/
void CLOCK_InitOsc0(osc_config_t const *config);
/*!
* @brief Deinitializes the OSC0.
*
* This function deinitializes the OSC0.
*/
void CLOCK_DeinitOsc0(void);
/*! @}*/
/*!
* @name External clock frequency
* @{
*/
/*!
* @brief Sets the XTAL0 frequency based on board settings.
*
* @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
*/
static inline void CLOCK_SetXtal0Freq(uint32_t freq)
{
g_xtal0Freq = freq;
}
/*!
* @brief Sets the XTAL32/RTC_CLKIN frequency based on board settings.
*
* @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz.
*/
static inline void CLOCK_SetXtal32Freq(uint32_t freq)
{
g_xtal32Freq = freq;
}
/*!
* @brief Delay at least for several microseconds.
* Please note that, this API will calculate the microsecond period with the maximum
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* @param delay_us Delay time in unit of microsecond.
*/
void SDK_DelayAtLeastUs(uint32_t delay_us);
/* @} */
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/*! @} */
#endif /* _FSL_CLOCK_H_ */

View File

@ -1,279 +0,0 @@
/*
* 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

@ -1,346 +0,0 @@
/*
* 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

@ -1,256 +0,0 @@
/*
* 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 <stddef.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

@ -1,77 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_cop.h"
/*******************************************************************************
* Code
******************************************************************************/
void COP_GetDefaultConfig(cop_config_t *config)
{
assert(config);
config->enableWindowMode = false;
#if defined(FSL_FEATURE_COP_HAS_LONGTIME_MODE) && FSL_FEATURE_COP_HAS_LONGTIME_MODE
config->timeoutMode = kCOP_LongTimeoutMode;
config->enableStop = false;
config->enableDebug = false;
#endif /* FSL_FEATURE_COP_HAS_LONGTIME_MODE */
config->clockSource = kCOP_LpoClock;
config->timeoutCycles = kCOP_2Power10CyclesOr2Power18Cycles;
}
void COP_Init(SIM_Type *base, const cop_config_t *config)
{
assert(config);
uint32_t value = 0U;
#if defined(FSL_FEATURE_COP_HAS_LONGTIME_MODE) && FSL_FEATURE_COP_HAS_LONGTIME_MODE
value = SIM_COPC_COPW(config->enableWindowMode) | SIM_COPC_COPCLKS(config->timeoutMode) |
SIM_COPC_COPT(config->timeoutCycles) | SIM_COPC_COPSTPEN(config->enableStop) |
SIM_COPC_COPDBGEN(config->enableDebug) | SIM_COPC_COPCLKSEL(config->clockSource);
#else
value = SIM_COPC_COPW(config->enableWindowMode) | SIM_COPC_COPCLKS(config->clockSource) |
SIM_COPC_COPT(config->timeoutCycles);
#endif /* FSL_FEATURE_COP_HAS_LONGTIME_MODE */
base->COPC = value;
}
void COP_Refresh(SIM_Type *base)
{
uint32_t primaskValue = 0U;
/* Disable the global interrupt to protect refresh sequence */
primaskValue = DisableGlobalIRQ();
base->SRVCOP = COP_FIRST_BYTE_OF_REFRESH;
base->SRVCOP = COP_SECOND_BYTE_OF_REFRESH;
EnableGlobalIRQ(primaskValue);
}

View File

@ -1,188 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_COP_H_
#define _FSL_COP_H_
#include "fsl_common.h"
/*!
* @addtogroup cop_driver
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
*******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief COP driver version 2.0.0. */
#define FSL_COP_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
/*! @name COP refresh sequence. */
/*@{*/
#define COP_FIRST_BYTE_OF_REFRESH (0x55U) /*!< First byte of refresh sequence */
#define COP_SECOND_BYTE_OF_REFRESH (0xAAU) /*!< Second byte of refresh sequence */
/*@}*/
/*! @brief COP clock source selection. */
typedef enum _cop_clock_source
{
kCOP_LpoClock = 0U, /*!< COP clock sourced from LPO */
#if defined(FSL_FEATURE_COP_HAS_MORE_CLKSRC) && FSL_FEATURE_COP_HAS_MORE_CLKSRC
kCOP_McgIrClock = 1U, /*!< COP clock sourced from MCGIRCLK */
kCOP_OscErClock = 2U, /*!< COP clock sourced from OSCERCLK */
#endif /* FSL_FEATURE_COP_HAS_MORE_CLKSRC */
kCOP_BusClock = 3U, /*!< COP clock sourced from Bus clock */
} cop_clock_source_t;
/*! @brief Define the COP timeout cycles. */
typedef enum _cop_timeout_cycles
{
kCOP_2Power5CyclesOr2Power13Cycles = 1U, /*!< 2^5 or 2^13 clock cycles */
kCOP_2Power8CyclesOr2Power16Cycles = 2U, /*!< 2^8 or 2^16 clock cycles */
kCOP_2Power10CyclesOr2Power18Cycles = 3U, /*!< 2^10 or 2^18 clock cycles */
} cop_timeout_cycles_t;
#if defined(FSL_FEATURE_COP_HAS_LONGTIME_MODE) && FSL_FEATURE_COP_HAS_LONGTIME_MODE
/*! @breif Define the COP timeout mode. */
typedef enum _cop_timeout_mode
{
kCOP_ShortTimeoutMode = 0U, /*!< COP selects long timeout */
kCOP_LongTimeoutMode = 1U, /*!< COP selects short timeout */
} cop_timeout_mode_t;
#endif /* FSL_FEATURE_COP_HAS_LONGTIME_MODE */
/*! @brief Describes COP configuration structure. */
typedef struct _cop_config
{
bool enableWindowMode; /*!< COP run mode: window mode or normal mode */
#if defined(FSL_FEATURE_COP_HAS_LONGTIME_MODE) && FSL_FEATURE_COP_HAS_LONGTIME_MODE
cop_timeout_mode_t timeoutMode; /*!< COP timeout mode: long timeout or short timeout */
bool enableStop; /*!< Enable or disable COP in STOP mode */
bool enableDebug; /*!< Enable or disable COP in DEBUG mode */
#endif /* FSL_FEATURE_COP_HAS_LONGTIME_MODE */
cop_clock_source_t clockSource; /*!< Set COP clock source */
cop_timeout_cycles_t timeoutCycles; /*!< Set COP timeout value */
} cop_config_t;
/*******************************************************************************
* API
*******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @name COP Functional Operation
* @{
*/
/*!
* @brief Initializes the COP configuration structure.
*
* This function initializes the COP configuration structure to default values. The default
* values are:
* @code
* copConfig->enableWindowMode = false;
* copConfig->timeoutMode = kCOP_LongTimeoutMode;
* copConfig->enableStop = false;
* copConfig->enableDebug = false;
* copConfig->clockSource = kCOP_LpoClock;
* copConfig->timeoutCycles = kCOP_2Power10CyclesOr2Power18Cycles;
* @endcode
*
* @param config Pointer to the COP configuration structure.
* @see cop_config_t
*/
void COP_GetDefaultConfig(cop_config_t *config);
/*!
* @brief Initializes the COP module.
*
* This function configures the COP. After it is called, the COP
* starts running according to the configuration.
* Because all COP control registers are write-once only, the COP_Init function
* and the COP_Disable function can be called only once. A second call has no effect.
*
* Example:
* @code
* cop_config_t config;
* COP_GetDefaultConfig(&config);
* config.timeoutCycles = kCOP_2Power8CyclesOr2Power16Cycles;
* COP_Init(sim_base,&config);
* @endcode
*
* @param base SIM peripheral base address.
* @param config The configuration of COP.
*/
void COP_Init(SIM_Type *base, const cop_config_t *config);
/*!
* @brief De-initializes the COP module.
* This dedicated function is not provided. Instead, the COP_Disable function can be used to disable the COP.
*/
/*!
* @brief Disables the COP module.
*
* This function disables the COP Watchdog.
* Note: The COP configuration register is a write-once after reset.
* To disable the COP Watchdog, call this function first.
*
* @param base SIM peripheral base address.
*/
static inline void COP_Disable(SIM_Type *base)
{
base->COPC &= ~SIM_COPC_COPT_MASK;
}
/*!
* @brief Refreshes the COP timer
*
* This function feeds the COP.
*
* @param base SIM peripheral base address.
*/
void COP_Refresh(SIM_Type *base);
/*@}*/
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/*! @}*/
#endif /* _FSL_COP_H_ */

View File

@ -1,270 +0,0 @@
/*
* 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

@ -1,195 +0,0 @@
/*
* 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

@ -1,306 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_dma.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for DMA.
*
* @param base DMA peripheral base address.
*/
static uint32_t DMA_GetInstance(DMA_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Array to map DMA instance number to base pointer. */
static DMA_Type *const s_dmaBases[] = DMA_BASE_PTRS;
/*! @brief Array to map DMA instance number to clock name. */
static const clock_ip_name_t s_dmaClockName[] = DMA_CLOCKS;
/*! @brief Array to map DMA instance number to IRQ number. */
static const IRQn_Type s_dmaIRQNumber[] = DMA_CHN_IRQS;
/*! @brief Pointers to transfer handle for each DMA channel. */
static dma_handle_t *s_DMAHandle[FSL_FEATURE_DMAMUX_MODULE_CHANNEL * FSL_FEATURE_SOC_DMA_COUNT];
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t DMA_GetInstance(DMA_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < FSL_FEATURE_SOC_DMA_COUNT; instance++)
{
if (s_dmaBases[instance] == base)
{
break;
}
}
assert(instance < FSL_FEATURE_SOC_DMA_COUNT);
return instance;
}
void DMA_Init(DMA_Type *base)
{
CLOCK_EnableClock(s_dmaClockName[DMA_GetInstance(base)]);
}
void DMA_Deinit(DMA_Type *base)
{
CLOCK_DisableClock(s_dmaClockName[DMA_GetInstance(base)]);
}
void DMA_ResetChannel(DMA_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
/* clear all status bit */
base->DMA[channel].DSR_BCR |= DMA_DSR_BCR_DONE(true);
/* clear all registers */
base->DMA[channel].SAR = 0;
base->DMA[channel].DAR = 0;
base->DMA[channel].DSR_BCR = 0;
/* enable cycle steal and enable auto disable channel request */
base->DMA[channel].DCR = DMA_DCR_D_REQ(true) | DMA_DCR_CS(true);
}
void DMA_SetTransferConfig(DMA_Type *base, uint32_t channel, const dma_transfer_config_t *config)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
assert(config != NULL);
uint32_t tmpreg;
/* Set source address */
base->DMA[channel].SAR = config->srcAddr;
/* Set destination address */
base->DMA[channel].DAR = config->destAddr;
/* Set transfer bytes */
base->DMA[channel].DSR_BCR = DMA_DSR_BCR_BCR(config->transferSize);
/* Set DMA Control Register */
tmpreg = base->DMA[channel].DCR;
tmpreg &= ~(DMA_DCR_DSIZE_MASK | DMA_DCR_DINC_MASK | DMA_DCR_SSIZE_MASK | DMA_DCR_SINC_MASK);
tmpreg |= (DMA_DCR_DSIZE(config->destSize) | DMA_DCR_DINC(config->enableDestIncrement) |
DMA_DCR_SSIZE(config->srcSize) | DMA_DCR_SINC(config->enableSrcIncrement));
base->DMA[channel].DCR = tmpreg;
}
void DMA_SetChannelLinkConfig(DMA_Type *base, uint32_t channel, const dma_channel_link_config_t *config)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
assert(config != NULL);
uint32_t tmpreg;
tmpreg = base->DMA[channel].DCR;
tmpreg &= ~(DMA_DCR_LINKCC_MASK | DMA_DCR_LCH1_MASK | DMA_DCR_LCH2_MASK);
tmpreg |= (DMA_DCR_LINKCC(config->linkType) | DMA_DCR_LCH1(config->channel1) | DMA_DCR_LCH2(config->channel2));
base->DMA[channel].DCR = tmpreg;
}
void DMA_SetModulo(DMA_Type *base, uint32_t channel, dma_modulo_t srcModulo, dma_modulo_t destModulo)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
uint32_t tmpreg;
tmpreg = base->DMA[channel].DCR;
tmpreg &= ~(DMA_DCR_SMOD_MASK | DMA_DCR_DMOD_MASK);
tmpreg |= (DMA_DCR_SMOD(srcModulo) | DMA_DCR_DMOD(destModulo));
base->DMA[channel].DCR = tmpreg;
}
void DMA_CreateHandle(dma_handle_t *handle, DMA_Type *base, uint32_t channel)
{
assert(handle != NULL);
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
uint32_t dmaInstance;
uint32_t channelIndex;
handle->base = base;
handle->channel = channel;
/* Get the DMA instance number */
dmaInstance = DMA_GetInstance(base);
channelIndex = (dmaInstance * FSL_FEATURE_DMAMUX_MODULE_CHANNEL) + channel;
/* Store handle */
s_DMAHandle[channelIndex] = handle;
/* Enable NVIC interrupt. */
EnableIRQ(s_dmaIRQNumber[channelIndex]);
}
void DMA_PrepareTransfer(dma_transfer_config_t *config,
void *srcAddr,
uint32_t srcWidth,
void *destAddr,
uint32_t destWidth,
uint32_t transferBytes,
dma_transfer_type_t type)
{
assert(config != NULL);
assert(srcAddr != NULL);
assert(destAddr != NULL);
assert(srcWidth == 1U || srcWidth == 2U || srcWidth == 4U);
assert(destWidth == 1U || destWidth == 2U || destWidth == 4U);
config->srcAddr = (uint32_t)srcAddr;
config->destAddr = (uint32_t)destAddr;
config->transferSize = transferBytes;
switch (srcWidth)
{
case 1U:
config->srcSize = kDMA_Transfersize8bits;
break;
case 2U:
config->srcSize = kDMA_Transfersize16bits;
break;
case 4U:
config->srcSize = kDMA_Transfersize32bits;
break;
default:
break;
}
switch (destWidth)
{
case 1U:
config->destSize = kDMA_Transfersize8bits;
break;
case 2U:
config->destSize = kDMA_Transfersize16bits;
break;
case 4U:
config->destSize = kDMA_Transfersize32bits;
break;
default:
break;
}
switch (type)
{
case kDMA_MemoryToMemory:
config->enableSrcIncrement = true;
config->enableDestIncrement = true;
break;
case kDMA_PeripheralToMemory:
config->enableSrcIncrement = false;
config->enableDestIncrement = true;
break;
case kDMA_MemoryToPeripheral:
config->enableSrcIncrement = true;
config->enableDestIncrement = false;
break;
default:
break;
}
}
void DMA_SetCallback(dma_handle_t *handle, dma_callback callback, void *userData)
{
assert(handle != NULL);
handle->callback = callback;
handle->userData = userData;
}
status_t DMA_SubmitTransfer(dma_handle_t *handle, const dma_transfer_config_t *config, uint32_t options)
{
assert(handle != NULL);
assert(config != NULL);
/* Check if DMA is busy */
if (handle->base->DMA[handle->channel].DSR_BCR & DMA_DSR_BCR_BSY_MASK)
{
return kStatus_DMA_Busy;
}
DMA_ResetChannel(handle->base, handle->channel);
DMA_SetTransferConfig(handle->base, handle->channel, config);
if (options & kDMA_EnableInterrupt)
{
DMA_EnableInterrupts(handle->base, handle->channel);
}
return kStatus_Success;
}
void DMA_AbortTransfer(dma_handle_t *handle)
{
assert(handle != NULL);
handle->base->DMA[handle->channel].DCR &= ~DMA_DCR_ERQ_MASK;
/* clear all status bit */
handle->base->DMA[handle->channel].DSR_BCR |= DMA_DSR_BCR_DONE(true);
}
void DMA_HandleIRQ(dma_handle_t *handle)
{
assert(handle != NULL);
/* Clear interrupt pending bit */
DMA_ClearChannelStatusFlags(handle->base, handle->channel, kDMA_TransactionsDoneFlag);
if (handle->callback)
{
(handle->callback)(handle, handle->userData);
}
}
#if defined(FSL_FEATURE_DMAMUX_MODULE_CHANNEL) && (FSL_FEATURE_DMAMUX_MODULE_CHANNEL == 4U)
void DMA0_DriverIRQHandler(void)
{
DMA_HandleIRQ(s_DMAHandle[0]);
}
void DMA1_DriverIRQHandler(void)
{
DMA_HandleIRQ(s_DMAHandle[1]);
}
void DMA2_DriverIRQHandler(void)
{
DMA_HandleIRQ(s_DMAHandle[2]);
}
void DMA3_DriverIRQHandler(void)
{
DMA_HandleIRQ(s_DMAHandle[3]);
}
#endif /* FSL_FEATURE_DMAMUX_MODULE_CHANNEL */

View File

@ -1,609 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_DMA_H_
#define _FSL_DMA_H_
#include "fsl_common.h"
/*!
* @addtogroup dma_driver
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief DMA driver version 2.0.0. */
#define FSL_DMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
/*! @brief status flag for the DMA driver. */
enum _dma_channel_status_flags
{
kDMA_TransactionsBCRFlag = DMA_DSR_BCR_BCR_MASK, /*!< Contains the number of bytes yet to be
transferred for a given block */
kDMA_TransactionsDoneFlag = DMA_DSR_BCR_DONE_MASK, /*!< Transactions Done */
kDMA_TransactionsBusyFlag = DMA_DSR_BCR_BSY_MASK, /*!< Transactions Busy */
kDMA_TransactionsRequestFlag = DMA_DSR_BCR_REQ_MASK, /*!< Transactions Request */
kDMA_BusErrorOnDestinationFlag = DMA_DSR_BCR_BED_MASK, /*!< Bus Error on Destination */
kDMA_BusErrorOnSourceFlag = DMA_DSR_BCR_BES_MASK, /*!< Bus Error on Source */
kDMA_ConfigurationErrorFlag = DMA_DSR_BCR_CE_MASK, /*!< Configuration Error */
};
/*! @brief DMA transfer size type*/
typedef enum _dma_transfer_size
{
kDMA_Transfersize32bits = 0x0U, /*!< 32 bits are transferred for every read/write */
kDMA_Transfersize8bits, /*!< 8 bits are transferred for every read/write */
kDMA_Transfersize16bits, /*!< 16b its are transferred for every read/write */
} dma_transfer_size_t;
/*! @brief Configuration type for the DMA modulo */
typedef enum _dma_modulo
{
kDMA_ModuloDisable = 0x0U, /*!< Buffer disabled */
kDMA_Modulo16Bytes, /*!< Circular buffer size is 16 bytes. */
kDMA_Modulo32Bytes, /*!< Circular buffer size is 32 bytes. */
kDMA_Modulo64Bytes, /*!< Circular buffer size is 64 bytes. */
kDMA_Modulo128Bytes, /*!< Circular buffer size is 128 bytes. */
kDMA_Modulo256Bytes, /*!< Circular buffer size is 256 bytes. */
kDMA_Modulo512Bytes, /*!< Circular buffer size is 512 bytes. */
kDMA_Modulo1KBytes, /*!< Circular buffer size is 1 KB. */
kDMA_Modulo2KBytes, /*!< Circular buffer size is 2 KB. */
kDMA_Modulo4KBytes, /*!< Circular buffer size is 4 KB. */
kDMA_Modulo8KBytes, /*!< Circular buffer size is 8 KB. */
kDMA_Modulo16KBytes, /*!< Circular buffer size is 16 KB. */
kDMA_Modulo32KBytes, /*!< Circular buffer size is 32 KB. */
kDMA_Modulo64KBytes, /*!< Circular buffer size is 64 KB. */
kDMA_Modulo128KBytes, /*!< Circular buffer size is 128 KB. */
kDMA_Modulo256KBytes, /*!< Circular buffer size is 256 KB. */
} dma_modulo_t;
/*! @brief DMA channel link type */
typedef enum _dma_channel_link_type
{
kDMA_ChannelLinkDisable = 0x0U, /*!< No channel link. */
kDMA_ChannelLinkChannel1AndChannel2, /*!< Perform a link to channel LCH1 after each cycle-steal transfer.
followed by a link to LCH2 after the BCR decrements to 0. */
kDMA_ChannelLinkChannel1, /*!< Perform a link to LCH1 after each cycle-steal transfer. */
kDMA_ChannelLinkChannel1AfterBCR0, /*!< Perform a link to LCH1 after the BCR decrements. */
} dma_channel_link_type_t;
/*! @brief DMA transfer type */
typedef enum _dma_transfer_type
{
kDMA_MemoryToMemory = 0x0U, /*!< Memory to Memory transfer. */
kDMA_PeripheralToMemory, /*!< Peripheral to Memory transfer. */
kDMA_MemoryToPeripheral, /*!< Memory to Peripheral transfer. */
} dma_transfer_type_t;
/*! @brief DMA transfer options */
typedef enum _dma_transfer_options
{
kDMA_NoOptions = 0x0U, /*!< Transfer without options. */
kDMA_EnableInterrupt, /*!< Enable interrupt while transfer complete. */
} dma_transfer_options_t;
/*! @brief DMA transfer status */
enum _dma_transfer_status
{
kStatus_DMA_Busy = MAKE_STATUS(kStatusGroup_DMA, 0),
};
/*! @brief DMA transfer configuration structure */
typedef struct _dma_transfer_config
{
uint32_t srcAddr; /*!< DMA transfer source address. */
uint32_t destAddr; /*!< DMA destination address.*/
bool enableSrcIncrement; /*!< Source address increase after each transfer. */
dma_transfer_size_t srcSize; /*!< Source transfer size unit. */
bool enableDestIncrement; /*!< Destination address increase after each transfer. */
dma_transfer_size_t destSize; /*!< Destination transfer unit.*/
uint32_t transferSize; /*!< The number of bytes to be transferred. */
} dma_transfer_config_t;
/*! @brief DMA transfer configuration structure */
typedef struct _dma_channel_link_config
{
dma_channel_link_type_t linkType; /*!< Channel link type. */
uint32_t channel1; /*!< The index of channel 1. */
uint32_t channel2; /*!< The index of channel 2. */
} dma_channel_link_config_t;
struct _dma_handle;
/*! @brief Callback function prototype for the DMA driver. */
typedef void (*dma_callback)(struct _dma_handle *handle, void *userData);
/*! @brief DMA DMA handle structure */
typedef struct _dma_handle
{
DMA_Type *base; /*!< DMA peripheral address. */
uint8_t channel; /*!< DMA channel used. */
dma_callback callback; /*!< DMA callback function.*/
void *userData; /*!< Callback parameter. */
} dma_handle_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*!
* @name DMA Initialization and De-initialization
* @{
*/
/*!
* @brief Initializes the DMA peripheral.
*
* This function ungates the DMA clock.
*
* @param base DMA peripheral base address.
*/
void DMA_Init(DMA_Type *base);
/*!
* @brief Deinitializes the DMA peripheral.
*
* This function gates the DMA clock.
*
* @param base DMA peripheral base address.
*/
void DMA_Deinit(DMA_Type *base);
/* @} */
/*!
* @name DMA Channel Operation
* @{
*/
/*!
* @brief Resets the DMA channel.
*
* Sets all register values to reset values and enables
* the cycle steal and auto stop channel request features.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
*/
void DMA_ResetChannel(DMA_Type *base, uint32_t channel);
/*!
* @brief Configures the DMA transfer attribute.
*
* This function configures the transfer attribute including the source address,
* destination address, transfer size, and so on.
* This example shows how to set up the the dma_transfer_config_t
* parameters and how to call the DMA_ConfigBasicTransfer function.
* @code
* dma_transfer_config_t transferConfig;
* memset(&transferConfig, 0, sizeof(transferConfig));
* transferConfig.srcAddr = (uint32_t)srcAddr;
* transferConfig.destAddr = (uint32_t)destAddr;
* transferConfig.enbaleSrcIncrement = true;
* transferConfig.enableDestIncrement = true;
* transferConfig.srcSize = kDMA_Transfersize32bits;
* transferConfig.destSize = kDMA_Transfersize32bits;
* transferConfig.transferSize = sizeof(uint32_t) * BUFF_LENGTH;
* DMA_SetTransferConfig(DMA0, 0, &transferConfig);
* @endcode
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
* @param config Pointer to the DMA transfer configuration structure.
*/
void DMA_SetTransferConfig(DMA_Type *base, uint32_t channel, const dma_transfer_config_t *config);
/*!
* @brief Configures the DMA channel link feature.
*
* This function allows DMA channels to have their transfers linked. The current DMA channel
* triggers a DMA request to the linked channels (LCH1 or LCH2) depending on the channel link
* type.
* Perform a link to channel LCH1 after each cycle-steal transfer followed by a link to LCH2
* after the BCR decrements to 0 if the type is kDMA_ChannelLinkChannel1AndChannel2.
* Perform a link to LCH1 after each cycle-steal transfer if the type is kDMA_ChannelLinkChannel1.
* Perform a link to LCH1 after the BCR decrements to 0 if the type is kDMA_ChannelLinkChannel1AfterBCR0.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
* @param config Pointer to the channel link configuration structure.
*/
void DMA_SetChannelLinkConfig(DMA_Type *base, uint32_t channel, const dma_channel_link_config_t *config);
/*!
* @brief Sets the DMA source address for the DMA transfer.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
* @param srcAddr DMA source address.
*/
static inline void DMA_SetSourceAddress(DMA_Type *base, uint32_t channel, uint32_t srcAddr)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->DMA[channel].SAR = srcAddr;
}
/*!
* @brief Sets the DMA destination address for the DMA transfer.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
* @param destAddr DMA destination address.
*/
static inline void DMA_SetDestinationAddress(DMA_Type *base, uint32_t channel, uint32_t destAddr)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->DMA[channel].DAR = destAddr;
}
/*!
* @brief Sets the DMA transfer size for the DMA transfer.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
* @param size The number of bytes to be transferred.
*/
static inline void DMA_SetTransferSize(DMA_Type *base, uint32_t channel, uint32_t size)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->DMA[channel].DSR_BCR = DMA_DSR_BCR_BCR(size);
}
/*!
* @brief Sets the DMA modulo for the DMA transfer.
*
* This function defines a specific address range specified to be the value after (SAR + SSIZE)/(DAR + DSIZE)
* calculation is performed or the original register value. It provides the ability to implement a circular
* data queue easily.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
* @param srcModulo source address modulo.
* @param destModulo destination address modulo.
*/
void DMA_SetModulo(DMA_Type *base, uint32_t channel, dma_modulo_t srcModulo, dma_modulo_t destModulo);
/*!
* @brief Enables the DMA cycle steal for the DMA transfer.
*
* If the cycle steal feature is enabled (true), the DMA controller forces a single read/write transfer per request,
* or it continuously makes read/write transfers until the BCR decrements to 0.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
* @param enable The command for enable (true) or disable (false).
*/
static inline void DMA_EnableCycleSteal(DMA_Type *base, uint32_t channel, bool enable)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->DMA[channel].DCR = (base->DMA[channel].DCR & (~DMA_DCR_CS_MASK)) | DMA_DCR_CS(enable);
}
/*!
* @brief Enables the DMA auto align for the DMA transfer.
*
* If the auto align feature is enabled (true), the appropriate address register increments,
* regardless of DINC or SINC.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
* @param enable The command for enable (true) or disable (false).
*/
static inline void DMA_EnableAutoAlign(DMA_Type *base, uint32_t channel, bool enable)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->DMA[channel].DCR = (base->DMA[channel].DCR & (~DMA_DCR_AA_MASK)) | DMA_DCR_AA(enable);
}
/*!
* @brief Enables the DMA async request for the DMA transfer.
*
* If the async request feature is enabled (true), the DMA supports asynchronous DREQs
* while the MCU is in stop mode.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
* @param enable The command for enable (true) or disable (false).
*/
static inline void DMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->DMA[channel].DCR = (base->DMA[channel].DCR & (~DMA_DCR_EADREQ_MASK)) | DMA_DCR_EADREQ(enable);
}
/*!
* @brief Enables an interrupt for the DMA transfer.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
*/
static inline void DMA_EnableInterrupts(DMA_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->DMA[channel].DCR |= DMA_DCR_EINT(true);
}
/*!
* @brief Disables an interrupt for the DMA transfer.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
*/
static inline void DMA_DisableInterrupts(DMA_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->DMA[channel].DCR &= ~DMA_DCR_EINT_MASK;
}
/* @} */
/*!
* @name DMA Channel Transfer Operation
* @{
*/
/*!
* @brief Enables the DMA hardware channel request.
*
* @param base DMA peripheral base address.
* @param channel The DMA channel number.
*/
static inline void DMA_EnableChannelRequest(DMA_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->DMA[channel].DCR |= DMA_DCR_ERQ_MASK;
}
/*!
* @brief Disables the DMA hardware channel request.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
*/
static inline void DMA_DisableChannelRequest(DMA_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->DMA[channel].DCR &= ~DMA_DCR_ERQ_MASK;
}
/*!
* @brief Starts the DMA transfer with a software trigger.
*
* This function starts only one read/write iteration.
*
* @param base DMA peripheral base address.
* @param channel The DMA channel number.
*/
static inline void DMA_TriggerChannelStart(DMA_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->DMA[channel].DCR |= DMA_DCR_START_MASK;
}
/* @} */
/*!
* @name DMA Channel Status Operation
* @{
*/
/*!
* @brief Gets the remaining bytes of the current DMA transfer.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
* @return The number of bytes which have not been transferred yet.
*/
static inline uint32_t DMA_GetRemainingBytes(DMA_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
return (base->DMA[channel].DSR_BCR & DMA_DSR_BCR_BCR_MASK) >> DMA_DSR_BCR_BCR_SHIFT;
}
/*!
* @brief Gets the DMA channel status flags.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
* @return The mask of the channel status. Use the _dma_channel_status_flags
* type to decode the return 32 bit variables.
*/
static inline uint32_t DMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
return base->DMA[channel].DSR_BCR;
}
/*!
* @brief Clears the DMA channel status flags.
*
* @param base DMA peripheral base address.
* @param channel DMA channel number.
* @param mask The mask of the channel status to be cleared. Use
* the defined _dma_channel_status_flags type.
*/
static inline void DMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
if (mask != 0U)
{
base->DMA[channel].DSR_BCR |= DMA_DSR_BCR_DONE(true);
}
}
/* @} */
/*!
* @name DMA Channel Transactional Operation
* @{
*/
/*!
* @brief Creates the DMA handle.
*
* This function is called first if using the transactional API for the DMA. This function
* initializes the internal state of the DMA handle.
*
* @param handle DMA handle pointer. The DMA handle stores callback function and
* parameters.
* @param base DMA peripheral base address.
* @param channel DMA channel number.
*/
void DMA_CreateHandle(dma_handle_t *handle, DMA_Type *base, uint32_t channel);
/*!
* @brief Sets the DMA callback function.
*
* This callback is called in the DMA IRQ handler. Use the callback to do something
* after the current transfer complete.
*
* @param handle DMA handle pointer.
* @param callback DMA callback function pointer.
* @param userData Parameter for callback function. If it is not needed, just set to NULL.
*/
void DMA_SetCallback(dma_handle_t *handle, dma_callback callback, void *userData);
/*!
* @brief Prepares the DMA transfer configuration structure.
*
* This function prepares the transfer configuration structure according to the user input.
*
* @param config Pointer to the user configuration structure of type dma_transfer_config_t.
* @param srcAddr DMA transfer source address.
* @param srcWidth DMA transfer source address width (byte).
* @param destAddr DMA transfer destination address.
* @param destWidth DMA transfer destination address width (byte).
* @param transferBytes DMA transfer bytes to be transferred.
* @param type DMA transfer type.
*/
void DMA_PrepareTransfer(dma_transfer_config_t *config,
void *srcAddr,
uint32_t srcWidth,
void *destAddr,
uint32_t destWidth,
uint32_t transferBytes,
dma_transfer_type_t type);
/*!
* @brief Submits the DMA transfer request.
*
* This function submits the DMA transfer request according to the transfer configuration structure.
*
* @param handle DMA handle pointer.
* @param config Pointer to DMA transfer configuration structure.
* @param options Additional configurations for transfer. Use
* the defined dma_transfer_options_t type.
* @retval kStatus_DMA_Success It indicates that the DMA submit transfer request succeeded.
* @retval kStatus_DMA_Busy It indicates that the DMA is busy. Submit transfer request is not allowed.
* @note This function can't process multi transfer request.
*/
status_t DMA_SubmitTransfer(dma_handle_t *handle, const dma_transfer_config_t *config, uint32_t options);
/*!
* @brief DMA starts a transfer.
*
* This function enables the channel request. Call this function
* after submitting a transfer request.
*
* @param handle DMA handle pointer.
* @retval kStatus_DMA_Success It indicates that the DMA start transfer succeed.
* @retval kStatus_DMA_Busy It indicates that the DMA has started a transfer.
*/
static inline void DMA_StartTransfer(dma_handle_t *handle)
{
assert(handle != NULL);
handle->base->DMA[handle->channel].DCR |= DMA_DCR_ERQ_MASK;
}
/*!
* @brief DMA stops a transfer.
*
* This function disables the channel request to stop a DMA transfer.
* The transfer can be resumed by calling the DMA_StartTransfer.
*
* @param handle DMA handle pointer.
*/
static inline void DMA_StopTransfer(dma_handle_t *handle)
{
assert(handle != NULL);
handle->base->DMA[handle->channel].DCR &= ~DMA_DCR_ERQ_MASK;
}
/*!
* @brief DMA aborts a transfer.
*
* This function disables the channel request and clears all status bits.
* Submit another transfer after calling this API.
*
* @param handle DMA handle pointer.
*/
void DMA_AbortTransfer(dma_handle_t *handle);
/*!
* @brief DMA IRQ handler for current transfer complete.
*
* This function clears the channel interrupt flag and calls
* the callback function if it is not NULL.
*
* @param handle DMA handle pointer.
*/
void DMA_HandleIRQ(dma_handle_t *handle);
/* @} */
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/* @}*/
#endif /* _FSL_DMA_H_ */

View File

@ -1,87 +0,0 @@
/*
* 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

@ -1,176 +0,0 @@
/*
* 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_ */

View File

@ -1,262 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_flexio.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*< @brief user configurable flexio handle count. */
#define FLEXIO_HANDLE_COUNT 2
/*******************************************************************************
* Variables
******************************************************************************/
/*< @brief pointer to array of FLEXIO handle. */
static void *s_flexioHandle[FLEXIO_HANDLE_COUNT];
/*< @brief pointer to array of FLEXIO IP types. */
static void *s_flexioType[FLEXIO_HANDLE_COUNT];
/*< @brief pointer to array of FLEXIO Isr. */
static flexio_isr_t s_flexioIsr[FLEXIO_HANDLE_COUNT];
/*******************************************************************************
* Codes
******************************************************************************/
void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig)
{
uint32_t ctrlReg = 0;
CLOCK_EnableClock(kCLOCK_Flexio0);
FLEXIO_Reset(base);
ctrlReg = base->CTRL;
ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
ctrlReg |= (FLEXIO_CTRL_DOZEN(userConfig->enableInDoze) | FLEXIO_CTRL_DBGE(userConfig->enableInDebug) |
FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) | FLEXIO_CTRL_FLEXEN(userConfig->enableFlexio));
base->CTRL = ctrlReg;
}
void FLEXIO_Deinit(FLEXIO_Type *base)
{
FLEXIO_Enable(base, false);
CLOCK_DisableClock(kCLOCK_Flexio0);
}
void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig)
{
assert(userConfig);
userConfig->enableFlexio = true;
userConfig->enableInDoze = false;
userConfig->enableInDebug = true;
userConfig->enableFastAccess = false;
}
void FLEXIO_Reset(FLEXIO_Type *base)
{
/*do software reset, software reset operation affect all other FLEXIO registers except CTRL*/
base->CTRL |= FLEXIO_CTRL_SWRST_MASK;
base->CTRL = 0;
}
uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index)
{
assert(index < FLEXIO_SHIFTBUF_COUNT);
uint32_t address = 0;
switch (type)
{
case kFLEXIO_ShifterBuffer:
address = (uint32_t) & (base->SHIFTBUF[index]);
break;
case kFLEXIO_ShifterBufferBitSwapped:
address = (uint32_t) & (base->SHIFTBUFBIS[index]);
break;
case kFLEXIO_ShifterBufferByteSwapped:
address = (uint32_t) & (base->SHIFTBUFBYS[index]);
break;
case kFLEXIO_ShifterBufferBitByteSwapped:
address = (uint32_t) & (base->SHIFTBUFBBS[index]);
break;
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP
case kFLEXIO_ShifterBufferNibbleByteSwapped:
address = (uint32_t) & (base->SHIFTBUFNBS[index]);
break;
#endif
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP
case kFLEXIO_ShifterBufferHalfWordSwapped:
address = (uint32_t) & (base->SHIFTBUFHWS[index]);
break;
#endif
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP
case kFLEXIO_ShifterBufferNibbleSwapped:
address = (uint32_t) & (base->SHIFTBUFNIS[index]);
break;
#endif
default:
break;
}
return address;
}
void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig)
{
base->SHIFTCFG[index] = FLEXIO_SHIFTCFG_INSRC(shifterConfig->inputSource)
#if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH
| FLEXIO_SHIFTCFG_PWIDTH(shifterConfig->parallelWidth)
#endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */
| FLEXIO_SHIFTCFG_SSTOP(shifterConfig->shifterStop) |
FLEXIO_SHIFTCFG_SSTART(shifterConfig->shifterStart);
base->SHIFTCTL[index] =
FLEXIO_SHIFTCTL_TIMSEL(shifterConfig->timerSelect) | FLEXIO_SHIFTCTL_TIMPOL(shifterConfig->timerPolarity) |
FLEXIO_SHIFTCTL_PINCFG(shifterConfig->pinConfig) | FLEXIO_SHIFTCTL_PINSEL(shifterConfig->pinSelect) |
FLEXIO_SHIFTCTL_PINPOL(shifterConfig->pinPolarity) | FLEXIO_SHIFTCTL_SMOD(shifterConfig->shifterMode);
}
void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig)
{
base->TIMCFG[index] =
FLEXIO_TIMCFG_TIMOUT(timerConfig->timerOutput) | FLEXIO_TIMCFG_TIMDEC(timerConfig->timerDecrement) |
FLEXIO_TIMCFG_TIMRST(timerConfig->timerReset) | FLEXIO_TIMCFG_TIMDIS(timerConfig->timerDisable) |
FLEXIO_TIMCFG_TIMENA(timerConfig->timerEnable) | FLEXIO_TIMCFG_TSTOP(timerConfig->timerStop) |
FLEXIO_TIMCFG_TSTART(timerConfig->timerStart);
base->TIMCMP[index] = FLEXIO_TIMCMP_CMP(timerConfig->timerCompare);
base->TIMCTL[index] = FLEXIO_TIMCTL_TRGSEL(timerConfig->triggerSelect) |
FLEXIO_TIMCTL_TRGPOL(timerConfig->triggerPolarity) |
FLEXIO_TIMCTL_TRGSRC(timerConfig->triggerSource) |
FLEXIO_TIMCTL_PINCFG(timerConfig->pinConfig) | FLEXIO_TIMCTL_PINSEL(timerConfig->pinSelect) |
FLEXIO_TIMCTL_PINPOL(timerConfig->pinPolarity) | FLEXIO_TIMCTL_TIMOD(timerConfig->timerMode);
}
status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr)
{
assert(base);
assert(handle);
assert(isr);
uint8_t index = 0;
/* Find the an empty handle pointer to store the handle. */
for (index = 0; index < FLEXIO_HANDLE_COUNT; index++)
{
if (s_flexioHandle[index] == NULL)
{
/* Register FLEXIO simulated driver base, handle and isr. */
s_flexioType[index] = base;
s_flexioHandle[index] = handle;
s_flexioIsr[index] = isr;
break;
}
}
if (index == FLEXIO_HANDLE_COUNT)
{
return kStatus_OutOfRange;
}
else
{
return kStatus_Success;
}
}
status_t FLEXIO_UnregisterHandleIRQ(void *base)
{
assert(base);
uint8_t index = 0;
/* Find the index from base address mappings. */
for (index = 0; index < FLEXIO_HANDLE_COUNT; index++)
{
if (s_flexioType[index] == base)
{
/* Unregister FLEXIO simulated driver handle and isr. */
s_flexioType[index] = NULL;
s_flexioHandle[index] = NULL;
s_flexioIsr[index] = NULL;
break;
}
}
if (index == FLEXIO_HANDLE_COUNT)
{
return kStatus_OutOfRange;
}
else
{
return kStatus_Success;
}
}
void FLEXIO_CommonIRQHandler(void)
{
uint8_t index;
for (index = 0; index < FLEXIO_HANDLE_COUNT; index++)
{
if (s_flexioHandle[index])
{
s_flexioIsr[index](s_flexioType[index], s_flexioHandle[index]);
}
}
}
void FLEXIO_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}
void FLEXIO0_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}
void UART2_FLEXIO_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}

View File

@ -1,707 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_FLEXIO_H_
#define _FSL_FLEXIO_H_
#include "fsl_common.h"
/*!
* @addtogroup flexio_driver
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief FlexIO driver version 2.0.0. */
#define FSL_FLEXIO_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
/*! @brief Calculate FlexIO timer trigger.*/
#define FLEXIO_TIMER_TRIGGER_SEL_PININPUT(x) ((uint32_t)(x) << 1U)
#define FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(x) (((uint32_t)(x) << 2U) | 0x1U)
#define FLEXIO_TIMER_TRIGGER_SEL_TIMn(x) (((uint32_t)(x) << 2U) | 0x3U)
/*! @brief Define time of timer trigger polarity.*/
typedef enum _flexio_timer_trigger_polarity
{
kFLEXIO_TimerTriggerPolarityActiveHigh = 0x0U, /*!< Active high. */
kFLEXIO_TimerTriggerPolarityActiveLow = 0x1U, /*!< Active low. */
} flexio_timer_trigger_polarity_t;
/*! @brief Define type of timer trigger source.*/
typedef enum _flexio_timer_trigger_source
{
kFLEXIO_TimerTriggerSourceExternal = 0x0U, /*!< External trigger selected. */
kFLEXIO_TimerTriggerSourceInternal = 0x1U, /*!< Internal trigger selected. */
} flexio_timer_trigger_source_t;
/*! @brief Define type of timer/shifter pin configuration.*/
typedef enum _flexio_pin_config
{
kFLEXIO_PinConfigOutputDisabled = 0x0U, /*!< Pin output disabled. */
kFLEXIO_PinConfigOpenDrainOrBidirection = 0x1U, /*!< Pin open drain or bidirectional output enable. */
kFLEXIO_PinConfigBidirectionOutputData = 0x2U, /*!< Pin bidirectional output data. */
kFLEXIO_PinConfigOutput = 0x3U, /*!< Pin output. */
} flexio_pin_config_t;
/*! @brief Definition of pin polarity.*/
typedef enum _flexio_pin_polarity
{
kFLEXIO_PinActiveHigh = 0x0U, /*!< Active high. */
kFLEXIO_PinActiveLow = 0x1U, /*!< Active low. */
} flexio_pin_polarity_t;
/*! @brief Define type of timer work mode.*/
typedef enum _flexio_timer_mode
{
kFLEXIO_TimerModeDisabled = 0x0U, /*!< Timer Disabled. */
kFLEXIO_TimerModeDual8BitBaudBit = 0x1U, /*!< Dual 8-bit counters baud/bit mode. */
kFLEXIO_TimerModeDual8BitPWM = 0x2U, /*!< Dual 8-bit counters PWM mode. */
kFLEXIO_TimerModeSingle16Bit = 0x3U, /*!< Single 16-bit counter mode. */
} flexio_timer_mode_t;
/*! @brief Define type of timer initial output or timer reset condition.*/
typedef enum _flexio_timer_output
{
kFLEXIO_TimerOutputOneNotAffectedByReset = 0x0U, /*!< Logic one when enabled and is not affected by timer
reset. */
kFLEXIO_TimerOutputZeroNotAffectedByReset = 0x1U, /*!< Logic zero when enabled and is not affected by timer
reset. */
kFLEXIO_TimerOutputOneAffectedByReset = 0x2U, /*!< Logic one when enabled and on timer reset. */
kFLEXIO_TimerOutputZeroAffectedByReset = 0x3U, /*!< Logic zero when enabled and on timer reset. */
} flexio_timer_output_t;
/*! @brief Define type of timer decrement.*/
typedef enum _flexio_timer_decrement_source
{
kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput = 0x0U, /*!< Decrement counter on FlexIO clock, Shift clock
equals Timer output. */
kFLEXIO_TimerDecSrcOnTriggerInputShiftTimerOutput = 0x1U, /*!< Decrement counter on Trigger input (both edges),
Shift clock equals Timer output. */
kFLEXIO_TimerDecSrcOnPinInputShiftPinInput = 0x2U, /*!< Decrement counter on Pin input (both edges),
Shift clock equals Pin input. */
kFLEXIO_TimerDecSrcOnTriggerInputShiftTriggerInput = 0x3U, /*!< Decrement counter on Trigger input (both edges),
Shift clock equals Trigger input. */
} flexio_timer_decrement_source_t;
/*! @brief Define type of timer reset condition.*/
typedef enum _flexio_timer_reset_condition
{
kFLEXIO_TimerResetNever = 0x0U, /*!< Timer never reset. */
kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput = 0x2U, /*!< Timer reset on Timer Pin equal to Timer Output. */
kFLEXIO_TimerResetOnTimerTriggerEqualToTimerOutput = 0x3U, /*!< Timer reset on Timer Trigger equal to
Timer Output. */
kFLEXIO_TimerResetOnTimerPinRisingEdge = 0x4U, /*!< Timer reset on Timer Pin rising edge. */
kFLEXIO_TimerResetOnTimerTriggerRisingEdge = 0x6U, /*!< Timer reset on Trigger rising edge. */
kFLEXIO_TimerResetOnTimerTriggerBothEdge = 0x7U, /*!< Timer reset on Trigger rising or falling edge. */
} flexio_timer_reset_condition_t;
/*! @brief Define type of timer disable condition.*/
typedef enum _flexio_timer_disable_condition
{
kFLEXIO_TimerDisableNever = 0x0U, /*!< Timer never disabled. */
kFLEXIO_TimerDisableOnPreTimerDisable = 0x1U, /*!< Timer disabled on Timer N-1 disable. */
kFLEXIO_TimerDisableOnTimerCompare = 0x2U, /*!< Timer disabled on Timer compare. */
kFLEXIO_TimerDisableOnTimerCompareTriggerLow = 0x3U, /*!< Timer disabled on Timer compare and Trigger Low. */
kFLEXIO_TimerDisableOnPinBothEdge = 0x4U, /*!< Timer disabled on Pin rising or falling edge. */
kFLEXIO_TimerDisableOnPinBothEdgeTriggerHigh = 0x5U, /*!< Timer disabled on Pin rising or falling edge provided
Trigger is high. */
kFLEXIO_TimerDisableOnTriggerFallingEdge = 0x6U, /*!< Timer disabled on Trigger falling edge. */
} flexio_timer_disable_condition_t;
/*! @brief Define type of timer enable condition.*/
typedef enum _flexio_timer_enable_condition
{
kFLEXIO_TimerEnabledAlways = 0x0U, /*!< Timer always enabled. */
kFLEXIO_TimerEnableOnPrevTimerEnable = 0x1U, /*!< Timer enabled on Timer N-1 enable. */
kFLEXIO_TimerEnableOnTriggerHigh = 0x2U, /*!< Timer enabled on Trigger high. */
kFLEXIO_TimerEnableOnTriggerHighPinHigh = 0x3U, /*!< Timer enabled on Trigger high and Pin high. */
kFLEXIO_TimerEnableOnPinRisingEdge = 0x4U, /*!< Timer enabled on Pin rising edge. */
kFLEXIO_TimerEnableOnPinRisingEdgeTriggerHigh = 0x5U, /*!< Timer enabled on Pin rising edge and Trigger high. */
kFLEXIO_TimerEnableOnTriggerRisingEdge = 0x6U, /*!< Timer enabled on Trigger rising edge. */
kFLEXIO_TimerEnableOnTriggerBothEdge = 0x7U, /*!< Timer enabled on Trigger rising or falling edge. */
} flexio_timer_enable_condition_t;
/*! @brief Define type of timer stop bit generate condition.*/
typedef enum _flexio_timer_stop_bit_condition
{
kFLEXIO_TimerStopBitDisabled = 0x0U, /*!< Stop bit disabled. */
kFLEXIO_TimerStopBitEnableOnTimerCompare = 0x1U, /*!< Stop bit is enabled on timer compare. */
kFLEXIO_TimerStopBitEnableOnTimerDisable = 0x2U, /*!< Stop bit is enabled on timer disable. */
kFLEXIO_TimerStopBitEnableOnTimerCompareDisable = 0x3U, /*!< Stop bit is enabled on timer compare and timer
disable. */
} flexio_timer_stop_bit_condition_t;
/*! @brief Define type of timer start bit generate condition.*/
typedef enum _flexio_timer_start_bit_condition
{
kFLEXIO_TimerStartBitDisabled = 0x0U, /*!< Start bit disabled. */
kFLEXIO_TimerStartBitEnabled = 0x1U, /*!< Start bit enabled. */
} flexio_timer_start_bit_condition_t;
/*! @brief Define type of timer polarity for shifter control. */
typedef enum _flexio_shifter_timer_polarity
{
kFLEXIO_ShifterTimerPolarityOnPositive = 0x0U, /* Shift on positive edge of shift clock. */
kFLEXIO_ShifterTimerPolarityOnNegitive = 0x1U, /* Shift on negative edge of shift clock. */
} flexio_shifter_timer_polarity_t;
/*! @brief Define type of shifter working mode.*/
typedef enum _flexio_shifter_mode
{
kFLEXIO_ShifterDisabled = 0x0U, /*!< Shifter is disabled. */
kFLEXIO_ShifterModeReceive = 0x1U, /*!< Receive mode. */
kFLEXIO_ShifterModeTransmit = 0x2U, /*!< Transmit mode. */
kFLEXIO_ShifterModeMatchStore = 0x4U, /*!< Match store mode. */
kFLEXIO_ShifterModeMatchContinuous = 0x5U, /*!< Match continuous mode. */
#if FSL_FEATURE_FLEXIO_HAS_STATE_MODE
kFLEXIO_ShifterModeState = 0x6U, /*!< SHIFTBUF contents are used for storing
programmable state attributes. */
#endif /* FSL_FEATURE_FLEXIO_HAS_STATE_MODE */
#if FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE
kFLEXIO_ShifterModeLogic = 0x7U, /*!< SHIFTBUF contents are used for implementing
programmable logic look up table. */
#endif /* FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE */
} flexio_shifter_mode_t;
/*! @brief Define type of shifter input source.*/
typedef enum _flexio_shifter_input_source
{
kFLEXIO_ShifterInputFromPin = 0x0U, /*!< Shifter input from pin. */
kFLEXIO_ShifterInputFromNextShifterOutput = 0x1U, /*!< Shifter input from Shifter N+1. */
} flexio_shifter_input_source_t;
/*! @brief Define of STOP bit configuration.*/
typedef enum _flexio_shifter_stop_bit
{
kFLEXIO_ShifterStopBitDisable = 0x0U, /*!< Disable shifter stop bit. */
kFLEXIO_ShifterStopBitLow = 0x2U, /*!< Set shifter stop bit to logic low level. */
kFLEXIO_ShifterStopBitHigh = 0x3U, /*!< Set shifter stop bit to logic high level. */
} flexio_shifter_stop_bit_t;
/*! @brief Define type of START bit configuration.*/
typedef enum _flexio_shifter_start_bit
{
kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable = 0x0U, /*!< Disable shifter start bit, transmitter loads
data on enable. */
kFLEXIO_ShifterStartBitDisabledLoadDataOnShift = 0x1U, /*!< Disable shifter start bit, transmitter loads
data on first shift. */
kFLEXIO_ShifterStartBitLow = 0x2U, /*!< Set shifter start bit to logic low level. */
kFLEXIO_ShifterStartBitHigh = 0x3U, /*!< Set shifter start bit to logic high level. */
} flexio_shifter_start_bit_t;
/*! @brief Define FlexIO shifter buffer type*/
typedef enum _flexio_shifter_buffer_type
{
kFLEXIO_ShifterBuffer = 0x0U, /*!< Shifter Buffer N Register. */
kFLEXIO_ShifterBufferBitSwapped = 0x1U, /*!< Shifter Buffer N Bit Byte Swapped Register. */
kFLEXIO_ShifterBufferByteSwapped = 0x2U, /*!< Shifter Buffer N Byte Swapped Register. */
kFLEXIO_ShifterBufferBitByteSwapped = 0x3U, /*!< Shifter Buffer N Bit Swapped Register. */
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP
kFLEXIO_ShifterBufferNibbleByteSwapped = 0x4U, /*!< Shifter Buffer N Nibble Byte Swapped Register. */
#endif /*FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP*/
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP
kFLEXIO_ShifterBufferHalfWordSwapped = 0x5U, /*!< Shifter Buffer N Half Word Swapped Register. */
#endif
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP
kFLEXIO_ShifterBufferNibbleSwapped = 0x6U, /*!< Shifter Buffer N Nibble Swapped Register. */
#endif
} flexio_shifter_buffer_type_t;
/*! @brief Define FlexIO user configuration structure. */
typedef struct _flexio_config_
{
bool enableFlexio; /*!< Enable/disable FlexIO module */
bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode */
bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode */
bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, fast access requires
the FlexIO clock to be at least twice the frequency of the bus clock. */
} flexio_config_t;
/*! @brief Define FlexIO timer configuration structure. */
typedef struct _flexio_timer_config
{
/* Trigger. */
uint32_t triggerSelect; /*!< The internal trigger selection number using MACROs. */
flexio_timer_trigger_polarity_t triggerPolarity; /*!< Trigger Polarity. */
flexio_timer_trigger_source_t triggerSource; /*!< Trigger Source, internal (see 'trgsel') or external. */
/* Pin. */
flexio_pin_config_t pinConfig; /*!< Timer Pin Configuration. */
uint32_t pinSelect; /*!< Timer Pin number Select. */
flexio_pin_polarity_t pinPolarity; /*!< Timer Pin Polarity. */
/* Timer. */
flexio_timer_mode_t timerMode; /*!< Timer work Mode. */
flexio_timer_output_t timerOutput; /*!< Configures the initial state of the Timer Output and
whether it is affected by the Timer reset. */
flexio_timer_decrement_source_t timerDecrement; /*!< Configures the source of the Timer decrement and the
source of the Shift clock. */
flexio_timer_reset_condition_t timerReset; /*!< Configures the condition that causes the timer counter
(and optionally the timer output) to be reset. */
flexio_timer_disable_condition_t timerDisable; /*!< Configures the condition that causes the Timer to be
disabled and stop decrementing. */
flexio_timer_enable_condition_t timerEnable; /*!< Configures the condition that causes the Timer to be
enabled and start decrementing. */
flexio_timer_stop_bit_condition_t timerStop; /*!< Timer STOP Bit generation. */
flexio_timer_start_bit_condition_t timerStart; /*!< Timer STRAT Bit generation. */
uint32_t timerCompare; /*!< Value for Timer Compare N Register. */
} flexio_timer_config_t;
/*! @brief Define FlexIO shifter configuration structure. */
typedef struct _flexio_shifter_config
{
/* Timer. */
uint32_t timerSelect; /*!< Selects which Timer is used for controlling the
logic/shift register and generating the Shift clock. */
flexio_shifter_timer_polarity_t timerPolarity; /*!< Timer Polarity. */
/* Pin. */
flexio_pin_config_t pinConfig; /*!< Shifter Pin Configuration. */
uint32_t pinSelect; /*!< Shifter Pin number Select. */
flexio_pin_polarity_t pinPolarity; /*!< Shifter Pin Polarity. */
/* Shifter. */
flexio_shifter_mode_t shifterMode; /*!< Configures the mode of the Shifter. */
#if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH
uint32_t parallelWidth; /*!< Configures the parallel width when using parallel mode.*/
#endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */
flexio_shifter_input_source_t inputSource; /*!< Selects the input source for the shifter. */
flexio_shifter_stop_bit_t shifterStop; /*!< Shifter STOP bit. */
flexio_shifter_start_bit_t shifterStart; /*!< Shifter START bit. */
} flexio_shifter_config_t;
/*! @brief typedef for FlexIO simulated driver interrupt handler.*/
typedef void (*flexio_isr_t)(void *base, void *handle);
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus*/
/*!
* @name FlexIO Initialization and De-initialization
* @{
*/
/*!
* @brief Gets the default configuration to configure FlexIO module. The configuration
* can used directly for calling FLEXIO_Configure().
*
* Example:
@code
flexio_config_t config;
FLEXIO_GetDefaultConfig(&config);
@endcode
*
* @param userConfig pointer to flexio_config_t structure
*/
void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig);
/*!
* @brief Configures the FlexIO with FlexIO configuration. The configuration structure
* can be filled by the user, or be set with default values by FLEXIO_GetDefaultConfig().
*
* Example
@code
flexio_config_t config = {
.enableFlexio = true,
.enableInDoze = false,
.enableInDebug = true,
.enableFastAccess = false
};
FLEXIO_Configure(base, &config);
@endcode
*
* @param base FlexIO peripheral base address
* @param userConfig pointer to flexio_config_t structure
*/
void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig);
/*!
* @brief Gates the FlexIO clock. Call this API to stop the FlexIO clock.
*
* @note After calling this API, call the FLEXO_Init to use the FlexIO module.
*
* @param base FlexIO peripheral base address
*/
void FLEXIO_Deinit(FLEXIO_Type *base);
/* @} */
/*!
* @name FlexIO Basic Operation
* @{
*/
/*!
* @brief Resets the FlexIO module.
*
* @param base FlexIO peripheral base address
*/
void FLEXIO_Reset(FLEXIO_Type *base);
/*!
* @brief Enables the FlexIO module operation.
*
* @param base FlexIO peripheral base address
* @param enable true to enable, false to disable.
*/
static inline void FLEXIO_Enable(FLEXIO_Type *base, bool enable)
{
if (enable)
{
base->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
}
else
{
base->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK;
}
}
#if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
/*!
* @brief Reads the input data on each of the FlexIO pins.
*
* @param base FlexIO peripheral base address
* @return FlexIO pin input data
*/
static inline uint32_t FLEXIO_ReadPinInput(FLEXIO_Type *base)
{
return base->PIN;
}
#endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
#if defined(FSL_FEATURE_FLEXIO_HAS_STATE_MODE) && FSL_FEATURE_FLEXIO_HAS_STATE_MODE
/*!
* @brief Gets the current state pointer for state mode use.
*
* @param base FlexIO peripheral base address
* @return current state pointer
*/
static inline uint8_t FLEXIO_GetShifterState(FLEXIO_Type *base)
{
return ((base->SHIFTSTATE) & FLEXIO_SHIFTSTATE_STATE_MASK);
}
#endif /*FSL_FEATURE_FLEXIO_HAS_STATE_MODE*/
/*!
* @brief Configures the shifter with shifter configuration. The configuration structure
* covers both the SHIFTCTL and SHIFTCFG registers. To configure the shifter to the proper
* mode, select which timer controls the shifter to shift, whether to generate start bit/stop
* bit, and the polarity of start bit and stop bit.
*
* Example
@code
flexio_shifter_config_t config = {
.timerSelect = 0,
.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive,
.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection,
.pinPolarity = kFLEXIO_PinActiveLow,
.shifterMode = kFLEXIO_ShifterModeTransmit,
.inputSource = kFLEXIO_ShifterInputFromPin,
.shifterStop = kFLEXIO_ShifterStopBitHigh,
.shifterStart = kFLEXIO_ShifterStartBitLow
};
FLEXIO_SetShifterConfig(base, &config);
@endcode
*
* @param base FlexIO peripheral base address
* @param index shifter index
* @param shifterConfig pointer to flexio_shifter_config_t structure
*/
void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig);
/*!
* @brief Configures the timer with the timer configuration. The configuration structure
* covers both the TIMCTL and TIMCFG registers. To configure the timer to the proper
* mode, select trigger source for timer and the timer pin output and the timing for timer.
*
* Example
@code
flexio_timer_config_t config = {
.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0),
.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow,
.triggerSource = kFLEXIO_TimerTriggerSourceInternal,
.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection,
.pinSelect = 0,
.pinPolarity = kFLEXIO_PinActiveHigh,
.timerMode = kFLEXIO_TimerModeDual8BitBaudBit,
.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset,
.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput,
.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput,
.timerDisable = kFLEXIO_TimerDisableOnTimerCompare,
.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh,
.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable,
.timerStart = kFLEXIO_TimerStartBitEnabled
};
FLEXIO_SetTimerConfig(base, &config);
@endcode
*
* @param base FlexIO peripheral base address
* @param index timer index
* @param timerConfig pointer to flexio_timer_config_t structure
*/
void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig);
/* @} */
/*!
* @name FlexIO Interrupt Operation
* @{
*/
/*!
* @brief Enables the shifter status interrupt. The interrupt generates when the corresponding SSF is set.
*
* @param base FlexIO peripheral base address
* @param mask the shifter status mask which could be calculated by (1 << shifter index)
* @note for multiple shifter status interrupt enable, for example, two shifter status enable, could calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_EnableShifterStatusInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTSIEN |= mask;
}
/*!
* @brief Disables the shifter status interrupt. The interrupt won't generate when the corresponding SSF is set.
*
* @param base FlexIO peripheral base address
* @param mask the shifter status mask which could be calculated by (1 << shifter index)
* @note for multiple shifter status interrupt enable, for example, two shifter status enable, could calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_DisableShifterStatusInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTSIEN &= ~mask;
}
/*!
* @brief Enables the shifter error interrupt. The interrupt generates when the corresponding SEF is set.
*
* @param base FlexIO peripheral base address
* @param mask the shifter error mask which could be calculated by (1 << shifter index)
* @note for multiple shifter error interrupt enable, for example, two shifter error enable, could calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_EnableShifterErrorInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTEIEN |= mask;
}
/*!
* @brief Disables the shifter error interrupt. The interrupt won't generate when the corresponding SEF is set.
*
* @param base FlexIO peripheral base address
* @param mask the shifter error mask which could be calculated by (1 << shifter index)
* @note for multiple shifter error interrupt enable, for example, two shifter error enable, could calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_DisableShifterErrorInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTEIEN &= ~mask;
}
/*!
* @brief Enables the timer status interrupt. The interrupt generates when the corresponding SSF is set.
*
* @param base FlexIO peripheral base address
* @param mask the timer status mask which could be calculated by (1 << timer index)
* @note for multiple timer status interrupt enable, for example, two timer status enable, could calculate
* the mask by using ((1 << timer index0) | (1 << timer index1))
*/
static inline void FLEXIO_EnableTimerStatusInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->TIMIEN |= mask;
}
/*!
* @brief Disables the timer status interrupt. The interrupt won't generate when the corresponding SSF is set.
*
* @param base FlexIO peripheral base address
* @param mask the timer status mask which could be calculated by (1 << timer index)
* @note for multiple timer status interrupt enable, for example, two timer status enable, could calculate
* the mask by using ((1 << timer index0) | (1 << timer index1))
*/
static inline void FLEXIO_DisableTimerStatusInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->TIMIEN &= ~mask;
}
/* @} */
/*!
* @name FlexIO Status Operation
* @{
*/
/*!
* @brief Gets the shifter status flags.
*
* @param base FlexIO peripheral base address
* @return shifter status flags
*/
static inline uint32_t FLEXIO_GetShifterStatusFlags(FLEXIO_Type *base)
{
return ((base->SHIFTSTAT) & FLEXIO_SHIFTSTAT_SSF_MASK);
}
/*!
* @brief Clears the shifter status flags.
*
* @param base FlexIO peripheral base address
* @param mask the shifter status mask which could be calculated by (1 << shifter index)
* @note for clearing multiple shifter status flags, for example, two shifter status flags, could calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_ClearShifterStatusFlags(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTSTAT = mask;
}
/*!
* @brief Gets the shifter error flags.
*
* @param base FlexIO peripheral base address
* @return shifter error flags
*/
static inline uint32_t FLEXIO_GetShifterErrorFlags(FLEXIO_Type *base)
{
return ((base->SHIFTERR) & FLEXIO_SHIFTERR_SEF_MASK);
}
/*!
* @brief Clears the shifter error flags.
*
* @param base FlexIO peripheral base address
* @param mask the shifter error mask which could be calculated by (1 << shifter index)
* @note for clearing multiple shifter error flags, for example, two shifter error flags, could calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_ClearShifterErrorFlags(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTERR = mask;
}
/*!
* @brief Gets the timer status flags.
*
* @param base FlexIO peripheral base address
* @return timer status flags
*/
static inline uint32_t FLEXIO_GetTimerStatusFlags(FLEXIO_Type *base)
{
return ((base->TIMSTAT) & FLEXIO_TIMSTAT_TSF_MASK);
}
/*!
* @brief Clears the timer status flags.
*
* @param base FlexIO peripheral base address
* @param mask the timer status mask which could be calculated by (1 << timer index)
* @note for clearing multiple timer status flags, for example, two timer status flags, could calculate
* the mask by using ((1 << timer index0) | (1 << timer index1))
*/
static inline void FLEXIO_ClearTimerStatusFlags(FLEXIO_Type *base, uint32_t mask)
{
base->TIMSTAT = mask;
}
/* @} */
/*!
* @name FlexIO DMA Operation
* @{
*/
/*!
* @brief Enables/disables the shifter status DMA. The DMA request generates when the corresponding SSF is set.
*
* @note For multiple shifter status DMA enables, for example, calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*
* @param base FlexIO peripheral base address
* @param mask the shifter status mask which could be calculated by (1 << shifter index)
* @param enable True to enable, false to disable.
*/
static inline void FLEXIO_EnableShifterStatusDMA(FLEXIO_Type *base, uint32_t mask, bool enable)
{
if (enable)
{
base->SHIFTSDEN |= mask;
}
else
{
base->SHIFTSDEN &= ~mask;
}
}
/*!
* @brief Gets the shifter buffer address for the DMA transfer usage.
*
* @param base FlexIO peripheral base address
* @param type shifter type of flexio_shifter_buffer_type_t
* @param index shifter index
* @return corresponding shifter buffer index
*/
uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index);
/*!
* @brief Registers the handle and the interrupt handler for the FlexIO-simulated peripheral.
*
* @param base pointer to FlexIO simulated peripheral type.
* @param handle pointer to handler for FlexIO simulated peripheral.
* @param isr FlexIO simulated peripheral interrupt handler.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
*/
status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr);
/*!
* @brief Unregisters the handle and the interrupt handler for the FlexIO-simulated peripheral.
*
* @param base pointer to FlexIO simulated peripheral type.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
*/
status_t FLEXIO_UnregisterHandleIRQ(void *base);
/* @} */
#if defined(__cplusplus)
}
#endif /*_cplusplus*/
/*@}*/
#endif /*_FSL_FLEXIO_H_*/

View File

@ -1,732 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_flexio_i2c_master.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief FLEXIO I2C transfer state */
enum _flexio_i2c_master_transfer_states
{
kFLEXIO_I2C_Idle = 0x0U, /*!< I2C bus idle */
kFLEXIO_I2C_CheckAddress = 0x1U, /*!< 7-bit address check state */
kFLEXIO_I2C_SendCommand = 0x2U, /*!< Send command byte phase */
kFLEXIO_I2C_SendData = 0x3U, /*!< Send data transfer phase*/
kFLEXIO_I2C_ReceiveDataBegin = 0x4U, /*!< Receive data begin transfer phase*/
kFLEXIO_I2C_ReceiveData = 0x5U, /*!< Receive data transfer phase*/
};
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Set up master transfer, send slave address and decide the initial
* transfer state.
*
* @param base pointer to FLEXIO_I2C_Type structure
* @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
* @param transfer pointer to flexio_i2c_master_transfer_t structure
*/
static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_t *xfer);
/*!
* @brief Master run transfer state machine to perform a byte of transfer.
*
* @param base pointer to FLEXIO_I2C_Type structure
* @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
* @param statusFlags flexio i2c hardware status
* @retval kStatus_Success Successfully run state machine
* @retval kStatus_FLEXIO_I2C_Nak Receive Nak during transfer
*/
static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
uint32_t statusFlags);
/*!
* @brief Complete transfer, disable interrupt and call callback.
*
* @param base pointer to FLEXIO_I2C_Type structure
* @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
* @param status flexio transfer status
*/
static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
status_t status);
/*******************************************************************************
* Codes
******************************************************************************/
static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_t *xfer)
{
bool needRestart;
uint32_t byteCount;
/* Init the handle member. */
handle->transfer.slaveAddress = xfer->slaveAddress;
handle->transfer.direction = xfer->direction;
handle->transfer.subaddress = xfer->subaddress;
handle->transfer.subaddressSize = xfer->subaddressSize;
handle->transfer.data = xfer->data;
handle->transfer.dataSize = xfer->dataSize;
handle->transfer.flags = xfer->flags;
handle->transferSize = xfer->dataSize;
/* Initial state, i2c check address state. */
handle->state = kFLEXIO_I2C_CheckAddress;
/* Clear all status before transfer. */
FLEXIO_I2C_MasterClearStatusFlags(base, kFLEXIO_I2C_ReceiveNakFlag);
/* Calculate whether need to send re-start. */
needRestart = (handle->transfer.subaddressSize != 0) && (handle->transfer.direction == kFLEXIO_I2C_Read);
/* Calculate total byte count in a frame. */
byteCount = 1;
if (!needRestart)
{
byteCount += handle->transfer.dataSize;
}
if (handle->transfer.subaddressSize != 0)
{
byteCount += handle->transfer.subaddressSize;
/* Next state, send command byte. */
handle->state = kFLEXIO_I2C_SendCommand;
}
/* Configure data count. */
if (FLEXIO_I2C_MasterSetTransferCount(base, byteCount) != kStatus_Success)
{
return kStatus_InvalidArgument;
}
while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
{
}
/* Send address byte first. */
if (needRestart)
{
FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Write);
}
else
{
FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, handle->transfer.direction);
}
return kStatus_Success;
}
static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
uint32_t statusFlags)
{
if (statusFlags & kFLEXIO_I2C_ReceiveNakFlag)
{
/* Clear receive nak flag. */
FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
if ((!((handle->state == kFLEXIO_I2C_SendData) && (handle->transfer.dataSize == 0U))) &&
(!(((handle->state == kFLEXIO_I2C_ReceiveData) || (handle->state == kFLEXIO_I2C_ReceiveDataBegin)) &&
(handle->transfer.dataSize == 1U))))
{
FLEXIO_I2C_MasterReadByte(base);
FLEXIO_I2C_MasterAbortStop(base);
handle->state = kFLEXIO_I2C_Idle;
return kStatus_FLEXIO_I2C_Nak;
}
}
if (handle->state == kFLEXIO_I2C_CheckAddress)
{
if (handle->transfer.direction == kFLEXIO_I2C_Write)
{
/* Next state, send data. */
handle->state = kFLEXIO_I2C_SendData;
}
else
{
/* Next state, receive data begin. */
handle->state = kFLEXIO_I2C_ReceiveDataBegin;
}
}
if ((statusFlags & kFLEXIO_I2C_RxFullFlag) && (handle->state != kFLEXIO_I2C_ReceiveData))
{
FLEXIO_I2C_MasterReadByte(base);
}
switch (handle->state)
{
case kFLEXIO_I2C_SendCommand:
if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
{
if (handle->transfer.subaddressSize > 0)
{
handle->transfer.subaddressSize--;
FLEXIO_I2C_MasterWriteByte(
base, ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize)));
if (handle->transfer.subaddressSize == 0)
{
/* Load re-start in advance. */
if (handle->transfer.direction == kFLEXIO_I2C_Read)
{
while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
{
}
FLEXIO_I2C_MasterRepeatedStart(base);
}
}
}
else
{
if (handle->transfer.direction == kFLEXIO_I2C_Write)
{
/* Next state, send data. */
handle->state = kFLEXIO_I2C_SendData;
/* Send first byte of data. */
if (handle->transfer.dataSize > 0)
{
FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
handle->transfer.data++;
handle->transfer.dataSize--;
}
}
else
{
FLEXIO_I2C_MasterSetTransferCount(base, (handle->transfer.dataSize + 1));
FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Read);
/* Next state, receive data begin. */
handle->state = kFLEXIO_I2C_ReceiveDataBegin;
}
}
}
break;
/* Send command byte. */
case kFLEXIO_I2C_SendData:
if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
{
/* Send one byte of data. */
if (handle->transfer.dataSize > 0)
{
FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
handle->transfer.data++;
handle->transfer.dataSize--;
}
else
{
FLEXIO_I2C_MasterStop(base);
handle->state = kFLEXIO_I2C_Idle;
}
}
break;
case kFLEXIO_I2C_ReceiveDataBegin:
if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
{
/* Read one byte of data. */
FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
/* Send nak at the last receive byte. */
if (handle->transfer.dataSize == 1)
{
FLEXIO_I2C_MasterEnableAck(base, false);
while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
{
}
FLEXIO_I2C_MasterStop(base);
}
else
{
FLEXIO_I2C_MasterEnableAck(base, true);
}
}
else
{
handle->state = kFLEXIO_I2C_ReceiveData;
}
break;
case kFLEXIO_I2C_ReceiveData:
if (statusFlags & kFLEXIO_I2C_RxFullFlag)
{
*handle->transfer.data = FLEXIO_I2C_MasterReadByte(base);
handle->transfer.data++;
/* Receive one byte of data. */
if (handle->transfer.dataSize--)
{
if (handle->transfer.dataSize != 0)
{
FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
}
else
{
FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_RxFullInterruptEnable);
handle->state = kFLEXIO_I2C_Idle;
}
/* Send nak at the last receive byte. */
if (handle->transfer.dataSize == 1)
{
FLEXIO_I2C_MasterEnableAck(base, false);
while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
{
}
FLEXIO_I2C_MasterStop(base);
}
}
}
break;
default:
break;
}
return kStatus_Success;
}
static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
status_t status)
{
FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
if (handle->completionCallback)
{
handle->completionCallback(base, handle, status, handle->userData);
}
}
void FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
{
assert(base && masterConfig);
flexio_shifter_config_t shifterConfig;
flexio_timer_config_t timerConfig;
uint32_t controlVal = 0;
memset(&shifterConfig, 0, sizeof(shifterConfig));
memset(&timerConfig, 0, sizeof(timerConfig));
/* Ungate flexio clock. */
CLOCK_EnableClock(kCLOCK_Flexio0);
FLEXIO_Reset(base->flexioBase);
/* Do hardware configuration. */
/* 1. Configure the shifter 0 for tx. */
shifterConfig.timerSelect = base->timerIndex[1];
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
shifterConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
shifterConfig.pinSelect = base->SDAPinIndex;
shifterConfig.pinPolarity = kFLEXIO_PinActiveLow;
shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow;
FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
/* 2. Configure the shifter 1 for rx. */
shifterConfig.timerSelect = base->timerIndex[1];
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
shifterConfig.pinSelect = base->SDAPinIndex;
shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
/*3. Configure the timer 0 for generating bit clock. */
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timerConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
timerConfig.pinSelect = base->SCLPinIndex;
timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput;
timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable;
timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
/* Set TIMCMP[7:0] = (baud rate divider / 2) - 1. */
timerConfig.timerCompare = (srcClock_Hz / masterConfig->baudRate_Bps) / 2 - 1;
FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
/* 4. Configure the timer 1 for controlling shifters. */
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
timerConfig.pinSelect = base->SCLPinIndex;
timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
timerConfig.timerReset = kFLEXIO_TimerResetNever;
timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable;
timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerCompare;
timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
/* Set TIMCMP[15:0] = (number of bits x 2) - 1. */
timerConfig.timerCompare = 8 * 2 - 1;
FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
/* Configure FLEXIO I2C Master. */
controlVal = base->flexioBase->CTRL;
controlVal &=
~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
controlVal |=
(FLEXIO_CTRL_DOZEN(masterConfig->enableInDoze) | FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) |
FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) | FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster));
base->flexioBase->CTRL = controlVal;
}
void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base)
{
FLEXIO_Deinit(base->flexioBase);
}
void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig)
{
assert(masterConfig);
masterConfig->enableMaster = true;
masterConfig->enableInDoze = false;
masterConfig->enableInDebug = true;
masterConfig->enableFastAccess = false;
/* Default baud rate at 100kbps. */
masterConfig->baudRate_Bps = 100000U;
}
uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base)
{
uint32_t status = 0;
status =
((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]);
status |=
(((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
<< 1U);
status |=
(((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
<< 2U);
return status;
}
void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_I2C_TxEmptyFlag)
{
FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]);
}
if (mask & kFLEXIO_I2C_RxFullFlag)
{
FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]);
}
if (mask & kFLEXIO_I2C_ReceiveNakFlag)
{
FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
}
}
void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable)
{
FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
}
if (mask & kFLEXIO_I2C_RxFullInterruptEnable)
{
FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
}
}
void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable)
{
FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
}
if (mask & kFLEXIO_I2C_RxFullInterruptEnable)
{
FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
}
}
void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
{
uint16_t timerDiv = 0;
uint16_t timerCmp = 0;
FLEXIO_Type *flexioBase = base->flexioBase;
/* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/
timerDiv = srcClock_Hz / baudRate_Bps;
timerDiv = timerDiv / 2 - 1U;
timerCmp = flexioBase->TIMCMP[base->timerIndex[0]];
timerCmp &= 0xFF00;
timerCmp |= timerDiv;
flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
}
status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint8_t count)
{
if (count > 14U)
{
return kStatus_InvalidArgument;
}
uint16_t timerCmp = 0;
uint32_t timerConfig = 0;
FLEXIO_Type *flexioBase = base->flexioBase;
timerCmp = flexioBase->TIMCMP[base->timerIndex[0]];
timerCmp &= 0x00FFU;
timerCmp |= (count * 18 + 1U) << 8U;
flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
timerConfig = flexioBase->TIMCFG[base->timerIndex[0]];
timerConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
timerConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare);
flexioBase->TIMCFG[base->timerIndex[0]] = timerConfig;
return kStatus_Success;
}
void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction)
{
uint32_t data;
data = ((uint32_t)address) << 1U | ((direction == kFLEXIO_I2C_Read) ? 1U : 0U);
FLEXIO_I2C_MasterWriteByte(base, data);
}
void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base)
{
/* Prepare for RESTART condition, no stop.*/
FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
}
void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base)
{
/* Prepare normal stop. */
FLEXIO_I2C_MasterSetTransferCount(base, 0x0U);
FLEXIO_I2C_MasterWriteByte(base, 0x0U);
}
void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base)
{
uint32_t tmpConfig;
/* Prepare abort stop. */
tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[0]];
tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge);
base->flexioBase->TIMCFG[base->timerIndex[0]] = tmpConfig;
}
void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable)
{
uint32_t tmpConfig = 0;
tmpConfig = base->flexioBase->SHIFTCFG[base->shifterIndex[0]];
tmpConfig &= ~FLEXIO_SHIFTCFG_SSTOP_MASK;
if (enable)
{
tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitLow);
}
else
{
tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitHigh);
}
base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = tmpConfig;
}
status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize)
{
assert(txBuff);
assert(txSize);
uint32_t status;
while (txSize--)
{
FLEXIO_I2C_MasterWriteByte(base, *txBuff++);
/* Wait until data transfer complete. */
while (!((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & kFLEXIO_I2C_RxFullFlag))
{
}
if (status & kFLEXIO_I2C_ReceiveNakFlag)
{
FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
return kStatus_FLEXIO_I2C_Nak;
}
}
return kStatus_Success;
}
void FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize)
{
assert(rxBuff);
assert(rxSize);
while (rxSize--)
{
/* Wait until data transfer complete. */
while (!(FLEXIO_I2C_MasterGetStatusFlags(base) & kFLEXIO_I2C_RxFullFlag))
{
}
*rxBuff++ = FLEXIO_I2C_MasterReadByte(base);
}
}
status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_callback_t callback,
void *userData)
{
assert(handle);
IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
/* Zero the handle. */
memset(handle, 0, sizeof(*handle));
/* Register callback and userData. */
handle->completionCallback = callback;
handle->userData = userData;
/* Enable interrupt in NVIC. */
EnableIRQ(flexio_irqs[0]);
/* Save the context in global variables to support the double weak mechanism. */
return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2C_MasterTransferHandleIRQ);
}
status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_t *xfer)
{
assert(handle);
assert(xfer);
if (handle->state != kFLEXIO_I2C_Idle)
{
return kStatus_FLEXIO_I2C_Busy;
}
else
{
/* Set up transfer machine. */
FLEXIO_I2C_MasterTransferInitStateMachine(base, handle, xfer);
/* Enable both tx empty and rxfull interrupt. */
FLEXIO_I2C_MasterEnableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
return kStatus_Success;
}
}
void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle)
{
assert(handle);
/* Disable interrupts. */
FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
/* Reset to idle state. */
handle->state = kFLEXIO_I2C_Idle;
}
status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count)
{
if (!count)
{
return kStatus_InvalidArgument;
}
*count = handle->transferSize - handle->transfer.dataSize;
return kStatus_Success;
}
void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle)
{
FLEXIO_I2C_Type *base = (FLEXIO_I2C_Type *)i2cType;
flexio_i2c_master_handle_t *handle = (flexio_i2c_master_handle_t *)i2cHandle;
uint32_t statusFlags;
status_t result;
statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base);
result = FLEXIO_I2C_MasterTransferRunStateMachine(base, handle, statusFlags);
if (handle->state == kFLEXIO_I2C_Idle)
{
FLEXIO_I2C_MasterTransferComplete(base, handle, result);
}
}

View File

@ -1,490 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_FLEXIO_I2C_MASTER_H_
#define _FSL_FLEXIO_I2C_MASTER_H_
#include "fsl_common.h"
#include "fsl_flexio.h"
/*!
* @addtogroup flexio_i2c_master
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief FlexIO I2C master driver version 2.1.0. */
#define FSL_FLEXIO_I2C_MASTER_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
/*@}*/
/*! @brief FlexIO I2C transfer status*/
enum _flexio_i2c_status
{
kStatus_FLEXIO_I2C_Busy = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 0), /*!< I2C is busy doing transfer. */
kStatus_FLEXIO_I2C_Idle = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 1), /*!< I2C is busy doing transfer. */
kStatus_FLEXIO_I2C_Nak = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 2), /*!< NAK received during transfer. */
};
/*! @brief Define FlexIO I2C master interrupt mask. */
enum _flexio_i2c_master_interrupt
{
kFLEXIO_I2C_TxEmptyInterruptEnable = 0x1U, /*!< Tx buffer empty interrupt enable. */
kFLEXIO_I2C_RxFullInterruptEnable = 0x2U, /*!< Rx buffer full interrupt enable. */
};
/*! @brief Define FlexIO I2C master status mask. */
enum _flexio_i2c_master_status_flags
{
kFLEXIO_I2C_TxEmptyFlag = 0x1U, /*!< Tx shifter empty flag. */
kFLEXIO_I2C_RxFullFlag = 0x2U, /*!< Rx shifter full/Transfer complete flag. */
kFLEXIO_I2C_ReceiveNakFlag = 0x4U, /*!< Receive NAK flag. */
};
/*! @brief Direction of master transfer.*/
typedef enum _flexio_i2c_direction
{
kFLEXIO_I2C_Write = 0x0U, /*!< Master send to slave. */
kFLEXIO_I2C_Read = 0x1U, /*!< Master receive from slave. */
} flexio_i2c_direction_t;
/*! @brief Define FlexIO I2C master access structure typedef. */
typedef struct _flexio_i2c_type
{
FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */
uint8_t SDAPinIndex; /*!< Pin select for I2C SDA. */
uint8_t SCLPinIndex; /*!< Pin select for I2C SCL. */
uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO I2C. */
uint8_t timerIndex[2]; /*!< Timer index used in FlexIO I2C. */
} FLEXIO_I2C_Type;
/*! @brief Define FlexIO I2C master user configuration structure. */
typedef struct _flexio_i2c_master_config
{
bool enableMaster; /*!< Enables the FLEXIO I2C peripheral at initialization time. */
bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode. */
bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode. */
bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, fast access requires
the FlexIO clock to be at least twice the frequency of the bus clock. */
uint32_t baudRate_Bps; /*!< Baud rate in Bps. */
} flexio_i2c_master_config_t;
/*! @brief Define FlexIO I2C master transfer structure. */
typedef struct _flexio_i2c_master_transfer
{
uint32_t flags; /*!< Transfer flag which controls the transfer, reserved for flexio i2c. */
uint8_t slaveAddress; /*!< 7-bit slave address. */
flexio_i2c_direction_t direction; /*!< Transfer direction, read or write. */
uint32_t subaddress; /*!< Sub address. Transferred MSB first. */
uint8_t subaddressSize; /*!< Size of command buffer. */
uint8_t volatile *data; /*!< Transfer buffer. */
volatile size_t dataSize; /*!< Transfer size. */
} flexio_i2c_master_transfer_t;
/*! @brief FlexIO I2C master handle typedef. */
typedef struct _flexio_i2c_master_handle flexio_i2c_master_handle_t;
/*! @brief FlexIO I2C master transfer callback typedef. */
typedef void (*flexio_i2c_master_transfer_callback_t)(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
status_t status,
void *userData);
/*! @brief Define FlexIO I2C master handle structure. */
struct _flexio_i2c_master_handle
{
flexio_i2c_master_transfer_t transfer; /*!< FlexIO I2C master transfer copy. */
size_t transferSize; /*!< Total bytes to be transferred. */
uint8_t state; /*!< Transfer state maintained during transfer. */
flexio_i2c_master_transfer_callback_t completionCallback; /*!< Callback function called at transfer event. */
/*!< Callback function called at transfer event. */
void *userData; /*!< Callback parameter passed to callback function. */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus*/
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO I2C
* hardware configuration.
*
* Example
@code
FLEXIO_I2C_Type base = {
.flexioBase = FLEXIO,
.SDAPinIndex = 0,
.SCLPinIndex = 1,
.shifterIndex = {0,1},
.timerIndex = {0,1}
};
flexio_i2c_master_config_t config = {
.enableInDoze = false,
.enableInDebug = true,
.enableFastAccess = false,
.baudRate_Bps = 100000
};
FLEXIO_I2C_MasterInit(base, &config, srcClock_Hz);
@endcode
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param masterConfig pointer to flexio_i2c_master_config_t structure.
* @param srcClock_Hz FlexIO source clock in Hz.
*/
void FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz);
/*!
* @brief De-initializes the FlexIO I2C master peripheral. Calling this API gates the FlexIO clock,
* so the FlexIO I2C master module can't work unless call FLEXIO_I2C_MasterInit.
*
* @param base pointer to FLEXIO_I2C_Type structure.
*/
void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base);
/*!
* @brief Gets the default configuration to configure the FlexIO module. The configuration
* can be used directly for calling FLEXIO_I2C_MasterInit().
*
* Example:
@code
flexio_i2c_master_config_t config;
FLEXIO_I2C_MasterGetDefaultConfig(&config);
@endcode
* @param masterConfig pointer to flexio_i2c_master_config_t structure.
*/
void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig);
/*!
* @brief Enables/disables the FlexIO module operation.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param enable pass true to enable module, false to disable module.
*/
static inline void FLEXIO_I2C_MasterEnable(FLEXIO_I2C_Type *base, bool enable)
{
if (enable)
{
base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
}
else
{
base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK;
}
}
/* @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Gets the FlexIO I2C master status flags.
*
* @param base pointer to FLEXIO_I2C_Type structure
* @return status flag, use status flag to AND #_flexio_i2c_master_status_flags could get the related status.
*/
uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base);
/*!
* @brief Clears the FlexIO I2C master status flags.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param mask status flag.
* The parameter could be any combination of the following values:
* @arg kFLEXIO_I2C_RxFullFlag
* @arg kFLEXIO_I2C_ReceiveNakFlag
*/
void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask);
/*@}*/
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables the FlexIO i2c master interrupt requests.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param mask interrupt source.
* Currently only one interrupt request source:
* @arg kFLEXIO_I2C_TransferCompleteInterruptEnable
*/
void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask);
/*!
* @brief Disables the FlexIO I2C master interrupt requests.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param mask interrupt source.
*/
void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask);
/*@}*/
/*!
* @name Bus Operations
* @{
*/
/*!
* @brief Sets the FlexIO I2C master transfer baudrate.
*
* @param base pointer to FLEXIO_I2C_Type structure
* @param baudRate_Bps the baud rate value in HZ
* @param srcClock_Hz source clock in HZ
*/
void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
/*!
* @brief Sends START + 7-bit address to the bus.
*
* @note This is API should be called when transfer configuration is ready to send a START signal
* and 7-bit address to the bus. This is a non-blocking API, which returns directly after the address
* is put into the data register but not address transfer finished on the bus. Ensure that
* the kFLEXIO_I2C_RxFullFlag status is asserted before calling this API.
* @param base pointer to FLEXIO_I2C_Type structure.
* @param address 7-bit address.
* @param direction transfer direction.
* This parameter is one of the values in flexio_i2c_direction_t:
* @arg kFLEXIO_I2C_Write: Transmit
* @arg kFLEXIO_I2C_Read: Receive
*/
void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction);
/*!
* @brief Sends the stop signal on the bus.
*
* @param base pointer to FLEXIO_I2C_Type structure.
*/
void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base);
/*!
* @brief Sends the repeated start signal on the bus.
*
* @param base pointer to FLEXIO_I2C_Type structure.
*/
void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base);
/*!
* @brief Sends the stop signal when transfer is still on-going.
*
* @param base pointer to FLEXIO_I2C_Type structure.
*/
void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base);
/*!
* @brief Configures the sent ACK/NAK for the following byte.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param enable true to configure send ACK, false configure to send NAK.
*/
void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable);
/*!
* @brief Sets the number of bytes to be transferred from a start signal to a stop signal.
*
* @note Call this API before a transfer begins because the timer generates a number of clocks according
* to the number of bytes that need to be transferred.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param count number of bytes need to be transferred from a start signal to a re-start/stop signal
* @retval kStatus_Success Successfully configured the count.
* @retval kStatus_InvalidArgument Input argument is invalid.
*/
status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint8_t count);
/*!
* @brief Writes one byte of data to the I2C bus.
*
* @note This is a non-blocking API, which returns directly after the data is put into the
* data register but not data transfer finished on the bus. Ensure that
* the TxEmptyFlag is asserted before calling this API.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param data a byte of data.
*/
static inline void FLEXIO_I2C_MasterWriteByte(FLEXIO_I2C_Type *base, uint32_t data)
{
base->flexioBase->SHIFTBUFBBS[base->shifterIndex[0]] = data;
}
/*!
* @brief Reads one byte of data from the I2C bus.
*
* @note This is a non-blocking API, which returns directly after the data is read from the
* data register. Ensure that the data is ready in the register.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @return data byte read.
*/
static inline uint8_t FLEXIO_I2C_MasterReadByte(FLEXIO_I2C_Type *base)
{
return base->flexioBase->SHIFTBUFBIS[base->shifterIndex[1]];
}
/*!
* @brief Sends a buffer of data in bytes.
*
* @note This function blocks via polling until all bytes have been sent.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param txBuff The data bytes to send.
* @param txSize The number of data bytes to send.
* @retval kStatus_Success Successfully write data.
* @retval kStatus_FLEXIO_I2C_Nak Receive NAK during writing data.
*/
status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize);
/*!
* @brief Receives a buffer of bytes.
*
* @note This function blocks via polling until all bytes have been received.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param rxBuff The buffer to store the received bytes.
* @param rxSize The number of data bytes to be received.
*/
void FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize);
/*!
* @brief Performs a master polling transfer on the I2C bus.
*
* @note The API does not return until the transfer succeeds or fails due
* to receiving NAK.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state.
* @param xfer pointer to flexio_i2c_master_transfer_t structure.
* @return status of status_t.
*/
status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_t *xfer);
/*@}*/
/*Transactional APIs*/
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the I2C handle which is used in transactional functions.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param handle pointer to flexio_i2c_master_handle_t structure to store the transfer state.
* @param callback pointer to user callback function.
* @param userData user param passed to the callback function.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO type/handle/isr table out of range.
*/
status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_callback_t callback,
void *userData);
/*!
* @brief Performs a master interrupt non-blocking transfer on the I2C bus.
*
* @note The API returns immediately after the transfer initiates.
* Call FLEXIO_I2C_MasterGetTransferCount to poll the transfer status to check whether
* the transfer is finished. If the return status is not kStatus_FLEXIO_I2C_Busy, the transfer
* is finished.
*
* @param base pointer to FLEXIO_I2C_Type structure
* @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
* @param xfer pointer to flexio_i2c_master_transfer_t structure
* @retval kStatus_Success Successfully start a transfer.
* @retval kStatus_FLEXIO_I2C_Busy FLEXIO I2C is not idle, is running another transfer.
*/
status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_t *xfer);
/*!
* @brief Gets the master transfer status during a interrupt non-blocking transfer.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state.
* @param count Number of bytes transferred so far by the non-blocking transaction.
* @retval kStatus_InvalidArgument count is Invalid.
* @retval kStatus_Success Successfully return the count.
*/
status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count);
/*!
* @brief Aborts an interrupt non-blocking transfer early.
*
* @note This API can be called at any time when an interrupt non-blocking transfer initiates
* to abort the transfer early.
*
* @param base pointer to FLEXIO_I2C_Type structure
* @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
*/
void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle);
/*!
* @brief Master interrupt handler.
*
* @param i2cType pointer to FLEXIO_I2C_Type structure
* @param i2cHandle pointer to flexio_i2c_master_transfer_t structure
*/
void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle);
/*@}*/
#if defined(__cplusplus)
}
#endif /*_cplusplus*/
/*@}*/
#endif /*_FSL_FLEXIO_I2C_MASTER_H_*/

View File

@ -1,637 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_flexio_i2s.h"
/*******************************************************************************
* Definitations
******************************************************************************/
enum _sai_transfer_state
{
kFLEXIO_I2S_Busy = 0x0U, /*!< FLEXIO_I2S is busy */
kFLEXIO_I2S_Idle, /*!< Transfer is done. */
};
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Receive a piece of data in non-blocking way.
*
* @param base FLEXIO I2S base pointer
* @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
* @param buffer Pointer to the data to be read.
* @param size Bytes to be read.
*/
static void FLEXIO_I2S_ReadNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size);
/*!
* @brief sends a piece of data in non-blocking way.
*
* @param base FLEXIO I2S base pointer
* @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
* @param buffer Pointer to the data to be written.
* @param size Bytes to be written.
*/
static void FLEXIO_I2S_WriteNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size);
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
static void FLEXIO_I2S_WriteNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size)
{
uint32_t i = 0;
uint8_t j = 0;
uint8_t bytesPerWord = bitWidth / 8U;
uint32_t data = 0;
uint32_t temp = 0;
for (i = 0; i < size / bytesPerWord; i++)
{
for (j = 0; j < bytesPerWord; j++)
{
temp = (uint32_t)(*txData);
data |= (temp << (8U * j));
txData++;
}
base->flexioBase->SHIFTBUFBIS[base->txShifterIndex] = (data << (32U - bitWidth));
data = 0;
}
}
static void FLEXIO_I2S_ReadNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size)
{
uint32_t i = 0;
uint8_t j = 0;
uint8_t bytesPerWord = bitWidth / 8U;
uint32_t data = 0;
for (i = 0; i < size / bytesPerWord; i++)
{
data = base->flexioBase->SHIFTBUFBIS[base->rxShifterIndex];
for (j = 0; j < bytesPerWord; j++)
{
*rxData = (data >> (8U * j)) & 0xFF;
rxData++;
}
}
}
void FLEXIO_I2S_Init(FLEXIO_I2S_Type *base, const flexio_i2s_config_t *config)
{
assert(base && config);
flexio_shifter_config_t shifterConfig = {0};
flexio_timer_config_t timerConfig = {0};
/* Ungate flexio clock. */
CLOCK_EnableClock(kCLOCK_Flexio0);
FLEXIO_Reset(base->flexioBase);
/* Set shifter for I2S Tx data */
shifterConfig.timerSelect = base->bclkTimerIndex;
shifterConfig.pinSelect = base->txPinIndex;
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
shifterConfig.pinConfig = kFLEXIO_PinConfigOutput;
shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
if (config->masterSlave == kFLEXIO_I2S_Master)
{
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift;
}
else
{
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
}
FLEXIO_SetShifterConfig(base->flexioBase, base->txShifterIndex, &shifterConfig);
/* Set shifter for I2S Rx Data */
shifterConfig.timerSelect = base->bclkTimerIndex;
shifterConfig.pinSelect = base->rxPinIndex;
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
FLEXIO_SetShifterConfig(base->flexioBase, base->rxShifterIndex, &shifterConfig);
/* Set Timer to I2S frame sync */
if (config->masterSlave == kFLEXIO_I2S_Master)
{
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->bclkTimerIndex);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceExternal;
timerConfig.pinConfig = kFLEXIO_PinConfigOutput;
timerConfig.pinSelect = base->fsPinIndex;
timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
timerConfig.timerReset = kFLEXIO_TimerResetNever;
timerConfig.timerDisable = kFLEXIO_TimerDisableNever;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable;
timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
}
else
{
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->bclkPinIndex);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
timerConfig.pinSelect = base->fsPinIndex;
timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnTriggerInputShiftTriggerInput;
timerConfig.timerReset = kFLEXIO_TimerResetNever;
timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdge;
timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
}
FLEXIO_SetTimerConfig(base->flexioBase, base->fsTimerIndex, &timerConfig);
/* Set Timer to I2S bit clock */
if (config->masterSlave == kFLEXIO_I2S_Master)
{
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->txShifterIndex);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timerConfig.pinSelect = base->bclkPinIndex;
timerConfig.pinConfig = kFLEXIO_PinConfigOutput;
timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
timerConfig.timerReset = kFLEXIO_TimerResetNever;
timerConfig.timerDisable = kFLEXIO_TimerDisableNever;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
}
else
{
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->fsTimerIndex);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timerConfig.pinSelect = base->bclkPinIndex;
timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
timerConfig.timerReset = kFLEXIO_TimerResetNever;
timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompareTriggerLow;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdgeTriggerHigh;
timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
}
FLEXIO_SetTimerConfig(base->flexioBase, base->bclkTimerIndex, &timerConfig);
/* If enable flexio I2S */
if (config->enableI2S)
{
base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
}
else
{
base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK;
}
}
void FLEXIO_I2S_GetDefaultConfig(flexio_i2s_config_t *config)
{
config->masterSlave = kFLEXIO_I2S_Master;
config->enableI2S = true;
}
void FLEXIO_I2S_Deinit(FLEXIO_I2S_Type *base)
{
/* Disable FLEXIO I2S module. */
FLEXIO_I2S_Enable(base, false);
/* Gate flexio clock. */
CLOCK_DisableClock(kCLOCK_Flexio0);
}
void FLEXIO_I2S_EnableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_I2S_TxDataRegEmptyInterruptEnable)
{
FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->txShifterIndex);
}
if (mask & kFLEXIO_I2S_RxDataRegFullInterruptEnable)
{
FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->rxShifterIndex);
}
}
uint32_t FLEXIO_I2S_GetStatusFlags(FLEXIO_I2S_Type *base)
{
uint32_t status = 0;
status = ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->txShifterIndex)) >> base->txShifterIndex);
status |=
(((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->rxShifterIndex)) >> (base->rxShifterIndex))
<< 1U);
return status;
}
void FLEXIO_I2S_DisableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_I2S_TxDataRegEmptyInterruptEnable)
{
FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->txShifterIndex);
}
if (mask & kFLEXIO_I2S_RxDataRegFullInterruptEnable)
{
FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->rxShifterIndex);
}
}
void FLEXIO_I2S_MasterSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format, uint32_t srcClock_Hz)
{
uint32_t timDiv = srcClock_Hz / (format->sampleRate_Hz * 32U * 2U);
uint32_t bclkDiv = 0;
/* Set Frame sync timer cmp */
base->flexioBase->TIMCMP[base->fsTimerIndex] = FLEXIO_TIMCMP_CMP(32U * timDiv - 1U);
/* Set bit clock timer cmp */
bclkDiv = ((timDiv / 2U - 1U) | (63U << 8U));
base->flexioBase->TIMCMP[base->bclkTimerIndex] = FLEXIO_TIMCMP_CMP(bclkDiv);
}
void FLEXIO_I2S_SlaveSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format)
{
/* Set Frame sync timer cmp */
base->flexioBase->TIMCMP[base->fsTimerIndex] = FLEXIO_TIMCMP_CMP(format->bitWidth * 4U - 3U);
/* Set bit clock timer cmp */
base->flexioBase->TIMCMP[base->bclkTimerIndex] = FLEXIO_TIMCMP_CMP(format->bitWidth * 2U - 1U);
}
void FLEXIO_I2S_WriteBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size)
{
uint32_t i = 0;
uint8_t bytesPerWord = bitWidth / 8U;
for (i = 0; i < size / bytesPerWord; i++)
{
/* Wait until it can write data */
while ((FLEXIO_I2S_GetStatusFlags(base) & kFLEXIO_I2S_TxDataRegEmptyFlag) == 0)
{
}
FLEXIO_I2S_WriteNonBlocking(base, bitWidth, txData, bytesPerWord);
txData += bytesPerWord;
}
/* Wait until the last data is sent */
while ((FLEXIO_I2S_GetStatusFlags(base) & kFLEXIO_I2S_TxDataRegEmptyFlag) == 0)
{
}
}
void FLEXIO_I2S_ReadBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size)
{
uint32_t i = 0;
uint8_t bytesPerWord = bitWidth / 8U;
for (i = 0; i < size / bytesPerWord; i++)
{
/* Wait until data is received */
while (!(FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->rxShifterIndex)))
{
}
FLEXIO_I2S_ReadNonBlocking(base, bitWidth, rxData, bytesPerWord);
rxData += bytesPerWord;
}
}
void FLEXIO_I2S_TransferTxCreateHandle(FLEXIO_I2S_Type *base,
flexio_i2s_handle_t *handle,
flexio_i2s_callback_t callback,
void *userData)
{
assert(handle);
IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
/* Zero the handle. */
memset(handle, 0, sizeof(*handle));
/* Store callback and user data. */
handle->callback = callback;
handle->userData = userData;
/* Save the context in global variables to support the double weak mechanism. */
FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2S_TransferTxHandleIRQ);
/* Set the TX/RX state. */
handle->state = kFLEXIO_I2S_Idle;
/* Enable interrupt in NVIC. */
EnableIRQ(flexio_irqs[0]);
}
void FLEXIO_I2S_TransferRxCreateHandle(FLEXIO_I2S_Type *base,
flexio_i2s_handle_t *handle,
flexio_i2s_callback_t callback,
void *userData)
{
assert(handle);
IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
/* Zero the handle. */
memset(handle, 0, sizeof(*handle));
/* Store callback and user data. */
handle->callback = callback;
handle->userData = userData;
/* Save the context in global variables to support the double weak mechanism. */
FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2S_TransferRxHandleIRQ);
/* Set the TX/RX state. */
handle->state = kFLEXIO_I2S_Idle;
/* Enable interrupt in NVIC. */
EnableIRQ(flexio_irqs[0]);
}
void FLEXIO_I2S_TransferSetFormat(FLEXIO_I2S_Type *base,
flexio_i2s_handle_t *handle,
flexio_i2s_format_t *format,
uint32_t srcClock_Hz)
{
assert(handle && format);
/* Set the bitWidth to handle */
handle->bitWidth = format->bitWidth;
/* Set sample rate */
if (srcClock_Hz != 0)
{
/* It is master */
FLEXIO_I2S_MasterSetFormat(base, format, srcClock_Hz);
}
else
{
FLEXIO_I2S_SlaveSetFormat(base, format);
}
}
status_t FLEXIO_I2S_TransferSendNonBlocking(FLEXIO_I2S_Type *base,
flexio_i2s_handle_t *handle,
flexio_i2s_transfer_t *xfer)
{
assert(handle);
/* Check if the queue is full */
if (handle->queue[handle->queueUser].data)
{
return kStatus_FLEXIO_I2S_QueueFull;
}
if ((xfer->dataSize == 0) || (xfer->data == NULL))
{
return kStatus_InvalidArgument;
}
/* Add into queue */
handle->queue[handle->queueUser].data = xfer->data;
handle->queue[handle->queueUser].dataSize = xfer->dataSize;
handle->transferSize[handle->queueUser] = xfer->dataSize;
handle->queueUser = (handle->queueUser + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE;
/* Set the state to busy */
handle->state = kFLEXIO_I2S_Busy;
FLEXIO_I2S_EnableInterrupts(base, kFLEXIO_I2S_TxDataRegEmptyInterruptEnable);
/* Enable Tx transfer */
FLEXIO_I2S_Enable(base, true);
return kStatus_Success;
}
status_t FLEXIO_I2S_TransferReceiveNonBlocking(FLEXIO_I2S_Type *base,
flexio_i2s_handle_t *handle,
flexio_i2s_transfer_t *xfer)
{
assert(handle);
/* Check if the queue is full */
if (handle->queue[handle->queueUser].data)
{
return kStatus_FLEXIO_I2S_QueueFull;
}
if ((xfer->dataSize == 0) || (xfer->data == NULL))
{
return kStatus_InvalidArgument;
}
/* Add into queue */
handle->queue[handle->queueUser].data = xfer->data;
handle->queue[handle->queueUser].dataSize = xfer->dataSize;
handle->transferSize[handle->queueUser] = xfer->dataSize;
handle->queueUser = (handle->queueUser + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE;
/* Set state to busy */
handle->state = kFLEXIO_I2S_Busy;
/* Enable interrupt */
FLEXIO_I2S_EnableInterrupts(base, kFLEXIO_I2S_RxDataRegFullInterruptEnable);
/* Enable Rx transfer */
FLEXIO_I2S_Enable(base, true);
return kStatus_Success;
}
void FLEXIO_I2S_TransferAbortSend(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle)
{
assert(handle);
/* Stop Tx transfer and disable interrupt */
FLEXIO_I2S_Enable(base, false);
FLEXIO_I2S_DisableInterrupts(base, kFLEXIO_I2S_TxDataRegEmptyInterruptEnable);
handle->state = kFLEXIO_I2S_Idle;
/* Clear the queue */
memset(handle->queue, 0, sizeof(flexio_i2s_transfer_t) * FLEXIO_I2S_XFER_QUEUE_SIZE);
handle->queueDriver = 0;
handle->queueUser = 0;
}
void FLEXIO_I2S_TransferAbortReceive(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle)
{
assert(handle);
/* Stop Tx transfer and disable interrupt */
FLEXIO_I2S_Enable(base, false);
FLEXIO_I2S_DisableInterrupts(base, kFLEXIO_I2S_RxDataRegFullInterruptEnable);
handle->state = kFLEXIO_I2S_Idle;
/* Clear the queue */
memset(handle->queue, 0, sizeof(flexio_i2s_transfer_t) * FLEXIO_I2S_XFER_QUEUE_SIZE);
handle->queueDriver = 0;
handle->queueUser = 0;
}
status_t FLEXIO_I2S_TransferGetSendCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count)
{
assert(handle);
status_t status = kStatus_Success;
if (handle->state != kFLEXIO_I2S_Busy)
{
status = kStatus_NoTransferInProgress;
}
else
{
*count = (handle->transferSize[handle->queueDriver] - handle->queue[handle->queueDriver].dataSize);
}
return status;
}
status_t FLEXIO_I2S_TransferGetReceiveCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count)
{
assert(handle);
status_t status = kStatus_Success;
if (handle->state != kFLEXIO_I2S_Busy)
{
status = kStatus_NoTransferInProgress;
}
else
{
*count = (handle->transferSize[handle->queueDriver] - handle->queue[handle->queueDriver].dataSize);
}
return status;
}
void FLEXIO_I2S_TransferTxHandleIRQ(void *i2sBase, void *i2sHandle)
{
assert(i2sHandle);
flexio_i2s_handle_t *handle = (flexio_i2s_handle_t *)i2sHandle;
FLEXIO_I2S_Type *base = (FLEXIO_I2S_Type *)i2sBase;
uint8_t *buffer = handle->queue[handle->queueDriver].data;
uint8_t dataSize = handle->bitWidth / 8U;
/* Handle error */
if (FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->txShifterIndex))
{
FLEXIO_ClearShifterErrorFlags(base->flexioBase, (1U << base->txShifterIndex));
}
/* Handle transfer */
if ((FLEXIO_I2S_GetStatusFlags(base) & kFLEXIO_I2S_TxDataRegEmptyFlag) != 0)
{
FLEXIO_I2S_WriteNonBlocking(base, handle->bitWidth, buffer, dataSize);
/* Update internal counter */
handle->queue[handle->queueDriver].dataSize -= dataSize;
handle->queue[handle->queueDriver].data += dataSize;
}
/* If finished a blcok, call the callback function */
if (handle->queue[handle->queueDriver].dataSize == 0U)
{
memset(&handle->queue[handle->queueDriver], 0, sizeof(flexio_i2s_transfer_t));
handle->queueDriver = (handle->queueDriver + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE;
if (handle->callback)
{
(handle->callback)(base, handle, kStatus_Success, handle->userData);
}
}
/* If all data finished, just stop the transfer */
if (handle->queue[handle->queueDriver].data == NULL)
{
FLEXIO_I2S_TransferAbortSend(base, handle);
}
}
void FLEXIO_I2S_TransferRxHandleIRQ(void *i2sBase, void *i2sHandle)
{
assert(i2sHandle);
flexio_i2s_handle_t *handle = (flexio_i2s_handle_t *)i2sHandle;
FLEXIO_I2S_Type *base = (FLEXIO_I2S_Type *)i2sBase;
uint8_t *buffer = handle->queue[handle->queueDriver].data;
uint8_t dataSize = handle->bitWidth / 8U;
/* Handle transfer */
if ((FLEXIO_I2S_GetStatusFlags(base) & kFLEXIO_I2S_RxDataRegFullFlag) != 0)
{
FLEXIO_I2S_ReadNonBlocking(base, handle->bitWidth, buffer, dataSize);
/* Update internal state */
handle->queue[handle->queueDriver].dataSize -= dataSize;
handle->queue[handle->queueDriver].data += dataSize;
}
/* If finished a blcok, call the callback function */
if (handle->queue[handle->queueDriver].dataSize == 0U)
{
memset(&handle->queue[handle->queueDriver], 0, sizeof(flexio_i2s_transfer_t));
handle->queueDriver = (handle->queueDriver + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE;
if (handle->callback)
{
(handle->callback)(base, handle, kStatus_Success, handle->userData);
}
}
/* If all data finished, just stop the transfer */
if (handle->queue[handle->queueDriver].data == NULL)
{
FLEXIO_I2S_TransferAbortReceive(base, handle);
}
}

View File

@ -1,570 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_FLEXIO_I2S_H_
#define _FSL_FLEXIO_I2S_H_
#include "fsl_common.h"
#include "fsl_flexio.h"
/*!
* @addtogroup flexio_i2s
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief FlexIO I2S driver version 2.1.0. */
#define FSL_FLEXIO_I2S_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
/*@}*/
/*! @brief FlexIO I2S transfer status */
enum _flexio_i2s_status
{
kStatus_FLEXIO_I2S_Idle = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 0), /*!< FlexIO I2S is in idle state */
kStatus_FLEXIO_I2S_TxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 1), /*!< FlexIO I2S Tx is busy */
kStatus_FLEXIO_I2S_RxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 2), /*!< FlexIO I2S Tx is busy */
kStatus_FLEXIO_I2S_Error = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 3), /*!< FlexIO I2S error occurred */
kStatus_FLEXIO_I2S_QueueFull = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 4), /*!< FlexIO I2S transfer queue is full. */
};
/*! @brief Define FlexIO I2S access structure typedef */
typedef struct _flexio_i2s_type
{
FLEXIO_Type *flexioBase; /*!< FlexIO base pointer */
uint8_t txPinIndex; /*!< Tx data pin index in FlexIO pins */
uint8_t rxPinIndex; /*!< Rx data pin index */
uint8_t bclkPinIndex; /*!< Bit clock pin index */
uint8_t fsPinIndex; /*!< Frame sync pin index */
uint8_t txShifterIndex; /*!< Tx data shifter index */
uint8_t rxShifterIndex; /*!< Rx data shifter index */
uint8_t bclkTimerIndex; /*!< Bit clock timer index */
uint8_t fsTimerIndex; /*!< Frame sync timer index */
} FLEXIO_I2S_Type;
/*! @brief Master or slave mode */
typedef enum _flexio_i2s_master_slave
{
kFLEXIO_I2S_Master = 0x0U, /*!< Master mode */
kFLEXIO_I2S_Slave = 0x1U /*!< Slave mode */
} flexio_i2s_master_slave_t;
/*! @brief Define FlexIO FlexIO I2S interrupt mask. */
enum _flexio_i2s_interrupt_enable
{
kFLEXIO_I2S_TxDataRegEmptyInterruptEnable = 0x1U, /*!< Transmit buffer empty interrupt enable. */
kFLEXIO_I2S_RxDataRegFullInterruptEnable = 0x2U, /*!< Receive buffer full interrupt enable. */
};
/*! @brief Define FlexIO FlexIO I2S status mask. */
enum _flexio_i2s_status_flags
{
kFLEXIO_I2S_TxDataRegEmptyFlag = 0x1U, /*!< Transmit buffer empty flag. */
kFLEXIO_I2S_RxDataRegFullFlag = 0x2U, /*!< Receive buffer full flag. */
};
/*! @brief FlexIO I2S configure structure */
typedef struct _flexio_i2s_config
{
bool enableI2S; /*!< Enable FlexIO I2S */
flexio_i2s_master_slave_t masterSlave; /*!< Master or slave */
} flexio_i2s_config_t;
/*! @brief FlexIO I2S audio format, FlexIO I2S only support the same format in Tx and Rx */
typedef struct _flexio_i2s_format
{
uint8_t bitWidth; /*!< Bit width of audio data, always 8/16/24/32 bits */
uint32_t sampleRate_Hz; /*!< Sample rate of the audio data */
} flexio_i2s_format_t;
/*!@brief FlexIO I2S transfer queue size, user can refine it according to use case. */
#define FLEXIO_I2S_XFER_QUEUE_SIZE (4)
/*! @brief Audio sample rate */
typedef enum _flexio_i2s_sample_rate
{
kFLEXIO_I2S_SampleRate8KHz = 8000U, /*!< Sample rate 8000Hz */
kFLEXIO_I2S_SampleRate11025Hz = 11025U, /*!< Sample rate 11025Hz */
kFLEXIO_I2S_SampleRate12KHz = 12000U, /*!< Sample rate 12000Hz */
kFLEXIO_I2S_SampleRate16KHz = 16000U, /*!< Sample rate 16000Hz */
kFLEXIO_I2S_SampleRate22050Hz = 22050U, /*!< Sample rate 22050Hz */
kFLEXIO_I2S_SampleRate24KHz = 24000U, /*!< Sample rate 24000Hz */
kFLEXIO_I2S_SampleRate32KHz = 32000U, /*!< Sample rate 32000Hz */
kFLEXIO_I2S_SampleRate44100Hz = 44100U, /*!< Sample rate 44100Hz */
kFLEXIO_I2S_SampleRate48KHz = 48000U, /*!< Sample rate 48000Hz */
kFLEXIO_I2S_SampleRate96KHz = 96000U /*!< Sample rate 96000Hz */
} flexio_i2s_sample_rate_t;
/*! @brief Audio word width */
typedef enum _flexio_i2s_word_width
{
kFLEXIO_I2S_WordWidth8bits = 8U, /*!< Audio data width 8 bits */
kFLEXIO_I2S_WordWidth16bits = 16U, /*!< Audio data width 16 bits */
kFLEXIO_I2S_WordWidth24bits = 24U, /*!< Audio data width 24 bits */
kFLEXIO_I2S_WordWidth32bits = 32U /*!< Audio data width 32 bits */
} flexio_i2s_word_width_t;
/*! @brief Define FlexIO I2S transfer structure. */
typedef struct _flexio_i2s_transfer
{
uint8_t *data; /*!< Data buffer start pointer */
size_t dataSize; /*!< Bytes to be transferred. */
} flexio_i2s_transfer_t;
typedef struct _flexio_i2s_handle flexio_i2s_handle_t;
/*! @brief FlexIO I2S xfer callback prototype */
typedef void (*flexio_i2s_callback_t)(FLEXIO_I2S_Type *base,
flexio_i2s_handle_t *handle,
status_t status,
void *userData);
/*! @brief Define FlexIO I2S handle structure. */
struct _flexio_i2s_handle
{
uint32_t state; /*!< Internal state */
flexio_i2s_callback_t callback; /*!< Callback function called at transfer event*/
void *userData; /*!< Callback parameter passed to callback function*/
uint8_t bitWidth; /*!< Bit width for transfer, 8/16/24/32bits */
flexio_i2s_transfer_t queue[FLEXIO_I2S_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer */
size_t transferSize[FLEXIO_I2S_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */
volatile uint8_t queueUser; /*!< Index for user to queue transfer */
volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus*/
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes the FlexIO I2S.
*
* This API configures FlexIO pins and shifter to I2S and configure FlexIO I2S with configuration structure.
* The configuration structure can be filled by the user, or be set with default values by
* FLEXIO_I2S_GetDefaultConfig().
*
* @note This API should be called at the beginning of the application to use
* the FlexIO I2S driver, or any access to the FlexIO I2S module could cause hard fault
* because clock is not enabled.
*
* @param base FlexIO I2S base pointer
* @param config FlexIO I2S configure structure.
*/
void FLEXIO_I2S_Init(FLEXIO_I2S_Type *base, const flexio_i2s_config_t *config);
/*!
* @brief Sets the FlexIO I2S configuration structure to default values.
*
* The purpose of this API is to get the configuration structure initialized for use in FLEXIO_I2S_Init().
* User may use the initialized structure unchanged in FLEXIO_I2S_Init(), or modify
* some fields of the structure before calling FLEXIO_I2S_Init().
*
* @param config pointer to master configuration structure
*/
void FLEXIO_I2S_GetDefaultConfig(flexio_i2s_config_t *config);
/*!
* @brief De-initializes the FlexIO I2S.
*
* Calling this API gates the FlexIO i2s clock. After calling this API, call the FLEXO_I2S_Init to use the
* FlexIO I2S module.
*
* @param base FlexIO I2S base pointer
*/
void FLEXIO_I2S_Deinit(FLEXIO_I2S_Type *base);
/*!
* @brief Enables/disables the FlexIO I2S module operation.
*
* @param base pointer to FLEXIO_I2S_Type
* @param enable True to enable, false to disable.
*/
static inline void FLEXIO_I2S_Enable(FLEXIO_I2S_Type *base, bool enable)
{
if (enable)
{
base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
}
else
{
base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK;
}
}
/*! @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Gets the FlexIO I2S status flags.
*
* @param base pointer to FLEXIO_I2S_Type structure
* @return Status flag, which are ORed by the enumerators in the _flexio_i2s_status_flags.
*/
uint32_t FLEXIO_I2S_GetStatusFlags(FLEXIO_I2S_Type *base);
/*! @} */
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables the FlexIO I2S interrupt.
*
* This function enables the FlexIO UART interrupt.
*
* @param base pointer to FLEXIO_I2S_Type structure
* @param mask interrupt source
*/
void FLEXIO_I2S_EnableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask);
/*!
* @brief Disables the FlexIO I2S interrupt.
*
* This function enables the FlexIO UART interrupt.
*
* @param base pointer to FLEXIO_I2S_Type structure
* @param mask interrupt source
*/
void FLEXIO_I2S_DisableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask);
/*! @} */
/*!
* @name DMA Control
* @{
*/
/*!
* @brief Enables/disables the FlexIO I2S Tx DMA requests.
*
* @param base FlexIO I2S base pointer
* @param enable True means enable DMA, false means disable DMA.
*/
static inline void FLEXIO_I2S_TxEnableDMA(FLEXIO_I2S_Type *base, bool enable)
{
FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->txShifterIndex, enable);
}
/*!
* @brief Enables/disables the FlexIO I2S Rx DMA requests.
*
* @param base FlexIO I2S base pointer
* @param enable True means enable DMA, false means disable DMA.
*/
static inline void FLEXIO_I2S_RxEnableDMA(FLEXIO_I2S_Type *base, bool enable)
{
FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->rxShifterIndex, enable);
}
/*!
* @brief Gets the FlexIO I2S send data register address.
*
* This function returns the I2S data register address, mainly used by DMA/eDMA.
*
* @param base pointer to FLEXIO_I2S_Type structure
* @return FlexIO i2s send data register address.
*/
static inline uint32_t FLEXIO_I2S_TxGetDataRegisterAddress(FLEXIO_I2S_Type *base)
{
return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferBitSwapped, base->txShifterIndex);
}
/*!
* @brief Gets the FlexIO I2S receive data register address.
*
* This function returns the I2S data register address, mainly used by DMA/eDMA.
*
* @param base pointer to FLEXIO_I2S_Type structure
* @return FlexIO i2s receive data register address.
*/
static inline uint32_t FLEXIO_I2S_RxGetDataRegisterAddress(FLEXIO_I2S_Type *base)
{
return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferBitSwapped, base->rxShifterIndex);
}
/*! @} */
/*!
* @name Bus Operations
* @{
*/
/*!
* @brief Configures the FlexIO I2S audio format in master mode.
*
* Audio format can be changed in run-time of FlexIO I2S. This function configures the sample rate and audio data
* format to be transferred.
*
* @param base pointer to FLEXIO_I2S_Type structure
* @param format Pointer to FlexIO I2S audio data format structure.
* @param srcClock_Hz I2S master clock source frequency in Hz.
*/
void FLEXIO_I2S_MasterSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format, uint32_t srcClock_Hz);
/*!
* @brief Configures the FlexIO I2S audio format in slave mode.
*
* Audio format can be changed in run-time of FlexIO I2S. This function configures the sample rate and audio data
* format to be transferred.
*
* @param base pointer to FLEXIO_I2S_Type structure
* @param format Pointer to FlexIO I2S audio data format structure.
*/
void FLEXIO_I2S_SlaveSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format);
/*!
* @brief Sends a piece of data using a blocking method.
*
* @note This function blocks via polling until data is ready to be sent.
*
* @param base FlexIO I2S base pointer.
* @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
* @param txData Pointer to the data to be written.
* @param size Bytes to be written.
*/
void FLEXIO_I2S_WriteBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size);
/*!
* @brief Writes a data into data register.
*
* @param base FlexIO I2S base pointer.
* @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
* @param data Data to be written.
*/
static inline void FLEXIO_I2S_WriteData(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint32_t data)
{
base->flexioBase->SHIFTBUFBIS[base->txShifterIndex] = (data << (32U - bitWidth));
}
/*!
* @brief Receives a piece of data using a blocking method.
*
* @note This function blocks via polling until data is ready to be sent.
*
* @param base FlexIO I2S base pointer
* @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
* @param rxData Pointer to the data to be read.
* @param size Bytes to be read.
*/
void FLEXIO_I2S_ReadBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size);
/*!
* @brief Reads a data from the data register.
*
* @param base FlexIO I2S base pointer
* @return Data read from data register.
*/
static inline uint32_t FLEXIO_I2S_ReadData(FLEXIO_I2S_Type *base)
{
return base->flexioBase->SHIFTBUFBIS[base->rxShifterIndex];
}
/*! @} */
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the FlexIO I2S handle.
*
* This function initializes the FlexIO I2S handle which can be used for other
* FlexIO I2S transactional APIs. Call this API once to get the
* initialized handle.
*
* @param base pointer to FLEXIO_I2S_Type structure
* @param handle pointer to flexio_i2s_handle_t structure to store the transfer state.
* @param callback FlexIO I2S callback function, which is called while finished a block.
* @param userData User parameter for the FlexIO I2S callback.
*/
void FLEXIO_I2S_TransferTxCreateHandle(FLEXIO_I2S_Type *base,
flexio_i2s_handle_t *handle,
flexio_i2s_callback_t callback,
void *userData);
/*!
* @brief Configures the FlexIO I2S audio format.
*
* Audio format can be changed in run-time of FlexIO i2s. This function configures the sample rate and audio data
* format to be transferred.
*
* @param base pointer to FLEXIO_I2S_Type structure.
* @param handle FlexIO I2S handle pointer.
* @param format Pointer to audio data format structure.
* @param srcClock_Hz FlexIO I2S bit clock source frequency in Hz. This parameter should be 0 while in slave mode.
*/
void FLEXIO_I2S_TransferSetFormat(FLEXIO_I2S_Type *base,
flexio_i2s_handle_t *handle,
flexio_i2s_format_t *format,
uint32_t srcClock_Hz);
/*!
* @brief Initializes the FlexIO I2S receive handle.
*
* This function initializes the FlexIO I2S handle which can be used for other
* FlexIO I2S transactional APIs. Usually, user only need to call this API once to get the
* initialized handle.
*
* @param base pointer to FLEXIO_I2S_Type structure.
* @param handle pointer to flexio_i2s_handle_t structure to store the transfer state.
* @param callback FlexIO I2S callback function, which is called while finished a block.
* @param userData User parameter for the FlexIO I2S callback.
*/
void FLEXIO_I2S_TransferRxCreateHandle(FLEXIO_I2S_Type *base,
flexio_i2s_handle_t *handle,
flexio_i2s_callback_t callback,
void *userData);
/*!
* @brief Performs an interrupt non-blocking send transfer on FlexIO I2S.
*
* @note Calling the API returns immediately after transfer initiates.
* Call FLEXIO_I2S_GetRemainingBytes to poll the transfer status and check whether
* the transfer is finished. If the return status is 0, the transfer is finished.
*
* @param base pointer to FLEXIO_I2S_Type structure.
* @param handle pointer to flexio_i2s_handle_t structure which stores the transfer state
* @param xfer pointer to flexio_i2s_transfer_t structure
* @retval kStatus_Success Successfully start the data transmission.
* @retval kStatus_FLEXIO_I2S_TxBusy Previous transmission still not finished, data not all written to TX register yet.
* @retval kStatus_InvalidArgument The input parameter is invalid.
*/
status_t FLEXIO_I2S_TransferSendNonBlocking(FLEXIO_I2S_Type *base,
flexio_i2s_handle_t *handle,
flexio_i2s_transfer_t *xfer);
/*!
* @brief Performs an interrupt non-blocking receive transfer on FlexIO I2S.
*
* @note The API returns immediately after transfer initiates.
* Call FLEXIO_I2S_GetRemainingBytes to poll the transfer status to check whether
* the transfer is finished. If the return status is 0, the transfer is finished.
*
* @param base pointer to FLEXIO_I2S_Type structure.
* @param handle pointer to flexio_i2s_handle_t structure which stores the transfer state
* @param xfer pointer to flexio_i2s_transfer_t structure
* @retval kStatus_Success Successfully start the data receive.
* @retval kStatus_FLEXIO_I2S_RxBusy Previous receive still not finished.
* @retval kStatus_InvalidArgument The input parameter is invalid.
*/
status_t FLEXIO_I2S_TransferReceiveNonBlocking(FLEXIO_I2S_Type *base,
flexio_i2s_handle_t *handle,
flexio_i2s_transfer_t *xfer);
/*!
* @brief Aborts the current send.
*
* @note This API can be called at any time when interrupt non-blocking transfer initiates
* to abort the transfer in a early time.
*
* @param base pointer to FLEXIO_I2S_Type structure.
* @param handle pointer to flexio_i2s_handle_t structure which stores the transfer state
*/
void FLEXIO_I2S_TransferAbortSend(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle);
/*!
* @brief Aborts the current receive.
*
* @note This API can be called at any time when interrupt non-blocking transfer initiates
* to abort the transfer in a early time.
*
* @param base pointer to FLEXIO_I2S_Type structure.
* @param handle pointer to flexio_i2s_handle_t structure which stores the transfer state
*/
void FLEXIO_I2S_TransferAbortReceive(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle);
/*!
* @brief Gets the remaining bytes to be sent.
*
* @param base pointer to FLEXIO_I2S_Type structure.
* @param handle pointer to flexio_i2s_handle_t structure which stores the transfer state
* @param count Bytes sent.
* @retval kStatus_Success Succeed get the transfer count.
* @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
*/
status_t FLEXIO_I2S_TransferGetSendCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count);
/*!
* @brief Gets the remaining bytes to be received.
*
* @param base pointer to FLEXIO_I2S_Type structure.
* @param handle pointer to flexio_i2s_handle_t structure which stores the transfer state
* @return count Bytes received.
* @retval kStatus_Success Succeed get the transfer count.
* @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
*/
status_t FLEXIO_I2S_TransferGetReceiveCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count);
/*!
* @brief Tx interrupt handler.
*
* @param i2sBase pointer to FLEXIO_I2S_Type structure.
* @param i2sHandle pointer to flexio_i2s_handle_t structure
*/
void FLEXIO_I2S_TransferTxHandleIRQ(void *i2sBase, void *i2sHandle);
/*!
* @brief Rx interrupt handler.
*
* @param i2sBase pointer to FLEXIO_I2S_Type structure.
* @param i2sHandle pointer to flexio_i2s_handle_t structure
*/
void FLEXIO_I2S_TransferRxHandleIRQ(void *i2sBase, void *i2sHandle);
/*! @} */
#if defined(__cplusplus)
}
#endif /*_cplusplus*/
/*! @} */
#endif /* _FSL_FLEXIO_I2S_H_ */

View File

@ -1,339 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_flexio_i2s_dma.h"
/*******************************************************************************
* Definitations
******************************************************************************/
/*<! Structure definition for flexio_i2s_dma_private_handle_t. The structure is private. */
typedef struct _flexio_i2s_dma_private_handle
{
FLEXIO_I2S_Type *base;
flexio_i2s_dma_handle_t *handle;
} flexio_i2s_dma_private_handle_t;
enum _flexio_i2s_dma_transfer_state
{
kFLEXIO_I2S_Busy = 0x0U, /*!< FLEXIO I2S is busy */
kFLEXIO_I2S_Idle, /*!< Transfer is done. */
};
/*<! Private handle only used for internally. */
static flexio_i2s_dma_private_handle_t s_dmaPrivateHandle[2];
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief FLEXIO I2S DMA callback for send.
*
* @param handle pointer to flexio_i2s_dma_handle_t structure which stores the transfer state.
* @param userData Parameter for user callback.
*/
static void FLEXIO_I2S_TxDMACallback(dma_handle_t *handle, void *userData);
/*!
* @brief FLEXIO I2S DMA callback for receive.
*
* @param handle pointer to flexio_i2s_dma_handle_t structure which stores the transfer state.
* @param userData Parameter for user callback.
*/
static void FLEXIO_I2S_RxDMACallback(dma_handle_t *handle, void *userData);
/*******************************************************************************
* Code
******************************************************************************/
static void FLEXIO_I2S_TxDMACallback(dma_handle_t *handle, void *userData)
{
flexio_i2s_dma_private_handle_t *privHandle = (flexio_i2s_dma_private_handle_t *)userData;
flexio_i2s_dma_handle_t *flexio_i2sHandle = privHandle->handle;
/* If finished a blcok, call the callback function */
memset(&flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver], 0, sizeof(flexio_i2s_transfer_t));
flexio_i2sHandle->queueDriver = (flexio_i2sHandle->queueDriver + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE;
if (flexio_i2sHandle->callback)
{
(flexio_i2sHandle->callback)(privHandle->base, flexio_i2sHandle, kStatus_Success, flexio_i2sHandle->userData);
}
/* If all data finished, just stop the transfer */
if (flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver].data == NULL)
{
FLEXIO_I2S_TransferAbortSendDMA(privHandle->base, flexio_i2sHandle);
}
}
static void FLEXIO_I2S_RxDMACallback(dma_handle_t *handle, void *userData)
{
flexio_i2s_dma_private_handle_t *privHandle = (flexio_i2s_dma_private_handle_t *)userData;
flexio_i2s_dma_handle_t *flexio_i2sHandle = privHandle->handle;
/* If finished a blcok, call the callback function */
memset(&flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver], 0, sizeof(flexio_i2s_transfer_t));
flexio_i2sHandle->queueDriver = (flexio_i2sHandle->queueDriver + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE;
if (flexio_i2sHandle->callback)
{
(flexio_i2sHandle->callback)(privHandle->base, flexio_i2sHandle, kStatus_Success, flexio_i2sHandle->userData);
}
/* If all data finished, just stop the transfer */
if (flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver].data == NULL)
{
FLEXIO_I2S_TransferAbortReceiveDMA(privHandle->base, flexio_i2sHandle);
}
}
void FLEXIO_I2S_TransferTxCreateHandleDMA(FLEXIO_I2S_Type *base,
flexio_i2s_dma_handle_t *handle,
flexio_i2s_dma_callback_t callback,
void *userData,
dma_handle_t *dmaHandle)
{
assert(handle && dmaHandle);
/* Set flexio_i2s base to handle */
handle->dmaHandle = dmaHandle;
handle->callback = callback;
handle->userData = userData;
/* Set FLEXIO I2S state to idle */
handle->state = kFLEXIO_I2S_Idle;
s_dmaPrivateHandle[0].base = base;
s_dmaPrivateHandle[0].handle = handle;
/* Install callback for Tx dma channel */
DMA_SetCallback(dmaHandle, FLEXIO_I2S_TxDMACallback, &s_dmaPrivateHandle[0]);
}
void FLEXIO_I2S_TransferRxCreateHandleDMA(FLEXIO_I2S_Type *base,
flexio_i2s_dma_handle_t *handle,
flexio_i2s_dma_callback_t callback,
void *userData,
dma_handle_t *dmaHandle)
{
assert(handle && dmaHandle);
/* Set flexio_i2s base to handle */
handle->dmaHandle = dmaHandle;
handle->callback = callback;
handle->userData = userData;
/* Set FLEXIO I2S state to idle */
handle->state = kFLEXIO_I2S_Idle;
s_dmaPrivateHandle[1].base = base;
s_dmaPrivateHandle[1].handle = handle;
/* Install callback for Tx dma channel */
DMA_SetCallback(dmaHandle, FLEXIO_I2S_RxDMACallback, &s_dmaPrivateHandle[1]);
}
void FLEXIO_I2S_TransferSetFormatDMA(FLEXIO_I2S_Type *base,
flexio_i2s_dma_handle_t *handle,
flexio_i2s_format_t *format,
uint32_t srcClock_Hz)
{
assert(handle && format);
/* Configure the audio format to FLEXIO I2S registers */
if (srcClock_Hz != 0)
{
/* It is master */
FLEXIO_I2S_MasterSetFormat(base, format, srcClock_Hz);
}
else
{
FLEXIO_I2S_SlaveSetFormat(base, format);
}
/* Get the tranfer size from format, this should be used in DMA configuration */
handle->bytesPerFrame = format->bitWidth / 8U;
}
status_t FLEXIO_I2S_TransferSendDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle, flexio_i2s_transfer_t *xfer)
{
assert(handle && xfer);
dma_transfer_config_t config = {0};
uint32_t destAddr = FLEXIO_I2S_TxGetDataRegisterAddress(base) + (4U - handle->bytesPerFrame);
/* Check if input parameter invalid */
if ((xfer->data == NULL) || (xfer->dataSize == 0U))
{
return kStatus_InvalidArgument;
}
if (handle->queue[handle->queueUser].data)
{
return kStatus_FLEXIO_I2S_QueueFull;
}
/* Change the state of handle */
handle->state = kFLEXIO_I2S_Busy;
/* Update the queue state */
handle->queue[handle->queueUser].data = xfer->data;
handle->queue[handle->queueUser].dataSize = xfer->dataSize;
handle->transferSize[handle->queueUser] = xfer->dataSize;
handle->queueUser = (handle->queueUser + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE;
DMA_PrepareTransfer(&config, xfer->data, handle->bytesPerFrame, (void *)destAddr, handle->bytesPerFrame,
xfer->dataSize, kDMA_MemoryToPeripheral);
/* Configure DMA channel */
DMA_SubmitTransfer(handle->dmaHandle, &config, true);
/* Start DMA transfer */
DMA_StartTransfer(handle->dmaHandle);
/* Enable DMA enable bit */
FLEXIO_I2S_TxEnableDMA(base, true);
/* Enable FLEXIO I2S Tx clock */
FLEXIO_I2S_Enable(base, true);
return kStatus_Success;
}
status_t FLEXIO_I2S_TransferReceiveDMA(FLEXIO_I2S_Type *base,
flexio_i2s_dma_handle_t *handle,
flexio_i2s_transfer_t *xfer)
{
assert(handle && xfer);
dma_transfer_config_t config = {0};
uint32_t srcAddr = FLEXIO_I2S_RxGetDataRegisterAddress(base) - (4U - handle->bytesPerFrame);
/* Check if input parameter invalid */
if ((xfer->data == NULL) || (xfer->dataSize == 0U))
{
return kStatus_InvalidArgument;
}
if (handle->queue[handle->queueUser].data)
{
return kStatus_FLEXIO_I2S_QueueFull;
}
/* Change the state of handle */
handle->state = kFLEXIO_I2S_Busy;
/* Update queue state */
handle->queue[handle->queueUser].data = xfer->data;
handle->queue[handle->queueUser].dataSize = xfer->dataSize;
handle->transferSize[handle->queueUser] = xfer->dataSize;
handle->queueUser = (handle->queueUser + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE;
/* Prepare dma configure */
DMA_PrepareTransfer(&config, (void *)srcAddr, handle->bytesPerFrame, xfer->data, handle->bytesPerFrame,
xfer->dataSize, kDMA_PeripheralToMemory);
DMA_SubmitTransfer(handle->dmaHandle, &config, true);
/* Start DMA transfer */
DMA_StartTransfer(handle->dmaHandle);
/* Enable DMA enable bit */
FLEXIO_I2S_RxEnableDMA(base, true);
/* Enable FLEXIO I2S Rx clock */
FLEXIO_I2S_Enable(base, true);
return kStatus_Success;
}
void FLEXIO_I2S_TransferAbortSendDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle)
{
assert(handle);
/* Disable dma */
DMA_AbortTransfer(handle->dmaHandle);
/* Disable DMA enable bit */
FLEXIO_I2S_TxEnableDMA(base, false);
/* Set the handle state */
handle->state = kFLEXIO_I2S_Idle;
}
void FLEXIO_I2S_TransferAbortReceiveDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle)
{
assert(handle);
/* Disable dma */
DMA_AbortTransfer(handle->dmaHandle);
/* Disable DMA enable bit */
FLEXIO_I2S_RxEnableDMA(base, false);
/* Set the handle state */
handle->state = kFLEXIO_I2S_Idle;
}
status_t FLEXIO_I2S_TransferGetSendCountDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle, size_t *count)
{
assert(handle);
status_t status = kStatus_Success;
if (handle->state != kFLEXIO_I2S_Busy)
{
status = kStatus_NoTransferInProgress;
}
else
{
*count = handle->transferSize[handle->queueDriver] -
DMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel);
}
return status;
}
status_t FLEXIO_I2S_TransferGetReceiveCountDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle, size_t *count)
{
assert(handle);
status_t status = kStatus_Success;
if (handle->state != kFLEXIO_I2S_Busy)
{
status = kStatus_NoTransferInProgress;
}
else
{
*count = handle->transferSize[handle->queueDriver] -
DMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel);
}
return status;
}

View File

@ -1,218 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_FLEXIO_I2S_DMA_H_
#define _FSL_FLEXIO_I2S_DMA_H_
#include "fsl_flexio_i2s.h"
#include "fsl_dma.h"
/*!
* @addtogroup flexio_dma_i2s
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
typedef struct _flexio_i2s_dma_handle flexio_i2s_dma_handle_t;
/*! @brief FlexIO I2S DMA transfer callback function for finish and error */
typedef void (*flexio_i2s_dma_callback_t)(FLEXIO_I2S_Type *base,
flexio_i2s_dma_handle_t *handle,
status_t status,
void *userData);
/*! @brief FlexIO I2S DMA transfer handle, users should not touch the content of the handle.*/
struct _flexio_i2s_dma_handle
{
dma_handle_t *dmaHandle; /*!< DMA handler for FlexIO I2S send */
uint8_t bytesPerFrame; /*!< Bytes in a frame */
uint32_t state; /*!< Internal state for FlexIO I2S DMA transfer */
flexio_i2s_dma_callback_t callback; /*!< Callback for users while transfer finish or error occurred */
void *userData; /*!< User callback parameter */
flexio_i2s_transfer_t queue[FLEXIO_I2S_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer. */
size_t transferSize[FLEXIO_I2S_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */
volatile uint8_t queueUser; /*!< Index for user to queue transfer. */
volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */
};
/*******************************************************************************
* APIs
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name DMA Transactional
* @{
*/
/*!
* @brief Initializes the FlexIO I2S DMA handle.
*
* This function initializes the FlexIO I2S master DMA handle which can be used for other FlexIO I2S master
* transactional APIs.
* Usually, for a specified FlexIO I2S instance, user need only call this API once to get the initialized handle.
*
* @param base FlexIO I2S peripheral base address.
* @param handle FlexIO I2S DMA handle pointer.
* @param callback FlexIO I2S DMA callback function called while finished a block.
* @param userData User parameter for callback.
* @param dmaHandle DMA handle for FlexIO I2S. This handle shall be a static value allocated by users.
*/
void FLEXIO_I2S_TransferTxCreateHandleDMA(FLEXIO_I2S_Type *base,
flexio_i2s_dma_handle_t *handle,
flexio_i2s_dma_callback_t callback,
void *userData,
dma_handle_t *dmaHandle);
/*!
* @brief Initializes the FlexIO I2S Rx DMA handle.
*
* This function initializes the FlexIO I2S slave DMA handle which can be used for other FlexIO I2S master transactional
* APIs.
* Usually, for a specified FlexIO I2S instance, user need only call this API once to get the initialized handle.
*
* @param base FlexIO I2S peripheral base address.
* @param handle FlexIO I2S DMA handle pointer.
* @param callback FlexIO I2S DMA callback function called while finished a block.
* @param userData User parameter for callback.
* @param dmaHandle DMA handle for FlexIO I2S. This handle shall be a static value allocated by users.
*/
void FLEXIO_I2S_TransferRxCreateHandleDMA(FLEXIO_I2S_Type *base,
flexio_i2s_dma_handle_t *handle,
flexio_i2s_dma_callback_t callback,
void *userData,
dma_handle_t *dmaHandle);
/*!
* @brief Configures the FlexIO I2S Tx audio format.
*
* Audio format can be changed in run-time of FlexIO I2S. This function configures the sample rate and audio data
* format to be transferred. This function also sets DMA parameter according to format.
*
* @param base FlexIO I2S peripheral base address.
* @param handle FlexIO I2S DMA handle pointer
* @param format Pointer to FlexIO I2S audio data format structure.
* @param srcClock_Hz FlexIO I2S clock source frequency in Hz. It should be 0 while in slave mode.
* @retval kStatus_Success Audio format set successfully.
* @retval kStatus_InvalidArgument The input arguments is invalid.
*/
void FLEXIO_I2S_TransferSetFormatDMA(FLEXIO_I2S_Type *base,
flexio_i2s_dma_handle_t *handle,
flexio_i2s_format_t *format,
uint32_t srcClock_Hz);
/*!
* @brief Performs a non-blocking FlexIO I2S transfer using DMA.
*
* @note This interface returns immediately after transfer initiates. Call
* FLEXIO_I2S_GetTransferStatus to poll the transfer status and check whether FLEXIO I2S transfer finished.
*
* @param base FlexIO I2S peripheral base address.
* @param handle FlexIO I2S DMA handle pointer.
* @param xfer Pointer to DMA transfer structure.
* @retval kStatus_Success Start a FlexIO I2S DMA send successfully.
* @retval kStatus_InvalidArgument The input arguments is invalid.
* @retval kStatus_TxBusy FlexIO I2S is busy sending data.
*/
status_t FLEXIO_I2S_TransferSendDMA(FLEXIO_I2S_Type *base,
flexio_i2s_dma_handle_t *handle,
flexio_i2s_transfer_t *xfer);
/*!
* @brief Performs a non-blocking FlexIO I2S receive using DMA.
*
* @note This interface returns immediately after transfer initiates. Call
* FLEXIO_I2S_GetReceiveRemainingBytes to poll the transfer status to check whether the FlexIO I2S transfer is finished.
*
* @param base FlexIO I2S peripheral base address.
* @param handle FlexIO I2S DMA handle pointer.
* @param xfer Pointer to DMA transfer structure.
* @retval kStatus_Success Start a FlexIO I2S DMA receive successfully.
* @retval kStatus_InvalidArgument The input arguments is invalid.
* @retval kStatus_RxBusy FlexIO I2S is busy receiving data.
*/
status_t FLEXIO_I2S_TransferReceiveDMA(FLEXIO_I2S_Type *base,
flexio_i2s_dma_handle_t *handle,
flexio_i2s_transfer_t *xfer);
/*!
* @brief Aborts a FlexIO I2S transfer using DMA.
*
* @param base FlexIO I2S peripheral base address.
* @param handle FlexIO I2S DMA handle pointer.
*/
void FLEXIO_I2S_TransferAbortSendDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle);
/*!
* @brief Aborts a FlexIO I2S receive using DMA.
*
* @param base FlexIO I2S peripheral base address.
* @param handle FlexIO I2S DMA handle pointer.
*/
void FLEXIO_I2S_TransferAbortReceiveDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle);
/*!
* @brief Gets the remaining bytes to be sent.
*
* @param base FlexIO I2S peripheral base address.
* @param handle FlexIO I2S DMA handle pointer.
* @param count Bytes sent.
* @retval kStatus_Success Succeed get the transfer count.
* @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
*/
status_t FLEXIO_I2S_TransferGetSendCountDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle, size_t *count);
/*!
* @brief Gets the remaining bytes to be received.
*
* @param base FlexIO I2S peripheral base address.
* @param handle FlexIO I2S DMA handle pointer.
* @param count Bytes received.
* @retval kStatus_Success Succeed get the transfer count.
* @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
*/
status_t FLEXIO_I2S_TransferGetReceiveCountDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle, size_t *count);
/*! @} */
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif

View File

@ -1,935 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_flexio_spi.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief FLEXIO SPI transfer state, which is used for SPI transactiaonl APIs' internal state. */
enum _flexio_spi_transfer_states
{
kFLEXIO_SPI_Idle = 0x0U, /*!< Nothing in the transmitter/receiver's queue. */
kFLEXIO_SPI_Busy, /*!< Transmiter/Receive's queue is not finished. */
};
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Send a piece of data for SPI.
*
* This function computes the number of data to be written into D register or Tx FIFO,
* and write the data into it. At the same time, this function updates the values in
* master handle structure.
*
* @param base pointer to FLEXIO_SPI_Type structure
* @param handle Pointer to SPI master handle structure.
*/
static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle);
/*!
* @brief Receive a piece of data for SPI master.
*
* This function computes the number of data to receive from D register or Rx FIFO,
* and write the data to destination address. At the same time, this function updates
* the values in master handle structure.
*
* @param base pointer to FLEXIO_SPI_Type structure
* @param handle Pointer to SPI master handle structure.
*/
static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle);
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Codes
******************************************************************************/
static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle)
{
uint16_t tmpData = FLEXIO_SPI_DUMMYDATA;
if (handle->txData != NULL)
{
/* Transmit data and update tx size/buff. */
if (handle->bytePerFrame == 1U)
{
tmpData = *(handle->txData);
handle->txData++;
}
else
{
tmpData = (uint32_t)(handle->txData[0]) << 8U;
tmpData += handle->txData[1];
handle->txData += 2U;
}
}
else
{
tmpData = FLEXIO_SPI_DUMMYDATA;
}
handle->txRemainingBytes -= handle->bytePerFrame;
FLEXIO_SPI_WriteData(base, handle->direction, tmpData);
if (!handle->txRemainingBytes)
{
FLEXIO_SPI_DisableInterrupts(base, kFLEXIO_SPI_TxEmptyInterruptEnable);
}
}
static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle)
{
uint16_t tmpData;
tmpData = FLEXIO_SPI_ReadData(base, handle->direction);
if (handle->rxData != NULL)
{
if (handle->bytePerFrame == 1U)
{
*handle->rxData = tmpData;
handle->rxData++;
}
else
{
*((uint16_t *)(handle->rxData)) = tmpData;
handle->rxData += 2U;
}
}
handle->rxRemainingBytes -= handle->bytePerFrame;
}
void FLEXIO_SPI_MasterInit(FLEXIO_SPI_Type *base, flexio_spi_master_config_t *masterConfig, uint32_t srcClock_Hz)
{
assert(base);
assert(masterConfig);
flexio_shifter_config_t shifterConfig;
flexio_timer_config_t timerConfig;
uint32_t ctrlReg = 0;
uint16_t timerDiv = 0;
uint16_t timerCmp = 0;
/* Clear the shifterConfig & timerConfig struct. */
memset(&shifterConfig, 0, sizeof(shifterConfig));
memset(&timerConfig, 0, sizeof(timerConfig));
/* Ungate flexio clock. */
CLOCK_EnableClock(kCLOCK_Flexio0);
/* Configure FLEXIO SPI Master */
ctrlReg = base->flexioBase->CTRL;
ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
ctrlReg |= (FLEXIO_CTRL_DOZEN(masterConfig->enableInDoze) | FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) |
FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) | FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster));
base->flexioBase->CTRL = ctrlReg;
/* Do hardware configuration. */
/* 1. Configure the shifter 0 for tx. */
shifterConfig.timerSelect = base->timerIndex[0];
shifterConfig.pinConfig = kFLEXIO_PinConfigOutput;
shifterConfig.pinSelect = base->SDOPinIndex;
shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
{
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
}
else
{
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift;
}
FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
/* 2. Configure the shifter 1 for rx. */
shifterConfig.timerSelect = base->timerIndex[0];
shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
shifterConfig.pinSelect = base->SDIPinIndex;
shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
{
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
}
else
{
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
}
FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
/*3. Configure the timer 0 for SCK. */
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timerConfig.pinConfig = kFLEXIO_PinConfigOutput;
timerConfig.pinSelect = base->SCKPinIndex;
timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
timerConfig.timerReset = kFLEXIO_TimerResetNever;
timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable;
timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
timerDiv = srcClock_Hz / masterConfig->baudRate_Bps;
timerDiv = timerDiv / 2 - 1;
timerCmp = ((uint32_t)(masterConfig->dataMode * 2 - 1U)) << 8U;
timerCmp |= timerDiv;
timerConfig.timerCompare = timerCmp;
FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
/* 4. Configure the timer 1 for CSn. */
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->timerIndex[0]);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timerConfig.pinConfig = kFLEXIO_PinConfigOutput;
timerConfig.pinSelect = base->CSnPinIndex;
timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
timerConfig.timerReset = kFLEXIO_TimerResetNever;
timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable;
timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
timerConfig.timerCompare = 0xFFFFU;
FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
}
void FLEXIO_SPI_MasterDeinit(FLEXIO_SPI_Type *base)
{
/* Disable FLEXIO SPI module. */
FLEXIO_SPI_Enable(base, false);
/* Gate flexio clock. */
CLOCK_DisableClock(kCLOCK_Flexio0);
}
void FLEXIO_SPI_MasterGetDefaultConfig(flexio_spi_master_config_t *masterConfig)
{
assert(masterConfig);
masterConfig->enableMaster = true;
masterConfig->enableInDoze = false;
masterConfig->enableInDebug = true;
masterConfig->enableFastAccess = false;
/* Default baud rate 500kbps. */
masterConfig->baudRate_Bps = 500000U;
/* Default CPHA = 0. */
masterConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge;
/* Default bit count at 8. */
masterConfig->dataMode = kFLEXIO_SPI_8BitMode;
}
void FLEXIO_SPI_SlaveInit(FLEXIO_SPI_Type *base, flexio_spi_slave_config_t *slaveConfig)
{
assert(base && slaveConfig);
flexio_shifter_config_t shifterConfig;
flexio_timer_config_t timerConfig;
uint32_t ctrlReg = 0;
/* Clear the shifterConfig & timerConfig struct. */
memset(&shifterConfig, 0, sizeof(shifterConfig));
memset(&timerConfig, 0, sizeof(timerConfig));
/* Ungate flexio clock. */
CLOCK_EnableClock(kCLOCK_Flexio0);
/* Configure FLEXIO SPI Slave */
ctrlReg = base->flexioBase->CTRL;
ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
ctrlReg |= (FLEXIO_CTRL_DOZEN(slaveConfig->enableInDoze) | FLEXIO_CTRL_DBGE(slaveConfig->enableInDebug) |
FLEXIO_CTRL_FASTACC(slaveConfig->enableFastAccess) | FLEXIO_CTRL_FLEXEN(slaveConfig->enableSlave));
base->flexioBase->CTRL = ctrlReg;
/* Do hardware configuration. */
/* 1. Configure the shifter 0 for tx. */
shifterConfig.timerSelect = base->timerIndex[0];
shifterConfig.pinConfig = kFLEXIO_PinConfigOutput;
shifterConfig.pinSelect = base->SDOPinIndex;
shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
{
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
}
else
{
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift;
}
FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
/* 2. Configure the shifter 1 for rx. */
shifterConfig.timerSelect = base->timerIndex[0];
shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
shifterConfig.pinSelect = base->SDIPinIndex;
shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
{
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
}
else
{
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
}
FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
/*3. Configure the timer 0 for shift clock. */
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->CSnPinIndex);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
timerConfig.pinSelect = base->SCKPinIndex;
timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
timerConfig.timerReset = kFLEXIO_TimerResetNever;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerRisingEdge;
timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
{
/* The configuration kFLEXIO_TimerDisableOnTimerCompare only support continuous
PCS access, change to kFLEXIO_TimerDisableNever to enable discontinuous PCS access. */
timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
}
else
{
timerConfig.timerDisable = kFLEXIO_TimerDisableOnTriggerFallingEdge;
timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
}
timerConfig.timerCompare = slaveConfig->dataMode * 2 - 1U;
FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
}
void FLEXIO_SPI_SlaveDeinit(FLEXIO_SPI_Type *base)
{
FLEXIO_SPI_MasterDeinit(base);
}
void FLEXIO_SPI_SlaveGetDefaultConfig(flexio_spi_slave_config_t *slaveConfig)
{
assert(slaveConfig);
slaveConfig->enableSlave = true;
slaveConfig->enableInDoze = false;
slaveConfig->enableInDebug = true;
slaveConfig->enableFastAccess = false;
/* Default CPHA = 0. */
slaveConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge;
/* Default bit count at 8. */
slaveConfig->dataMode = kFLEXIO_SPI_8BitMode;
}
void FLEXIO_SPI_EnableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_SPI_TxEmptyInterruptEnable)
{
FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1 << base->shifterIndex[0]);
}
if (mask & kFLEXIO_SPI_RxFullInterruptEnable)
{
FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1 << base->shifterIndex[1]);
}
}
void FLEXIO_SPI_DisableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_SPI_TxEmptyInterruptEnable)
{
FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1 << base->shifterIndex[0]);
}
if (mask & kFLEXIO_SPI_RxFullInterruptEnable)
{
FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1 << base->shifterIndex[1]);
}
}
void FLEXIO_SPI_EnableDMA(FLEXIO_SPI_Type *base, uint32_t mask, bool enable)
{
if (mask & kFLEXIO_SPI_TxDmaEnable)
{
FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1U << base->shifterIndex[0], enable);
}
if (mask & kFLEXIO_SPI_RxDmaEnable)
{
FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1U << base->shifterIndex[1], enable);
}
}
uint32_t FLEXIO_SPI_GetStatusFlags(FLEXIO_SPI_Type *base)
{
uint32_t shifterStatus = FLEXIO_GetShifterStatusFlags(base->flexioBase);
uint32_t status = 0;
status = ((shifterStatus & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]);
status |= (((shifterStatus & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) << 1U);
return status;
}
void FLEXIO_SPI_ClearStatusFlags(FLEXIO_SPI_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_SPI_TxBufferEmptyFlag)
{
FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]);
}
if (mask & kFLEXIO_SPI_RxBufferFullFlag)
{
FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]);
}
}
void FLEXIO_SPI_MasterSetBaudRate(FLEXIO_SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClockHz)
{
uint16_t timerDiv = 0;
uint16_t timerCmp = 0;
FLEXIO_Type *flexioBase = base->flexioBase;
/* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/
timerDiv = srcClockHz / baudRate_Bps;
timerDiv = timerDiv / 2 - 1U;
timerCmp = flexioBase->TIMCMP[base->timerIndex[0]];
timerCmp &= 0xFF00U;
timerCmp |= timerDiv;
flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
}
void FLEXIO_SPI_WriteBlocking(FLEXIO_SPI_Type *base,
flexio_spi_shift_direction_t direction,
const uint8_t *buffer,
size_t size)
{
assert(buffer);
assert(size);
while (size--)
{
/* Wait until data transfer complete. */
while (!(FLEXIO_SPI_GetStatusFlags(base) & kFLEXIO_SPI_TxBufferEmptyFlag))
{
}
FLEXIO_SPI_WriteData(base, direction, *buffer++);
}
}
void FLEXIO_SPI_ReadBlocking(FLEXIO_SPI_Type *base,
flexio_spi_shift_direction_t direction,
uint8_t *buffer,
size_t size)
{
assert(buffer);
assert(size);
while (size--)
{
/* Wait until data transfer complete. */
while (!(FLEXIO_SPI_GetStatusFlags(base) & kFLEXIO_SPI_RxBufferFullFlag))
{
}
*buffer++ = FLEXIO_SPI_ReadData(base, direction);
}
}
void FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_transfer_t *xfer)
{
flexio_spi_shift_direction_t direction;
uint8_t bytesPerFrame;
uint32_t dataMode = 0;
uint16_t timerCmp = base->flexioBase->TIMCMP[base->timerIndex[0]];
uint16_t tmpData = FLEXIO_SPI_DUMMYDATA;
timerCmp &= 0x00FFU;
/* Configure the values in handle. */
switch (xfer->flags)
{
case kFLEXIO_SPI_8bitMsb:
dataMode = (8 * 2 - 1U) << 8U;
bytesPerFrame = 1;
direction = kFLEXIO_SPI_MsbFirst;
break;
case kFLEXIO_SPI_8bitLsb:
dataMode = (8 * 2 - 1U) << 8U;
bytesPerFrame = 1;
direction = kFLEXIO_SPI_LsbFirst;
break;
case kFLEXIO_SPI_16bitMsb:
dataMode = (16 * 2 - 1U) << 8U;
bytesPerFrame = 2;
direction = kFLEXIO_SPI_MsbFirst;
break;
case kFLEXIO_SPI_16bitLsb:
dataMode = (16 * 2 - 1U) << 8U;
bytesPerFrame = 2;
direction = kFLEXIO_SPI_LsbFirst;
break;
default:
dataMode = (8 * 2 - 1U) << 8U;
bytesPerFrame = 1;
direction = kFLEXIO_SPI_MsbFirst;
assert(true);
break;
}
dataMode |= timerCmp;
/* Configure transfer size. */
base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
while (xfer->dataSize)
{
/* Wait until data transfer complete. */
while (!(FLEXIO_SPI_GetStatusFlags(base) & kFLEXIO_SPI_TxBufferEmptyFlag))
{
}
if (xfer->txData != NULL)
{
/* Transmit data and update tx size/buff. */
if (bytesPerFrame == 1U)
{
tmpData = *(xfer->txData);
xfer->txData++;
}
else
{
tmpData = (uint32_t)(xfer->txData[0]) << 8U;
tmpData += xfer->txData[1];
xfer->txData += 2U;
}
}
else
{
tmpData = FLEXIO_SPI_DUMMYDATA;
}
xfer->dataSize -= bytesPerFrame;
FLEXIO_SPI_WriteData(base, direction, tmpData);
while (!(FLEXIO_SPI_GetStatusFlags(base) & kFLEXIO_SPI_RxBufferFullFlag))
{
}
tmpData = FLEXIO_SPI_ReadData(base, direction);
if (xfer->rxData != NULL)
{
if (bytesPerFrame == 1U)
{
*xfer->rxData = tmpData;
xfer->rxData++;
}
else
{
*((uint16_t *)(xfer->rxData)) = tmpData;
xfer->rxData += 2U;
}
}
}
}
status_t FLEXIO_SPI_MasterTransferCreateHandle(FLEXIO_SPI_Type *base,
flexio_spi_master_handle_t *handle,
flexio_spi_master_transfer_callback_t callback,
void *userData)
{
assert(handle);
IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
/* Zero the handle. */
memset(handle, 0, sizeof(*handle));
/* Register callback and userData. */
handle->callback = callback;
handle->userData = userData;
/* Enable interrupt in NVIC. */
EnableIRQ(flexio_irqs[0]);
/* Save the context in global variables to support the double weak mechanism. */
return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_MasterTransferHandleIRQ);
}
status_t FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type *base,
flexio_spi_master_handle_t *handle,
flexio_spi_transfer_t *xfer)
{
assert(handle);
assert(xfer);
uint32_t dataMode = 0;
uint16_t timerCmp = base->flexioBase->TIMCMP[base->timerIndex[0]];
uint16_t tmpData = FLEXIO_SPI_DUMMYDATA;
timerCmp &= 0x00FFU;
/* Check if SPI is busy. */
if (handle->state == kFLEXIO_SPI_Busy)
{
return kStatus_FLEXIO_SPI_Busy;
}
/* Check if the argument is legal. */
if ((xfer->txData == NULL) && (xfer->rxData == NULL))
{
return kStatus_InvalidArgument;
}
/* Configure the values in handle */
switch (xfer->flags)
{
case kFLEXIO_SPI_8bitMsb:
dataMode = (8 * 2 - 1U) << 8U;
handle->bytePerFrame = 1U;
handle->direction = kFLEXIO_SPI_MsbFirst;
break;
case kFLEXIO_SPI_8bitLsb:
dataMode = (8 * 2 - 1U) << 8U;
handle->bytePerFrame = 1U;
handle->direction = kFLEXIO_SPI_LsbFirst;
break;
case kFLEXIO_SPI_16bitMsb:
dataMode = (16 * 2 - 1U) << 8U;
handle->bytePerFrame = 2U;
handle->direction = kFLEXIO_SPI_MsbFirst;
break;
case kFLEXIO_SPI_16bitLsb:
dataMode = (16 * 2 - 1U) << 8U;
handle->bytePerFrame = 2U;
handle->direction = kFLEXIO_SPI_LsbFirst;
break;
default:
dataMode = (8 * 2 - 1U) << 8U;
handle->bytePerFrame = 1U;
handle->direction = kFLEXIO_SPI_MsbFirst;
assert(true);
break;
}
dataMode |= timerCmp;
/* Configure transfer size. */
base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
handle->state = kFLEXIO_SPI_Busy;
handle->txData = xfer->txData;
handle->rxData = xfer->rxData;
handle->rxRemainingBytes = xfer->dataSize;
/* Save total transfer size. */
handle->transferSize = xfer->dataSize;
/* Send first byte of data to trigger the rx interrupt. */
if (handle->txData != NULL)
{
/* Transmit data and update tx size/buff. */
if (handle->bytePerFrame == 1U)
{
tmpData = *(handle->txData);
handle->txData++;
}
else
{
tmpData = (uint32_t)(handle->txData[0]) << 8U;
tmpData += handle->txData[1];
handle->txData += 2U;
}
}
else
{
tmpData = FLEXIO_SPI_DUMMYDATA;
}
handle->txRemainingBytes = xfer->dataSize - handle->bytePerFrame;
FLEXIO_SPI_WriteData(base, handle->direction, tmpData);
/* Enable transmit and receive interrupt to handle rx. */
FLEXIO_SPI_EnableInterrupts(base, kFLEXIO_SPI_RxFullInterruptEnable);
return kStatus_Success;
}
status_t FLEXIO_SPI_MasterTransferGetCount(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle, size_t *count)
{
assert(handle);
if (!count)
{
return kStatus_InvalidArgument;
}
/* Return remaing bytes in different cases. */
if (handle->rxData)
{
*count = handle->transferSize - handle->rxRemainingBytes;
}
else
{
*count = handle->transferSize - handle->txRemainingBytes;
}
return kStatus_Success;
}
void FLEXIO_SPI_MasterTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle)
{
assert(handle);
FLEXIO_SPI_DisableInterrupts(base, kFLEXIO_SPI_RxFullInterruptEnable);
FLEXIO_SPI_DisableInterrupts(base, kFLEXIO_SPI_TxEmptyInterruptEnable);
/* Transfer finished, set the state to idle. */
handle->state = kFLEXIO_SPI_Idle;
/* Clear the internal state. */
handle->rxRemainingBytes = 0;
handle->txRemainingBytes = 0;
}
void FLEXIO_SPI_MasterTransferHandleIRQ(void *spiType, void *spiHandle)
{
assert(spiHandle);
flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle;
FLEXIO_SPI_Type *base;
uint32_t status;
if (handle->state == kFLEXIO_SPI_Idle)
{
return;
}
base = (FLEXIO_SPI_Type *)spiType;
status = FLEXIO_SPI_GetStatusFlags(base);
/* Handle rx. */
if ((status & kFLEXIO_SPI_RxBufferFullFlag) && (handle->rxRemainingBytes))
{
FLEXIO_SPI_TransferReceiveTransaction(base, handle);
}
/* Handle tx. */
if ((status & kFLEXIO_SPI_TxBufferEmptyFlag) && (handle->txRemainingBytes))
{
FLEXIO_SPI_TransferSendTransaction(base, handle);
}
/* All the transfer finished. */
if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U))
{
FLEXIO_SPI_MasterTransferAbort(base, handle);
if (handle->callback)
{
(handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData);
}
}
}
status_t FLEXIO_SPI_SlaveTransferCreateHandle(FLEXIO_SPI_Type *base,
flexio_spi_slave_handle_t *handle,
flexio_spi_slave_transfer_callback_t callback,
void *userData)
{
assert(handle);
IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
/* Zero the handle. */
memset(handle, 0, sizeof(*handle));
/* Register callback and userData. */
handle->callback = callback;
handle->userData = userData;
/* Enable interrupt in NVIC. */
EnableIRQ(flexio_irqs[0]);
/* Save the context in global variables to support the double weak mechanism. */
return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_SlaveTransferHandleIRQ);
}
status_t FLEXIO_SPI_SlaveTransferNonBlocking(FLEXIO_SPI_Type *base,
flexio_spi_slave_handle_t *handle,
flexio_spi_transfer_t *xfer)
{
assert(handle);
assert(xfer);
uint32_t dataMode = 0;
/* Check if SPI is busy. */
if (handle->state == kFLEXIO_SPI_Busy)
{
return kStatus_FLEXIO_SPI_Busy;
}
/* Check if the argument is legal. */
if ((xfer->txData == NULL) && (xfer->rxData == NULL))
{
return kStatus_InvalidArgument;
}
/* Configure the values in handle */
switch (xfer->flags)
{
case kFLEXIO_SPI_8bitMsb:
dataMode = 8 * 2 - 1U;
handle->bytePerFrame = 1U;
handle->direction = kFLEXIO_SPI_MsbFirst;
break;
case kFLEXIO_SPI_8bitLsb:
dataMode = 8 * 2 - 1U;
handle->bytePerFrame = 1U;
handle->direction = kFLEXIO_SPI_LsbFirst;
break;
case kFLEXIO_SPI_16bitMsb:
dataMode = 16 * 2 - 1U;
handle->bytePerFrame = 2U;
handle->direction = kFLEXIO_SPI_MsbFirst;
break;
case kFLEXIO_SPI_16bitLsb:
dataMode = 16 * 2 - 1U;
handle->bytePerFrame = 2U;
handle->direction = kFLEXIO_SPI_LsbFirst;
break;
default:
dataMode = 8 * 2 - 1U;
handle->bytePerFrame = 1U;
handle->direction = kFLEXIO_SPI_MsbFirst;
assert(true);
break;
}
/* Configure transfer size. */
base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
handle->state = kFLEXIO_SPI_Busy;
handle->txData = xfer->txData;
handle->rxData = xfer->rxData;
handle->txRemainingBytes = xfer->dataSize;
handle->rxRemainingBytes = xfer->dataSize;
/* Save total transfer size. */
handle->transferSize = xfer->dataSize;
/* Enable transmit and receive interrupt to handle tx and rx. */
FLEXIO_SPI_EnableInterrupts(base, kFLEXIO_SPI_TxEmptyInterruptEnable);
FLEXIO_SPI_EnableInterrupts(base, kFLEXIO_SPI_RxFullInterruptEnable);
return kStatus_Success;
}
void FLEXIO_SPI_SlaveTransferHandleIRQ(void *spiType, void *spiHandle)
{
assert(spiHandle);
flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle;
FLEXIO_SPI_Type *base;
uint32_t status;
if (handle->state == kFLEXIO_SPI_Idle)
{
return;
}
base = (FLEXIO_SPI_Type *)spiType;
status = FLEXIO_SPI_GetStatusFlags(base);
/* Handle tx. */
if ((status & kFLEXIO_SPI_TxBufferEmptyFlag) && (handle->txRemainingBytes))
{
FLEXIO_SPI_TransferSendTransaction(base, handle);
}
/* Handle rx. */
if ((status & kFLEXIO_SPI_RxBufferFullFlag) && (handle->rxRemainingBytes))
{
FLEXIO_SPI_TransferReceiveTransaction(base, handle);
}
/* All the transfer finished. */
if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U))
{
FLEXIO_SPI_SlaveTransferAbort(base, handle);
if (handle->callback)
{
(handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData);
}
}
}

View File

@ -1,708 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_FLEXIO_SPI_H_
#define _FSL_FLEXIO_SPI_H_
#include "fsl_common.h"
#include "fsl_flexio.h"
/*!
* @addtogroup flexio_spi
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief FlexIO SPI driver version 2.1.0. */
#define FSL_FLEXIO_SPI_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
/*@}*/
/*! @brief FlexIO SPI dummy transfer data, the data is sent while txData is NULL. */
#define FLEXIO_SPI_DUMMYDATA (0xFFFFU)
/*! @brief Error codes for the FlexIO SPI driver. */
enum _flexio_spi_status
{
kStatus_FLEXIO_SPI_Busy = MAKE_STATUS(kStatusGroup_FLEXIO_SPI, 1), /*!< FlexIO SPI is busy. */
kStatus_FLEXIO_SPI_Idle = MAKE_STATUS(kStatusGroup_FLEXIO_SPI, 2), /*!< SPI is idle */
kStatus_FLEXIO_SPI_Error = MAKE_STATUS(kStatusGroup_FLEXIO_SPI, 3), /*!< FlexIO SPI error. */
};
/*! @brief FlexIO SPI clock phase configuration. */
typedef enum _flexio_spi_clock_phase
{
kFLEXIO_SPI_ClockPhaseFirstEdge = 0x0U, /*!< First edge on SPSCK occurs at the middle of the first
* cycle of a data transfer. */
kFLEXIO_SPI_ClockPhaseSecondEdge = 0x1U, /*!< First edge on SPSCK occurs at the start of the
* first cycle of a data transfer. */
} flexio_spi_clock_phase_t;
/*! @brief FlexIO SPI data shifter direction options. */
typedef enum _flexio_spi_shift_direction
{
kFLEXIO_SPI_MsbFirst = 0, /*!< Data transfers start with most significant bit. */
kFLEXIO_SPI_LsbFirst = 1, /*!< Data transfers start with least significant bit. */
} flexio_spi_shift_direction_t;
/*! @brief FlexIO SPI data length mode options. */
typedef enum _flexio_spi_data_bitcount_mode
{
kFLEXIO_SPI_8BitMode = 0x08U, /*!< 8-bit data transmission mode. */
kFLEXIO_SPI_16BitMode = 0x10U, /*!< 16-bit data transmission mode. */
} flexio_spi_data_bitcount_mode_t;
/*! @brief Define FlexIO SPI interrupt mask. */
enum _flexio_spi_interrupt_enable
{
kFLEXIO_SPI_TxEmptyInterruptEnable = 0x1U, /*!< Transmit buffer empty interrupt enable. */
kFLEXIO_SPI_RxFullInterruptEnable = 0x2U, /*!< Receive buffer full interrupt enable. */
};
/*! @brief Define FlexIO SPI status mask. */
enum _flexio_spi_status_flags
{
kFLEXIO_SPI_TxBufferEmptyFlag = 0x1U, /*!< Transmit buffer empty flag. */
kFLEXIO_SPI_RxBufferFullFlag = 0x2U, /*!< Receive buffer full flag. */
};
/*! @brief Define FlexIO SPI DMA mask. */
enum _flexio_spi_dma_enable
{
kFLEXIO_SPI_TxDmaEnable = 0x1U, /*!< Tx DMA request source */
kFLEXIO_SPI_RxDmaEnable = 0x2U, /*!< Rx DMA request source */
kFLEXIO_SPI_DmaAllEnable = 0x3U, /*!< All DMA request source*/
};
/*! @brief Define FlexIO SPI transfer flags. */
enum _flexio_spi_transfer_flags
{
kFLEXIO_SPI_8bitMsb = 0x1U, /*!< FlexIO SPI 8-bit MSB first */
kFLEXIO_SPI_8bitLsb = 0x2U, /*!< FlexIO SPI 8-bit LSB first */
kFLEXIO_SPI_16bitMsb = 0x9U, /*!< FlexIO SPI 16-bit MSB first */
kFLEXIO_SPI_16bitLsb = 0xaU, /*!< FlexIO SPI 16-bit LSB first */
};
/*! @brief Define FlexIO SPI access structure typedef. */
typedef struct _flexio_spi_type
{
FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */
uint8_t SDOPinIndex; /*!< Pin select for data output. */
uint8_t SDIPinIndex; /*!< Pin select for data input. */
uint8_t SCKPinIndex; /*!< Pin select for clock. */
uint8_t CSnPinIndex; /*!< Pin select for enable. */
uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO SPI. */
uint8_t timerIndex[2]; /*!< Timer index used in FlexIO SPI. */
} FLEXIO_SPI_Type;
/*! @brief Define FlexIO SPI master configuration structure. */
typedef struct _flexio_spi_master_config
{
bool enableMaster; /*!< Enable/disable FlexIO SPI master after configuration. */
bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode. */
bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode. */
bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers,
fast access requires the FlexIO clock to be at least
twice the frequency of the bus clock. */
uint32_t baudRate_Bps; /*!< Baud rate in Bps. */
flexio_spi_clock_phase_t phase; /*!< Clock phase. */
flexio_spi_data_bitcount_mode_t dataMode; /*!< 8bit or 16bit mode. */
} flexio_spi_master_config_t;
/*! @brief Define FlexIO SPI slave configuration structure. */
typedef struct _flexio_spi_slave_config
{
bool enableSlave; /*!< Enable/disable FlexIO SPI slave after configuration. */
bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode. */
bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode. */
bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers,
fast access requires the FlexIO clock to be at least
twice the frequency of the bus clock. */
flexio_spi_clock_phase_t phase; /*!< Clock phase. */
flexio_spi_data_bitcount_mode_t dataMode; /*!< 8bit or 16bit mode. */
} flexio_spi_slave_config_t;
/*! @brief Define FlexIO SPI transfer structure. */
typedef struct _flexio_spi_transfer
{
uint8_t *txData; /*!< Send buffer. */
uint8_t *rxData; /*!< Receive buffer. */
size_t dataSize; /*!< Transfer bytes. */
uint8_t flags; /*!< FlexIO SPI control flag, MSB first or LSB first. */
} flexio_spi_transfer_t;
/*! @brief typedef for flexio_spi_master_handle_t in advance. */
typedef struct _flexio_spi_master_handle flexio_spi_master_handle_t;
/*! @brief Slave handle is the same with master handle. */
typedef flexio_spi_master_handle_t flexio_spi_slave_handle_t;
/*! @brief FlexIO SPI master callback for finished transmit */
typedef void (*flexio_spi_master_transfer_callback_t)(FLEXIO_SPI_Type *base,
flexio_spi_master_handle_t *handle,
status_t status,
void *userData);
/*! @brief FlexIO SPI slave callback for finished transmit */
typedef void (*flexio_spi_slave_transfer_callback_t)(FLEXIO_SPI_Type *base,
flexio_spi_slave_handle_t *handle,
status_t status,
void *userData);
/*! @brief Define FlexIO SPI handle structure. */
struct _flexio_spi_master_handle
{
uint8_t *txData; /*!< Transfer buffer. */
uint8_t *rxData; /*!< Receive buffer. */
size_t transferSize; /*!< Total bytes to be transferred. */
volatile size_t txRemainingBytes; /*!< Send data remaining in bytes. */
volatile size_t rxRemainingBytes; /*!< Receive data remaining in bytes. */
volatile uint32_t state; /*!< FlexIO SPI internal state. */
uint8_t bytePerFrame; /*!< SPI mode, 2bytes or 1byte in a frame */
flexio_spi_shift_direction_t direction; /*!< Shift direction. */
flexio_spi_master_transfer_callback_t callback; /*!< FlexIO SPI callback. */
void *userData; /*!< Callback parameter. */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus*/
/*!
* @name FlexIO SPI Configuration
* @{
*/
/*!
* @brief Ungates the FlexIO clock, resets the FlexIO module and configures the FlexIO SPI master hardware,
* and configures the FlexIO SPI with FlexIO SPI master configuration. The
* configuration structure can be filled by the user, or be set with default values
* by the FLEXIO_SPI_MasterGetDefaultConfig().
*
* @note FlexIO SPI master only support CPOL = 0, which means clock inactive low.
*
* Example
@code
FLEXIO_SPI_Type spiDev = {
.flexioBase = FLEXIO,
.SDOPinIndex = 0,
.SDIPinIndex = 1,
.SCKPinIndex = 2,
.CSnPinIndex = 3,
.shifterIndex = {0,1},
.timerIndex = {0,1}
};
flexio_spi_master_config_t config = {
.enableMaster = true,
.enableInDoze = false,
.enableInDebug = true,
.enableFastAccess = false,
.baudRate_Bps = 500000,
.phase = kFLEXIO_SPI_ClockPhaseFirstEdge,
.direction = kFLEXIO_SPI_MsbFirst,
.dataMode = kFLEXIO_SPI_8BitMode
};
FLEXIO_SPI_MasterInit(&spiDev, &config, srcClock_Hz);
@endcode
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param masterConfig Pointer to the flexio_spi_master_config_t structure.
* @param srcClock_Hz FlexIO source clock in Hz.
*/
void FLEXIO_SPI_MasterInit(FLEXIO_SPI_Type *base, flexio_spi_master_config_t *masterConfig, uint32_t srcClock_Hz);
/*!
* @brief Gates the FlexIO clock.
*
* @param base Pointer to the FLEXIO_SPI_Type.
*/
void FLEXIO_SPI_MasterDeinit(FLEXIO_SPI_Type *base);
/*!
* @brief Gets the default configuration to configure the FlexIO SPI master. The configuration
* can be used directly by calling the FLEXIO_SPI_MasterConfigure().
* Example:
@code
flexio_spi_master_config_t masterConfig;
FLEXIO_SPI_MasterGetDefaultConfig(&masterConfig);
@endcode
* @param masterConfig Pointer to the flexio_spi_master_config_t structure.
*/
void FLEXIO_SPI_MasterGetDefaultConfig(flexio_spi_master_config_t *masterConfig);
/*!
* @brief Ungates the FlexIO clock, resets the FlexIO module, configures the FlexIO SPI slave hardware
* configuration, and configures the FlexIO SPI with FlexIO SPI slave configuration. The
* configuration structure can be filled by the user, or be set with default values
* by the FLEXIO_SPI_SlaveGetDefaultConfig().
*
* @note Only one timer is needed in the FlexIO SPI slave. As a result, the second timer index is ignored.
* FlexIO SPI slave only support CPOL = 0, which means clock inactive low.
* Example
@code
FLEXIO_SPI_Type spiDev = {
.flexioBase = FLEXIO,
.SDOPinIndex = 0,
.SDIPinIndex = 1,
.SCKPinIndex = 2,
.CSnPinIndex = 3,
.shifterIndex = {0,1},
.timerIndex = {0}
};
flexio_spi_slave_config_t config = {
.enableSlave = true,
.enableInDoze = false,
.enableInDebug = true,
.enableFastAccess = false,
.phase = kFLEXIO_SPI_ClockPhaseFirstEdge,
.direction = kFLEXIO_SPI_MsbFirst,
.dataMode = kFLEXIO_SPI_8BitMode
};
FLEXIO_SPI_SlaveInit(&spiDev, &config);
@endcode
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param slaveConfig Pointer to the flexio_spi_slave_config_t structure.
*/
void FLEXIO_SPI_SlaveInit(FLEXIO_SPI_Type *base, flexio_spi_slave_config_t *slaveConfig);
/*!
* @brief Gates the FlexIO clock.
*
* @param base Pointer to the FLEXIO_SPI_Type.
*/
void FLEXIO_SPI_SlaveDeinit(FLEXIO_SPI_Type *base);
/*!
* @brief Gets the default configuration to configure the FlexIO SPI slave. The configuration
* can be used directly for calling the FLEXIO_SPI_SlaveConfigure().
* Example:
@code
flexio_spi_slave_config_t slaveConfig;
FLEXIO_SPI_SlaveGetDefaultConfig(&slaveConfig);
@endcode
* @param slaveConfig Pointer to the flexio_spi_slave_config_t structure.
*/
void FLEXIO_SPI_SlaveGetDefaultConfig(flexio_spi_slave_config_t *slaveConfig);
/*@}*/
/*!
* @name Status
* @{
*/
/*!
* @brief Gets FlexIO SPI status flags.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @return status flag; Use the status flag to AND the following flag mask and get the status.
* @arg kFLEXIO_SPI_TxEmptyFlag
* @arg kFLEXIO_SPI_RxEmptyFlag
*/
uint32_t FLEXIO_SPI_GetStatusFlags(FLEXIO_SPI_Type *base);
/*!
* @brief Clears FlexIO SPI status flags.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param mask status flag
* The parameter can be any combination of the following values:
* @arg kFLEXIO_SPI_TxEmptyFlag
* @arg kFLEXIO_SPI_RxEmptyFlag
*/
void FLEXIO_SPI_ClearStatusFlags(FLEXIO_SPI_Type *base, uint32_t mask);
/*@}*/
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables the FlexIO SPI interrupt.
*
* This function enables the FlexIO SPI interrupt.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param mask interrupt source. The parameter can be any combination of the following values:
* @arg kFLEXIO_SPI_RxFullInterruptEnable
* @arg kFLEXIO_SPI_TxEmptyInterruptEnable
*/
void FLEXIO_SPI_EnableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask);
/*!
* @brief Disables the FlexIO SPI interrupt.
*
* This function disables the FlexIO SPI interrupt.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param mask interrupt source The parameter can be any combination of the following values:
* @arg kFLEXIO_SPI_RxFullInterruptEnable
* @arg kFLEXIO_SPI_TxEmptyInterruptEnable
*/
void FLEXIO_SPI_DisableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask);
/*@}*/
/*!
* @name DMA Control
* @{
*/
/*!
* @brief Enables/disables the FlexIO SPI transmit DMA. This function enables/disables the FlexIO SPI Tx DMA,
* which means that asserting the kFLEXIO_SPI_TxEmptyFlag does/doesn't trigger the DMA request.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param mask SPI DMA source.
* @param enable True means enable DMA, false means disable DMA.
*/
void FLEXIO_SPI_EnableDMA(FLEXIO_SPI_Type *base, uint32_t mask, bool enable);
/*!
* @brief Gets the FlexIO SPI transmit data register address for MSB first transfer.
*
* This function returns the SPI data register address, which is mainly used by DMA/eDMA.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param direction Shift direction of MSB first or LSB first.
* @return FlexIO SPI transmit data register address.
*/
static inline uint32_t FLEXIO_SPI_GetTxDataRegisterAddress(FLEXIO_SPI_Type *base,
flexio_spi_shift_direction_t direction)
{
if (direction == kFLEXIO_SPI_MsbFirst)
{
return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferBitSwapped,
base->shifterIndex[0]) +
3U;
}
else
{
return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBuffer, base->shifterIndex[0]);
}
}
/*!
* @brief Gets the FlexIO SPI receive data register address for the MSB first transfer.
*
* This function returns the SPI data register address, which is mainly used by DMA/eDMA.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param direction Shift direction of MSB first or LSB first.
* @return FlexIO SPI receive data register address.
*/
static inline uint32_t FLEXIO_SPI_GetRxDataRegisterAddress(FLEXIO_SPI_Type *base,
flexio_spi_shift_direction_t direction)
{
if (direction == kFLEXIO_SPI_MsbFirst)
{
return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferBitSwapped, base->shifterIndex[1]);
}
else
{
return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferByteSwapped,
base->shifterIndex[1]);
}
}
/*@}*/
/*!
* @name Bus Operations
* @{
*/
/*!
* @brief Enables/disables the FlexIO SPI module operation.
*
* @param base Pointer to the FLEXIO_SPI_Type.
* @param enable True to enable, false to disable.
*/
static inline void FLEXIO_SPI_Enable(FLEXIO_SPI_Type *base, bool enable)
{
if (enable)
{
base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
}
else
{
base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK;
}
}
/*!
* @brief Sets baud rate for the FlexIO SPI transfer, which is only used for the master.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param baudRate_Bps Baud Rate needed in Hz.
* @param srcClockHz SPI source clock frequency in Hz.
*/
void FLEXIO_SPI_MasterSetBaudRate(FLEXIO_SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClockHz);
/*!
* @brief Writes one byte of data, which is sent using the MSB method.
*
* @note This is a non-blocking API, which returns directly after the data is put into the
* data register but the data transfer is not finished on the bus. Ensure that
* the TxEmptyFlag is asserted before calling this API.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param direction Shift direction of MSB first or LSB first.
* @param data 8 bit/16 bit data.
*/
static inline void FLEXIO_SPI_WriteData(FLEXIO_SPI_Type *base, flexio_spi_shift_direction_t direction, uint16_t data)
{
if (direction == kFLEXIO_SPI_MsbFirst)
{
base->flexioBase->SHIFTBUFBBS[base->shifterIndex[0]] = data;
}
else
{
base->flexioBase->SHIFTBUF[base->shifterIndex[0]] = data;
}
}
/*!
* @brief Reads 8 bit/16 bit data.
*
* @note This is a non-blocking API, which returns directly after the data is read from the
* data register. Ensure that the RxFullFlag is asserted before calling this API.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param direction Shift direction of MSB first or LSB first.
* @return 8 bit/16 bit data received.
*/
static inline uint16_t FLEXIO_SPI_ReadData(FLEXIO_SPI_Type *base, flexio_spi_shift_direction_t direction)
{
if (direction == kFLEXIO_SPI_MsbFirst)
{
return base->flexioBase->SHIFTBUFBIS[base->shifterIndex[1]];
}
else
{
return base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]];
}
}
/*!
* @brief Sends a buffer of data bytes.
*
* @note This function blocks using the polling method until all bytes have been sent.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param direction Shift direction of MSB first or LSB first.
* @param buffer The data bytes to send.
* @param size The number of data bytes to send.
*/
void FLEXIO_SPI_WriteBlocking(FLEXIO_SPI_Type *base,
flexio_spi_shift_direction_t direction,
const uint8_t *buffer,
size_t size);
/*!
* @brief Receives a buffer of bytes.
*
* @note This function blocks using the polling method until all bytes have been received.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param direction Shift direction of MSB first or LSB first.
* @param buffer The buffer to store the received bytes.
* @param size The number of data bytes to be received.
* @param direction Shift direction of MSB first or LSB first.
*/
void FLEXIO_SPI_ReadBlocking(FLEXIO_SPI_Type *base,
flexio_spi_shift_direction_t direction,
uint8_t *buffer,
size_t size);
/*!
* @brief Receives a buffer of bytes.
*
* @note This function blocks via polling until all bytes have been received.
*
* @param base pointer to FLEXIO_SPI_Type structure
* @param xfer FlexIO SPI transfer structure, see #flexio_spi_transfer_t.
*/
void FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_transfer_t *xfer);
/*Transactional APIs*/
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the FlexIO SPI Master handle, which is used in transactional functions.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
* @param callback The callback function.
* @param userData The parameter of the callback function.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
*/
status_t FLEXIO_SPI_MasterTransferCreateHandle(FLEXIO_SPI_Type *base,
flexio_spi_master_handle_t *handle,
flexio_spi_master_transfer_callback_t callback,
void *userData);
/*!
* @brief Master transfer data using IRQ.
*
* This function sends data using IRQ. This is a non-blocking function, which returns
* right away. When all data is sent out/received, the callback function is called.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
* @param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t.
* @retval kStatus_Success Successfully start a transfer.
* @retval kStatus_InvalidArgument Input argument is invalid.
* @retval kStatus_FLEXIO_SPI_Busy SPI is not idle, is running another transfer.
*/
status_t FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type *base,
flexio_spi_master_handle_t *handle,
flexio_spi_transfer_t *xfer);
/*!
* @brief Aborts the master data transfer, which used IRQ.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
*/
void FLEXIO_SPI_MasterTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle);
/*!
* @brief Gets the data transfer status which used IRQ.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
* @param count Number of bytes transferred so far by the non-blocking transaction.
* @retval kStatus_InvalidArgument count is Invalid.
* @retval kStatus_Success Successfully return the count.
*/
status_t FLEXIO_SPI_MasterTransferGetCount(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle, size_t *count);
/*!
* @brief FlexIO SPI master IRQ handler function.
*
* @param spiType Pointer to the FLEXIO_SPI_Type structure.
* @param spiHandle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
*/
void FLEXIO_SPI_MasterTransferHandleIRQ(void *spiType, void *spiHandle);
/*!
* @brief Initializes the FlexIO SPI Slave handle, which is used in transactional functions.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
* @param callback The callback function.
* @param userData The parameter of the callback function.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
*/
status_t FLEXIO_SPI_SlaveTransferCreateHandle(FLEXIO_SPI_Type *base,
flexio_spi_slave_handle_t *handle,
flexio_spi_slave_transfer_callback_t callback,
void *userData);
/*!
* @brief Slave transfer data using IRQ.
*
* This function sends data using IRQ. This is a non-blocking function, which returns
* right away. When all data is sent out/received, the callback function is called.
* @param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t.
* @retval kStatus_Success Successfully start a transfer.
* @retval kStatus_InvalidArgument Input argument is invalid.
* @retval kStatus_FLEXIO_SPI_Busy SPI is not idle; it is running another transfer.
*/
status_t FLEXIO_SPI_SlaveTransferNonBlocking(FLEXIO_SPI_Type *base,
flexio_spi_slave_handle_t *handle,
flexio_spi_transfer_t *xfer);
/*!
* @brief Aborts the slave data transfer which used IRQ, share same API with master.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
*/
static inline void FLEXIO_SPI_SlaveTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_slave_handle_t *handle)
{
FLEXIO_SPI_MasterTransferAbort(base, handle);
}
/*!
* @brief Gets the data transfer status which used IRQ, share same API with master.
*
* @param base Pointer to the FLEXIO_SPI_Type structure.
* @param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
* @param count Number of bytes transferred so far by the non-blocking transaction.
* @retval kStatus_InvalidArgument count is Invalid.
* @retval kStatus_Success Successfully return the count.
*/
static inline status_t FLEXIO_SPI_SlaveTransferGetCount(FLEXIO_SPI_Type *base,
flexio_spi_slave_handle_t *handle,
size_t *count)
{
return FLEXIO_SPI_MasterTransferGetCount(base, handle, count);
}
/*!
* @brief FlexIO SPI slave IRQ handler function.
*
* @param spiType Pointer to the FLEXIO_SPI_Type structure.
* @param spiHandle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
*/
void FLEXIO_SPI_SlaveTransferHandleIRQ(void *spiType, void *spiHandle);
/*@}*/
#if defined(__cplusplus)
}
#endif /*_cplusplus*/
/*@}*/
#endif /*_FSL_FLEXIO_SPI_H_*/

View File

@ -1,415 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_flexio_spi_dma.h"
/*******************************************************************************
* Definitons
******************************************************************************/
/*<! Structure definition for spi_dma_private_handle_t. The structure is private. */
typedef struct _flexio_spi_master_dma_private_handle
{
FLEXIO_SPI_Type *base;
flexio_spi_master_dma_handle_t *handle;
} flexio_spi_master_dma_private_handle_t;
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief DMA callback function for FLEXIO SPI send transfer.
*
* @param handle DMA handle pointer.
* @param param Callback function parameter.
*/
static void FLEXIO_SPI_TxDMACallback(dma_handle_t *handle, void *param);
/*!
* @brief DMA callback function for FLEXIO SPI receive transfer.
*
* @param handle DMA handle pointer.
* @param param Callback function parameter.
*/
static void FLEXIO_SPI_RxDMACallback(dma_handle_t *handle, void *param);
/*!
* @brief EDMA config for FLEXIO SPI transfer.
*
* @param base pointer to FLEXIO_SPI_Type structure.
* @param handle pointer to flexio_spi_master_dma_handle_t structure to store the transfer state.
* @param xfer Pointer to flexio spi transfer structure.
*/
static void FLEXIO_SPI_DMAConfig(FLEXIO_SPI_Type *base,
flexio_spi_master_dma_handle_t *handle,
flexio_spi_transfer_t *xfer);
/*******************************************************************************
* Variables
******************************************************************************/
/* Dummy data used to send */
static const uint16_t s_dummyData = FLEXIO_SPI_DUMMYDATA;
/*< @brief user configurable flexio spi handle count. */
#define FLEXIO_SPI_HANDLE_COUNT 2
/*<! Private handle only used for internally. */
static flexio_spi_master_dma_private_handle_t s_dmaPrivateHandle[FLEXIO_SPI_HANDLE_COUNT];
/*******************************************************************************
* Code
******************************************************************************/
static void FLEXIO_SPI_TxDMACallback(dma_handle_t *handle, void *param)
{
flexio_spi_master_dma_private_handle_t *spiPrivateHandle = (flexio_spi_master_dma_private_handle_t *)param;
/* Disable Tx DMA. */
FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, kFLEXIO_SPI_TxDmaEnable, false);
/* Disable interrupt. */
DMA_DisableInterrupts(handle->base, handle->channel);
/* change the state. */
spiPrivateHandle->handle->txInProgress = false;
/* All finished, call the callback. */
if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false))
{
if (spiPrivateHandle->handle->callback)
{
(spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success,
spiPrivateHandle->handle->userData);
}
}
}
static void FLEXIO_SPI_RxDMACallback(dma_handle_t *handle, void *param)
{
flexio_spi_master_dma_private_handle_t *spiPrivateHandle = (flexio_spi_master_dma_private_handle_t *)param;
/* Disable Rx DMA. */
FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, kFLEXIO_SPI_RxDmaEnable, false);
/* Disable interrupt. */
DMA_DisableInterrupts(handle->base, handle->channel);
/* change the state. */
spiPrivateHandle->handle->rxInProgress = false;
/* All finished, call the callback. */
if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false))
{
if (spiPrivateHandle->handle->callback)
{
(spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success,
spiPrivateHandle->handle->userData);
}
}
}
static void FLEXIO_SPI_DMAConfig(FLEXIO_SPI_Type *base,
flexio_spi_master_dma_handle_t *handle,
flexio_spi_transfer_t *xfer)
{
dma_transfer_config_t xferConfig;
flexio_spi_shift_direction_t direction;
uint8_t bytesPerFrame;
/* Configure the values in handle. */
switch (xfer->flags)
{
case kFLEXIO_SPI_8bitMsb:
bytesPerFrame = 1;
direction = kFLEXIO_SPI_MsbFirst;
break;
case kFLEXIO_SPI_8bitLsb:
bytesPerFrame = 1;
direction = kFLEXIO_SPI_LsbFirst;
break;
case kFLEXIO_SPI_16bitMsb:
bytesPerFrame = 2;
direction = kFLEXIO_SPI_MsbFirst;
break;
case kFLEXIO_SPI_16bitLsb:
bytesPerFrame = 2;
direction = kFLEXIO_SPI_LsbFirst;
break;
default:
bytesPerFrame = 1;
direction = kFLEXIO_SPI_MsbFirst;
assert(true);
break;
}
/* Save total transfer size. */
handle->transferSize = xfer->dataSize;
/* Configure tx transfer DMA. */
xferConfig.destAddr = FLEXIO_SPI_GetTxDataRegisterAddress(base, direction);
xferConfig.enableDestIncrement = false;
if (bytesPerFrame == 1U)
{
xferConfig.srcSize = kDMA_Transfersize8bits;
xferConfig.destSize = kDMA_Transfersize8bits;
}
else
{
if (direction == kFLEXIO_SPI_MsbFirst)
{
xferConfig.destAddr -= 1U;
}
xferConfig.srcSize = kDMA_Transfersize16bits;
xferConfig.destSize = kDMA_Transfersize16bits;
}
/* Configure DMA channel. */
if (xfer->txData)
{
xferConfig.enableSrcIncrement = true;
xferConfig.srcAddr = (uint32_t)(xfer->txData);
}
else
{
/* Disable the source increasement and source set to dummyData. */
xferConfig.enableSrcIncrement = false;
xferConfig.srcAddr = (uint32_t)(&s_dummyData);
}
xferConfig.transferSize = xfer->dataSize;
if (handle->txHandle)
{
DMA_SubmitTransfer(handle->txHandle, &xferConfig, kDMA_EnableInterrupt);
}
/* Configure tx transfer DMA. */
if (xfer->rxData)
{
xferConfig.srcAddr = FLEXIO_SPI_GetRxDataRegisterAddress(base, direction);
xferConfig.enableSrcIncrement = false;
xferConfig.destAddr = (uint32_t)(xfer->rxData);
xferConfig.enableDestIncrement = true;
DMA_SubmitTransfer(handle->rxHandle, &xferConfig, kDMA_EnableInterrupt);
handle->rxInProgress = true;
FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_RxDmaEnable, true);
DMA_StartTransfer(handle->rxHandle);
}
/* Always start Tx transfer. */
if (handle->txHandle)
{
handle->txInProgress = true;
FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_TxDmaEnable, true);
DMA_StartTransfer(handle->txHandle);
}
}
status_t FLEXIO_SPI_MasterTransferCreateHandleDMA(FLEXIO_SPI_Type *base,
flexio_spi_master_dma_handle_t *handle,
flexio_spi_master_dma_transfer_callback_t callback,
void *userData,
dma_handle_t *txHandle,
dma_handle_t *rxHandle)
{
assert(handle);
uint8_t index = 0;
/* Find the an empty handle pointer to store the handle. */
for (index = 0; index < FLEXIO_SPI_HANDLE_COUNT; index++)
{
if (s_dmaPrivateHandle[index].base == NULL)
{
s_dmaPrivateHandle[index].base = base;
s_dmaPrivateHandle[index].handle = handle;
break;
}
}
if (index == FLEXIO_SPI_HANDLE_COUNT)
{
return kStatus_OutOfRange;
}
/* Set spi base to handle. */
handle->txHandle = txHandle;
handle->rxHandle = rxHandle;
/* Register callback and userData. */
handle->callback = callback;
handle->userData = userData;
/* Set SPI state to idle. */
handle->txInProgress = false;
handle->rxInProgress = false;
/* Install callback for Tx/Rx dma channel. */
if (handle->txHandle)
{
DMA_SetCallback(handle->txHandle, FLEXIO_SPI_TxDMACallback, &s_dmaPrivateHandle[index]);
}
if (handle->rxHandle)
{
DMA_SetCallback(handle->rxHandle, FLEXIO_SPI_RxDMACallback, &s_dmaPrivateHandle[index]);
}
return kStatus_Success;
}
status_t FLEXIO_SPI_MasterTransferDMA(FLEXIO_SPI_Type *base,
flexio_spi_master_dma_handle_t *handle,
flexio_spi_transfer_t *xfer)
{
assert(handle);
assert(xfer);
uint32_t dataMode = 0;
uint16_t timerCmp = base->flexioBase->TIMCMP[base->timerIndex[0]];
timerCmp &= 0x00FFU;
/* Check if the device is busy. */
if ((handle->txInProgress) || (handle->rxInProgress))
{
return kStatus_FLEXIO_SPI_Busy;
}
/* Check if input parameter invalid. */
if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U))
{
return kStatus_InvalidArgument;
}
/* configure data mode. */
if ((xfer->flags == kFLEXIO_SPI_8bitMsb) || (xfer->flags == kFLEXIO_SPI_8bitLsb))
{
dataMode = (8 * 2 - 1U) << 8U;
}
else if ((xfer->flags == kFLEXIO_SPI_16bitMsb) || (xfer->flags == kFLEXIO_SPI_16bitLsb))
{
dataMode = (16 * 2 - 1U) << 8U;
}
else
{
dataMode = 8 * 2 - 1U;
}
dataMode |= timerCmp;
base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
FLEXIO_SPI_DMAConfig(base, handle, xfer);
return kStatus_Success;
}
status_t FLEXIO_SPI_MasterTransferGetCountDMA(FLEXIO_SPI_Type *base,
flexio_spi_master_dma_handle_t *handle,
size_t *count)
{
assert(handle);
if (!count)
{
return kStatus_InvalidArgument;
}
if (handle->rxInProgress)
{
*count = (handle->transferSize - DMA_GetRemainingBytes(handle->rxHandle->base, handle->rxHandle->channel));
}
else
{
*count = (handle->transferSize - DMA_GetRemainingBytes(handle->txHandle->base, handle->txHandle->channel));
}
return kStatus_Success;
}
void FLEXIO_SPI_MasterTransferAbortDMA(FLEXIO_SPI_Type *base, flexio_spi_master_dma_handle_t *handle)
{
assert(handle);
/* Disable dma. */
DMA_AbortTransfer(handle->txHandle);
DMA_AbortTransfer(handle->rxHandle);
/* Disable DMA enable bit. */
FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_DmaAllEnable, false);
/* Set the handle state. */
handle->txInProgress = false;
handle->rxInProgress = false;
}
status_t FLEXIO_SPI_SlaveTransferDMA(FLEXIO_SPI_Type *base,
flexio_spi_slave_dma_handle_t *handle,
flexio_spi_transfer_t *xfer)
{
assert(handle);
assert(xfer);
uint32_t dataMode = 0;
/* Check if the device is busy. */
if ((handle->txInProgress) || (handle->rxInProgress))
{
return kStatus_FLEXIO_SPI_Busy;
}
/* Check if input parameter invalid. */
if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U))
{
return kStatus_InvalidArgument;
}
/* configure data mode. */
if ((xfer->flags == kFLEXIO_SPI_8bitMsb) || (xfer->flags == kFLEXIO_SPI_8bitLsb))
{
dataMode = 8 * 2 - 1U;
}
else if ((xfer->flags == kFLEXIO_SPI_16bitMsb) || (xfer->flags == kFLEXIO_SPI_16bitLsb))
{
dataMode = 16 * 2 - 1U;
}
else
{
dataMode = 8 * 2 - 1U;
}
base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
FLEXIO_SPI_DMAConfig(base, handle, xfer);
return kStatus_Success;
}

View File

@ -1,222 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_FLEXIO_SPI_DMA_H_
#define _FSL_FLEXIO_SPI_DMA_H_
#include "fsl_flexio_spi.h"
#include "fsl_dma.h"
/*!
* @addtogroup flexio_dma_spi
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief typedef for flexio_spi_master_dma_handle_t in advance. */
typedef struct _flexio_spi_master_dma_handle flexio_spi_master_dma_handle_t;
/*! @brief Slave handle is the same with master handle. */
typedef flexio_spi_master_dma_handle_t flexio_spi_slave_dma_handle_t;
/*! @brief FlexIO SPI master callback for finished transmit */
typedef void (*flexio_spi_master_dma_transfer_callback_t)(FLEXIO_SPI_Type *base,
flexio_spi_master_dma_handle_t *handle,
status_t status,
void *userData);
/*! @brief FlexIO SPI slave callback for finished transmit */
typedef void (*flexio_spi_slave_dma_transfer_callback_t)(FLEXIO_SPI_Type *base,
flexio_spi_slave_dma_handle_t *handle,
status_t status,
void *userData);
/*! @brief FlexIO SPI DMA transfer handle, users should not touch the content of the handle.*/
struct _flexio_spi_master_dma_handle
{
size_t transferSize; /*!< Total bytes to be transferred. */
bool txInProgress; /*!< Send transfer in progress */
bool rxInProgress; /*!< Receive transfer in progress */
dma_handle_t *txHandle; /*!< DMA handler for SPI send */
dma_handle_t *rxHandle; /*!< DMA handler for SPI receive */
flexio_spi_master_dma_transfer_callback_t callback; /*!< Callback for SPI DMA transfer */
void *userData; /*!< User Data for SPI DMA callback */
};
/*******************************************************************************
* APIs
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name DMA Transactional
* @{
*/
/*!
* @brief Initializes the FLEXO SPI master DMA handle.
*
* This function initializes the FLEXO SPI master DMA handle which can be used for other FLEXO SPI master transactional
* APIs.
* Usually, for a specified FLEXO SPI instance, user need only call this API once to get the initialized handle.
*
* @param base pointer to FLEXIO_SPI_Type structure.
* @param handle pointer to flexio_spi_master_dma_handle_t structure to store the transfer state.
* @param callback SPI callback, NULL means no callback.
* @param userData callback function parameter.
* @param txHandle User requested DMA handle for FlexIO SPI RX DMA transfer.
* @param rxHandle User requested DMA handle for FlexIO SPI TX DMA transfer.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO SPI DMA type/handle table out of range.
*/
status_t FLEXIO_SPI_MasterTransferCreateHandleDMA(FLEXIO_SPI_Type *base,
flexio_spi_master_dma_handle_t *handle,
flexio_spi_master_dma_transfer_callback_t callback,
void *userData,
dma_handle_t *txHandle,
dma_handle_t *rxHandle);
/*!
* @brief Performs a non-blocking FlexIO SPI transfer using DMA.
*
* @note This interface returned immediately after transfer initiates, users could call
* FLEXIO_SPI_MasterGetTransferCountDMA to poll the transfer status to check
* whether FlexIO SPI transfer finished.
*
* @param base pointer to FLEXIO_SPI_Type structure.
* @param handle pointer to flexio_spi_master_dma_handle_t structure to store the transfer state.
* @param xfer Pointer to FlexIO SPI transfer structure.
* @retval kStatus_Success Successfully start a transfer.
* @retval kStatus_InvalidArgument Input argument is invalid.
* @retval kStatus_FLEXIO_SPI_Busy FlexIO SPI is not idle, is running another transfer.
*/
status_t FLEXIO_SPI_MasterTransferDMA(FLEXIO_SPI_Type *base,
flexio_spi_master_dma_handle_t *handle,
flexio_spi_transfer_t *xfer);
/*!
* @brief Aborts a FlexIO SPI transfer using DMA.
*
* @param base pointer to FLEXIO_SPI_Type structure.
* @param handle FlexIO SPI DMA handle pointer.
*/
void FLEXIO_SPI_MasterTransferAbortDMA(FLEXIO_SPI_Type *base, flexio_spi_master_dma_handle_t *handle);
/*!
* @brief Gets the remaining bytes for FlexIO SPI DMA transfer.
*
* @param base pointer to FLEXIO_SPI_Type structure.
* @param handle FlexIO SPI DMA handle pointer.
* @param count Number of bytes transferred so far by the non-blocking transaction.
*/
status_t FLEXIO_SPI_MasterTransferGetCountDMA(FLEXIO_SPI_Type *base,
flexio_spi_master_dma_handle_t *handle,
size_t *count);
/*!
* @brief Initializes the FlexIO SPI slave DMA handle.
*
* This function initializes the FlexIO SPI slave DMA handle.
*
* @param base pointer to FLEXIO_SPI_Type structure.
* @param handle pointer to flexio_spi_slave_dma_handle_t structure to store the transfer state.
* @param callback SPI callback, NULL means no callback.
* @param userData callback function parameter.
* @param txHandle User requested DMA handle for FlexIO SPI TX DMA transfer.
* @param rxHandle User requested DMA handle for FlexIO SPI RX DMA transfer.
*/
static inline void FLEXIO_SPI_SlaveTransferCreateHandleDMA(FLEXIO_SPI_Type *base,
flexio_spi_slave_dma_handle_t *handle,
flexio_spi_slave_dma_transfer_callback_t callback,
void *userData,
dma_handle_t *txHandle,
dma_handle_t *rxHandle)
{
FLEXIO_SPI_MasterTransferCreateHandleDMA(base, handle, callback, userData, txHandle, rxHandle);
}
/*!
* @brief Performs a non-blocking FlexIO SPI transfer using DMA.
*
* @note This interface returned immediately after transfer initiates, users could call
* FLEXIO_SPI_SlaveGetTransferCountDMA to poll the transfer status to
* check whether FlexIO SPI transfer finished.
*
* @param base pointer to FLEXIO_SPI_Type structure.
* @param handle pointer to flexio_spi_slave_dma_handle_t structure to store the transfer state.
* @param xfer Pointer to FlexIO SPI transfer structure.
* @retval kStatus_Success Successfully start a transfer.
* @retval kStatus_InvalidArgument Input argument is invalid.
* @retval kStatus_FLEXIO_SPI_Busy FlexIO SPI is not idle, is running another transfer.
*/
status_t FLEXIO_SPI_SlaveTransferDMA(FLEXIO_SPI_Type *base,
flexio_spi_slave_dma_handle_t *handle,
flexio_spi_transfer_t *xfer);
/*!
* @brief Aborts a FlexIO SPI transfer using DMA.
*
* @param base pointer to FLEXIO_SPI_Type structure.
* @param handle pointer to flexio_spi_slave_dma_handle_t structure to store the transfer state.
*/
static inline void FLEXIO_SPI_SlaveTransferAbortDMA(FLEXIO_SPI_Type *base, flexio_spi_slave_dma_handle_t *handle)
{
FLEXIO_SPI_MasterTransferAbortDMA(base, handle);
}
/*!
* @brief Gets the remaining bytes to be transferred for FlexIO SPI DMA.
*
* @param base pointer to FLEXIO_SPI_Type structure.
* @param handle FlexIO SPI DMA handle pointer.
* @param count Number of bytes transferred so far by the non-blocking transaction.
*/
static inline status_t FLEXIO_SPI_SlaveTransferGetCountDMA(FLEXIO_SPI_Type *base,
flexio_spi_slave_dma_handle_t *handle,
size_t *count)
{
return FLEXIO_SPI_MasterTransferGetCountDMA(base, handle, count);
}
/*! @} */
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif

View File

@ -1,690 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_flexio_uart.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*<! @brief uart transfer state. */
enum _flexio_uart_transfer_states
{
kFLEXIO_UART_TxIdle, /* TX idle. */
kFLEXIO_UART_TxBusy, /* TX busy. */
kFLEXIO_UART_RxIdle, /* RX idle. */
kFLEXIO_UART_RxBusy /* RX busy. */
};
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get the length of received data in RX ring buffer.
*
* @param handle FLEXIO UART handle pointer.
* @return Length of received data in RX ring buffer.
*/
static size_t FLEXIO_UART_TransferGetRxRingBufferLength(flexio_uart_handle_t *handle);
/*!
* @brief Check whether the RX ring buffer is full.
*
* @param handle FLEXIO UART handle pointer.
* @retval true RX ring buffer is full.
* @retval false RX ring buffer is not full.
*/
static bool FLEXIO_UART_TransferIsRxRingBufferFull(flexio_uart_handle_t *handle);
/*******************************************************************************
* Codes
******************************************************************************/
static size_t FLEXIO_UART_TransferGetRxRingBufferLength(flexio_uart_handle_t *handle)
{
size_t size;
if (handle->rxRingBufferTail > handle->rxRingBufferHead)
{
size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail);
}
else
{
size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail);
}
return size;
}
static bool FLEXIO_UART_TransferIsRxRingBufferFull(flexio_uart_handle_t *handle)
{
bool full;
if (FLEXIO_UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U))
{
full = true;
}
else
{
full = false;
}
return full;
}
void FLEXIO_UART_Init(FLEXIO_UART_Type *base, const flexio_uart_config_t *userConfig, uint32_t srcClock_Hz)
{
assert(base && userConfig);
flexio_shifter_config_t shifterConfig;
flexio_timer_config_t timerConfig;
uint32_t ctrlReg = 0;
uint16_t timerDiv = 0;
uint16_t timerCmp = 0;
/* Clear the shifterConfig & timerConfig struct. */
memset(&shifterConfig, 0, sizeof(shifterConfig));
memset(&timerConfig, 0, sizeof(timerConfig));
/* Ungate flexio clock. */
CLOCK_EnableClock(kCLOCK_Flexio0);
/* Reset FLEXIO before configuration. */
FLEXIO_Reset(base->flexioBase);
/* Configure FLEXIO UART */
ctrlReg = base->flexioBase->CTRL;
ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
ctrlReg |= (FLEXIO_CTRL_DOZEN(userConfig->enableInDoze) | FLEXIO_CTRL_DBGE(userConfig->enableInDebug) |
FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) | FLEXIO_CTRL_FLEXEN(userConfig->enableUart));
base->flexioBase->CTRL = ctrlReg;
/* Do hardware configuration. */
/* 1. Configure the shifter 0 for tx. */
shifterConfig.timerSelect = base->timerIndex[0];
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
shifterConfig.pinConfig = kFLEXIO_PinConfigOutput;
shifterConfig.pinSelect = base->TxPinIndex;
shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow;
FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
/*2. Configure the timer 0 for tx. */
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
timerConfig.pinSelect = base->TxPinIndex;
timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
timerConfig.timerReset = kFLEXIO_TimerResetNever;
timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable;
timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
timerDiv = srcClock_Hz / userConfig->baudRate_Bps;
timerDiv = timerDiv / 2 - 1;
timerCmp = ((uint32_t)(userConfig->bitCountPerChar * 2 - 1)) << 8U;
timerCmp |= timerDiv;
timerConfig.timerCompare = timerCmp;
FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
/* 3. Configure the shifter 1 for rx. */
shifterConfig.timerSelect = base->timerIndex[1];
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
shifterConfig.pinSelect = base->RxPinIndex;
shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow;
FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
/* 4. Configure the timer 1 for rx. */
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->RxPinIndex);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceExternal;
timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
timerConfig.pinSelect = base->RxPinIndex;
timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
timerConfig.timerOutput = kFLEXIO_TimerOutputOneAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinRisingEdge;
timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdge;
timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable;
timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
timerConfig.timerCompare = timerCmp;
FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
}
void FLEXIO_UART_Deinit(FLEXIO_UART_Type *base)
{
/* Disable FLEXIO UART module. */
FLEXIO_UART_Enable(base, false);
/* Gate flexio clock. */
CLOCK_DisableClock(kCLOCK_Flexio0);
}
void FLEXIO_UART_GetDefaultConfig(flexio_uart_config_t *userConfig)
{
assert(userConfig);
userConfig->enableUart = true;
userConfig->enableInDoze = false;
userConfig->enableInDebug = true;
userConfig->enableFastAccess = false;
/* Default baud rate 115200. */
userConfig->baudRate_Bps = 115200U;
/* Default bit count at 8. */
userConfig->bitCountPerChar = kFLEXIO_UART_8BitsPerChar;
}
void FLEXIO_UART_EnableInterrupts(FLEXIO_UART_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_UART_TxDataRegEmptyInterruptEnable)
{
FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
}
if (mask & kFLEXIO_UART_RxDataRegFullInterruptEnable)
{
FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
}
}
void FLEXIO_UART_DisableInterrupts(FLEXIO_UART_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_UART_TxDataRegEmptyInterruptEnable)
{
FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
}
if (mask & kFLEXIO_UART_RxDataRegFullInterruptEnable)
{
FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
}
}
uint32_t FLEXIO_UART_GetStatusFlags(FLEXIO_UART_Type *base)
{
uint32_t status = 0;
status =
((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]);
status |=
(((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
<< 1U);
status |=
(((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
<< 2U);
return status;
}
void FLEXIO_UART_ClearStatusFlags(FLEXIO_UART_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_UART_TxDataRegEmptyFlag)
{
FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]);
}
if (mask & kFLEXIO_UART_RxDataRegFullFlag)
{
FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]);
}
if (mask & kFLEXIO_UART_RxOverRunFlag)
{
FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
}
}
void FLEXIO_UART_WriteBlocking(FLEXIO_UART_Type *base, const uint8_t *txData, size_t txSize)
{
assert(txData);
assert(txSize);
while (txSize--)
{
/* Wait until data transfer complete. */
while (!(FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])))
{
}
base->flexioBase->SHIFTBUF[base->shifterIndex[0]] = *txData++;
}
}
void FLEXIO_UART_ReadBlocking(FLEXIO_UART_Type *base, uint8_t *rxData, size_t rxSize)
{
assert(rxData);
assert(rxSize);
while (rxSize--)
{
/* Wait until data transfer complete. */
while (!(FLEXIO_UART_GetStatusFlags(base) & kFLEXIO_UART_RxDataRegFullFlag))
{
}
*rxData++ = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]];
}
}
status_t FLEXIO_UART_TransferCreateHandle(FLEXIO_UART_Type *base,
flexio_uart_handle_t *handle,
flexio_uart_transfer_callback_t callback,
void *userData)
{
assert(handle);
IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
/* Zero the handle. */
memset(handle, 0, sizeof(*handle));
/* Set the TX/RX state. */
handle->rxState = kFLEXIO_UART_RxIdle;
handle->txState = kFLEXIO_UART_TxIdle;
/* Set the callback and user data. */
handle->callback = callback;
handle->userData = userData;
/* Enable interrupt in NVIC. */
EnableIRQ(flexio_irqs[0]);
/* Save the context in global variables to support the double weak mechanism. */
return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_UART_TransferHandleIRQ);
}
void FLEXIO_UART_TransferStartRingBuffer(FLEXIO_UART_Type *base,
flexio_uart_handle_t *handle,
uint8_t *ringBuffer,
size_t ringBufferSize)
{
assert(handle);
/* Setup the ringbuffer address */
if (ringBuffer)
{
handle->rxRingBuffer = ringBuffer;
handle->rxRingBufferSize = ringBufferSize;
handle->rxRingBufferHead = 0U;
handle->rxRingBufferTail = 0U;
/* Enable the interrupt to accept the data when user need the ring buffer. */
FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable);
}
}
void FLEXIO_UART_TransferStopRingBuffer(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle)
{
assert(handle);
if (handle->rxState == kFLEXIO_UART_RxIdle)
{
FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable);
}
handle->rxRingBuffer = NULL;
handle->rxRingBufferSize = 0U;
handle->rxRingBufferHead = 0U;
handle->rxRingBufferTail = 0U;
}
status_t FLEXIO_UART_TransferSendNonBlocking(FLEXIO_UART_Type *base,
flexio_uart_handle_t *handle,
flexio_uart_transfer_t *xfer)
{
status_t status;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* Return error if current TX busy. */
if (kFLEXIO_UART_TxBusy == handle->txState)
{
status = kStatus_FLEXIO_UART_TxBusy;
}
else
{
handle->txData = xfer->data;
handle->txDataSize = xfer->dataSize;
handle->txState = kFLEXIO_UART_TxBusy;
/* Enable transmiter interrupt. */
FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable);
status = kStatus_Success;
}
return status;
}
void FLEXIO_UART_TransferAbortSend(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle)
{
/* Disable the transmitter and disable the interrupt. */
FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable);
handle->txDataSize = 0;
handle->txState = kFLEXIO_UART_TxIdle;
}
status_t FLEXIO_UART_TransferGetSendCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count)
{
assert(handle);
if (!count)
{
return kStatus_Success;
}
*count = handle->txSize - handle->txDataSize;
return kStatus_Success;
}
status_t FLEXIO_UART_TransferReceiveNonBlocking(FLEXIO_UART_Type *base,
flexio_uart_handle_t *handle,
flexio_uart_transfer_t *xfer,
size_t *receivedBytes)
{
uint32_t i;
status_t status;
/* How many bytes to copy from ring buffer to user memory. */
size_t bytesToCopy = 0U;
/* How many bytes to receive. */
size_t bytesToReceive;
/* How many bytes currently have received. */
size_t bytesCurrentReceived;
uint32_t regPrimask = 0U;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* How to get data:
1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
to uart handle, enable interrupt to store received data to xfer->data. When
all data received, trigger callback.
2. If RX ring buffer is enabled and not empty, get data from ring buffer first.
If there are enough data in ring buffer, copy them to xfer->data and return.
If there are not enough data in ring buffer, copy all of them to xfer->data,
save the xfer->data remained empty space to uart handle, receive data
to this empty space and trigger callback when finished. */
if (kFLEXIO_UART_RxBusy == handle->rxState)
{
status = kStatus_FLEXIO_UART_RxBusy;
}
else
{
bytesToReceive = xfer->dataSize;
bytesCurrentReceived = 0U;
/* If RX ring buffer is used. */
if (handle->rxRingBuffer)
{
/* Disable IRQ, protect ring buffer. */
regPrimask = __get_PRIMASK();
__disable_irq();
/* How many bytes in RX ring buffer currently. */
bytesToCopy = FLEXIO_UART_TransferGetRxRingBufferLength(handle);
if (bytesToCopy)
{
bytesToCopy = MIN(bytesToReceive, bytesToCopy);
bytesToReceive -= bytesToCopy;
/* Copy data from ring buffer to user memory. */
for (i = 0U; i < bytesToCopy; i++)
{
xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail];
/* Wrap to 0. Not use modulo (%) because it might be large and slow. */
if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
{
handle->rxRingBufferTail = 0U;
}
else
{
handle->rxRingBufferTail++;
}
}
}
/* If ring buffer does not have enough data, still need to read more data. */
if (bytesToReceive)
{
/* No data in ring buffer, save the request to UART handle. */
handle->rxData = xfer->data + bytesCurrentReceived;
handle->rxDataSize = bytesToReceive;
handle->rxState = kFLEXIO_UART_RxBusy;
}
/* Recover PRIMASK, enable IRQ if previously enabled. */
__set_PRIMASK(regPrimask);
}
/* Ring buffer not used. */
else
{
handle->rxData = xfer->data + bytesCurrentReceived;
handle->rxDataSize = bytesToReceive;
handle->rxState = kFLEXIO_UART_RxBusy;
/* Enable RX interrupt. */
FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable);
}
/* Return the how many bytes have read. */
if (receivedBytes)
{
*receivedBytes = bytesCurrentReceived;
}
status = kStatus_Success;
}
return status;
}
void FLEXIO_UART_TransferAbortReceive(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle)
{
/* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
if (!handle->rxRingBuffer)
{
/* Disable RX interrupt. */
FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable);
}
handle->rxDataSize = 0U;
handle->rxState = kFLEXIO_UART_RxIdle;
}
status_t FLEXIO_UART_TransferGetReceiveCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count)
{
assert(handle);
if (!count)
{
return kStatus_Success;
}
*count = handle->rxSize - handle->rxDataSize;
return kStatus_Success;
}
void FLEXIO_UART_TransferHandleIRQ(void *uartType, void *uartHandle)
{
uint8_t count = 1;
FLEXIO_UART_Type *base = (FLEXIO_UART_Type *)uartType;
flexio_uart_handle_t *handle = (flexio_uart_handle_t *)uartHandle;
/* Read the status back. */
uint8_t status = FLEXIO_UART_GetStatusFlags(base);
/* If RX overrun. */
if (kFLEXIO_UART_RxOverRunFlag & status)
{
/* Clear Overrun flag. */
FLEXIO_UART_ClearStatusFlags(base, kFLEXIO_UART_RxOverRunFlag);
/* Trigger callback. */
if (handle->callback)
{
handle->callback(base, handle, kStatus_FLEXIO_UART_RxHardwareOverrun, handle->userData);
}
}
/* Receive data register full */
if ((kFLEXIO_UART_RxDataRegFullFlag & status) && (base->flexioBase->SHIFTSIEN & (1U << base->shifterIndex[1])))
{
/* If handle->rxDataSize is not 0, first save data to handle->rxData. */
if (handle->rxDataSize)
{
/* Using non block API to read the data from the registers. */
FLEXIO_UART_ReadByte(base, handle->rxData);
handle->rxDataSize--;
handle->rxData++;
count--;
/* If all the data required for upper layer is ready, trigger callback. */
if (!handle->rxDataSize)
{
handle->rxState = kFLEXIO_UART_RxIdle;
if (handle->callback)
{
handle->callback(base, handle, kStatus_FLEXIO_UART_RxIdle, handle->userData);
}
}
}
if (handle->rxRingBuffer)
{
if (count)
{
/* If RX ring buffer is full, trigger callback to notify over run. */
if (FLEXIO_UART_TransferIsRxRingBufferFull(handle))
{
if (handle->callback)
{
handle->callback(base, handle, kStatus_FLEXIO_UART_RxRingBufferOverrun, handle->userData);
}
}
/* If ring buffer is still full after callback function, the oldest data is overrided. */
if (FLEXIO_UART_TransferIsRxRingBufferFull(handle))
{
/* Increase handle->rxRingBufferTail to make room for new data. */
if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
{
handle->rxRingBufferTail = 0U;
}
else
{
handle->rxRingBufferTail++;
}
}
/* Read data. */
handle->rxRingBuffer[handle->rxRingBufferHead] = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]];
/* Increase handle->rxRingBufferHead. */
if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
{
handle->rxRingBufferHead = 0U;
}
else
{
handle->rxRingBufferHead++;
}
}
}
/* If no receive requst pending, stop RX interrupt. */
else if (!handle->rxDataSize)
{
FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable);
}
else
{
}
}
/* Send data register empty and the interrupt is enabled. */
if ((kFLEXIO_UART_TxDataRegEmptyFlag & status) && (base->flexioBase->SHIFTSIEN & (1U << base->shifterIndex[0])))
{
if (handle->txDataSize)
{
/* Using non block API to write the data to the registers. */
FLEXIO_UART_WriteByte(base, handle->txData);
handle->txData++;
handle->txDataSize--;
count--;
/* If all the data are written to data register, TX finished. */
if (!handle->txDataSize)
{
handle->txState = kFLEXIO_UART_TxIdle;
/* Disable TX register empty interrupt. */
FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable);
/* Trigger callback. */
if (handle->callback)
{
handle->callback(base, handle, kStatus_FLEXIO_UART_TxIdle, handle->userData);
}
}
}
}
}

View File

@ -1,586 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_FLEXIO_UART_H_
#define _FSL_FLEXIO_UART_H_
#include "fsl_common.h"
#include "fsl_flexio.h"
/*!
* @addtogroup flexio_uart
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief FlexIO UART driver version 2.1.0. */
#define FSL_FLEXIO_UART_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
/*@}*/
/*! @brief Error codes for the UART driver. */
enum _flexio_uart_status
{
kStatus_FLEXIO_UART_TxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 0), /*!< Transmitter is busy. */
kStatus_FLEXIO_UART_RxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 1), /*!< Receiver is busy. */
kStatus_FLEXIO_UART_TxIdle = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 2), /*!< UART transmitter is idle. */
kStatus_FLEXIO_UART_RxIdle = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 3), /*!< UART receiver is idle. */
kStatus_FLEXIO_UART_ERROR = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 4), /*!< ERROR happens on UART. */
kStatus_FLEXIO_UART_RxRingBufferOverrun =
MAKE_STATUS(kStatusGroup_FLEXIO_UART, 5), /*!< UART RX software ring buffer overrun. */
kStatus_FLEXIO_UART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 6) /*!< UART RX receiver overrun. */
};
/*! @brief FlexIO UART bit count per char. */
typedef enum _flexio_uart_bit_count_per_char
{
kFLEXIO_UART_7BitsPerChar = 7U, /*!< 7-bit data characters */
kFLEXIO_UART_8BitsPerChar = 8U, /*!< 8-bit data characters */
kFLEXIO_UART_9BitsPerChar = 9U, /*!< 9-bit data characters */
} flexio_uart_bit_count_per_char_t;
/*! @brief Define FlexIO UART interrupt mask. */
enum _flexio_uart_interrupt_enable
{
kFLEXIO_UART_TxDataRegEmptyInterruptEnable = 0x1U, /*!< Transmit buffer empty interrupt enable. */
kFLEXIO_UART_RxDataRegFullInterruptEnable = 0x2U, /*!< Receive buffer full interrupt enable. */
};
/*! @brief Define FlexIO UART status mask. */
enum _flexio_uart_status_flags
{
kFLEXIO_UART_TxDataRegEmptyFlag = 0x1U, /*!< Transmit buffer empty flag. */
kFLEXIO_UART_RxDataRegFullFlag = 0x2U, /*!< Receive buffer full flag. */
kFLEXIO_UART_RxOverRunFlag = 0x4U, /*!< Receive buffer over run flag. */
};
/*! @brief Define FlexIO UART access structure typedef. */
typedef struct _flexio_uart_type
{
FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */
uint8_t TxPinIndex; /*!< Pin select for UART_Tx. */
uint8_t RxPinIndex; /*!< Pin select for UART_Rx. */
uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO UART. */
uint8_t timerIndex[2]; /*!< Timer index used in FlexIO UART. */
} FLEXIO_UART_Type;
/*! @brief Define FlexIO UART user configuration structure. */
typedef struct _flexio_uart_config
{
bool enableUart; /*!< Enable/disable FlexIO UART TX & RX. */
bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode*/
bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode*/
bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers,
fast access requires the FlexIO clock to be at least
twice the frequency of the bus clock. */
uint32_t baudRate_Bps; /*!< Baud rate in Bps. */
flexio_uart_bit_count_per_char_t bitCountPerChar; /*!< number of bits, 7/8/9 -bit */
} flexio_uart_config_t;
/*! @brief Define FlexIO UART transfer structure. */
typedef struct _flexio_uart_transfer
{
uint8_t *data; /*!< Transfer buffer*/
size_t dataSize; /*!< Transfer size*/
} flexio_uart_transfer_t;
/* Forward declaration of the handle typedef. */
typedef struct _flexio_uart_handle flexio_uart_handle_t;
/*! @brief FlexIO UART transfer callback function. */
typedef void (*flexio_uart_transfer_callback_t)(FLEXIO_UART_Type *base,
flexio_uart_handle_t *handle,
status_t status,
void *userData);
/*! @brief Define FLEXIO UART handle structure*/
struct _flexio_uart_handle
{
uint8_t *volatile txData; /*!< Address of remaining data to send. */
volatile size_t txDataSize; /*!< Size of the remaining data to send. */
uint8_t *volatile rxData; /*!< Address of remaining data to receive. */
volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */
size_t txSize; /*!< Total bytes to be sent. */
size_t rxSize; /*!< Total bytes to be received. */
uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */
size_t rxRingBufferSize; /*!< Size of the ring buffer. */
volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */
volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */
flexio_uart_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< UART callback function parameter.*/
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus*/
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Ungates the FlexIO clock, resets the FlexIO module, configures FlexIO UART
* hardware, and configures the FlexIO UART with FlexIO UART configuration.
* The configuration structure can be filled by the user, or be set with
* default values by FLEXIO_UART_GetDefaultConfig().
*
* Example
@code
FLEXIO_UART_Type base = {
.flexioBase = FLEXIO,
.TxPinIndex = 0,
.RxPinIndex = 1,
.shifterIndex = {0,1},
.timerIndex = {0,1}
};
flexio_uart_config_t config = {
.enableInDoze = false,
.enableInDebug = true,
.enableFastAccess = false,
.baudRate_Bps = 115200U,
.bitCountPerChar = 8
};
FLEXIO_UART_Init(base, &config, srcClock_Hz);
@endcode
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param userConfig Pointer to the flexio_uart_config_t structure.
* @param srcClock_Hz FlexIO source clock in Hz.
*/
void FLEXIO_UART_Init(FLEXIO_UART_Type *base, const flexio_uart_config_t *userConfig, uint32_t srcClock_Hz);
/*!
* @brief Disables the FlexIO UART and gates the FlexIO clock.
*
* @note After calling this API, call the FLEXO_UART_Init to use the FlexIO UART module.
*
* @param base pointer to FLEXIO_UART_Type structure
*/
void FLEXIO_UART_Deinit(FLEXIO_UART_Type *base);
/*!
* @brief Gets the default configuration to configure the FlexIO UART. The configuration
* can be used directly for calling the FLEXIO_UART_Init().
* Example:
@code
flexio_uart_config_t config;
FLEXIO_UART_GetDefaultConfig(&userConfig);
@endcode
* @param userConfig Pointer to the flexio_uart_config_t structure.
*/
void FLEXIO_UART_GetDefaultConfig(flexio_uart_config_t *userConfig);
/* @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Gets the FlexIO UART status flags.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @return FlexIO UART status flags.
*/
uint32_t FLEXIO_UART_GetStatusFlags(FLEXIO_UART_Type *base);
/*!
* @brief Gets the FlexIO UART status flags.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param mask Status flag.
* The parameter can be any combination of the following values:
* @arg kFLEXIO_UART_TxDataRegEmptyFlag
* @arg kFLEXIO_UART_RxEmptyFlag
* @arg kFLEXIO_UART_RxOverRunFlag
*/
void FLEXIO_UART_ClearStatusFlags(FLEXIO_UART_Type *base, uint32_t mask);
/* @} */
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables the FlexIO UART interrupt.
*
* This function enables the FlexIO UART interrupt.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param mask Interrupt source.
*/
void FLEXIO_UART_EnableInterrupts(FLEXIO_UART_Type *base, uint32_t mask);
/*!
* @brief Disables the FlexIO UART interrupt.
*
* This function disables the FlexIO UART interrupt.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param mask Interrupt source.
*/
void FLEXIO_UART_DisableInterrupts(FLEXIO_UART_Type *base, uint32_t mask);
/* @} */
/*!
* @name DMA Control
* @{
*/
/*!
* @brief Gets the FlexIO UARt transmit data register address.
*
* This function returns the UART data register address, which is mainly used by DMA/eDMA.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @return FlexIO UART transmit data register address.
*/
static inline uint32_t FLEXIO_UART_GetTxDataRegisterAddress(FLEXIO_UART_Type *base)
{
return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBuffer, base->shifterIndex[0]);
}
/*!
* @brief Gets the FlexIO UART receive data register address.
*
* This function returns the UART data register address, which is mainly used by DMA/eDMA.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @return FlexIO UART receive data register address.
*/
static inline uint32_t FLEXIO_UART_GetRxDataRegisterAddress(FLEXIO_UART_Type *base)
{
return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferByteSwapped, base->shifterIndex[1]);
}
/*!
* @brief Enables/disables the FlexIO UART transmit DMA.
* This function enables/disables the FlexIO UART Tx DMA,
* which means asserting the kFLEXIO_UART_TxDataRegEmptyFlag does/doesn't trigger the DMA request.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param enable True to enable, false to disable.
*/
static inline void FLEXIO_UART_EnableTxDMA(FLEXIO_UART_Type *base, bool enable)
{
FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->shifterIndex[0], enable);
}
/*!
* @brief Enables/disables the FlexIO UART receive DMA.
* This function enables/disables the FlexIO UART Rx DMA,
* which means asserting kFLEXIO_UART_RxDataRegFullFlag does/doesn't trigger the DMA request.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param enable True to enable, false to disable.
*/
static inline void FLEXIO_UART_EnableRxDMA(FLEXIO_UART_Type *base, bool enable)
{
FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->shifterIndex[1], enable);
}
/* @} */
/*!
* @name Bus Operations
* @{
*/
/*!
* @brief Enables/disables the FlexIO UART module operation.
*
* @param base Pointer to the FLEXIO_UART_Type.
* @param enable True to enable, false to disable.
*/
static inline void FLEXIO_UART_Enable(FLEXIO_UART_Type *base, bool enable)
{
if (enable)
{
base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
}
else
{
base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK;
}
}
/*!
* @brief Writes one byte of data.
*
* @note This is a non-blocking API, which returns directly after the data is put into the
* data register. Ensure that the TxEmptyFlag is asserted before calling
* this API.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param buffer The data bytes to send.
*/
static inline void FLEXIO_UART_WriteByte(FLEXIO_UART_Type *base, const uint8_t *buffer)
{
base->flexioBase->SHIFTBUF[base->shifterIndex[0]] = *buffer;
}
/*!
* @brief Reads one byte of data.
*
* @note This is a non-blocking API, which returns directly after the data is read from the
* data register. Ensure that the RxFullFlag is asserted before calling this API.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param buffer The buffer to store the received bytes.
*/
static inline void FLEXIO_UART_ReadByte(FLEXIO_UART_Type *base, uint8_t *buffer)
{
*buffer = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]];
}
/*!
* @brief Sends a buffer of data bytes.
*
* @note This function blocks using the polling method until all bytes have been sent.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param txData The data bytes to send.
* @param txSize The number of data bytes to send.
*/
void FLEXIO_UART_WriteBlocking(FLEXIO_UART_Type *base, const uint8_t *txData, size_t txSize);
/*!
* @brief Receives a buffer of bytes.
*
* @note This function blocks using the polling method until all bytes have been received.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param rxData The buffer to store the received bytes.
* @param rxSize The number of data bytes to be received.
*/
void FLEXIO_UART_ReadBlocking(FLEXIO_UART_Type *base, uint8_t *rxData, size_t rxSize);
/* @} */
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the UART handle.
*
* This function initializes the FlexIO UART handle, which can be used for other FlexIO
* UART transactional APIs. Call this API once to get the
* initialized handle.
*
* The UART driver supports the "background" receiving, which means that user can set up
* a RX ring buffer optionally. Data received is stored into the ring buffer even when
* the user doesn't call the FLEXIO_UART_TransferReceiveNonBlocking() API. If there is already data
* received in the ring buffer, user can get the received data from the ring buffer
* directly. The ring buffer is disabled if passing NULL as @p ringBuffer.
*
* @param base to FLEXIO_UART_Type structure.
* @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state.
* @param callback The callback function.
* @param userData The parameter of the callback function.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
*/
status_t FLEXIO_UART_TransferCreateHandle(FLEXIO_UART_Type *base,
flexio_uart_handle_t *handle,
flexio_uart_transfer_callback_t callback,
void *userData);
/*!
* @brief Sets up the RX ring buffer.
*
* This function sets up the RX ring buffer to a specific UART handle.
*
* When the RX ring buffer is used, data received is stored into the ring buffer even when
* the user doesn't call the UART_ReceiveNonBlocking() API. If there are already data received
* in the ring buffer, user can get the received data from the ring buffer directly.
*
* @note When using the RX ring buffer, one byte is reserved for internal use. In other
* words, if @p ringBufferSize is 32, only 31 bytes are used for saving data.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state.
* @param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer.
* @param ringBufferSize Size of the ring buffer.
*/
void FLEXIO_UART_TransferStartRingBuffer(FLEXIO_UART_Type *base,
flexio_uart_handle_t *handle,
uint8_t *ringBuffer,
size_t ringBufferSize);
/*!
* @brief Aborts the background transfer and uninstalls the ring buffer.
*
* This function aborts the background transfer and uninstalls the ring buffer.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state.
*/
void FLEXIO_UART_StopRingBuffer(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle);
/*!
* @brief Transmits a buffer of data using the interrupt method.
*
* This function sends data using an interrupt method. This is a non-blocking function,
* which returns directly without waiting for all data to be written to the TX register. When
* all data are written to TX register in ISR, the FlexIO UART driver calls the callback
* function and passes the @ref kStatus_FLEXIO_UART_TxIdle as status parameter.
*
* @note The kStatus_FLEXIO_UART_TxIdle is passed to the upper layer when all data is written
* to the TX register. However, it does not ensure that all data is sent out.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state.
* @param xfer FlexIO UART transfer structure. See #flexio_uart_transfer_t.
* @retval kStatus_Success Successfully starts the data transmission.
* @retval kStatus_UART_TxBusy Previous transmission still not finished, data not written to the TX register.
*/
status_t FLEXIO_UART_TransferSendNonBlocking(FLEXIO_UART_Type *base,
flexio_uart_handle_t *handle,
flexio_uart_transfer_t *xfer);
/*!
* @brief Aborts the interrupt-driven data transmit.
*
* This function aborts the interrupt-driven data sending. Get the remainBytes to know
* how many bytes are still not sent out.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state.
*/
void FLEXIO_UART_TransferAbortSend(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle);
/*!
* @brief Gets the number of remaining bytes not sent.
*
* This function gets the number of remaining bytes not sent driven by interrupt.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state.
* @param count Number of bytes sent so far by the non-blocking transaction.
* @retval kStatus_InvalidArgument count is Invalid.
* @retval kStatus_Success Successfully return the count.
*/
status_t FLEXIO_UART_TransferGetSendCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count);
/*!
* @brief Receives a buffer of data using the interrupt method.
*
* This function receives data using the interrupt method. This is a non-blocking function,
* which returns without waiting for all data to be received.
* If the RX ring buffer is used and not empty, the data in ring buffer is copied and
* the parameter @p receivedBytes shows how many bytes are copied from the ring buffer.
* After copying, if the data in ring buffer is not enough to read, the receive
* request is saved by the UART driver. When new data arrives, the receive request
* is serviced first. When all data is received, the UART driver notifies the upper layer
* through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
* For example, if the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer,
* the 5 bytes are copied to xfer->data. This function returns with the
* parameter @p receivedBytes set to 5. For the last 5 bytes, newly arrived data is
* saved from the xfer->data[5]. When 5 bytes are received, the UART driver notifies upper layer.
* If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
* to receive data to xfer->data. When all data is received, the upper layer is notified.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state.
* @param xfer UART transfer structure. See #flexio_uart_transfer_t.
* @param receivedBytes Bytes received from the ring buffer directly.
* @retval kStatus_Success Successfully queue the transfer into the transmit queue.
* @retval kStatus_FLEXIO_UART_RxBusy Previous receive request is not finished.
*/
status_t FLEXIO_UART_TransferReceiveNonBlocking(FLEXIO_UART_Type *base,
flexio_uart_handle_t *handle,
flexio_uart_transfer_t *xfer,
size_t *receivedBytes);
/*!
* @brief Aborts the receive data which was using IRQ.
*
* This function aborts the receive data which was using IRQ.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state.
*/
void FLEXIO_UART_TransferAbortReceive(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle);
/*!
* @brief Gets the number of remaining bytes not received.
*
* This function gets the number of remaining bytes not received driven by interrupt.
*
* @param base Pointer to the FLEXIO_UART_Type structure.
* @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state.
* @param count Number of bytes received so far by the non-blocking transaction.
* @retval kStatus_InvalidArgument count is Invalid.
* @retval kStatus_Success Successfully return the count.
*/
status_t FLEXIO_UART_TransferGetReceiveCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count);
/*!
* @brief FlexIO UART IRQ handler function.
*
* This function processes the FlexIO UART transmit and receives the IRQ request.
*
* @param uartType Pointer to the FLEXIO_UART_Type structure.
* @param uartHandle Pointer to the flexio_uart_handle_t structure to store the transfer state.
*/
void FLEXIO_UART_TransferHandleIRQ(void *uartType, void *uartHandle);
/*@}*/
#if defined(__cplusplus)
}
#endif /*_cplusplus*/
/*@}*/
#endif /*_FSL_FLEXIO_UART_H_*/

View File

@ -1,358 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_flexio_uart_dma.h"
#include "fsl_dmamux.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*<! @brief Structure definition for DMA callback param pass in. */
typedef struct _flexio_uart_dma_private_handle
{
FLEXIO_UART_Type *base;
flexio_uart_dma_handle_t *handle;
} flexio_uart_dma_private_handle_t;
/*<! @brief uart transfer state. */
enum _flexio_uart_dma_transfer_states
{
kFLEXIO_UART_TxIdle, /* TX idle. */
kFLEXIO_UART_TxBusy, /* TX busy. */
kFLEXIO_UART_RxIdle, /* RX idle. */
kFLEXIO_UART_RxBusy /* RX busy. */
};
/*******************************************************************************
* Variables
******************************************************************************/
/*< @brief user configurable flexio uart handle count. */
#define FLEXIO_UART_HANDLE_COUNT 2
/*<! Private handle only used for internally. */
static flexio_uart_dma_private_handle_t s_dmaPrivateHandle[FLEXIO_UART_HANDLE_COUNT];
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief FLEXIO UART DMA send finished callback function.
*
* This function is called when FLEXIO UART DMA send finished. It disables the UART
* TX DMA request and sends @ref kStatus_FLEXIO_UART_TxIdle to FLEXIO UART callback.
*
* @param handle The DMA handle.
* @param param Callback function parameter.
*/
static void FLEXIO_UART_TransferSendDMACallback(dma_handle_t *handle, void *param);
/*!
* @brief FLEXIO UART DMA receive finished callback function.
*
* This function is called when FLEXIO UART DMA receive finished. It disables the FLEXIO
* UART RX DMA request and sends @ref kStatus_FLEXIO_UART_RxIdle to UART callback.
*
* @param handle The DMA handle.
* @param param Callback function parameter.
*/
static void FLEXIO_UART_TransferReceiveDMACallback(dma_handle_t *handle, void *param);
/*******************************************************************************
* Code
******************************************************************************/
static void FLEXIO_UART_TransferSendDMACallback(dma_handle_t *handle, void *param)
{
flexio_uart_dma_private_handle_t *uartPrivateHandle = (flexio_uart_dma_private_handle_t *)param;
/* Disable UART TX DMA. */
FLEXIO_UART_EnableTxDMA(uartPrivateHandle->base, false);
/* Disable interrupt. */
DMA_DisableInterrupts(handle->base, handle->channel);
uartPrivateHandle->handle->txState = kFLEXIO_UART_TxIdle;
if (uartPrivateHandle->handle->callback)
{
uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle,
kStatus_FLEXIO_UART_TxIdle, uartPrivateHandle->handle->userData);
}
}
static void FLEXIO_UART_TransferReceiveDMACallback(dma_handle_t *handle, void *param)
{
flexio_uart_dma_private_handle_t *uartPrivateHandle = (flexio_uart_dma_private_handle_t *)param;
/* Disable UART RX DMA. */
FLEXIO_UART_EnableRxDMA(uartPrivateHandle->base, false);
/* Disable interrupt. */
DMA_DisableInterrupts(handle->base, handle->channel);
uartPrivateHandle->handle->rxState = kFLEXIO_UART_RxIdle;
if (uartPrivateHandle->handle->callback)
{
uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle,
kStatus_FLEXIO_UART_RxIdle, uartPrivateHandle->handle->userData);
}
}
status_t FLEXIO_UART_TransferCreateHandleDMA(FLEXIO_UART_Type *base,
flexio_uart_dma_handle_t *handle,
flexio_uart_dma_transfer_callback_t callback,
void *userData,
dma_handle_t *txDmaHandle,
dma_handle_t *rxDmaHandle)
{
assert(handle);
dma_transfer_config_t dmaXferConfig;
uint8_t index = 0;
/* Find the an empty handle pointer to store the handle. */
for (index = 0; index < FLEXIO_UART_HANDLE_COUNT; index++)
{
if (s_dmaPrivateHandle[index].base == NULL)
{
s_dmaPrivateHandle[index].base = base;
s_dmaPrivateHandle[index].handle = handle;
break;
}
}
if (index == FLEXIO_UART_HANDLE_COUNT)
{
return kStatus_OutOfRange;
}
memset(handle, 0, sizeof(*handle));
handle->rxState = kFLEXIO_UART_RxIdle;
handle->txState = kFLEXIO_UART_TxIdle;
handle->callback = callback;
handle->userData = userData;
handle->rxDmaHandle = rxDmaHandle;
handle->txDmaHandle = txDmaHandle;
/* Set DMA channel configuration. */
memset(&dmaXferConfig, 0, sizeof(dmaXferConfig));
dmaXferConfig.srcSize = kDMA_Transfersize8bits;
dmaXferConfig.destSize = kDMA_Transfersize8bits;
/* Configure TX. */
if (txDmaHandle)
{
DMA_SetCallback(txDmaHandle, FLEXIO_UART_TransferSendDMACallback, &s_dmaPrivateHandle[index]);
DMA_ResetChannel(txDmaHandle->base, txDmaHandle->channel);
dmaXferConfig.destAddr = FLEXIO_UART_GetTxDataRegisterAddress(base);
dmaXferConfig.enableSrcIncrement = true;
dmaXferConfig.enableDestIncrement = false;
DMA_SetTransferConfig(txDmaHandle->base, txDmaHandle->channel, &dmaXferConfig);
}
/* Configure RX. */
if (rxDmaHandle)
{
DMA_SetCallback(rxDmaHandle, FLEXIO_UART_TransferReceiveDMACallback, &s_dmaPrivateHandle[index]);
DMA_ResetChannel(rxDmaHandle->base, rxDmaHandle->channel);
dmaXferConfig.destAddr = 0U;
dmaXferConfig.srcAddr = FLEXIO_UART_GetRxDataRegisterAddress(base);
dmaXferConfig.enableSrcIncrement = false;
dmaXferConfig.enableDestIncrement = true;
DMA_SetTransferConfig(rxDmaHandle->base, rxDmaHandle->channel, &dmaXferConfig);
}
return kStatus_Success;
}
status_t FLEXIO_UART_TransferSendDMA(FLEXIO_UART_Type *base,
flexio_uart_dma_handle_t *handle,
flexio_uart_transfer_t *xfer)
{
assert(handle->txDmaHandle);
status_t status;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* If previous TX not finished. */
if (kFLEXIO_UART_TxBusy == handle->txState)
{
status = kStatus_FLEXIO_UART_TxBusy;
}
else
{
handle->txState = kFLEXIO_UART_TxBusy;
/* Set transfer data address and data size. */
DMA_SetSourceAddress(handle->txDmaHandle->base, handle->txDmaHandle->channel, (uint32_t)xfer->data);
DMA_SetTransferSize(handle->txDmaHandle->base, handle->txDmaHandle->channel, xfer->dataSize);
/* Enable FLEXIO UART TX DMA. */
FLEXIO_UART_EnableTxDMA(base, true);
/* Enable DMA transfer complete interrupt and start transfer. */
DMA_EnableInterrupts(handle->txDmaHandle->base, handle->txDmaHandle->channel);
DMA_EnableChannelRequest(handle->txDmaHandle->base, handle->txDmaHandle->channel);
status = kStatus_Success;
}
return status;
}
status_t FLEXIO_UART_TransferReceiveDMA(FLEXIO_UART_Type *base,
flexio_uart_dma_handle_t *handle,
flexio_uart_transfer_t *xfer)
{
assert(handle->rxDmaHandle);
status_t status;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* If previous RX not finished. */
if (kFLEXIO_UART_RxBusy == handle->rxState)
{
status = kStatus_FLEXIO_UART_RxBusy;
}
else
{
handle->rxState = kFLEXIO_UART_RxBusy;
/* Set transfer data address and data size. */
DMA_SetDestinationAddress(handle->rxDmaHandle->base, handle->rxDmaHandle->channel, (uint32_t)xfer->data);
DMA_SetTransferSize(handle->rxDmaHandle->base, handle->rxDmaHandle->channel, xfer->dataSize);
/* Enable FLEXIO UART RX DMA. */
FLEXIO_UART_EnableRxDMA(base, true);
/* Enable DMA transfer complete interrupt and start transfer. */
DMA_EnableInterrupts(handle->rxDmaHandle->base, handle->rxDmaHandle->channel);
DMA_EnableChannelRequest(handle->rxDmaHandle->base, handle->rxDmaHandle->channel);
status = kStatus_Success;
}
return status;
}
void FLEXIO_UART_TransferAbortSendDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle)
{
assert(handle->txDmaHandle);
/* Disable FLEXIO UART TX DMA. */
FLEXIO_UART_EnableTxDMA(base, false);
/* Stop transfer. */
DMA_StopTransfer(handle->txDmaHandle);
/* Write DMA->DSR[DONE] to abort transfer and clear status. */
DMA_ClearChannelStatusFlags(handle->txDmaHandle->base, handle->txDmaHandle->channel, kDMA_TransactionsDoneFlag);
handle->txState = kFLEXIO_UART_TxIdle;
}
void FLEXIO_UART_TransferAbortReceiveDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle)
{
assert(handle->rxDmaHandle);
/* Disable FLEXIO UART RX DMA. */
FLEXIO_UART_EnableRxDMA(base, false);
/* Stop transfer. */
DMA_StopTransfer(handle->rxDmaHandle);
/* Write DMA->DSR[DONE] to abort transfer and clear status. */
DMA_ClearChannelStatusFlags(handle->rxDmaHandle->base, handle->rxDmaHandle->channel, kDMA_TransactionsDoneFlag);
handle->rxState = kFLEXIO_UART_RxIdle;
}
status_t FLEXIO_UART_TransferGetSendCountDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle, size_t *count)
{
assert(handle->txDmaHandle);
if (!count)
{
return kStatus_InvalidArgument;
}
if (kFLEXIO_UART_TxBusy == handle->txState)
{
*count = (handle->txSize - DMA_GetRemainingBytes(handle->txDmaHandle->base, handle->txDmaHandle->channel));
}
else
{
*count = handle->txSize;
}
return kStatus_Success;
}
status_t FLEXIO_UART_TransferGetReceiveCountDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle, size_t *count)
{
assert(handle->rxDmaHandle);
if (!count)
{
return kStatus_InvalidArgument;
}
if (kFLEXIO_UART_RxBusy == handle->rxState)
{
*count = (handle->rxSize - DMA_GetRemainingBytes(handle->rxDmaHandle->base, handle->rxDmaHandle->channel));
}
else
{
*count = handle->rxSize;
}
return kStatus_Success;
}

View File

@ -1,191 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_FLEXIO_UART_DMA_H_
#define _FSL_FLEXIO_UART_DMA_H_
#include "fsl_flexio_uart.h"
#include "fsl_dmamux.h"
#include "fsl_dma.h"
/*!
* @addtogroup flexio_dma_uart
* @{
*/
/*! @file*/
/*******************************************************************************
* Definitions
******************************************************************************/
/* Forward declaration of the handle typedef. */
typedef struct _flexio_uart_dma_handle flexio_uart_dma_handle_t;
/*! @brief UART transfer callback function. */
typedef void (*flexio_uart_dma_transfer_callback_t)(FLEXIO_UART_Type *base,
flexio_uart_dma_handle_t *handle,
status_t status,
void *userData);
/*!
* @brief UART DMA handle
*/
struct _flexio_uart_dma_handle
{
flexio_uart_dma_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< UART callback function parameter.*/
size_t txSize; /*!< Total bytes to be sent. */
size_t rxSize; /*!< Total bytes to be received. */
dma_handle_t *txDmaHandle; /*!< The DMA TX channel used. */
dma_handle_t *rxDmaHandle; /*!< The DMA RX channel used. */
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name eDMA transactional
* @{
*/
/*!
* @brief Initializes the FLEXIO_UART handle which is used in transactional functions
*
* @param base Pointer to FLEXIO_UART_Type structure.
* @param handle Pointer to flexio_uart_dma_handle_t structure.
* @param callback FlexIO UART callback, NULL means no callback.
* @param userData User callback function data.
* @param txDmaHandle User requested DMA handle for TX DMA transfer.
* @param rxDmaHandle User requested DMA handle for RX DMA transfer.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO UART DMA type/handle table out of range.
*/
status_t FLEXIO_UART_TransferCreateHandleDMA(FLEXIO_UART_Type *base,
flexio_uart_dma_handle_t *handle,
flexio_uart_dma_transfer_callback_t callback,
void *userData,
dma_handle_t *txDmaHandle,
dma_handle_t *rxDmaHandle);
/*!
* @brief Sends data using DMA.
*
* This function send data using DMA, this is non-blocking function, which return
* right away. When all data have been sent out, the send callback function is called.
*
* @param base Pointer to FLEXIO_UART_Type structure
* @param handle Pointer to flexio_uart_dma_handle_t structure
* @param xfer FLEXIO_UART DMA transfer structure, refer to #flexio_uart_transfer_t.
* @retval kStatus_Success if succeed, others failed.
* @retval kStatus_FLEXIO_UART_TxBusy Previous transfer on going.
*/
status_t FLEXIO_UART_TransferSendDMA(FLEXIO_UART_Type *base,
flexio_uart_dma_handle_t *handle,
flexio_uart_transfer_t *xfer);
/*!
* @brief Receives data using DMA.
*
* This function receives data using DMA. This is non-blocking function, which returns
* right away. When all data have been received, the receive callback function is called.
*
* @param base Pointer to FLEXIO_UART_Type structure
* @param handle Pointer to flexio_uart_dma_handle_t structure
* @param xfer FLEXIO_UART DMA transfer sturcture, refer to #flexio_uart_transfer_t.
* @retval kStatus_Success if succeed, others failed.
* @retval kStatus_FLEXIO_UART_RxBusy Previous transfer on going.
*/
status_t FLEXIO_UART_TransferReceiveDMA(FLEXIO_UART_Type *base,
flexio_uart_dma_handle_t *handle,
flexio_uart_transfer_t *xfer);
/*!
* @brief Aborts the sent data which using DMA.
*
* This function aborts the sent data which using DMA.
*
* @param base Pointer to FLEXIO_UART_Type structure
* @param handle Pointer to flexio_uart_dma_handle_t structure
*/
void FLEXIO_UART_TransferAbortSendDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle);
/*!
* @brief Aborts the receive data which using DMA.
*
* This function aborts the receive data which using DMA.
*
* @param base Pointer to FLEXIO_UART_Type structure
* @param handle Pointer to flexio_uart_dma_handle_t structure
*/
void FLEXIO_UART_TransferAbortReceiveDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle);
/*!
* @brief Gets the number of bytes still not sent out.
*
* This function gets the number of bytes still not sent out.
*
* @param base Pointer to FLEXIO_UART_Type structure
* @param handle Pointer to flexio_uart_dma_handle_t structure
* @param count Number of bytes sent so far by the non-blocking transaction.
*/
status_t FLEXIO_UART_TransferGetSendCountDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle, size_t *count);
/*!
* @brief Gets the number of bytes still not received.
*
* This function gets the number of bytes still not received.
*
* @param base Pointer to FLEXIO_UART_Type structure
* @param handle Pointer to flexio_uart_dma_handle_t structure
* @param count Number of bytes received so far by the non-blocking transaction.
*/
status_t FLEXIO_UART_TransferGetReceiveCountDMA(FLEXIO_UART_Type *base,
flexio_uart_dma_handle_t *handle,
size_t *count);
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_UART_DMA_H_ */

View File

@ -1,179 +0,0 @@
/*
* 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

@ -1,390 +0,0 @@
/*
* 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_*/

View File

@ -1,781 +0,0 @@
/*
* 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

@ -1,523 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_i2c_dma.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*<! @brief Structure definition for i2c_master_dma_handle_t. The structure is private. */
typedef struct _i2c_master_dma_private_handle
{
I2C_Type *base;
i2c_master_dma_handle_t *handle;
} i2c_master_dma_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 DMA callback for I2C master DMA driver.
*
* @param handle DMA handler for I2C master DMA driver
* @param userData user param passed to the callback function
*/
static void I2C_MasterTransferCallbackDMA(dma_handle_t *handle, void *userData);
/*!
* @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 DMA config for I2C master driver.
*
* @param base I2C peripheral base address.
* @param handle pointer to i2c_master_dma_handle_t structure which stores the transfer state.
*/
static void I2C_MasterTransferDMAConfig(I2C_Type *base, i2c_master_dma_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_dma_handle_t structure which stores the transfer state.
* @param xfer pointer to i2c_master_transfer_t structure.
*/
static status_t I2C_InitTransferStateMachineDMA(I2C_Type *base,
i2c_master_dma_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_dma_private_handle_t s_dmaPrivateHandle[FSL_FEATURE_SOC_I2C_COUNT];
/*******************************************************************************
* Codes
******************************************************************************/
static void I2C_MasterTransferCallbackDMA(dma_handle_t *handle, void *userData)
{
i2c_master_dma_private_handle_t *i2cPrivateHandle = (i2c_master_dma_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_InitTransferStateMachineDMA(I2C_Type *base,
i2c_master_dma_handle_t *handle,
i2c_master_transfer_t *xfer)
{
assert(handle);
assert(xfer);
/* Set up transfer first. */
i2c_direction_t direction = xfer->direction;
status_t result = kStatus_Success;
uint16_t timeout = UINT16_MAX;
if (handle->state != kIdleState)
{
return kStatus_I2C_Busy;
}
else
{
/* Init the handle member. */
handle->transfer = *xfer;
/* Save total transfer size. */
handle->transferSize = xfer->dataSize;
handle->state = kTransferDataState;
/* Wait until ready to complete. */
while ((!(base->S & kI2C_TransferCompleteFlag)) && (--timeout))
{
}
/* Failed to start the transfer. */
if (timeout == 0)
{
return kStatus_I2C_Timeout;
}
/* Clear all status before transfer. */
I2C_MasterClearStatusFlags(base, kClearFlags);
/* Change to send write address when it's a read operation with command. */
if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read))
{
direction = kI2C_Write;
}
/* If repeated start is requested, send repeated start. */
if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag)
{
result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction);
}
else /* For normal transfer, send start. */
{
result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction);
}
/* Send subaddress. */
if (handle->transfer.subaddressSize)
{
do
{
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
/* Clear interrupt pending flag. */
base->S = kI2C_IntPendingFlag;
handle->transfer.subaddressSize--;
base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize));
/* Check if there's transfer error. */
result = I2C_CheckAndClearError(base, base->S);
if (result)
{
return result;
}
} while ((handle->transfer.subaddressSize > 0) && (result == kStatus_Success));
if (handle->transfer.direction == kI2C_Read)
{
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
/* Clear pending flag. */
base->S = kI2C_IntPendingFlag;
/* Send repeated start and slave address. */
result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read);
}
}
if (result)
{
return result;
}
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
/* Clear pending flag. */
base->S = kI2C_IntPendingFlag;
/* Check if there's transfer error. */
result = I2C_CheckAndClearError(base, base->S);
}
return result;
}
static void I2C_MasterTransferDMAConfig(I2C_Type *base, i2c_master_dma_handle_t *handle)
{
dma_transfer_config_t transfer_config;
dma_transfer_options_t transfer_options = kDMA_EnableInterrupt;
if (handle->transfer.direction == kI2C_Read)
{
transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base);
transfer_config.destAddr = (uint32_t)(handle->transfer.data);
/* Send stop if kI2C_TransferNoStop flag is not asserted. */
if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
{
transfer_config.transferSize = (handle->transfer.dataSize - 1);
}
else
{
transfer_config.transferSize = handle->transfer.dataSize;
}
transfer_config.srcSize = kDMA_Transfersize8bits;
transfer_config.enableSrcIncrement = false;
transfer_config.destSize = kDMA_Transfersize8bits;
transfer_config.enableDestIncrement = true;
}
else
{
transfer_config.srcAddr = (uint32_t)(handle->transfer.data + 1);
transfer_config.destAddr = (uint32_t)I2C_GetDataRegAddr(base);
transfer_config.transferSize = (handle->transfer.dataSize - 1);
transfer_config.srcSize = kDMA_Transfersize8bits;
transfer_config.enableSrcIncrement = true;
transfer_config.destSize = kDMA_Transfersize8bits;
transfer_config.enableDestIncrement = false;
}
DMA_SubmitTransfer(handle->dmaHandle, &transfer_config, transfer_options);
DMA_StartTransfer(handle->dmaHandle);
}
void I2C_MasterTransferCreateHandleDMA(I2C_Type *base,
i2c_master_dma_handle_t *handle,
i2c_master_dma_transfer_callback_t callback,
void *userData,
dma_handle_t *dmaHandle)
{
assert(handle);
assert(dmaHandle);
uint32_t instance = I2C_GetInstance(base);
/* Zero handle. */
memset(handle, 0, sizeof(*handle));
/* Set the user callback and userData. */
handle->completionCallback = callback;
handle->userData = userData;
/* Set the handle for DMA. */
handle->dmaHandle = dmaHandle;
s_dmaPrivateHandle[instance].base = base;
s_dmaPrivateHandle[instance].handle = handle;
DMA_SetCallback(dmaHandle, (dma_callback)I2C_MasterTransferCallbackDMA, &s_dmaPrivateHandle[instance]);
}
status_t I2C_MasterTransferDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, i2c_master_transfer_t *xfer)
{
assert(handle);
assert(xfer);
status_t result;
uint8_t tmpReg;
volatile uint8_t dummy = 0;
/* Add this to avoid build warning. */
dummy++;
/* Disable dma transfer. */
I2C_EnableDMA(base, false);
/* Send address and command buffer(if there is), until senddata phase or receive data phase. */
result = I2C_InitTransferStateMachineDMA(base, handle, xfer);
if (result != kStatus_Success)
{
/* Send stop if received Nak. */
if (result == kStatus_I2C_Nak)
{
if (I2C_MasterStop(base) != kStatus_Success)
{
result = kStatus_I2C_Timeout;
}
}
/* Reset the state to idle state. */
handle->state = kIdleState;
return result;
}
/* Configure dma transfer. */
/* For i2c send, need to send 1 byte first to trigger the dma, for i2c read,
need to send stop before reading the last byte, so the dma transfer size should
be (xSize - 1). */
if (handle->transfer.dataSize > 1)
{
I2C_MasterTransferDMAConfig(base, handle);
if (handle->transfer.direction == kI2C_Read)
{
/* Change direction for receive. */
base->C1 &= ~I2C_C1_TX_MASK;
/* Read dummy to release the bus. */
dummy = base->D;
/* Enabe dma transfer. */
I2C_EnableDMA(base, true);
}
else
{
/* Enabe dma transfer. */
I2C_EnableDMA(base, true);
/* Send the first data. */
base->D = *handle->transfer.data;
}
}
else /* If transfer size is 1, use polling method. */
{
if (handle->transfer.direction == kI2C_Read)
{
tmpReg = base->C1;
/* Change direction to Rx. */
tmpReg &= ~I2C_C1_TX_MASK;
/* Configure send NAK */
tmpReg |= I2C_C1_TXAK_MASK;
base->C1 = tmpReg;
/* Read dummy to release the bus. */
dummy = base->D;
}
else
{
base->D = *handle->transfer.data;
}
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
/* Clear pending flag. */
base->S = kI2C_IntPendingFlag;
/* Send stop if kI2C_TransferNoStop flag is not asserted. */
if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
{
result = I2C_MasterStop(base);
}
/* Read the last byte of data. */
if (handle->transfer.direction == kI2C_Read)
{
*handle->transfer.data = base->D;
}
/* Reset the state to idle. */
handle->state = kIdleState;
}
return result;
}
status_t I2C_MasterTransferGetCountDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, size_t *count)
{
assert(handle);
if (!count)
{
return kStatus_InvalidArgument;
}
if (kIdleState != handle->state)
{
*count = (handle->transferSize - DMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel));
}
else
{
*count = handle->transferSize;
}
return kStatus_Success;
}
void I2C_MasterTransferAbortDMA(I2C_Type *base, i2c_master_dma_handle_t *handle)
{
DMA_AbortTransfer(handle->dmaHandle);
/* Disable dma transfer. */
I2C_EnableDMA(base, false);
/* Reset the state to idle. */
handle->state = kIdleState;
}

View File

@ -1,132 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_I2C_DMA_H_
#define _FSL_I2C_DMA_H_
#include "fsl_i2c.h"
#include "fsl_dmamux.h"
#include "fsl_dma.h"
/*!
* @addtogroup i2c_dma_driver
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief I2C master dma handle typedef. */
typedef struct _i2c_master_dma_handle i2c_master_dma_handle_t;
/*! @brief I2C master dma transfer callback typedef. */
typedef void (*i2c_master_dma_transfer_callback_t)(I2C_Type *base,
i2c_master_dma_handle_t *handle,
status_t status,
void *userData);
/*! @brief I2C master dma transfer structure. */
struct _i2c_master_dma_handle
{
i2c_master_transfer_t transfer; /*!< I2C master transfer struct. */
size_t transferSize; /*!< Total bytes to be transferred. */
uint8_t state; /*!< I2C master transfer status. */
dma_handle_t *dmaHandle; /*!< The DMA handler used. */
i2c_master_dma_transfer_callback_t completionCallback; /*!< Callback function called after dma transfer finished. */
void *userData; /*!< Callback parameter passed to callback function. */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus. */
/*!
* @name I2C Block DMA Transfer Operation
* @{
*/
/*!
* @brief Init the I2C handle which is used in transcational functions
*
* @param base I2C peripheral base address
* @param handle pointer to i2c_master_dma_handle_t structure
* @param callback pointer to user callback function
* @param userData user param passed to the callback function
* @param dmaHandle DMA handle pointer
*/
void I2C_MasterTransferCreateHandleDMA(I2C_Type *base,
i2c_master_dma_handle_t *handle,
i2c_master_dma_transfer_callback_t callback,
void *userData,
dma_handle_t *dmaHandle);
/*!
* @brief Performs a master dma non-blocking transfer on the I2C bus
*
* @param base I2C peripheral base address
* @param handle pointer to i2c_master_dma_handle_t structure
* @param xfer pointer to transfer structure of i2c_master_transfer_t
* @retval kStatus_Success Sucessully complete the data transmission.
* @retval kStatus_I2C_Busy Previous transmission still not finished.
* @retval kStatus_I2C_Timeout Transfer error, wait signal timeout.
* @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
* @retval kStataus_I2C_Nak Transfer error, receive Nak during transfer.
*/
status_t I2C_MasterTransferDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, i2c_master_transfer_t *xfer);
/*!
* @brief Get master transfer status during a dma non-blocking transfer
*
* @param base I2C peripheral base address
* @param handle pointer to i2c_master_dma_handle_t structure
* @param count Number of bytes transferred so far by the non-blocking transaction.
*/
status_t I2C_MasterTransferGetCountDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, size_t *count);
/*!
* @brief Abort a master dma non-blocking transfer in a early time
*
* @param base I2C peripheral base address
* @param handle pointer to i2c_master_dma_handle_t structure
*/
void I2C_MasterTransferAbortDMA(I2C_Type *base, i2c_master_dma_handle_t *handle);
/* @} */
#if defined(__cplusplus)
}
#endif /*_cplusplus. */
/*@}*/
#endif /*_FSL_I2C_DMA_H_*/

View File

@ -1,404 +0,0 @@
/*
* 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

@ -1,321 +0,0 @@
/*
* 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

@ -1,117 +0,0 @@
/*
* 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

@ -1,351 +0,0 @@
/*
* 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

@ -1,753 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_LPUART_H_
#define _FSL_LPUART_H_
#include "fsl_common.h"
/*!
* @addtogroup lpuart_driver
* @{
*/
/*! @file*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief LPUART driver version 2.1.0. */
#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
/*@}*/
/*! @brief Error codes for the LPUART driver. */
enum _lpuart_status
{
kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */
kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */
kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */
kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */
kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */
kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */
kStatus_LPUART_FlagCannotClearManually =
MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */
kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */
kStatus_LPUART_RxRingBufferOverrun =
MAKE_STATUS(kStatusGroup_LPUART, 8), /*!< LPUART RX software ring buffer overrun. */
kStatus_LPUART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_LPUART, 9), /*!< LPUART RX receiver overrun. */
kStatus_LPUART_NoiseError = MAKE_STATUS(kStatusGroup_LPUART, 10), /*!< LPUART noise error. */
kStatus_LPUART_FramingError = MAKE_STATUS(kStatusGroup_LPUART, 11), /*!< LPUART framing error. */
kStatus_LPUART_ParityError = MAKE_STATUS(kStatusGroup_LPUART, 12), /*!< LPUART parity error. */
};
/*! @brief LPUART parity mode. */
typedef enum _lpuart_parity_mode
{
kLPUART_ParityDisabled = 0x0U, /*!< Parity disabled */
kLPUART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */
kLPUART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */
} lpuart_parity_mode_t;
/*! @brief LPUART stop bit count. */
typedef enum _lpuart_stop_bit_count
{
kLPUART_OneStopBit = 0U, /*!< One stop bit */
kLPUART_TwoStopBit = 1U, /*!< Two stop bits */
} lpuart_stop_bit_count_t;
/*!
* @brief LPUART interrupt configuration structure, default settings all disabled.
*
* This structure contains the settings for all LPUART interrupt configurations.
*/
enum _lpuart_interrupt_enable
{
#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
kLPUART_LinBreakInterruptEnable = (LPUART_BAUD_LBKDIE_MASK >> 8), /*!< LIN break detect. */
#endif
kLPUART_RxActiveEdgeInterruptEnable = (LPUART_BAUD_RXEDGIE_MASK >> 8), /*!< Receive Active Edge. */
kLPUART_TxDataRegEmptyInterruptEnable = (LPUART_CTRL_TIE_MASK), /*!< Transmit data register empty. */
kLPUART_TransmissionCompleteInterruptEnable = (LPUART_CTRL_TCIE_MASK), /*!< Transmission complete. */
kLPUART_RxDataRegFullInterruptEnable = (LPUART_CTRL_RIE_MASK), /*!< Receiver data register full. */
kLPUART_IdleLineInterruptEnable = (LPUART_CTRL_ILIE_MASK), /*!< Idle line. */
kLPUART_RxOverrunInterruptEnable = (LPUART_CTRL_ORIE_MASK), /*!< Receiver Overrun. */
kLPUART_NoiseErrorInterruptEnable = (LPUART_CTRL_NEIE_MASK), /*!< Noise error flag. */
kLPUART_FramingErrorInterruptEnable = (LPUART_CTRL_FEIE_MASK), /*!< Framing error flag. */
kLPUART_ParityErrorInterruptEnable = (LPUART_CTRL_PEIE_MASK), /*!< Parity error flag. */
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kLPUART_TxFifoOverflowInterruptEnable = (LPUART_FIFO_TXOFE_MASK >> 8), /*!< Transmit FIFO Overflow. */
kLPUART_RxFifoUnderflowInterruptEnable = (LPUART_FIFO_RXUFE_MASK >> 8), /*!< Receive FIFO Underflow. */
#endif
};
/*!
* @brief LPUART status flags.
*
* This provides constants for the LPUART status flags for use in the LPUART functions.
*/
enum _lpuart_flags
{
kLPUART_TxDataRegEmptyFlag =
(LPUART_STAT_TDRE_MASK), /*!< Transmit data register empty flag, sets when transmit buffer is empty */
kLPUART_TransmissionCompleteFlag =
(LPUART_STAT_TC_MASK), /*!< Transmission complete flag, sets when transmission activity complete */
kLPUART_RxDataRegFullFlag =
(LPUART_STAT_RDRF_MASK), /*!< Receive data register full flag, sets when the receive data buffer is full */
kLPUART_IdleLineFlag = (LPUART_STAT_IDLE_MASK), /*!< Idle line detect flag, sets when idle line detected */
kLPUART_RxOverrunFlag = (LPUART_STAT_OR_MASK), /*!< Receive Overrun, sets when new data is received before data is
read from receive register */
kLPUART_NoiseErrorFlag = (LPUART_STAT_NF_MASK), /*!< Receive takes 3 samples of each received bit. If any of these
samples differ, noise flag sets */
kLPUART_FramingErrorFlag =
(LPUART_STAT_FE_MASK), /*!< Frame error flag, sets if logic 0 was detected where stop bit expected */
kLPUART_ParityErrorFlag = (LPUART_STAT_PF_MASK), /*!< If parity enabled, sets upon parity error detection */
#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
kLPUART_LinBreakFlag = (LPUART_STAT_LBKDIF_MASK), /*!< LIN break detect interrupt flag, sets when LIN break char
detected and LIN circuit enabled */
#endif
kLPUART_RxActiveEdgeFlag =
(LPUART_STAT_RXEDGIF_MASK), /*!< Receive pin active edge interrupt flag, sets when active edge detected */
kLPUART_RxActiveFlag =
(LPUART_STAT_RAF_MASK), /*!< Receiver Active Flag (RAF), sets at beginning of valid start bit */
#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
kLPUART_DataMatch1Flag = LPUART_STAT_MA1F_MASK, /*!< The next character to be read from LPUART_DATA matches MA1*/
kLPUART_DataMatch2Flag = LPUART_STAT_MA2F_MASK, /*!< The next character to be read from LPUART_DATA matches MA2*/
#endif
#if defined(FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS
kLPUART_NoiseErrorInRxDataRegFlag =
(LPUART_DATA_NOISY_MASK >> 10), /*!< NOISY bit, sets if noise detected in current data word */
kLPUART_ParityErrorInRxDataRegFlag =
(LPUART_DATA_PARITYE_MASK >> 10), /*!< PARITYE bit, sets if noise detected in current data word */
#endif
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kLPUART_TxFifoEmptyFlag = (LPUART_FIFO_TXEMPT_MASK >> 16), /*!< TXEMPT bit, sets if transmit buffer is empty */
kLPUART_RxFifoEmptyFlag = (LPUART_FIFO_RXEMPT_MASK >> 16), /*!< RXEMPT bit, sets if receive buffer is empty */
kLPUART_TxFifoOverflowFlag =
(LPUART_FIFO_TXOF_MASK >> 16), /*!< TXOF bit, sets if transmit buffer overflow occurred */
kLPUART_RxFifoUnderflowFlag =
(LPUART_FIFO_RXUF_MASK >> 16), /*!< RXUF bit, sets if receive buffer underflow occurred */
#endif
};
/*! @brief LPUART configure structure. */
typedef struct _lpuart_config
{
uint32_t baudRate_Bps; /*!< LPUART baud rate */
lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
lpuart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
#endif
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
uint8_t txFifoWatermark; /*!< TX FIFO watermark */
uint8_t rxFifoWatermark; /*!< RX FIFO watermark */
#endif
bool enableTx; /*!< Enable TX */
bool enableRx; /*!< Enable RX */
} lpuart_config_t;
/*! @brief LPUART transfer structure. */
typedef struct _lpuart_transfer
{
uint8_t *data; /*!< The buffer of data to be transfer.*/
size_t dataSize; /*!< The byte count to be transfer. */
} lpuart_transfer_t;
/* Forward declaration of the handle typedef. */
typedef struct _lpuart_handle lpuart_handle_t;
/*! @brief LPUART transfer callback function. */
typedef void (*lpuart_transfer_callback_t)(LPUART_Type *base, lpuart_handle_t *handle, status_t status, void *userData);
/*! @brief LPUART handle structure. */
struct _lpuart_handle
{
uint8_t *volatile txData; /*!< Address of remaining data to send. */
volatile size_t txDataSize; /*!< Size of the remaining data to send. */
size_t txDataSizeAll; /*!< Size of the data to send out. */
uint8_t *volatile rxData; /*!< Address of remaining data to receive. */
volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */
size_t rxDataSizeAll; /*!< Size of the data to receive. */
uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */
size_t rxRingBufferSize; /*!< Size of the ring buffer. */
volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */
volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */
lpuart_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< LPUART callback function parameter.*/
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock.
*
* This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function
* to configure the configuration structure and get the default configuration.
* The example below shows how to use this API to configure the LPUART.
* @code
* lpuart_config_t lpuartConfig;
* lpuartConfig.baudRate_Bps = 115200U;
* lpuartConfig.parityMode = kLPUART_ParityDisabled;
* lpuartConfig.stopBitCount = kLPUART_OneStopBit;
* lpuartConfig.txFifoWatermark = 0;
* lpuartConfig.rxFifoWatermark = 1;
* LPUART_Init(LPUART1, &lpuartConfig, 20000000U);
* @endcode
*
* @param base LPUART peripheral base address.
* @param config Pointer to a user-defined configuration structure.
* @param srcClock_Hz LPUART clock source frequency in HZ.
*/
void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz);
/*!
* @brief Deinitializes a LPUART instance.
*
* This function waits for transmit to complete, disables TX and RX, and disables the LPUART clock.
*
* @param base LPUART peripheral base address.
*/
void LPUART_Deinit(LPUART_Type *base);
/*!
* @brief Gets the default configuration structure.
*
* This function initializes the LPUART configuration structure to a default value. The default
* values are:
* lpuartConfig->baudRate_Bps = 115200U;
* lpuartConfig->parityMode = kLPUART_ParityDisabled;
* lpuartConfig->stopBitCount = kLPUART_OneStopBit;
* lpuartConfig->txFifoWatermark = 0;
* lpuartConfig->rxFifoWatermark = 1;
* lpuartConfig->enableTx = false;
* lpuartConfig->enableRx = false;
*
* @param config Pointer to a configuration structure.
*/
void LPUART_GetDefaultConfig(lpuart_config_t *config);
/*!
* @brief Sets the LPUART instance baudrate.
*
* This function configures the LPUART module baudrate. This function is used to update
* the LPUART module baudrate after the LPUART module is initialized by the LPUART_Init.
* @code
* LPUART_SetBaudRate(LPUART1, 115200U, 20000000U);
* @endcode
*
* @param base LPUART peripheral base address.
* @param baudRate_Bps LPUART baudrate to be set.
* @param srcClock_Hz LPUART clock source frequency in HZ.
*/
void LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
/* @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Gets LPUART status flags.
*
* This function gets all LPUART status flags. The flags are returned as the logical
* OR value of the enumerators @ref _lpuart_flags. To check for a specific status,
* compare the return value with enumerators in the @ref _lpuart_flags.
* For example, to check whether the TX is empty:
* @code
* if (kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1))
* {
* ...
* }
* @endcode
*
* @param base LPUART peripheral base address.
* @return LPUART status flags which are ORed by the enumerators in the _lpuart_flags.
*/
uint32_t LPUART_GetStatusFlags(LPUART_Type *base);
/*!
* @brief Clears status flags with a provided mask.
*
* This function clears LPUART status flags with a provided mask. Automatically cleared flags
* can't be cleared by this function.
* Flags that can only cleared or set by hardware are:
* kLPUART_TxDataRegEmptyFlag, kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag,
* kLPUART_RxActiveFlag, kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag,
* kLPUART_TxFifoEmptyFlag,kLPUART_RxFifoEmptyFlag
* Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects.
*
* @param base LPUART peripheral base address.
* @param mask the status flags to be cleared. The user can use the enumerators in the
* _lpuart_status_flag_t to do the OR operation and get the mask.
* @return 0 succeed, others failed.
* @retval kStatus_LPUART_FlagCannotClearManually The flag can't be cleared by this function but
* it is cleared automatically by hardware.
* @retval kStatus_Success Status in the mask are cleared.
*/
status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask);
/* @} */
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables LPUART interrupts according to a provided mask.
*
* This function enables the LPUART interrupts according to a provided mask. The mask
* is a logical OR of enumeration members. See the @ref _lpuart_interrupt_enable.
* This examples shows how to enable TX empty interrupt and RX full interrupt:
* @code
* LPUART_EnableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable);
* @endcode
*
* @param base LPUART peripheral base address.
* @param mask The interrupts to enable. Logical OR of @ref _uart_interrupt_enable.
*/
void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask);
/*!
* @brief Disables LPUART interrupts according to a provided mask.
*
* This function disables the LPUART interrupts according to a provided mask. The mask
* is a logical OR of enumeration members. See @ref _lpuart_interrupt_enable.
* This example shows how to disable the TX empty interrupt and RX full interrupt:
* @code
* LPUART_DisableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable);
* @endcode
*
* @param base LPUART peripheral base address.
* @param mask The interrupts to disable. Logical OR of @ref _lpuart_interrupt_enable.
*/
void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask);
/*!
* @brief Gets enabled LPUART interrupts.
*
* This function gets the enabled LPUART interrupts. The enabled interrupts are returned
* as the logical OR value of the enumerators @ref _lpuart_interrupt_enable. To check
* a specific interrupt enable status, compare the return value with enumerators
* in @ref _lpuart_interrupt_enable.
* For example, to check whether the TX empty interrupt is enabled:
* @code
* uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(LPUART1);
*
* if (kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts)
* {
* ...
* }
* @endcode
*
* @param base LPUART peripheral base address.
* @return LPUART interrupt flags which are logical OR of the enumerators in @ref _lpuart_interrupt_enable.
*/
uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base);
#if defined(FSL_FEATURE_LPUART_HAS_DMA_ENABLE) && FSL_FEATURE_LPUART_HAS_DMA_ENABLE
/*!
* @brief Gets the LPUART data register address.
*
* This function returns the LPUART data register address, which is mainly used by the DMA/eDMA.
*
* @param base LPUART peripheral base address.
* @return LPUART data register addresses which are used both by the transmitter and receiver.
*/
static inline uint32_t LPUART_GetDataRegisterAddress(LPUART_Type *base)
{
return (uint32_t) & (base->DATA);
}
/*!
* @brief Enables or disables the LPUART transmitter DMA request.
*
* This function enables or disables the transmit data register empty flag, STAT[TDRE], to generate DMA requests.
*
* @param base LPUART peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void LPUART_EnableTxDMA(LPUART_Type *base, bool enable)
{
if (enable)
{
base->BAUD |= LPUART_BAUD_TDMAE_MASK;
base->CTRL |= LPUART_CTRL_TIE_MASK;
}
else
{
base->BAUD &= ~LPUART_BAUD_TDMAE_MASK;
base->CTRL &= ~LPUART_CTRL_TIE_MASK;
}
}
/*!
* @brief Enables or disables the LPUART receiver DMA.
*
* This function enables or disables the receiver data register full flag, STAT[RDRF], to generate DMA requests.
*
* @param base LPUART peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void LPUART_EnableRxDMA(LPUART_Type *base, bool enable)
{
if (enable)
{
base->BAUD |= LPUART_BAUD_RDMAE_MASK;
base->CTRL |= LPUART_CTRL_RIE_MASK;
}
else
{
base->BAUD &= ~LPUART_BAUD_RDMAE_MASK;
base->CTRL &= ~LPUART_CTRL_RIE_MASK;
}
}
/* @} */
#endif /* FSL_FEATURE_LPUART_HAS_DMA_ENABLE */
/*!
* @name Bus Operations
* @{
*/
/*!
* @brief Enables or disables the LPUART transmitter.
*
* This function enables or disables the LPUART transmitter.
*
* @param base LPUART peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void LPUART_EnableTx(LPUART_Type *base, bool enable)
{
if (enable)
{
base->CTRL |= LPUART_CTRL_TE_MASK;
}
else
{
base->CTRL &= ~LPUART_CTRL_TE_MASK;
}
}
/*!
* @brief Enables or disables the LPUART receiver.
*
* This function enables or disables the LPUART receiver.
*
* @param base LPUART peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void LPUART_EnableRx(LPUART_Type *base, bool enable)
{
if (enable)
{
base->CTRL |= LPUART_CTRL_RE_MASK;
}
else
{
base->CTRL &= ~LPUART_CTRL_RE_MASK;
}
}
/*!
* @brief Writes to the transmitter register.
*
* This function writes data to the transmitter register directly. The upper layer must
* ensure that the TX register is empty or that the TX FIFO has room before calling this function.
*
* @param base LPUART peripheral base address.
* @param data Data write to the TX register.
*/
static inline void LPUART_WriteByte(LPUART_Type *base, uint8_t data)
{
base->DATA = data;
}
/*!
* @brief Reads the RX register.
*
* This function reads data from the TX register directly. The upper layer must
* ensure that the RX register is full or that the TX FIFO has data before calling this function.
*
* @param base LPUART peripheral base address.
* @return Data read from data register.
*/
static inline uint8_t LPUART_ReadByte(LPUART_Type *base)
{
return base->DATA;
}
/*!
* @brief Writes to transmitter register using a blocking method.
*
* This function polls the transmitter register, waits for the register to be empty or for TX FIFO to have
* room and then writes data to the transmitter buffer.
*
* @note This function does not check whether all data has been sent out to the bus.
* Before disabling the transmitter, check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is
* finished.
*
* @param base LPUART peripheral base address.
* @param data Start address of the data to write.
* @param length Size of the data to write.
*/
void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length);
/*!
* @brief Reads the RX data register using a blocking method.
*
* This function polls the RX register, waits for the RX register full or RX FIFO
* has data then reads data from the TX register.
*
* @param base LPUART peripheral base address.
* @param data Start address of the buffer to store the received data.
* @param length Size of the buffer.
* @retval kStatus_LPUART_RxHardwareOverrun Receiver overrun happened while receiving data.
* @retval kStatus_LPUART_NoiseError Noise error happened while receiving data.
* @retval kStatus_LPUART_FramingError Framing error happened while receiving data.
* @retval kStatus_LPUART_ParityError Parity error happened while receiving data.
* @retval kStatus_Success Successfully received all data.
*/
status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length);
/* @} */
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the LPUART handle.
*
* This function initializes the LPUART handle, which can be used for other LPUART
* transactional APIs. Usually, for a specified LPUART instance,
* call this API once to get the initialized handle.
*
* The LPUART driver supports the "background" receiving, which means that user can set up
* an RX ring buffer optionally. Data received is stored into the ring buffer even when the
* user doesn't call the LPUART_TransferReceiveNonBlocking() API. If there is already data received
* in the ring buffer, the user can get the received data from the ring buffer directly.
* The ring buffer is disabled if passing NULL as @p ringBuffer.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param callback Callback function.
* @param userData User data.
*/
void LPUART_TransferCreateHandle(LPUART_Type *base,
lpuart_handle_t *handle,
lpuart_transfer_callback_t callback,
void *userData);
/*!
* @brief Transmits a buffer of data using the interrupt method.
*
* This function send data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data written to the transmitter register. When
* all data is written to the TX register in the ISR, the LPUART driver calls the callback
* function and passes the @ref kStatus_LPUART_TxIdle as status parameter.
*
* @note The kStatus_LPUART_TxIdle is passed to the upper layer when all data are written
* to the TX register. However, there is no check to ensure that all the data sent out. Before disabling the TX,
* check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is finished.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param xfer LPUART transfer structure, refer to #lpuart_transfer_t.
* @retval kStatus_Success Successfully start the data transmission.
* @retval kStatus_LPUART_TxBusy Previous transmission still not finished, data not all written to the TX register.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer);
/*!
* @brief Sets up the RX ring buffer.
*
* This function sets up the RX ring buffer to a specific UART handle.
*
* When the RX ring buffer is used, data received is stored into the ring buffer even when
* the user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received
* in the ring buffer, the user can get the received data from the ring buffer directly.
*
* @note When using RX ring buffer, one byte is reserved for internal use. In other
* words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer.
* @param ringBufferSize size of the ring buffer.
*/
void LPUART_TransferStartRingBuffer(LPUART_Type *base,
lpuart_handle_t *handle,
uint8_t *ringBuffer,
size_t ringBufferSize);
/*!
* @brief Abort the background transfer and uninstall the ring buffer.
*
* This function aborts the background transfer and uninstalls the ring buffer.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
*/
void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle);
/*!
* @brief Aborts the interrupt-driven data transmit.
*
* This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out
* how many bytes are still not sent out.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
*/
void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been written to LPUART TX register.
*
* This function gets the number of bytes that have been written to LPUART TX
* register by interrupt method.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param count Send bytes count.
* @retval kStatus_NoTransferInProgress No send in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count);
/*!
* @brief Receives a buffer of data using the interrupt method.
*
* This function receives data using an interrupt method. This is a non-blocking function
* which returns without waiting to ensure that all data are received.
* If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
* the parameter @p receivedBytes shows how many bytes are copied from the ring buffer.
* After copying, if the data in the ring buffer is not enough for read, the receive
* request is saved by the LPUART driver. When the new data arrives, the receive request
* is serviced first. When all data is received, the LPUART driver notifies the upper layer
* through a callback function and passes a status parameter @ref kStatus_UART_RxIdle.
* For example, the upper layer needs 10 bytes but there are only 5 bytes in ring buffer.
* The 5 bytes are copied to xfer->data, which returns with the
* parameter @p receivedBytes set to 5. For the remaining 5 bytes, the newly arrived data is
* saved from xfer->data[5]. When 5 bytes are received, the LPUART driver notifies the upper layer.
* If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
* to receive data to xfer->data. When all data is received, the upper layer is notified.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param xfer LPUART transfer structure, refer to #uart_transfer_t.
* @param receivedBytes Bytes received from the ring buffer directly.
* @retval kStatus_Success Successfully queue the transfer into the transmit queue.
* @retval kStatus_LPUART_RxBusy Previous receive request is not finished.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
lpuart_handle_t *handle,
lpuart_transfer_t *xfer,
size_t *receivedBytes);
/*!
* @brief Aborts the interrupt-driven data receiving.
*
* This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out
* how many bytes not received yet.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
*/
void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param count Receive bytes count.
* @retval kStatus_NoTransferInProgress No receive in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count);
/*!
* @brief LPUART IRQ handle function.
*
* This function handles the LPUART transmit and receive IRQ request.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
*/
void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle);
/*!
* @brief LPUART Error IRQ handle function.
*
* This function handles the LPUART error IRQ request.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
*/
void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_LPUART_H_ */

View File

@ -1,339 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_lpuart_dma.h"
#include "fsl_dmamux.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*<! Structure definition for lpuart_dma_handle_t. The structure is private. */
typedef struct _lpuart_dma_private_handle
{
LPUART_Type *base;
lpuart_dma_handle_t *handle;
} lpuart_dma_private_handle_t;
/* LPUART DMA transfer handle. */
enum _uart_dma_tansfer_states
{
kLPUART_TxIdle, /* TX idle. */
kLPUART_TxBusy, /* TX busy. */
kLPUART_RxIdle, /* RX idle. */
kLPUART_RxBusy /* RX busy. */
};
/*******************************************************************************
* Variables
******************************************************************************/
/*<! Private handle only used for internally. */
static lpuart_dma_private_handle_t s_dmaPrivateHandle[FSL_FEATURE_SOC_LPUART_COUNT];
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief LPUART DMA send finished callback function.
*
* This function is called when LPUART DMA send finished. It disables the LPUART
* TX DMA request and sends @ref kStatus_LPUART_TxIdle to LPUART callback.
*
* @param handle The DMA handle.
* @param param Callback function parameter.
*/
static void LPUART_TransferSendDMACallback(dma_handle_t *handle, void *param);
/*!
* @brief LPUART DMA receive finished callback function.
*
* This function is called when LPUART DMA receive finished. It disables the LPUART
* RX DMA request and sends @ref kStatus_LPUART_RxIdle to LPUART callback.
*
* @param handle The DMA handle.
* @param param Callback function parameter.
*/
static void LPUART_TransferReceiveDMACallback(dma_handle_t *handle, void *param);
/*!
* @brief Get the LPUART instance from peripheral base address.
*
* @param base LPUART peripheral base address.
* @return LPUART instance.
*/
extern uint32_t LPUART_GetInstance(LPUART_Type *base);
/*******************************************************************************
* Code
******************************************************************************/
static void LPUART_TransferSendDMACallback(dma_handle_t *handle, void *param)
{
lpuart_dma_private_handle_t *lpuartPrivateHandle = (lpuart_dma_private_handle_t *)param;
/* Disable LPUART TX DMA. */
LPUART_EnableTxDMA(lpuartPrivateHandle->base, false);
/* Disable interrupt. */
DMA_DisableInterrupts(lpuartPrivateHandle->handle->txDmaHandle->base,
lpuartPrivateHandle->handle->txDmaHandle->channel);
lpuartPrivateHandle->handle->txState = kLPUART_TxIdle;
if (lpuartPrivateHandle->handle->callback)
{
lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle,
kStatus_LPUART_TxIdle, lpuartPrivateHandle->handle->userData);
}
}
static void LPUART_TransferReceiveDMACallback(dma_handle_t *handle, void *param)
{
lpuart_dma_private_handle_t *lpuartPrivateHandle = (lpuart_dma_private_handle_t *)param;
/* Disable LPUART RX DMA. */
LPUART_EnableRxDMA(lpuartPrivateHandle->base, false);
/* Disable interrupt. */
DMA_DisableInterrupts(lpuartPrivateHandle->handle->rxDmaHandle->base,
lpuartPrivateHandle->handle->rxDmaHandle->channel);
lpuartPrivateHandle->handle->rxState = kLPUART_RxIdle;
if (lpuartPrivateHandle->handle->callback)
{
lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle,
kStatus_LPUART_RxIdle, lpuartPrivateHandle->handle->userData);
}
}
void LPUART_TransferCreateHandleDMA(LPUART_Type *base,
lpuart_dma_handle_t *handle,
lpuart_dma_transfer_callback_t callback,
void *userData,
dma_handle_t *txDmaHandle,
dma_handle_t *rxDmaHandle)
{
assert(handle);
uint32_t instance = LPUART_GetInstance(base);
memset(handle, 0, sizeof(lpuart_dma_handle_t));
s_dmaPrivateHandle[instance].base = base;
s_dmaPrivateHandle[instance].handle = handle;
handle->rxState = kLPUART_RxIdle;
handle->txState = kLPUART_TxIdle;
handle->callback = callback;
handle->userData = userData;
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
/* Note:
Take care of the RX FIFO, DMA request only assert when received bytes
equal or more than RX water mark, there is potential issue if RX water
mark larger than 1.
For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and
5 bytes are received. the last byte will be saved in FIFO but not trigger
DMA transfer because the water mark is 2.
*/
if (rxDmaHandle)
{
base->WATER &= (~LPUART_WATER_RXWATER_MASK);
}
#endif
handle->rxDmaHandle = rxDmaHandle;
handle->txDmaHandle = txDmaHandle;
/* Configure TX. */
if (txDmaHandle)
{
DMA_SetCallback(txDmaHandle, LPUART_TransferSendDMACallback, &s_dmaPrivateHandle[instance]);
}
/* Configure RX. */
if (rxDmaHandle)
{
DMA_SetCallback(rxDmaHandle, LPUART_TransferReceiveDMACallback, &s_dmaPrivateHandle[instance]);
}
}
status_t LPUART_TransferSendDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, lpuart_transfer_t *xfer)
{
assert(handle->txDmaHandle);
status_t status;
dma_transfer_config_t xferConfig;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* If previous TX not finished. */
if (kLPUART_TxBusy == handle->txState)
{
status = kStatus_LPUART_TxBusy;
}
else
{
handle->txState = kLPUART_TxBusy;
handle->txDataSizeAll = xfer->dataSize;
/* Prepare transfer. */
DMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)LPUART_GetDataRegisterAddress(base),
sizeof(uint8_t), xfer->dataSize, kDMA_MemoryToPeripheral);
/* Submit transfer. */
DMA_SubmitTransfer(handle->txDmaHandle, &xferConfig, kDMA_EnableInterrupt);
DMA_StartTransfer(handle->txDmaHandle);
/* Enable LPUART TX DMA. */
LPUART_EnableTxDMA(base, true);
status = kStatus_Success;
}
return status;
}
status_t LPUART_TransferReceiveDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, lpuart_transfer_t *xfer)
{
assert(handle->rxDmaHandle);
status_t status;
dma_transfer_config_t xferConfig;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* If previous RX not finished. */
if (kLPUART_RxBusy == handle->rxState)
{
status = kStatus_LPUART_RxBusy;
}
else
{
handle->rxState = kLPUART_RxBusy;
handle->rxDataSizeAll = xfer->dataSize;
/* Prepare transfer. */
DMA_PrepareTransfer(&xferConfig, (void *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data,
sizeof(uint8_t), xfer->dataSize, kDMA_PeripheralToMemory);
/* Submit transfer. */
DMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig, kDMA_EnableInterrupt);
DMA_StartTransfer(handle->rxDmaHandle);
/* Enable LPUART RX DMA. */
LPUART_EnableRxDMA(base, true);
status = kStatus_Success;
}
return status;
}
void LPUART_TransferAbortSendDMA(LPUART_Type *base, lpuart_dma_handle_t *handle)
{
assert(handle->txDmaHandle);
/* Disable LPUART TX DMA. */
LPUART_EnableTxDMA(base, false);
/* Stop transfer. */
DMA_AbortTransfer(handle->txDmaHandle);
/* Write DMA->DSR[DONE] to abort transfer and clear status. */
DMA_ClearChannelStatusFlags(handle->txDmaHandle->base, handle->txDmaHandle->channel, kDMA_TransactionsDoneFlag);
handle->txState = kLPUART_TxIdle;
}
void LPUART_TransferAbortReceiveDMA(LPUART_Type *base, lpuart_dma_handle_t *handle)
{
assert(handle->rxDmaHandle);
/* Disable LPUART RX DMA. */
LPUART_EnableRxDMA(base, false);
/* Stop transfer. */
DMA_AbortTransfer(handle->rxDmaHandle);
/* Write DMA->DSR[DONE] to abort transfer and clear status. */
DMA_ClearChannelStatusFlags(handle->rxDmaHandle->base, handle->rxDmaHandle->channel, kDMA_TransactionsDoneFlag);
handle->rxState = kLPUART_RxIdle;
}
status_t LPUART_TransferGetSendCountDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, uint32_t *count)
{
assert(handle->txDmaHandle);
if (kLPUART_TxIdle == handle->txState)
{
return kStatus_NoTransferInProgress;
}
if (!count)
{
return kStatus_InvalidArgument;
}
*count = handle->txDataSizeAll - DMA_GetRemainingBytes(handle->txDmaHandle->base, handle->txDmaHandle->channel);
return kStatus_Success;
}
status_t LPUART_TransferGetReceiveCountDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, uint32_t *count)
{
assert(handle->rxDmaHandle);
if (kLPUART_RxIdle == handle->rxState)
{
return kStatus_NoTransferInProgress;
}
if (!count)
{
return kStatus_InvalidArgument;
}
*count = handle->rxDataSizeAll - DMA_GetRemainingBytes(handle->rxDmaHandle->base, handle->rxDmaHandle->channel);
return kStatus_Success;
}

View File

@ -1,189 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_LPUART_DMA_H_
#define _FSL_LPUART_DMA_H_
#include "fsl_lpuart.h"
#include "fsl_dma.h"
/*!
* @addtogroup lpuart_dma_driver
* @{
*/
/*! @file*/
/*******************************************************************************
* Definitions
******************************************************************************/
/* Forward declaration of the handle typedef. */
typedef struct _lpuart_dma_handle lpuart_dma_handle_t;
/*! @brief LPUART transfer callback function. */
typedef void (*lpuart_dma_transfer_callback_t)(LPUART_Type *base,
lpuart_dma_handle_t *handle,
status_t status,
void *userData);
/*!
* @brief LPUART DMA handle
*/
struct _lpuart_dma_handle
{
lpuart_dma_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< LPUART callback function parameter.*/
size_t rxDataSizeAll; /*!< Size of the data to receive. */
size_t txDataSizeAll; /*!< Size of the data to send out. */
dma_handle_t *txDmaHandle; /*!< The DMA TX channel used. */
dma_handle_t *rxDmaHandle; /*!< The DMA RX channel used. */
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name EDMA transactional
* @{
*/
/*!
* @brief Initializes the LPUART handle which is used in transactional functions.
* @param base LPUART peripheral base address.
* @param handle Pointer to lpuart_dma_handle_t structure.
* @param callback Callback function.
* @param userData User data.
* @param txDmaHandle User-requested DMA handle for TX DMA transfer.
* @param rxDmaHandle User-requested DMA handle for RX DMA transfer.
*/
void LPUART_TransferCreateHandleDMA(LPUART_Type *base,
lpuart_dma_handle_t *handle,
lpuart_dma_transfer_callback_t callback,
void *userData,
dma_handle_t *txDmaHandle,
dma_handle_t *rxDmaHandle);
/*!
* @brief Sends data using DMA.
*
* This function sends data using DMA. This is a non-blocking function, which returns
* right away. When all data is sent, the send callback function is called.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param xfer LPUART DMA transfer structure. See #lpuart_transfer_t.
* @retval kStatus_Success if succeed, others failed.
* @retval kStatus_LPUART_TxBusy Previous transfer on going.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t LPUART_TransferSendDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, lpuart_transfer_t *xfer);
/*!
* @brief Receives data using DMA.
*
* This function receives data using DMA. This is a non-blocking function, which returns
* right away. When all data is received, the receive callback function is called.
*
* @param base LPUART peripheral base address.
* @param handle Pointer to lpuart_dma_handle_t structure.
* @param xfer LPUART DMA transfer structure. See #lpuart_transfer_t.
* @retval kStatus_Success if succeed, others failed.
* @retval kStatus_LPUART_RxBusy Previous transfer on going.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t LPUART_TransferReceiveDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, lpuart_transfer_t *xfer);
/*!
* @brief Aborts the sent data using DMA.
*
* This function aborts send data using DMA.
*
* @param base LPUART peripheral base address
* @param handle Pointer to lpuart_dma_handle_t structure
*/
void LPUART_TransferAbortSendDMA(LPUART_Type *base, lpuart_dma_handle_t *handle);
/*!
* @brief Aborts the received data using DMA.
*
* This function aborts the received data using DMA.
*
* @param base LPUART peripheral base address
* @param handle Pointer to lpuart_dma_handle_t structure
*/
void LPUART_TransferAbortReceiveDMA(LPUART_Type *base, lpuart_dma_handle_t *handle);
/*!
* @brief Get the number of bytes that have been written to LPUART TX register.
*
* This function gets the number of bytes that have been written to LPUART TX
* register by DMA.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param count Send bytes count.
* @retval kStatus_NoTransferInProgress No send in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t LPUART_TransferGetSendCountDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, uint32_t *count);
/*!
* @brief Get the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param count Receive bytes count.
* @retval kStatus_NoTransferInProgress No receive in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t LPUART_TransferGetReceiveCountDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, uint32_t *count);
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_LPUART_DMA_H_ */

View File

@ -1,119 +0,0 @@
/*
* 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

@ -1,355 +0,0 @@
/*
* 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

@ -1,93 +0,0 @@
/*
* 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

@ -1,423 +0,0 @@
/*
* 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

@ -1,382 +0,0 @@
/*
* 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

@ -1,63 +0,0 @@
/*
* 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

@ -1,432 +0,0 @@
/*
* 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

@ -1,370 +0,0 @@
/*
* 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

@ -1,405 +0,0 @@
/*
* 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_ */

View File

@ -1,53 +0,0 @@
/*
* 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

@ -1,128 +0,0 @@
/*
* 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_ */

View File

@ -1,511 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_smc.h"
#include "fsl_common.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.smc"
#endif
typedef void (*smc_stop_ram_func_t)(void);
/*******************************************************************************
* Prototypes
******************************************************************************/
static void SMC_EnterStopRamFunc(void);
/*******************************************************************************
* Variables
******************************************************************************/
static uint32_t g_savedPrimask;
/*
* The ram function code is:
*
* uint32_t i;
* for (i=0; i<0x8; i++)
* {
* __NOP();
* }
* __DSB();
* __WFI();
* __ISB();
*
* When entring the stop modes, the flash prefetch might be interrupted, thus
* the prefetched code or data might be broken. To make sure the flash is idle
* when entring the stop modes, the code is moved to ram. And delay for a while
* before WFI to make sure previous flash prefetch is finished.
*
* Only need to do like this when code is in flash, if code is in rom or ram,
* this is not necessary.
*/
static uint16_t s_stopRamFuncArray[] = {
0x2000, /* MOVS R0, #0 */
0x2808, /* CMP R0, #8 */
0xD202, /* BCS.N */
0xBF00, /* NOP */
0x1C40, /* ADDS R0, R0, #1 */
0xE7FA, /* B.N */
0xF3BF, 0x8F4F, /* DSB */
0xBF30, /* WFI */
0xF3BF, 0x8F6F, /* ISB */
0x4770, /* BX LR */
};
/*******************************************************************************
* Code
******************************************************************************/
static void SMC_EnterStopRamFunc(void)
{
uint32_t ramFuncEntry = ((uint32_t)(s_stopRamFuncArray)) + 1U;
smc_stop_ram_func_t stopRamFunc = (smc_stop_ram_func_t)ramFuncEntry;
stopRamFunc();
}
#if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM)
/*!
* brief Gets the SMC parameter.
*
* This function gets the SMC parameter including the enabled power mdoes.
*
* param base SMC peripheral base address.
* param param Pointer to the SMC param structure.
*/
void SMC_GetParam(SMC_Type *base, smc_param_t *param)
{
uint32_t reg = base->PARAM;
param->hsrunEnable = (bool)(reg & SMC_PARAM_EHSRUN_MASK);
param->llsEnable = (bool)(reg & SMC_PARAM_ELLS_MASK);
param->lls2Enable = (bool)(reg & SMC_PARAM_ELLS2_MASK);
param->vlls0Enable = (bool)(reg & SMC_PARAM_EVLLS0_MASK);
}
#endif /* FSL_FEATURE_SMC_HAS_PARAM */
/*!
* brief Prepares to enter stop modes.
*
* This function should be called before entering STOP/VLPS/LLS/VLLS modes.
*/
void SMC_PreEnterStopModes(void)
{
g_savedPrimask = DisableGlobalIRQ();
__ISB();
}
/*!
* brief Recovers after wake up from stop modes.
*
* This function should be called after wake up from STOP/VLPS/LLS/VLLS modes.
* It is used with ref SMC_PreEnterStopModes.
*/
void SMC_PostExitStopModes(void)
{
EnableGlobalIRQ(g_savedPrimask);
__ISB();
}
/*!
* brief Prepares to enter wait modes.
*
* This function should be called before entering WAIT/VLPW modes.
*/
void SMC_PreEnterWaitModes(void)
{
g_savedPrimask = DisableGlobalIRQ();
__ISB();
}
/*!
* brief Recovers after wake up from stop modes.
*
* This function should be called after wake up from WAIT/VLPW modes.
* It is used with ref SMC_PreEnterWaitModes.
*/
void SMC_PostExitWaitModes(void)
{
EnableGlobalIRQ(g_savedPrimask);
__ISB();
}
/*!
* brief Configures the system to RUN power mode.
*
* param base SMC peripheral base address.
* return SMC configuration error code.
*/
status_t SMC_SetPowerModeRun(SMC_Type *base)
{
uint8_t reg;
reg = base->PMCTRL;
/* configure Normal RUN mode */
reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK;
reg |= ((uint8_t)kSMC_RunNormal << SMC_PMCTRL_RUNM_SHIFT);
base->PMCTRL = reg;
return kStatus_Success;
}
#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE)
/*!
* brief Configures the system to HSRUN power mode.
*
* param base SMC peripheral base address.
* return SMC configuration error code.
*/
status_t SMC_SetPowerModeHsrun(SMC_Type *base)
{
uint8_t reg;
reg = base->PMCTRL;
/* configure High Speed RUN mode */
reg &= ~SMC_PMCTRL_RUNM_MASK;
reg |= ((uint8_t)kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT);
base->PMCTRL = reg;
return kStatus_Success;
}
#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
/*!
* brief Configures the system to WAIT power mode.
*
* param base SMC peripheral base address.
* return SMC configuration error code.
*/
status_t SMC_SetPowerModeWait(SMC_Type *base)
{
/* configure Normal Wait mode */
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
__DSB();
__WFI();
__ISB();
return kStatus_Success;
}
/*!
* brief Configures the system to Stop power mode.
*
* param base SMC peripheral base address.
* param option Partial Stop mode option.
* return SMC configuration error code.
*/
status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option)
{
uint8_t reg;
#if (defined(FSL_FEATURE_SMC_HAS_PSTOPO) && FSL_FEATURE_SMC_HAS_PSTOPO)
/* configure the Partial Stop mode in Normal Stop mode */
reg = base->STOPCTRL;
reg &= ~(uint8_t)SMC_STOPCTRL_PSTOPO_MASK;
reg |= ((uint8_t)option << SMC_STOPCTRL_PSTOPO_SHIFT);
base->STOPCTRL = reg;
#endif
/* configure Normal Stop mode */
reg = base->PMCTRL;
reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK;
reg |= ((uint8_t)kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT);
base->PMCTRL = reg;
/* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
/* read back to make sure the configuration valid before enter stop mode */
(void)base->PMCTRL;
SMC_EnterStopRamFunc();
/* check whether the power mode enter Stop mode succeed */
if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK))
{
return kStatus_SMC_StopAbort;
}
else
{
return kStatus_Success;
}
}
/*!
* brief Configures the system to VLPR power mode.
*
* param base SMC peripheral base address.
* return SMC configuration error code.
*/
status_t SMC_SetPowerModeVlpr(SMC_Type *base
#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI)
,
bool wakeupMode
#endif
)
{
uint8_t reg;
reg = base->PMCTRL;
#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI)
/* configure whether the system remains in VLP mode on an interrupt */
if (wakeupMode)
{
/* exits to RUN mode on an interrupt */
reg |= SMC_PMCTRL_LPWUI_MASK;
}
else
{
/* remains in VLP mode on an interrupt */
reg &= ~(uint8_t)SMC_PMCTRL_LPWUI_MASK;
}
#endif /* FSL_FEATURE_SMC_HAS_LPWUI */
/* configure VLPR mode */
reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK;
reg |= ((uint8_t)kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT);
base->PMCTRL = reg;
return kStatus_Success;
}
/*!
* brief Configures the system to VLPW power mode.
*
* param base SMC peripheral base address.
* return SMC configuration error code.
*/
status_t SMC_SetPowerModeVlpw(SMC_Type *base)
{
/* configure VLPW mode */
/* Set the SLEEPDEEP bit to enable deep sleep mode */
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
__DSB();
__WFI();
__ISB();
return kStatus_Success;
}
/*!
* brief Configures the system to VLPS power mode.
*
* param base SMC peripheral base address.
* return SMC configuration error code.
*/
status_t SMC_SetPowerModeVlps(SMC_Type *base)
{
uint8_t reg;
/* configure VLPS mode */
reg = base->PMCTRL;
reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK;
reg |= ((uint8_t)kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT);
base->PMCTRL = reg;
/* Set the SLEEPDEEP bit to enable deep sleep mode */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
/* read back to make sure the configuration valid before enter stop mode */
(void)base->PMCTRL;
SMC_EnterStopRamFunc();
/* check whether the power mode enter VLPS mode succeed */
if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK))
{
return kStatus_SMC_StopAbort;
}
else
{
return kStatus_Success;
}
}
#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE)
/*!
* brief Configures the system to LLS power mode.
*
* param base SMC peripheral base address.
* return SMC configuration error code.
*/
status_t SMC_SetPowerModeLls(SMC_Type *base
#if ((defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \
(defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO))
,
const smc_power_mode_lls_config_t *config
#endif
)
{
uint8_t reg;
/* configure to LLS mode */
reg = base->PMCTRL;
reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK;
reg |= ((uint8_t)kSMC_StopLls << SMC_PMCTRL_STOPM_SHIFT);
base->PMCTRL = reg;
/* configure LLS sub-mode*/
#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE)
reg = base->STOPCTRL;
reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK;
reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT);
base->STOPCTRL = reg;
#endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */
#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)
if (config->enableLpoClock)
{
base->STOPCTRL &= ~SMC_STOPCTRL_LPOPO_MASK;
}
else
{
base->STOPCTRL |= SMC_STOPCTRL_LPOPO_MASK;
}
#endif /* FSL_FEATURE_SMC_HAS_LPOPO */
/* Set the SLEEPDEEP bit to enable deep sleep mode */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
/* read back to make sure the configuration valid before enter stop mode */
(void)base->PMCTRL;
SMC_EnterStopRamFunc();
/* check whether the power mode enter LLS mode succeed */
if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK))
{
return kStatus_SMC_StopAbort;
}
else
{
return kStatus_Success;
}
}
#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */
#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
/*!
* brief Configures the system to VLLS power mode.
*
* param base SMC peripheral base address.
* param config The VLLS power mode configuration structure.
* return SMC configuration error code.
*/
status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config)
{
uint8_t reg;
#if (defined(FSL_FEATURE_SMC_HAS_PORPO) && FSL_FEATURE_SMC_HAS_PORPO)
#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) || \
(defined(FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) && FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) || \
(defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE)
if (config->subMode == kSMC_StopSub0)
#endif
{
/* configure whether the Por Detect work in Vlls0 mode */
if (true == config->enablePorDetectInVlls0)
{
#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG)
base->VLLSCTRL &= ~SMC_VLLSCTRL_PORPO_MASK;
#else
base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_PORPO_MASK;
#endif
}
else
{
#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG)
base->VLLSCTRL |= SMC_VLLSCTRL_PORPO_MASK;
#else
base->STOPCTRL |= SMC_STOPCTRL_PORPO_MASK;
#endif
}
}
#endif /* FSL_FEATURE_SMC_HAS_PORPO */
#if (defined(FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) && FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION)
else if (config->subMode == kSMC_StopSub2)
{
/* configure whether the Por Detect work in Vlls0 mode */
if (true == config->enableRam2InVlls2)
{
#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG)
base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK;
#else
base->STOPCTRL |= SMC_STOPCTRL_RAM2PO_MASK;
#endif
}
else
{
#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG)
base->VLLSCTRL &= ~SMC_VLLSCTRL_RAM2PO_MASK;
#else
base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_RAM2PO_MASK;
#endif
}
}
else
{
/* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */
}
#endif /* FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION */
/* configure to VLLS mode */
reg = base->PMCTRL;
reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK;
reg |= ((uint8_t)kSMC_StopVlls << SMC_PMCTRL_STOPM_SHIFT);
base->PMCTRL = reg;
/* configure the VLLS sub-mode */
#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG)
reg = base->VLLSCTRL;
reg &= ~SMC_VLLSCTRL_VLLSM_MASK;
reg |= ((uint8_t)config->subMode << SMC_VLLSCTRL_VLLSM_SHIFT);
base->VLLSCTRL = reg;
#else
#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE)
reg = base->STOPCTRL;
reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK;
reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT);
base->STOPCTRL = reg;
#else
reg = base->STOPCTRL;
reg &= ~SMC_STOPCTRL_VLLSM_MASK;
reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT);
base->STOPCTRL = reg;
#endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */
#endif
#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)
if (config->enableLpoClock)
{
base->STOPCTRL &= ~SMC_STOPCTRL_LPOPO_MASK;
}
else
{
base->STOPCTRL |= SMC_STOPCTRL_LPOPO_MASK;
}
#endif /* FSL_FEATURE_SMC_HAS_LPOPO */
/* Set the SLEEPDEEP bit to enable deep sleep mode */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
/* read back to make sure the configuration valid before enter stop mode */
(void)base->PMCTRL;
SMC_EnterStopRamFunc();
/* check whether the power mode enter LLS mode succeed */
if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK))
{
return kStatus_SMC_StopAbort;
}
else
{
return kStatus_Success;
}
}
#endif /* FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE */

View File

@ -1,421 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_SMC_H_
#define _FSL_SMC_H_
#include "fsl_common.h"
/*! @addtogroup smc */
/*! @{ */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief SMC driver version 2.0.5. */
#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 5))
/*@}*/
/*!
* @brief Power Modes Protection
*/
typedef enum _smc_power_mode_protection
{
#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-low-leakage Stop Mode. */
#endif
#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE)
kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-leakage Stop Mode. */
#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */
kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-power Mode. */
#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE)
kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High-speed Run mode. */
#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
kSMC_AllowPowerModeAll = (0U
#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
| SMC_PMPROT_AVLLS_MASK
#endif
#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE)
| SMC_PMPROT_ALLS_MASK
#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */
| SMC_PMPROT_AVLP_MASK
#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE)
| kSMC_AllowPowerModeHsrun
#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
) /*!< Allow all power mode. */
} smc_power_mode_protection_t;
/*!
* @brief Power Modes in PMSTAT
*/
typedef enum _smc_power_state
{
kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */
kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */
kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */
kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */
kSMC_PowerStateVlps = 0x01U << 4U, /*!< 0001_0000 - Current power mode is VLPS */
#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE)
kSMC_PowerStateLls = 0x01U << 5U, /*!< 0010_0000 - Current power mode is LLS */
#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */
#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
kSMC_PowerStateVlls = 0x01U << 6U, /*!< 0100_0000 - Current power mode is VLLS */
#endif
#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE)
kSMC_PowerStateHsrun = 0x01U << 7U /*!< 1000_0000 - Current power mode is HSRUN */
#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
} smc_power_state_t;
/*!
* @brief Run mode definition
*/
typedef enum _smc_run_mode
{
kSMC_RunNormal = 0U, /*!< Normal RUN mode. */
kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */
#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE)
kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */
#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
} smc_run_mode_t;
/*!
* @brief Stop mode definition
*/
typedef enum _smc_stop_mode
{
kSMC_StopNormal = 0U, /*!< Normal STOP mode. */
kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */
#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE)
kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */
#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */
#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
kSMC_StopVlls = 4U /*!< Very-low-leakage Stop mode. */
#endif
} smc_stop_mode_t;
#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) || \
(defined(FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) && FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) || \
(defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE)
/*!
* @brief VLLS/LLS stop sub mode definition
*/
typedef enum _smc_stop_submode
{
kSMC_StopSub0 = 0U, /*!< Stop submode 0, for VLLS0/LLS0. */
kSMC_StopSub1 = 1U, /*!< Stop submode 1, for VLLS1/LLS1. */
kSMC_StopSub2 = 2U, /*!< Stop submode 2, for VLLS2/LLS2. */
kSMC_StopSub3 = 3U /*!< Stop submode 3, for VLLS3/LLS3. */
} smc_stop_submode_t;
#endif
/*!
* @brief Partial STOP option
*/
typedef enum _smc_partial_stop_mode
{
kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/
kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/
kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/
} smc_partial_stop_option_t;
/*!
* @brief SMC configuration status.
*/
enum _smc_status
{
kStatus_SMC_StopAbort = MAKE_STATUS(kStatusGroup_POWER, 0) /*!< Entering Stop mode is abort*/
};
#if (defined(FSL_FEATURE_SMC_HAS_VERID) && FSL_FEATURE_SMC_HAS_VERID)
/*!
* @brief IP version ID definition.
*/
typedef struct _smc_version_id
{
uint16_t feature; /*!< Feature Specification Number. */
uint8_t minor; /*!< Minor version number. */
uint8_t major; /*!< Major version number. */
} smc_version_id_t;
#endif /* FSL_FEATURE_SMC_HAS_VERID */
#if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM)
/*!
* @brief IP parameter definition.
*/
typedef struct _smc_param
{
bool hsrunEnable; /*!< HSRUN mode enable. */
bool llsEnable; /*!< LLS mode enable. */
bool lls2Enable; /*!< LLS2 mode enable. */
bool vlls0Enable; /*!< VLLS0 mode enable. */
} smc_param_t;
#endif /* FSL_FEATURE_SMC_HAS_PARAM */
#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \
(defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)
/*!
* @brief SMC Low-Leakage Stop power mode configuration.
*/
typedef struct _smc_power_mode_lls_config
{
#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE)
smc_stop_submode_t subMode; /*!< Low-leakage Stop sub-mode */
#endif
#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)
bool enableLpoClock; /*!< Enable LPO clock in LLS mode */
#endif
} smc_power_mode_lls_config_t;
#endif /* (FSL_FEATURE_SMC_HAS_LLS_SUBMODE || FSL_FEATURE_SMC_HAS_LPOPO) */
#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
/*!
* @brief SMC Very Low-Leakage Stop power mode configuration.
*/
typedef struct _smc_power_mode_vlls_config
{
#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) || \
(defined(FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) && FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) || \
(defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE)
smc_stop_submode_t subMode; /*!< Very Low-leakage Stop sub-mode */
#endif
#if (defined(FSL_FEATURE_SMC_HAS_PORPO) && FSL_FEATURE_SMC_HAS_PORPO)
bool enablePorDetectInVlls0; /*!< Enable Power on reset detect in VLLS mode */
#endif
#if (defined(FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) && FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION)
bool enableRam2InVlls2; /*!< Enable RAM2 power in VLLS2 */
#endif
#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)
bool enableLpoClock; /*!< Enable LPO clock in VLLS mode */
#endif
} smc_power_mode_vlls_config_t;
#endif
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*! @name System mode controller APIs*/
/*@{*/
#if (defined(FSL_FEATURE_SMC_HAS_VERID) && FSL_FEATURE_SMC_HAS_VERID)
/*!
* @brief Gets the SMC version ID.
*
* This function gets the SMC version ID, including major version number,
* minor version number, and feature specification number.
*
* @param base SMC peripheral base address.
* @param versionId Pointer to the version ID structure.
*/
static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId)
{
*((uint32_t *)versionId) = base->VERID;
}
#endif /* FSL_FEATURE_SMC_HAS_VERID */
#if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM)
/*!
* @brief Gets the SMC parameter.
*
* This function gets the SMC parameter including the enabled power mdoes.
*
* @param base SMC peripheral base address.
* @param param Pointer to the SMC param structure.
*/
void SMC_GetParam(SMC_Type *base, smc_param_t *param);
#endif
/*!
* @brief Configures all power mode protection settings.
*
* This function configures the power mode protection settings for
* supported power modes in the specified chip family. The available power modes
* are defined in the smc_power_mode_protection_t. This should be done at an early
* system level initialization stage. See the reference manual for details.
* This register can only write once after the power reset.
*
* The allowed modes are passed as bit map. For example, to allow LLS and VLLS,
* use SMC_SetPowerModeProtection(kSMC_AllowPowerModeVlls | kSMC_AllowPowerModeVlps).
* To allow all modes, use SMC_SetPowerModeProtection(kSMC_AllowPowerModeAll).
*
* @param base SMC peripheral base address.
* @param allowedModes Bitmap of the allowed power modes.
*/
static inline void SMC_SetPowerModeProtection(SMC_Type *base, uint8_t allowedModes)
{
base->PMPROT = allowedModes;
}
/*!
* @brief Gets the current power mode status.
*
* This function returns the current power mode status. After the application
* switches the power mode, it should always check the status to check whether it
* runs into the specified mode or not. The application should check
* this mode before switching to a different mode. The system requires that
* only certain modes can switch to other specific modes. See the
* reference manual for details and the smc_power_state_t for information about
* the power status.
*
* @param base SMC peripheral base address.
* @return Current power mode status.
*/
static inline smc_power_state_t SMC_GetPowerModeState(SMC_Type *base)
{
return (smc_power_state_t)base->PMSTAT;
}
/*!
* @brief Prepares to enter stop modes.
*
* This function should be called before entering STOP/VLPS/LLS/VLLS modes.
*/
void SMC_PreEnterStopModes(void);
/*!
* @brief Recovers after wake up from stop modes.
*
* This function should be called after wake up from STOP/VLPS/LLS/VLLS modes.
* It is used with @ref SMC_PreEnterStopModes.
*/
void SMC_PostExitStopModes(void);
/*!
* @brief Prepares to enter wait modes.
*
* This function should be called before entering WAIT/VLPW modes.
*/
void SMC_PreEnterWaitModes(void);
/*!
* @brief Recovers after wake up from stop modes.
*
* This function should be called after wake up from WAIT/VLPW modes.
* It is used with @ref SMC_PreEnterWaitModes.
*/
void SMC_PostExitWaitModes(void);
/*!
* @brief Configures the system to RUN power mode.
*
* @param base SMC peripheral base address.
* @return SMC configuration error code.
*/
status_t SMC_SetPowerModeRun(SMC_Type *base);
#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE)
/*!
* @brief Configures the system to HSRUN power mode.
*
* @param base SMC peripheral base address.
* @return SMC configuration error code.
*/
status_t SMC_SetPowerModeHsrun(SMC_Type *base);
#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
/*!
* @brief Configures the system to WAIT power mode.
*
* @param base SMC peripheral base address.
* @return SMC configuration error code.
*/
status_t SMC_SetPowerModeWait(SMC_Type *base);
/*!
* @brief Configures the system to Stop power mode.
*
* @param base SMC peripheral base address.
* @param option Partial Stop mode option.
* @return SMC configuration error code.
*/
status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option);
#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI)
/*!
* @brief Configures the system to VLPR power mode.
*
* @param base SMC peripheral base address.
* @param wakeupMode Enter Normal Run mode if true, else stay in VLPR mode.
* @return SMC configuration error code.
*/
status_t SMC_SetPowerModeVlpr(SMC_Type *base, bool wakeupMode);
#else
/*!
* @brief Configures the system to VLPR power mode.
*
* @param base SMC peripheral base address.
* @return SMC configuration error code.
*/
status_t SMC_SetPowerModeVlpr(SMC_Type *base);
#endif /* FSL_FEATURE_SMC_HAS_LPWUI */
/*!
* @brief Configures the system to VLPW power mode.
*
* @param base SMC peripheral base address.
* @return SMC configuration error code.
*/
status_t SMC_SetPowerModeVlpw(SMC_Type *base);
/*!
* @brief Configures the system to VLPS power mode.
*
* @param base SMC peripheral base address.
* @return SMC configuration error code.
*/
status_t SMC_SetPowerModeVlps(SMC_Type *base);
#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE)
#if ((defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \
(defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO))
/*!
* @brief Configures the system to LLS power mode.
*
* @param base SMC peripheral base address.
* @param config The LLS power mode configuration structure
* @return SMC configuration error code.
*/
status_t SMC_SetPowerModeLls(SMC_Type *base, const smc_power_mode_lls_config_t *config);
#else
/*!
* @brief Configures the system to LLS power mode.
*
* @param base SMC peripheral base address.
* @return SMC configuration error code.
*/
status_t SMC_SetPowerModeLls(SMC_Type *base);
#endif
#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */
#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
/*!
* @brief Configures the system to VLLS power mode.
*
* @param base SMC peripheral base address.
* @param config The VLLS power mode configuration structure.
* @return SMC configuration error code.
*/
status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config);
#endif /* FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE */
/*@}*/
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/*! @}*/
#endif /* _FSL_SMC_H_ */

View File

@ -1,708 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_SPI_H_
#define _FSL_SPI_H_
#include "fsl_common.h"
/*!
* @addtogroup spi_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief SPI driver version 2.0.4. */
#define FSL_SPI_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
/*@}*/
#ifndef SPI_DUMMYDATA
/*! @brief SPI dummy transfer data, the data is sent while txBuff is NULL. */
#define SPI_DUMMYDATA (0xFFU)
#endif
/*! @brief Global variable for dummy data value setting. */
extern volatile uint8_t g_spiDummyData[];
/*! @brief Return status for the SPI driver.*/
enum _spi_status
{
kStatus_SPI_Busy = MAKE_STATUS(kStatusGroup_SPI, 0), /*!< SPI bus is busy */
kStatus_SPI_Idle = MAKE_STATUS(kStatusGroup_SPI, 1), /*!< SPI is idle */
kStatus_SPI_Error = MAKE_STATUS(kStatusGroup_SPI, 2) /*!< SPI error */
};
/*! @brief SPI clock polarity configuration.*/
typedef enum _spi_clock_polarity
{
kSPI_ClockPolarityActiveHigh = 0x0U, /*!< Active-high SPI clock (idles low). */
kSPI_ClockPolarityActiveLow /*!< Active-low SPI clock (idles high). */
} spi_clock_polarity_t;
/*! @brief SPI clock phase configuration.*/
typedef enum _spi_clock_phase
{
kSPI_ClockPhaseFirstEdge = 0x0U, /*!< First edge on SPSCK occurs at the middle of the first
* cycle of a data transfer. */
kSPI_ClockPhaseSecondEdge /*!< First edge on SPSCK occurs at the start of the
* first cycle of a data transfer. */
} spi_clock_phase_t;
/*! @brief SPI data shifter direction options.*/
typedef enum _spi_shift_direction
{
kSPI_MsbFirst = 0x0U, /*!< Data transfers start with most significant bit. */
kSPI_LsbFirst /*!< Data transfers start with least significant bit. */
} spi_shift_direction_t;
/*! @brief SPI slave select output mode options.*/
typedef enum _spi_ss_output_mode
{
kSPI_SlaveSelectAsGpio = 0x0U, /*!< Slave select pin configured as GPIO. */
kSPI_SlaveSelectFaultInput = 0x2U, /*!< Slave select pin configured for fault detection. */
kSPI_SlaveSelectAutomaticOutput = 0x3U /*!< Slave select pin configured for automatic SPI output. */
} spi_ss_output_mode_t;
/*! @brief SPI pin mode options.*/
typedef enum _spi_pin_mode
{
kSPI_PinModeNormal = 0x0U, /*!< Pins operate in normal, single-direction mode.*/
kSPI_PinModeInput = 0x1U, /*!< Bidirectional mode. Master: MOSI pin is input;
* Slave: MISO pin is input. */
kSPI_PinModeOutput = 0x3U /*!< Bidirectional mode. Master: MOSI pin is output;
* Slave: MISO pin is output. */
} spi_pin_mode_t;
/*! @brief SPI data length mode options.*/
typedef enum _spi_data_bitcount_mode
{
kSPI_8BitMode = 0x0U, /*!< 8-bit data transmission mode*/
kSPI_16BitMode /*!< 16-bit data transmission mode*/
} spi_data_bitcount_mode_t;
/*! @brief SPI interrupt sources.*/
enum _spi_interrupt_enable
{
kSPI_RxFullAndModfInterruptEnable = 0x1U, /*!< Receive buffer full (SPRF) and mode fault (MODF) interrupt */
kSPI_TxEmptyInterruptEnable = 0x2U, /*!< Transmit buffer empty interrupt */
kSPI_MatchInterruptEnable = 0x4U, /*!< Match interrupt */
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kSPI_RxFifoNearFullInterruptEnable = 0x8U, /*!< Receive FIFO nearly full interrupt */
kSPI_TxFifoNearEmptyInterruptEnable = 0x10U, /*!< Transmit FIFO nearly empty interrupt */
#endif /* FSL_FEATURE_SPI_HAS_FIFO */
};
/*! @brief SPI status flags.*/
enum _spi_flags
{
kSPI_RxBufferFullFlag = SPI_S_SPRF_MASK, /*!< Read buffer full flag */
kSPI_MatchFlag = SPI_S_SPMF_MASK, /*!< Match flag */
kSPI_TxBufferEmptyFlag = SPI_S_SPTEF_MASK, /*!< Transmit buffer empty flag */
kSPI_ModeFaultFlag = SPI_S_MODF_MASK, /*!< Mode fault flag */
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kSPI_RxFifoNearFullFlag = SPI_S_RNFULLF_MASK, /*!< Rx FIFO near full */
kSPI_TxFifoNearEmptyFlag = SPI_S_TNEAREF_MASK, /*!< Tx FIFO near empty */
kSPI_TxFifoFullFlag = SPI_S_TXFULLF_MASK, /*!< Tx FIFO full */
kSPI_RxFifoEmptyFlag = SPI_S_RFIFOEF_MASK, /*!< Rx FIFO empty */
kSPI_TxFifoError = SPI_CI_TXFERR_MASK << 8U, /*!< Tx FIFO error */
kSPI_RxFifoError = SPI_CI_RXFERR_MASK << 8U, /*!< Rx FIFO error */
kSPI_TxOverflow = SPI_CI_TXFOF_MASK << 8U, /*!< Tx FIFO Overflow */
kSPI_RxOverflow = SPI_CI_RXFOF_MASK << 8U /*!< Rx FIFO Overflow */
#endif /* FSL_FEATURE_SPI_HAS_FIFO */
};
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
/*! @brief SPI FIFO write-1-to-clear interrupt flags.*/
typedef enum _spi_w1c_interrupt
{
kSPI_RxFifoFullClearInterrupt = SPI_CI_SPRFCI_MASK, /*!< Receive FIFO full interrupt */
kSPI_TxFifoEmptyClearInterrupt = SPI_CI_SPTEFCI_MASK, /*!< Transmit FIFO empty interrupt */
kSPI_RxNearFullClearInterrupt = SPI_CI_RNFULLFCI_MASK, /*!< Receive FIFO nearly full interrupt */
kSPI_TxNearEmptyClearInterrupt = SPI_CI_TNEAREFCI_MASK /*!< Transmit FIFO nearly empty interrupt */
} spi_w1c_interrupt_t;
/*! @brief SPI TX FIFO watermark settings.*/
typedef enum _spi_txfifo_watermark
{
kSPI_TxFifoOneFourthEmpty = 0, /*!< SPI tx watermark at 1/4 FIFO size */
kSPI_TxFifoOneHalfEmpty = 1 /*!< SPI tx watermark at 1/2 FIFO size */
} spi_txfifo_watermark_t;
/*! @brief SPI RX FIFO watermark settings.*/
typedef enum _spi_rxfifo_watermark
{
kSPI_RxFifoThreeFourthsFull = 0, /*!< SPI rx watermark at 3/4 FIFO size */
kSPI_RxFifoOneHalfFull = 1 /*!< SPI rx watermark at 1/2 FIFO size */
} spi_rxfifo_watermark_t;
#endif /* FSL_FEATURE_SPI_HAS_FIFO */
#if defined(FSL_FEATURE_SPI_HAS_DMA_SUPPORT) && FSL_FEATURE_SPI_HAS_DMA_SUPPORT
/*! @brief SPI DMA source*/
enum _spi_dma_enable_t
{
kSPI_TxDmaEnable = SPI_C2_TXDMAE_MASK, /*!< Tx DMA request source */
kSPI_RxDmaEnable = SPI_C2_RXDMAE_MASK, /*!< Rx DMA request source */
kSPI_DmaAllEnable = (SPI_C2_TXDMAE_MASK | SPI_C2_RXDMAE_MASK) /*!< All DMA request source*/
};
#endif /* FSL_FEATURE_SPI_HAS_DMA_SUPPORT */
/*! @brief SPI master user configure structure.*/
typedef struct _spi_master_config
{
bool enableMaster; /*!< Enable SPI at initialization time */
bool enableStopInWaitMode; /*!< SPI stop in wait mode */
spi_clock_polarity_t polarity; /*!< Clock polarity */
spi_clock_phase_t phase; /*!< Clock phase */
spi_shift_direction_t direction; /*!< MSB or LSB */
#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
spi_data_bitcount_mode_t dataMode; /*!< 8bit or 16bit mode */
#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
spi_txfifo_watermark_t txWatermark; /*!< Tx watermark settings */
spi_rxfifo_watermark_t rxWatermark; /*!< Rx watermark settings */
#endif /* FSL_FEATURE_SPI_HAS_FIFO */
spi_ss_output_mode_t outputMode; /*!< SS pin setting */
spi_pin_mode_t pinMode; /*!< SPI pin mode select */
uint32_t baudRate_Bps; /*!< Baud Rate for SPI in Hz */
} spi_master_config_t;
/*! @brief SPI slave user configure structure.*/
typedef struct _spi_slave_config
{
bool enableSlave; /*!< Enable SPI at initialization time */
bool enableStopInWaitMode; /*!< SPI stop in wait mode */
spi_clock_polarity_t polarity; /*!< Clock polarity */
spi_clock_phase_t phase; /*!< Clock phase */
spi_shift_direction_t direction; /*!< MSB or LSB */
#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
spi_data_bitcount_mode_t dataMode; /*!< 8bit or 16bit mode */
#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
spi_txfifo_watermark_t txWatermark; /*!< Tx watermark settings */
spi_rxfifo_watermark_t rxWatermark; /*!< Rx watermark settings */
#endif /* FSL_FEATURE_SPI_HAS_FIFO */
spi_pin_mode_t pinMode; /*!< SPI pin mode select */
} spi_slave_config_t;
/*! @brief SPI transfer structure */
typedef struct _spi_transfer
{
uint8_t *txData; /*!< Send buffer */
uint8_t *rxData; /*!< Receive buffer */
size_t dataSize; /*!< Transfer bytes */
uint32_t flags; /*!< SPI control flag, useless to SPI.*/
} spi_transfer_t;
typedef struct _spi_master_handle spi_master_handle_t;
/*! @brief Slave handle is the same with master handle */
typedef spi_master_handle_t spi_slave_handle_t;
/*! @brief SPI master callback for finished transmit */
typedef void (*spi_master_callback_t)(SPI_Type *base, spi_master_handle_t *handle, status_t status, void *userData);
/*! @brief SPI master callback for finished transmit */
typedef void (*spi_slave_callback_t)(SPI_Type *base, spi_slave_handle_t *handle, status_t status, void *userData);
/*! @brief SPI transfer handle structure */
struct _spi_master_handle
{
uint8_t *volatile txData; /*!< Transfer buffer */
uint8_t *volatile rxData; /*!< Receive buffer */
volatile size_t txRemainingBytes; /*!< Send data remaining in bytes */
volatile size_t rxRemainingBytes; /*!< Receive data remaining in bytes */
volatile uint32_t state; /*!< SPI internal state */
size_t transferSize; /*!< Bytes to be transferred */
uint8_t bytePerFrame; /*!< SPI mode, 2bytes or 1byte in a frame */
uint8_t watermark; /*!< Watermark value for SPI transfer */
spi_master_callback_t callback; /*!< SPI callback */
void *userData; /*!< Callback parameter */
};
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* APIs
******************************************************************************/
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Sets the SPI master configuration structure to default values.
*
* The purpose of this API is to get the configuration structure initialized for use in SPI_MasterInit().
* User may use the initialized structure unchanged in SPI_MasterInit(), or modify
* some fields of the structure before calling SPI_MasterInit(). After calling this API,
* the master is ready to transfer.
* Example:
@code
spi_master_config_t config;
SPI_MasterGetDefaultConfig(&config);
@endcode
*
* @param config pointer to master config structure
*/
void SPI_MasterGetDefaultConfig(spi_master_config_t *config);
/*!
* @brief Initializes the SPI with master configuration.
*
* The configuration structure can be filled by user from scratch, or be set with default
* values by SPI_MasterGetDefaultConfig(). After calling this API, the slave is ready to transfer.
* Example
@code
spi_master_config_t config = {
.baudRate_Bps = 400000,
...
};
SPI_MasterInit(SPI0, &config);
@endcode
*
* @param base SPI base pointer
* @param config pointer to master configuration structure
* @param srcClock_Hz Source clock frequency.
*/
void SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz);
/*!
* @brief Sets the SPI slave configuration structure to default values.
*
* The purpose of this API is to get the configuration structure initialized for use in SPI_SlaveInit().
* Modify some fields of the structure before calling SPI_SlaveInit().
* Example:
@code
spi_slave_config_t config;
SPI_SlaveGetDefaultConfig(&config);
@endcode
*
* @param config pointer to slave configuration structure
*/
void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config);
/*!
* @brief Initializes the SPI with slave configuration.
*
* The configuration structure can be filled by user from scratch or be set with
* default values by SPI_SlaveGetDefaultConfig().
* After calling this API, the slave is ready to transfer.
* Example
@code
spi_slave_config_t config = {
.polarity = kSPIClockPolarity_ActiveHigh;
.phase = kSPIClockPhase_FirstEdge;
.direction = kSPIMsbFirst;
...
};
SPI_MasterInit(SPI0, &config);
@endcode
*
* @param base SPI base pointer
* @param config pointer to master configuration structure
*/
void SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config);
/*!
* @brief De-initializes the SPI.
*
* Calling this API resets the SPI module, gates the SPI clock.
* The SPI module can't work unless calling the SPI_MasterInit/SPI_SlaveInit to initialize module.
*
* @param base SPI base pointer
*/
void SPI_Deinit(SPI_Type *base);
/*!
* @brief Enables or disables the SPI.
*
* @param base SPI base pointer
* @param enable pass true to enable module, false to disable module
*/
static inline void SPI_Enable(SPI_Type *base, bool enable)
{
if (enable)
{
base->C1 |= SPI_C1_SPE_MASK;
}
else
{
base->C1 &= ~SPI_C1_SPE_MASK;
}
}
/*! @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Gets the status flag.
*
* @param base SPI base pointer
* @return SPI Status, use status flag to AND #_spi_flags could get the related status.
*/
uint32_t SPI_GetStatusFlags(SPI_Type *base);
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
/*!
* @brief Clear the interrupt if enable INCTLR.
*
* @param base SPI base pointer
* @param interrupt Interrupt need to be cleared
* The parameter could be any combination of the following values:
* @arg kSPIRxFifoFullClearInt
* @arg kSPITxFifoEmptyClearInt
* @arg kSPIRxNearFullClearInt
* @arg kSPITxNearEmptyClearInt
*/
static inline void SPI_ClearInterrupt(SPI_Type *base, uint32_t mask)
{
base->CI |= mask;
}
#endif /* FSL_FEATURE_SPI_HAS_FIFO */
/*! @} */
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables the interrupt for the SPI.
*
* @param base SPI base pointer
* @param mask SPI interrupt source. The parameter can be any combination of the following values:
* @arg kSPI_RxFullAndModfInterruptEnable
* @arg kSPI_TxEmptyInterruptEnable
* @arg kSPI_MatchInterruptEnable
* @arg kSPI_RxFifoNearFullInterruptEnable
* @arg kSPI_TxFifoNearEmptyInterruptEnable
*/
void SPI_EnableInterrupts(SPI_Type *base, uint32_t mask);
/*!
* @brief Disables the interrupt for the SPI.
*
* @param base SPI base pointer
* @param mask SPI interrupt source. The parameter can be any combination of the following values:
* @arg kSPI_RxFullAndModfInterruptEnable
* @arg kSPI_TxEmptyInterruptEnable
* @arg kSPI_MatchInterruptEnable
* @arg kSPI_RxFifoNearFullInterruptEnable
* @arg kSPI_TxFifoNearEmptyInterruptEnable
*/
void SPI_DisableInterrupts(SPI_Type *base, uint32_t mask);
/*! @} */
/*!
* @name DMA Control
* @{
*/
#if defined(FSL_FEATURE_SPI_HAS_DMA_SUPPORT) && FSL_FEATURE_SPI_HAS_DMA_SUPPORT
/*!
* @brief Enables the DMA source for SPI.
*
* @param base SPI base pointer
* @param source SPI DMA source.
* @param enable True means enable DMA, false means disable DMA
*/
static inline void SPI_EnableDMA(SPI_Type *base, uint32_t mask, bool enable)
{
if (enable)
{
base->C2 |= mask;
}
else
{
base->C2 &= ~mask;
}
}
#endif /* FSL_FEATURE_SPI_HAS_DMA_SUPPORT */
/*!
* @brief Gets the SPI tx/rx data register address.
*
* This API is used to provide a transfer address for the SPI DMA transfer configuration.
*
* @param base SPI base pointer
* @return data register address
*/
static inline uint32_t SPI_GetDataRegisterAddress(SPI_Type *base)
{
#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
return (uint32_t)(&(base->DL));
#else
return (uint32_t)(&(base->D));
#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
}
/*! @} */
/*!
* @name Bus Operations
* @{
*/
/*!
* @brief Get the instance for SPI module.
*
* @param base SPI base address
*/
uint32_t SPI_GetInstance(SPI_Type *base);
/*!
* @brief Sets the pin mode for transfer.
*
* @param base SPI base pointer
* @param pinMode pin mode for transfer AND #_spi_pin_mode could get the related configuration.
*/
static inline void SPI_SetPinMode(SPI_Type *base, spi_pin_mode_t pinMode)
{
/* Clear SPC0 and BIDIROE bit. */
base->C2 &= ~(SPI_C2_BIDIROE_MASK | SPI_C2_SPC0_MASK);
/* Set pin mode for transfer. */
base->C2 |= SPI_C2_BIDIROE(pinMode >> 1U) | SPI_C2_SPC0(pinMode & 1U);
}
/*!
* @brief Sets the baud rate for SPI transfer. This is only used in master.
*
* @param base SPI base pointer
* @param baudRate_Bps baud rate needed in Hz.
* @param srcClock_Hz SPI source clock frequency in Hz.
*/
void SPI_MasterSetBaudRate(SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
/*!
* @brief Sets the match data for SPI.
*
* The match data is a hardware comparison value. When the value received in the SPI receive data
* buffer equals the hardware comparison value, the SPI Match Flag in the S register (S[SPMF]) sets.
* This can also generate an interrupt if the enable bit sets.
*
* @param base SPI base pointer
* @param matchData Match data.
*/
static inline void SPI_SetMatchData(SPI_Type *base, uint32_t matchData)
{
#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
base->ML = matchData & 0xFFU;
base->MH = (matchData >> 8U) & 0xFFU;
#else
base->M = matchData;
#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
}
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
/*!
* @brief Enables or disables the FIFO if there is a FIFO.
*
* @param base SPI base pointer
* @param enable True means enable FIFO, false means disable FIFO.
*/
void SPI_EnableFIFO(SPI_Type *base, bool enable);
#endif
/*!
* @brief Sends a buffer of data bytes using a blocking method.
*
* @note This function blocks via polling until all bytes have been sent.
*
* @param base SPI base pointer
* @param buffer The data bytes to send
* @param size The number of data bytes to send
*/
void SPI_WriteBlocking(SPI_Type *base, uint8_t *buffer, size_t size);
/*!
* @brief Writes a data into the SPI data register.
*
* @param base SPI base pointer
* @param data needs to be write.
*/
void SPI_WriteData(SPI_Type *base, uint16_t data);
/*!
* @brief Gets a data from the SPI data register.
*
* @param base SPI base pointer
* @return Data in the register.
*/
uint16_t SPI_ReadData(SPI_Type *base);
/*!
* @brief Set up the dummy data.
*
* @param base SPI peripheral address.
* @param dummyData Data to be transferred when tx buffer is NULL.
*/
void SPI_SetDummyData(SPI_Type *base, uint8_t dummyData);
/*! @} */
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the SPI master handle.
*
* This function initializes the SPI master handle which can be used for other SPI master transactional APIs. Usually,
* for a specified SPI instance, call this API once to get the initialized handle.
*
* @param base SPI peripheral base address.
* @param handle SPI handle pointer.
* @param callback Callback function.
* @param userData User data.
*/
void SPI_MasterTransferCreateHandle(SPI_Type *base,
spi_master_handle_t *handle,
spi_master_callback_t callback,
void *userData);
/*!
* @brief Transfers a block of data using a polling method.
*
* @param base SPI base pointer
* @param xfer pointer to spi_xfer_config_t structure
* @retval kStatus_Success Successfully start a transfer.
* @retval kStatus_InvalidArgument Input argument is invalid.
*/
status_t SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer);
/*!
* @brief Performs a non-blocking SPI interrupt transfer.
*
* @note The API immediately returns after transfer initialization is finished.
* Call SPI_GetStatusIRQ() to get the transfer status.
* @note If SPI transfer data frame size is 16 bits, the transfer size cannot be an odd number.
*
* @param base SPI peripheral base address.
* @param handle pointer to spi_master_handle_t structure which stores the transfer state
* @param xfer pointer to spi_xfer_config_t structure
* @retval kStatus_Success Successfully start a transfer.
* @retval kStatus_InvalidArgument Input argument is invalid.
* @retval kStatus_SPI_Busy SPI is not idle, is running another transfer.
*/
status_t SPI_MasterTransferNonBlocking(SPI_Type *base, spi_master_handle_t *handle, spi_transfer_t *xfer);
/*!
* @brief Gets the bytes of the SPI interrupt transferred.
*
* @param base SPI peripheral base address.
* @param handle Pointer to SPI transfer handle, this should be a static variable.
* @param count Transferred bytes of SPI master.
* @retval kStatus_SPI_Success Succeed get the transfer count.
* @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
*/
status_t SPI_MasterTransferGetCount(SPI_Type *base, spi_master_handle_t *handle, size_t *count);
/*!
* @brief Aborts an SPI transfer using interrupt.
*
* @param base SPI peripheral base address.
* @param handle Pointer to SPI transfer handle, this should be a static variable.
*/
void SPI_MasterTransferAbort(SPI_Type *base, spi_master_handle_t *handle);
/*!
* @brief Interrupts the handler for the SPI.
*
* @param base SPI peripheral base address.
* @param handle pointer to spi_master_handle_t structure which stores the transfer state.
*/
void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle);
/*!
* @brief Initializes the SPI slave handle.
*
* This function initializes the SPI slave handle which can be used for other SPI slave transactional APIs. Usually,
* for a specified SPI instance, call this API once to get the initialized handle.
*
* @param base SPI peripheral base address.
* @param handle SPI handle pointer.
* @param callback Callback function.
* @param userData User data.
*/
void SPI_SlaveTransferCreateHandle(SPI_Type *base,
spi_slave_handle_t *handle,
spi_slave_callback_t callback,
void *userData);
/*!
* @brief Performs a non-blocking SPI slave interrupt transfer.
*
* @note The API returns immediately after the transfer initialization is finished.
* Call SPI_GetStatusIRQ() to get the transfer status.
* @note If SPI transfer data frame size is 16 bits, the transfer size cannot be an odd number.
*
* @param base SPI peripheral base address.
* @param handle pointer to spi_master_handle_t structure which stores the transfer state
* @param xfer pointer to spi_xfer_config_t structure
* @retval kStatus_Success Successfully start a transfer.
* @retval kStatus_InvalidArgument Input argument is invalid.
* @retval kStatus_SPI_Busy SPI is not idle, is running another transfer.
*/
static inline status_t SPI_SlaveTransferNonBlocking(SPI_Type *base, spi_slave_handle_t *handle, spi_transfer_t *xfer)
{
return SPI_MasterTransferNonBlocking(base, handle, xfer);
}
/*!
* @brief Gets the bytes of the SPI interrupt transferred.
*
* @param base SPI peripheral base address.
* @param handle Pointer to SPI transfer handle, this should be a static variable.
* @param count Transferred bytes of SPI slave.
* @retval kStatus_SPI_Success Succeed get the transfer count.
* @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
*/
static inline status_t SPI_SlaveTransferGetCount(SPI_Type *base, spi_slave_handle_t *handle, size_t *count)
{
return SPI_MasterTransferGetCount(base, handle, count);
}
/*!
* @brief Aborts an SPI slave transfer using interrupt.
*
* @param base SPI peripheral base address.
* @param handle Pointer to SPI transfer handle, this should be a static variable.
*/
static inline void SPI_SlaveTransferAbort(SPI_Type *base, spi_slave_handle_t *handle)
{
SPI_MasterTransferAbort(base, handle);
}
/*!
* @brief Interrupts a handler for the SPI slave.
*
* @param base SPI peripheral base address.
* @param handle pointer to spi_slave_handle_t structure which stores the transfer state
*/
void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle);
/*! @} */
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* _FSL_SPI_H_*/

View File

@ -1,345 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_spi_dma.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.spi_dma"
#endif
/*<! Structure definition for spi_dma_private_handle_t. The structure is private. */
typedef struct _spi_dma_private_handle
{
SPI_Type *base;
spi_dma_handle_t *handle;
} spi_dma_private_handle_t;
/*! @brief SPI transfer state, which is used for SPI transactiaonl APIs' internal state. */
enum _spi_dma_states_t
{
kSPI_Idle = 0x0, /*!< SPI is idle state */
kSPI_Busy /*!< SPI is busy tranferring data. */
};
/*<! Private handle only used for internally. */
static spi_dma_private_handle_t s_dmaPrivateHandle[FSL_FEATURE_SOC_SPI_COUNT];
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief DMA callback function for SPI send transfer.
*
* @param handle DMA handle pointer.
* @param userData User data for DMA callback function.
*/
static void SPI_TxDMACallback(dma_handle_t *handle, void *userData);
/*!
* @brief DMA callback function for SPI receive transfer.
*
* @param handle DMA handle pointer.
* @param userData User data for DMA callback function.
*/
static void SPI_RxDMACallback(dma_handle_t *handle, void *userData);
/*******************************************************************************
* Code
******************************************************************************/
static void SPI_TxDMACallback(dma_handle_t *handle, void *userData)
{
spi_dma_private_handle_t *privHandle = (spi_dma_private_handle_t *)userData;
spi_dma_handle_t *spiHandle = privHandle->handle;
SPI_Type *base = privHandle->base;
/* Disable Tx dma */
SPI_EnableDMA(base, kSPI_TxDmaEnable, false);
/* Stop DMA transfer */
DMA_StopTransfer(spiHandle->txHandle);
/* change the state */
spiHandle->txInProgress = false;
/* All finished, call the callback */
if ((spiHandle->txInProgress == false) && (spiHandle->rxInProgress == false))
{
spiHandle->state = kSPI_Idle;
if (spiHandle->callback)
{
(spiHandle->callback)(base, spiHandle, kStatus_Success, spiHandle->userData);
}
}
}
static void SPI_RxDMACallback(dma_handle_t *handle, void *userData)
{
spi_dma_private_handle_t *privHandle = (spi_dma_private_handle_t *)userData;
spi_dma_handle_t *spiHandle = privHandle->handle;
SPI_Type *base = privHandle->base;
/* Disable Tx dma */
SPI_EnableDMA(base, kSPI_RxDmaEnable, false);
/* Stop DMA transfer */
DMA_StopTransfer(spiHandle->rxHandle);
/* change the state */
spiHandle->rxInProgress = false;
/* All finished, call the callback */
if ((spiHandle->txInProgress == false) && (spiHandle->rxInProgress == false))
{
spiHandle->state = kSPI_Idle;
if (spiHandle->callback)
{
(spiHandle->callback)(base, spiHandle, kStatus_Success, spiHandle->userData);
}
}
}
/*!
* brief Initialize the SPI master DMA handle.
*
* This function initializes the SPI master DMA handle which can be used for other SPI master transactional APIs.
* Usually, for a specified SPI instance, user need only call this API once to get the initialized handle.
*
* param base SPI peripheral base address.
* param handle SPI handle pointer.
* param callback User callback function called at the end of a transfer.
* param userData User data for callback.
* param txHandle DMA handle pointer for SPI Tx, the handle shall be static allocated by users.
* param rxHandle DMA handle pointer for SPI Rx, the handle shall be static allocated by users.
*/
void SPI_MasterTransferCreateHandleDMA(SPI_Type *base,
spi_dma_handle_t *handle,
spi_dma_callback_t callback,
void *userData,
dma_handle_t *txHandle,
dma_handle_t *rxHandle)
{
assert(handle);
dma_transfer_config_t config = {0};
uint32_t instance = SPI_GetInstance(base);
/* Zero the handle */
memset(handle, 0, sizeof(*handle));
/* Set spi base to handle */
handle->txHandle = txHandle;
handle->rxHandle = rxHandle;
handle->callback = callback;
handle->userData = userData;
/* Set SPI state to idle */
handle->state = kSPI_Idle;
/* Set handle to global state */
s_dmaPrivateHandle[instance].base = base;
s_dmaPrivateHandle[instance].handle = handle;
/* Compute internal state */
#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && (FSL_FEATURE_SPI_16BIT_TRANSFERS)
handle->bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U;
#else
handle->bytesPerFrame = 1U;
#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && (FSL_FEATURE_SPI_HAS_FIFO)
/* If using DMA, disable FIFO, as the FIFO may cause data loss if the data size is not integer
times of 2bytes. As SPI cannot set watermark to 0, only can set to 1/2 FIFO size or 3/4 FIFO
size. */
if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0)
{
base->C3 &= ~SPI_C3_FIFOMODE_MASK;
}
#endif /* FSL_FEATURE_SPI_HAS_FIFO */
/* Set the non-change attribute for Tx DMA transfer, to improve efficiency */
config.destAddr = SPI_GetDataRegisterAddress(base);
config.enableDestIncrement = false;
config.enableSrcIncrement = true;
if (handle->bytesPerFrame == 1U)
{
config.srcSize = kDMA_Transfersize8bits;
config.destSize = kDMA_Transfersize8bits;
}
else
{
config.srcSize = kDMA_Transfersize16bits;
config.destSize = kDMA_Transfersize16bits;
}
DMA_SubmitTransfer(handle->txHandle, &config, true);
/* Set non-change attribute for Rx DMA */
config.srcAddr = SPI_GetDataRegisterAddress(base);
config.destAddr = 0U;
config.enableDestIncrement = true;
config.enableSrcIncrement = false;
DMA_SubmitTransfer(handle->rxHandle, &config, true);
/* Install callback for Tx dma channel */
DMA_SetCallback(handle->txHandle, SPI_TxDMACallback, &s_dmaPrivateHandle[instance]);
DMA_SetCallback(handle->rxHandle, SPI_RxDMACallback, &s_dmaPrivateHandle[instance]);
}
/*!
* brief Perform a non-blocking SPI transfer using DMA.
*
* note This interface returned immediately after transfer initiates, users should call
* SPI_GetTransferStatus to poll the transfer status to check whether SPI transfer finished.
*
* param base SPI peripheral base address.
* param handle SPI DMA handle pointer.
* param xfer Pointer to dma transfer structure.
* retval kStatus_Success Successfully start a transfer.
* retval kStatus_InvalidArgument Input argument is invalid.
* retval kStatus_SPI_Busy SPI is not idle, is running another transfer.
*/
status_t SPI_MasterTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer)
{
assert(handle && xfer);
dma_transfer_config_t config = {0};
/* Check if the device is busy */
if (handle->state == kSPI_Busy)
{
return kStatus_SPI_Busy;
}
/* Check if input parameter invalid */
if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U))
{
return kStatus_InvalidArgument;
}
/* Disable SPI and then enable it, this is used to clear S register*/
SPI_Enable(base, false);
SPI_Enable(base, true);
/* Configure tx transfer DMA */
config.destAddr = SPI_GetDataRegisterAddress(base);
config.enableDestIncrement = false;
if (handle->bytesPerFrame == 1U)
{
config.srcSize = kDMA_Transfersize8bits;
config.destSize = kDMA_Transfersize8bits;
}
else
{
config.srcSize = kDMA_Transfersize16bits;
config.destSize = kDMA_Transfersize16bits;
}
config.transferSize = xfer->dataSize;
/* Configure DMA channel */
if (xfer->txData)
{
config.enableSrcIncrement = true;
config.srcAddr = (uint32_t)(xfer->txData);
}
else
{
/* Disable the source increasement and source set to dummyData */
config.enableSrcIncrement = false;
config.srcAddr = (uint32_t)(&g_spiDummyData[SPI_GetInstance(base)]);
}
DMA_SubmitTransfer(handle->txHandle, &config, true);
/* Handle rx transfer */
if (xfer->rxData)
{
/* Set the source address */
DMA_SetDestinationAddress(handle->rxHandle->base, handle->rxHandle->channel, (uint32_t)(xfer->rxData));
/* Set the transfer size */
DMA_SetTransferSize(handle->rxHandle->base, handle->rxHandle->channel, xfer->dataSize);
}
/* Change the state of handle */
handle->transferSize = xfer->dataSize;
handle->state = kSPI_Busy;
/* Start Rx transfer if needed */
if (xfer->rxData)
{
handle->rxInProgress = true;
SPI_EnableDMA(base, kSPI_RxDmaEnable, true);
DMA_StartTransfer(handle->rxHandle);
}
/* Always start Tx transfer */
handle->txInProgress = true;
SPI_EnableDMA(base, kSPI_TxDmaEnable, true);
DMA_StartTransfer(handle->txHandle);
return kStatus_Success;
}
/*!
* brief Get the transferred bytes for SPI slave DMA.
*
* param base SPI peripheral base address.
* param handle SPI DMA handle pointer.
* param count Transferred bytes.
* retval kStatus_SPI_Success Succeed get the transfer count.
* retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
*/
status_t SPI_MasterTransferGetCountDMA(SPI_Type *base, spi_dma_handle_t *handle, size_t *count)
{
assert(handle);
status_t status = kStatus_Success;
if (handle->state != kSPI_Busy)
{
status = kStatus_NoTransferInProgress;
}
else
{
if (handle->rxInProgress)
{
*count = handle->transferSize - DMA_GetRemainingBytes(handle->rxHandle->base, handle->rxHandle->channel);
}
else
{
*count = handle->transferSize - DMA_GetRemainingBytes(handle->txHandle->base, handle->txHandle->channel);
}
}
return status;
}
/*!
* brief Abort a SPI transfer using DMA.
*
* param base SPI peripheral base address.
* param handle SPI DMA handle pointer.
*/
void SPI_MasterTransferAbortDMA(SPI_Type *base, spi_dma_handle_t *handle)
{
assert(handle);
/* Disable dma */
DMA_StopTransfer(handle->txHandle);
DMA_StopTransfer(handle->rxHandle);
/* Disable DMA enable bit */
SPI_EnableDMA(base, kSPI_DmaAllEnable, false);
/* Set the handle state */
handle->txInProgress = false;
handle->rxInProgress = false;
handle->state = kSPI_Idle;
}

View File

@ -1,189 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_SPI_DMA_H_
#define _FSL_SPI_DMA_H_
#include "fsl_spi.h"
#include "fsl_dma.h"
/*!
* @addtogroup spi_dma_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief SPI DMA driver version 2.0.4. */
#define FSL_SPI_DMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
/*@}*/
typedef struct _spi_dma_handle spi_dma_handle_t;
/*! @brief SPI DMA callback called at the end of transfer. */
typedef void (*spi_dma_callback_t)(SPI_Type *base, spi_dma_handle_t *handle, status_t status, void *userData);
/*! @brief SPI DMA transfer handle, users should not touch the content of the handle.*/
struct _spi_dma_handle
{
bool txInProgress; /*!< Send transfer finished */
bool rxInProgress; /*!< Receive transfer finished */
dma_handle_t *txHandle; /*!< DMA handler for SPI send */
dma_handle_t *rxHandle; /*!< DMA handler for SPI receive */
uint8_t bytesPerFrame; /*!< Bytes in a frame for SPI transfer */
spi_dma_callback_t callback; /*!< Callback for SPI DMA transfer */
void *userData; /*!< User Data for SPI DMA callback */
uint32_t state; /*!< Internal state of SPI DMA transfer */
size_t transferSize; /*!< Bytes need to be transfer */
};
/*******************************************************************************
* APIs
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name DMA Transactional
* @{
*/
/*!
* @brief Initialize the SPI master DMA handle.
*
* This function initializes the SPI master DMA handle which can be used for other SPI master transactional APIs.
* Usually, for a specified SPI instance, user need only call this API once to get the initialized handle.
*
* @param base SPI peripheral base address.
* @param handle SPI handle pointer.
* @param callback User callback function called at the end of a transfer.
* @param userData User data for callback.
* @param txHandle DMA handle pointer for SPI Tx, the handle shall be static allocated by users.
* @param rxHandle DMA handle pointer for SPI Rx, the handle shall be static allocated by users.
*/
void SPI_MasterTransferCreateHandleDMA(SPI_Type *base,
spi_dma_handle_t *handle,
spi_dma_callback_t callback,
void *userData,
dma_handle_t *txHandle,
dma_handle_t *rxHandle);
/*!
* @brief Perform a non-blocking SPI transfer using DMA.
*
* @note This interface returned immediately after transfer initiates, users should call
* SPI_GetTransferStatus to poll the transfer status to check whether SPI transfer finished.
*
* @param base SPI peripheral base address.
* @param handle SPI DMA handle pointer.
* @param xfer Pointer to dma transfer structure.
* @retval kStatus_Success Successfully start a transfer.
* @retval kStatus_InvalidArgument Input argument is invalid.
* @retval kStatus_SPI_Busy SPI is not idle, is running another transfer.
*/
status_t SPI_MasterTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer);
/*!
* @brief Abort a SPI transfer using DMA.
*
* @param base SPI peripheral base address.
* @param handle SPI DMA handle pointer.
*/
void SPI_MasterTransferAbortDMA(SPI_Type *base, spi_dma_handle_t *handle);
/*!
* @brief Get the transferred bytes for SPI slave DMA.
*
* @param base SPI peripheral base address.
* @param handle SPI DMA handle pointer.
* @param count Transferred bytes.
* @retval kStatus_SPI_Success Succeed get the transfer count.
* @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
*/
status_t SPI_MasterTransferGetCountDMA(SPI_Type *base, spi_dma_handle_t *handle, size_t *count);
/*!
* @brief Initialize the SPI slave DMA handle.
*
* This function initializes the SPI slave DMA handle which can be used for other SPI master transactional APIs.
* Usually, for a specified SPI instance, user need only call this API once to get the initialized handle.
*
* @param base SPI peripheral base address.
* @param handle SPI handle pointer.
* @param callback User callback function called at the end of a transfer.
* @param userData User data for callback.
* @param txHandle DMA handle pointer for SPI Tx, the handle shall be static allocated by users.
* @param rxHandle DMA handle pointer for SPI Rx, the handle shall be static allocated by users.
*/
static inline void SPI_SlaveTransferCreateHandleDMA(SPI_Type *base,
spi_dma_handle_t *handle,
spi_dma_callback_t callback,
void *userData,
dma_handle_t *txHandle,
dma_handle_t *rxHandle)
{
SPI_MasterTransferCreateHandleDMA(base, handle, callback, userData, txHandle, rxHandle);
}
/*!
* @brief Perform a non-blocking SPI transfer using DMA.
*
* @note This interface returned immediately after transfer initiates, users should call
* SPI_GetTransferStatus to poll the transfer status to check whether SPI transfer finished.
*
* @param base SPI peripheral base address.
* @param handle SPI DMA handle pointer.
* @param xfer Pointer to dma transfer structure.
* @retval kStatus_Success Successfully start a transfer.
* @retval kStatus_InvalidArgument Input argument is invalid.
* @retval kStatus_SPI_Busy SPI is not idle, is running another transfer.
*/
static inline status_t SPI_SlaveTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer)
{
return SPI_MasterTransferDMA(base, handle, xfer);
}
/*!
* @brief Abort a SPI transfer using DMA.
*
* @param base SPI peripheral base address.
* @param handle SPI DMA handle pointer.
*/
static inline void SPI_SlaveTransferAbortDMA(SPI_Type *base, spi_dma_handle_t *handle)
{
SPI_MasterTransferAbortDMA(base, handle);
}
/*!
* @brief Get the transferred bytes for SPI slave DMA.
*
* @param base SPI peripheral base address.
* @param handle SPI DMA handle pointer.
* @param count Transferred bytes.
* @retval kStatus_SPI_Success Succeed get the transfer count.
* @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
*/
static inline status_t SPI_SlaveTransferGetCountDMA(SPI_Type *base, spi_dma_handle_t *handle, size_t *count)
{
return SPI_MasterTransferGetCountDMA(base, handle, count);
}
/*! @} */
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif

View File

@ -1,725 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_tpm.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define TPM_COMBINE_SHIFT (8U)
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Gets the instance from the base address
*
* @param base TPM peripheral base address
*
* @return The TPM instance
*/
static uint32_t TPM_GetInstance(TPM_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to TPM bases for each instance. */
static TPM_Type *const s_tpmBases[] = TPM_BASE_PTRS;
/*! @brief Pointers to TPM clocks for each instance. */
static const clock_ip_name_t s_tpmClocks[] = TPM_CLOCKS;
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t TPM_GetInstance(TPM_Type *base)
{
uint32_t instance;
uint32_t tpmArrayCount = (sizeof(s_tpmBases) / sizeof(s_tpmBases[0]));
/* Find the instance index from base address mappings. */
for (instance = 0; instance < tpmArrayCount; instance++)
{
if (s_tpmBases[instance] == base)
{
break;
}
}
assert(instance < tpmArrayCount);
return instance;
}
void TPM_Init(TPM_Type *base, const tpm_config_t *config)
{
assert(config);
/* Enable the module clock */
CLOCK_EnableClock(s_tpmClocks[TPM_GetInstance(base)]);
#if defined(FSL_FEATURE_TPM_HAS_GLOBAL) && FSL_FEATURE_TPM_HAS_GLOBAL
/* TPM reset is available on certain SoC's */
TPM_Reset(base);
#endif
/* Set the clock prescale factor */
base->SC = TPM_SC_PS(config->prescale);
/* Setup the counter operation */
base->CONF = TPM_CONF_DOZEEN(config->enableDoze) | TPM_CONF_GTBEEN(config->useGlobalTimeBase) |
TPM_CONF_CROT(config->enableReloadOnTrigger) | TPM_CONF_CSOT(config->enableStartOnTrigger) |
TPM_CONF_CSOO(config->enableStopOnOverflow) |
#if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER
TPM_CONF_CPOT(config->enablePauseOnTrigger) |
#endif
#if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION
TPM_CONF_TRGSRC(config->triggerSource) |
#endif
TPM_CONF_TRGSEL(config->triggerSelect);
if (config->enableDebugMode)
{
base->CONF |= TPM_CONF_DBGMODE_MASK;
}
else
{
base->CONF &= ~TPM_CONF_DBGMODE_MASK;
}
}
void TPM_Deinit(TPM_Type *base)
{
/* Stop the counter */
base->SC &= ~TPM_SC_CMOD_MASK;
/* Gate the TPM clock */
CLOCK_DisableClock(s_tpmClocks[TPM_GetInstance(base)]);
}
void TPM_GetDefaultConfig(tpm_config_t *config)
{
assert(config);
/* TPM clock divide by 1 */
config->prescale = kTPM_Prescale_Divide_1;
/* Use internal TPM counter as timebase */
config->useGlobalTimeBase = false;
/* TPM counter continues in doze mode */
config->enableDoze = false;
/* TPM counter pauses when in debug mode */
config->enableDebugMode = false;
/* TPM counter will not be reloaded on input trigger */
config->enableReloadOnTrigger = false;
/* TPM counter continues running after overflow */
config->enableStopOnOverflow = false;
/* TPM counter starts immediately once it is enabled */
config->enableStartOnTrigger = false;
#if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER
config->enablePauseOnTrigger = false;
#endif
/* Choose trigger select 0 as input trigger for controlling counter operation */
config->triggerSelect = kTPM_Trigger_Select_0;
#if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION
/* Choose external trigger source to control counter operation */
config->triggerSource = kTPM_TriggerSource_External;
#endif
}
status_t TPM_SetupPwm(TPM_Type *base,
const tpm_chnl_pwm_signal_param_t *chnlParams,
uint8_t numOfChnls,
tpm_pwm_mode_t mode,
uint32_t pwmFreq_Hz,
uint32_t srcClock_Hz)
{
assert(chnlParams);
assert(pwmFreq_Hz);
assert(numOfChnls);
assert(srcClock_Hz);
uint32_t mod;
uint32_t tpmClock = (srcClock_Hz / (1U << (base->SC & TPM_SC_PS_MASK)));
uint16_t cnv;
uint8_t i;
#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
/* Clear quadrature Decoder mode because in quadrature Decoder mode PWM doesn't operate*/
base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
#endif
switch (mode)
{
case kTPM_EdgeAlignedPwm:
#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
case kTPM_CombinedPwm:
#endif
base->SC &= ~TPM_SC_CPWMS_MASK;
mod = (tpmClock / pwmFreq_Hz) - 1;
break;
case kTPM_CenterAlignedPwm:
base->SC |= TPM_SC_CPWMS_MASK;
mod = tpmClock / (pwmFreq_Hz * 2);
break;
default:
return kStatus_Fail;
}
/* Return an error in case we overflow the registers, probably would require changing
* clock source to get the desired frequency */
if (mod > 65535U)
{
return kStatus_Fail;
}
/* Set the PWM period */
base->MOD = mod;
/* Setup each TPM channel */
for (i = 0; i < numOfChnls; i++)
{
/* Return error if requested dutycycle is greater than the max allowed */
if (chnlParams->dutyCyclePercent > 100)
{
return kStatus_Fail;
}
#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
if (mode == kTPM_CombinedPwm)
{
uint16_t cnvFirstEdge;
/* This check is added for combined mode as the channel number should be the pair number */
if (chnlParams->chnlNumber >= (FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2))
{
return kStatus_Fail;
}
/* Return error if requested value is greater than the max allowed */
if (chnlParams->firstEdgeDelayPercent > 100)
{
return kStatus_Fail;
}
/* Configure delay of the first edge */
if (chnlParams->firstEdgeDelayPercent == 0)
{
/* No delay for the first edge */
cnvFirstEdge = 0;
}
else
{
cnvFirstEdge = (mod * chnlParams->firstEdgeDelayPercent) / 100;
}
/* Configure dutycycle */
if (chnlParams->dutyCyclePercent == 0)
{
/* Signal stays low */
cnv = 0;
cnvFirstEdge = 0;
}
else
{
cnv = (mod * chnlParams->dutyCyclePercent) / 100;
/* For 100% duty cycle */
if (cnv >= mod)
{
cnv = mod + 1;
}
}
/* Set the combine bit for the channel pair */
base->COMBINE |= (1U << (TPM_COMBINE_COMBINE0_SHIFT + (TPM_COMBINE_SHIFT * chnlParams->chnlNumber)));
/* When switching mode, disable channel n first */
base->CONTROLS[chnlParams->chnlNumber * 2].CnSC &=
~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
/* Wait till mode change to disable channel is acknowledged */
while ((base->CONTROLS[chnlParams->chnlNumber * 2].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
/* Set the requested PWM mode for channel n, PWM output requires mode select to be set to 2 */
base->CONTROLS[chnlParams->chnlNumber * 2].CnSC |=
((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT));
/* Wait till mode change is acknowledged */
while (!(base->CONTROLS[chnlParams->chnlNumber * 2].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
/* Set the channel pair values */
base->CONTROLS[chnlParams->chnlNumber * 2].CnV = cnvFirstEdge;
/* When switching mode, disable channel n + 1 first */
base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC &=
~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
/* Wait till mode change to disable channel is acknowledged */
while ((base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
/* Set the requested PWM mode for channel n + 1, PWM output requires mode select to be set to 2 */
base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC |=
((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT));
/* Wait till mode change is acknowledged */
while (!(base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
/* Set the channel pair values */
base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv;
}
else
{
#endif
if (chnlParams->dutyCyclePercent == 0)
{
/* Signal stays low */
cnv = 0;
}
else
{
cnv = (mod * chnlParams->dutyCyclePercent) / 100;
/* For 100% duty cycle */
if (cnv >= mod)
{
cnv = mod + 1;
}
}
/* When switching mode, disable channel first */
base->CONTROLS[chnlParams->chnlNumber].CnSC &=
~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
/* Wait till mode change to disable channel is acknowledged */
while ((base->CONTROLS[chnlParams->chnlNumber].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
/* Set the requested PWM mode, PWM output requires mode select to be set to 2 */
base->CONTROLS[chnlParams->chnlNumber].CnSC |=
((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT));
/* Wait till mode change is acknowledged */
while (!(base->CONTROLS[chnlParams->chnlNumber].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
base->CONTROLS[chnlParams->chnlNumber].CnV = cnv;
#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
}
#endif
chnlParams++;
}
return kStatus_Success;
}
void TPM_UpdatePwmDutycycle(TPM_Type *base,
tpm_chnl_t chnlNumber,
tpm_pwm_mode_t currentPwmMode,
uint8_t dutyCyclePercent)
{
assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base));
uint16_t cnv, mod;
mod = base->MOD;
#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
if (currentPwmMode == kTPM_CombinedPwm)
{
uint16_t cnvFirstEdge;
/* This check is added for combined mode as the channel number should be the pair number */
if (chnlNumber >= (FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2))
{
return;
}
cnv = (mod * dutyCyclePercent) / 100;
cnvFirstEdge = base->CONTROLS[chnlNumber * 2].CnV;
/* For 100% duty cycle */
if (cnv >= mod)
{
cnv = mod + 1;
}
base->CONTROLS[(chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv;
}
else
{
#endif
cnv = (mod * dutyCyclePercent) / 100;
/* For 100% duty cycle */
if (cnv >= mod)
{
cnv = mod + 1;
}
base->CONTROLS[chnlNumber].CnV = cnv;
#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
}
#endif
}
void TPM_UpdateChnlEdgeLevelSelect(TPM_Type *base, tpm_chnl_t chnlNumber, uint8_t level)
{
assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base));
uint32_t reg = base->CONTROLS[chnlNumber].CnSC & ~(TPM_CnSC_CHF_MASK);
/* When switching mode, disable channel first */
base->CONTROLS[chnlNumber].CnSC &=
~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
/* Wait till mode change to disable channel is acknowledged */
while ((base->CONTROLS[chnlNumber].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
/* Clear the field and write the new level value */
reg &= ~(TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
reg |= ((uint32_t)level << TPM_CnSC_ELSA_SHIFT) & (TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
base->CONTROLS[chnlNumber].CnSC = reg;
/* Wait till mode change is acknowledged */
reg &= (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
while (reg != (base->CONTROLS[chnlNumber].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
}
void TPM_SetupInputCapture(TPM_Type *base, tpm_chnl_t chnlNumber, tpm_input_capture_edge_t captureMode)
{
assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base));
#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
/* Clear quadrature Decoder mode for channel 0 or 1*/
if ((chnlNumber == 0) || (chnlNumber == 1))
{
base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
}
#endif
#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
/* Clear the combine bit for chnlNumber */
base->COMBINE &= ~(1U << TPM_COMBINE_SHIFT * (chnlNumber / 2));
#endif
/* When switching mode, disable channel first */
base->CONTROLS[chnlNumber].CnSC &=
~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
/* Wait till mode change to disable channel is acknowledged */
while ((base->CONTROLS[chnlNumber].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
/* Set the requested input capture mode */
base->CONTROLS[chnlNumber].CnSC |= captureMode;
/* Wait till mode change is acknowledged */
while (!(base->CONTROLS[chnlNumber].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
}
void TPM_SetupOutputCompare(TPM_Type *base,
tpm_chnl_t chnlNumber,
tpm_output_compare_mode_t compareMode,
uint32_t compareValue)
{
assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base));
#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
/* Clear quadrature Decoder mode for channel 0 or 1 */
if ((chnlNumber == 0) || (chnlNumber == 1))
{
base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
}
#endif
/* When switching mode, disable channel first */
base->CONTROLS[chnlNumber].CnSC &=
~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
/* Wait till mode change to disable channel is acknowledged */
while ((base->CONTROLS[chnlNumber].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
/* Setup the channel output behaviour when a match occurs with the compare value */
base->CONTROLS[chnlNumber].CnSC |= compareMode;
/* Setup the compare value */
base->CONTROLS[chnlNumber].CnV = compareValue;
/* Wait till mode change is acknowledged */
while (!(base->CONTROLS[chnlNumber].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
}
#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
void TPM_SetupDualEdgeCapture(TPM_Type *base,
tpm_chnl_t chnlPairNumber,
const tpm_dual_edge_capture_param_t *edgeParam,
uint32_t filterValue)
{
assert(edgeParam);
assert(chnlPairNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2);
uint32_t reg;
/* Clear quadrature Decoder mode for channel 0 or 1*/
#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
if (chnlPairNumber == 0)
{
base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
}
#endif
/* Unlock: When switching mode, disable channel first */
base->CONTROLS[chnlPairNumber * 2].CnSC &=
~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
/* Wait till mode change to disable channel is acknowledged */
while ((base->CONTROLS[chnlPairNumber * 2].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
base->CONTROLS[chnlPairNumber * 2 + 1].CnSC &=
~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
/* Wait till mode change to disable channel is acknowledged */
while ((base->CONTROLS[chnlPairNumber * 2 + 1].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
/* Now, the registers for input mode can be operated. */
if (edgeParam->enableSwap)
{
/* Set the combine and swap bits for the channel pair */
base->COMBINE |= (TPM_COMBINE_COMBINE0_MASK | TPM_COMBINE_COMSWAP0_MASK)
<< (TPM_COMBINE_SHIFT * chnlPairNumber);
/* Input filter setup for channel n+1 input */
reg = base->FILTER;
reg &= ~(TPM_FILTER_CH0FVAL_MASK << (TPM_FILTER_CH1FVAL_SHIFT * (chnlPairNumber + 1)));
reg |= (filterValue << (TPM_FILTER_CH1FVAL_SHIFT * (chnlPairNumber + 1)));
base->FILTER = reg;
}
else
{
reg = base->COMBINE;
/* Clear the swap bit for the channel pair */
reg &= ~(TPM_COMBINE_COMSWAP0_MASK << (TPM_COMBINE_COMSWAP0_SHIFT * chnlPairNumber));
/* Set the combine bit for the channel pair */
reg |= TPM_COMBINE_COMBINE0_MASK << (TPM_COMBINE_SHIFT * chnlPairNumber);
base->COMBINE = reg;
/* Input filter setup for channel n input */
reg = base->FILTER;
reg &= ~(TPM_FILTER_CH0FVAL_MASK << (TPM_FILTER_CH1FVAL_SHIFT * chnlPairNumber));
reg |= (filterValue << (TPM_FILTER_CH1FVAL_SHIFT * chnlPairNumber));
base->FILTER = reg;
}
/* Setup the edge detection from channel n */
base->CONTROLS[chnlPairNumber * 2].CnSC |= edgeParam->currChanEdgeMode;
/* Wait till mode change is acknowledged */
while (!(base->CONTROLS[chnlPairNumber * 2].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
/* Setup the edge detection from channel n+1 */
base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC |= edgeParam->nextChanEdgeMode;
/* Wait till mode change is acknowledged */
while (!(base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC &
(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
}
#endif
#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
void TPM_SetupQuadDecode(TPM_Type *base,
const tpm_phase_params_t *phaseAParams,
const tpm_phase_params_t *phaseBParams,
tpm_quad_decode_mode_t quadMode)
{
assert(phaseAParams);
assert(phaseBParams);
base->CONTROLS[0].CnSC &= ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
/* Wait till mode change to disable channel is acknowledged */
while ((base->CONTROLS[0].CnSC & (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
uint32_t reg;
/* Set Phase A filter value */
reg = base->FILTER;
reg &= ~(TPM_FILTER_CH0FVAL_MASK);
reg |= TPM_FILTER_CH0FVAL(phaseAParams->phaseFilterVal);
base->FILTER = reg;
#if defined(FSL_FEATURE_TPM_HAS_POL) && FSL_FEATURE_TPM_HAS_POL
/* Set Phase A polarity */
if (phaseAParams->phasePolarity)
{
base->POL |= TPM_POL_POL0_MASK;
}
else
{
base->POL &= ~TPM_POL_POL0_MASK;
}
#endif
base->CONTROLS[1].CnSC &= ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK);
/* Wait till mode change to disable channel is acknowledged */
while ((base->CONTROLS[1].CnSC & (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK)))
{
}
/* Set Phase B filter value */
reg = base->FILTER;
reg &= ~(TPM_FILTER_CH1FVAL_MASK);
reg |= TPM_FILTER_CH1FVAL(phaseBParams->phaseFilterVal);
base->FILTER = reg;
#if defined(FSL_FEATURE_TPM_HAS_POL) && FSL_FEATURE_TPM_HAS_POL
/* Set Phase B polarity */
if (phaseBParams->phasePolarity)
{
base->POL |= TPM_POL_POL1_MASK;
}
else
{
base->POL &= ~TPM_POL_POL1_MASK;
}
#endif
/* Set Quadrature mode */
reg = base->QDCTRL;
reg &= ~(TPM_QDCTRL_QUADMODE_MASK);
reg |= TPM_QDCTRL_QUADMODE(quadMode);
base->QDCTRL = reg;
/* Enable Quad decode */
base->QDCTRL |= TPM_QDCTRL_QUADEN_MASK;
}
#endif
void TPM_EnableInterrupts(TPM_Type *base, uint32_t mask)
{
uint32_t chnlInterrupts = (mask & 0xFF);
uint8_t chnlNumber = 0;
/* Enable the timer overflow interrupt */
if (mask & kTPM_TimeOverflowInterruptEnable)
{
base->SC |= TPM_SC_TOIE_MASK;
}
/* Enable the channel interrupts */
while (chnlInterrupts)
{
if (chnlInterrupts & 0x1)
{
base->CONTROLS[chnlNumber].CnSC |= TPM_CnSC_CHIE_MASK;
}
chnlNumber++;
chnlInterrupts = chnlInterrupts >> 1U;
}
}
void TPM_DisableInterrupts(TPM_Type *base, uint32_t mask)
{
uint32_t chnlInterrupts = (mask & 0xFF);
uint8_t chnlNumber = 0;
/* Disable the timer overflow interrupt */
if (mask & kTPM_TimeOverflowInterruptEnable)
{
base->SC &= ~TPM_SC_TOIE_MASK;
}
/* Disable the channel interrupts */
while (chnlInterrupts)
{
if (chnlInterrupts & 0x1)
{
base->CONTROLS[chnlNumber].CnSC &= ~TPM_CnSC_CHIE_MASK;
}
chnlNumber++;
chnlInterrupts = chnlInterrupts >> 1U;
}
}
uint32_t TPM_GetEnabledInterrupts(TPM_Type *base)
{
uint32_t enabledInterrupts = 0;
int8_t chnlCount = FSL_FEATURE_TPM_CHANNEL_COUNTn(base);
/* The CHANNEL_COUNT macro returns -1 if it cannot match the TPM instance */
assert(chnlCount != -1);
/* Check if timer overflow interrupt is enabled */
if (base->SC & TPM_SC_TOIE_MASK)
{
enabledInterrupts |= kTPM_TimeOverflowInterruptEnable;
}
/* Check if the channel interrupts are enabled */
while (chnlCount > 0)
{
chnlCount--;
if (base->CONTROLS[chnlCount].CnSC & TPM_CnSC_CHIE_MASK)
{
enabledInterrupts |= (1U << chnlCount);
}
}
return enabledInterrupts;
}

View File

@ -1,590 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_TPM_H_
#define _FSL_TPM_H_
#include "fsl_common.h"
/*!
* @addtogroup tpm
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
#define FSL_TPM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2 */
/*@}*/
/*!
* @brief List of TPM channels.
* @note Actual number of available channels is SoC dependent
*/
typedef enum _tpm_chnl
{
kTPM_Chnl_0 = 0U, /*!< TPM channel number 0*/
kTPM_Chnl_1, /*!< TPM channel number 1 */
kTPM_Chnl_2, /*!< TPM channel number 2 */
kTPM_Chnl_3, /*!< TPM channel number 3 */
kTPM_Chnl_4, /*!< TPM channel number 4 */
kTPM_Chnl_5, /*!< TPM channel number 5 */
kTPM_Chnl_6, /*!< TPM channel number 6 */
kTPM_Chnl_7 /*!< TPM channel number 7 */
} tpm_chnl_t;
/*! @brief TPM PWM operation modes */
typedef enum _tpm_pwm_mode
{
kTPM_EdgeAlignedPwm = 0U, /*!< Edge aligned PWM */
kTPM_CenterAlignedPwm, /*!< Center aligned PWM */
#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
kTPM_CombinedPwm /*!< Combined PWM */
#endif
} tpm_pwm_mode_t;
/*! @brief TPM PWM output pulse mode: high-true, low-true or no output */
typedef enum _tpm_pwm_level_select
{
kTPM_NoPwmSignal = 0U, /*!< No PWM output on pin */
kTPM_LowTrue, /*!< Low true pulses */
kTPM_HighTrue /*!< High true pulses */
} tpm_pwm_level_select_t;
/*! @brief Options to configure a TPM channel's PWM signal */
typedef struct _tpm_chnl_pwm_signal_param
{
tpm_chnl_t chnlNumber; /*!< TPM channel to configure.
In combined mode (available in some SoC's, this represents the
channel pair number */
tpm_pwm_level_select_t level; /*!< PWM output active level select */
uint8_t dutyCyclePercent; /*!< PWM pulse width, value should be between 0 to 100
0=inactive signal(0% duty cycle)...
100=always active signal (100% duty cycle)*/
#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
uint8_t firstEdgeDelayPercent; /*!< Used only in combined PWM mode to generate asymmetrical PWM.
Specifies the delay to the first edge in a PWM period.
If unsure, leave as 0; Should be specified as
percentage of the PWM period */
#endif
} tpm_chnl_pwm_signal_param_t;
/*!
* @brief Trigger options available.
*
* This is used for both internal & external trigger sources (external option available in certain SoC's)
*
* @note The actual trigger options available is SoC-specific.
*/
typedef enum _tpm_trigger_select
{
kTPM_Trigger_Select_0 = 0U,
kTPM_Trigger_Select_1,
kTPM_Trigger_Select_2,
kTPM_Trigger_Select_3,
kTPM_Trigger_Select_4,
kTPM_Trigger_Select_5,
kTPM_Trigger_Select_6,
kTPM_Trigger_Select_7,
kTPM_Trigger_Select_8,
kTPM_Trigger_Select_9,
kTPM_Trigger_Select_10,
kTPM_Trigger_Select_11,
kTPM_Trigger_Select_12,
kTPM_Trigger_Select_13,
kTPM_Trigger_Select_14,
kTPM_Trigger_Select_15
} tpm_trigger_select_t;
#if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION
/*!
* @brief Trigger source options available
*
* @note This selection is available only on some SoC's. For SoC's without this selection, the only
* trigger source available is internal triger.
*/
typedef enum _tpm_trigger_source
{
kTPM_TriggerSource_External = 0U, /*!< Use external trigger input */
kTPM_TriggerSource_Internal /*!< Use internal trigger */
} tpm_trigger_source_t;
#endif
/*! @brief TPM output compare modes */
typedef enum _tpm_output_compare_mode
{
kTPM_NoOutputSignal = (1U << TPM_CnSC_MSA_SHIFT), /*!< No channel output when counter reaches CnV */
kTPM_ToggleOnMatch = ((1U << TPM_CnSC_MSA_SHIFT) | (1U << TPM_CnSC_ELSA_SHIFT)), /*!< Toggle output */
kTPM_ClearOnMatch = ((1U << TPM_CnSC_MSA_SHIFT) | (2U << TPM_CnSC_ELSA_SHIFT)), /*!< Clear output */
kTPM_SetOnMatch = ((1U << TPM_CnSC_MSA_SHIFT) | (3U << TPM_CnSC_ELSA_SHIFT)), /*!< Set output */
kTPM_HighPulseOutput = ((3U << TPM_CnSC_MSA_SHIFT) | (1U << TPM_CnSC_ELSA_SHIFT)), /*!< Pulse output high */
kTPM_LowPulseOutput = ((3U << TPM_CnSC_MSA_SHIFT) | (2U << TPM_CnSC_ELSA_SHIFT)) /*!< Pulse output low */
} tpm_output_compare_mode_t;
/*! @brief TPM input capture edge */
typedef enum _tpm_input_capture_edge
{
kTPM_RisingEdge = (1U << TPM_CnSC_ELSA_SHIFT), /*!< Capture on rising edge only */
kTPM_FallingEdge = (2U << TPM_CnSC_ELSA_SHIFT), /*!< Capture on falling edge only */
kTPM_RiseAndFallEdge = (3U << TPM_CnSC_ELSA_SHIFT) /*!< Capture on rising or falling edge */
} tpm_input_capture_edge_t;
#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
/*!
* @brief TPM dual edge capture parameters
*
* @note This mode is available only on some SoC's.
*/
typedef struct _tpm_dual_edge_capture_param
{
bool enableSwap; /*!< true: Use channel n+1 input, channel n input is ignored;
false: Use channel n input, channel n+1 input is ignored */
tpm_input_capture_edge_t currChanEdgeMode; /*!< Input capture edge select for channel n */
tpm_input_capture_edge_t nextChanEdgeMode; /*!< Input capture edge select for channel n+1 */
} tpm_dual_edge_capture_param_t;
#endif
#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
/*!
* @brief TPM quadrature decode modes
*
* @note This mode is available only on some SoC's.
*/
typedef enum _tpm_quad_decode_mode
{
kTPM_QuadPhaseEncode = 0U, /*!< Phase A and Phase B encoding mode */
kTPM_QuadCountAndDir /*!< Count and direction encoding mode */
} tpm_quad_decode_mode_t;
/*! @brief TPM quadrature phase polarities */
typedef enum _tpm_phase_polarity
{
kTPM_QuadPhaseNormal = 0U, /*!< Phase input signal is not inverted */
kTPM_QuadPhaseInvert /*!< Phase input signal is inverted */
} tpm_phase_polarity_t;
/*! @brief TPM quadrature decode phase parameters */
typedef struct _tpm_phase_param
{
uint32_t phaseFilterVal; /*!< Filter value, filter is disabled when the value is zero */
tpm_phase_polarity_t phasePolarity; /*!< Phase polarity */
} tpm_phase_params_t;
#endif
/*! @brief TPM clock source selection*/
typedef enum _tpm_clock_source
{
kTPM_SystemClock = 1U, /*!< System clock */
kTPM_ExternalClock /*!< External clock */
} tpm_clock_source_t;
/*! @brief TPM prescale value selection for the clock source*/
typedef enum _tpm_clock_prescale
{
kTPM_Prescale_Divide_1 = 0U, /*!< Divide by 1 */
kTPM_Prescale_Divide_2, /*!< Divide by 2 */
kTPM_Prescale_Divide_4, /*!< Divide by 4 */
kTPM_Prescale_Divide_8, /*!< Divide by 8 */
kTPM_Prescale_Divide_16, /*!< Divide by 16 */
kTPM_Prescale_Divide_32, /*!< Divide by 32 */
kTPM_Prescale_Divide_64, /*!< Divide by 64 */
kTPM_Prescale_Divide_128 /*!< Divide by 128 */
} tpm_clock_prescale_t;
/*!
* @brief TPM config structure
*
* This structure holds the configuration settings for the TPM peripheral. To initialize this
* structure to reasonable defaults, call the TPM_GetDefaultConfig() function and pass a
* pointer to your config structure instance.
*
* The config struct can be made const so it resides in flash
*/
typedef struct _tpm_config
{
tpm_clock_prescale_t prescale; /*!< Select TPM clock prescale value */
bool useGlobalTimeBase; /*!< true: Use of an external global time base is enabled;
false: disabled */
tpm_trigger_select_t triggerSelect; /*!< Input trigger to use for controlling the counter operation */
#if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION
tpm_trigger_source_t triggerSource; /*!< Decides if we use external or internal trigger. */
#endif
bool enableDoze; /*!< true: TPM counter is paused in doze mode;
false: TPM counter continues in doze mode */
bool enableDebugMode; /*!< true: TPM counter continues in debug mode;
false: TPM counter is paused in debug mode */
bool enableReloadOnTrigger; /*!< true: TPM counter is reloaded on trigger;
false: TPM counter not reloaded */
bool enableStopOnOverflow; /*!< true: TPM counter stops after overflow;
false: TPM counter continues running after overflow */
bool enableStartOnTrigger; /*!< true: TPM counter only starts when a trigger is detected;
false: TPM counter starts immediately */
#if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER
bool enablePauseOnTrigger; /*!< true: TPM counter will pause while trigger remains asserted;
false: TPM counter continues running */
#endif
} tpm_config_t;
/*! @brief List of TPM interrupts */
typedef enum _tpm_interrupt_enable
{
kTPM_Chnl0InterruptEnable = (1U << 0), /*!< Channel 0 interrupt.*/
kTPM_Chnl1InterruptEnable = (1U << 1), /*!< Channel 1 interrupt.*/
kTPM_Chnl2InterruptEnable = (1U << 2), /*!< Channel 2 interrupt.*/
kTPM_Chnl3InterruptEnable = (1U << 3), /*!< Channel 3 interrupt.*/
kTPM_Chnl4InterruptEnable = (1U << 4), /*!< Channel 4 interrupt.*/
kTPM_Chnl5InterruptEnable = (1U << 5), /*!< Channel 5 interrupt.*/
kTPM_Chnl6InterruptEnable = (1U << 6), /*!< Channel 6 interrupt.*/
kTPM_Chnl7InterruptEnable = (1U << 7), /*!< Channel 7 interrupt.*/
kTPM_TimeOverflowInterruptEnable = (1U << 8) /*!< Time overflow interrupt.*/
} tpm_interrupt_enable_t;
/*! @brief List of TPM flags */
typedef enum _tpm_status_flags
{
kTPM_Chnl0Flag = (1U << 0), /*!< Channel 0 flag */
kTPM_Chnl1Flag = (1U << 1), /*!< Channel 1 flag */
kTPM_Chnl2Flag = (1U << 2), /*!< Channel 2 flag */
kTPM_Chnl3Flag = (1U << 3), /*!< Channel 3 flag */
kTPM_Chnl4Flag = (1U << 4), /*!< Channel 4 flag */
kTPM_Chnl5Flag = (1U << 5), /*!< Channel 5 flag */
kTPM_Chnl6Flag = (1U << 6), /*!< Channel 6 flag */
kTPM_Chnl7Flag = (1U << 7), /*!< Channel 7 flag */
kTPM_TimeOverflowFlag = (1U << 8) /*!< Time overflow flag */
} tpm_status_flags_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Ungates the TPM clock and configures the peripheral for basic operation.
*
* @note This API should be called at the beginning of the application using the TPM driver.
*
* @param base TPM peripheral base address
* @param config Pointer to user's TPM config structure.
*/
void TPM_Init(TPM_Type *base, const tpm_config_t *config);
/*!
* @brief Stops the counter and gates the TPM clock
*
* @param base TPM peripheral base address
*/
void TPM_Deinit(TPM_Type *base);
/*!
* @brief Fill in the TPM config struct with the default settings
*
* The default values are:
* @code
* config->prescale = kTPM_Prescale_Divide_1;
* config->useGlobalTimeBase = false;
* config->dozeEnable = false;
* config->dbgMode = false;
* config->enableReloadOnTrigger = false;
* config->enableStopOnOverflow = false;
* config->enableStartOnTrigger = false;
*#if FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER
* config->enablePauseOnTrigger = false;
*#endif
* config->triggerSelect = kTPM_Trigger_Select_0;
*#if FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION
* config->triggerSource = kTPM_TriggerSource_External;
*#endif
* @endcode
* @param config Pointer to user's TPM config structure.
*/
void TPM_GetDefaultConfig(tpm_config_t *config);
/*! @}*/
/*!
* @name Channel mode operations
* @{
*/
/*!
* @brief Configures the PWM signal parameters
*
* User calls this function to configure the PWM signals period, mode, dutycycle and edge. Use this
* function to configure all the TPM channels that will be used to output a PWM signal
*
* @param base TPM peripheral base address
* @param chnlParams Array of PWM channel parameters to configure the channel(s)
* @param numOfChnls Number of channels to configure, this should be the size of the array passed in
* @param mode PWM operation mode, options available in enumeration ::tpm_pwm_mode_t
* @param pwmFreq_Hz PWM signal frequency in Hz
* @param srcClock_Hz TPM counter clock in Hz
*
* @return kStatus_Success if the PWM setup was successful,
* kStatus_Error on failure
*/
status_t TPM_SetupPwm(TPM_Type *base,
const tpm_chnl_pwm_signal_param_t *chnlParams,
uint8_t numOfChnls,
tpm_pwm_mode_t mode,
uint32_t pwmFreq_Hz,
uint32_t srcClock_Hz);
/*!
* @brief Update the duty cycle of an active PWM signal
*
* @param base TPM peripheral base address
* @param chnlNumber The channel number. In combined mode, this represents
* the channel pair number
* @param currentPwmMode The current PWM mode set during PWM setup
* @param dutyCyclePercent New PWM pulse width, value should be between 0 to 100
* 0=inactive signal(0% duty cycle)...
* 100=active signal (100% duty cycle)
*/
void TPM_UpdatePwmDutycycle(TPM_Type *base,
tpm_chnl_t chnlNumber,
tpm_pwm_mode_t currentPwmMode,
uint8_t dutyCyclePercent);
/*!
* @brief Update the edge level selection for a channel
*
* @param base TPM peripheral base address
* @param chnlNumber The channel number
* @param level The level to be set to the ELSnB:ELSnA field; valid values are 00, 01, 10, 11.
* See the appropriate SoC reference manual for details about this field.
*/
void TPM_UpdateChnlEdgeLevelSelect(TPM_Type *base, tpm_chnl_t chnlNumber, uint8_t level);
/*!
* @brief Enables capturing an input signal on the channel using the function parameters.
*
* When the edge specified in the captureMode argument occurs on the channel, the TPM counter is captured into
* the CnV register. The user has to read the CnV register separately to get this value.
*
* @param base TPM peripheral base address
* @param chnlNumber The channel number
* @param captureMode Specifies which edge to capture
*/
void TPM_SetupInputCapture(TPM_Type *base, tpm_chnl_t chnlNumber, tpm_input_capture_edge_t captureMode);
/*!
* @brief Configures the TPM to generate timed pulses.
*
* When the TPM counter matches the value of compareVal argument (this is written into CnV reg), the channel
* output is changed based on what is specified in the compareMode argument.
*
* @param base TPM peripheral base address
* @param chnlNumber The channel number
* @param compareMode Action to take on the channel output when the compare condition is met
* @param compareValue Value to be programmed in the CnV register.
*/
void TPM_SetupOutputCompare(TPM_Type *base,
tpm_chnl_t chnlNumber,
tpm_output_compare_mode_t compareMode,
uint32_t compareValue);
#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE
/*!
* @brief Configures the dual edge capture mode of the TPM.
*
* This function allows to measure a pulse width of the signal on the input of channel of a
* channel pair. The filter function is disabled if the filterVal argument passed is zero.
*
* @param base TPM peripheral base address
* @param chnlPairNumber The TPM channel pair number; options are 0, 1, 2, 3
* @param edgeParam Sets up the dual edge capture function
* @param filterValue Filter value, specify 0 to disable filter.
*/
void TPM_SetupDualEdgeCapture(TPM_Type *base,
tpm_chnl_t chnlPairNumber,
const tpm_dual_edge_capture_param_t *edgeParam,
uint32_t filterValue);
#endif
#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL
/*!
* @brief Configures the parameters and activates the quadrature decode mode.
*
* @param base TPM peripheral base address
* @param phaseAParams Phase A configuration parameters
* @param phaseBParams Phase B configuration parameters
* @param quadMode Selects encoding mode used in quadrature decoder mode
*/
void TPM_SetupQuadDecode(TPM_Type *base,
const tpm_phase_params_t *phaseAParams,
const tpm_phase_params_t *phaseBParams,
tpm_quad_decode_mode_t quadMode);
#endif
/*! @}*/
/*!
* @name Interrupt Interface
* @{
*/
/*!
* @brief Enables the selected TPM interrupts.
*
* @param base TPM peripheral base address
* @param mask The interrupts to enable. This is a logical OR of members of the
* enumeration ::tpm_interrupt_enable_t
*/
void TPM_EnableInterrupts(TPM_Type *base, uint32_t mask);
/*!
* @brief Disables the selected TPM interrupts.
*
* @param base TPM peripheral base address
* @param mask The interrupts to disable. This is a logical OR of members of the
* enumeration ::tpm_interrupt_enable_t
*/
void TPM_DisableInterrupts(TPM_Type *base, uint32_t mask);
/*!
* @brief Gets the enabled TPM interrupts.
*
* @param base TPM peripheral base address
*
* @return The enabled interrupts. This is the logical OR of members of the
* enumeration ::tpm_interrupt_enable_t
*/
uint32_t TPM_GetEnabledInterrupts(TPM_Type *base);
/*! @}*/
/*!
* @name Status Interface
* @{
*/
/*!
* @brief Gets the TPM status flags
*
* @param base TPM peripheral base address
*
* @return The status flags. This is the logical OR of members of the
* enumeration ::tpm_status_flags_t
*/
static inline uint32_t TPM_GetStatusFlags(TPM_Type *base)
{
return base->STATUS;
}
/*!
* @brief Clears the TPM status flags
*
* @param base TPM peripheral base address
* @param mask The status flags to clear. This is a logical OR of members of the
* enumeration ::tpm_status_flags_t
*/
static inline void TPM_ClearStatusFlags(TPM_Type *base, uint32_t mask)
{
/* Clear the status flags */
base->STATUS = mask;
}
/*! @}*/
/*!
* @name Timer Start and Stop
* @{
*/
/*!
* @brief Starts the TPM counter.
*
*
* @param base TPM peripheral base address
* @param clockSource TPM clock source; once clock source is set the counter will start running
*/
static inline void TPM_StartTimer(TPM_Type *base, tpm_clock_source_t clockSource)
{
uint32_t reg = base->SC;
reg &= ~(TPM_SC_CMOD_MASK);
reg |= TPM_SC_CMOD(clockSource);
base->SC = reg;
}
/*!
* @brief Stops the TPM counter.
*
* @param base TPM peripheral base address
*/
static inline void TPM_StopTimer(TPM_Type *base)
{
/* Set clock source to none to disable counter */
base->SC &= ~(TPM_SC_CMOD_MASK);
/* Wait till this reads as zero acknowledging the counter is disabled */
while (base->SC & TPM_SC_CMOD_MASK)
{
}
}
/*! @}*/
#if defined(FSL_FEATURE_TPM_HAS_GLOBAL) && FSL_FEATURE_TPM_HAS_GLOBAL
/*!
* @brief Performs a software reset on the TPM module.
*
* Reset all internal logic and registers, except the Global Register. Remains set until cleared by software..
*
* @note TPM software reset is available on certain SoC's only
*
* @param base TPM peripheral base address
*/
static inline void TPM_Reset(TPM_Type *base)
{
base->GLOBAL |= TPM_GLOBAL_RST_MASK;
base->GLOBAL &= ~TPM_GLOBAL_RST_MASK;
}
#endif
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_TPM_H_ */

View File

@ -1,757 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_UART_H_
#define _FSL_UART_H_
#include "fsl_common.h"
/*!
* @addtogroup uart_driver
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief UART driver version 2.1.0. */
#define FSL_UART_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
/*@}*/
/*! @brief Error codes for the UART driver. */
enum _uart_status
{
kStatus_UART_TxBusy = MAKE_STATUS(kStatusGroup_UART, 0), /*!< Transmitter is busy. */
kStatus_UART_RxBusy = MAKE_STATUS(kStatusGroup_UART, 1), /*!< Receiver is busy. */
kStatus_UART_TxIdle = MAKE_STATUS(kStatusGroup_UART, 2), /*!< UART transmitter is idle. */
kStatus_UART_RxIdle = MAKE_STATUS(kStatusGroup_UART, 3), /*!< UART receiver is idle. */
kStatus_UART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_UART, 4), /*!< TX FIFO watermark too large */
kStatus_UART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_UART, 5), /*!< RX FIFO watermark too large */
kStatus_UART_FlagCannotClearManually =
MAKE_STATUS(kStatusGroup_UART, 6), /*!< UART flag can't be manually cleared. */
kStatus_UART_Error = MAKE_STATUS(kStatusGroup_UART, 7), /*!< Error happens on UART. */
kStatus_UART_RxRingBufferOverrun = MAKE_STATUS(kStatusGroup_UART, 8), /*!< UART RX software ring buffer overrun. */
kStatus_UART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_UART, 9), /*!< UART RX receiver overrun. */
kStatus_UART_NoiseError = MAKE_STATUS(kStatusGroup_UART, 10), /*!< UART noise error. */
kStatus_UART_FramingError = MAKE_STATUS(kStatusGroup_UART, 11), /*!< UART framing error. */
kStatus_UART_ParityError = MAKE_STATUS(kStatusGroup_UART, 12), /*!< UART parity error. */
};
/*! @brief UART parity mode. */
typedef enum _uart_parity_mode
{
kUART_ParityDisabled = 0x0U, /*!< Parity disabled */
kUART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */
kUART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */
} uart_parity_mode_t;
/*! @brief UART stop bit count. */
typedef enum _uart_stop_bit_count
{
kUART_OneStopBit = 0U, /*!< One stop bit */
kUART_TwoStopBit = 1U, /*!< Two stop bits */
} uart_stop_bit_count_t;
/*!
* @brief UART interrupt configuration structure, default settings all disabled.
*
* This structure contains the settings for all of the UART interrupt configurations.
*/
enum _uart_interrupt_enable
{
#if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT
kUART_LinBreakInterruptEnable = (UART_BDH_LBKDIE_MASK), /*!< LIN break detect interrupt. */
#endif
kUART_RxActiveEdgeInterruptEnable = (UART_BDH_RXEDGIE_MASK), /*!< RX active edge interrupt. */
kUART_TxDataRegEmptyInterruptEnable = (UART_C2_TIE_MASK << 8), /*!< Transmit data register empty interrupt. */
kUART_TransmissionCompleteInterruptEnable = (UART_C2_TCIE_MASK << 8), /*!< Transmission complete interrupt. */
kUART_RxDataRegFullInterruptEnable = (UART_C2_RIE_MASK << 8), /*!< Receiver data register full interrupt. */
kUART_IdleLineInterruptEnable = (UART_C2_ILIE_MASK << 8), /*!< Idle line interrupt. */
kUART_RxOverrunInterruptEnable = (UART_C3_ORIE_MASK << 16), /*!< Receiver overrun interrupt. */
kUART_NoiseErrorInterruptEnable = (UART_C3_NEIE_MASK << 16), /*!< Noise error flag interrupt. */
kUART_FramingErrorInterruptEnable = (UART_C3_FEIE_MASK << 16), /*!< Framing error flag interrupt. */
kUART_ParityErrorInterruptEnable = (UART_C3_PEIE_MASK << 16), /*!< Parity error flag interrupt. */
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
kUART_RxFifoOverflowInterruptEnable = (UART_CFIFO_TXOFE_MASK << 24), /*!< TX FIFO overflow interrupt. */
kUART_TxFifoOverflowInterruptEnable = (UART_CFIFO_RXUFE_MASK << 24), /*!< RX FIFO underflow interrupt. */
kUART_RxFifoUnderflowInterruptEnable = (UART_CFIFO_RXUFE_MASK << 24), /*!< RX FIFO underflow interrupt. */
#endif
};
/*!
* @brief UART status flags.
*
* This provides constants for the UART status flags for use in the UART functions.
*/
enum _uart_flags
{
kUART_TxDataRegEmptyFlag = (UART_S1_TDRE_MASK), /*!< TX data register empty flag. */
kUART_TransmissionCompleteFlag = (UART_S1_TC_MASK), /*!< Transmission complete flag. */
kUART_RxDataRegFullFlag = (UART_S1_RDRF_MASK), /*!< RX data register full flag. */
kUART_IdleLineFlag = (UART_S1_IDLE_MASK), /*!< Idle line detect flag. */
kUART_RxOverrunFlag = (UART_S1_OR_MASK), /*!< RX overrun flag. */
kUART_NoiseErrorFlag = (UART_S1_NF_MASK), /*!< RX takes 3 samples of each received bit.
If any of these samples differ, noise flag sets */
kUART_FramingErrorFlag = (UART_S1_FE_MASK), /*!< Frame error flag, sets if logic 0 was detected
where stop bit expected */
kUART_ParityErrorFlag = (UART_S1_PF_MASK), /*!< If parity enabled, sets upon parity error detection */
#if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT
kUART_LinBreakFlag =
(UART_S2_LBKDIF_MASK << 8), /*!< LIN break detect interrupt flag, sets when
LIN break char detected and LIN circuit enabled */
#endif
kUART_RxActiveEdgeFlag = (UART_S2_RXEDGIF_MASK << 8), /*!< RX pin active edge interrupt flag,
sets when active edge detected */
kUART_RxActiveFlag = (UART_S2_RAF_MASK << 8), /*!< Receiver Active Flag (RAF),
sets at beginning of valid start bit */
#if defined(FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS
kUART_NoiseErrorInRxDataRegFlag = (UART_ED_NOISY_MASK << 16), /*!< Noisy bit, sets if noise detected. */
kUART_ParityErrorInRxDataRegFlag = (UART_ED_PARITYE_MASK << 16), /*!< Paritye bit, sets if parity error detected. */
#endif
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
kUART_TxFifoEmptyFlag = (UART_SFIFO_TXEMPT_MASK << 24), /*!< TXEMPT bit, sets if TX buffer is empty */
kUART_RxFifoEmptyFlag = (UART_SFIFO_RXEMPT_MASK << 24), /*!< RXEMPT bit, sets if RX buffer is empty */
kUART_TxFifoOverflowFlag = (UART_SFIFO_TXOF_MASK << 24), /*!< TXOF bit, sets if TX buffer overflow occurred */
kUART_RxFifoOverflowFlag = (UART_SFIFO_RXOF_MASK << 24), /*!< RXOF bit, sets if receive buffer overflow */
kUART_RxFifoUnderflowFlag = (UART_SFIFO_RXUF_MASK << 24), /*!< RXUF bit, sets if receive buffer underflow */
#endif
};
/*! @brief UART configuration structure. */
typedef struct _uart_config
{
uint32_t baudRate_Bps; /*!< UART baud rate */
uart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
#if defined(FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT
uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
#endif
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
uint8_t txFifoWatermark; /*!< TX FIFO watermark */
uint8_t rxFifoWatermark; /*!< RX FIFO watermark */
#endif
bool enableTx; /*!< Enable TX */
bool enableRx; /*!< Enable RX */
} uart_config_t;
/*! @brief UART transfer structure. */
typedef struct _uart_transfer
{
uint8_t *data; /*!< The buffer of data to be transfer.*/
size_t dataSize; /*!< The byte count to be transfer. */
} uart_transfer_t;
/* Forward declaration of the handle typedef. */
typedef struct _uart_handle uart_handle_t;
/*! @brief UART transfer callback function. */
typedef void (*uart_transfer_callback_t)(UART_Type *base, uart_handle_t *handle, status_t status, void *userData);
/*! @brief UART handle structure. */
struct _uart_handle
{
uint8_t *volatile txData; /*!< Address of remaining data to send. */
volatile size_t txDataSize; /*!< Size of the remaining data to send. */
size_t txDataSizeAll; /*!< Size of the data to send out. */
uint8_t *volatile rxData; /*!< Address of remaining data to receive. */
volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */
size_t rxDataSizeAll; /*!< Size of the data to receive. */
uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */
size_t rxRingBufferSize; /*!< Size of the ring buffer. */
volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */
volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */
uart_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< UART callback function parameter.*/
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes a UART instance with user configuration structure and peripheral clock.
*
* This function configures the UART module with the user-defined settings. The user can configure the configuration
* structure and also get the default configuration by using the UART_GetDefaultConfig() function.
* Example below shows how to use this API to configure UART.
* @code
* uart_config_t uartConfig;
* uartConfig.baudRate_Bps = 115200U;
* uartConfig.parityMode = kUART_ParityDisabled;
* uartConfig.stopBitCount = kUART_OneStopBit;
* uartConfig.txFifoWatermark = 0;
* uartConfig.rxFifoWatermark = 1;
* UART_Init(UART1, &uartConfig, 20000000U);
* @endcode
*
* @param base UART peripheral base address.
* @param config Pointer to user-defined configuration structure.
* @param srcClock_Hz UART clock source frequency in HZ.
*/
void UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz);
/*!
* @brief Deinitializes a UART instance.
*
* This function waits for TX complete, disables TX and RX, and disables the UART clock.
*
* @param base UART peripheral base address.
*/
void UART_Deinit(UART_Type *base);
/*!
* @brief Gets the default configuration structure.
*
* This function initializes the UART configuration structure to a default value. The default
* values are:
* uartConfig->baudRate_Bps = 115200U;
* uartConfig->bitCountPerChar = kUART_8BitsPerChar;
* uartConfig->parityMode = kUART_ParityDisabled;
* uartConfig->stopBitCount = kUART_OneStopBit;
* uartConfig->txFifoWatermark = 0;
* uartConfig->rxFifoWatermark = 1;
* uartConfig->enableTx = false;
* uartConfig->enableRx = false;
*
* @param config Pointer to configuration structure.
*/
void UART_GetDefaultConfig(uart_config_t *config);
/*!
* @brief Sets the UART instance baud rate.
*
* This function configures the UART module baud rate. This function is used to update
* the UART module baud rate after the UART module is initialized by the UART_Init.
* @code
* UART_SetBaudRate(UART1, 115200U, 20000000U);
* @endcode
*
* @param base UART peripheral base address.
* @param baudRate_Bps UART baudrate to be set.
* @param srcClock_Hz UART clock source freqency in HZ.
*/
void UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
/* @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Get UART status flags.
*
* This function get all UART status flags, the flags are returned as the logical
* OR value of the enumerators @ref _uart_flags. To check specific status,
* compare the return value with enumerators in @ref _uart_flags.
* For example, to check whether the TX is empty:
* @code
* if (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(UART1))
* {
* ...
* }
* @endcode
*
* @param base UART peripheral base address.
* @return UART status flags which are ORed by the enumerators in the _uart_flags.
*/
uint32_t UART_GetStatusFlags(UART_Type *base);
/*!
* @brief Clears status flags with the provided mask.
*
* This function clears UART status flags with a provided mask. Automatically cleared flag
* can't be cleared by this function.
* Some flags can only be cleared or set by hardware itself. These flags are:
* kUART_TxDataRegEmptyFlag, kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag,
* kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag, kUART_ParityErrorInRxDataRegFlag,
* kUART_TxFifoEmptyFlag,kUART_RxFifoEmptyFlag
* Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects.
*
* @param base UART peripheral base address.
* @param mask The status flags to be cleared, it is logical OR value of @ref _uart_flags.
* @retval kStatus_UART_FlagCannotClearManually The flag can't be cleared by this function but
* it is cleared automatically by hardware.
* @retval kStatus_Success Status in the mask are cleared.
*/
status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask);
/* @} */
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables UART interrupts according to the provided mask.
*
* This function enables the UART interrupts according to the provided mask. The mask
* is a logical OR of enumeration members. See @ref _uart_interrupt_enable.
* For example, to enable TX empty interrupt and RX full interrupt:
* @code
* UART_EnableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable);
* @endcode
*
* @param base UART peripheral base address.
* @param mask The interrupts to enable. Logical OR of @ref _uart_interrupt_enable.
*/
void UART_EnableInterrupts(UART_Type *base, uint32_t mask);
/*!
* @brief Disables the UART interrupts according to the provided mask.
*
* This function disables the UART interrupts according to the provided mask. The mask
* is a logical OR of enumeration members. See @ref _uart_interrupt_enable.
* For example, to disable TX empty interrupt and RX full interrupt:
* @code
* UART_DisableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable);
* @endcode
*
* @param base UART peripheral base address.
* @param mask The interrupts to disable. Logical OR of @ref _uart_interrupt_enable.
*/
void UART_DisableInterrupts(UART_Type *base, uint32_t mask);
/*!
* @brief Gets the enabled UART interrupts.
*
* This function gets the enabled UART interrupts. The enabled interrupts are returned
* as the logical OR value of the enumerators @ref _uart_interrupt_enable. To check
* specific interrupts enable status, compare the return value with enumerators
* in @ref _uart_interrupt_enable.
* For example, to check whether TX empty interrupt is enabled:
* @code
* uint32_t enabledInterrupts = UART_GetEnabledInterrupts(UART1);
*
* if (kUART_TxDataRegEmptyInterruptEnable & enabledInterrupts)
* {
* ...
* }
* @endcode
*
* @param base UART peripheral base address.
* @return UART interrupt flags which are logical OR of the enumerators in @ref _uart_interrupt_enable.
*/
uint32_t UART_GetEnabledInterrupts(UART_Type *base);
/* @} */
#if defined(FSL_FEATURE_UART_HAS_DMA_SELECT) && FSL_FEATURE_UART_HAS_DMA_SELECT
/*!
* @name DMA Control
* @{
*/
/*!
* @brief Gets the UART data register address.
*
* This function returns the UART data register address, which is mainly used by DMA/eDMA.
*
* @param base UART peripheral base address.
* @return UART data register address which are used both by transmitter and receiver.
*/
static inline uint32_t UART_GetDataRegisterAddress(UART_Type *base)
{
return (uint32_t) & (base->D);
}
/*!
* @brief Enables or disables the UART transmitter DMA request.
*
* This function enables or disables the transmit data register empty flag, S1[TDRE], to generate the DMA requests.
*
* @param base UART peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void UART_EnableTxDMA(UART_Type *base, bool enable)
{
if (enable)
{
#if (defined(FSL_FEATURE_UART_IS_SCI) && FSL_FEATURE_UART_IS_SCI)
base->C4 |= UART_C4_TDMAS_MASK;
#else
base->C5 |= UART_C5_TDMAS_MASK;
#endif
base->C2 |= UART_C2_TIE_MASK;
}
else
{
#if (defined(FSL_FEATURE_UART_IS_SCI) && FSL_FEATURE_UART_IS_SCI)
base->C4 &= ~UART_C4_TDMAS_MASK;
#else
base->C5 &= ~UART_C5_TDMAS_MASK;
#endif
base->C2 &= ~UART_C2_TIE_MASK;
}
}
/*!
* @brief Enables or disables the UART receiver DMA.
*
* This function enables or disables the receiver data register full flag, S1[RDRF], to generate DMA requests.
*
* @param base UART peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void UART_EnableRxDMA(UART_Type *base, bool enable)
{
if (enable)
{
#if (defined(FSL_FEATURE_UART_IS_SCI) && FSL_FEATURE_UART_IS_SCI)
base->C4 |= UART_C4_RDMAS_MASK;
#else
base->C5 |= UART_C5_RDMAS_MASK;
#endif
base->C2 |= UART_C2_RIE_MASK;
}
else
{
#if (defined(FSL_FEATURE_UART_IS_SCI) && FSL_FEATURE_UART_IS_SCI)
base->C4 &= ~UART_C4_RDMAS_MASK;
#else
base->C5 &= ~UART_C5_RDMAS_MASK;
#endif
base->C2 &= ~UART_C2_RIE_MASK;
}
}
/* @} */
#endif /* FSL_FEATURE_UART_HAS_DMA_SELECT */
/*!
* @name Bus Operations
* @{
*/
/*!
* @brief Enables or disables the UART transmitter.
*
* This function enables or disables the UART transmitter.
*
* @param base UART peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void UART_EnableTx(UART_Type *base, bool enable)
{
if (enable)
{
base->C2 |= UART_C2_TE_MASK;
}
else
{
base->C2 &= ~UART_C2_TE_MASK;
}
}
/*!
* @brief Enables or disables the UART receiver.
*
* This function enables or disables the UART receiver.
*
* @param base UART peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void UART_EnableRx(UART_Type *base, bool enable)
{
if (enable)
{
base->C2 |= UART_C2_RE_MASK;
}
else
{
base->C2 &= ~UART_C2_RE_MASK;
}
}
/*!
* @brief Writes to the TX register.
*
* This function writes data to the TX register directly. The upper layer must ensure
* that the TX register is empty or TX FIFO has empty room before calling this function.
*
* @param base UART peripheral base address.
* @param data The byte to write.
*/
static inline void UART_WriteByte(UART_Type *base, uint8_t data)
{
base->D = data;
}
/*!
* @brief Reads the RX register directly.
*
* This function reads data from the TX register directly. The upper layer must
* ensure that the RX register is full or that the TX FIFO has data before calling this function.
*
* @param base UART peripheral base address.
* @return The byte read from UART data register.
*/
static inline uint8_t UART_ReadByte(UART_Type *base)
{
return base->D;
}
/*!
* @brief Writes to the TX register using a blocking method.
*
* This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
* to have room and writes data to the TX buffer.
*
* @note This function does not check whether all the data has been sent out to the bus.
* Before disabling the TX, check kUART_TransmissionCompleteFlag to ensure that the TX is
* finished.
*
* @param base UART peripheral base address.
* @param data Start address of the data to write.
* @param length Size of the data to write.
*/
void UART_WriteBlocking(UART_Type *base, const uint8_t *data, size_t length);
/*!
* @brief Read RX data register using a blocking method.
*
* This function polls the RX register, waits for the RX register to be full or for RX FIFO to
* have data and read data from the TX register.
*
* @param base UART peripheral base address.
* @param data Start address of the buffer to store the received data.
* @param length Size of the buffer.
* @retval kStatus_UART_RxHardwareOverrun Receiver overrun happened while receiving data.
* @retval kStatus_UART_NoiseError Noise error happened while receiving data.
* @retval kStatus_UART_FramingError Framing error happened while receiving data.
* @retval kStatus_UART_ParityError Parity error happened while receiving data.
* @retval kStatus_Success Successfully received all data.
*/
status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length);
/* @} */
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the UART handle.
*
* This function initializes the UART handle which can be used for other UART
* transactional APIs. Usually, for a specified UART instance,
* call this API once to get the initialized handle.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param callback The callback function.
* @param userData The parameter of the callback function.
*/
void UART_TransferCreateHandle(UART_Type *base,
uart_handle_t *handle,
uart_transfer_callback_t callback,
void *userData);
/*!
* @brief Sets up the RX ring buffer.
*
* This function sets up the RX ring buffer to a specific UART handle.
*
* When the RX ring buffer is used, data received are stored into the ring buffer even when the
* user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received
* in the ring buffer, the user can get the received data from the ring buffer directly.
*
* @note When using the RX ring buffer, one byte is reserved for internal use. In other
* words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer.
* @param ringBufferSize size of the ring buffer.
*/
void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize);
/*!
* @brief Aborts the background transfer and uninstalls the ring buffer.
*
* This function aborts the background transfer and uninstalls the ring buffer.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
*/
void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle);
/*!
* @brief Transmits a buffer of data using the interrupt method.
*
* This function sends data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data to be written to the TX register. When
* all data is written to the TX register in the ISR, the UART driver calls the callback
* function and passes the @ref kStatus_UART_TxIdle as status parameter.
*
* @note The kStatus_UART_TxIdle is passed to the upper layer when all data is written
* to the TX register. However it does not ensure that all data are sent out. Before disabling the TX,
* check the kUART_TransmissionCompleteFlag to ensure that the TX is finished.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param xfer UART transfer structure. See #uart_transfer_t.
* @retval kStatus_Success Successfully start the data transmission.
* @retval kStatus_UART_TxBusy Previous transmission still not finished, data not all written to TX register yet.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer);
/*!
* @brief Aborts the interrupt driven data transmit.
*
* This function aborts the interrupt driven data sending. The user can get the remainBytes to find out
* how many bytes are still not sent out.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
*/
void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been written to UART TX register.
*
* This function gets the number of bytes that have been written to UART TX
* register by interrupt method.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param count Send bytes count.
* @retval kStatus_NoTransferInProgress No send in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count);
/*!
* @brief Receives a buffer of data using an interrupt method.
*
* This function receives data using an interrupt method. This is a non-blocking function, which
* returns without waiting for all data to be received.
* If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
* the parameter @p receivedBytes shows how many bytes are copied from the ring buffer.
* After copying, if the data in the ring buffer is not enough to read, the receive
* request is saved by the UART driver. When the new data arrives, the receive request
* is serviced first. When all data is received, the UART driver notifies the upper layer
* through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
* For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
* The 5 bytes are copied to the xfer->data and this function returns with the
* parameter @p receivedBytes set to 5. For the left 5 bytes, newly arrived data is
* saved from the xfer->data[5]. When 5 bytes are received, the UART driver notifies the upper layer.
* If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
* to receive data to the xfer->data. When all data is received, the upper layer is notified.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param xfer UART transfer structure, refer to #uart_transfer_t.
* @param receivedBytes Bytes received from the ring buffer directly.
* @retval kStatus_Success Successfully queue the transfer into transmit queue.
* @retval kStatus_UART_RxBusy Previous receive request is not finished.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t UART_TransferReceiveNonBlocking(UART_Type *base,
uart_handle_t *handle,
uart_transfer_t *xfer,
size_t *receivedBytes);
/*!
* @brief Aborts the interrupt-driven data receiving.
*
* This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
* how many bytes not received yet.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
*/
void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param count Receive bytes count.
* @retval kStatus_NoTransferInProgress No receive in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, uint32_t *count);
/*!
* @brief UART IRQ handle function.
*
* This function handles the UART transmit and receive IRQ request.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
*/
void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle);
/*!
* @brief UART Error IRQ handle function.
*
* This function handle the UART error IRQ request.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
*/
void UART_TransferHandleErrorIRQ(UART_Type *base, uart_handle_t *handle);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_UART_H_ */

View File

@ -1,365 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_uart_dma.h"
#include "fsl_dmamux.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Array of UART handle. */
#if (defined(UART5))
#define UART_HANDLE_ARRAY_SIZE 6
#else /* UART5 */
#if (defined(UART4))
#define UART_HANDLE_ARRAY_SIZE 5
#else /* UART4 */
#if (defined(UART3))
#define UART_HANDLE_ARRAY_SIZE 4
#else /* UART3 */
#if (defined(UART2))
#define UART_HANDLE_ARRAY_SIZE 3
#else /* UART2 */
#if (defined(UART1))
#define UART_HANDLE_ARRAY_SIZE 2
#else /* UART1 */
#if (defined(UART0))
#define UART_HANDLE_ARRAY_SIZE 1
#else /* UART0 */
#error No UART instance.
#endif /* UART 0 */
#endif /* UART 1 */
#endif /* UART 2 */
#endif /* UART 3 */
#endif /* UART 4 */
#endif /* UART 5 */
/*<! Structure definition for uart_dma_handle_t. The structure is private. */
typedef struct _uart_dma_private_handle
{
UART_Type *base;
uart_dma_handle_t *handle;
} uart_dma_private_handle_t;
/* UART DMA transfer handle. */
enum _uart_dma_tansfer_states
{
kUART_TxIdle, /* TX idle. */
kUART_TxBusy, /* TX busy. */
kUART_RxIdle, /* RX idle. */
kUART_RxBusy /* RX busy. */
};
/*******************************************************************************
* Variables
******************************************************************************/
/*<! Private handle only used for internally. */
static uart_dma_private_handle_t s_dmaPrivateHandle[UART_HANDLE_ARRAY_SIZE];
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief UART DMA send finished callback function.
*
* This function is called when UART DMA send finished. It disables the UART
* TX DMA request and sends @ref kStatus_UART_TxIdle to UART callback.
*
* @param handle The DMA handle.
* @param param Callback function parameter.
*/
static void UART_TransferSendDMACallback(dma_handle_t *handle, void *param);
/*!
* @brief UART DMA receive finished callback function.
*
* This function is called when UART DMA receive finished. It disables the UART
* RX DMA request and sends @ref kStatus_UART_RxIdle to UART callback.
*
* @param handle The DMA handle.
* @param param Callback function parameter.
*/
static void UART_TransferReceiveDMACallback(dma_handle_t *handle, void *param);
/*!
* @brief Get the UART instance from peripheral base address.
*
* @param base UART peripheral base address.
* @return UART instance.
*/
extern uint32_t UART_GetInstance(UART_Type *base);
/*******************************************************************************
* Code
******************************************************************************/
static void UART_TransferSendDMACallback(dma_handle_t *handle, void *param)
{
uart_dma_private_handle_t *uartPrivateHandle = (uart_dma_private_handle_t *)param;
/* Disable UART TX DMA. */
UART_EnableTxDMA(uartPrivateHandle->base, false);
/* Disable interrupt. */
DMA_DisableInterrupts(handle->base, handle->channel);
uartPrivateHandle->handle->txState = kUART_TxIdle;
if (uartPrivateHandle->handle->callback)
{
uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle, kStatus_UART_TxIdle,
uartPrivateHandle->handle->userData);
}
}
static void UART_TransferReceiveDMACallback(dma_handle_t *handle, void *param)
{
uart_dma_private_handle_t *uartPrivateHandle = (uart_dma_private_handle_t *)param;
/* Disable UART RX DMA. */
UART_EnableRxDMA(uartPrivateHandle->base, false);
/* Disable interrupt. */
DMA_DisableInterrupts(handle->base, handle->channel);
uartPrivateHandle->handle->rxState = kUART_RxIdle;
if (uartPrivateHandle->handle->callback)
{
uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle, kStatus_UART_RxIdle,
uartPrivateHandle->handle->userData);
}
}
void UART_TransferCreateHandleDMA(UART_Type *base,
uart_dma_handle_t *handle,
uart_dma_transfer_callback_t callback,
void *userData,
dma_handle_t *txDmaHandle,
dma_handle_t *rxDmaHandle)
{
assert(handle);
uint32_t instance = UART_GetInstance(base);
memset(handle, 0, sizeof(*handle));
s_dmaPrivateHandle[instance].base = base;
s_dmaPrivateHandle[instance].handle = handle;
handle->rxState = kUART_RxIdle;
handle->txState = kUART_TxIdle;
handle->callback = callback;
handle->userData = userData;
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
/* Note:
Take care of the RX FIFO, DMA request only assert when received bytes
equal or more than RX water mark, there is potential issue if RX water
mark larger than 1.
For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and
5 bytes are received. the last byte will be saved in FIFO but not trigger
DMA transfer because the water mark is 2.
*/
if (rxDmaHandle)
{
base->RWFIFO = 1U;
}
#endif
handle->rxDmaHandle = rxDmaHandle;
handle->txDmaHandle = txDmaHandle;
/* Configure TX. */
if (txDmaHandle)
{
DMA_SetCallback(txDmaHandle, UART_TransferSendDMACallback, &s_dmaPrivateHandle[instance]);
}
/* Configure RX. */
if (rxDmaHandle)
{
DMA_SetCallback(rxDmaHandle, UART_TransferReceiveDMACallback, &s_dmaPrivateHandle[instance]);
}
}
status_t UART_TransferSendDMA(UART_Type *base, uart_dma_handle_t *handle, uart_transfer_t *xfer)
{
assert(handle->txDmaHandle);
dma_transfer_config_t xferConfig;
status_t status;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* If previous TX not finished. */
if (kUART_TxBusy == handle->txState)
{
status = kStatus_UART_TxBusy;
}
else
{
handle->txState = kUART_TxBusy;
handle->txDataSizeAll = xfer->dataSize;
/* Prepare transfer. */
DMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)UART_GetDataRegisterAddress(base),
sizeof(uint8_t), xfer->dataSize, kDMA_MemoryToPeripheral);
/* Submit transfer. */
DMA_SubmitTransfer(handle->txDmaHandle, &xferConfig, kDMA_EnableInterrupt);
DMA_StartTransfer(handle->txDmaHandle);
/* Enable UART TX DMA. */
UART_EnableTxDMA(base, true);
status = kStatus_Success;
}
return status;
}
status_t UART_TransferReceiveDMA(UART_Type *base, uart_dma_handle_t *handle, uart_transfer_t *xfer)
{
assert(handle->rxDmaHandle);
dma_transfer_config_t xferConfig;
status_t status;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* If previous RX not finished. */
if (kUART_RxBusy == handle->rxState)
{
status = kStatus_UART_RxBusy;
}
else
{
handle->rxState = kUART_RxBusy;
handle->rxDataSizeAll = xfer->dataSize;
/* Prepare transfer. */
DMA_PrepareTransfer(&xferConfig, (void *)UART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data,
sizeof(uint8_t), xfer->dataSize, kDMA_PeripheralToMemory);
/* Submit transfer. */
DMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig, kDMA_EnableInterrupt);
DMA_StartTransfer(handle->rxDmaHandle);
/* Enable UART RX DMA. */
UART_EnableRxDMA(base, true);
status = kStatus_Success;
}
return status;
}
void UART_TransferAbortSendDMA(UART_Type *base, uart_dma_handle_t *handle)
{
assert(handle->txDmaHandle);
/* Disable UART TX DMA. */
UART_EnableTxDMA(base, false);
/* Stop transfer. */
DMA_AbortTransfer(handle->txDmaHandle);
/* Write DMA->DSR[DONE] to abort transfer and clear status. */
DMA_ClearChannelStatusFlags(handle->txDmaHandle->base, handle->txDmaHandle->channel, kDMA_TransactionsDoneFlag);
handle->txState = kUART_TxIdle;
}
void UART_TransferAbortReceiveDMA(UART_Type *base, uart_dma_handle_t *handle)
{
assert(handle->rxDmaHandle);
/* Disable UART RX DMA. */
UART_EnableRxDMA(base, false);
/* Stop transfer. */
DMA_AbortTransfer(handle->rxDmaHandle);
/* Write DMA->DSR[DONE] to abort transfer and clear status. */
DMA_ClearChannelStatusFlags(handle->rxDmaHandle->base, handle->rxDmaHandle->channel, kDMA_TransactionsDoneFlag);
handle->rxState = kUART_RxIdle;
}
status_t UART_TransferGetSendCountDMA(UART_Type *base, uart_dma_handle_t *handle, uint32_t *count)
{
assert(handle->txDmaHandle);
if (kUART_TxIdle == handle->txState)
{
return kStatus_NoTransferInProgress;
}
if (!count)
{
return kStatus_InvalidArgument;
}
*count = handle->txDataSizeAll - DMA_GetRemainingBytes(handle->txDmaHandle->base, handle->txDmaHandle->channel);
return kStatus_Success;
}
status_t UART_TransferGetReceiveCountDMA(UART_Type *base, uart_dma_handle_t *handle, uint32_t *count)
{
assert(handle->rxDmaHandle);
if (kUART_RxIdle == handle->rxState)
{
return kStatus_NoTransferInProgress;
}
if (!count)
{
return kStatus_InvalidArgument;
}
*count = handle->rxDataSizeAll - DMA_GetRemainingBytes(handle->rxDmaHandle->base, handle->rxDmaHandle->channel);
return kStatus_Success;
}

View File

@ -1,193 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_UART_DMA_H_
#define _FSL_UART_DMA_H_
#include "fsl_uart.h"
#include "fsl_dmamux.h"
#include "fsl_dma.h"
/*!
* @addtogroup uart_dma_driver
* @{
*/
/*! @file*/
/*******************************************************************************
* Definitions
******************************************************************************/
/* Forward declaration of the handle typedef. */
typedef struct _uart_dma_handle uart_dma_handle_t;
/*! @brief UART transfer callback function. */
typedef void (*uart_dma_transfer_callback_t)(UART_Type *base,
uart_dma_handle_t *handle,
status_t status,
void *userData);
/*!
* @brief UART DMA handle
*/
struct _uart_dma_handle
{
UART_Type *base; /*!< UART peripheral base address. */
uart_dma_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< UART callback function parameter.*/
size_t rxDataSizeAll; /*!< Size of the data to receive. */
size_t txDataSizeAll; /*!< Size of the data to send out. */
dma_handle_t *txDmaHandle; /*!< The DMA TX channel used. */
dma_handle_t *rxDmaHandle; /*!< The DMA RX channel used. */
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name EDMA transactional
* @{
*/
/*!
* @brief Initializes the UART handle which is used in transactional functions and sets the callback.
*
* @param base UART peripheral base address.
* @param handle Pointer to uart_dma_handle_t structure.
* @param callback UART callback, NULL means no callback.
* @param userData User callback function data.
* @param rxDmaHandle User requested DMA handle for RX DMA transfer.
* @param txDmaHandle User requested DMA handle for TX DMA transfer.
*/
void UART_TransferCreateHandleDMA(UART_Type *base,
uart_dma_handle_t *handle,
uart_dma_transfer_callback_t callback,
void *userData,
dma_handle_t *txDmaHandle,
dma_handle_t *rxDmaHandle);
/*!
* @brief Sends data using DMA.
*
* This function sends data using DMA. This is non-blocking function, which returns
* right away. When all data is sent, the send callback function is called.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param xfer UART DMA transfer structure. See #uart_transfer_t.
* @retval kStatus_Success if succeed, others failed.
* @retval kStatus_UART_TxBusy Previous transfer on going.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t UART_TransferSendDMA(UART_Type *base, uart_dma_handle_t *handle, uart_transfer_t *xfer);
/*!
* @brief Receives data using DMA.
*
* This function receives data using DMA. This is non-blocking function, which returns
* right away. When all data is received, the receive callback function is called.
*
* @param base UART peripheral base address.
* @param handle Pointer to uart_dma_handle_t structure.
* @param xfer UART DMA transfer structure. See #uart_transfer_t.
* @retval kStatus_Success if succeed, others failed.
* @retval kStatus_UART_RxBusy Previous transfer on going.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t UART_TransferReceiveDMA(UART_Type *base, uart_dma_handle_t *handle, uart_transfer_t *xfer);
/*!
* @brief Aborts the send data using DMA.
*
* This function aborts the sent data using DMA.
*
* @param base UART peripheral base address.
* @param handle Pointer to uart_dma_handle_t structure.
*/
void UART_TransferAbortSendDMA(UART_Type *base, uart_dma_handle_t *handle);
/*!
* @brief Aborts the received data using DMA.
*
* This function abort receive data which using DMA.
*
* @param base UART peripheral base address.
* @param handle Pointer to uart_dma_handle_t structure.
*/
void UART_TransferAbortReceiveDMA(UART_Type *base, uart_dma_handle_t *handle);
/*!
* @brief Get the number of bytes that have been written to UART TX register.
*
* This function gets the number of bytes that have been written to UART TX
* register by DMA.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param count Send bytes count.
* @retval kStatus_NoTransferInProgress No send in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t UART_TransferGetSendCountDMA(UART_Type *base, uart_dma_handle_t *handle, uint32_t *count);
/*!
* @brief Get the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*
* @param base UART peripheral base address.
* @param handle UART handle pointer.
* @param count Receive bytes count.
* @retval kStatus_NoTransferInProgress No receive in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t UART_TransferGetReceiveCountDMA(UART_Type *base, uart_dma_handle_t *handle, uint32_t *count);
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_UART_DMA_H_ */

View File

@ -1,172 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_vref.h"
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Gets the instance from the base address
*
* @param base VREF peripheral base address
*
* @return The VREF instance
*/
static uint32_t VREF_GetInstance(VREF_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to VREF bases for each instance. */
static VREF_Type *const s_vrefBases[] = VREF_BASE_PTRS;
/*! @brief Pointers to VREF clocks for each instance. */
static const clock_ip_name_t s_vrefClocks[] = VREF_CLOCKS;
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t VREF_GetInstance(VREF_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < FSL_FEATURE_SOC_VREF_COUNT; instance++)
{
if (s_vrefBases[instance] == base)
{
break;
}
}
assert(instance < FSL_FEATURE_SOC_VREF_COUNT);
return instance;
}
void VREF_Init(VREF_Type *base, const vref_config_t *config)
{
assert(config != NULL);
uint8_t reg = 0U;
/* Ungate clock for VREF */
CLOCK_EnableClock(s_vrefClocks[VREF_GetInstance(base)]);
/* Configure VREF to a known state */
#if defined(FSL_FEATURE_VREF_HAS_CHOP_OSC) && FSL_FEATURE_VREF_HAS_CHOP_OSC
/* Set chop oscillator bit */
base->TRM |= VREF_TRM_CHOPEN_MASK;
#endif /* FSL_FEATURE_VREF_HAS_CHOP_OSC */
reg = base->SC;
/* Set buffer Mode selection and Regulator enable bit */
reg |= VREF_SC_MODE_LV(config->bufferMode) | VREF_SC_REGEN(1U);
#if defined(FSL_FEATURE_VREF_HAS_COMPENSATION) && FSL_FEATURE_VREF_HAS_COMPENSATION
/* Set second order curvature compensation enable bit */
reg |= VREF_SC_ICOMPEN(1U);
#endif /* FSL_FEATURE_VREF_HAS_COMPENSATION */
/* Enable VREF module */
reg |= VREF_SC_VREFEN(1U);
/* Update bit-field from value to Status and Control register */
base->SC = reg;
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
reg = base->VREFL_TRM;
/* Clear old select external voltage reference and VREFL (0.4 V) reference buffer enable bits*/
reg &= ~(VREF_VREFL_TRM_VREFL_EN_MASK | VREF_VREFL_TRM_VREFL_SEL_MASK);
/* Select external voltage reference and set VREFL (0.4 V) reference buffer enable */
reg |= VREF_VREFL_TRM_VREFL_SEL(config->enableExternalVoltRef) | VREF_VREFL_TRM_VREFL_EN(config->enableLowRef);
base->VREFL_TRM = reg;
#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */
/* Wait until internal voltage stable */
while ((base->SC & VREF_SC_VREFST_MASK) == 0)
{
}
}
void VREF_Deinit(VREF_Type *base)
{
/* Gate clock for VREF */
CLOCK_DisableClock(s_vrefClocks[VREF_GetInstance(base)]);
}
void VREF_GetDefaultConfig(vref_config_t *config)
{
/* Set High power buffer mode in */
#if defined(FSL_FEATURE_VREF_MODE_LV_TYPE) && FSL_FEATURE_VREF_MODE_LV_TYPE
config->bufferMode = kVREF_ModeHighPowerBuffer;
#else
config->bufferMode = kVREF_ModeTightRegulationBuffer;
#endif /* FSL_FEATURE_VREF_MODE_LV_TYPE */
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
/* Select internal voltage reference */
config->enableExternalVoltRef = false;
/* Set VREFL (0.4 V) reference buffer disable */
config->enableLowRef = false;
#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */
}
void VREF_SetTrimVal(VREF_Type *base, uint8_t trimValue)
{
uint8_t reg = 0U;
/* Set TRIM bits value in voltage reference */
reg = base->TRM;
reg = ((reg & ~VREF_TRM_TRIM_MASK) | VREF_TRM_TRIM(trimValue));
base->TRM = reg;
/* Wait until internal voltage stable */
while ((base->SC & VREF_SC_VREFST_MASK) == 0)
{
}
}
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
void VREF_SetLowReferenceTrimVal(VREF_Type *base, uint8_t trimValue)
{
/* The values 111b and 110b are NOT valid/allowed */
assert((trimValue != 0x7U) && (trimValue != 0x6U));
uint8_t reg = 0U;
/* Set TRIM bits value in low voltage reference */
reg = base->VREFL_TRM;
reg = ((reg & ~VREF_VREFL_TRM_VREFL_TRIM_MASK) | VREF_VREFL_TRM_VREFL_TRIM(trimValue));
base->VREFL_TRM = reg;
/* Wait until internal voltage stable */
while ((base->SC & VREF_SC_VREFST_MASK) == 0)
{
}
}
#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */

View File

@ -1,228 +0,0 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_VREF_H_
#define _FSL_VREF_H_
#include "fsl_common.h"
/*!
* @addtogroup vref
* @{
*/
/*! @file */
/******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
#define FSL_VREF_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
/*@}*/
/* Those macros below defined to support SoC family which have VREFL (0.4V) reference */
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
#define SC VREFH_SC
#define VREF_SC_MODE_LV VREF_VREFH_SC_MODE_LV
#define VREF_SC_REGEN VREF_VREFH_SC_REGEN
#define VREF_SC_VREFEN VREF_VREFH_SC_VREFEN
#define VREF_SC_ICOMPEN VREF_VREFH_SC_ICOMPEN
#define VREF_SC_REGEN_MASK VREF_VREFH_SC_REGEN_MASK
#define VREF_SC_VREFST_MASK VREF_VREFH_SC_VREFST_MASK
#define VREF_SC_VREFEN_MASK VREF_VREFH_SC_VREFEN_MASK
#define VREF_SC_MODE_LV_MASK VREF_VREFH_SC_MODE_LV_MASK
#define VREF_SC_ICOMPEN_MASK VREF_VREFH_SC_ICOMPEN_MASK
#define TRM VREFH_TRM
#define VREF_TRM_TRIM VREF_VREFH_TRM_TRIM
#define VREF_TRM_CHOPEN_MASK VREF_VREFH_TRM_CHOPEN_MASK
#define VREF_TRM_TRIM_MASK VREF_VREFH_TRM_TRIM_MASK
#define VREF_TRM_CHOPEN_SHIFT VREF_VREFH_TRM_CHOPEN_SHIFT
#define VREF_TRM_TRIM_SHIFT VREF_VREFH_TRM_TRIM_SHIFT
#define VREF_SC_MODE_LV_SHIFT VREF_VREFH_SC_MODE_LV_SHIFT
#define VREF_SC_REGEN_SHIFT VREF_VREFH_SC_REGEN_SHIFT
#define VREF_SC_VREFST_SHIFT VREF_VREFH_SC_VREFST_SHIFT
#define VREF_SC_ICOMPEN_SHIFT VREF_VREFH_SC_ICOMPEN_SHIFT
#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */
/*!
* @brief VREF modes.
*/
typedef enum _vref_buffer_mode
{
kVREF_ModeBandgapOnly = 0U, /*!< Bandgap on only, for stabilization and startup */
#if defined(FSL_FEATURE_VREF_MODE_LV_TYPE) && FSL_FEATURE_VREF_MODE_LV_TYPE
kVREF_ModeHighPowerBuffer = 1U, /*!< High power buffer mode enabled */
kVREF_ModeLowPowerBuffer = 2U /*!< Low power buffer mode enabled */
#else
kVREF_ModeTightRegulationBuffer = 2U /*!< Tight regulation buffer enabled */
#endif /* FSL_FEATURE_VREF_MODE_LV_TYPE */
} vref_buffer_mode_t;
/*!
* @brief The description structure for the VREF module.
*/
typedef struct _vref_config
{
vref_buffer_mode_t bufferMode; /*!< Buffer mode selection */
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
bool enableLowRef; /*!< Set VREFL (0.4 V) reference buffer enable or disable */
bool enableExternalVoltRef; /*!< Select external voltage reference or not (internal) */
#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */
} vref_config_t;
/******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*!
* @name VREF functional operation
* @{
*/
/*!
* @brief Enables the clock gate and configures the VREF module according to the configuration structure.
*
* This function must be called before calling all the other VREF driver functions,
* read/write registers, and configurations with user-defined settings.
* The example below shows how to set up vref_config_t parameters and
* how to call the VREF_Init function by passing in these parameters:
* Example:
* @code
* vref_config_t vrefConfig;
* vrefConfig.bufferMode = kVREF_ModeHighPowerBuffer;
* vrefConfig.enableExternalVoltRef = false;
* vrefConfig.enableLowRef = false;
* VREF_Init(VREF, &vrefConfig);
* @endcode
*
* @param base VREF peripheral address.
* @param config Pointer to the configuration structure.
*/
void VREF_Init(VREF_Type *base, const vref_config_t *config);
/*!
* @brief Stops and disables the clock for the VREF module.
*
* This function should be called to shut down the module.
* Example:
* @code
* vref_config_t vrefUserConfig;
* VREF_Init(VREF);
* VREF_GetDefaultConfig(&vrefUserConfig);
* ...
* VREF_Deinit(VREF);
* @endcode
*
* @param base VREF peripheral address.
*/
void VREF_Deinit(VREF_Type *base);
/*!
* @brief Initializes the VREF configuration structure.
*
* This function initializes the VREF configuration structure to a default value.
* Example:
* @code
* vrefConfig->bufferMode = kVREF_ModeHighPowerBuffer;
* vrefConfig->enableExternalVoltRef = false;
* vrefConfig->enableLowRef = false;
* @endcode
*
* @param config Pointer to the initialization structure.
*/
void VREF_GetDefaultConfig(vref_config_t *config);
/*!
* @brief Sets a TRIM value for reference voltage.
*
* This function sets a TRIM value for reference voltage.
* Note that the TRIM value maximum is 0x3F.
*
* @param base VREF peripheral address.
* @param trimValue Value of the trim register to set the output reference voltage (maximum 0x3F (6-bit)).
*/
void VREF_SetTrimVal(VREF_Type *base, uint8_t trimValue);
/*!
* @brief Reads the value of the TRIM meaning output voltage.
*
* This function gets the TRIM value from the TRM register.
*
* @param base VREF peripheral address.
* @return Six-bit value of trim setting.
*/
static inline uint8_t VREF_GetTrimVal(VREF_Type *base)
{
return (base->TRM & VREF_TRM_TRIM_MASK);
}
#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE
/*!
* @brief Sets the TRIM value for low voltage reference.
*
* This function sets the TRIM value for low reference voltage.
* NOTE:
* - The TRIM value maximum is 0x05U
* - The values 111b and 110b are not valid/allowed.
*
* @param base VREF peripheral address.
* @param trimValue Value of the trim register to set output low reference voltage (maximum 0x05U (3-bit)).
*/
void VREF_SetLowReferenceTrimVal(VREF_Type *base, uint8_t trimValue);
/*!
* @brief Reads the value of the TRIM meaning output voltage.
*
* This function gets the TRIM value from the VREFL_TRM register.
*
* @param base VREF peripheral address.
* @return Three-bit value of the trim setting.
*/
static inline uint8_t VREF_GetLowReferenceTrimVal(VREF_Type *base)
{
return (base->VREFL_TRM & VREF_VREFL_TRM_VREFL_TRIM_MASK);
}
#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */
/*@}*/
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/*! @}*/
#endif /* _FSL_VREF_H_ */

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSL_PERIPHERAL_CLOCK_H_
#define _FSL_PERIPHERAL_CLOCK_H_
#include "fsl_clock.h"
/* Array for UART module clocks */
#define UART_CLOCK_FREQS \
{ \
kCLOCK_IpInvalid, kCLOCK_IpInvalid, UART2_CLK_SRC \
}
/* Array for LPUART module clocks */
#define LPUART_CLOCK_FREQS \
{ \
kCLOCK_McgIrc48MClk, kCLOCK_McgIrc48MClk \
}
/* Array for I2C module clocks */
#define I2C_CLOCK_FREQS \
{ \
I2C0_CLK_SRC, I2C1_CLK_SRC \
}
/* Array for DSPI module clocks */
#define SPI_CLOCK_FREQS \
{ \
SPI0_CLK_SRC, SPI1_CLK_SRC \
}
#endif /* _FSL_PERIPHERAL_CLOCK_H_ */

View File

@ -1,175 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_assert.h"
#include "pwmout_api.h"
#if DEVICE_PWMOUT
#include "cmsis.h"
#include "pinmap.h"
#include "fsl_tpm.h"
#include "PeripheralPins.h"
static float pwm_clock_mhz;
/* Array of TPM peripheral base address. */
static TPM_Type *const tpm_addrs[] = TPM_BASE_PTRS;
void pwmout_init(pwmout_t *obj, PinName pin)
{
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
MBED_ASSERT(pwm != (PWMName)NC);
obj->pwm_name = pwm;
uint32_t pwm_base_clock;
/* TPM clock source is set to IRC48M during init */
pwm_base_clock = CLOCK_GetFreq(kCLOCK_McgIrc48MClk);
float clkval = (float)pwm_base_clock / 1000000.0f;
uint32_t clkdiv = 0;
while (clkval > 1) {
clkdiv++;
clkval /= 2.0f;
if (clkdiv == 7) {
break;
}
}
pwm_clock_mhz = clkval;
uint32_t channel = pwm & 0xF;
uint32_t instance = pwm >> TPM_SHIFT;
tpm_config_t tpmInfo;
TPM_GetDefaultConfig(&tpmInfo);
tpmInfo.prescale = (tpm_clock_prescale_t)clkdiv;
/* Initialize TPM module */
TPM_Init(tpm_addrs[instance], &tpmInfo);
tpm_chnl_pwm_signal_param_t config = {
.chnlNumber = (tpm_chnl_t)channel,
.level = kTPM_HighTrue,
.dutyCyclePercent = 0,
};
// default to 20ms: standard for servos, and fine for e.g. brightness control
TPM_SetupPwm(tpm_addrs[instance], &config, 1, kTPM_EdgeAlignedPwm, 50, pwm_base_clock);
TPM_StartTimer(tpm_addrs[instance], kTPM_SystemClock);
// Wire pinout
pinmap_pinout(pin, PinMap_PWM);
}
void pwmout_free(pwmout_t *obj)
{
TPM_Deinit(tpm_addrs[obj->pwm_name >> TPM_SHIFT]);
}
void pwmout_write(pwmout_t *obj, float value)
{
if (value < 0.0f) {
value = 0.0f;
} else if (value > 1.0f) {
value = 1.0f;
}
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
uint16_t mod = base->MOD & TPM_MOD_MOD_MASK;
uint32_t new_count = (uint32_t)((float)(mod) * value);
// Update of CnV register
base->CONTROLS[obj->pwm_name & 0xF].CnV = new_count;
base->CNT = 0;
}
float pwmout_read(pwmout_t *obj)
{
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & TPM_CnV_VAL_MASK;
uint16_t mod = base->MOD & TPM_MOD_MOD_MASK;
if (mod == 0) {
return 0.0;
}
float v = (float)(count) / (float)(mod);
return (v > 1.0f) ? (1.0f) : (v);
}
void pwmout_period(pwmout_t *obj, float seconds)
{
pwmout_period_us(obj, seconds * 1000000.0f);
}
void pwmout_period_ms(pwmout_t *obj, int ms)
{
pwmout_period_us(obj, ms * 1000);
}
// Set the PWM period, keeping the duty cycle the same.
void pwmout_period_us(pwmout_t *obj, int us)
{
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
float dc = pwmout_read(obj);
// Stop TPM clock to ensure instant update of MOD register
base->MOD = TPM_MOD_MOD((pwm_clock_mhz * (float)us) - 1);
pwmout_write(obj, dc);
}
int pwmout_read_period_us(pwmout_t *obj)
{
uint32_t pwm_period = 0;
if (pwm_clock_mhz > 0) {
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
pwm_period = ((base->MOD) + 1) / pwm_clock_mhz;
}
return pwm_period;
}
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
{
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
}
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
{
pwmout_pulsewidth_us(obj, ms * 1000);
}
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
{
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us);
// Update of CnV register
base->CONTROLS[obj->pwm_name & 0xF].CnV = value;
}
int pwmout_read_pulsewidth_us(pwmout_t *obj)
{
uint32_t pwm_pulsewidth = 0;
if (pwm_clock_mhz > 0) {
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz;
}
return pwm_pulsewidth;
}
const PinMap *pwmout_pinmap()
{
return PinMap_PWM;
}
#endif

View File

@ -1,334 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "serial_api.h"
#if DEVICE_SERIAL
// math.h required for floating point operations for baud rate calculation
#include <math.h>
#include "mbed_assert.h"
#include <string.h>
#include "cmsis.h"
#include "pinmap.h"
#include "fsl_lpuart.h"
#include "peripheral_clock_defines.h"
#include "PeripheralPins.h"
#include "fsl_clock_config.h"
static uint32_t serial_irq_ids[FSL_FEATURE_SOC_LPUART_COUNT] = {0};
static uart_irq_handler irq_handler;
/* Array of UART peripheral base address. */
static LPUART_Type *const uart_addrs[] = LPUART_BASE_PTRS;
/* Array of LPUART bus clock frequencies */
static clock_name_t const uart_clocks[] = LPUART_CLOCK_FREQS;
int stdio_uart_inited = 0;
serial_t stdio_uart;
void serial_init(serial_t *obj, PinName tx, PinName rx)
{
uint32_t uart_tx = pinmap_peripheral(tx, PinMap_UART_TX);
uint32_t uart_rx = pinmap_peripheral(rx, PinMap_UART_RX);
obj->index = pinmap_merge(uart_tx, uart_rx);
MBED_ASSERT((int)obj->index != NC);
/* Set the LPUART clock source */
if (obj->index == LPUART_0) {
CLOCK_SetLpuart0Clock(1U);
} else {
CLOCK_SetLpuart1Clock(1U);
}
lpuart_config_t config;
LPUART_GetDefaultConfig(&config);
config.baudRate_Bps = 9600;
config.enableTx = false;
config.enableRx = false;
LPUART_Init(uart_addrs[obj->index], &config, CLOCK_GetFreq(uart_clocks[obj->index]));
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
if (tx != NC) {
LPUART_EnableTx(uart_addrs[obj->index], true);
pin_mode(tx, PullUp);
}
if (rx != NC) {
LPUART_EnableRx(uart_addrs[obj->index], true);
pin_mode(rx, PullUp);
}
if (obj->index == STDIO_UART) {
stdio_uart_inited = 1;
memcpy(&stdio_uart, obj, sizeof(serial_t));
}
}
void serial_free(serial_t *obj)
{
LPUART_Deinit(uart_addrs[obj->index]);
serial_irq_ids[obj->index] = 0;
}
void serial_baud(serial_t *obj, int baudrate)
{
LPUART_SetBaudRate(uart_addrs[obj->index], (uint32_t)baudrate, CLOCK_GetFreq(uart_clocks[obj->index]));
}
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
LPUART_Type *base = uart_addrs[obj->index];
uint8_t temp;
/* Set bit count and parity mode. */
temp = base->CTRL & ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK);
if (parity != ParityNone)
{
/* Enable Parity */
temp |= (LPUART_CTRL_PE_MASK | LPUART_CTRL_M_MASK);
if (parity == ParityOdd) {
temp |= LPUART_CTRL_PT_MASK;
} else if (parity == ParityEven) {
// PT=0 so nothing more to do
} else {
// Hardware does not support forced parity
MBED_ASSERT(0);
}
}
base->CTRL = temp;
#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
/* set stop bit per char */
temp = base->BAUD & ~LPUART_BAUD_SBNS_MASK;
base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)--stop_bits);
#endif
}
/******************************************************************************
* INTERRUPTS HANDLING
******************************************************************************/
static inline void uart_irq(uint32_t transmit_empty, uint32_t receive_full, uint32_t index)
{
LPUART_Type *base = uart_addrs[index];
/* If RX overrun. */
if (LPUART_STAT_OR_MASK & base->STAT)
{
/* Read base->D, otherwise the RX does not work. */
(void)base->DATA;
LPUART_ClearStatusFlags(base, kLPUART_RxOverrunFlag);
}
if (serial_irq_ids[index] != 0) {
if (transmit_empty && (LPUART_GetEnabledInterrupts(uart_addrs[index]) & kLPUART_TxDataRegEmptyInterruptEnable))
irq_handler(serial_irq_ids[index], TxIrq);
if (receive_full && (LPUART_GetEnabledInterrupts(uart_addrs[index]) & kLPUART_RxDataRegFullInterruptEnable))
irq_handler(serial_irq_ids[index], RxIrq);
}
}
void uart0_irq()
{
uint32_t status_flags = LPUART0->STAT;
uart_irq((status_flags & kLPUART_TxDataRegEmptyFlag), (status_flags & kLPUART_RxDataRegFullFlag), 0);
}
void uart1_irq()
{
uint32_t status_flags = LPUART1->STAT;
uart_irq((status_flags & kLPUART_TxDataRegEmptyFlag), (status_flags & kLPUART_RxDataRegFullFlag), 1);
}
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
{
irq_handler = handler;
serial_irq_ids[obj->index] = id;
}
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
{
IRQn_Type uart_irqs[] = LPUART_RX_TX_IRQS;
uint32_t vector = 0;
switch (obj->index) {
case 0:
vector = (uint32_t)&uart0_irq;
break;
case 1:
vector = (uint32_t)&uart1_irq;
break;
default:
break;
}
if (enable) {
switch (irq) {
case RxIrq:
LPUART_EnableInterrupts(uart_addrs[obj->index], kLPUART_RxDataRegFullInterruptEnable);
break;
case TxIrq:
LPUART_EnableInterrupts(uart_addrs[obj->index], kLPUART_TxDataRegEmptyInterruptEnable);
break;
default:
break;
}
NVIC_SetVector(uart_irqs[obj->index], vector);
NVIC_EnableIRQ(uart_irqs[obj->index]);
} else { // disable
int all_disabled = 0;
SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
switch (irq) {
case RxIrq:
LPUART_DisableInterrupts(uart_addrs[obj->index], kLPUART_RxDataRegFullInterruptEnable);
break;
case TxIrq:
LPUART_DisableInterrupts(uart_addrs[obj->index], kLPUART_TxDataRegEmptyInterruptEnable);
break;
default:
break;
}
switch (other_irq) {
case RxIrq:
all_disabled = ((LPUART_GetEnabledInterrupts(uart_addrs[obj->index]) & kLPUART_RxDataRegFullInterruptEnable) == 0);
break;
case TxIrq:
all_disabled = ((LPUART_GetEnabledInterrupts(uart_addrs[obj->index]) & kLPUART_TxDataRegEmptyInterruptEnable) == 0);
break;
default:
break;
}
if (all_disabled)
NVIC_DisableIRQ(uart_irqs[obj->index]);
}
}
int serial_getc(serial_t *obj)
{
uint8_t data;
LPUART_ReadBlocking(uart_addrs[obj->index], &data, 1);
return data;
}
void serial_putc(serial_t *obj, int c)
{
while (!serial_writable(obj));
LPUART_WriteByte(uart_addrs[obj->index], (uint8_t)c);
}
int serial_readable(serial_t *obj)
{
uint32_t status_flags = LPUART_GetStatusFlags(uart_addrs[obj->index]);
if (status_flags & kLPUART_RxOverrunFlag)
LPUART_ClearStatusFlags(uart_addrs[obj->index], kLPUART_RxOverrunFlag);
return (status_flags & kLPUART_RxDataRegFullFlag);
}
int serial_writable(serial_t *obj)
{
uint32_t status_flags = LPUART_GetStatusFlags(uart_addrs[obj->index]);
if (status_flags & kLPUART_RxOverrunFlag)
LPUART_ClearStatusFlags(uart_addrs[obj->index], kLPUART_RxOverrunFlag);
return (status_flags & kLPUART_TxDataRegEmptyFlag);
}
void serial_clear(serial_t *obj)
{
}
void serial_pinout_tx(PinName tx)
{
pinmap_pinout(tx, PinMap_UART_TX);
}
void serial_break_set(serial_t *obj)
{
uart_addrs[obj->index]->CTRL |= LPUART_CTRL_SBK_MASK;
}
void serial_break_clear(serial_t *obj)
{
uart_addrs[obj->index]->CTRL &= ~LPUART_CTRL_SBK_MASK;
}
const PinMap *serial_tx_pinmap()
{
return PinMap_UART_TX;
}
const PinMap *serial_rx_pinmap()
{
return PinMap_UART_RX;
}
const PinMap *serial_cts_pinmap()
{
return PinMap_UART_CTS;
}
const PinMap *serial_rts_pinmap()
{
return PinMap_UART_RTS;
}
static int serial_is_enabled(uint32_t uart_index)
{
int clock_enabled = 0;
switch (uart_index) {
case 0:
clock_enabled = (SIM->SCGC5 & SIM_SCGC5_LPUART0_MASK) >> SIM_SCGC5_LPUART0_SHIFT;
break;
case 1:
clock_enabled = (SIM->SCGC5 & SIM_SCGC5_LPUART1_MASK) >> SIM_SCGC5_LPUART1_SHIFT;
break;
default:
break;
}
return clock_enabled;
}
bool serial_check_tx_ongoing()
{
LPUART_Type *base;
int i;
bool uart_tx_ongoing = false;
for (i = 0; i < FSL_FEATURE_SOC_LPUART_COUNT; i++) {
/* First check if UART is enabled */
if (!serial_is_enabled(i)) {
/* UART is not enabled, check the next instance */
continue;
}
base = uart_addrs[i];
/* Check if data is waiting to be written out of transmit buffer */
if (!(kLPUART_TransmissionCompleteFlag & LPUART_GetStatusFlags((LPUART_Type *)base))) {
uart_tx_ongoing = true;
break;
}
}
return uart_tx_ongoing;
}
#endif

View File

@ -1,198 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2013 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 <math.h>
#include "mbed_assert.h"
#include "spi_api.h"
#if DEVICE_SPI
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#include "fsl_spi.h"
#include "peripheral_clock_defines.h"
#include "PeripheralPins.h"
/* Array of SPI peripheral base address. */
static SPI_Type *const spi_address[] = SPI_BASE_PTRS;
/* Array of SPI bus clock frequencies */
static clock_name_t const spi_clocks[] = SPI_CLOCK_FREQS;
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
{
// determine the SPI to use
uint32_t spi_mosi = pinmap_peripheral(mosi, PinMap_SPI_MOSI);
uint32_t spi_miso = pinmap_peripheral(miso, PinMap_SPI_MISO);
uint32_t spi_sclk = pinmap_peripheral(sclk, PinMap_SPI_SCLK);
uint32_t spi_ssel = pinmap_peripheral(ssel, PinMap_SPI_SSEL);
uint32_t spi_data = pinmap_merge(spi_mosi, spi_miso);
uint32_t spi_cntl = pinmap_merge(spi_sclk, spi_ssel);
obj->instance = pinmap_merge(spi_data, spi_cntl);
MBED_ASSERT((int)obj->instance != NC);
// pin out the spi pins
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
if (ssel != NC) {
pinmap_pinout(ssel, PinMap_SPI_SSEL);
}
}
void spi_free(spi_t *obj)
{
SPI_Deinit(spi_address[obj->instance]);
}
void spi_format(spi_t *obj, int bits, int mode, int slave)
{
spi_master_config_t master_config;
spi_slave_config_t slave_config;
if ((bits != 8) && (bits != 16)) {
error("Only 8bits and 16bits SPI supported");
return;
}
if (slave) {
/* Slave config */
SPI_SlaveGetDefaultConfig(&slave_config);
slave_config.dataMode = (bits == 16) ? kSPI_16BitMode : kSPI_8BitMode;
slave_config.polarity = (mode & 0x2) ? kSPI_ClockPolarityActiveLow : kSPI_ClockPolarityActiveHigh;
slave_config.phase = (mode & 0x1) ? kSPI_ClockPhaseSecondEdge : kSPI_ClockPhaseFirstEdge;
SPI_SlaveInit(spi_address[obj->instance], &slave_config);
} else {
/* Master config */
SPI_MasterGetDefaultConfig(&master_config);
master_config.dataMode = (bits == 16) ? kSPI_16BitMode : kSPI_8BitMode;
master_config.polarity = (mode & 0x2) ? kSPI_ClockPolarityActiveLow : kSPI_ClockPolarityActiveHigh;
master_config.phase = (mode & 0x1) ? kSPI_ClockPhaseSecondEdge : kSPI_ClockPhaseFirstEdge;
master_config.direction = kSPI_MsbFirst;
SPI_MasterInit(spi_address[obj->instance], &master_config, CLOCK_GetFreq(spi_clocks[obj->instance]));
}
}
void spi_frequency(spi_t *obj, int hz)
{
SPI_MasterSetBaudRate(spi_address[obj->instance], (uint32_t)hz, CLOCK_GetFreq(spi_clocks[obj->instance]));
}
static inline int spi_readable(spi_t * obj)
{
return (SPI_GetStatusFlags(spi_address[obj->instance]) & kSPI_RxBufferFullFlag);
}
int spi_master_write(spi_t *obj, int value)
{
spi_transfer_t xfer = {0};
uint32_t rx_data;
SPI_Type *base = spi_address[obj->instance];
/* SPI master start transfer */
xfer.txData = (uint8_t *)&value;
xfer.rxData = (uint8_t *)&rx_data;
xfer.dataSize = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U;
SPI_MasterTransferBlocking(base, &xfer);
return rx_data & 0xffff;
}
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
char *rx_buffer, int rx_length, char write_fill)
{
int total = (tx_length > rx_length) ? tx_length : rx_length;
// Default write is done in each and every call, in future can create HAL API instead
SPI_SetDummyData(spi_address[obj->instance], write_fill);
SPI_MasterTransferBlocking(spi_address[obj->instance], &(spi_transfer_t) {
.txData = (uint8_t *)tx_buffer,
.rxData = (uint8_t *)rx_buffer,
.dataSize = total
});
return total;
}
int spi_slave_receive(spi_t *obj)
{
return spi_readable(obj);
}
int spi_slave_read(spi_t *obj)
{
uint32_t rx_data;
while (!spi_readable(obj));
rx_data = SPI_ReadData(spi_address[obj->instance]);
return rx_data & 0xffff;
}
void spi_slave_write(spi_t *obj, int value)
{
SPI_Type *base = spi_address[obj->instance];
size_t size = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U;
SPI_WriteBlocking(spi_address[obj->instance], (uint8_t *)&value, size);
}
const PinMap *spi_master_mosi_pinmap()
{
return PinMap_SPI_MOSI;
}
const PinMap *spi_master_miso_pinmap()
{
return PinMap_SPI_MISO;
}
const PinMap *spi_master_clk_pinmap()
{
return PinMap_SPI_SCLK;
}
const PinMap *spi_master_cs_pinmap()
{
return PinMap_SPI_SSEL;
}
const PinMap *spi_slave_mosi_pinmap()
{
return PinMap_SPI_MOSI;
}
const PinMap *spi_slave_miso_pinmap()
{
return PinMap_SPI_MISO;
}
const PinMap *spi_slave_clk_pinmap()
{
return PinMap_SPI_SCLK;
}
const PinMap *spi_slave_cs_pinmap()
{
return PinMap_SPI_SSEL;
}
#endif

View File

@ -1,161 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2018 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 <stddef.h>
#include "us_ticker_api.h"
#include "us_ticker_defines.h"
#include "PeripheralNames.h"
#include "fsl_pit.h"
#include "fsl_tpm.h"
#include "fsl_clock_config.h"
const ticker_info_t* us_ticker_get_info()
{
static const ticker_info_t info = {
3000000,
32
};
return &info;
}
static bool us_ticker_inited = false;
static uint32_t us_ticker_int_counter = 0;
static uint16_t us_ticker_int_remainder = 0;
static void tpm_isr(void)
{
// Clear the TPM timer overflow flag
TPM_ClearStatusFlags(TPM2, kTPM_TimeOverflowFlag);
TPM_StopTimer(TPM2);
if (us_ticker_int_counter > 0) {
TPM2->MOD = 0xFFFF;
TPM_StartTimer(TPM2, kTPM_SystemClock);
us_ticker_int_counter--;
} else {
if (us_ticker_int_remainder > 0) {
TPM2->MOD = us_ticker_int_remainder;
TPM_StartTimer(TPM2, kTPM_SystemClock);
us_ticker_int_remainder = 0;
} else {
// This function is going to disable the interrupts if there are
// no other events in the queue
us_ticker_irq_handler();
}
}
}
void us_ticker_init(void)
{
/* Common for ticker/timer. */
uint32_t busClock;
/* Structure to initialize PIT. */
pit_config_t pitConfig;
if (us_ticker_inited) {
/* calling init again should cancel current interrupt */
TPM_DisableInterrupts(TPM2, kTPM_TimeOverflowInterruptEnable);
return;
}
PIT_GetDefaultConfig(&pitConfig);
PIT_Init(PIT, &pitConfig);
busClock = CLOCK_GetFreq(kCLOCK_BusClk);
PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, (busClock / 3000000) - 1);
PIT_SetTimerPeriod(PIT, kPIT_Chnl_1, 0xFFFFFFFF);
PIT_SetTimerChainMode(PIT, kPIT_Chnl_1, true);
PIT_StartTimer(PIT, kPIT_Chnl_0);
PIT_StartTimer(PIT, kPIT_Chnl_1);
/* Configure interrupt generation counters and disable ticker interrupts. */
tpm_config_t tpmConfig;
TPM_GetDefaultConfig(&tpmConfig);
/* Set to Div 16 to get 3MHz clock source for TPM */
tpmConfig.prescale = kTPM_Prescale_Divide_16;
TPM_Init(TPM2, &tpmConfig);
NVIC_SetVector(TPM2_IRQn, (uint32_t)tpm_isr);
NVIC_EnableIRQ(TPM2_IRQn);
us_ticker_inited = true;
}
uint32_t (us_ticker_read)()
{
return us_ticker_read();
}
void us_ticker_disable_interrupt(void)
{
TPM_DisableInterrupts(TPM2, kTPM_TimeOverflowInterruptEnable);
}
void us_ticker_clear_interrupt(void)
{
TPM_ClearStatusFlags(TPM2, kTPM_TimeOverflowFlag);
}
void us_ticker_set_interrupt(timestamp_t timestamp)
{
/* We get here absolute interrupt time which takes into account counter overflow.
* Since we use additional count-down timer to generate interrupt we need to calculate
* load value based on time-stamp.
*/
const uint32_t now_ticks = us_ticker_read();
uint32_t delta_ticks =
timestamp >= now_ticks ? timestamp - now_ticks : (uint32_t)((uint64_t) timestamp + 0xFFFFFFFF - now_ticks);
if (delta_ticks == 0) {
/* The requested delay is less than the minimum resolution of this counter. */
delta_ticks = 1;
}
us_ticker_int_counter = (uint32_t)(delta_ticks >> 16);
us_ticker_int_remainder = (uint16_t)(0xFFFF & delta_ticks);
TPM_StopTimer(TPM2);
TPM2->CNT = 0;
if (us_ticker_int_counter > 0) {
TPM2->MOD = 0xFFFF;
us_ticker_int_counter--;
} else {
TPM2->MOD = us_ticker_int_remainder;
us_ticker_int_remainder = 0;
}
/* Clear the count and set match value */
TPM_ClearStatusFlags(TPM2, kTPM_TimeOverflowFlag);
TPM_EnableInterrupts(TPM2, kTPM_TimeOverflowInterruptEnable);
TPM_StartTimer(TPM2, kTPM_SystemClock);
}
void us_ticker_fire_interrupt(void)
{
us_ticker_int_counter = 0;
us_ticker_int_remainder = 0;
NVIC_SetPendingIRQ(TPM2_IRQn);
}
void us_ticker_free(void)
{
}

View File

@ -1,30 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2019 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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 _FSL_US_TICKER_DEFINES_H_
#define _FSL_US_TICKER_DEFINES_H_
#include "fsl_pit.h"
#define US_TICKER_PERIOD_NUM 1
#define US_TICKER_PERIOD_DEN 1
#define US_TICKER_MASK 0xFFFFFFFF
/* Macro-optimised form of us_ticker_read */
#define us_ticker_read() (~(PIT_GetCurrentTimerCount(PIT, kPIT_Chnl_1)))
#endif /* _FSL_US_TICKER_DEFINES_H_ */