diff options
author | David Barksdale <amatus@amatus.name> | 2015-09-27 12:55:47 -0500 |
---|---|---|
committer | David Barksdale <amatus@amatus.name> | 2015-09-27 12:59:41 -0500 |
commit | f0668e8033f3858c520d98bd787f951c3f9fb0fd (patch) | |
tree | b7c8b19d579fcd13e30a6ca8f6e44235d83d823e /KSDK_1.2.0/platform/drivers | |
parent | 5a84136c6b03f7e4efd051d3afa557f9bbde2fa9 (diff) |
Adding subset of Kinetis SDK
This is just the free-software-licensed stuff and the KL27Z4 stuff.
Diffstat (limited to 'KSDK_1.2.0/platform/drivers')
292 files changed, 82450 insertions, 0 deletions
diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_adc16_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_adc16_driver.h new file mode 100755 index 0000000..3b85166 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_adc16_driver.h @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_ADC16_DRIVER_H__ +#define __FSL_ADC16_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_adc16_hal.h" +#if FSL_FEATURE_SOC_ADC16_COUNT + +/*! + * @addtogroup adc16_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#if FSL_FEATURE_ADC16_HAS_CALIBRATION + +/*! + * @brief Defines the structure to configure the ADC16 module calibration. + * + * This structure holds the configuration for the ADC16 module internal calibration. + */ +typedef struct Adc16CalibrationParam +{ + /* PG. */ + uint16_t plusSideGainValue; /*!< Plus-side gain value. */ + + /* MG. */ +#if FSL_FEATURE_ADC16_HAS_DIFF_MODE + uint16_t minusSideGainValue; /*!< Minus-side gain value. */ +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ + + /* Offset value. */ +#if FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION + uint16_t offsetValue; /*!< Offset error from correction value. */ +#endif /* FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION */ + +} adc16_calibration_param_t; + +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ + +/*! + * @brief Defines the type of event flags. + */ +typedef enum _adc16_flag_t +{ + kAdcConvActiveFlag = 0U, /*!< Indicates if a conversion or hardware averaging is in progress. */ +#if FSL_FEATURE_ADC16_HAS_CALIBRATION + kAdcCalibrationFailedFlag = 1U, /*!< Indicates if the calibration failed. */ + kAdcCalibrationActiveFlag = 2U, /*!< Indicates if the calibration is activated.*/ +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ + kAdcChnConvCompleteFlag = 3U /*!< Indicates if the channel group A is ready.*/ +} adc16_flag_t; + +/*! @brief Table of base addresses for ADC16 instances. */ +extern ADC_Type * const g_adcBase[]; + +/*! @brief Table to save ADC IRQ enum numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_adcIrqId[ADC_INSTANCE_COUNT]; + +#if defined(__cplusplus) +extern "C" { +#endif + +/****************************************************************************** + * API + *****************************************************************************/ + +#if FSL_FEATURE_ADC16_HAS_CALIBRATION +/*! + * @brief Gets the calibration parameters by auto calibration. + * + * This function executes auto calibration and fetches the calibration parameters + * that are kept in the "adc16_calibration_param_t" type variable. + * + * @param instance ADC16 instance ID. + * @param paramPtr Pointer to the parameter structure. See the "adc16_calibration_param_t". + * @return Execution status. + */ +adc16_status_t ADC16_DRV_GetAutoCalibrationParam(uint32_t instance, adc16_calibration_param_t *paramPtr); + +/*! + * @brief Sets the calibration parameters. + * + * This function sets the calibration parameters. + * + * @param instance ADC16 instance ID. + * @param paramPtr Pointer to parameter structure. See the "adc16_calibration_param_t". + * @return Execution status. + */ +adc16_status_t ADC16_DRV_SetCalibrationParam(uint32_t instance, const adc16_calibration_param_t *paramPtr); + +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ + +/*! + * @brief Fills the initial user configuration by default for a one-time trigger mode. + * + * This function fills the initial user configuration by default for a one-time + * trigger mode. Calling the initialization function with the filled parameter + * configures the ADC module work as one-time trigger mode. The settings are: + * \n + * + * \li.lowPowerEnable = true; + * \li.clkDividerMode = kAdc16ClkDividerOf8; + * \li.longSampleTimeEnable = true; + * \li.resolutionMode = kAdc16ResolutionBitOfSingleEndAs12; + * \li.clkSrc = kAdc16ClkSrcOfAsynClk + * \li.asyncClkEnable = true; + * \li.highSpeedEnable = false; + * \li.longSampleCycleMode = kAdc16LongSampleCycleOf24; + * \li.hwTriggerEnable = false; + * \li.refVoltSrc = kAdcRefVoltSrcOfVref; + * \li.continuousConvEnable = false; + * \li.dmaEnable = false; + * + * @param userConfigPtr Pointer to the user configuration structure. See the "adc16_converter_config_t". + * @return Execution status. + */ +adc16_status_t ADC16_DRV_StructInitUserConfigDefault(adc16_converter_config_t *userConfigPtr); + +/*! + * @brief Initializes the ADC module converter. + * + * This function initializes the converter in the ADC module. + * + * @param instance ADC16 instance ID. + * @param userConfigPtr Pointer to the initialization structure. See the "adc16_converter_config_t". + * @return Execution status. + */ +adc16_status_t ADC16_DRV_Init(uint32_t instance, const adc16_converter_config_t *userConfigPtr); + +/*! + * @brief De-initializes the ADC module converter. + * + * This function de-initializes and gates the ADC module. When ADC is no longer used, calling + * this API function shuts down the device to reduce the power consumption. + * + * @param instance ADC16 instance ID. + * @return Execution status. + */ +adc16_status_t ADC16_DRV_Deinit(uint32_t instance); + +/*! + * @brief Configures the hardware compare feature. + * + * This function configures the hardware compare feature with indicated configuration. + * + * @param instance ADC16 instance ID. + * @param configPtr Pointer to configuration structure. See the "adc16_hw_cmp_config_t". + * @return Execution status. + */ +adc16_status_t ADC16_DRV_ConfigHwCompare(uint32_t instance, const adc16_hw_cmp_config_t *configPtr); + +#if FSL_FEATURE_ADC16_HAS_HW_AVERAGE + +/*! + * @brief Configures the hardware averaging feature. + * + * This function configures the hardware averaging feature with an indicated configuration. + * + * @param instance ADC16 instance ID. + * @param configPtr Pointer to configuration structure. See to "adc16_hw_average_config_t". + * @return Execution status. + */ +adc16_status_t ADC16_DRV_ConfigHwAverage(uint32_t instance, const adc16_hw_average_config_t *configPtr); + +#endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ + +#if FSL_FEATURE_ADC16_HAS_PGA + +/*! + * @brief Configures the Programmable Gain Amplifier (PGA) feature. + * + * This function configures the PGA feature. + * + * @param instance ADC16 instance ID. + * @param configPtr Pointer to configuration structure. See the "adc16_pga_config_t". + * @return Execution status. + */ +adc16_status_t ADC16_DRV_ConfigPga(uint32_t instance, const adc16_pga_config_t *configPtr); + +#endif /* FSL_FEATURE_ADC16_HAS_PGA */ + +#if FSL_FEATURE_ADC16_HAS_MUX_SELECT +/*! + * @brief Switches the channel mux. + * + * This function switches the channel mux. For some channels share the same + * channel index with different channel mux, like AD4a and AD4b, could be switched + * to each group by calling this function. + * + * @param instance ADC16 instance ID. + * @param chnMuxMode Setting channel mux. See the "adc16_chn_mux_mode_t". + */ +void ADC16_DRV_SetChnMux(uint32_t instance, adc16_chn_mux_mode_t chnMuxMode); +#endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */ + +/*! + * @brief Configure the conversion channel by software. + * + * This function configures the conversion channel. When the ADC16 module has + * been initialized by enabling the software trigger (disable hardware trigger), + * calling this API triggers the conversion. + * + * @param instance ADC16 instance ID. + * @param chnGroup Selection of the configuration group. + * @param configPtr Pointer to configuration structure. See the "adc16_chn_config_t". + * @return Execution status. + */ +adc16_status_t ADC16_DRV_ConfigConvChn(uint32_t instance, uint32_t chnGroup, const adc16_chn_config_t *configPtr); + +/*! + * @brief Waits for the latest conversion to be complete. + * + * This function waits for the latest conversion to be complete. When + * triggering the conversion by configuring the available channel, the converter is + * launched. This API function should be called to wait for the conversion to be + * complete when no interrupt or DMA mode is used for the ADC16 module. After the + * waiting period, the available data from the conversion result are fetched. + * The complete flag is not cleared until the result data is read. + * + * @param instance ADC16 instance ID. + * @param chnGroup Selection of configuration group. + */ +void ADC16_DRV_WaitConvDone(uint32_t instance, uint32_t chnGroup); + +/*! + * @brief Pauses the current conversion by software. + * + * This function pauses the current conversion setting by software. + * + * @param instance ADC16 instance ID. + * @param chnGroup Selection of configuration group. + */ +void ADC16_DRV_PauseConv(uint32_t instance, uint32_t chnGroup); + +/*! + * @brief Gets the latest conversion value with no format. + * + * This function gets the conversion value from the ADC16 module. + * + * @param instance ADC16 instance ID. + * @param chnGroup Selection of configuration group. + * @return Unformatted conversion value. + */ +uint16_t ADC16_DRV_GetConvValueRAW(uint32_t instance, uint32_t chnGroup); + +/*! + * @brief Gets the latest conversion value with signed. + * + * This function gets the conversion value from the ADC16 module with signed. + * + * @param instance ADC16 instance ID. + * @param chnGroup Selection of configuration group. + * @return Signed conversion value. + */ +int16_t ADC16_DRV_GetConvValueSigned(uint32_t instance, uint32_t chnGroup); + +/*! + * @brief Gets the event status of the ADC16 module. + * + * This function gets the event status of the ADC16 converter. + * If the event is asserted, it returns "true". Otherwise, it is "false". + * + * @param instance ADC16 instance ID. + * @param flag Indicated event. + * @return Assertion of event flag. + */ +bool ADC16_DRV_GetConvFlag(uint32_t instance, adc16_flag_t flag); + +/*! + * @brief Gets the event status of each channel group. + * + * This function gets the event status of each channel group. + * If the event is asserted, it returns "true". Otherwise, it is "false". + * + * @param instance ADC16 instance ID. + * @param chnGroup ADC16 channel group number. + * @param flag Indicated event. + * @return Assertion of event flag. + */ +bool ADC16_DRV_GetChnFlag(uint32_t instance, uint32_t chnGroup, adc16_flag_t flag); + +#if defined(__cplusplus) +} +#endif + + +/*! + *@} + */ + +#endif +#endif /* __FSL_ADC16_DRIVER_H__ */ + +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_aoi_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_aoi_driver.h new file mode 100755 index 0000000..fedba50 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_aoi_driver.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_AOI_DRIVER_H__ +#define __FSL_AOI_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_aoi_hal.h" + +#if FSL_FEATURE_SOC_AOI_COUNT + +/*! + * @addtogroup aoi_driver + * @{ + */ + +/*! @brief Table of base addresses for AOI instances. */ +extern AOI_Type* const g_aoiBase[]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief AOI product term configuration structure */ +typedef struct AoiProductTermConfig +{ + aoi_input_config_t PTAC; /*!< PTx_AC configuration. */ + aoi_input_config_t PTBC; /*!< PTx_BC configuration. */ + aoi_input_config_t PTCC; /*!< PTx_CC configuration. */ + aoi_input_config_t PTDC; /*!< PTx_DC configuration. */ +} aoi_product_term_config_t; + +/*! + * @brief AOI event configuration structure + * + * Defines structure AoiEventConfig and use the AOI_DRV_ConfigEventLogic() function to make + * whole event configuration. + */ +typedef struct AoiEventConfig +{ + aoi_input_config_t PT1DC; /*!< PT1_DC configuration. */ + aoi_input_config_t PT1CC; /*!< PT1_CC configuration. */ + aoi_input_config_t PT1BC; /*!< PT1_BC configuration. */ + aoi_input_config_t PT1AC; /*!< PT1_AC configuration. */ + aoi_input_config_t PT0DC; /*!< PT0_DC configuration. */ + aoi_input_config_t PT0CC; /*!< PT0_CC configuration. */ + aoi_input_config_t PT0BC; /*!< PT0_BC configuration. */ + aoi_input_config_t PT0AC; /*!< PT0_AC configuration. */ + aoi_input_config_t PT3DC; /*!< PT3_DC configuration. */ + aoi_input_config_t PT3CC; /*!< PT3_CC configuration. */ + aoi_input_config_t PT3BC; /*!< PT3_BC configuration. */ + aoi_input_config_t PT3AC; /*!< PT3_AC configuration. */ + aoi_input_config_t PT2DC; /*!< PT2_DC configuration. */ + aoi_input_config_t PT2CC; /*!< PT2_CC configuration. */ + aoi_input_config_t PT2BC; /*!< PT2_BC configuration. */ + aoi_input_config_t PT2AC; /*!< PT2_AC configuration. */ +} aoi_event_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes AOI module. + * + * This function initializes AOI module. It configures all the AOI module inputs + * of all events to the reset state (kAoiLogicZero). + * + * This is an example to initialize the AOI module: + @code + status = AOI_DRV_Init(); + switch (status) + { + //... + } + @endcode + * + * @param instance The instance number of the AOI peripheral + * @return kStatus_AOI_Success indicating successful initialization + */ +aoi_status_t AOI_DRV_Init(uint32_t instance); + +/*! + * @brief De-initializes the AOI module. + * + * This function clears all configurations and shuts down the AOI module clock to reduce the power + * consumption. + * + * @param instance The instance number of the AOI peripheral + * @return kStatus_AOI_Success indicating successful de-initialization + */ +aoi_status_t AOI_DRV_Deinit(uint32_t instance); + +/*! + * @brief Configures an AOI event. + * + * This function configures an AOI event according + * to the aoiEventConfig structure. This function configures all inputs (A, B, C, and D) + * of all product terms (0, 1, 2, and 3) of a desired event. + * This is an example to set up the AOI Event structure: + * + @code + + aoi_event_config_t aoiEventConfig; + + aoiEventConfig.PT0AC = kAoiConfigInputSignal; + aoiEventConfig.PT0BC = kAoiConfigLogicZero; + aoiEventConfig.PT0CC = kAoiConfigLogicZero; + aoiEventConfig.PT0DC = kAoiConfigLogicZero; + + aoiEventConfig.PT1AC = kAoiConfigInvInputSignal; + aoiEventConfig.PT1BC = kAoiConfigLogicZero; + aoiEventConfig.PT1CC = kAoiConfigLogicZero; + aoiEventConfig.PT1DC = kAoiConfigInputSignal; + + aoiEventConfig.PT2AC = kAoiConfigInputSignal; + aoiEventConfig.PT2BC = kAoiConfigInputSignal; + aoiEventConfig.PT2CC = kAoiConfigInputSignal; + aoiEventConfig.PT2DC = kAoiConfigLogicOne; + + aoiEventConfig.PT3AC = kAoiConfigLogicOne; + aoiEventConfig.PT3BC = kAoiConfigLogicOne; + aoiEventConfig.PT3CC = kAoiConfigLogicOne; + aoiEventConfig.PT3DC = kAoiConfigLogicOne; + + aoi_status_t status; + // In the function call below, the value of "2" indicates event #2 is being used. + status = AOI_DRV_ConfigEventLogic(0, 2, &aoiEventConfig); + switch (status) + { + //... + } + @endcode + * + * @param instance The instance number of the AOI peripheral + * @param event Event which will be configured of type aoi_event_index_t. + * @param eventConfigPtr Pointer to type aoi_event_config_t structure. The user is responsible to + * fill out the members of this structure and pass the pointer to this function. + * @return An error code or kStatus_AOI_Success. + */ +aoi_status_t AOI_DRV_ConfigEventLogic(uint32_t instance, + aoi_event_index_t event, + const aoi_event_config_t * eventConfigPtr); + +/*! + * @brief Configures an AOI module product term in a specific event. + * + * This function configures an AOI module product terms for a specific event. The user has + * to select the event and the product term which is configured and fill the + * AoiProductTermConfig configuration structure. + * + * Example: + @code + + aoi_product_term_config_t productTermConfigStruct; + aoi_status_t status; + + productTermConfigStruct.PTAC = kAoiConfigLogicZero; + productTermConfigStruct.PTBC = kAoiConfigInputSignal; + productTermConfigStruct.PTCC = kAoiConfigInvInputSignal; + productTermConfigStruct.PTDC = kAoiConfigLogicOne; + + // Configure product term 1 of event 3 + status = AOI_DRV_ConfigProductTermLogic(0, 3, kAoiTerm1, &productTermConfigStruct); + switch (status) + { + //... + } + @endcode + * + * @param instance The instance number of the AOI peripheral + * @param event Event which will be configured of type aoi_event_index_t. + * @param productTerm Product term which will be configured of type aoi_product_term_t. + * @param productTermConfigPtr Pointer to type aoi_product_term_config_t structure. + * The user is responsible to fill out the members of this structure and pass the pointer + * to this function. + * @return An error code or kStatus_AOI_Success. + */ +aoi_status_t AOI_DRV_ConfigProductTermLogic(uint32_t instance, + aoi_event_index_t event, + aoi_product_term_t productTerm, + const aoi_product_term_config_t * productTermConfigPtr); + +#if defined(__cplusplus) +} +#endif + +/*! + *@} + */ + +#endif /* FSL_FEATURE_SOC_AOI_COUNT */ +#endif /* __FSL_AOI_DRIVER_H__ */ +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_cadc_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_cadc_driver.h new file mode 100755 index 0000000..54d30cf --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_cadc_driver.h @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_CADC_DRIVER_H__ +#define __FSL_CADC_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_cadc_hal.h" +#if FSL_FEATURE_SOC_CADC_COUNT + +/*! + * @addtogroup cadc_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Defines the type of enumerating ADC converter ID. + */ +typedef enum _cadc_conv_id +{ + kCAdcConvA = 0U,/*!< ID for ADC converter A. */ + kCAdcConvB = 1U /*!< ID for ADC converter B. */ +} cadc_conv_id_t; + +/*! + * @brief Defines types for an enumerating event. + */ +typedef enum _cadc_flag +{ + /* Converter events. */ + kCAdcConvInProgress = 0U, /*!< Conversion in progress for each converter. */ + kCAdcConvEndOfScanInt = 1U, /*!< End of scan interrupt. */ + kCAdcConvPowerDown = 2U, /*!< The converter is powered Down. */ + + /* Global events. */ + kCAdcZeroCrossingInt = 3U, /*!< Zero crossing interrupt. */ + kCAdcLowLimitInt = 4U, /*!< Low limit interrupt. */ + kCAdcHighLimitInt = 5U, /*!< High limit interrupt. */ + + /* Slot events. */ + kCAdcSlotReady = 6U, /*!< Sample is ready to be read. */ + kCAdcSlotLowLimitEvent = 7U, /*!< Low limit event for each slot. */ + kCAdcSlotHighLimitEvent = 8U, /*!< High limit event for each slot. */ + kCAdcSlotCrossingEvent = 9U /*!< Zero crossing event for each slot. */ +} cadc_flag_t; + +/*! @brief Table of base addresses for ADC instances. */ +extern ADC_Type * g_cadcBaseAddr[]; + +/*! @brief Table to save ADC IRQ enumeration numbers defined in the CMSIS header file. */ +extern IRQn_Type g_cadcErrIrqId[ADC_INSTANCE_COUNT]; +extern IRQn_Type g_cadcConvAIrqId[ADC_INSTANCE_COUNT]; +extern IRQn_Type g_cadcConvBIrqId[ADC_INSTANCE_COUNT]; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name CADC Driver + * @{ + */ + +/*! + * @brief Populates the user configuration structure for the CyclicADC common settings. + * + * This function populates the cadc_user_config_t structure with + * default settings, which are used in polling mode for ADC conversion. + * These settings are: + * + * .zeroCrossingIntEnable = false; + * .lowLimitIntEnable = false; + * .highLimitIntEnable = false; + * .scanMode = kCAdcScanOnceSequential; + * .parallelSimultModeEnable = false; + * .dmaSrc = kCAdcDmaTriggeredByEndOfScan; + * .autoStandbyEnable = false; + * .powerUpDelayCount = 0x2AU; + * .autoPowerDownEnable = false; + * + * @param userConfigPtr Pointer to structure of "cadc_controller_config_t". + * @return Execution status. + */ +cadc_status_t CADC_DRV_StructInitUserConfigDefault(cadc_controller_config_t *userConfigPtr); + +/*! + * @brief Initializes the CyclicADC module for a global configuration. + * + * This function configures the CyclicADC module for the global configuration + * which is shared by all converters. + * + * @param instance Instance ID number. + * @param userConfigPtr Pointer to structure of "cadc_controller_config_t". + * @return Execution status. + */ +cadc_status_t CADC_DRV_Init(uint32_t instance, const cadc_controller_config_t *userConfigPtr); + +/*! + * @brief De-initializes the CyclicADC module. + * + * This function shuts down the CyclicADC module and disables related IRQs. + * + * @param instance Instance ID number. + * @return Execution status. + */ +cadc_status_t CADC_DRV_Deinit(uint32_t instance); + +/*! + * @brief Populates the user configuration structure for each converter. + * + * This function populates the cadc_conv_config_t structure with + * default settings, which are used in polling mode for ADC conversion. + * These settings are: + * + * .dmaEnable = false; + * .stopEnable = false; + * .syncEnable = false; + * .endOfScanIntEnable = false; + * .clkDivValue = 0x3FU; + * .useChnInputAsVrefH = false; + * .useChnInputAsVrefL = false; + * .speedMode = kCAdcConvClkLimitBy25MHz; + * .sampleWindowCount = 0U; + * + * @param configPtr Pointer to structure of "cadc_converter_config_t". + * @return Execution status. + */ +cadc_status_t CADC_DRV_StructInitConvConfigDefault(cadc_converter_config_t *configPtr); + +/*! + * @brief Configures each converter in the CyclicADC module. + * + * This function configures each converter in the CyclicADC module. However, when + * the multiple converters are operating simultaneously, the converter settings + * are interrelated. For more information, see the appropriate device + * reference manual. + * + * @param instance Instance ID number. + * @param convId Converter ID. See "cadc_conv_id_t". + * @param configPtr Pointer to configure structure. See "cadc_converter_config_t". + * @return Execution status. + */ +cadc_status_t CADC_DRV_ConfigConverter( + uint32_t instance, cadc_conv_id_t convId, const cadc_converter_config_t *configPtr); + +/*! + * @brief Configures the input channel for ADC conversion. + * + * This function configures the input channel for ADC conversion. The CyclicADC + * module input channels are organized in pairs. The configuration can + * be set for each channel in the pair. + * + * @param instance Instance ID number. + * @param configPtr Pointer to configure structure. See "cadc_chn_config_t". + * @return Execution status. + */ +cadc_status_t CADC_DRV_ConfigSampleChn(uint32_t instance, const cadc_chn_config_t *configPtr); + +/*! + * @brief Configures each slot for the ADC conversion sequence. + * + * This function configures each slot in the ADC conversion sequence. ADC conversion + * sequence is the basic execution unit in the CyclicADC module. However, the + * sequence should be configured slot-by-slot. The end of the sequence is a + * slot that is configured as disabled. + * + * @param instance Instance ID number. + * @param slotIdx Indicated slot number, available in range of 0 - 15. + * @param configPtr Pointer to configure structure. See "cadc_slot_config_t". + * @return Execution status. + */ +cadc_status_t CADC_DRV_ConfigSeqSlot( + uint32_t instance, uint32_t slotIdx, const cadc_slot_config_t *configPtr); + +/*! + * @brief Triggers the ADC conversion sequence by software. + * + * This function triggers the ADC conversion by executing a software command. It + * starts the conversion if no other SYNC input (hardware trigger) is needed. + * + * @param instance Instance ID number. + * @param convId Indicated converter. See "cadc_conv_id_t". + */ +void CADC_DRV_SoftTriggerConv(uint32_t instance, cadc_conv_id_t convId); + +/*! + * @brief Reads the conversion value and returns an absolute value. + * + * This function reads the conversion value from each slot in a conversion sequence. + * The return value is the absolute value without being signed. + * + * @param instance Instance ID number. + * @param slotIdx Indicated slot number, available in range of 0 - 15. + */ +uint16_t CADC_DRV_GetSeqSlotConvValue(uint32_t instance, uint32_t slotIdx); + +/*! + * @brief Gets the global event flag. + * + * This function gets the global flag of the CyclicADC module. + * + * @param instance Instance ID number. + * @param flag Indicated event. See "cadc_flag_t". + * @return Assertion of indicated event. + */ +bool CADC_DRV_GetFlag(uint32_t instance, cadc_flag_t flag); + +/*! + * @brief Clears the global event flag. + * + * This function clears the global event flag of the CyclicADC module. + * + * @param instance Instance ID number. + * @param flag Indicated event. See "cadc_flag_t". + */ +void CADC_DRV_ClearFlag(uint32_t instance, cadc_flag_t flag); + +/*! + * @brief Gets the flag for each converter event. + * + * This function gets the flag for each converter event. + * + * @param instance Instance ID number. + * @param convId Indicated converter. + * @param flag Indicated event. See "cadc_flag_t". + * @return Assertion of indicated event. + */ +bool CADC_DRV_GetConvFlag(uint32_t instance, cadc_conv_id_t convId, cadc_flag_t flag); + +/*! + * @brief Clears the flag for each converter event. + * + * This function clears the flag for each converter event. + * + * @param instance Instance ID number. + * @param convId Indicated converter. + * @param flag Indicated event. See "cadc_flag_t". + */ +void CADC_DRV_ClearConvFlag(uint32_t instance, cadc_conv_id_t convId, cadc_flag_t flag); + +/*! + * @brief Gets the flag for each slot event. + * + * This function gets the flag for each slot event in the conversion in + * sequence. + * + * @param instance Instance ID number. + * @param slotIdxMask Indicated slot number's mask. + * @param flag Indicated event. See "cadc_flag_t". + * @return Assertion of indicated event. + */ +uint16_t CADC_DRV_GetSlotFlag(uint32_t instance, uint16_t slotIdxMask, cadc_flag_t flag); + +/*! + * @brief Clears the flag for each slot event. + * + * This function clears the flag for each slot event in the conversion in + * sequence. + * + * @param instance Instance ID number. + * @param slotIdxMask Indicated slot number's mask. + * @param flag Indicated event. See "cadc_flag_t". + */ +void CADC_DRV_ClearSlotFlag(uint32_t instance, uint16_t slotIdxMask, cadc_flag_t flag); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif +#endif /* __FSL_CADC_DRIVER_H__ */ +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_cmp_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_cmp_driver.h new file mode 100755 index 0000000..fee8ac8 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_cmp_driver.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_CMP_DRIVER_H__ +#define __FSL_CMP_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_cmp_hal.h" +#if FSL_FEATURE_SOC_CMP_COUNT + +/*! + * @addtogroup cmp_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Defines type of flags for the CMP event. + */ +typedef enum _cmp_flag +{ + kCmpFlagOfCoutRising = 0U, /*!< Identifier to indicate if the COUT change from logic zero to one. */ + kCmpFlagOfCoutFalling = 1U /*!< Identifier to indicate if the COUT change from logic one to zero. */ +} cmp_flag_t; + +/*! + * @brief Internal driver state information. + * + * The contents of this structure are internal to the driver and should not be + * modified by users. Also, contents of the structure are subject to change in + * future releases. + */ +typedef struct CmpState +{ + bool isInUsed; /* If the CMP instance is in use. All the CMP instances share + * the same clock gate and are aligned to use clock.*/ +} cmp_state_t; + +/*! @brief Table of base addresses for CMP instances. */ +extern CMP_Type * const g_cmpBase[]; + +/*! @brief Table to save CMP IRQ enumeration numbers defined in CMSIS header file. */ +extern const IRQn_Type g_cmpIrqId[CMP_INSTANCE_COUNT]; + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************************************* + * APIs + ******************************************************************************/ +/*! + * @brief Populates the initial user configuration with default settings. + * + * This function populates the initial user configuration with default settings. + * The default settings enable the CMP module to operate as a comparator. + * The settings are :\n + * \li.hystersisMode = kCmpHystersisOfLevel0 + * \li.pinoutEnable = true + * \li.pinoutUnfilteredEnable = true + * \li.invertEnable = false + * \li.highSpeedEnable = false + * \li.dmaEnable = false + * \li.risingIntEnable = false + * \li.fallingIntEnable = false + * \li.triggerEnable = false + * However, it is still recommended to fill some fields of structure such as + * channel mux according to the application requirements. Note that this function does not set the + * configuration to hardware. + * + * @param userConfigPtr Pointer to structure of configuration. See "cmp_user_config_t". + * @param plusInput Plus Input mux selection. See "cmp_chn_mux_mode_t". + * @param minusInput Minus Input mux selection. See "cmp_chn_mux_mode_t". + * @return Execution status. + */ +cmp_status_t CMP_DRV_StructInitUserConfigDefault(cmp_comparator_config_t *userConfigPtr, + cmp_chn_mux_mode_t plusInput, cmp_chn_mux_mode_t minusInput); + +/*! + * @brief Initializes the CMP module. + * + * This function initializes the CMP module, enables the clock, and + * sets the interrupt switcher. The CMP module is + * configured as a basic comparator. + * + * @param instance CMP instance ID. + * @param userStatePtr Pointer to structure of context. See "cmp_state_t". + * @param userConfigPtr Pointer to structure of configuration. See "cmp_user_config_t". + * @return Execution status. + */ +cmp_status_t CMP_DRV_Init(uint32_t instance, cmp_state_t *userStatePtr, + const cmp_comparator_config_t *userConfigPtr); + +/*! + * @brief De-initializes the CMP module. + * + * This function de-initializes the CMP module. It shuts down the CMP + * clock and disables the interrupt. This API should be called when CMP is no + * longer used in the application. It also reduces power consumption. + * + * @param instance CMP instance ID. + * @return Execution status. + */ +cmp_status_t CMP_DRV_Deinit(uint32_t instance); + +/*! + * @brief Starts the CMP module. + * + * This function starts the CMP module. The configuration does not take + * effect until the module is started. + * + * @param instance CMP instance ID. + */ +void CMP_DRV_Start(uint32_t instance); + +/*! + * @brief Stops the CMP module. + * + * This function stops the CMP module. Note that this function does not shut down + * the module, but only pauses the features. + * + * @param instance CMP instance ID. + */ +void CMP_DRV_Stop(uint32_t instance); + +/*! + * @brief Enables the internal DAC in the CMP module. + * + * This function enables the internal DAC in the CMP module. It takes + * effect only when the internal DAC has been chosen as an input + * channel for the comparator. Then, the DAC channel can be programmed to provide + * a reference voltage level. + * + * @param instance CMP instance ID. + * @param dacConfigPtr Pointer to structure of configuration. See "cmp_dac_config_t". + * @return Execution status. + */ +cmp_status_t CMP_DRV_ConfigDacChn(uint32_t instance, const cmp_dac_config_t *dacConfigPtr); + +/*! + * @brief Configures the Sample\Filter feature in the CMP module. + * + * This function configures the CMP working in Sample\Filter modes. These + * modes are advanced features in addition to the basic comparator such as + * Window Mode, Filter Mode, etc. See + * "cmp_sample_filter_config_t"for detailed description. + * + * @param instance CMP instance ID. + * @param configPtr Pointer to a structure of configurations. + * See "cmp_sample_filter_config_t". + * @return Execution status. + */ +cmp_status_t CMP_DRV_ConfigSampleFilter(uint32_t instance, const cmp_sample_filter_config_t *configPtr); + +/*! + * @brief Gets the output of the CMP module. + * + * This function gets the output of the CMP module. + * The output source depends on the configuration when initializing the comparator. + * When the cmp_user_config_t.pinoutUnfilteredEnable is false, the output is + * processed by the filter. Otherwise, the output is that the signal did not pass + * the filter. + * + * @param instance CMP instance ID. + * @return Output logic's assertion. When not inverted, plus side > minus side, it is true. + */ +bool CMP_DRV_GetOutputLogic(uint32_t instance); + +/*! + * @brief Gets the state of the CMP module. + * + * This function gets the state of the CMP module. It returns if the indicated + * event has been detected. + * + * @param instance CMP instance ID. + * @param flag Represent events or states. See "cmp_flag_t". + * @return Assertion if indicated event occurs. + */ +bool CMP_DRV_GetFlag(uint32_t instance, cmp_flag_t flag); + +/*! + * @brief Clears the event record of the CMP module. + * + * This function clears the event record of the CMP module. + * + * @param instance CMP instance ID. + * @param flag Represent events or states. See "cmp_flag_t". + */ +void CMP_DRV_ClearFlag(uint32_t instance, cmp_flag_t flag); + +#if defined(__cplusplus) +} +#endif + +/*! + *@} + */ + +#endif +#endif /* __FSL_CMP_DRIVER_H__ */ +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_cop_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_cop_driver.h new file mode 100755 index 0000000..cd26816 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_cop_driver.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_DRIVER_H__ +#define __FSL_COP_DRIVER_H__ + +#include "fsl_cop_hal.h" +#include "fsl_device_registers.h" +#include <stdbool.h> +#include <string.h> +#include <stdint.h> +#include <assert.h> + +/*! + * @addtogroup cop_driver + * @{ + */ + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @brief Table of base addresses for COP instances. */ +extern SIM_Type * const g_copBase[]; + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name COP Driver + * @{ + */ + + +/*! + * @brief Initializes the COP. + * + * This function initializes 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_shutdown function can be called only once. A second call has no effect. + * + * @param instance The COP peripheral instance number. + * @param initPtr COP Initialize data structure. + * + */ +cop_status_t COP_DRV_Init(uint32_t instance, const cop_config_t* initPtr); + +/*! + * @brief Disables the COP Watchdog. + * + * This function disables the COP Watchdog. + * Note: The COP configuration register is write-once after reset. + * To disable the COP Watchdog, call this function first. + * + * @param instance The COP peripheral instance number. + */ +void COP_DRV_Disable(uint32_t instance); + +/*! + * @brief Resets the COP timeout counter. + * + * This function feeds the COP. It sets the COP timer count to zero and + * should be called before the COP timer expires. Otherwise, a RESET is asserted. + * + * @param instance The COP peripheral instance number. + */ +void COP_DRV_Refresh(uint32_t instance); + +/*! + * @brief Gets the COP running status. + * + * This function gets the COP running status. + * + * @param instance The COP peripheral instance number. + * @return COP running status; 0 means not running; 1 means running + */ +bool COP_DRV_IsRunning(uint32_t instance); + +/*! + * @brief Resets the system. + * + * This function resets the device. + * + * @param instance The COP peripheral instance number. + */ +void COP_DRV_ResetSystem(uint32_t instance); + +/*@}*/ +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __FSL_COP_H__*/ +/******************************************************************************* + * EOF + *******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_crc_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_crc_driver.h new file mode 100755 index 0000000..2f05987 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_crc_driver.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_CRC_DRIVER_H__ +#define __FSL_CRC_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_crc_hal.h" +#if FSL_FEATURE_SOC_CRC_COUNT + +/*! + * @addtogroup crc_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Table of base addresses for the CRC instances. */ +extern CRC_Type * const g_crcBase[CRC_INSTANCE_COUNT]; + +/*! + * @brief Defines a structure to initialize the CRC module. + * + * This structure holds the configuration for the CRC. + * @internal gui name="CRC configuration" id="crcCfg" + */ +typedef struct _crc_user_config +{ + crc_prot_width_t crcWidth; /*!< Selects 16 or 32-bit CRC protocol @internal gui name="Width" id="crcWidth" */ + uint32_t seed; /*!< Value of the seed (initial) CRC value @internal gui name="Seed" id="seed" */ + uint32_t polynomial; /*!< Value of the polynomial for the CRC calculation @internal gui name="Polynomial" id="polynomial" */ + crc_transpose_t writeTranspose; /*!< Defines transpose configuration of the data written to the CRC data register @internal gui name="Write transpose" id="writeTranspose" */ + crc_transpose_t readTranspose; /*!< Defines transpose configuration of the value read from the CRC data register @internal gui name="Read transpose" id="readTranspose" */ + bool complementRead; /*!< Enables complement read of CRC data register @internal gui name="Complement read" id="complementRead" */ +} crc_user_config_t; + +#if defined(__cplusplus) +extern "C" { +#endif + +/****************************************************************************** + * API + *****************************************************************************/ + +/*! + * @brief Initializes the CRC module. + * + * This API + * should be called with the initial configuration before any other operations. + * + * @param instance CRC instance ID. + * @param userConfigPtr Pointer to structure of initialization, see to "crc_user_config_t". + * @return Execution status. + */ +crc_status_t CRC_DRV_Init(uint32_t instance, const crc_user_config_t *userConfigPtr); + +/*! + * @brief CRC_DRV_Deinit + * + * Shuts down the CRC instance. + * + * @param instance CRC instance ID. + * @return Execution status. + */ +void CRC_DRV_Deinit(uint32_t instance); + +/*! + * @brief CRC_DRV_GetCrcBlock + * + * This function appends a block of bytes to the current CRC calculation + * and returns a new result. + * + * @param instance CRC instance ID. + * @param data data for current CRC calculation + * @param dataLen length of data to be calculated + * @return Execution status. + */ +uint32_t CRC_DRV_GetCrcBlock(uint32_t instance, uint8_t *data, uint32_t dataLen); + +/*! + * @brief CRC_DRV_Configure + * + * This function configures the CRC module from a user configuration structure. + * + * @param instance CRC instance ID. + * @param userConfigPtr Pointer to structure of initialization, see to "crc_user_config_t". + * @return Execution status. + */ +crc_status_t CRC_DRV_Configure(uint32_t instance, const crc_user_config_t *userConfigPtr); + +#if defined(__cplusplus) +} +#endif + +/*! + *@} + */ + +#endif +#endif /* __FSL_CRC_DRIVER_H__ */ + +/****************************************************************************** + * EOF + *****************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_dac_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_dac_driver.h new file mode 100755 index 0000000..65ce73e --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_dac_driver.h @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_DAC_DRIVER_H__ +#define __FSL_DAC_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_dac_hal.h" + +#if FSL_FEATURE_SOC_DAC_COUNT + +/*! + * @addtogroup dac_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Defines the type of event flags. + */ +typedef enum _dac_flag_t +{ +#if FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION + kDacBuffIndexWatermarkFlag = 0U, /*!< Event for the buffer index hit the watermark. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + kDacBuffIndexStartFlag = 1U, /*!< Event for the buffer index hit the start (0). */ + kDacBuffIndexUpperFlag = 2U /*!< Event for the buffer index hit the upper. */ +} dac_flag_t; + +/*! @brief Table of base addresses for DAC instances. */ +extern DAC_Type * const g_dacBase[]; + +/*! @brief Table to save DAC IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_dacIrqId[DAC_INSTANCE_COUNT]; + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Populates the initial user configuration for the DAC module without interrupt and buffer features. + * + * This function populates the initial user configuration + * without interrupt and buffer features. Calling the initialization + * function with the populated parameter configures the DAC module to operate as + * a simple converter. The settings are:\n + * + * \li.refVoltSrcMode = kDacRefVoltSrcOfVref2; // Vdda + * \li.triggerMode = kDacTriggerBySoftware; + * \li.lowPowerEnable = false; + * + * @param userConfigPtr Pointer to the user configuration structure. See the "dac_user_config_t". + * @return Execution status. + */ +dac_status_t DAC_DRV_StructInitUserConfigNormal(dac_converter_config_t *userConfigPtr); + +/*! + * @brief Initializes the converter. + * + * This function initializes the converter. + * + * @param instance DAC instance ID. + * @param userConfigPtr Pointer to the initialization structure. See the "dac_user_config_t". + * @return Execution status. + */ +dac_status_t DAC_DRV_Init(uint32_t instance, const dac_converter_config_t *userConfigPtr); + +/*! + * @brief De-initializes the DAC module converter. + * + * This function de-initializes the converter. It disables the + * DAC module and shuts down the clock to reduce the power consumption. + * + * @param instance DAC instance ID. + * @return Execution status. + */ +dac_status_t DAC_DRV_Deinit(uint32_t instance); + +/*! + * @brief Drives the converter to output the DAC value. + * + * This function drives the converter to output the DAC value. It forces + * the buffer index to be the first one and load the setting value to this item. + * Then, the converter outputs the voltage indicated by the indicated value + * immediately. + * + * @param instance DAC instance ID. + * @param value Setting value for DAC. + */ +void DAC_DRV_Output(uint32_t instance, uint16_t value); + +/*! + * @brief Configures the internal buffer. + * + * This function configures the feature of the internal buffer for the DAC module. + * By default, the buffer feature is disabled. Calling this API enables + * the buffer and configures it. + * + * @param instance DAC instance ID. + * @param configPtr Pointer to the configuration structure. See the "dac_buff_config_t". + * @return Execution status. + */ +dac_status_t DAC_DRV_ConfigBuffer(uint32_t instance, const dac_buffer_config_t *configPtr); + +/*! + * @brief Sets values into the DAC internal buffer. + * + * This function sets values into the DAC internal buffer. Note that the buffer + * size is defined by the "FSL_FEATURE_DAC_BUFFER_SIZE" macro and the available + * value is 12 bit. + * + * @param instance DAC instance ID. + * @param start Start index of setting values. + * @param offset Length of setting values' array. + * @param arr Setting values' array. + * @return Execution status. + */ +dac_status_t DAC_DRV_SetBuffValue(uint32_t instance, uint8_t start, uint8_t offset, uint16_t arr[]); + +/*! + * @brief Triggers the buffer by software and returns the current value. + * + * This function triggers the buffer by software and returns the current + * value. After it is triggered, the buffer index updates according to work mode. + * Then, the value kept inside the pointed item is immediately output. + * + * @param instance DAC instance ID. + */ +void DAC_DRV_SoftTriggerBuffCmd(uint32_t instance); + +/*! + * @brief Clears the flag for an indicated event causing an interrupt. + * + * This function clears the flag for an indicated event causing an interrupt. + * + * @param instance DAC instance ID. + * @param flag Indicated flag. See "dac_flag_t". + */ +void DAC_DRV_ClearBuffFlag(uint32_t instance, dac_flag_t flag); + +/*! + * @brief Gets the flag for an indicated event causing an interrupt. + * + * This function gets the flag for an indicated event causing an interrupt. + * If the event occurs, the return value is asserted. + * + * @param instance DAC instance ID. + * @param flag Indicated flag. See "dac_flag_t". + * @return Assertion of indicated event. + */ +bool DAC_DRV_GetBuffFlag(uint32_t instance, dac_flag_t flag); + +/*! + * @brief Sets the current read pointer in DAC buffer. + * + * This function sets the current read pointer in DAC buffer. + * + * @param instance DAC instance ID. + * @param idx Index for read pointer in buffer. + */ +void DAC_DRV_SetBuffCurIdx(uint32_t instance, uint8_t idx); + +/*! + * @brief Gets the current read pointer in the DAC buffer. + * + * This function gets the current read pointer in DAC buffer. + * + * @param instance DAC instance ID. + * @return Index for current read pointer in buffer. + */ +uint8_t DAC_DRV_GetBuffCurIdx(uint32_t instance); + +#if defined(__cplusplus) +} +#endif + +/*! + *@} + */ + +#endif /* __FSL_DAC_DRIVER_H__ */ + +/****************************************************************************** + * EOF + *****************************************************************************/ + +#endif diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_dma_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_dma_driver.h new file mode 100755 index 0000000..e243be7 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_dma_driver.h @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_DMA_DRIVER_H__) +#define __FSL_DMA_DRIVER_H__ + +#include <stdint.h> +#include <stdlib.h> +#include "fsl_device_registers.h" +#include "fsl_dma_request.h" +#include "fsl_dma_hal.h" +#include "fsl_dmamux_hal.h" +#include "fsl_os_abstraction.h" +#if FSL_FEATURE_SOC_DMA_COUNT + +/*! + * @addtogroup dma_driver + * @{ + */ +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Array for eDMA module register base address. */ +extern DMA_Type * const g_dmaBase[DMA_INSTANCE_COUNT]; + +/*! @brief Array for DMAMUX module register base address. */ +extern DMAMUX_Type * const g_dmamuxBase[DMAMUX_INSTANCE_COUNT]; + +/*! @brief Two-dimensional array for EDMA channel interrupt vector number. */ +extern const IRQn_Type g_dmaIrqId[DMA_INSTANCE_COUNT][FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + +/*! + * @brief Channel status for the DMA channel. + * + * A structure describing the status of the DMA channel. The user can get the status from the channel callback + * function. + */ +typedef enum _dma_channel_status { + kDmaIdle, /*!< DMA channel is idle. */ + kDmaNormal, /*!< DMA channel is occupied. */ + kDmaError /*!< Error occurs in the DMA channel. */ +} dma_channel_status_t; + +/*! @brief Type for the DMA channel, which is used for the DMA channel allocation. */ +typedef enum _dma_channel_type { + kDmaInvalidChannel = 0xFFU, /*!< Macros indicating the failure of the channel request. */ + kDmaAnyChannel = 0xFEU /*!< Macros used when requesting a channel. */ + /*!< kEdmaAnyChannel means a request of dynamic channel allocation. */ +} dma_channel_type_t; + +/*! + * @brief A definition for the DMA channel callback function. + * + * A prototype for the callback function registered into the DMA driver. + */ +typedef void (*dma_callback_t)(void *parameter, dma_channel_status_t status); + +/*! @brief Data structure for the DMA channel management. */ +typedef struct DmaChannel { + uint8_t channel; /*!< Channel number */ + uint8_t dmamuxModule; /*!< Dmamux module index */ + uint8_t dmamuxChannel; /*!< Dmamux module channel */ + dma_callback_t callback; /*!< Callback function for this channel */ + void *parameter; /*!< Parameter for the callback function */ + volatile dma_channel_status_t status;/*!< Channel status */ +} dma_channel_t; + +/*! @brief Data structure for the DMA controller management. */ +typedef struct DmaState { + dma_channel_t * volatile dmaChan[FSL_FEATURE_DMA_DMAMUX_CHANNELS]; +#if USE_RTOS + mutex_t lock; +#endif +} dma_state_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name DMA Driver + * @{ + */ + +/*! + * @brief Initializes the DMA. + * + * @param state DMA state structure used for the DMA internal logic. + * @return If successful, returns the kStatus_DMA_Success. Otherwise, it returns an error. + */ +dma_status_t DMA_DRV_Init(dma_state_t *state); + +/*! + * @brief De-initializes the DMA. + * + * @return If successful, returns the kStatus_DMA_Success. Otherwise, it returns an error. + */ +dma_status_t DMA_DRV_Deinit(void); + +/*! + * @brief Registers the callback function and a parameter. + * + * The user registers the callback function and a parameter for a specified DMA channel. When the channel + * interrupt or a channel error happens, the callback and the parameter are called. + * The user parameter is also provided to give a channel status. + * + * @param chn A handler for the DMA channel + * @param callback Callback function + * @param para A parameter for callback functions + * @return If successful, returns the kStatus_DMA_Success. Otherwise, it returns an error. + */ +dma_status_t DMA_DRV_RegisterCallback( + dma_channel_t *chn, dma_callback_t callback, void *para); + +/*! + * @brief Gets the number of unfinished bytes. + * + * Gets the bytes that remain to be transferred. + * + * @param chn A handler for the DMA channel + * @return If successful, returns the kStatus_DMA_Success. Otherwise, it returns an error. + */ +uint32_t DMA_DRV_GetUnfinishedBytes(dma_channel_t *chn); + +/*! + * @brief Claims a DMA channel. + * + * @param channel Channel index which needs to claim. + * @param source DMA request source. + * @param chn A handler for the DMA channel + * @return If successful, returns the kStatus_DMA_Success. Otherwise, it returns an error. + */ +dma_status_t DMA_DRV_ClaimChannel( + uint32_t channel, dma_request_source_t source, dma_channel_t *chn); + + +/*! + * @brief Requests a DMA channel. + * + * This function provides two ways to allocate a DMA channel: static and dynamic allocation. + * To allocate a channel dynamically, set the channel parameter with the value of + * kDmaAnyChannel. The driver searches all available free channels and assigns the first + * channel to the user. + * To allocate the channel statically, set the channel parameter with the value of a specified + * channel. If the channel is available, the driver assigns the channel. + * Notes: The user must provide a handler memory for the DMA channel. The driver initializes + * the handler and configures the handler memory. + * + * @param channel A DMA channel number. If a channel is assigned with a valid channel number, the + * DMA driver tries to assign a specified channel. If a channel is assigned with + * kDmaAnyChannel, the DMA driver searches all available channels and assigns the first channel to the user. + * @param source A DMA hardware request. + * @param chn Memory pointing to DMA channel. The user must ensure that the handler memory is + * valid and that it will not be released or changed by any other code before the channel + * dma_free_channel() operation. + * + * @return If the channel allocation is successful, the return value indicates the requested channel. If + * not, the driver returns a kDmaInvalidChannel value to indicate that the request operation has failed. + */ +uint32_t DMA_DRV_RequestChannel( + uint32_t channel, dma_request_source_t source, dma_channel_t *chn); + +/*! + * @brief Frees DMA channel hardware and software resource. + * + * This function frees the relevant software and hardware resources. Both the request and the free operations need to + * be called as a pair. + * + * @param chn Memory pointing to DMA channel. + * @return If successful, returns the kStatus_DMA_Success. Otherwise, it returns an error. + * + */ +dma_status_t DMA_DRV_FreeChannel(dma_channel_t *chn); + +/*! + * @brief Starts a DMA channel. + * + * Starts a DMA channel. The driver starts a DMA channel by enabling the DMA request. + * A software start bit is not used in the DMA Peripheral driver. + * + * @param chn Memory pointing to the DMA channel. + * @return If successful, returns the kStatus_DMA_Success. Otherwise, it returns an error. + */ +dma_status_t DMA_DRV_StartChannel(dma_channel_t *chn); + +/*! + * @brief Stops a DMA channel. + * + * @param chn Memory pointing to the DMA channel. + * @return If successful, returns the kStatus_DMA_Success. Otherwise, it returns an error. + */ +dma_status_t DMA_DRV_StopChannel(dma_channel_t *chn); + +/*! + * @brief Configures a transfer for the DMA. + * + * Configures a transfer for the DMA. + * + * @param chn Memory pointing to the DMA channel. + * @param type Transfer type. + * @param size Size to be transferred on each DMA write/read. Source/Dest share the same write/read + * size. + * @param sourceAddr Source address. + * @param destAddr Destination address. + * @param length Bytes to be transferred. + * @return If successful, returns the kStatus_DMA_Success. Otherwise, it returns an error. + */ +dma_status_t DMA_DRV_ConfigTransfer( + dma_channel_t *chn, dma_transfer_type_t type, + uint32_t size, uint32_t sourceAddr, uint32_t destAddr, uint32_t length); + +/*! + * @brief Configures the channel link feature. + * + * @param chn Memory pointing to the DMA channel. + * @param link_config Configure of channel link in DMA. + * @return If successful, returns the kStatus_DMA_Success. Otherwise, it returns an error. + */ +dma_status_t DMA_DRV_ConfigChanLink( + dma_channel_t *chn, dma_channel_link_config_t *link_config); + + +/*! + * @brief DMA IRQ handler for both an interrupt and an error. + * + * @param channel DMA channel number. + * + */ +void DMA_DRV_IRQhandler(uint32_t channel); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif +#endif /* __FSL_DMA_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_dma_request.h b/KSDK_1.2.0/platform/drivers/inc/fsl_dma_request.h new file mode 100755 index 0000000..c093ea4 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_dma_request.h @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if !defined(__FSL_DMA_REQUEST_H__) +#define __FSL_DMA_REQUEST_H__ + +/*! + * @addtogroup edma_request + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Structure for the DMA hardware request + * + * Defines the structure for the DMA hardware request collections. The user can configure the + * hardware request into DMAMUX to trigger the DMA transfer accordingly. The index + * of the hardware request varies according to the to SoC. + */ +typedef enum _dma_request_source { +#if defined(CPU_MKL14Z32VFM4) || defined(CPU_MKL14Z64VFM4) || defined(CPU_MKL14Z32VFT4) || defined(CPU_MKL14Z64VFT4) || \ + defined(CPU_MKL14Z32VLH4) || defined(CPU_MKL14Z64VLH4) || defined(CPU_MKL14Z32VLK4) || defined(CPU_MKL14Z64VLK4) || \ + defined(CPU_MKL24Z32VFM4) || defined(CPU_MKL24Z64VFM4) || defined(CPU_MKL24Z32VFT4) || defined(CPU_MKL24Z64VFT4) || \ + defined(CPU_MKL24Z32VLH4) || defined(CPU_MKL24Z64VLH4) || defined(CPU_MKL24Z32VLK4) || defined(CPU_MKL24Z64VLK4) + kDmaRequestMux0Disable = 0|0x100U, + kDmaRequestMux0Reserved1 = 1|0x100U, + kDmaRequestMux0UART0Rx = 2|0x100U, + kDmaRequestMux0LPSCI0Rx = 2|0x100U, + kDmaRequestMux0UART0Tx = 3|0x100U, + kDmaRequestMux0LPSCI0Tx = 3|0x100U, + kDmaRequestMux0UART1Rx = 4|0x100U, + kDmaRequestMux0UART1Tx = 5|0x100U, + kDmaRequestMux0UART2Rx = 6|0x100U, + kDmaRequestMux0UART2Tx = 7|0x100U, + kDmaRequestMux0Reserved8 = 8|0x100U, + kDmaRequestMux0Reserved9 = 9|0x100U, + kDmaRequestMux0Reserved10 = 10|0x100U, + kDmaRequestMux0Reserved11 = 11|0x100U, + kDmaRequestMux0Reserved12 = 12|0x100U, + kDmaRequestMux0Reserved13 = 13|0x100U, + kDmaRequestMux0Reserved14 = 14|0x100U, + kDmaRequestMux0Reserved15 = 15|0x100U, + kDmaRequestMux0SPI0Rx = 16|0x100U, + kDmaRequestMux0SPI0Tx = 17|0x100U, + kDmaRequestMux0SPI1Rx = 18|0x100U, + kDmaRequestMux0SPI1Tx = 19|0x100U, + kDmaRequestMux0Reserved20 = 20|0x100U, + kDmaRequestMux0Reserved21 = 21|0x100U, + kDmaRequestMux0I2C0 = 22|0x100U, + kDmaRequestMux0I2C1 = 23|0x100U, + kDmaRequestMux0TPM0Channel0 = 24|0x100U, + kDmaRequestMux0TPM0Channel1 = 25|0x100U, + kDmaRequestMux0TPM0Channel2 = 26|0x100U, + kDmaRequestMux0TPM0Channel3 = 27|0x100U, + kDmaRequestMux0TPM0Channel4 = 28|0x100U, + kDmaRequestMux0TPM0Channel5 = 29|0x100U, + kDmaRequestMux0Reserved30 = 30|0x100U, + kDmaRequestMux0Reserved31 = 31|0x100U, + kDmaRequestMux0TPM1Channel0 = 32|0x100U, + kDmaRequestMux0TPM1Channel1 = 33|0x100U, + kDmaRequestMux0TPM2Channel0 = 34|0x100U, + kDmaRequestMux0TPM2Channel1 = 35|0x100U, + kDmaRequestMux0Reserved36 = 36|0x100U, + kDmaRequestMux0Reserved37 = 37|0x100U, + kDmaRequestMux0Reserved38 = 38|0x100U, + kDmaRequestMux0Reserved39 = 39|0x100U, + kDmaRequestMux0ADC0 = 40|0x100U, + kDmaRequestMux0Reserved41 = 41|0x100U, + kDmaRequestMux0CMP0 = 42|0x100U, + kDmaRequestMux0Reserved43 = 43|0x100U, + kDmaRequestMux0Reserved44 = 44|0x100U, + kDmaRequestMux0Reserved45 = 45|0x100U, + kDmaRequestMux0Reserved46 = 46|0x100U, + kDmaRequestMux0Reserved47 = 47|0x100U, + kDmaRequestMux0Reserved48 = 48|0x100U, + kDmaRequestMux0PortA = 49|0x100U, + kDmaRequestMux0Reserved50 = 50|0x100U, + kDmaRequestMux0Reserved51 = 51|0x100U, + kDmaRequestMux0PortD = 52|0x100U, + kDmaRequestMux0Reserved53 = 53|0x100U, + kDmaRequestMux0TPM0Overflow = 54|0x100U, + kDmaRequestMux0TPM1Overflow = 55|0x100U, + kDmaRequestMux0TPM2Overflow = 56|0x100U, + kDmaRequestMux0Reserved57 = 57|0x100U, + kDmaRequestMux0Reserved58 = 58|0x100U, + kDmaRequestMux0Reserved59 = 59|0x100U, + kDmaRequestMux0AlwaysOn60 = 60|0x100U, + kDmaRequestMux0AlwaysOn61 = 61|0x100U, + kDmaRequestMux0AlwaysOn62 = 62|0x100U, + kDmaRequestMux0AlwaysOn63 = 63|0x100U, +#elif defined(CPU_MKL15Z128CAD4) || defined(CPU_MKL15Z32VFM4) || defined(CPU_MKL15Z64VFM4) || defined(CPU_MKL15Z128VFM4) || \ + defined(CPU_MKL15Z32VFT4) || defined(CPU_MKL15Z64VFT4) || defined(CPU_MKL15Z128VFT4) || defined(CPU_MKL15Z32VLH4) || \ + defined(CPU_MKL15Z64VLH4) || defined(CPU_MKL15Z128VLH4) || defined(CPU_MKL15Z32VLK4) || defined(CPU_MKL15Z64VLK4) || \ + defined(CPU_MKL15Z128VLK4) || defined(CPU_MKL25Z32VFM4) || defined(CPU_MKL25Z64VFM4) || defined(CPU_MKL25Z128VFM4) || \ + defined(CPU_MKL25Z32VFT4) || defined(CPU_MKL25Z64VFT4) || defined(CPU_MKL25Z128VFT4) || defined(CPU_MKL25Z32VLH4) || \ + defined(CPU_MKL25Z64VLH4) || defined(CPU_MKL25Z128VLH4) || defined(CPU_MKL25Z32VLK4) || defined(CPU_MKL25Z64VLK4) || \ + defined(CPU_MKL25Z128VLK4) + kDmaRequestMux0Disable = 0|0x100U, + kDmaRequestMux0Reserved1 = 1|0x100U, + kDmaRequestMux0UART0Rx = 2|0x100U, + kDmaRequestMux0LPSCI0Rx = 2|0x100U, + kDmaRequestMux0UART0Tx = 3|0x100U, + kDmaRequestMux0LPSCI0Tx = 3|0x100U, + kDmaRequestMux0UART1Rx = 4|0x100U, + kDmaRequestMux0UART1Tx = 5|0x100U, + kDmaRequestMux0UART2Rx = 6|0x100U, + kDmaRequestMux0UART2Tx = 7|0x100U, + kDmaRequestMux0Reserved8 = 8|0x100U, + kDmaRequestMux0Reserved9 = 9|0x100U, + kDmaRequestMux0Reserved10 = 10|0x100U, + kDmaRequestMux0Reserved11 = 11|0x100U, + kDmaRequestMux0Reserved12 = 12|0x100U, + kDmaRequestMux0Reserved13 = 13|0x100U, + kDmaRequestMux0Reserved14 = 14|0x100U, + kDmaRequestMux0Reserved15 = 15|0x100U, + kDmaRequestMux0SPI0Rx = 16|0x100U, + kDmaRequestMux0SPI0Tx = 17|0x100U, + kDmaRequestMux0SPI1Rx = 18|0x100U, + kDmaRequestMux0SPI1Tx = 19|0x100U, + kDmaRequestMux0Reserved20 = 20|0x100U, + kDmaRequestMux0Reserved21 = 21|0x100U, + kDmaRequestMux0I2C0 = 22|0x100U, + kDmaRequestMux0I2C1 = 23|0x100U, + kDmaRequestMux0TPM0Channel0 = 24|0x100U, + kDmaRequestMux0TPM0Channel1 = 25|0x100U, + kDmaRequestMux0TPM0Channel2 = 26|0x100U, + kDmaRequestMux0TPM0Channel3 = 27|0x100U, + kDmaRequestMux0TPM0Channel4 = 28|0x100U, + kDmaRequestMux0TPM0Channel5 = 29|0x100U, + kDmaRequestMux0Reserved30 = 30|0x100U, + kDmaRequestMux0Reserved31 = 31|0x100U, + kDmaRequestMux0TPM1Channel0 = 32|0x100U, + kDmaRequestMux0TPM1Channel1 = 33|0x100U, + kDmaRequestMux0TPM2Channel0 = 34|0x100U, + kDmaRequestMux0TPM2Channel1 = 35|0x100U, + kDmaRequestMux0Reserved36 = 36|0x100U, + kDmaRequestMux0Reserved37 = 37|0x100U, + kDmaRequestMux0Reserved38 = 38|0x100U, + kDmaRequestMux0Reserved39 = 39|0x100U, + kDmaRequestMux0ADC0 = 40|0x100U, + kDmaRequestMux0Reserved41 = 41|0x100U, + kDmaRequestMux0CMP0 = 42|0x100U, + kDmaRequestMux0Reserved43 = 43|0x100U, + kDmaRequestMux0Reserved44 = 44|0x100U, + kDmaRequestMux0DAC0 = 45|0x100U, + kDmaRequestMux0Reserved46 = 46|0x100U, + kDmaRequestMux0Reserved47 = 47|0x100U, + kDmaRequestMux0Reserved48 = 48|0x100U, + kDmaRequestMux0PortA = 49|0x100U, + kDmaRequestMux0Reserved50 = 50|0x100U, + kDmaRequestMux0Reserved51 = 51|0x100U, + kDmaRequestMux0PortD = 52|0x100U, + kDmaRequestMux0Reserved53 = 53|0x100U, + kDmaRequestMux0TPM0Overflow = 54|0x100U, + kDmaRequestMux0TPM1Overflow = 55|0x100U, + kDmaRequestMux0TPM2Overflow = 56|0x100U, + kDmaRequestMux0TSI0 = 57|0x100U, + kDmaRequestMux0Reserved58 = 58|0x100U, + kDmaRequestMux0Reserved59 = 59|0x100U, + kDmaRequestMux0AlwaysOn60 = 60|0x100U, + kDmaRequestMux0AlwaysOn61 = 61|0x100U, + kDmaRequestMux0AlwaysOn62 = 62|0x100U, + kDmaRequestMux0AlwaysOn63 = 63|0x100U, +#elif defined(CPU_MKL16Z32VFM4) || defined(CPU_MKL16Z64VFM4) || defined(CPU_MKL16Z128VFM4) || defined(CPU_MKL16Z32VFT4) || \ + defined(CPU_MKL16Z64VFT4) || defined(CPU_MKL16Z128VFT4) || defined(CPU_MKL16Z32VLH4) || defined(CPU_MKL16Z64VLH4) || \ + defined(CPU_MKL16Z128VLH4) || defined(CPU_MKL26Z128CAL4) || defined(CPU_MKL26Z32VFM4) || defined(CPU_MKL26Z64VFM4) || \ + defined(CPU_MKL26Z128VFM4) || defined(CPU_MKL26Z32VFT4) || defined(CPU_MKL26Z64VFT4) || defined(CPU_MKL26Z128VFT4) || \ + defined(CPU_MKL26Z32VLH4) || defined(CPU_MKL26Z64VLH4) || defined(CPU_MKL26Z128VLH4) + kDmaRequestMux0Disable = 0|0x100U, + kDmaRequestMux0Reserved1 = 1|0x100U, + kDmaRequestMux0UART0Rx = 2|0x100U, + kDmaRequestMux0LPSCI0Rx = 2|0x100U, + kDmaRequestMux0UART0Tx = 3|0x100U, + kDmaRequestMux0LPSCI0Tx = 3|0x100U, + kDmaRequestMux0UART1Rx = 4|0x100U, + kDmaRequestMux0UART1Tx = 5|0x100U, + kDmaRequestMux0UART2Rx = 6|0x100U, + kDmaRequestMux0UART2Tx = 7|0x100U, + kDmaRequestMux0Reserved8 = 8|0x100U, + kDmaRequestMux0Reserved9 = 9|0x100U, + kDmaRequestMux0Reserved10 = 10|0x100U, + kDmaRequestMux0Reserved11 = 11|0x100U, + kDmaRequestMux0Reserved12 = 12|0x100U, + kDmaRequestMux0Reserved13 = 13|0x100U, + kDmaRequestMux0I2S0Rx = 14|0x100U, + kDmaRequestMux0I2S0Tx = 15|0x100U, + kDmaRequestMux0SPI0Rx = 16|0x100U, + kDmaRequestMux0SPI0Tx = 17|0x100U, + kDmaRequestMux0SPI1Rx = 18|0x100U, + kDmaRequestMux0SPI1Tx = 19|0x100U, + kDmaRequestMux0Reserved20 = 20|0x100U, + kDmaRequestMux0Reserved21 = 21|0x100U, + kDmaRequestMux0I2C0 = 22|0x100U, + kDmaRequestMux0I2C1 = 23|0x100U, + kDmaRequestMux0TPM0Channel0 = 24|0x100U, + kDmaRequestMux0TPM0Channel1 = 25|0x100U, + kDmaRequestMux0TPM0Channel2 = 26|0x100U, + kDmaRequestMux0TPM0Channel3 = 27|0x100U, + kDmaRequestMux0TPM0Channel4 = 28|0x100U, + kDmaRequestMux0TPM0Channel5 = 29|0x100U, + kDmaRequestMux0Reserved30 = 30|0x100U, + kDmaRequestMux0Reserved31 = 31|0x100U, + kDmaRequestMux0TPM1Channel0 = 32|0x100U, + kDmaRequestMux0TPM1Channel1 = 33|0x100U, + kDmaRequestMux0TPM2Channel0 = 34|0x100U, + kDmaRequestMux0TPM2Channel1 = 35|0x100U, + kDmaRequestMux0Reserved36 = 36|0x100U, + kDmaRequestMux0Reserved37 = 37|0x100U, + kDmaRequestMux0Reserved38 = 38|0x100U, + kDmaRequestMux0Reserved39 = 39|0x100U, + kDmaRequestMux0ADC0 = 40|0x100U, + kDmaRequestMux0Reserved41 = 41|0x100U, + kDmaRequestMux0CMP0 = 42|0x100U, + kDmaRequestMux0Reserved43 = 43|0x100U, + kDmaRequestMux0Reserved44 = 44|0x100U, + kDmaRequestMux0DAC0 = 45|0x100U, + kDmaRequestMux0Reserved46 = 46|0x100U, + kDmaRequestMux0Reserved47 = 47|0x100U, + kDmaRequestMux0Reserved48 = 48|0x100U, + kDmaRequestMux0PortA = 49|0x100U, + kDmaRequestMux0Reserved50 = 50|0x100U, + kDmaRequestMux0PortC = 51|0x100U, + kDmaRequestMux0PortD = 52|0x100U, + kDmaRequestMux0Reserved53 = 53|0x100U, + kDmaRequestMux0TPM0Overflow = 54|0x100U, + kDmaRequestMux0TPM1Overflow = 55|0x100U, + kDmaRequestMux0TPM2Overflow = 56|0x100U, + kDmaRequestMux0Reserved57 = 57|0x100U, + kDmaRequestMux0Reserved58 = 58|0x100U, + kDmaRequestMux0Reserved59 = 59|0x100U, + kDmaRequestMux0AlwaysOn60 = 60|0x100U, + kDmaRequestMux0AlwaysOn61 = 61|0x100U, + kDmaRequestMux0AlwaysOn62 = 62|0x100U, + kDmaRequestMux0AlwaysOn63 = 63|0x100U, +#elif defined(CPU_MKL16Z256VLH4) || defined(CPU_MKL16Z256VMP4) || defined(CPU_MKL26Z256VLH4) || defined(CPU_MKL26Z128VLL4) || \ + defined(CPU_MKL26Z256VLL4) || defined(CPU_MKL26Z128VMC4) || defined(CPU_MKL26Z256VMC4) || defined(CPU_MKL26Z256VMP4) || \ + defined(CPU_MKL36Z64VLH4) || defined(CPU_MKL36Z128VLH4) || defined(CPU_MKL36Z256VLH4) || defined(CPU_MKL36Z64VLL4) || \ + defined(CPU_MKL36Z128VLL4) || defined(CPU_MKL36Z256VLL4) || defined(CPU_MKL36Z128VMC4) || defined(CPU_MKL36Z256VMC4) || \ + defined(CPU_MKL36Z256VMP4) || defined(CPU_MKL46Z128VLH4) || defined(CPU_MKL46Z256VLH4) || defined(CPU_MKL46Z128VLL4) || \ + defined(CPU_MKL46Z256VLL4) || defined(CPU_MKL46Z128VMC4) || defined(CPU_MKL46Z256VMC4) || defined(CPU_MKL46Z256VMP4) + kDmaRequestMux0Disable = 0|0x100U, + kDmaRequestMux0Reserved1 = 1|0x100U, + kDmaRequestMux0UART0Rx = 2|0x100U, + kDmaRequestMux0LPSCI0Rx = 2|0x100U, + kDmaRequestMux0UART0Tx = 3|0x100U, + kDmaRequestMux0LPSCI0Tx = 3|0x100U, + kDmaRequestMux0UART1Rx = 4|0x100U, + kDmaRequestMux0UART1Tx = 5|0x100U, + kDmaRequestMux0UART2Rx = 6|0x100U, + kDmaRequestMux0UART2Tx = 7|0x100U, + kDmaRequestMux0Reserved8 = 8|0x100U, + kDmaRequestMux0Reserved9 = 9|0x100U, + kDmaRequestMux0Reserved10 = 10|0x100U, + kDmaRequestMux0Reserved11 = 11|0x100U, + kDmaRequestMux0Reserved12 = 12|0x100U, + kDmaRequestMux0Reserved13 = 13|0x100U, + kDmaRequestMux0I2S0Rx = 14|0x100U, + kDmaRequestMux0I2S0Tx = 15|0x100U, + kDmaRequestMux0SPI0Rx = 16|0x100U, + kDmaRequestMux0SPI0Tx = 17|0x100U, + kDmaRequestMux0SPI1Rx = 18|0x100U, + kDmaRequestMux0SPI1Tx = 19|0x100U, + kDmaRequestMux0Reserved20 = 20|0x100U, + kDmaRequestMux0Reserved21 = 21|0x100U, + kDmaRequestMux0I2C0 = 22|0x100U, + kDmaRequestMux0I2C1 = 23|0x100U, + kDmaRequestMux0TPM0Channel0 = 24|0x100U, + kDmaRequestMux0TPM0Channel1 = 25|0x100U, + kDmaRequestMux0TPM0Channel2 = 26|0x100U, + kDmaRequestMux0TPM0Channel3 = 27|0x100U, + kDmaRequestMux0TPM0Channel4 = 28|0x100U, + kDmaRequestMux0TPM0Channel5 = 29|0x100U, + kDmaRequestMux0Reserved30 = 30|0x100U, + kDmaRequestMux0Reserved31 = 31|0x100U, + kDmaRequestMux0TPM1Channel0 = 32|0x100U, + kDmaRequestMux0TPM1Channel1 = 33|0x100U, + kDmaRequestMux0TPM2Channel0 = 34|0x100U, + kDmaRequestMux0TPM2Channel1 = 35|0x100U, + kDmaRequestMux0Reserved36 = 36|0x100U, + kDmaRequestMux0Reserved37 = 37|0x100U, + kDmaRequestMux0Reserved38 = 38|0x100U, + kDmaRequestMux0Reserved39 = 39|0x100U, + kDmaRequestMux0ADC0 = 40|0x100U, + kDmaRequestMux0Reserved41 = 41|0x100U, + kDmaRequestMux0CMP0 = 42|0x100U, + kDmaRequestMux0Reserved43 = 43|0x100U, + kDmaRequestMux0Reserved44 = 44|0x100U, + kDmaRequestMux0DAC0 = 45|0x100U, + kDmaRequestMux0Reserved46 = 46|0x100U, + kDmaRequestMux0Reserved47 = 47|0x100U, + kDmaRequestMux0Reserved48 = 48|0x100U, + kDmaRequestMux0PortA = 49|0x100U, + kDmaRequestMux0Reserved50 = 50|0x100U, + kDmaRequestMux0PortC = 51|0x100U, + kDmaRequestMux0PortD = 52|0x100U, + kDmaRequestMux0Reserved53 = 53|0x100U, + kDmaRequestMux0TPM0Overflow = 54|0x100U, + kDmaRequestMux0TPM1Overflow = 55|0x100U, + kDmaRequestMux0TPM2Overflow = 56|0x100U, + kDmaRequestMux0TSI = 57|0x100U, + kDmaRequestMux0Reserved58 = 58|0x100U, + kDmaRequestMux0Reserved59 = 59|0x100U, + kDmaRequestMux0AlwaysOn60 = 60|0x100U, + kDmaRequestMux0AlwaysOn61 = 61|0x100U, + kDmaRequestMux0AlwaysOn62 = 62|0x100U, + kDmaRequestMux0AlwaysOn63 = 63|0x100U, +#elif defined(CPU_MKL17Z128VFM4) || defined(CPU_MKL17Z256VFM4) || defined(CPU_MKL17Z128VFT4) || defined(CPU_MKL17Z256VFT4) || \ + defined(CPU_MKL17Z128VLH4) || defined(CPU_MKL17Z256VLH4) || defined(CPU_MKL17Z128VMP4) || defined(CPU_MKL17Z256VMP4) || \ + defined(CPU_MKL27Z128VFM4) || defined(CPU_MKL27Z256VFM4) || defined(CPU_MKL27Z128VFT4) || defined(CPU_MKL27Z256VFT4) || \ + defined(CPU_MKL27Z128VLH4) || defined(CPU_MKL27Z256VLH4) || defined(CPU_MKL27Z128VMP4) || defined(CPU_MKL27Z256VMP4) || \ + defined(CPU_MKL33Z128VLH4) || defined(CPU_MKL33Z256VLH4) || defined(CPU_MKL33Z128VMP4) || defined(CPU_MKL33Z256VMP4) || \ + defined(CPU_MKL43Z128VLH4) || defined(CPU_MKL43Z256VLH4) || defined(CPU_MKL43Z128VMP4) || defined(CPU_MKL43Z256VMP4) + kDmaRequestMux0Disable = 0|0x100U, + kDmaRequestMux0Reserved1 = 1|0x100U, + kDmaRequestMux0LPUART0Rx = 2|0x100U, + kDmaRequestMux0LPUART0Tx = 3|0x100U, + kDmaRequestMux0LPUART1Rx = 4|0x100U, + kDmaRequestMux0LPUART1Tx = 5|0x100U, + kDmaRequestMux0UART2Rx = 6|0x100U, + kDmaRequestMux0UART2Tx = 7|0x100U, + kDmaRequestMux0Reserved8 = 8|0x100U, + kDmaRequestMux0Reserved9 = 9|0x100U, + kDmaRequestMux0FlexIOChannel0 = 10|0x100U, + kDmaRequestMux0FlexIOChannel1 = 11|0x100U, + kDmaRequestMux0FlexIOChannel2 = 12|0x100U, + kDmaRequestMux0FlexIOChannel3 = 13|0x100U, + kDmaRequestMux0I2S0Rx = 14|0x100U, + kDmaRequestMux0I2S0Tx = 15|0x100U, + kDmaRequestMux0SPI0Rx = 16|0x100U, + kDmaRequestMux0SPI0Tx = 17|0x100U, + kDmaRequestMux0SPI1Rx = 18|0x100U, + kDmaRequestMux0SPI1Tx = 19|0x100U, + kDmaRequestMux0Reserved20 = 20|0x100U, + kDmaRequestMux0Reserved21 = 21|0x100U, + kDmaRequestMux0I2C0 = 22|0x100U, + kDmaRequestMux0I2C1 = 23|0x100U, + kDmaRequestMux0TPM0Channel0 = 24|0x100U, + kDmaRequestMux0TPM0Channel1 = 25|0x100U, + kDmaRequestMux0TPM0Channel2 = 26|0x100U, + kDmaRequestMux0TPM0Channel3 = 27|0x100U, + kDmaRequestMux0TPM0Channel4 = 28|0x100U, + kDmaRequestMux0TPM0Channel5 = 29|0x100U, + kDmaRequestMux0Reserved30 = 30|0x100U, + kDmaRequestMux0Reserved31 = 31|0x100U, + kDmaRequestMux0TPM1Channel0 = 32|0x100U, + kDmaRequestMux0TPM1Channel1 = 33|0x100U, + kDmaRequestMux0TPM2Channel0 = 34|0x100U, + kDmaRequestMux0TPM2Channel1 = 35|0x100U, + kDmaRequestMux0Reserved36 = 36|0x100U, + kDmaRequestMux0Reserved37 = 37|0x100U, + kDmaRequestMux0Reserved38 = 38|0x100U, + kDmaRequestMux0Reserved39 = 39|0x100U, + kDmaRequestMux0ADC0 = 40|0x100U, + kDmaRequestMux0Reserved41 = 41|0x100U, + kDmaRequestMux0CMP0 = 42|0x100U, + kDmaRequestMux0Reserved43 = 43|0x100U, + kDmaRequestMux0Reserved44 = 44|0x100U, + kDmaRequestMux0DAC0 = 45|0x100U, + kDmaRequestMux0Reserved46 = 46|0x100U, + kDmaRequestMux0Reserved47 = 47|0x100U, + kDmaRequestMux0Reserved48 = 48|0x100U, + kDmaRequestMux0PortA = 49|0x100U, + kDmaRequestMux0Reserved50 = 50|0x100U, + kDmaRequestMux0PortC = 51|0x100U, + kDmaRequestMux0PortD = 52|0x100U, + kDmaRequestMux0Reserved53 = 53|0x100U, + kDmaRequestMux0TPM0Overflow = 54|0x100U, + kDmaRequestMux0TPM1Overflow = 55|0x100U, + kDmaRequestMux0TPM2Overflow = 56|0x100U, + kDmaRequestMux0Reserved57 = 57|0x100U, + kDmaRequestMux0Reserved58 = 58|0x100U, + kDmaRequestMux0Reserved59 = 59|0x100U, + kDmaRequestMux0AlwaysOn60 = 60|0x100U, + kDmaRequestMux0AlwaysOn61 = 61|0x100U, + kDmaRequestMux0AlwaysOn62 = 62|0x100U, + kDmaRequestMux0AlwaysOn63 = 63|0x100U, +#elif defined(CPU_MKL17Z32VDA4) || defined(CPU_MKL17Z64VDA4) || defined(CPU_MKL17Z32VFM4) || defined(CPU_MKL17Z64VFM4) || \ + defined(CPU_MKL17Z32VFT4) || defined(CPU_MKL17Z64VFT4) || defined(CPU_MKL17Z32VLH4) || defined(CPU_MKL17Z64VLH4) || \ + defined(CPU_MKL17Z32VMP4) || defined(CPU_MKL17Z64VMP4) || 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) + kDmaRequestMux0Disable = 0|0x100U, + kDmaRequestMux0Reserved1 = 1|0x100U, + kDmaRequestMux0LPUART0Rx = 2|0x100U, + kDmaRequestMux0LPUART0Tx = 3|0x100U, + kDmaRequestMux0LPUART1Rx = 4|0x100U, + kDmaRequestMux0LPUART1Tx = 5|0x100U, + kDmaRequestMux0UART2Rx = 6|0x100U, + kDmaRequestMux0UART2Tx = 7|0x100U, + kDmaRequestMux0Reserved8 = 8|0x100U, + kDmaRequestMux0Reserved9 = 9|0x100U, + kDmaRequestMux0FlexIOChannel0 = 10|0x100U, + kDmaRequestMux0FlexIOChannel1 = 11|0x100U, + kDmaRequestMux0FlexIOChannel2 = 12|0x100U, + kDmaRequestMux0FlexIOChannel3 = 13|0x100U, + kDmaRequestMux0Reserved14 = 14|0x100U, + kDmaRequestMux0Reserved15 = 15|0x100U, + kDmaRequestMux0SPI0Rx = 16|0x100U, + kDmaRequestMux0SPI0Tx = 17|0x100U, + kDmaRequestMux0SPI1Rx = 18|0x100U, + kDmaRequestMux0SPI1Tx = 19|0x100U, + kDmaRequestMux0Reserved20 = 20|0x100U, + kDmaRequestMux0Reserved21 = 21|0x100U, + kDmaRequestMux0I2C0 = 22|0x100U, + kDmaRequestMux0I2C1 = 23|0x100U, + kDmaRequestMux0TPM0Channel0 = 24|0x100U, + kDmaRequestMux0TPM0Channel1 = 25|0x100U, + kDmaRequestMux0TPM0Channel2 = 26|0x100U, + kDmaRequestMux0TPM0Channel3 = 27|0x100U, + kDmaRequestMux0TPM0Channel4 = 28|0x100U, + kDmaRequestMux0TPM0Channel5 = 29|0x100U, + kDmaRequestMux0Reserved30 = 30|0x100U, + kDmaRequestMux0Reserved31 = 31|0x100U, + kDmaRequestMux0TPM1Channel0 = 32|0x100U, + kDmaRequestMux0TPM1Channel1 = 33|0x100U, + kDmaRequestMux0TPM2Channel0 = 34|0x100U, + kDmaRequestMux0TPM2Channel1 = 35|0x100U, + kDmaRequestMux0Reserved36 = 36|0x100U, + kDmaRequestMux0Reserved37 = 37|0x100U, + kDmaRequestMux0Reserved38 = 38|0x100U, + kDmaRequestMux0Reserved39 = 39|0x100U, + kDmaRequestMux0ADC0 = 40|0x100U, + kDmaRequestMux0Reserved41 = 41|0x100U, + kDmaRequestMux0CMP0 = 42|0x100U, + kDmaRequestMux0Reserved43 = 43|0x100U, + kDmaRequestMux0Reserved44 = 44|0x100U, + kDmaRequestMux0Reserved45 = 45|0x100U, + kDmaRequestMux0Reserved46 = 46|0x100U, + kDmaRequestMux0Reserved47 = 47|0x100U, + kDmaRequestMux0Reserved48 = 48|0x100U, + kDmaRequestMux0PortA = 49|0x100U, + kDmaRequestMux0PortB = 50|0x100U, + kDmaRequestMux0PortC = 51|0x100U, + kDmaRequestMux0PortD = 52|0x100U, + kDmaRequestMux0PortE = 53|0x100U, + kDmaRequestMux0TPM0Overflow = 54|0x100U, + kDmaRequestMux0TPM1Overflow = 55|0x100U, + kDmaRequestMux0TPM2Overflow = 56|0x100U, + kDmaRequestMux0Reserved57 = 57|0x100U, + kDmaRequestMux0Reserved58 = 58|0x100U, + kDmaRequestMux0Reserved59 = 59|0x100U, + kDmaRequestMux0AlwaysOn60 = 60|0x100U, + kDmaRequestMux0AlwaysOn61 = 61|0x100U, + kDmaRequestMux0AlwaysOn62 = 62|0x100U, + kDmaRequestMux0AlwaysOn63 = 63|0x100U, +#elif defined(CPU_MKL34Z64VLH4) || defined(CPU_MKL34Z64VLL4) + kDmaRequestMux0Disable = 0|0x100U, + kDmaRequestMux0Reserved1 = 1|0x100U, + kDmaRequestMux0UART0Rx = 2|0x100U, + kDmaRequestMux0LPSCI0Rx = 2|0x100U, + kDmaRequestMux0UART0Tx = 3|0x100U, + kDmaRequestMux0LPSCI0Tx = 3|0x100U, + kDmaRequestMux0UART1Rx = 4|0x100U, + kDmaRequestMux0UART1Tx = 5|0x100U, + kDmaRequestMux0UART2Rx = 6|0x100U, + kDmaRequestMux0UART2Tx = 7|0x100U, + kDmaRequestMux0Reserved8 = 8|0x100U, + kDmaRequestMux0Reserved9 = 9|0x100U, + kDmaRequestMux0Reserved10 = 10|0x100U, + kDmaRequestMux0Reserved11 = 11|0x100U, + kDmaRequestMux0Reserved12 = 12|0x100U, + kDmaRequestMux0Reserved13 = 13|0x100U, + kDmaRequestMux0Reserved14 = 14|0x100U, + kDmaRequestMux0Reserved15 = 15|0x100U, + kDmaRequestMux0SPI0Rx = 16|0x100U, + kDmaRequestMux0SPI0Tx = 17|0x100U, + kDmaRequestMux0SPI1Rx = 18|0x100U, + kDmaRequestMux0SPI1Tx = 19|0x100U, + kDmaRequestMux0Reserved20 = 20|0x100U, + kDmaRequestMux0Reserved21 = 21|0x100U, + kDmaRequestMux0I2C0 = 22|0x100U, + kDmaRequestMux0I2C1 = 23|0x100U, + kDmaRequestMux0TPM0Channel0 = 24|0x100U, + kDmaRequestMux0TPM0Channel1 = 25|0x100U, + kDmaRequestMux0TPM0Channel2 = 26|0x100U, + kDmaRequestMux0TPM0Channel3 = 27|0x100U, + kDmaRequestMux0TPM0Channel4 = 28|0x100U, + kDmaRequestMux0TPM0Channel5 = 29|0x100U, + kDmaRequestMux0Reserved30 = 30|0x100U, + kDmaRequestMux0Reserved31 = 31|0x100U, + kDmaRequestMux0TPM1Channel0 = 32|0x100U, + kDmaRequestMux0TPM1Channel1 = 33|0x100U, + kDmaRequestMux0TPM2Channel0 = 34|0x100U, + kDmaRequestMux0TPM2Channel1 = 35|0x100U, + kDmaRequestMux0Reserved36 = 36|0x100U, + kDmaRequestMux0Reserved37 = 37|0x100U, + kDmaRequestMux0Reserved38 = 38|0x100U, + kDmaRequestMux0Reserved39 = 39|0x100U, + kDmaRequestMux0ADC0 = 40|0x100U, + kDmaRequestMux0Reserved41 = 41|0x100U, + kDmaRequestMux0CMP0 = 42|0x100U, + kDmaRequestMux0Reserved43 = 43|0x100U, + kDmaRequestMux0Reserved44 = 44|0x100U, + kDmaRequestMux0Reserved45 = 45|0x100U, + kDmaRequestMux0Reserved46 = 46|0x100U, + kDmaRequestMux0Reserved47 = 47|0x100U, + kDmaRequestMux0Reserved48 = 48|0x100U, + kDmaRequestMux0PortA = 49|0x100U, + kDmaRequestMux0Reserved50 = 50|0x100U, + kDmaRequestMux0PortC = 51|0x100U, + kDmaRequestMux0PortD = 52|0x100U, + kDmaRequestMux0Reserved53 = 53|0x100U, + kDmaRequestMux0TPM0Overflow = 54|0x100U, + kDmaRequestMux0TPM1Overflow = 55|0x100U, + kDmaRequestMux0TPM2Overflow = 56|0x100U, + kDmaRequestMux0Reserved57 = 57|0x100U, + kDmaRequestMux0Reserved58 = 58|0x100U, + kDmaRequestMux0Reserved59 = 59|0x100U, + kDmaRequestMux0AlwaysOn60 = 60|0x100U, + kDmaRequestMux0AlwaysOn61 = 61|0x100U, + kDmaRequestMux0AlwaysOn62 = 62|0x100U, + kDmaRequestMux0AlwaysOn63 = 63|0x100U, +#elif defined(CPU_MKW01Z128CHN4) + kDmaRequestMux0Disable = 0|0x100U, + kDmaRequestMux0Reserved1 = 1|0x100U, + kDmaRequestMux0UART0Rx = 2|0x100U, + kDmaRequestMux0LPSCI0Rx = 2|0x100U, + kDmaRequestMux0UART0Tx = 3|0x100U, + kDmaRequestMux0LPSCI0Tx = 3|0x100U, + kDmaRequestMux0UART1Rx = 4|0x100U, + kDmaRequestMux0UART1Tx = 5|0x100U, + kDmaRequestMux0UART2Rx = 6|0x100U, + kDmaRequestMux0UART2Tx = 7|0x100U, + kDmaRequestMux0Reserved8 = 8|0x100U, + kDmaRequestMux0Reserved9 = 9|0x100U, + kDmaRequestMux0Reserved10 = 10|0x100U, + kDmaRequestMux0Reserved11 = 11|0x100U, + kDmaRequestMux0Reserved12 = 12|0x100U, + kDmaRequestMux0Reserved13 = 13|0x100U, + kDmaRequestMux0Reserved14 = 14|0x100U, + kDmaRequestMux0Reserved15 = 15|0x100U, + kDmaRequestMux0SPI0Rx = 16|0x100U, + kDmaRequestMux0SPI0Tx = 17|0x100U, + kDmaRequestMux0SPI1Rx = 18|0x100U, + kDmaRequestMux0SPI1Tx = 19|0x100U, + kDmaRequestMux0Reserved20 = 20|0x100U, + kDmaRequestMux0Reserved21 = 21|0x100U, + kDmaRequestMux0I2C0 = 22|0x100U, + kDmaRequestMux0I2C1 = 23|0x100U, + kDmaRequestMux0TPM0Channel0 = 24|0x100U, + kDmaRequestMux0TPM0Channel1 = 25|0x100U, + kDmaRequestMux0TPM0Channel2 = 26|0x100U, + kDmaRequestMux0TPM0Channel3 = 27|0x100U, + kDmaRequestMux0TPM0Channel4 = 28|0x100U, + kDmaRequestMux0TPM0Channel5 = 29|0x100U, + kDmaRequestMux0Reserved30 = 30|0x100U, + kDmaRequestMux0Reserved31 = 31|0x100U, + kDmaRequestMux0TPM1Channel0 = 32|0x100U, + kDmaRequestMux0TPM1Channel1 = 33|0x100U, + kDmaRequestMux0TPM2Channel0 = 34|0x100U, + kDmaRequestMux0TPM2Channel1 = 35|0x100U, + kDmaRequestMux0Reserved36 = 36|0x100U, + kDmaRequestMux0Reserved37 = 37|0x100U, + kDmaRequestMux0Reserved38 = 38|0x100U, + kDmaRequestMux0Reserved39 = 39|0x100U, + kDmaRequestMux0ADC0 = 40|0x100U, + kDmaRequestMux0Reserved41 = 41|0x100U, + kDmaRequestMux0CMP0 = 42|0x100U, + kDmaRequestMux0Reserved43 = 43|0x100U, + kDmaRequestMux0Reserved44 = 44|0x100U, + kDmaRequestMux0DAC0 = 45|0x100U, + kDmaRequestMux0Reserved46 = 46|0x100U, + kDmaRequestMux0Reserved47 = 47|0x100U, + kDmaRequestMux0Reserved48 = 48|0x100U, + kDmaRequestMux0PortA = 49|0x100U, + kDmaRequestMux0Reserved50 = 50|0x100U, + kDmaRequestMux0PortC = 51|0x100U, + kDmaRequestMux0PortD = 52|0x100U, + kDmaRequestMux0Reserved53 = 53|0x100U, + kDmaRequestMux0TPM0Overflow = 54|0x100U, + kDmaRequestMux0TPM1Overflow = 55|0x100U, + kDmaRequestMux0TPM2Overflow = 56|0x100U, + kDmaRequestMux0TSI0 = 57|0x100U, + kDmaRequestMux0Reserved58 = 58|0x100U, + kDmaRequestMux0Reserved59 = 59|0x100U, + kDmaRequestMux0AlwaysOn60 = 60|0x100U, + kDmaRequestMux0AlwaysOn61 = 61|0x100U, + kDmaRequestMux0AlwaysOn62 = 62|0x100U, + kDmaRequestMux0AlwaysOn63 = 63|0x100U, +#else + #error "No valid CPU defined!" +#endif +} dma_request_source_t; + + + +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_edma_master_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_edma_master_driver.h new file mode 100755 index 0000000..f9e0001 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_edma_master_driver.h @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_DSPI_EDMA_MASTER_DRIVER_H__) +#define __FSL_DSPI_EDMA_MASTER_DRIVER_H__ + +#include "fsl_dspi_hal.h" +#include "fsl_os_abstraction.h" +#include "fsl_edma_driver.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/*! + * @addtogroup dspi_master_driver + * @{ + */ + +/*! @brief Table of base pointers for SPI instances. */ +extern SPI_Type * const g_dspiBase[SPI_INSTANCE_COUNT]; + +/*! @brief Table to save DSPI IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_dspiIrqId[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Data structure containing information about a device on the SPI bus with EDMA. + * + * The user must populate the members to set up the DSPI master with EDMA and + * properly communicate with the SPI device. + */ +typedef struct DspiEdmaDevice { + uint32_t bitsPerSec; /*!< @brief Baud rate in bits per second.*/ + dspi_data_format_config_t dataBusConfig; /* data format configuration structure*/ +} dspi_edma_device_t; + +/*! + * @brief Runtime state structure for the DSPI master driver with EDMA. + * + * This structure holds data used by the DSPI master Peripheral driver to + * communicate between the transfer function and the interrupt handler. The + * interrupt handler also uses this information to keep track of its progress. + * The user passes the memory for this run-time state structure. The + * DSPI master driver populates the members. + */ +typedef struct DspiEdmaMasterState { + dspi_ctar_selection_t whichCtar; /*!< Desired Clock and Transfer Attributes Register (CTAR)*/ + uint32_t bitsPerFrame; /*!< Desired number of bits per frame */ + dspi_which_pcs_config_t whichPcs; /*!< Desired Peripheral Chip Select (pcs) */ + bool isChipSelectContinuous; /*!< Option to enable the continuous assertion of chip select + between transfers*/ + uint32_t dspiSourceClock; /*!< Module source clock*/ + volatile bool isTransferInProgress; /*!< True if there is an active transfer.*/ + volatile bool isTransferBlocking; /*!< True if transfer is a blocking transaction. */ + semaphore_t irqSync; /*!< Used to wait for ISR to complete its business.*/ + edma_chn_state_t dmaCmdData2Fifo; /*!< Structure definition for the eDMA channel */ + edma_chn_state_t dmaSrc2CmdData; /*!< Structure definition for the eDMA channel */ + edma_chn_state_t dmaFifo2Receive; /*!< Structure definition for the eDMA channel */ + edma_software_tcd_t * stcdSrc2CmdDataLast; /*!< Pointer to SW TCD in memory */ + bool extraByte; /*!< Flag used for 16-bit transfers with odd byte count */ + uint8_t * rxBuffer; /*!< The buffer into which received bytes are placed.*/ + uint32_t rxTransferByteCnt; /*!< Number of bytes to receive.*/ +} dspi_edma_master_state_t; + +/*! + * @brief The user configuration structure for the DSPI master driver with EDMA. + * + * Use an instance of this structure with the DSPI_DRV_EdmaMasterInit() function. This allows the user to configure + * the most common settings of the DSPI peripheral with a single function call. + */ +typedef struct DspiEdmaMasterUserConfig { + dspi_ctar_selection_t whichCtar; /*!< Desired Clock and Transfer Attributes Register(CTAR)*/ + bool isSckContinuous; /*!< Disable or Enable continuous SCK operation*/ + bool isChipSelectContinuous; /*!< Option to enable the continuous assertion of chip select + between transfers */ + dspi_which_pcs_config_t whichPcs; /*!< Desired Peripheral Chip Select (pcs) */ + dspi_pcs_polarity_config_t pcsPolarity; /*!< Peripheral Chip Select (pcs) polarity setting.*/ +} dspi_edma_master_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and shutdown + * @{ + */ + +/*! + * @brief Initializes a DSPI instance for master mode operation to work with EDMA. + * + * This function uses a DMA-driven method for transferring data. + * This function initializes the run-time state structure to track the ongoing + * transfers, ungates the clock to the DSPI module, resets the DSPI module, initializes the module + * to user defined settings and default settings, configures the IRQ state structure, enables + * the module-level interrupt to the core, and enables the DSPI module. + * The CTAR parameter is special in that it allows the user to have different SPI devices + * connected to the same DSPI module instance in addition to different peripheral chip + * selects. Each CTAR contains the bus attributes associated with that particular SPI device. + * For most use cases, where only one SPI device is connected per DSPI module + * instance, use CTAR0. + * This is an example to set up and call the DSPI_DRV_EdmaMasterInit function by passing + * in these parameters: + @code + dspi_edma_master_state_t dspiEdmaState; <- the user allocates memory for this structure + uint32_t calculatedBaudRate; + dspi_edma_master_user_config_t userConfig; <- the user populates members for this structure + userConfig.isChipSelectContinuous = false; + userConfig.isSckContinuous = false; + userConfig.pcsPolarity = kDspiPcs_ActiveLow; + userConfig.whichCtar = kDspiCtar0; + userConfig.whichPcs = kDspiPcs0; + DSPI_DRV_EdmaMasterInit(masterInstance, &dspiEdmaState, &userConfig); + @endcode + * + * @param instance The instance number of the DSPI peripheral. + * @param dspiEdmaState The pointer to the DSPI EDMA master driver state structure. The user + * passes the memory for the run-time state structure. The DSPI master driver + * populates the members. The run-time state structure keeps track of the + * transfer in progress. + * @param userConfig The dspi_edma_master_user_config_t user configuration structure. The user + * populates the members of this structure and passes the pointer of the structure + * into the function. + * @param stcdSrc2CmdDataLast This is a pointer to a structure of the stcdSrc2CmdDataLast type. It + * needs to be aligned to a 32-byte boundary. Some compilers allow you to use a + * #pragma directive to align a variable to a desired boundary. + * + * @return An error code or kStatus_DSPI_Success. + */ +dspi_status_t DSPI_DRV_EdmaMasterInit(uint32_t instance, + dspi_edma_master_state_t * dspiEdmaState, + const dspi_edma_master_user_config_t * userConfig, + edma_software_tcd_t * stcdSrc2CmdDataLast); + + +/*! + * @brief Shuts down a DSPI instance with the EDMA support. + * + * This function resets the DSPI peripheral, gates its clock, disables any used interrupts to + * the core, and releases any used DMA channels. + * + * @param instance The instance number of the DSPI peripheral. + * @return kStatus_DSPI_Success indicating successful de-initialization + */ +dspi_status_t DSPI_DRV_EdmaMasterDeinit(uint32_t instance); + + +/*! + * @brief Configures the DSPI master mode bus timing delay options with the EDMA support. + * + * This function uses the DSPI module delay options to + * "fine tune" some of the signal timings and match the timing needs of a slower peripheral device. + * This is an optional function that can be called after the DSPI module has been initialized for + * master mode. + * The bus timing delays that can be adjusted are listed below: + * + * PCS to SCK Delay: Adjustable delay option between the assertion of the PCS signal to the + * first SCK edge. + * + * After SCK Delay: Adjustable delay option between the last edge of SCK to the de-assertion + * of the PCS signal. + * + * Delay after Transfer: Adjustable delay option between the de-assertion of the PCS signal for a + * frame to the assertion of the PCS signal for the next frame. Note that this + * is not adjustable for continuous clock mode because this delay is fixed at + * one SCK period. + * + * Each of the above delay parameters use both a pre-scalar and scalar value to calculate the + * needed delay. This function takes in as a parameter the desired delay type and the + * delay value (in nanoseconds), calculates the values needed for the prescaler and scaler. + * Returning the actual calculated delay as an exact delay match may not be possible. In this + * case, the closest match is calculated without going below the desired delay value input. + * It is possible to input a very large delay value that exceeds the capability of the part, in + * which case the maximum supported delay is returned. In addition, the function returns + * an out-of-range status. + * + * @param instance The instance number of the DSPI peripheral. + * @param whichDelay The desired delay to configure, must be of type dspi_delay_type_t + * @param delayInNanoSec The desired delay value in nanoseconds. + * @param calculatedDelay The calculated delay that best matches the desired + * delay (in nanoseconds). + * @return Either kStatus_DSPI_Success or kStatus_DSPI_OutOfRange if the desired delay exceeds + * the capability of the device. + */ +dspi_status_t DSPI_DRV_EdmaMasterSetDelay(uint32_t instance, dspi_delay_type_t whichDelay, + uint32_t delayInNanoSec, uint32_t * calculatedDelay); + +/*@}*/ + +/*! + * @name Bus configuration + * @{ + */ + +/*! + * @brief Configures the DSPI port physical parameters to access a device on the bus with the EDMA + * support. + * + * The term "device" is used to indicate the SPI device for which the DSPI master is communicating. + * The user has two options to configure the device parameters: pass in the + * pointer to the device configuration structure to the desired transfer function (see + * DSPI_DRV_EdmaMasterTransferBlocking or DSPI_DRV_EdmaMasterTransfer) or pass it in to the + * DSPI_DRV_EdmaMasterConfigureBus function. The user can pass in a device structure to the + * transfer function which contains the parameters for the bus (the transfer function then calls + * this function). However, the user has the option to call this function directly especially + * to get the calculated baud rate, at which point they may pass in NULL for the device + * structure in the transfer function (assuming they have called this configure bus function + * first). This is an example to set up the dspi_device_t structure to call + * the DSPI_DRV_EdmaMasterConfigureBus function by passing in these parameters: + @code + dspi_edma_device_t spiDevice; + spiDevice.dataBusConfig.bitsPerFrame = 16; + spiDevice.dataBusConfig.clkPhase = kDspiClockPhase_FirstEdge; + spiDevice.dataBusConfig.clkPolarity = kDspiClockPolarity_ActiveHigh; + spiDevice.dataBusConfig.direction = kDspiMsbFirst; + spiDevice.bitsPerSec = 50000; + DSPI_DRV_EdmaMasterConfigureBus(instance, &spiDevice, &calculatedBaudRate); + @endcode + * + * @param instance The instance number of the DSPI peripheral. + * @param device Pointer to the device information structure. This structure contains the settings + * for the SPI bus configuration. The device parameters are the desired baud rate (in + * bits-per-sec), and the data format field which consists of bits-per-frame, clock polarity and + * phase, and data shift direction. + * @param calculatedBaudRate The calculated baud rate passed back to the user to determine + * if the calculated baud rate is close enough to meet the needs. The baud rate never exceeds + * the desired baud rate. + * @return An error code or kStatus_DSPI_Success. + */ +dspi_status_t DSPI_DRV_EdmaMasterConfigureBus(uint32_t instance, + const dspi_edma_device_t * device, + uint32_t * calculatedBaudRate); + +/*@}*/ + +/*! + * @name Blocking transfers + * @{ + */ + +/*! + * @brief Performs a blocking SPI master mode transfer with the EDMA support. + * + * This function simultaneously sends and receives data on the SPI bus, because the SPI is naturally + * a full-duplex bus. The function does not return until the transfer is complete. + * + * @param instance The instance number of the DSPI peripheral. + * @param device Pointer to the device information structure. This structure contains the settings + * for the SPI bus configuration in this transfer. You may pass NULL for this + * parameter, in which case the current bus configuration is used unmodified. The device can be + * configured separately by calling the DSPI_DRV_EdmaMasterConfigureBus function. + * @param sendBuffer The pointer to the data buffer of the data to send. You may pass NULL for this + * parameter and bytes with a value of 0 (zero) is sent. + * @param receiveBuffer Pointer to the buffer where the received bytes are stored. If you pass NULL + * for this parameter, the received bytes are ignored. + * @param transferByteCount The number of bytes to send and receive. + * @param timeout A timeout for the transfer in milliseconds. If the transfer takes longer than + * this amount of time, the transfer is aborted and a kStatus_SPI_Timeout error + * returned. + * + * @return kStatus_DSPI_Success The transfer was successful, or + * kStatus_DSPI_Busy Cannot perform transfer because a transfer is already in progress, or + * kStatus_DSPI_Timeout The transfer timed out and was aborted. + */ +dspi_status_t DSPI_DRV_EdmaMasterTransferBlocking(uint32_t instance, + const dspi_edma_device_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount, + uint32_t timeout); +/*@}*/ + +/*! + * @name Non-blocking transfers + * @{ + */ + +/*! + * @brief Performs a non-blocking SPI master mode transfer with the EDMA support. + * + * This function returns immediately. The user must check back + * whether the transfer is complete (using the DSPI_DRV_EdmaMasterGetTransferStatus function). + * This function simultaneously sends and receives data on the SPI bus because the SPI is + * a full-duplex bus. + * + * @param instance The instance number of the DSPI peripheral. + * @param device Pointer to the device information structure. This structure contains the settings + * for the SPI bus configuration in this transfer. You may pass NULL for this + * parameter, in which case the current bus configuration is used unmodified. The device can be + * configured separately by calling the DSPI_DRV_EdmaMasterConfigureBus function. + * @param sendBuffer The pointer to the data buffer of the data to send. You may pass NULL for this + * parameter, in which case bytes with a value of 0 (zero) are sent. + * @param receiveBuffer Pointer to the buffer where the received bytes are stored. If you pass NULL + * for this parameter, the received bytes are ignored. + * @param transferByteCount The number of bytes to send and receive. + * + * @return kStatus_DSPI_Success The transfer was successful, or + * kStatus_DSPI_Busy Cannot perform transfer because a transfer is already in progress. + */ +dspi_status_t DSPI_DRV_EdmaMasterTransfer(uint32_t instance, + const dspi_edma_device_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount); + + +/*! + * @brief Returns whether the previous transfer is completed with the EDMA support. + * + * When performing an a-sync transfer, the user can call this function to ascertain the state of the + * current transfer: in progress (or busy) or complete (success). In addition, if the transfer + * is still in progress, the user can get the number of words that have been + * transferred up to now. + * + * @param instance The instance number of the DSPI peripheral. + * @param framesTransferred Pointer to value populated with the number of frames that + * have been sent during the active transfer. A frame is defined as the number of bits per frame. + * + * @return kStatus_DSPI_Success The transfer has completed successfully, or + * kStatus_DSPI_Busy The transfer is still in progress. framesTransferred is filled + * with the number of words that have been transferred so far. + */ +dspi_status_t DSPI_DRV_EdmaMasterGetTransferStatus(uint32_t instance, uint32_t * framesTransferred); + +/*! + * @brief Terminates an asynchronous transfer early with the EDMA support. + * + * During an a-sync transfer, the user has the option to terminate the transfer early if the transfer + * is still in progress. + * + * @param instance The instance number of the DSPI peripheral. + * + * @return kStatus_DSPI_Success The transfer was successful, or + * kStatus_DSPI_NoTransferInProgress No transfer is currently in progress. + */ +dspi_status_t DSPI_DRV_EdmaMasterAbortTransfer(uint32_t instance); + +/*! + * @brief Interrupt handler for DSPI master mode. + * This handler uses the buffers stored in the dspi_master_state_t structs to transfer data. + * + * @param instance The instance number of the DSPI peripheral. + */ +void DSPI_DRV_EdmaMasterIRQHandler(uint32_t instance); + +/* @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +#endif /* __FSL_DSPI_EDMA_MASTER_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_edma_shared_function.h b/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_edma_shared_function.h new file mode 100755 index 0000000..94ef939 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_edma_shared_function.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_DSPI_EDMA_SHARED_FUNCTION_H__) +#define __FSL_DSPI_EDMA_SHARED_FUNCTION_H__ + +#include <stdbool.h> +#include "fsl_device_registers.h" +#include "fsl_dspi_hal.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/*! + * @addtogroup dspi_shared_irq + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Table of base pointers for SPI instances. */ +extern SPI_Type * const g_dspiBase[SPI_INSTANCE_COUNT]; + +/*! @brief Table to save DSPI IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_dspiIrqId[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief The function DSPI_DRV_EdmaIRQHandler passes IRQ control to either the master or + * slave driver. + * + * The address of the IRQ handlers are checked to make sure they are non-zero before + * they are called. If the IRQ handler's address is zero, it means that driver was + * not present in the link (because the IRQ handlers are marked as weak). This would + * actually be a program error, because it means the master/slave config for the IRQ + * was set incorrectly. + * @param instance The instance number of the DSPI peripheral. + */ +void DSPI_DRV_EdmaIRQHandler(uint32_t instance); + +/*! @} */ + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +#endif /* __FSL_DSPI_EDMA_SHARED_FUNCTION_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_edma_slave_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_edma_slave_driver.h new file mode 100755 index 0000000..c4db996 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_edma_slave_driver.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_DSPI_EDMA_SLAVE_DRIVER_H__) +#define __FSL_DSPI_EDMA_SLAVE_DRIVER_H__ + +#include "fsl_dspi_hal.h" +#include "fsl_edma_driver.h" +#include "fsl_os_abstraction.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/*! + * @addtogroup dspi_slave_driver + * @{ + */ + +/*! @brief Table of base pointers for SPI instances. */ +extern SPI_Type * const g_dspiBase[SPI_INSTANCE_COUNT]; + +/*! @brief Table to save DSPI IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_dspiIrqId[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define DSPI_EDMA_DEFAULT_DUMMY_PATTERN (0u) /*!< Dummy pattern, that DSPI slave will send + when transmit data was not configured */ + +/*! + * @brief User configuration structure for the DSPI slave driver. + */ +typedef struct DSPIEdmaSlaveUserConfig { + dspi_data_format_config_t dataConfig; /*!< Data format configuration structure */ + uint16_t dummyPattern; /*!< Dummy data value */ +} dspi_edma_slave_user_config_t; + +/*! + * @brief Runtime state structure of the DSPI slave driver. + * + * This structure holds data that is used by the DSPI slave peripheral driver to + * communicate between the transfer function and the interrupt handler. The user + * needs to pass in the memory for this structure and the driver fills out + * the members. + */ +typedef struct DSPIEdmaSlaveState { + uint32_t bitsPerFrame; /*!< Desired number of bits per frame */ + dspi_status_t status; /*!< Current state of slave */ + event_t event; /*!< Event to notify waiting task */ + uint16_t errorCount; /*!< Driver error count */ + uint32_t dummyPattern; /*!< Dummy data will be send when do not have data + in transmit buffer */ + volatile bool isTransferInProgress; /*!< True if there is an active transfer.*/ + const uint8_t * sendBuffer; /*!< Pointer to transmit buffer */ + uint8_t * receiveBuffer; /*!< Pointer to receive buffer */ + volatile int32_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ + volatile int32_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ + uint8_t extraReceiveByte; /*!< Number of extra receive bytes */ + bool isSync; /*!< Indicates the function call is sync or async */ + edma_chn_state_t edmaTxChannel; /*!< Structure definition for the eDMA channel */ + edma_chn_state_t edmaRxChannel; /*!< Structure definition for the eDMA channel */ +} dspi_edma_slave_state_t; + +/******************************************************************************* + * API + ******************************************************************************/ + + +#if defined(__cplusplus) +extern "C" { +#endif +/*! + * @name Initialization and shutdown + * @{ + */ + +/*! + * @brief Initializes a DSPI instance for a slave mode operation, using eDMA mechanism. + * + * This function un-gates the clock to the DSPI module, initializes the DSPI for slave + * mode and initializes eDMA channels. After it is initialized, the DSPI module is configured + * in slave mode and user can start transmit, receive data by calls send, receive, + * transfer functions. This function indicates DSPI slave uses the eDMA mechanism. + * + * @param instance The instance number of the DSPI peripheral. + * @param dspiState The pointer to the DSPI slave driver state structure. + * @param slaveConfig The configuration structure dspi_edma_slave_user_config_t which + * configures the data bus format. + * + * @return An error code or kStatus_DSPI_Success. + */ +dspi_status_t DSPI_DRV_EdmaSlaveInit(uint32_t instance, + dspi_edma_slave_state_t * dspiState, + const dspi_edma_slave_user_config_t * slaveConfig); + +/*! + * @brief Shuts down a DSPI instance - eDMA mechanism. + * + * Disables the DSPI module, gates its clock, changes the DSPI slave driver state to NonInit + * for DSPI slave module which is initialized with the eDMA mechanism. After de-initialization, + * the user can re-initialize the DSPI slave module with other mechanisms. + * + * @param instance The instance number of the DSPI peripheral. + * @return kStatus_DSPI_Success indicating successful de-initialization or error code + */ +dspi_status_t DSPI_DRV_EdmaSlaveDeinit(uint32_t instance); +/*! @} */ + +/*! + * @name Blocking transfers + * @{ + */ + +/*! + * @brief Transfers data on the SPI bus using the eDMA and blocking call. + * + * This function checks driver status, mechanism and transmits/receives data through SPI bus. + * If sendBuffer is NULL, transmit process is ignored, and if the receiveBuffer is NULL, the receive + * process is ignored. If both the receiveBuffer and the sendBuffer are available, the transmit and + * receive progress is processed. If only the receiveBuffer is available, the receive is processed, + * Otherwise, the transmit is processed. This function only returns when its processes + * are complete. This function uses the eDMA mechanism. + * + * @param instance The instance number of DSPI peripheral + * @param sendBuffer The pointer to data that user wants to transmit. + * @param receiveBuffer The pointer to data that user wants to store received data. + * @param transferByteCount The number of bytes to send and receive. + * @param timeOut The maximum number of milliseconds that function will wait before + * timed out reached. + * + * @return kStatus_DSPI_Success if driver starts to send/receive data successfully. + * kStatus_DSPI_Error if driver is error and needs to clean error. + * kStatus_DSPI_Busy if driver is receiving/transmitting data and not available. + * kStatus_DSPI_Timeout if time out reached while transferring is in progress. + */ +dspi_status_t DSPI_DRV_EdmaSlaveTransferBlocking(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount, + uint32_t timeOut); + +/*@}*/ + +/*! + * @name Non-blocking transfers + * @{ + */ + +/*! + * @brief Starts transfer data on SPI bus using eDMA + * + * This function checks the driver status then sets buffer pointers to receive and transmit + * SPI data. If the sendBuffer is NULL, transmit process is ignored. If the receiveBuffer is + * NULL, the receive process is ignored. If both the receiveBuffer and sendBuffer are available, the + * transfer is done when the kDspiTxDone and the kDspiRxDone are set. If only the receiveBuffer is + * available, the transfer is done when the kDspiRxDone flag is set. Otherwise, the transfer is + * done when the kDspiTxDone is set. This function uses the eDMA mechanism. + * + * @param instance The instance number of DSPI peripheral. + * @param sendBuffer The pointer to data that user wants to transmit. + * @param receiveBuffer The pointer to data that user wants to store received data. + * @param transferByteCount The number of bytes to send and receive. + * + * @return kStatus_DSPI_Success if driver starts to send/receive data successfully. + * kStatus_DSPI_Error if driver is error and needs to clean error. + * kStatus_DSPI_Busy if driver is receiving/transmitting data and not available. + */ +dspi_status_t DSPI_DRV_EdmaSlaveTransfer(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount); + +/*! + * @brief Aborts the transfer that started by a non-blocking call to the eDMA transfer function. + * + * This function stops the transfer which was started by the DSPI_DRV_EdmaSlaveTransfer() function. + * + * @param instance The instance number of DSPI peripheral + * + * @return kStatus_DSPI_Success if everything is ok. + * kStatus_DSPI_InvalidMechanism if the current transaction does not use + * eDMA mechanism. + */ +dspi_status_t DSPI_DRV_EdmaSlaveAbortTransfer(uint32_t instance); + +/*! + * @brief Returns whether the previous transfer is finished. + * + * When performing an a-sync transfer, the user can call this function to ascertain + * the state of the current transfer: in progress (or busy) or complete (success). + * In addition, if the transfer is still in progress, the user can get the number + * of words that have been transferred up to now. + * + * @param instance The instance number of the DSPI peripheral. + * @param framesTransferred Pointer to value that is filled in with the number of + * frames that have been sent in the active transfer. A frame is defined as the + * number of bits per frame. + * + * @return kStatus_DSPI_Success The transfer has completed successfully, or + * kStatus_DSPI_Busy The transfer is still in progress. framesTransferred + * is filled with the number of words that have been transferred so far. + */ +dspi_status_t DSPI_DRV_EdmaSlaveGetTransferStatus(uint32_t instance, + uint32_t * framesTransferred); + +/*! + * @brief DSPI slave interrupt handler + * @details This function is DSPI slave interrupt handler using eDMA mechanism. The + * pupose of this interrupt handler is indicates when the transfer is really + * finished. The eDMA only used to copy data from/to RX FIFO/TX FIFO, but it + * not sure the data was transmitted to the master. So must have to enable + * this interrupt to do it. This interrupt only be enabled when the last + * four FIFO will be transmitted. + * + * @param instance The SPI number + */ +void DSPI_DRV_EdmaSlaveIRQHandler(uint32_t instance); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +#endif /* __FSL_DSPI_EDMA_SLAVE_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_master_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_master_driver.h new file mode 100755 index 0000000..74393a2 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_master_driver.h @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_DSPI_MASTER_DRIVER_H__) +#define __FSL_DSPI_MASTER_DRIVER_H__ + +#include "fsl_dspi_hal.h" +#include "fsl_os_abstraction.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/*! + * @addtogroup dspi_master_driver + * @{ + */ + +/*! @brief Table of base pointers for SPI instances. */ +extern SPI_Type * const g_dspiBase[SPI_INSTANCE_COUNT]; + +/*! @brief Table to save DSPI IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_dspiIrqId[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Data structure containing information about a device on the SPI bus. + * + * The user must populate these members to set up the DSPI master and + * properly communicate with the SPI device. + */ +typedef struct DspiDevice { + uint32_t bitsPerSec; /*!< @brief Baud rate in bits per second.*/ + dspi_data_format_config_t dataBusConfig; /* data format configuration structure*/ +} dspi_device_t; + +/*! + * @brief Runtime state structure for the DSPI master driver. + * + * This structure holds data that is used by the DSPI master peripheral driver to + * communicate between the transfer function and the interrupt handler. The + * interrupt handler also uses this information to keep track of its progress. + * The user must pass the memory for this run-time state structure. The + * DSPI master driver populates the members. + */ +typedef struct DspiMasterState { + dspi_ctar_selection_t whichCtar; /*!< Desired Clock and Transfer Attributes Register (CTAR)*/ + uint32_t bitsPerFrame; /*!< Desired number of bits per frame */ + dspi_which_pcs_config_t whichPcs; /*!< Desired Peripheral Chip Select (pcs) */ + bool isChipSelectContinuous; /*!< Option to enable the continuous assertion of chip select + between transfers*/ + uint32_t dspiSourceClock; /*!< Module source clock*/ + volatile bool isTransferInProgress; /*!< True if there is an active transfer.*/ + const uint8_t * sendBuffer; /*!< The buffer from which transmitted bytes are taken.*/ + uint8_t * receiveBuffer; /*!< The buffer into which received bytes are placed.*/ + volatile size_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ + volatile size_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ + volatile bool isTransferBlocking; /*!< True if transfer is a blocking transaction. */ + semaphore_t irqSync; /*!< Used to wait for ISR to complete its business.*/ + bool extraByte; /*!< Flag used for 16-bit transfers with odd byte count */ +} dspi_master_state_t; + +/*! + * @brief The user configuration structure for the DSPI master driver. + * + * Use an instance of this structure with the DSPI_DRV_MasterInit() function. This allows the user to configure + * the most common settings of the DSPI peripheral with a single function call. + * @internal gui name="Master configuration" id="dspiMasterCfg" + */ +typedef struct DspiMasterUserConfig { + dspi_ctar_selection_t whichCtar; /*!< Desired Clock and Transfer Attributes Register(CTAR) @internal gui name="CTAR selection" id="MasterCtar" */ + bool isSckContinuous; /*!< Disable or Enable continuous SCK operation @internal gui name="Continuous SCK" id="MasterContSck" */ + bool isChipSelectContinuous; /*!< Option to enable the continuous assertion of chip select + between transfers @internal gui name="Continuous chip select" id="MasterContCs" */ + dspi_which_pcs_config_t whichPcs; /*!< Desired Peripheral Chip Select (pcs) @internal gui name="Chip select" id="MasterCs" */ + dspi_pcs_polarity_config_t pcsPolarity; /*!< Peripheral Chip Select (pcs) polarity setting. @internal gui name="Chip select polarity" id="MasterPolarity" */ +} dspi_master_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and shutdown + * @{ + */ + +/*! + * @brief Initializes a DSPI instance for master mode operation. + * + * This function uses a CPU interrupt driven method for transferring data. + * This function initializes the run-time state structure to track the ongoing + * transfers, un-gates the clock to the DSPI module, resets the DSPI module, initializes the module + * to user defined settings and default settings, configures the IRQ state structure, enables + * the module-level interrupt to the core, and enables the DSPI module. + * The CTAR parameter is special in that it allows the user to have different SPI devices + * connected to the same DSPI module instance in addition to different peripheral device + * selects. Each CTAR contains the bus attributes associated with that particular SPI device. + * For most use cases where only one SPI device is connected per DSPI module + * instance, use CTAR0. + * This is an example to set up the dspi_master_state_t and the + * dspi_master_user_config_t parameters and to call the DSPI_DRV_MasterInit function by passing + * in these parameters: + @code + dspi_master_state_t dspiMasterState; <- the user allocates memory for this structure + uint32_t calculatedBaudRate; + dspi_master_user_config_t userConfig; <- the user populates members for this structure + userConfig.isChipSelectContinuous = false; + userConfig.isSckContinuous = false; + userConfig.pcsPolarity = kDspiPcs_ActiveLow; + userConfig.whichCtar = kDspiCtar0; + userConfig.whichPcs = kDspiPcs0; + DSPI_DRV_MasterInit(masterInstance, &dspiMasterState, &userConfig); + @endcode + * + * @param instance The instance number of the DSPI peripheral. + * @param dspiState The pointer to the DSPI master driver state structure. The user + * passes the memory for this run-time state structure. The DSPI master driver + * populates the members. This run-time state structure keeps track of the + * transfer in progress. + * @param userConfig The dspi_master_user_config_t user configuration structure. The user + * populates the members of this structure and passes the pointer of this structure + * to the function. + * + * @return An error code or kStatus_DSPI_Success. + */ +dspi_status_t DSPI_DRV_MasterInit(uint32_t instance, + dspi_master_state_t * dspiState, + const dspi_master_user_config_t * userConfig); + +/*! + * @brief Shuts down a DSPI instance. + * + * This function resets the DSPI peripheral, gates its clock, and disables the interrupt to + * the core. + * + * @param instance The instance number of the DSPI peripheral. + * @return kStatus_DSPI_Success indicating successful de-initialization + */ +dspi_status_t DSPI_DRV_MasterDeinit(uint32_t instance); + + +/*! + * @brief Configures the DSPI master mode bus timing delay options. + * + * This function involves the DSPI module's delay options to + * "fine tune" some of the signal timings and match the timing needs of a slower peripheral device. + * This is an optional function that can be called after the DSPI module has been initialized for + * master mode. + * The bus timing delays that can be adjusted are listed below: + * + * PCS to SCK Delay: Adjustable delay option between the assertion of the PCS signal to the + * first SCK edge. + * + * After SCK Delay: Adjustable delay option between the last edge of SCK to the de-assertion + * of the PCS signal. + * + * Delay after Transfer: Adjustable delay option between the de-assertion of the PCS signal for a + * frame to the assertion of the PCS signal for the next frame. Note that this + * is not adjustable for continuous clock mode because this delay is fixed at + * one SCK period. + * + * Each of the above delay parameters use both a pre-scalar and scalar value to calculate the + * needed delay. This function takes in as a parameter the desired delay type and the + * delay value (in nanoseconds), calculates the values needed for the prescaler and scaler. + * Returning the actual calculated delay as an exact delay match may not be possible. In this + * case, the closest match is calculated without going below the desired delay value input. + * It is possible to input a very large delay value that exceeds the capability of the part, in + * which case the maximum supported delay is returned. In addition, the function returns + * an out-of-range status. + * + * @param instance The instance number of the DSPI peripheral. + * @param whichDelay The desired delay to configure, must be of type dspi_delay_type_t + * @param delayInNanoSec The desired delay value in nanoseconds. + * @param calculatedDelay The calculated delay that best matches the desired + * delay (in nanoseconds). + * @return Either kStatus_DSPI_Success or kStatus_DSPI_OutOfRange if the desired delay exceeds + * the capability of the device. + */ +dspi_status_t DSPI_DRV_MasterSetDelay(uint32_t instance, dspi_delay_type_t whichDelay, + uint32_t delayInNanoSec, uint32_t * calculatedDelay); + +/*@}*/ + +/*! + * @name Bus configuration + * @{ + */ + +/*! + * @brief Configures the DSPI port physical parameters to access a device on the bus. + * + * The term "device" is used to indicate the SPI device for which the DSPI master is communicating. + * The user has two options to configure the device parameters: either pass in the + * pointer to the device configuration structure to the desired transfer function (see + * DSPI_DRV_MasterTransferBlocking or DSPI_DRV_MasterTransfer) or pass it in to the + * DSPI_DRV_MasterConfigureBus function. The user can pass in a device structure to the transfer + * function which contains the parameters for the bus (the transfer function then calls + * this function). However, the user has the option to call this function directly especially + * to get the calculated baud rate, at which point they may pass in NULL for the device + * structure in the transfer function (assuming they have called this configure bus function + * first). This is an example to set up the dspi_device_t structure to call + * the DSPI_DRV_MasterConfigureBus function by passing in these parameters: + @code + dspi_device_t spiDevice; + spiDevice.dataBusConfig.bitsPerFrame = 16; + spiDevice.dataBusConfig.clkPhase = kDspiClockPhase_FirstEdge; + spiDevice.dataBusConfig.clkPolarity = kDspiClockPolarity_ActiveHigh; + spiDevice.dataBusConfig.direction = kDspiMsbFirst; + spiDevice.bitsPerSec = 50000; + DSPI_DRV_MasterConfigureBus(instance, &spiDevice, &calculatedBaudRate); + @endcode + * + * @param instance The instance number of the DSPI peripheral. + * @param device Pointer to the device information structure. This structure contains the settings + * for the SPI bus configuration. The device parameters are the desired baud rate (in + * bits-per-sec), and the data format field which consists of bits-per-frame, clock polarity and + * phase, and data shift direction. + * @param calculatedBaudRate The calculated baud rate passed back to the user to determine + * if the calculated baud rate is close enough to meet the needs. The baud rate never exceeds + * the desired baud rate. + * @return An error code or kStatus_DSPI_Success. + */ +dspi_status_t DSPI_DRV_MasterConfigureBus(uint32_t instance, + const dspi_device_t * device, + uint32_t * calculatedBaudRate); + +/*@}*/ + +/*! + * @name Blocking transfers + * @{ + */ + +/*! + * @brief Performs a blocking SPI master mode transfer. + * + * This function simultaneously sends and receives data on the SPI bus, as SPI is naturally + * a full-duplex bus. The function does not return until the transfer is complete. + * + * @param instance The instance number of the DSPI peripheral. + * @param device Pointer to the device information structure. This structure contains the settings + * for the SPI bus configuration in this transfer. You may pass NULL for this + * parameter, in which case the current bus configuration is used unmodified. The device can be + * configured separately by calling the DSPI_DRV_MasterConfigureBus function. + * @param sendBuffer The pointer to the data buffer of the data to send. You may pass NULL for this + * parameter and bytes with a value of 0 (zero) is sent. + * @param receiveBuffer Pointer to the buffer where the received bytes are stored. If you pass NULL + * for this parameter, the received bytes are ignored. + * @param transferByteCount The number of bytes to send and receive. + * @param timeout A timeout for the transfer in milliseconds. If the transfer takes longer than + * this amount of time, the transfer is aborted and a #kStatus_SPI_Timeout error + * returned. + * + * @return kStatus_DSPI_Success The transfer was successful, or + * kStatus_DSPI_Busy Cannot perform transfer because a transfer is already in progress, or + * kStatus_DSPI_Timeout The transfer timed out and was aborted. + */ +dspi_status_t DSPI_DRV_MasterTransferBlocking(uint32_t instance, + const dspi_device_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount, + uint32_t timeout); +/*@}*/ + +/*! + * @name Non-blocking transfers + * @{ + */ + +/*! + * @brief Performs a non-blocking SPI master mode transfer. + * + * This function returns immediately. The user needs to + * check whether the transfer is complete using the DSPI_DRV_MasterGetTransferStatus function. This + * function simultaneously sends and receives data on the SPI bus because the SPI is naturally + * a full-duplex bus. + * + * @param instance The instance number of the DSPI peripheral. + * @param device Pointer to the device information structure. This structure contains the settings + * for the SPI bus configuration in this transfer. You may pass NULL for this + * parameter, in which case the current bus configuration is used unmodified. The device can be + * configured separately by calling the DSPI_DRV_MasterConfigureBus function. + * @param sendBuffer The pointer to the data buffer of the data to send. You may pass NULL for this + * parameter, in which case bytes with a value of 0 (zero) are sent. + * @param receiveBuffer Pointer to the buffer where the received bytes are stored. If you pass NULL + * for this parameter, the received bytes are ignored. + * @param transferByteCount The number of bytes to send and receive. + * + * @return kStatus_DSPI_Success The transfer was successful, or + * kStatus_DSPI_Busy Cannot perform transfer because a transfer is already in progress. + */ +dspi_status_t DSPI_DRV_MasterTransfer(uint32_t instance, + const dspi_device_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount); + + +/*! + * @brief Returns whether the previous transfer is completed. + * + * When performing an a-sync transfer, the user can call this function to ascertain the state of the + * current transfer: in progress (or busy) or complete (success). In addition, if the transfer + * is still in progress, the user can get the number of words that have been + * transferred up to now. + * + * @param instance The instance number of the DSPI peripheral. + * @param framesTransferred Pointer to value that is filled in with the number of frames that + * have been sent in the active transfer. A frame is defined as the number of bits per frame. + * + * @return kStatus_DSPI_Success The transfer has completed successfully, or + * kStatus_DSPI_Busy The transfer is still in progress. framesTransferred is filled + * with the number of words that have been transferred so far. + */ +dspi_status_t DSPI_DRV_MasterGetTransferStatus(uint32_t instance, uint32_t * framesTransferred); + +/*! + * @brief Terminates an asynchronous transfer early. + * + * During an a-sync transfer, the user has the option to terminate the transfer early if the transfer + * is still in progress. + * + * @param instance The instance number of the DSPI peripheral. + * + * @return kStatus_DSPI_Success The transfer was successful, or + * kStatus_DSPI_NoTransferInProgress No transfer is currently in progress. + */ +dspi_status_t DSPI_DRV_MasterAbortTransfer(uint32_t instance); + +/*! + * @brief Interrupt handler for DSPI master mode. + * This handler uses the buffers stored in the dspi_master_state_t structs to transfer data. + * + * @param instance The instance number of the DSPI peripheral. + */ +void DSPI_DRV_MasterIRQHandler(uint32_t instance); + +/* @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +#endif /* __FSL_DSPI_MASTER_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_shared_function.h b/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_shared_function.h new file mode 100755 index 0000000..57c36ec --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_shared_function.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_DSPI_SHARED_FUNCTION_H__) +#define __FSL_DSPI_SHARED_FUNCTION_H__ + +#include <stdbool.h> +#include "fsl_device_registers.h" +#include "fsl_dspi_hal.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/*! + * @addtogroup dspi_shared_irq + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Table of base pointers for SPI instances. */ +extern SPI_Type * const g_dspiBase[SPI_INSTANCE_COUNT]; + +/*! @brief Table to save DSPI IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_dspiIrqId[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief The function DSPI_DRV_IRQHandler passes IRQ control to either the master or + * slave driver. + * + * The address of the IRQ handlers are checked to make sure they are non-zero before + * they are called. If the IRQ handler's address is zero, it means that driver was + * not present in the link (because the IRQ handlers are marked as weak). This would + * actually be a program error, because it means the master/slave configuration for the IRQ + * was set incorrectly. + * @param instance The instance number of the DSPI peripheral. + */ +void DSPI_DRV_IRQHandler(uint32_t instance); + +/*! @} */ + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +#endif /* __FSL_DSPI_SHARED_FUNCTION_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_slave_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_slave_driver.h new file mode 100755 index 0000000..5cc986c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_dspi_slave_driver.h @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_DSPI_SLAVE_DRIVER_H__) +#define __FSL_DSPI_SLAVE_DRIVER_H__ + +#include "fsl_dspi_hal.h" +#include "fsl_os_abstraction.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/*! + * @addtogroup dspi_slave_driver + * @{ + */ + +/*! @brief Table of base pointers for SPI instances. */ +extern SPI_Type * const g_dspiBase[SPI_INSTANCE_COUNT]; + +/*! @brief Table to save DSPI IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_dspiIrqId[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define DSPI_DEFAULT_DUMMY_PATTERN (0x0U) /*!< Dummy pattern, that DSPI slave will send + when transmit data was not configured */ + +/*! + * @brief User configuration structure for the DSPI slave driver. + */ +typedef struct DSPISlaveUserConfig { + dspi_data_format_config_t dataConfig; /*!< Data format configuration structure */ + uint16_t dummyPattern; /*!< Dummy data value */ +} dspi_slave_user_config_t; + +/*! + * @brief Runtime state of the DSPI slave driver. + * + * This structure holds data that is used by the DSPI slave peripheral driver to + * communicate between the transfer function and the interrupt handler. The user + * needs to pass in the memory for this structure and the driver fills out + * the members. + */ +typedef struct DSPISlaveState { + uint32_t bitsPerFrame; /*!< Desired number of bits per frame */ + dspi_status_t status; /*!< Current state of slave */ + event_t event; /*!< Event to notify waiting task */ + uint16_t errorCount; /*!< Driver error count */ + uint32_t dummyPattern; /*!< Dummy data will be send when do not have data + in transmit buffer */ + volatile bool isTransferInProgress; /*!< True if there is an active transfer.*/ + const uint8_t * sendBuffer; /*!< Pointer to transmit buffer */ + uint8_t * receiveBuffer; /*!< Pointer to receive buffer */ + volatile int32_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ + volatile int32_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ + bool isSync; /*!< Indicates the function call is sync or async */ +} dspi_slave_state_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and shutdown + * @{ + */ + +/*! + * @brief Initializes a DSPI instance for a slave mode operation, using interrupt mechanism. + * + * This function un-gates the clock to the DSPI module, initializes the DSPI for + * slave mode. Once initialized, the DSPI module is configured in slave mode and + * user can start transmit, receive data by calls send, receive, transfer functions. + * This function indicates DSPI slave will use interrupt mechanism. + * + * @param instance The instance number of the DSPI peripheral. + * @param dspiState The pointer to the DSPI slave driver state structure. + * @param slaveConfig The configuration structure dspi_slave_user_config_t which + * configures the data bus format. + * + * @return An error code or kStatus_DSPI_Success. + */ + +dspi_status_t DSPI_DRV_SlaveInit(uint32_t instance, + dspi_slave_state_t * dspiState, + const dspi_slave_user_config_t * slaveConfig); + +/*! + * @brief Shuts down a DSPI instance - interrupt mechanism. + * + * Disables the DSPI module, gates its clock, change DSPI slave driver state to NonInit for + * DSPI slave module which is initialized with interrupt mechanism. After de-initialized, + * user can re-initialize DSPI slave module with other mechanisms. + * + * @param instance The instance number of the DSPI peripheral. + * @return kStatus_DSPI_Success indicating successful de-initialization or error code + */ +dspi_status_t DSPI_DRV_SlaveDeinit(uint32_t instance); + +/*! @} */ + +/*! + * @name Blocking transfers + * @{ + */ + +/*! + * @brief Transfers data on SPI bus using interrupt and blocking call + * + * This function check driver status, mechanism and transmit/receive data through SPI + * bus. If sendBuffer is NULL, the transmit process is ignored, and if receiveBuffer is NULL the + * receive process is ignored. If both receiveBuffer and sendBuffer are available, both the transmit + * and the receive progress are processed. If only the receiveBuffer is available, the receive is + * processed. Otherwise, the transmit is processed. This function only returns when its + * processes are complete. This function uses an interrupt mechanism. + * + * @param instance The instance number of DSPI peripheral + * @param sendBuffer The pointer to data that user wants to transmit. + * @param receiveBuffer The pointer to data that user wants to store received data. + * @param transferByteCount The number of bytes to send and receive. + * @param timeout The maximum number of milliseconds that function will wait before + * timed out reached. + * + * @return kStatus_DSPI_Success if driver starts to send/receive data successfully. + * kStatus_DSPI_Error if driver is error and needs to clean error. + * kStatus_DSPI_Busy if driver is receiving/transmitting data and not available. + * kStatus_DSPI_Timeout if time out reached while transferring is in progress. + */ +dspi_status_t DSPI_DRV_SlaveTransferBlocking(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount, + uint32_t timeout); + +/*@}*/ + +/*! + * @name Non-blocking transfers + * @{ + */ + +/*! + * @brief Starts transfer data on SPI bus using interrupt and a non-blocking call. + * + * This function checks the driver status and sets buffer pointers to receive and transmit + * the SPI data. If the sendBuffer is NULL, the transmit process is ignored. If the receiveBuffer + * is NULL, the receive process is ignored. If both the receiveBuffer and the sendBuffer are , + * available the transfer is done when the kDspiTxDone and the kDspiRxDone are set. If only the + * receiveBuffer is available, the transfer is done when the kDspiRxDone flag is set. Otherwise, + * the transfer is done when the kDspiTxDone is set. This function uses an interrupt mechanism. + * + * @param instance The instance number of DSPI peripheral + * @param sendBuffer The pointer to data that user wants to transmit. + * @param receiveBuffer The pointer to data that user wants to store received data. + * @param transferByteCount The number of bytes to send and receive. + * + * @return kStatus_DSPI_Success if driver starts to send/receive data successfully. + * kStatus_DSPI_Error if driver is error and needs to clean error. + * kStatus_DSPI_Busy if driver is receiving/transmitting data and not + * available. + */ +dspi_status_t DSPI_DRV_SlaveTransfer(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount); + +/*! + * @brief Aborts the transfer that started by a non-blocking call to a transfer function. + * + * This function stops the transfer which started by calling the DSPI_DRV_SlaveTransfer() function. + * + * @param instance The instance number of DSPI peripheral + * + * @return kStatus_DSPI_Success if everything is OK. + * kStatus_DSPI_InvalidMechanism if the current transaction does not use + * interrupt mechanism. + */ +dspi_status_t DSPI_DRV_SlaveAbortTransfer(uint32_t instance); + +/*! + * @brief Returns whether the previous transfer is finished. + * + * When performing an a-sync transfer, the user can call this function to ascertain + * the state of the current transfer: in progress (or busy) or complete (success). + * In addition, if the transfer is still in progress, the user can get the number + * of words that have been transferred up to now. + * + * @param instance The instance number of the DSPI peripheral. + * @param framesTransferred Pointer to value that is filled in with the number of + * frames that have been sent in the active transfer. A frame is defined as the + * number of bits per frame. + * + * @return kStatus_DSPI_Success The transfer has completed successfully, or + * kStatus_DSPI_Busy The transfer is still in progress. framesTransferred + * is filled with the number of words that have been transferred so far. + */ +dspi_status_t DSPI_DRV_SlaveGetTransferStatus(uint32_t instance, + uint32_t * framesTransferred); + +/*! + * @brief DSPI Slave Generic IRQ handler. + * + * This handler check errors of driver and it puts data into Tx FIFO, gets data + * from Rx FIFO whenever data transmitting/received. + * + * @param instance The instance number of the DSPI peripheral. + */ +void DSPI_DRV_SlaveIRQHandler(uint32_t instance); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +#endif /* __FSL_DSPI_SLAVE_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_edma_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_edma_driver.h new file mode 100755 index 0000000..950caff --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_edma_driver.h @@ -0,0 +1,643 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_EDMA_DRIVER_H__) +#define __FSL_EDMA_DRIVER_H__ + +#include <stdint.h> +#include "fsl_device_registers.h" +#include "fsl_edma_request.h" +#include "fsl_edma_hal.h" +#include "fsl_dmamux_hal.h" +#include "fsl_os_abstraction.h" +#if FSL_FEATURE_SOC_EDMA_COUNT + +/*! + * @addtogroup edma_driver + * @{ + */ + +/*! @brief Array for the eDMA module register base address. */ +extern DMA_Type * const g_edmaBase[]; + +/*! @brief Array for DMAMUX module register base address. */ +extern DMAMUX_Type * const g_dmamuxBase[]; + +/*! @brief Two dimensional array for eDMA channel interrupt vector number. */ +extern const IRQn_Type g_edmaIrqId[DMA_INSTANCE_COUNT][FSL_FEATURE_EDMA_MODULE_CHANNEL]; + +#if !defined FSL_FEATURE_EDMA_HAS_ERROR_IRQ +/*! @brief Array for eDMA module's error interrupt vector number. */ +extern const IRQn_Type g_edmaErrIrqId[DMA_INSTANCE_COUNT]; +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @brief Macro for the memory size needed for the software TCD. + * + * Software TCD is aligned to 32 bytes. To make sure the software TCD can meet the + * eDMA module requirement, allocate memory with extra 32 bytes. + */ +#define STCD_SIZE(number) ((number + 1) * 32) +#define STCD_ADDR(address) (edma_software_tcd_t *)(((uint32_t)address + 32) & ~0x1FU) + +/*! + * @brief The user configuration structure for the eDMA driver. + * + * Use an instance of this structure with the EDMA_DRV_Init() function. This allows the user to configure + * settings of the EDMA peripheral with a single function call. + * @internal gui name="Configuration" id="edmaCfg" + */ +typedef struct EDMAUserConfig { + edma_channel_arbitration_t chnArbitration; /*!< eDMA channel arbitration. @internal gui name="Channel arbitration" id="ChnArbitration" */ +#if FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 0x1U + edma_group_arbitration_t groupArbitration; /*!< eDMA group arbitration. @internal gui name="Group arbitration" id="GroupArbitration" */ + edma_group_priority_t groupPriority; /*!< eDMA group priority. It is used while eDMA + group arbitration is set to fixed priority. @internal gui name="Group priority" id="GroupPriority" */ +#endif + bool notHaltOnError; + /*!< Any error causes the HALT bit to set. Subsequently, all service requests are ignored until the HALT bit is cleared. + @internal gui name="Set HALT on Error" id="HaltOnError" */ +} edma_user_config_t; + +/*! + * @brief Channel status for eDMA channel. + * + * A structure describing the eDMA channel status. The user can get the status by callback parameter + * or by calling EDMA_DRV_getStatus() function. + */ +typedef enum _edma_chn_status { + kEDMAChnNormal = 0U, /*!< eDMA channel is occupied. */ + kEDMAChnIdle, /*!< eDMA channel is idle. */ + kEDMAChnError /*!< An error occurs in the eDMA channel. */ +} edma_chn_status_t; + + +/*! + * @brief Definition for the eDMA channel callback function. + * + * Prototype for the callback function registered in the eDMA driver. + */ +typedef void (*edma_callback_t)(void *parameter, edma_chn_status_t status); + +/*! @brief Macro to get the eDMA physical module indicator from the virtual channel indicator. */ +#define VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(chn) g_edmaBase[chn/FSL_FEATURE_EDMA_MODULE_CHANNEL] + +/*! @brief Macro to get the eDMA physical channel indicator from the virtual channel indicator. */ +#define VIRTUAL_CHN_TO_EDMA_CHN(chn) (chn%FSL_FEATURE_EDMA_MODULE_CHANNEL) + +/*! @brief Macro to get the DMAMUX physical module indicator from the virtual channel indicator. */ +#define VIRTUAL_CHN_TO_DMAMUX_MODULE_REGBASE(chn) g_dmamuxBase[chn/FSL_FEATURE_DMAMUX_MODULE_CHANNEL] + +/*! @brief Macro to get the DMAMUX physical channel indicator from the virtual channel indicator. */ +#define VIRTUAL_CHN_TO_DMAMUX_CHN(chn) (chn%FSL_FEATURE_DMAMUX_MODULE_CHANNEL) + +/*! @brief Data structure for the eDMA channel. */ +typedef struct EDMAChnState { + uint8_t channel; /*!< Virtual channel indicator. */ + edma_callback_t callback; /*!< Callback function pointer for the eDMA channel. It will + be called at the eDMA channel complete and eDMA channel + error. */ + void *parameter; /*!< Parameter for the callback function pointer. */ + volatile edma_chn_status_t status; /*!< eDMA channel status. */ +} edma_chn_state_t; + +/*! @brief enum type for channel allocation. */ +typedef enum _edma_chn_state_type { + kEDMAInvalidChannel = 0xFFU, /*!< Macros indicate the failure of the channel request. */ + kEDMAAnyChannel = 0xFEU /*!< Macros used when requesting channel dynamically. */ +} edma_chn_state_type_t; + +/*! @brief A type for the DMA transfer. */ +typedef enum _edma_transfer_type { + kEDMAPeripheralToMemory, /*!< Transfer from peripheral to memory */ + kEDMAMemoryToPeripheral, /*!< Transfer from memory to peripheral */ + kEDMAMemoryToMemory, /*!< Transfer from memory to memory */ +} edma_transfer_type_t; + +/*! @brief Data structure for configuring a discrete memory transfer. */ +typedef struct EDMAScatterGatherList { + uint32_t address; /*!< Address of buffer. */ + uint32_t length; /*!< Length of buffer. */ +} edma_scatter_gather_list_t; + +/*! + * @brief Runtime state structure for the eDMA driver. + * + * This structure holds data that is used by the eDMA peripheral driver to manage + * multi eDMA channels. + * The user passes the memory for this run-time state structure and the eDMA + * driver populates the members. + */ +typedef struct EDMAState { +#if (USE_RTOS) + mutex_t lock; /*!< Lock for channel allocation and release. */ +#endif + edma_chn_state_t * volatile chn[FSL_FEATURE_EDMA_DMAMUX_CHANNELS]; /*!< Pointer array storing + channel state. */ +} edma_state_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name eDMA Peripheral Driver + * @{ + */ + +/*! + * @name eDMA peripheral driver module level functions + * @{ + */ + +/*! + * @brief Initializes all eDMA modules in an SOC. + * + * This function initializes the run-time state structure to provide the eDMA channel allocation + * release, protect, and track the state for channels. This function also opens the clock to the eDMA + * modules, resets the eDMA modules, initializes the module to user-defined settings and default + * settings. + * This is an example to set up the edma_state_t and the edma_user_config_t parameters and to call + * the EDMA_DRV_Init function by passing in these parameters. + @code + edma_state_t state; <- The user simply allocates memory for this structure. + edma_user_config_t userConfig; <- The user fills out members for this structure. + + userConfig.chnArbitration = kEDMAChnArbitrationRoundrobin; +#if (FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 0x1U) + //configuration for 2 lines below only valid for SoCs with more than on group. + userConfig.groupArbitration = kEDMAGroupArbitrationFixedPriority; + userConfig.groupPriority = kEDMAGroup0PriorityHighGroup1PriorityLow; +#endif + userCOnfig.notHaltOnError = false; <- The default setting is false, means eDMA halt on error. + + EDMA_DRV_Init(&state, &userConfig); + + @endcode + * + * @param edmaState The pointer to the eDMA peripheral driver state structure. The user passes + * the memory for this run-time state structure and the eDMA peripheral driver populates the + * members. This run-time state structure keeps track of the eDMA channels status. The memory must + * be kept valid before calling the EDMA_DRV_DeInit. + * @param userConfig User configuration structure for eDMA peripheral drivers. The user populates the + * members of this structure and passes the pointer of this structure into the function. + * + * @return An eDMA error codes or kStatus_EDMA_Success. + */ +edma_status_t EDMA_DRV_Init(edma_state_t *edmaState, const edma_user_config_t *userConfig); + +/*! + * @brief Shuts down all eDMA modules. + * + * This function resets the eDMA modules to reset state, gates the clock, and disables the interrupt + * to the core. + * + * @return An eDMA error codes or kStatus_EDMA_Success. + */ +edma_status_t EDMA_DRV_Deinit(void); + +/* @} */ + +/*! + * @name eDMA peripheral driver channel management functions + * @{ + */ + +/*! + * @brief Requests an eDMA channel dynamically or statically. + * + * This function allocates the eDMA channel according to the required channel allocation and + * corresponding to the eDMA hardware request, initializes the channel state memory provided by user and fills + * out the members. This functions also sets up the hardware request configuration according to the + * user's requirements. + * + * For Kinetis devices, a hardware request can be mapped to eDMA channels and used for the channel trigger. + * Some hardware requests can only be mapped to a limited channels. For example, the + * Kinetis K70FN1M0VMJ15 device eDMA module has 2 eDMA channel groups. The first group consists of the channel + * 0 - 15. The second group consists of channel 16 - 31. The hardware request UART0-Receive can be + * only mapped to group 1. Therefore, the hardware request is one of the parameter that the user needs to provide + * for the channel request. Channel needn't be triggered by the peripheral hardware request. The user can + * provide the ALWAYSON type hardware request to trigger the channel continuously. + * + * This function provides two ways to allocate an eDMA channel: statically and dynamically. + * In a static allocation, the user provides the required channel number and eDMA driver tries to allocate the + * required channel to the user. If the channel is not occupied, the eDMA driver is + * successfully assigned to the user. If the channel is already occupied, the user + * gets the return value kEDMAInvalidChn. + * This is an example to request a channel statically: + @code + uint32_t channelNumber = 14; <- Try to allocate the channel 14 + edma_chn_state_t chn; <- The user simply allocates memory for this structure. + + if ( kEDMAInvalidChannel == EDMA_DRV_RequestChannel(channel, kDmaRequestMux0AlwaysOn54, chn)) + { + printf("request channel %d failed!\n", channel); + } + + @endcode + * In a dynamic allocation, any of the free eDMA channels are available for use. eDMA driver + * assigns the first free channel to the user. + * This is an example for user to request a channel dynamically : + @code + uint32_t channel; <- Store the allocated channel number. + edma_chn_state_t chn; <- The user simply allocates memory for this structure. + + channel = EDMA_DRV_RequestChannel(kEDMAAnyChannel, kDmaRequestMux0AlwaysOn54, chn); + + if (channel == kEDMAInvalidChannel) + { + printf("request channel %d failed!\n", channel); + } + else + { + printf("Channel %d is successfully allocated! /n", channel); + } + + @endcode + * + * @param channel Requested channel number. If the channel is assigned with the kEDMAAnyChannel, the eDMA driver + * allocates the channel dynamically. If the channel is assigned with a valid channel number, the eDMA driver + * allocates that channel. + * @param source eDMA hardware request number. + * @param chn The pointer to the eDMA channel state structure. The user passes the memory for this + * run-time state structure. The eDMA peripheral driver populates the members. This run-time + * state structure keeps tracks of the eDMA channel status. The memory must be kept valid before + * calling the EDMA_DRV_ReleaseChannel(). + * + * @return Successfully allocated channel number or the kEDMAInvalidChannel indicating that the request is + * failed. + */ +uint8_t EDMA_DRV_RequestChannel( + uint8_t channel, dma_request_source_t source, edma_chn_state_t *chn); + +/*! + * @brief Releases an eDMA channel. + * + * This function stops the eDMA channel and disables the interrupt of this channel. The channel state + * structure can be released after this function is called. + * + * @param chn The pointer to the channel state structure. + * + * @return An eDMA error codes or kStatus_EDMA_Success. + */ +edma_status_t EDMA_DRV_ReleaseChannel(edma_chn_state_t *chn); + +/* @} */ + +/*! + * @name eDMA peripheral driver transfer setup functions + * @{ + */ +/*! + * @brief Sets the descriptor basic transfer for the descriptor. + * + * This function sets up the basic transfer for the descriptor. The minor loop setting is not + * used because the minor loop configuration impacts the global eDMA setting. + * The source minor loop offset is relevant to the destination minor loop offset. For these reasons, the minor + * loop offset configuration is treated as an advanced configuration. The user can call the + * EDMA_HAL_STCDSetMinorLoopOffset() function to configure the minor loop offset feature. + * + * @param channel Virtual channel number. + * @param chn The pointer to the channel state structure. + * @param stcd The pointer to the descriptor. + * @param config Configuration for the basic transfer. + * @param enableInt Enables (true) or Disables (false) interrupt on TCD complete. + * @param disableDmaRequest Disables (true) or Enable (false) DMA request on TCD complete. + * @return An eDMA error codes or kStatus_EDMA_Success. + */ + +static inline edma_status_t EDMA_DRV_PrepareDescriptorTransfer( + edma_chn_state_t *chn, edma_software_tcd_t *stcd, + edma_transfer_config_t *config, + bool enableInt, bool disableDmaRequest) + +{ + EDMA_HAL_STCDSetBasicTransfer( + VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(chn->channel), stcd, config, enableInt, disableDmaRequest); + + return kStatus_EDMA_Success; + +} + +/*! + * @brief Configures the memory address for the next transfer TCD for the software TCD. + * + * + * This function enables the scatter/gather feature for the software TCD and configures the next + * TCD address.This address points to the beginning of a 0-modulo-32 byte region containing + * the next transfer TCD to be loaded into this channel. The channel reload is performed as the + * major iteration count completes. The scatter/gather address must be 0-modulo-32-byte. Otherwise, + * a configuration error is reported. + * + * @param stcd The pointer to the software TCD, which needs to link to the software TCD. The + * address needs to be aligned to 32 bytes. + * @param nextStcd The pointer to the software TCD, which is to be linked to the software TCD. The + * address needs to be aligned to 32 bytes. + * @return An eDMA error codes or kStatus_EDMA_Success. + */ +static inline edma_status_t EDMA_DRV_PrepareDescriptorScatterGather( + edma_software_tcd_t *stcd, + edma_software_tcd_t *nextStcd) +{ + EDMA_HAL_STCDSetScatterGatherLink(stcd, nextStcd); + return kStatus_EDMA_Success; +} + +/*! + * @brief Configures the major channel link the software TCD. + * + * If the major link is enabled, after the major loop counter is exhausted, the eDMA engine initiates a + * channel service request at the channel defined by these six bits by setting that channel start + * bits. + * + * @param stcd The pointer to the software TCD. The address need to be aligned to 32 bytes. + * @param linkChn Channel number for major link + * @return An eDMA error codes or kStatus_EDMA_Success. + */ +static inline edma_status_t EDMA_DRV_PrepareDescriptorChannelLink( + edma_software_tcd_t *stcd, uint32_t linkChn) +{ + EDMA_HAL_STCDSetChannelMajorLink(stcd, linkChn, true); + return kStatus_EDMA_Success; +} + +/*! + * @brief Copies the software TCD configuration to the hardware TCD. + * + * @param chn The pointer to the channel state structure. + * @param stcd memory pointing to the software TCD. + * @return An eDMA error codes or kStatus_EDMA_Success. + */ +edma_status_t EDMA_DRV_PushDescriptorToReg(edma_chn_state_t *chn, edma_software_tcd_t *stcd); + +/*! + * @brief Configures the DMA transfer in a scatter-gather mode. + * + * This function configures the descriptors in a loop chain. The user passes a block of memory into this + * function and the memory is divided into the "period" sub blocks. The DMA driver configures the "period" + * descriptors. Each descriptor stands for a sub block. The DMA driver transfers data from the first + * descriptor to the last descriptor. Then, the DMA driver wraps to the first descriptor to continue + * the loop. The interrupt handler is called every time a descriptor is completed. + * The user can get a transfer status of a descriptor by calling the edma_get_descriptor_status() function in the interrupt handler or any + * other task context. At the same + * time, calling the edma_update_descriptor() function notifies the DMA driver that the content belonging to + * a descriptor is already updated and the DMA needs to count it as and underflow next time it + * loops to this descriptor. + * This is an example that describes how to use this interface in audio playback case: + * 1. Use a ping-pong buffer to transfer the data, the size of the each buffer is 1024 bytes. + * 2. Each DMA request needs to transfer 8 bytes. + * 3. The audio data is 16 bit. + @code + edma_chn_state_t chn; <--- Simply allocates the structure. + edma_software_tcd_t stcd[2]; <-- Need 32 bytes aligned, two buffer block, needs 2 TCD. + uint32_t srcAddr = buffer; <----Start address of the buffer. + uint32_t destAddr = SAI_TDR; <-----Destination address, usually SAI TDR register. + + EDMA_DRV_ConfigLoopTransfer(&chn, stcd, kEDMAMemoryToPeripheral, srcAddr, destAddr, + kEDMATransferSize_2Bytes, 8, 2048, 2) ; + + @endcode + * @param chn The pointer to the channel state structure. + * @param stcd Memory pointing to software TCDs. The user must prepare this memory block. The required + * memory size is equal to a "period" * size of(edma_software_tcd_t). At the same time, the "stcd" + * must align with 32 bytes. If not, an error occurs in the eDMA driver. + * @param type Transfer type. + * @param srcAddr A source register address or a source memory address. + * @param destAddr A destination register address or a destination memory address. + * @param size Bytes to be transferred on every DMA write/read. Source/Dest share the same write/read + * size. + * @param bytesOnEachRequest Bytes to be transferred in each DMA request. + * @param totalLength Total bytes to be transferred in a loop cycle. In audio case, it means the total buffer size. + * @param number The number of the TCDs, usually in audio case, it means the buffer block number. + * + * @return An error code of kStatus_EDMA_Success + */ +edma_status_t EDMA_DRV_ConfigLoopTransfer( + edma_chn_state_t *chn, edma_software_tcd_t *stcd, + edma_transfer_type_t type, + uint32_t srcAddr, uint32_t destAddr, uint32_t size, + uint32_t bytesOnEachRequest, uint32_t totalLength, uint8_t number); + +/*! + * @brief Configures the DMA transfer in a scatter-gather mode. + * + * This function configures the descriptors into a single-ended chain. The user passes blocks of memory into + * this function. The interrupt is triggered only when the last memory block is completed. The memory block + * information is passed with the edma_scatter_gather_list_t data structure, which can tell + * the memory address and length. + * The DMA driver configures the descriptor for each memory block, transfers the descriptor from the + * first one to the last one, and stops. + * + * @param chn The pointer to the channel state structure. + * @param stcd Memory pointing to software TCDs. The user must prepare this memory block. The required + * memory size is equal to the "number" * size of(edma_software_tcd_t). At the same time, the "stcd" + * must align with 32 bytes. If not, an error occurs in the eDMA driver. + * @param type Transfer type. + * @param size Bytes to be transferred on each DMA write/read. Source/Dest share the same write/read + * size. + * @param bytesOnEachRequest Bytes to be transferred in each DMA request. + * @param srcList Data structure storing the address and length to be transferred for source + * memory blocks. If the source memory is peripheral, the length is not used. + * @param destList Data structure storing the address and length to be transferred for destination + * memory blocks. If in the memory-to-memory transfer mode, the user must ensure that the length of + * the destination scatter gather list is equal to the source scatter gather list. If the destination memory is a + * peripheral register, the length is not used. + * @param number The number of TCD memory blocks contained in the scatter gather list. + * + * @return An error code of kStatus_EDMA_Success + */ +edma_status_t EDMA_DRV_ConfigScatterGatherTransfer( + edma_chn_state_t *chn, edma_software_tcd_t *stcd, + edma_transfer_type_t type, + uint32_t size, uint32_t bytesOnEachRequest, + edma_scatter_gather_list_t *srcList, edma_scatter_gather_list_t *destList, + uint8_t number); + +/* @} */ + +/*! + * @name eDMA Peripheral driver channel operation functions + * @{ + */ +/*! + * @brief Starts an eDMA channel. + * + * This function enables the eDMA channel DMA request. + * + * @param chn The pointer to the channel state structure. + * + * @return An eDMA error codes or kStatus_EDMA_Success. + */ +edma_status_t EDMA_DRV_StartChannel(edma_chn_state_t *chn); + +/*! + * @brief Stops the eDMA channel. + * + * This function disables the eDMA channel DMA request. + * + * @param chn The pointer to the channel state structure. + * + * @return An eDMA error codes or kStatus_EDMA_Success. + */ +edma_status_t EDMA_DRV_StopChannel(edma_chn_state_t *chn); + +/* @} */ + +/*! + * @name eDMA Peripheral callback and interrupt functions + * @{ + */ + +/*! + * @brief Registers the callback function and the parameter for eDMA channel. + * + * This function registers the callback function and the parameter into the eDMA channel state structure. + * The callback function is called when the channel is complete or a channel error occurs. The eDMA + * driver passes the channel status to this callback function to indicate whether it is caused by the + * channel complete event or the channel error event. + * + * To un-register the callback function, set the callback function to "NULL" and call this + * function. + * + * @param chn The pointer to the channel state structure. + * @param callback The pointer to the callback function. + * @param parameter The pointer to the callback function's parameter. + * + * @return An eDMA error codes or kStatus_EDMA_Success. + */ +edma_status_t EDMA_DRV_InstallCallback( + edma_chn_state_t *chn, edma_callback_t callback, void *parameter); + +/*! + * @brief IRQ Handler for eDMA channel interrupt. + * + * This function is provided as the default flow for eDMA channel interrupt. This function clears the + * status and calls the callback functions. + * The user can add this function into the hardware interrupt entry and implement a + * custom interrupt action function. + * + * @param channel Virtual channel number. + */ +void EDMA_DRV_IRQHandler(uint8_t channel); + +/*! + * @brief ERROR IRQ Handler for eDMA channel interrupt. + * + * This function is provided as the default action for eDMA module error interrupt. This function + * clears status, stops the error on a eDMA channel, and calls the eDMA channel callback function if the + * error eDMA channel is already requested. + * The user can add this function into the eDMA error interrupt entry and implement a custom + * interrupt action function. + * + * @param instance eDMA module indicator. + */ +void EDMA_DRV_ErrorIRQHandler(uint8_t instance); + +/* @} */ + +/*! + * @name eDMA Peripheral driver miscellaneous functions + * @{ + */ +/*! + * @brief Gets the eDMA channel status. + * + * @param chn The pointer to the channel state structure. + * + * @return Channel status. + */ +static inline edma_chn_status_t EDMA_DRV_GetChannelStatus(edma_chn_state_t *chn) +{ + return chn->status; +} + +/*! + * @brief Gets the unfinished bytes for the eDMA channel current TCD. + * + * This function checks the TCD (Task Control Descriptor) status for a specified eDMA channel and returns + * the bytes that have not finished. + * This function can only be used for one TCD scenario. + * + * @param chn The pointer to the channel state structure. + * + * @return Bytes already transferred for the current TCD. + */ +static inline uint32_t EDMA_DRV_GetUnfinishedBytes(edma_chn_state_t *chn) +{ + uint32_t channel = chn->channel; + + return EDMA_HAL_HTCDGetUnfinishedBytes( + VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(channel), + VIRTUAL_CHN_TO_EDMA_CHN(channel)); +} + +/*! + * @brief Gets the bytes already transferred for the eDMA channel current TCD. + * + * This function checks the TCD (Task Control Descriptor) status for a specified eDMA channel and returns + * the bytes that remain to the user. + * This function can only be used for one TCD scenario. + * + * @param chn The pointer to the channel state structure. + * + * @return Bytes already transferred for the current TCD. + */ +static inline uint32_t EDMA_DRV_GetFinishedBytes(edma_chn_state_t *chn) +{ + uint32_t channel = chn->channel; + + return EDMA_HAL_HTCDGetFinishedBytes( + VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(channel), + VIRTUAL_CHN_TO_EDMA_CHN(channel)); +} + +/* @} */ + + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif +#endif /* __FSL_EDMA_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_edma_request.h b/KSDK_1.2.0/platform/drivers/inc/fsl_edma_request.h new file mode 100755 index 0000000..825b690 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_edma_request.h @@ -0,0 +1,2550 @@ +/* + * 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. + */ + +#if !defined(__FSL_EDMA_REQUEST_H__) +#define __FSL_EDMA_REQUEST_H__ + +/*! + * @addtogroup edma_request + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Structure for the DMA hardware request + * + * Defines the structure for the DMA hardware request collections. The user can configure the + * hardware request into DMAMUX to trigger the DMA transfer accordingly. The index + * of the hardware request varies according to the to SoC. + */ + +typedef enum _dma_request_source { +#if defined(CPU_MK02FN128VFM10) || defined(CPU_MK02FN64VFM10) || defined(CPU_MK02FN128VLF10) || defined(CPU_MK02FN64VLF10) || \ + defined(CPU_MK02FN128VLH10) || defined(CPU_MK02FN64VLH10) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0Reserved6 = 6|0x100U, /*!< Reserved6 */ + kDmaRequestMux0Reserved7 = 7|0x100U, /*!< Reserved7 */ + kDmaRequestMux0Reserved8 = 8|0x100U, /*!< Reserved8 */ + kDmaRequestMux0Reserved9 = 9|0x100U, /*!< Reserved9 */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0Reserved16 = 16|0x100U, /*!< Reserved16 */ + kDmaRequestMux0Reserved17 = 17|0x100U, /*!< Reserved17 */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0. */ + kDmaRequestMux0Reserved19 = 19|0x100U, /*!< Reserved19 */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0Reserved26 = 26|0x100U, /*!< Reserved26 */ + kDmaRequestMux0Reserved27 = 27|0x100U, /*!< Reserved27 */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V. */ + kDmaRequestMux0Reserved32 = 32|0x100U, /*!< Reserved32 */ + kDmaRequestMux0Reserved33 = 33|0x100U, /*!< Reserved33 */ + kDmaRequestMux0Reserved34 = 34|0x100U, /*!< Reserved34 */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0Reserved41 = 41|0x100U, /*!< Reserved41 */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0Reserved47 = 47|0x100U, /*!< Reserved47 */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0Reserved58 = 58|0x100U, /*!< Reserved58 */ + kDmaRequestMux0Reserved59 = 59|0x100U, /*!< Reserved59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MK10DN512VLK10) || defined(CPU_MK20DN512VLK10) || defined(CPU_MK20DX256VLK10) || defined(CPU_MK30DN512VLK10) || \ + defined(CPU_MK40DN512VLK10) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 receive complete */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 transmit complete */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 receive complete */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 transmit complete */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 receive complete */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 transmit complete */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0SPI1Rx = 18|0x100U, /*!< SPI1 receive complete */ + kDmaRequestMux0SPI1Tx = 19|0x100U, /*!< SPI1 transmit complete */ + kDmaRequestMux0Reserved20 = 20|0x100U, /*!< Reserved20 */ + kDmaRequestMux0Reserved21 = 21|0x100U, /*!< Reserved21 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0I2C1 = 23|0x100U, /*!< I2C1 transmission complete */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 channel 1 event (CMP or CAP) */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0 conversion complete */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1 conversion complete */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2 Output */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT end of modulation cycle event */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MK10DN512VLL10) || defined(CPU_MK20DN512VLL10) || defined(CPU_MK20DX256VLL10) || defined(CPU_MK30DN512VLL10) || \ + defined(CPU_MK40DN512VLL10) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 receive complete */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 transmit complete */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 receive complete */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 transmit complete */ + kDmaRequestMux0UART4Rx = 10|0x100U, /*!< UART4 receive complete */ + kDmaRequestMux0UART4Tx = 11|0x100U, /*!< UART4 transmit complete */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 receive complete */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 transmit complete */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0SPI1Rx = 18|0x100U, /*!< SPI1 receive complete */ + kDmaRequestMux0SPI1Tx = 19|0x100U, /*!< SPI1 transmit complete */ + kDmaRequestMux0SPI2Rx = 20|0x100U, /*!< SPI2 receive complete */ + kDmaRequestMux0SPI2Tx = 21|0x100U, /*!< SPI2 transmit complete */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0I2C1 = 23|0x100U, /*!< I2C1 transmission complete */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 channel 1 event (CMP or CAP) */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0 conversion complete */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1 conversion complete */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2 Output */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT end of modulation cycle event */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MK10DX128VLQ10) || defined(CPU_MK10DX256VLQ10) || defined(CPU_MK10DN512VLQ10) || defined(CPU_MK10DN512VMC10) || \ + defined(CPU_MK10DX128VMD10) || defined(CPU_MK10DX256VMD10) || defined(CPU_MK10DN512VMD10) || defined(CPU_MK20DX128VLQ10) || \ + defined(CPU_MK20DX256VLQ10) || defined(CPU_MK20DN512VLQ10) || defined(CPU_MK20DX256VMC10) || defined(CPU_MK20DN512VMC10) || \ + defined(CPU_MK20DX128VMD10) || defined(CPU_MK20DX256VMD10) || defined(CPU_MK20DN512VMD10) || defined(CPU_MK30DX128VLQ10) || \ + defined(CPU_MK30DX256VLQ10) || defined(CPU_MK30DN512VLQ10) || defined(CPU_MK30DN512VMC10) || defined(CPU_MK30DX128VMD10) || \ + defined(CPU_MK30DX256VMD10) || defined(CPU_MK30DN512VMD10) || defined(CPU_MK40DX128VLQ10) || defined(CPU_MK40DX256VLQ10) || \ + defined(CPU_MK40DN512VLQ10) || defined(CPU_MK40DN512VMC10) || defined(CPU_MK40DX128VMD10) || defined(CPU_MK40DX256VMD10) || \ + defined(CPU_MK40DN512VMD10) || defined(CPU_MK50DN512CLQ10) || defined(CPU_MK50DX256CMC10) || defined(CPU_MK50DN512CMC10) || \ + defined(CPU_MK50DN512CMD10) || defined(CPU_MK50DX256CMD10) || defined(CPU_MK51DN256CLQ10) || defined(CPU_MK51DN512CLQ10) || \ + defined(CPU_MK51DX256CMC10) || defined(CPU_MK51DN512CMC10) || defined(CPU_MK51DN256CMD10) || defined(CPU_MK51DN512CMD10) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 receive complete */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 transmit complete */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 receive complete */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 transmit complete */ + kDmaRequestMux0UART4Rx = 10|0x100U, /*!< UART4 receive complete */ + kDmaRequestMux0UART4Tx = 11|0x100U, /*!< UART4 transmit complete */ + kDmaRequestMux0UART5Rx = 12|0x100U, /*!< UART5 receive complete */ + kDmaRequestMux0UART5Tx = 13|0x100U, /*!< UART5 transmit complete */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 receive complete */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 transmit complete */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0SPI1Rx = 18|0x100U, /*!< SPI1 receive complete */ + kDmaRequestMux0SPI1Tx = 19|0x100U, /*!< SPI1 transmit complete */ + kDmaRequestMux0SPI2Rx = 20|0x100U, /*!< SPI2 receive complete */ + kDmaRequestMux0SPI2Tx = 21|0x100U, /*!< SPI2 transmit complete */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0I2C1 = 23|0x100U, /*!< I2C1 transmission complete */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 channel 1 event (CMP or CAP) */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0 conversion complete */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1 conversion complete */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2 Output */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0DAC1 = 46|0x100U, /*!< DAC1 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT end of modulation cycle event */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MK11DX128AVLK5WS) || defined(CPU_MK11DX256AVLK5WS) || defined(CPU_MK11DN512AVLK5WS) || defined(CPU_MK11DX128AVLK5) || \ + defined(CPU_MK11DX256AVLK5) || defined(CPU_MK11DN512AVLK5) || defined(CPU_MK11DX128VLK5WS) || defined(CPU_MK11DX256VLK5WS) || \ + defined(CPU_MK11DN512VLK5WS) || defined(CPU_MK11DX128VLK5) || defined(CPU_MK11DX256VLK5) || defined(CPU_MK11DN512VLK5) || \ + defined(CPU_MK21DX128AVLK5WS) || defined(CPU_MK21DX256AVLK5WS) || defined(CPU_MK21DN512AVLK5WS) || defined(CPU_MK21DX128AVLK5) || \ + defined(CPU_MK21DX256AVLK5) || defined(CPU_MK21DN512AVLK5) || defined(CPU_MK21DX128VLK5WS) || defined(CPU_MK21DX256VLK5WS) || \ + defined(CPU_MK21DN512VLK5WS) || defined(CPU_MK21DX128VLK5) || defined(CPU_MK21DX256VLK5) || defined(CPU_MK21DN512VLK5) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 receive complete */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 transmit complete */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 receive complete */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 transmit complete */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 receive complete */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 transmit complete */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0SPI1Rx = 18|0x100U, /*!< SPI1 receive complete */ + kDmaRequestMux0SPI1Tx = 19|0x100U, /*!< SPI1 transmit complete */ + kDmaRequestMux0Reserved20 = 20|0x100U, /*!< Reserved20 */ + kDmaRequestMux0Reserved21 = 21|0x100U, /*!< Reserved21 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0I2C1 = 23|0x100U, /*!< I2C1 transmission complete */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 channel 1 event (CMP or CAP) */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0 conversion complete */ + kDmaRequestMux0Reserved41 = 41|0x100U, /*!< Reserved41 */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0Reserved45 = 45|0x100U, /*!< Reserved45 */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT end of modulation cycle event */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MK11DX128AVMC5WS) || defined(CPU_MK11DX256AVMC5WS) || defined(CPU_MK11DN512AVMC5WS) || defined(CPU_MK11DX128AVMC5) || \ + defined(CPU_MK11DX256AVMC5) || defined(CPU_MK11DN512AVMC5) || defined(CPU_MK11DX128VMC5WS) || defined(CPU_MK11DX256VMC5WS) || \ + defined(CPU_MK11DN512VMC5WS) || defined(CPU_MK11DX128VMC5) || defined(CPU_MK11DX256VMC5) || defined(CPU_MK11DN512VMC5) || \ + defined(CPU_MK12DX128VLK5) || defined(CPU_MK12DX256VLK5) || defined(CPU_MK12DN512VLK5) || defined(CPU_MK12DX128VMC5) || \ + defined(CPU_MK12DX256VMC5) || defined(CPU_MK12DN512VMC5) || defined(CPU_MK21DX128AVMC5WS) || defined(CPU_MK21DX256AVMC5WS) || \ + defined(CPU_MK21DN512AVMC5WS) || defined(CPU_MK21DX128AVMC5) || defined(CPU_MK21DX256AVMC5) || defined(CPU_MK21DN512AVMC5) || \ + defined(CPU_MK21DX128VMC5WS) || defined(CPU_MK21DX256VMC5WS) || defined(CPU_MK21DN512VMC5WS) || defined(CPU_MK21DX128VMC5) || \ + defined(CPU_MK21DX256VMC5) || defined(CPU_MK21DN512VMC5) || defined(CPU_MK22DX128VLK5) || defined(CPU_MK22DX256VLK5) || \ + defined(CPU_MK22DN512VLK5) || defined(CPU_MK22DX128VMC5) || defined(CPU_MK22DX256VMC5) || defined(CPU_MK22DN512VMC5) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 receive complete */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 transmit complete */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 receive complete */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 transmit complete */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 receive complete */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 transmit complete */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0SPI1Rx = 18|0x100U, /*!< SPI1 receive complete */ + kDmaRequestMux0SPI1Tx = 19|0x100U, /*!< SPI1 transmit complete */ + kDmaRequestMux0Reserved20 = 20|0x100U, /*!< Reserved20 */ + kDmaRequestMux0Reserved21 = 21|0x100U, /*!< Reserved21 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0I2C1 = 23|0x100U, /*!< I2C1 transmission complete */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 channel 1 event (CMP or CAP) */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0 conversion complete */ + kDmaRequestMux0Reserved41 = 41|0x100U, /*!< Reserved41 */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT end of modulation cycle event */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MK12DX128VLH5) || defined(CPU_MK12DX256VLH5) || defined(CPU_MK12DN512VLH5) || defined(CPU_MK22DX128VLH5) || \ + defined(CPU_MK22DX256VLH5) || defined(CPU_MK22DN512VLH5) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 receive complete */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 transmit complete */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 receive complete */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 transmit complete */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 receive complete */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 transmit complete */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0Reserved18 = 18|0x100U, /*!< Reserved18 */ + kDmaRequestMux0Reserved19 = 19|0x100U, /*!< Reserved19 */ + kDmaRequestMux0Reserved20 = 20|0x100U, /*!< Reserved20 */ + kDmaRequestMux0Reserved21 = 21|0x100U, /*!< Reserved21 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0I2C1 = 23|0x100U, /*!< I2C1 transmission complete */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 channel 1 event (CMP or CAP) */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0 conversion complete */ + kDmaRequestMux0Reserved41 = 41|0x100U, /*!< Reserved41 */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT end of modulation cycle event */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MK12DX128VLF5) || defined(CPU_MK12DX256VLF5) || defined(CPU_MK22DX128VLF5) || defined(CPU_MK22DX256VLF5) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 receive complete */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 transmit complete */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 receive complete */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 transmit complete */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 receive complete */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 transmit complete */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0Reserved18 = 18|0x100U, /*!< Reserved18 */ + kDmaRequestMux0Reserved19 = 19|0x100U, /*!< Reserved19 */ + kDmaRequestMux0Reserved20 = 20|0x100U, /*!< Reserved20 */ + kDmaRequestMux0Reserved21 = 21|0x100U, /*!< Reserved21 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0Reserved23 = 23|0x100U, /*!< Reserved23 */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0Reserved34 = 34|0x100U, /*!< Reserved34 */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0 conversion complete */ + kDmaRequestMux0Reserved41 = 41|0x100U, /*!< Reserved41 */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0Reserved45 = 45|0x100U, /*!< Reserved45 */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT end of modulation cycle event */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MK21FX512AVLQ12WS) || defined(CPU_MK21FN1M0AVLQ12WS) || defined(CPU_MK21FX512AVLQ12) || defined(CPU_MK21FN1M0AVLQ12) || \ + defined(CPU_MK21FX512AVMC12WS) || defined(CPU_MK21FN1M0AVMC12WS) || defined(CPU_MK21FX512AVMC12) || defined(CPU_MK21FN1M0AVMC12) || \ + defined(CPU_MK21FX512AVMD12WS) || defined(CPU_MK21FN1M0AVMD12WS) || defined(CPU_MK21FX512AVMD12) || defined(CPU_MK21FN1M0AVMD12) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 Transmit. */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 Receive. */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 Transmit. */ + kDmaRequestMux0UART4 = 10|0x100U, /*!< UART4 Transmit or Receive. */ + kDmaRequestMux0UART5 = 11|0x100U, /*!< UART5 Transmit or Receive. */ + kDmaRequestMux0I2S0Rx = 12|0x100U, /*!< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 13|0x100U, /*!< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0SPI1 = 16|0x100U, /*!< SPI1 Transmit or Receive. */ + kDmaRequestMux0SPI2 = 17|0x100U, /*!< SPI2 Transmit or Receive. */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0. */ + kDmaRequestMux0I2C1I2C2 = 19|0x100U, /*!< I2C1 and I2C2. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /*!< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /*!< FTM0 C7V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V. */ + kDmaRequestMux0FTM3Channel0 = 32|0x100U, /*!< FTM3 C0V. */ + kDmaRequestMux0FTM3Channel1 = 33|0x100U, /*!< FTM3 C1V. */ + kDmaRequestMux0FTM3Channel2 = 34|0x100U, /*!< FTM3 C2V. */ + kDmaRequestMux0FTM3Channel3 = 35|0x100U, /*!< FTM3 C3V. */ + kDmaRequestMux0FTM3Channel4 = 36|0x100U, /*!< FTM3 C4V. */ + kDmaRequestMux0FTM3Channel5 = 37|0x100U, /*!< FTM3 C5V. */ + kDmaRequestMux0FTM3Channel6 = 38|0x100U, /*!< FTM3 C6V. */ + kDmaRequestMux0FTM3Channel7 = 39|0x100U, /*!< FTM3 C7V. */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2. */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0DAC1 = 46|0x100U, /*!< DAC1. */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT. */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MK22FN128VDC10) || defined(CPU_MK22FN128VLH10) || defined(CPU_MK22FN128VLL10) || defined(CPU_MK22FN128VMP10) || \ + defined(CPU_MK22FN256CAH12) || defined(CPU_MK22FN128CAH12) || defined(CPU_MK22FN256VDC12) || defined(CPU_MK22FN256VLH12) || \ + defined(CPU_MK22FN256VLL12) || defined(CPU_MK22FN256VMP12) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 Transmit. */ + kDmaRequestMux0Reserved8 = 8|0x100U, /*!< Reserved8 */ + kDmaRequestMux0Reserved9 = 9|0x100U, /*!< Reserved9 */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0I2S0Rx = 12|0x100U, /*!< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 13|0x100U, /*!< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0SPI1 = 16|0x100U, /*!< SPI1 Transmit or Receive. */ + kDmaRequestMux0Reserved17 = 17|0x100U, /*!< Reserved17 */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0. */ + kDmaRequestMux0I2C1 = 19|0x100U, /*!< I2C1. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /*!< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /*!< FTM0 C7V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V. */ + kDmaRequestMux0Reserved32 = 32|0x100U, /*!< Reserved32 */ + kDmaRequestMux0Reserved33 = 33|0x100U, /*!< Reserved33 */ + kDmaRequestMux0Reserved34 = 34|0x100U, /*!< Reserved34 */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0Reserved47 = 47|0x100U, /*!< Reserved47 */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0LPUART0Rx = 58|0x100U, /*!< LPUART0 Receive. */ + kDmaRequestMux0LPUART0Tx = 59|0x100U, /*!< LPUART0 Transmit. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MK22FN512CAP12) || defined(CPU_MK22FN512VDC12) || defined(CPU_MK22FN512VLH12) || defined(CPU_MK22FN512VLL12) || \ + defined(CPU_MK22FN512VMP12) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 Transmit. */ + kDmaRequestMux0Reserved8 = 8|0x100U, /*!< Reserved8 */ + kDmaRequestMux0Reserved9 = 9|0x100U, /*!< Reserved9 */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0I2S0Rx = 12|0x100U, /*!< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 13|0x100U, /*!< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0SPI1 = 16|0x100U, /*!< SPI1 Transmit or Receive. */ + kDmaRequestMux0Reserved17 = 17|0x100U, /*!< Reserved17 */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0. */ + kDmaRequestMux0I2C1 = 19|0x100U, /*!< I2C1. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /*!< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /*!< FTM0 C7V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V. */ + kDmaRequestMux0FTM3Channel0 = 32|0x100U, /*!< FTM3 C0V. */ + kDmaRequestMux0FTM3Channel1 = 33|0x100U, /*!< FTM3 C1V. */ + kDmaRequestMux0FTM3Channel2 = 34|0x100U, /*!< FTM3 C2V. */ + kDmaRequestMux0FTM3Channel3 = 35|0x100U, /*!< FTM3 C3V. */ + kDmaRequestMux0FTM3Channel4 = 36|0x100U, /*!< FTM3 C4V. */ + kDmaRequestMux0FTM3Channel5 = 37|0x100U, /*!< FTM3 C5V. */ + kDmaRequestMux0FTM3Channel6 = 38|0x100U, /*!< FTM3 C6V. */ + kDmaRequestMux0FTM3Channel7 = 39|0x100U, /*!< FTM3 C7V. */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0DAC1 = 46|0x100U, /*!< DAC1. */ + kDmaRequestMux0Reserved47 = 47|0x100U, /*!< Reserved47 */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0LPUART0Rx = 58|0x100U, /*!< LPUART0 Receive. */ + kDmaRequestMux0LPUART0Tx = 59|0x100U, /*!< LPUART0 Transmit. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MK24FN1M0VDC12) || defined(CPU_MK24FN1M0VLL12) || defined(CPU_MK24FN1M0VLQ12) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 Transmit. */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 Receive. */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 Transmit. */ + kDmaRequestMux0UART4 = 10|0x100U, /*!< UART4 Transmit or Receive. */ + kDmaRequestMux0UART5 = 11|0x100U, /*!< UART5 Transmit or Receive. */ + kDmaRequestMux0I2S0Rx = 12|0x100U, /*!< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 13|0x100U, /*!< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0SPI1 = 16|0x100U, /*!< SPI1 Transmit or Receive. */ + kDmaRequestMux0SPI2 = 17|0x100U, /*!< SPI2 Transmit or Receive. */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0. */ + kDmaRequestMux0I2C1I2C2 = 19|0x100U, /*!< I2C1 and I2C2. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /*!< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /*!< FTM0 C7V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V. */ + kDmaRequestMux0FTM3Channel0 = 32|0x100U, /*!< FTM3 C0V. */ + kDmaRequestMux0FTM3Channel1 = 33|0x100U, /*!< FTM3 C1V. */ + kDmaRequestMux0FTM3Channel2 = 34|0x100U, /*!< FTM3 C2V. */ + kDmaRequestMux0FTM3Channel3 = 35|0x100U, /*!< FTM3 C3V. */ + kDmaRequestMux0FTM3Channel4 = 36|0x100U, /*!< FTM3 C4V. */ + kDmaRequestMux0FTM3Channel5 = 37|0x100U, /*!< FTM3 C5V. */ + kDmaRequestMux0FTM3Channel6 = 38|0x100U, /*!< FTM3 C6V. */ + kDmaRequestMux0FTM3Channel7 = 39|0x100U, /*!< FTM3 C7V. */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2. */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0DAC1 = 46|0x100U, /*!< DAC1. */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT. */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MK24FN256VDC12) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 Transmit. */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 Receive. */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 Transmit. */ + kDmaRequestMux0UART4 = 10|0x100U, /*!< UART4 Transmit or Receive. */ + kDmaRequestMux0UART5 = 11|0x100U, /*!< UART5 Transmit or Receive. */ + kDmaRequestMux0I2S0Rx = 12|0x100U, /*!< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 13|0x100U, /*!< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0SPI1 = 16|0x100U, /*!< SPI1 Transmit or Receive. */ + kDmaRequestMux0SPI2 = 17|0x100U, /*!< SPI2 Transmit or Receive. */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0. */ + kDmaRequestMux0I2C1I2C2 = 19|0x100U, /*!< I2C1 and I2C2. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /*!< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /*!< FTM0 C7V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V. */ + kDmaRequestMux0FTM3Channel0 = 32|0x100U, /*!< FTM3 C0V. */ + kDmaRequestMux0FTM3Channel1 = 33|0x100U, /*!< FTM3 C1V. */ + kDmaRequestMux0FTM3Channel2 = 34|0x100U, /*!< FTM3 C2V. */ + kDmaRequestMux0FTM3Channel3 = 35|0x100U, /*!< FTM3 C3V. */ + kDmaRequestMux0FTM3Channel4 = 36|0x100U, /*!< FTM3 C4V. */ + kDmaRequestMux0FTM3Channel5 = 37|0x100U, /*!< FTM3 C5V. */ + kDmaRequestMux0FTM3Channel6 = 38|0x100U, /*!< FTM3 C6V. */ + kDmaRequestMux0FTM3Channel7 = 39|0x100U, /*!< FTM3 C7V. */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT. */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MK26FN2M0CAC18) || defined(CPU_MK26FN2M0VLQ18) || defined(CPU_MK26FN2M0VMD18) || defined(CPU_MK26FN2M0VMI18) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0TSI0 = 1|0x100U, /*!< TSI0. */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 Transmit. */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 Receive. */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 Transmit. */ + kDmaRequestMux0UART4 = 10|0x100U, /*!< UART4 Transmit or Receive. */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0I2S0Rx = 12|0x100U, /*!< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 13|0x100U, /*!< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0SPI1Rx = 16|0x100U, /*!< SPI1 Receive. */ + kDmaRequestMux0SPI1Tx = 17|0x100U, /*!< SPI1 Transmit. */ + kDmaRequestMux0I2C0I2C3 = 18|0x100U, /*!< I2C0 and I2C3. */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0 and I2C3. */ + kDmaRequestMux0I2C3 = 18|0x100U, /*!< I2C0 and I2C3. */ + kDmaRequestMux0I2C1I2C2 = 19|0x100U, /*!< I2C1 and I2C2. */ + kDmaRequestMux0I2C1 = 19|0x100U, /*!< I2C1 and I2C2. */ + kDmaRequestMux0I2C2 = 19|0x100U, /*!< I2C1 and I2C2. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /*!< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /*!< FTM0 C7V. */ + kDmaRequestMux0FTM1TPM1Channel0 = 28|0x100U, /*!< FTM1 C0V and TPM1_C0V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V and TPM1 C0V. */ + kDmaRequestMux0TPM1Channel0 = 28|0x100U, /*!< FTM1 C0V and TPM1 C0V. */ + kDmaRequestMux0FTM1TPM1Channel1 = 29|0x100U, /*!< FTM1 C1V and TPM1_C1V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V and TPM1 C1V. */ + kDmaRequestMux0TPM1Channel1 = 29|0x100U, /*!< FTM1 C1V and TPM1 C1V. */ + kDmaRequestMux0FTM2TPM2Channel0 = 30|0x100U, /*!< FTM2 C0V and TPM2_C0V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V and TPM2 C0V. */ + kDmaRequestMux0TPM2Channel0 = 30|0x100U, /*!< FTM2 C0V and TPM2 C0V. */ + kDmaRequestMux0FTM2TPM2Channel1 = 31|0x100U, /*!< FTM2 C1V and TPM2_C1V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V and TPM2 C1V. */ + kDmaRequestMux0TPM2Channel1 = 31|0x100U, /*!< FTM2 C1V and TPM2 C1V. */ + kDmaRequestMux0FTM3Channel0 = 32|0x100U, /*!< FTM3 C0V. */ + kDmaRequestMux0FTM3Channel1 = 33|0x100U, /*!< FTM3 C1V. */ + kDmaRequestMux0FTM3Channel2 = 34|0x100U, /*!< FTM3 C2V. */ + kDmaRequestMux0FTM3Channel3 = 35|0x100U, /*!< FTM3 C3V. */ + kDmaRequestMux0FTM3Channel4 = 36|0x100U, /*!< FTM3 C4V. */ + kDmaRequestMux0FTM3Channel5 = 37|0x100U, /*!< FTM3 C5V. */ + kDmaRequestMux0FTM3Channel6SPI2Rx = 38|0x100U, /*!< FTM3 C6V and SPI2 Receive. */ + kDmaRequestMux0FTM3Channel6 = 38|0x100U, /*!< FTM3 C6V and SPI2 Receive. */ + kDmaRequestMux0SPI2Rx = 38|0x100U, /*!< FTM3 C6V and SPI2 Receive. */ + kDmaRequestMux0FTM3Channel7SPI2Tx = 39|0x100U, /*!< FTM3 C7V and SPI2 Transmit. */ + kDmaRequestMux0FTM3Channel7 = 39|0x100U, /*!< FTM3 C7V and SPI2 Transmit. */ + kDmaRequestMux0SPI2Tx = 39|0x100U, /*!< FTM3 C7V and SPI2 Transmit. */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0CMP2CMP3 = 44|0x100U, /*!< CMP2 and CMP3. */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2 and CMP3. */ + kDmaRequestMux0CMP3 = 44|0x100U, /*!< CMP2 and CMP3. */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0DAC1 = 46|0x100U, /*!< DAC1. */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT. */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0TPM1Overflow = 55|0x100U, /*!< TPM1. */ + kDmaRequestMux0IEEE1588Timer2TPM2_Overflow = 56|0x100U, /*!<TPM2 DMA request. */ + kDmaRequestMux0TPM2Overflow = 56|0x100U, /*!< ENET IEEE 1588 timer 2 and TPM2. */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0LPUART0Rx = 58|0x100U, /*!< LPUART0 Receive. */ + kDmaRequestMux0LPUART0Tx = 59|0x100U, /*!< LPUART0 Transmit. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MK50DX256CLL10) || defined(CPU_MK50DN512CLL10) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 receive complete */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 transmit complete */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 receive complete */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 transmit complete */ + kDmaRequestMux0UART4Rx = 10|0x100U, /*!< UART4 receive complete */ + kDmaRequestMux0UART4Tx = 11|0x100U, /*!< UART4 transmit complete */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 receive complete */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 transmit complete */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0SPI1Rx = 18|0x100U, /*!< SPI1 receive complete */ + kDmaRequestMux0SPI1Tx = 19|0x100U, /*!< SPI1 transmit complete */ + kDmaRequestMux0SPI2Rx = 20|0x100U, /*!< SPI2 receive complete */ + kDmaRequestMux0SPI2Tx = 21|0x100U, /*!< SPI2 transmit complete */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0I2C1 = 23|0x100U, /*!< I2C1 transmission complete */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 channel 1 event (CMP or CAP) */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0 conversion complete */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1 conversion complete */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2 Output */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0DAC1 = 46|0x100U, /*!< DAC1 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT end of modulation cycle event */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MK50DX256CLK10) || defined(CPU_MK51DX256CLK10) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 receive complete */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 transmit complete */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 receive complete */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 transmit complete */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 receive complete */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 transmit complete */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0SPI1Rx = 18|0x100U, /*!< SPI1 receive complete */ + kDmaRequestMux0SPI1Tx = 19|0x100U, /*!< SPI1 transmit complete */ + kDmaRequestMux0Reserved20 = 20|0x100U, /*!< Reserved20 */ + kDmaRequestMux0Reserved21 = 21|0x100U, /*!< Reserved21 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0I2C1 = 23|0x100U, /*!< I2C1 transmission complete */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 channel 1 event (CMP or CAP) */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0 conversion complete */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1 conversion complete */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2 Output */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0DAC1 = 46|0x100U, /*!< DAC1 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT end of modulation cycle event */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0Reserved53 = 53|0x100U, /*!< Reserved53 */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MK51DX256CLL10) || defined(CPU_MK51DN512CLL10) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 receive complete */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 transmit complete */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 receive complete */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 transmit complete */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 receive complete */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 transmit complete */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0SPI1Rx = 18|0x100U, /*!< SPI1 receive complete */ + kDmaRequestMux0SPI1Tx = 19|0x100U, /*!< SPI1 transmit complete */ + kDmaRequestMux0SPI2Rx = 20|0x100U, /*!< SPI2 receive complete */ + kDmaRequestMux0SPI2Tx = 21|0x100U, /*!< SPI2 transmit complete */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0I2C1 = 23|0x100U, /*!< I2C1 transmission complete */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 channel 1 event (CMP or CAP) */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0 conversion complete */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1 conversion complete */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2 Output */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0DAC1 = 46|0x100U, /*!< DAC1 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT end of modulation cycle event */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MK52DN512CLQ10) || defined(CPU_MK52DN512CMD10) || defined(CPU_MK53DN512CLQ10) || defined(CPU_MK53DX256CLQ10) || \ + defined(CPU_MK53DN512CMD10) || defined(CPU_MK53DX256CMD10) || defined(CPU_MK60DN256VLQ10) || defined(CPU_MK60DX256VLQ10) || \ + defined(CPU_MK60DN512VLQ10) || defined(CPU_MK60DN256VMC10) || defined(CPU_MK60DX256VMC10) || defined(CPU_MK60DN512VMC10) || \ + defined(CPU_MK60DN256VMD10) || defined(CPU_MK60DX256VMD10) || defined(CPU_MK60DN512VMD10) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 receive complete */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 transmit complete */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 receive complete */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 transmit complete */ + kDmaRequestMux0UART4Rx = 10|0x100U, /*!< UART4 receive complete */ + kDmaRequestMux0UART4Tx = 11|0x100U, /*!< UART4 transmit complete */ + kDmaRequestMux0UART5Rx = 12|0x100U, /*!< UART5 receive complete */ + kDmaRequestMux0UART5Tx = 13|0x100U, /*!< UART5 transmit complete */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 receive complete */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 transmit complete */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0SPI1Rx = 18|0x100U, /*!< SPI1 receive complete */ + kDmaRequestMux0SPI1Tx = 19|0x100U, /*!< SPI1 transmit complete */ + kDmaRequestMux0SPI2Rx = 20|0x100U, /*!< SPI2 receive complete */ + kDmaRequestMux0SPI2Tx = 21|0x100U, /*!< SPI2 transmit complete */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0I2C1 = 23|0x100U, /*!< I2C1 transmission complete */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 channel 1 event (CMP or CAP) */ + kDmaRequestMux0IEEE1588Timer0 = 36|0x100U, /*!< Ethernet IEEE 1588 timer 0 */ + kDmaRequestMux0IEEE1588Timer1 = 37|0x100U, /*!< Ethernet IEEE 1588 timer 1 */ + kDmaRequestMux0IEEE1588Timer2 = 38|0x100U, /*!< Ethernet IEEE 1588 timer 2 */ + kDmaRequestMux0IEEE1588Timer3 = 39|0x100U, /*!< Ethernet IEEE 1588 timer 3 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0 conversion complete */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1 conversion complete */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2 Output */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0DAC1 = 46|0x100U, /*!< DAC1 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT end of modulation cycle event */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MK60DN256VLL10) || defined(CPU_MK60DX256VLL10) || defined(CPU_MK60DN512VLL10) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 receive complete */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 transmit complete */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 receive complete */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 transmit complete */ + kDmaRequestMux0UART4Rx = 10|0x100U, /*!< UART4 receive complete */ + kDmaRequestMux0UART4Tx = 11|0x100U, /*!< UART4 transmit complete */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 receive complete */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 transmit complete */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0SPI1Rx = 18|0x100U, /*!< SPI1 receive complete */ + kDmaRequestMux0SPI1Tx = 19|0x100U, /*!< SPI1 transmit complete */ + kDmaRequestMux0SPI2Rx = 20|0x100U, /*!< SPI2 receive complete */ + kDmaRequestMux0SPI2Tx = 21|0x100U, /*!< SPI2 transmit complete */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0I2C1 = 23|0x100U, /*!< I2C1 transmission complete */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 channel 1 event (CMP or CAP) */ + kDmaRequestMux0IEEE1588Timer0 = 36|0x100U, /*!< Ethernet IEEE 1588 timer 0 */ + kDmaRequestMux0IEEE1588Timer1 = 37|0x100U, /*!< Ethernet IEEE 1588 timer 1 */ + kDmaRequestMux0IEEE1588Timer2 = 38|0x100U, /*!< Ethernet IEEE 1588 timer 2 */ + kDmaRequestMux0IEEE1588Timer3 = 39|0x100U, /*!< Ethernet IEEE 1588 timer 3 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0 conversion complete */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1 conversion complete */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2 Output */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT end of modulation cycle event */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MK63FN1M0VLQ12WS) || defined(CPU_MK63FN1M0VLQ12) || defined(CPU_MK63FN1M0VMD12WS) || defined(CPU_MK63FN1M0VMD12) || \ + defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FX512VLQ12) || defined(CPU_MK64FN1M0VLQ12) || \ + defined(CPU_MK64FX512VMD12) || defined(CPU_MK64FN1M0VMD12) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 Transmit. */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 Receive. */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 Transmit. */ + kDmaRequestMux0UART4 = 10|0x100U, /*!< UART4 Transmit or Receive. */ + kDmaRequestMux0UART5 = 11|0x100U, /*!< UART5 Transmit or Receive. */ + kDmaRequestMux0I2S0Rx = 12|0x100U, /*!< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 13|0x100U, /*!< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0SPI1 = 16|0x100U, /*!< SPI1 Transmit or Receive. */ + kDmaRequestMux0SPI2 = 17|0x100U, /*!< SPI2 Transmit or Receive. */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0. */ + kDmaRequestMux0I2C1I2C2 = 19|0x100U, /*!< I2C1 and I2C2. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /*!< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /*!< FTM0 C7V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V. */ + kDmaRequestMux0FTM3Channel0 = 32|0x100U, /*!< FTM3 C0V. */ + kDmaRequestMux0FTM3Channel1 = 33|0x100U, /*!< FTM3 C1V. */ + kDmaRequestMux0FTM3Channel2 = 34|0x100U, /*!< FTM3 C2V. */ + kDmaRequestMux0FTM3Channel3 = 35|0x100U, /*!< FTM3 C3V. */ + kDmaRequestMux0FTM3Channel4 = 36|0x100U, /*!< FTM3 C4V. */ + kDmaRequestMux0FTM3Channel5 = 37|0x100U, /*!< FTM3 C5V. */ + kDmaRequestMux0FTM3Channel6 = 38|0x100U, /*!< FTM3 C6V. */ + kDmaRequestMux0FTM3Channel7 = 39|0x100U, /*!< FTM3 C7V. */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2. */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0DAC1 = 46|0x100U, /*!< DAC1. */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT. */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0IEEE1588Timer0 = 54|0x100U, /*!< ENET IEEE 1588_timer_0. */ + kDmaRequestMux0IEEE1588Timer1 = 55|0x100U, /*!< ENET IEEE 1588_timer_1. */ + kDmaRequestMux0IEEE1588Timer2 = 56|0x100U, /*!< ENET IEEE 1588_timer_2. */ + kDmaRequestMux0IEEE1588Timer3 = 57|0x100U, /*!< ENET IEEE 1588_timer_3. */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MK64FX512VLL12) || defined(CPU_MK64FN1M0VLL12) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 Transmit. */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 Receive. */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 Transmit. */ + kDmaRequestMux0UART4 = 10|0x100U, /*!< UART4 Transmit or Receive. */ + kDmaRequestMux0UART5 = 11|0x100U, /*!< UART5 Transmit or Receive. */ + kDmaRequestMux0I2S0Rx = 12|0x100U, /*!< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 13|0x100U, /*!< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0SPI1 = 16|0x100U, /*!< SPI1 Transmit or Receive. */ + kDmaRequestMux0SPI2 = 17|0x100U, /*!< SPI2 Transmit or Receive. */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0. */ + kDmaRequestMux0I2C1I2C2 = 19|0x100U, /*!< I2C1 or I2C2. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /*!< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /*!< FTM0 C7V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V. */ + kDmaRequestMux0FTM3Channel0 = 32|0x100U, /*!< FTM3 C0V. */ + kDmaRequestMux0FTM3Channel1 = 33|0x100U, /*!< FTM3 C1V. */ + kDmaRequestMux0FTM3Channel2 = 34|0x100U, /*!< FTM3 C2V. */ + kDmaRequestMux0FTM3Channel3 = 35|0x100U, /*!< FTM3 C3V. */ + kDmaRequestMux0FTM3Channel4 = 36|0x100U, /*!< FTM3 C4V. */ + kDmaRequestMux0FTM3Channel5 = 37|0x100U, /*!< FTM3 C5V. */ + kDmaRequestMux0FTM3Channel6 = 38|0x100U, /*!< FTM3 C6V. */ + kDmaRequestMux0FTM3Channel7 = 39|0x100U, /*!< FTM3 C7V. */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2. */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT. */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0IEEE1588Timer0 = 54|0x100U, /*!< ENET IEEE 1588_timer_0. */ + kDmaRequestMux0IEEE1588Timer1 = 55|0x100U, /*!< ENET IEEE 1588_timer_1. */ + kDmaRequestMux0IEEE1588Timer2 = 56|0x100U, /*!< ENET IEEE 1588_timer_2. */ + kDmaRequestMux0IEEE1588Timer3 = 57|0x100U, /*!< ENET IEEE 1588_timer_3. */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MK65FN2M0CAC18) || defined(CPU_MK65FX1M0CAC18) || defined(CPU_MK65FN2M0CAC18WS) || defined(CPU_MK65FX1M0CAC18WS) || \ + defined(CPU_MK65FN2M0VMI18) || defined(CPU_MK65FX1M0VMI18) || defined(CPU_MK65FN2M0VMI18WS) || defined(CPU_MK65FX1M0VMI18WS) || \ + defined(CPU_MK66FN2M0VLQ18) || defined(CPU_MK66FX1M0VLQ18) || defined(CPU_MK66FN2M0VMD18) || defined(CPU_MK66FX1M0VMD18) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0TSI0 = 1|0x100U, /*!< TSI0. */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 Transmit. */ + kDmaRequestMux0UART3Rx = 8|0x100U, /*!< UART3 Receive. */ + kDmaRequestMux0UART3Tx = 9|0x100U, /*!< UART3 Transmit. */ + kDmaRequestMux0UART4 = 10|0x100U, /*!< UART4 Transmit or Receive. */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0I2S0Rx = 12|0x100U, /*!< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 13|0x100U, /*!< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0SPI1Rx = 16|0x100U, /*!< SPI1 Receive. */ + kDmaRequestMux0SPI1Tx = 17|0x100U, /*!< SPI1 Transmit. */ + kDmaRequestMux0I2C0I2C3 = 18|0x100U, /*!< I2C0 and I2C3. */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0 and I2C3. */ + kDmaRequestMux0I2C3 = 18|0x100U, /*!< I2C0 and I2C3. */ + kDmaRequestMux0I2C1I2C2 = 19|0x100U, /*!< I2C1 and I2C2. */ + kDmaRequestMux0I2C1 = 19|0x100U, /*!< I2C1 and I2C2. */ + kDmaRequestMux0I2C2 = 19|0x100U, /*!< I2C1 and I2C2. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /*!< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /*!< FTM0 C7V. */ + kDmaRequestMux0FTM1TPM1Channel0 = 28|0x100U, /*!< FTM1 C0V and TPM1_C0V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V and TPM1 C0V. */ + kDmaRequestMux0TPM1Channel0 = 28|0x100U, /*!< FTM1 C0V and TPM1 C0V. */ + kDmaRequestMux0FTM1TPM1Channel1 = 29|0x100U, /*!< FTM1 C1V and TPM1_C1V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V and TPM1 C1V. */ + kDmaRequestMux0TPM1Channel1 = 29|0x100U, /*!< FTM1 C1V and TPM1 C1V. */ + kDmaRequestMux0FTM2TPM2Channel0 = 30|0x100U, /*!< FTM2 C0V and TPM2_C0V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V and TPM2 C0V. */ + kDmaRequestMux0TPM2Channel0 = 30|0x100U, /*!< FTM2 C0V and TPM2 C0V. */ + kDmaRequestMux0FTM2TPM2Channel1 = 31|0x100U, /*!< FTM2 C1V and TPM2_C1V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V and TPM2 C1V. */ + kDmaRequestMux0TPM2Channel1 = 31|0x100U, /*!< FTM2 C1V and TPM2 C1V. */ + kDmaRequestMux0FTM3Channel0 = 32|0x100U, /*!< FTM3 C0V. */ + kDmaRequestMux0FTM3Channel1 = 33|0x100U, /*!< FTM3 C1V. */ + kDmaRequestMux0FTM3Channel2 = 34|0x100U, /*!< FTM3 C2V. */ + kDmaRequestMux0FTM3Channel3 = 35|0x100U, /*!< FTM3 C3V. */ + kDmaRequestMux0FTM3Channel4 = 36|0x100U, /*!< FTM3 C4V. */ + kDmaRequestMux0FTM3Channel5 = 37|0x100U, /*!< FTM3 C5V. */ + kDmaRequestMux0FTM3Channel6SPI2Rx = 38|0x100U, /*!< FTM3 C6V and SPI2 Receive. */ + kDmaRequestMux0FTM3Channel6 = 38|0x100U, /*!< FTM3 C6V and SPI2 Receive. */ + kDmaRequestMux0SPI2Rx = 38|0x100U, /*!< FTM3 C6V and SPI2 Receive. */ + kDmaRequestMux0FTM3Channel7SPI2Tx = 39|0x100U, /*!< FTM3 C7V and SPI2 Transmit. */ + kDmaRequestMux0FTM3Channel7 = 39|0x100U, /*!< FTM3 C7V and SPI2 Transmit. */ + kDmaRequestMux0SPI2Tx = 39|0x100U, /*!< FTM3 C7V and SPI2 Transmit. */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0CMP2CMP3 = 44|0x100U, /*!< CMP2 and CMP3. */ + kDmaRequestMux0CMP2 = 44|0x100U, /*!< CMP2 and CMP3. */ + kDmaRequestMux0CMP3 = 44|0x100U, /*!< CMP2 and CMP3. */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0DAC1 = 46|0x100U, /*!< DAC1. */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT. */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0IEEE1588Timer0 = 54|0x100U, /*!< ENET IEEE 1588_timer_0. */ + kDmaRequestMux0IEEE1588Timer1TPM1Overflow = 55|0x100U, /*!< ENET IEEE 1588_timer_1 and TPM1. */ + kDmaRequestMux0IEEE1588Timer1 = 55|0x100U, /*!< ENET IEEE 1588 timer_1 and TPM1. */ + kDmaRequestMux0TPM1Overflow = 55|0x100U, /*!< ENET IEEE 1588 timer 1 and TPM1. */ + kDmaRequestMux0IEEE1588Timer2TPM2Overflow = 56|0x100U, /*!< ENET IEEE 1588_timer_2 and TPM2. */ + kDmaRequestMux0IEEE1588Timer2 = 56|0x100U, /*!< ENET IEEE 1588 timer_2 and TPM2. */ + kDmaRequestMux0TPM2Overflow = 56|0x100U, /*!< ENET IEEE 1588 timer 2 and TPM2. */ + kDmaRequestMux0IEEE1588Timer3 = 57|0x100U, /*!< ENET IEEE 1588_timer_3. */ + kDmaRequestMux0LPUART0Rx = 58|0x100U, /*!< LPUART0 Receive. */ + kDmaRequestMux0LPUART0Tx = 59|0x100U, /*!< LPUART0 Transmit. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MKV10Z16VFM7) || defined(CPU_MKV10Z16VLC7) || defined(CPU_MKV10Z16VLF7) || defined(CPU_MKV10Z32VFM7) || \ + defined(CPU_MKV10Z32VLC7) || defined(CPU_MKV10Z32VLF7) + kDmaRequestMux0Disable = 0|0x100U, /*!< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART 0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART 0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART 1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART 1 transmit complete */ + kDmaRequestMux0Reserved6 = 6|0x100U, /*!< Reserved6 */ + kDmaRequestMux0Reserved7 = 7|0x100U, /*!< Reserved7 */ + kDmaRequestMux0Reserved8 = 8|0x100U, /*!< Reserved8 */ + kDmaRequestMux0Reserved9 = 9|0x100U, /*!< Reserved9 */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0Reserved14 = 14|0x100U, /*!< Reserved14 */ + kDmaRequestMux0Reserved15 = 15|0x100U, /*!< Reserved15 */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 transmit complete */ + kDmaRequestMux0Reserved18 = 18|0x100U, /*!< Reserved18 */ + kDmaRequestMux0Reserved19 = 19|0x100U, /*!< Reserved19 */ + kDmaRequestMux0Reserved20 = 20|0x100U, /*!< Reserved20 */ + kDmaRequestMux0Reserved21 = 21|0x100U, /*!< Reserved21 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0 transmission complete */ + kDmaRequestMux0Reserved23 = 23|0x100U, /*!< Reserved23 */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0Reserved30 = 30|0x100U, /*!< Reserved30 */ + kDmaRequestMux0Reserved31 = 31|0x100U, /*!< Reserved31 */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 channel 1 event (CMP or CAP) */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC 0 conversion complete */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC 1 conversion complete */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0 Output */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1 Output */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0 buffer pointer reaches upper or lower limit */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0Reserved47 = 47|0x100U, /*!< Reserved47 */ + kDmaRequestMux0PDB0 = 48|0x100U, /*!< PDB0 programmable interrupt delay event */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< Always enabled 54 */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< Always enabled 55 */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< Always enabled 56 */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< Always enabled 57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Always enabled 58 */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Always enabled 59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Always enabled 60 */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Always enabled 61 */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Always enabled 62 */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Always enabled 63 */ +#elif defined(CPU_MKV30F128VFM10) || defined(CPU_MKV30F64VFM10) || defined(CPU_MKV30F128VLF10) || defined(CPU_MKV30F64VLF10) || \ + defined(CPU_MKV30F128VLH10) || defined(CPU_MKV30F64VLH10) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0Reserved6 = 6|0x100U, /*!< Reserved6 */ + kDmaRequestMux0Reserved7 = 7|0x100U, /*!< Reserved7 */ + kDmaRequestMux0Reserved8 = 8|0x100U, /*!< Reserved8 */ + kDmaRequestMux0Reserved9 = 9|0x100U, /*!< Reserved9 */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0Reserved16 = 16|0x100U, /*!< Reserved16 */ + kDmaRequestMux0Reserved17 = 17|0x100U, /*!< Reserved17 */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0. */ + kDmaRequestMux0Reserved19 = 19|0x100U, /*!< Reserved19 */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0Reserved26 = 26|0x100U, /*!< Reserved26 */ + kDmaRequestMux0Reserved27 = 27|0x100U, /*!< Reserved27 */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V. */ + kDmaRequestMux0Reserved32 = 32|0x100U, /*!< Reserved32 */ + kDmaRequestMux0Reserved33 = 33|0x100U, /*!< Reserved33 */ + kDmaRequestMux0Reserved34 = 34|0x100U, /*!< Reserved34 */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0Reserved47 = 47|0x100U, /*!< Reserved47 */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0Reserved58 = 58|0x100U, /*!< Reserved58 */ + kDmaRequestMux0Reserved59 = 59|0x100U, /*!< Reserved59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MKV31F128VLH10) || defined(CPU_MKV31F128VLL10) || defined(CPU_MKV31F256VLH12) || defined(CPU_MKV31F256VLL12) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 Transmit. */ + kDmaRequestMux0Reserved8 = 8|0x100U, /*!< Reserved8 */ + kDmaRequestMux0Reserved9 = 9|0x100U, /*!< Reserved9 */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0SPI1 = 16|0x100U, /*!< SPI1 Transmit or Receive. */ + kDmaRequestMux0Reserved17 = 17|0x100U, /*!< Reserved17 */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0. */ + kDmaRequestMux0I2C1 = 19|0x100U, /*!< I2C1. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /*!< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /*!< FTM0 C7V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V. */ + kDmaRequestMux0Reserved32 = 32|0x100U, /*!< Reserved32 */ + kDmaRequestMux0Reserved33 = 33|0x100U, /*!< Reserved33 */ + kDmaRequestMux0Reserved34 = 34|0x100U, /*!< Reserved34 */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0Reserved47 = 47|0x100U, /*!< Reserved47 */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0LPUART0Rx = 58|0x100U, /*!< LPUART0 Receive. */ + kDmaRequestMux0LPUART0Tx = 59|0x100U, /*!< LPUART0 Transmit. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MKV31F512VLH12) || defined(CPU_MKV31F512VLL12) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 Transmit. */ + kDmaRequestMux0Reserved8 = 8|0x100U, /*!< Reserved8 */ + kDmaRequestMux0Reserved9 = 9|0x100U, /*!< Reserved9 */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0SPI1 = 16|0x100U, /*!< SPI1 Transmit or Receive. */ + kDmaRequestMux0Reserved17 = 17|0x100U, /*!< Reserved17 */ + kDmaRequestMux0I2C0 = 18|0x100U, /*!< I2C0. */ + kDmaRequestMux0I2C1 = 19|0x100U, /*!< I2C1. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /*!< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /*!< FTM0 C7V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /*!< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /*!< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /*!< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /*!< FTM2 C1V. */ + kDmaRequestMux0FTM3Channel0 = 32|0x100U, /*!< FTM3 C0V. */ + kDmaRequestMux0FTM3Channel1 = 33|0x100U, /*!< FTM3 C1V. */ + kDmaRequestMux0FTM3Channel2 = 34|0x100U, /*!< FTM3 C2V. */ + kDmaRequestMux0FTM3Channel3 = 35|0x100U, /*!< FTM3 C3V. */ + kDmaRequestMux0FTM3Channel4 = 36|0x100U, /*!< FTM3 C4V. */ + kDmaRequestMux0FTM3Channel5 = 37|0x100U, /*!< FTM3 C5V. */ + kDmaRequestMux0FTM3Channel6 = 38|0x100U, /*!< FTM3 C6V. */ + kDmaRequestMux0FTM3Channel7 = 39|0x100U, /*!< FTM3 C7V. */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /*!< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC0. */ + kDmaRequestMux0DAC1 = 46|0x100U, /*!< DAC1. */ + kDmaRequestMux0Reserved47 = 47|0x100U, /*!< Reserved47 */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0LPUART0Rx = 58|0x100U, /*!< LPUART0 Receive. */ + kDmaRequestMux0LPUART0Tx = 59|0x100U, /*!< LPUART0 Transmit. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#elif defined(CPU_MKV40F128VLH15) || defined(CPU_MKV40F256VLH15) || defined(CPU_MKV40F64VLH15) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMA requests are disabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0Reserved6 = 6|0x100U, /*!< Reserved6 */ + kDmaRequestMux0Reserved7 = 7|0x100U, /*!< Reserved7 */ + kDmaRequestMux0Reserved8 = 8|0x100U, /*!< Reserved8 */ + kDmaRequestMux0Reserved9 = 9|0x100U, /*!< Reserved9 */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0CAN0Rx = 14|0x100U, /*!< CAN0 reach receiever mailbox level */ + kDmaRequestMux0Reserved15 = 15|0x100U, /*!< Reserved15 */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI transmit complete */ + kDmaRequestMux0XBARAOut0 = 18|0x100U, /*!< XBARA output 0 */ + kDmaRequestMux0XBARAOut1 = 19|0x100U, /*!< XBARA output 1 */ + kDmaRequestMux0XBARAOut2 = 20|0x100U, /*!< XBARA output 2 */ + kDmaRequestMux0XBARAOut3 = 21|0x100U, /*!< XBARA output 3 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C transmission complete */ + kDmaRequestMux0Reserved23 = 23|0x100U, /*!< Reserved23 */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0CMP0 = 34|0x100U, /*!< CMP0 output */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADCA = 40|0x100U, /*!< ADC converter A end of scan */ + kDmaRequestMux0ADCB = 41|0x100U, /*!< ADC converter B end of scan */ + kDmaRequestMux0CMP1 = 42|0x100U, /*!< CMP1 output */ + kDmaRequestMux0CMP2 = 43|0x100U, /*!< CMP2 output */ + kDmaRequestMux0CMP3 = 44|0x100U, /*!< CMP3 output */ + kDmaRequestMux0Reserved45 = 45|0x100U, /*!< Reserved45 */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0PDB0 = 47|0x100U, /*!< PDB0 channel 0 output trigger */ + kDmaRequestMux0PDB1 = 48|0x100U, /*!< PDB1 channel 0 output trigger */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Slot 58 is always enabled */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Slot 59 is always enabled */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Slot 60 is always enabled */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Slot 61 is always enabled */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Slot 62 is always enabled */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Slot 63 is always enabled */ +#elif defined(CPU_MKV40F128VLL15) || defined(CPU_MKV40F256VLL15) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMA requests are disabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0Reserved6 = 6|0x100U, /*!< Reserved6 */ + kDmaRequestMux0Reserved7 = 7|0x100U, /*!< Reserved7 */ + kDmaRequestMux0Reserved8 = 8|0x100U, /*!< Reserved8 */ + kDmaRequestMux0Reserved9 = 9|0x100U, /*!< Reserved9 */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0CAN0Rx = 14|0x100U, /*!< CAN0 reach receiever mailbox level */ + kDmaRequestMux0CAN1Rx = 15|0x100U, /*!< CAN1 reach receiever mailbox level */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI transmit complete */ + kDmaRequestMux0XBARAOut0 = 18|0x100U, /*!< XBARA output 0 */ + kDmaRequestMux0XBARAOut1 = 19|0x100U, /*!< XBARA output 1 */ + kDmaRequestMux0XBARAOut2 = 20|0x100U, /*!< XBARA output 2 */ + kDmaRequestMux0XBARAOut3 = 21|0x100U, /*!< XBARA output 3 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C transmission complete */ + kDmaRequestMux0Reserved23 = 23|0x100U, /*!< Reserved23 */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0CMP0 = 34|0x100U, /*!< CMP0 output */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0FTM3Channel0 = 36|0x100U, /*!< FTM3 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel1 = 37|0x100U, /*!< FTM3 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel2 = 38|0x100U, /*!< FTM3 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel3 = 39|0x100U, /*!< FTM3 channel 3 event (CMP or CAP) */ + kDmaRequestMux0ADCA = 40|0x100U, /*!< ADC converter A end of scan */ + kDmaRequestMux0ADCB = 41|0x100U, /*!< ADC converter B end of scan */ + kDmaRequestMux0CMP1 = 42|0x100U, /*!< CMP1 output */ + kDmaRequestMux0CMP2 = 43|0x100U, /*!< CMP2 output */ + kDmaRequestMux0CMP3 = 44|0x100U, /*!< CMP3 output */ + kDmaRequestMux0Reserved45 = 45|0x100U, /*!< Reserved45 */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0PDB0 = 47|0x100U, /*!< PDB0 channel 0 output trigger */ + kDmaRequestMux0PDB1 = 48|0x100U, /*!< PDB1 channel 0 output trigger */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0FTM3Channel4 = 54|0x100U, /*!< FTM3 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel5 = 55|0x100U, /*!< FTM3 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel6 = 56|0x100U, /*!< FTM3 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel7 = 57|0x100U, /*!< FTM3 channel 7 event (CMP or CAP) */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Slot 58 is always enabled */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Slot 59 is always enabled */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Slot 60 is always enabled */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Slot 61 is always enabled */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Slot 62 is always enabled */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Slot 63 is always enabled */ +#elif defined(CPU_MKV43F128VLH15) || defined(CPU_MKV43F64VLH15) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMA requests are disabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0PWMA0WR = 6|0x100U, /*!< PWMA submodule 0 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA1WR = 7|0x100U, /*!< PWMA submodule 1 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA2WR = 8|0x100U, /*!< PWMA submodule 2 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA3WR = 9|0x100U, /*!< PWMA submodule 3 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA0CP = 10|0x100U, /*!< PWMA submodule 0 read request on capture FIFO marker */ + kDmaRequestMux0PWMA1CP = 11|0x100U, /*!< PWMA submodule 1 read request on capture FIFO marker */ + kDmaRequestMux0PWMA2CP = 12|0x100U, /*!< PWMA submodule 2 read request on capture FIFO marker */ + kDmaRequestMux0PWMA3CP = 13|0x100U, /*!< PWMA submodule 3 read request on capture FIFO marker */ + kDmaRequestMux0CAN0Rx = 14|0x100U, /*!< CAN0 reach receiever mailbox level */ + kDmaRequestMux0Reserved15 = 15|0x100U, /*!< Reserved15 */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI transmit complete */ + kDmaRequestMux0XBARAOut0 = 18|0x100U, /*!< XBARA output 0 */ + kDmaRequestMux0XBARAOut1 = 19|0x100U, /*!< XBARA output 1 */ + kDmaRequestMux0XBARAOut2 = 20|0x100U, /*!< XBARA output 2 */ + kDmaRequestMux0XBARAOut3 = 21|0x100U, /*!< XBARA output 3 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C transmission complete */ + kDmaRequestMux0Reserved23 = 23|0x100U, /*!< Reserved23 */ + kDmaRequestMux0Reserved24 = 24|0x100U, /*!< Reserved24 */ + kDmaRequestMux0Reserved25 = 25|0x100U, /*!< Reserved25 */ + kDmaRequestMux0Reserved26 = 26|0x100U, /*!< Reserved26 */ + kDmaRequestMux0Reserved27 = 27|0x100U, /*!< Reserved27 */ + kDmaRequestMux0Reserved28 = 28|0x100U, /*!< Reserved28 */ + kDmaRequestMux0Reserved29 = 29|0x100U, /*!< Reserved29 */ + kDmaRequestMux0Reserved30 = 30|0x100U, /*!< Reserved30 */ + kDmaRequestMux0Reserved31 = 31|0x100U, /*!< Reserved31 */ + kDmaRequestMux0Reserved32 = 32|0x100U, /*!< Reserved32 */ + kDmaRequestMux0Reserved33 = 33|0x100U, /*!< Reserved33 */ + kDmaRequestMux0CMP0 = 34|0x100U, /*!< CMP0 output */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADCA = 40|0x100U, /*!< ADC converter A end of scan */ + kDmaRequestMux0ADCB = 41|0x100U, /*!< ADC converter B end of scan */ + kDmaRequestMux0CMP1 = 42|0x100U, /*!< CMP1 output */ + kDmaRequestMux0CMP2 = 43|0x100U, /*!< CMP2 output */ + kDmaRequestMux0CMP3 = 44|0x100U, /*!< CMP3 output */ + kDmaRequestMux0Reserved45 = 45|0x100U, /*!< Reserved45 */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0PDB0 = 47|0x100U, /*!< PDB0 channel 0 output trigger */ + kDmaRequestMux0PDB1 = 48|0x100U, /*!< PDB1 channel 0 output trigger */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Slot 58 is always enabled */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Slot 59 is always enabled */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Slot 60 is always enabled */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Slot 61 is always enabled */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Slot 62 is always enabled */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Slot 63 is always enabled */ +#elif defined(CPU_MKV43F128VLL15) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMA requests are disabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0PWMA0WR = 6|0x100U, /*!< PWMA submodule 0 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA1WR = 7|0x100U, /*!< PWMA submodule 1 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA2WR = 8|0x100U, /*!< PWMA submodule 2 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA3WR = 9|0x100U, /*!< PWMA submodule 3 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA0CP = 10|0x100U, /*!< PWMA submodule 0 read request on capture FIFO marker */ + kDmaRequestMux0PWMA1CP = 11|0x100U, /*!< PWMA submodule 1 read request on capture FIFO marker */ + kDmaRequestMux0PWMA2CP = 12|0x100U, /*!< PWMA submodule 2 read request on capture FIFO marker */ + kDmaRequestMux0PWMA3CP = 13|0x100U, /*!< PWMA submodule 3 read request on capture FIFO marker */ + kDmaRequestMux0CAN0Rx = 14|0x100U, /*!< CAN0 reach receiever mailbox level */ + kDmaRequestMux0CAN1Rx = 15|0x100U, /*!< CAN1 reach receiever mailbox level */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI transmit complete */ + kDmaRequestMux0XBARAOut0 = 18|0x100U, /*!< XBARA output 0 */ + kDmaRequestMux0XBARAOut1 = 19|0x100U, /*!< XBARA output 1 */ + kDmaRequestMux0XBARAOut2 = 20|0x100U, /*!< XBARA output 2 */ + kDmaRequestMux0XBARAOut3 = 21|0x100U, /*!< XBARA output 3 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C transmission complete */ + kDmaRequestMux0Reserved23 = 23|0x100U, /*!< Reserved23 */ + kDmaRequestMux0Reserved24 = 24|0x100U, /*!< Reserved24 */ + kDmaRequestMux0Reserved25 = 25|0x100U, /*!< Reserved25 */ + kDmaRequestMux0Reserved26 = 26|0x100U, /*!< Reserved26 */ + kDmaRequestMux0Reserved27 = 27|0x100U, /*!< Reserved27 */ + kDmaRequestMux0Reserved28 = 28|0x100U, /*!< Reserved28 */ + kDmaRequestMux0Reserved29 = 29|0x100U, /*!< Reserved29 */ + kDmaRequestMux0Reserved30 = 30|0x100U, /*!< Reserved30 */ + kDmaRequestMux0Reserved31 = 31|0x100U, /*!< Reserved31 */ + kDmaRequestMux0Reserved32 = 32|0x100U, /*!< Reserved32 */ + kDmaRequestMux0Reserved33 = 33|0x100U, /*!< Reserved33 */ + kDmaRequestMux0CMP0 = 34|0x100U, /*!< CMP0 output */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADCA = 40|0x100U, /*!< ADC converter A end of scan */ + kDmaRequestMux0ADCB = 41|0x100U, /*!< ADC converter B end of scan */ + kDmaRequestMux0CMP1 = 42|0x100U, /*!< CMP1 output */ + kDmaRequestMux0CMP2 = 43|0x100U, /*!< CMP2 output */ + kDmaRequestMux0CMP3 = 44|0x100U, /*!< CMP3 output */ + kDmaRequestMux0Reserved45 = 45|0x100U, /*!< Reserved45 */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0PDB0 = 47|0x100U, /*!< PDB0 channel 0 output trigger */ + kDmaRequestMux0PDB1 = 48|0x100U, /*!< PDB1 channel 0 output trigger */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Slot 58 is always enabled */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Slot 59 is always enabled */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Slot 60 is always enabled */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Slot 61 is always enabled */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Slot 62 is always enabled */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Slot 63 is always enabled */ +#elif defined(CPU_MKV44F128VLH15) || defined(CPU_MKV44F128VLL15) || defined(CPU_MKV44F64VLH15) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMA requests are disabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0PWMA0WR = 6|0x100U, /*!< PWMA submodule 0 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA1WR = 7|0x100U, /*!< PWMA submodule 1 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA2WR = 8|0x100U, /*!< PWMA submodule 2 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA3WR = 9|0x100U, /*!< PWMA submodule 3 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA0CP = 10|0x100U, /*!< PWMA submodule 0 read request on capture FIFO marker */ + kDmaRequestMux0PWMA1CP = 11|0x100U, /*!< PWMA submodule 1 read request on capture FIFO marker */ + kDmaRequestMux0PWMA2CP = 12|0x100U, /*!< PWMA submodule 2 read request on capture FIFO marker */ + kDmaRequestMux0PWMA3CP = 13|0x100U, /*!< PWMA submodule 3 read request on capture FIFO marker */ + kDmaRequestMux0CAN0Rx = 14|0x100U, /*!< CAN0 reach receiever mailbox level */ + kDmaRequestMux0Reserved15 = 15|0x100U, /*!< Reserved15 */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI transmit complete */ + kDmaRequestMux0XBARAOut0 = 18|0x100U, /*!< XBARA output 0 */ + kDmaRequestMux0XBARAOut1 = 19|0x100U, /*!< XBARA output 1 */ + kDmaRequestMux0XBARAOut2 = 20|0x100U, /*!< XBARA output 2 */ + kDmaRequestMux0XBARAOut3 = 21|0x100U, /*!< XBARA output 3 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C transmission complete */ + kDmaRequestMux0Reserved23 = 23|0x100U, /*!< Reserved23 */ + kDmaRequestMux0Reserved24 = 24|0x100U, /*!< Reserved24 */ + kDmaRequestMux0Reserved25 = 25|0x100U, /*!< Reserved25 */ + kDmaRequestMux0Reserved26 = 26|0x100U, /*!< Reserved26 */ + kDmaRequestMux0Reserved27 = 27|0x100U, /*!< Reserved27 */ + kDmaRequestMux0Reserved28 = 28|0x100U, /*!< Reserved28 */ + kDmaRequestMux0Reserved29 = 29|0x100U, /*!< Reserved29 */ + kDmaRequestMux0Reserved30 = 30|0x100U, /*!< Reserved30 */ + kDmaRequestMux0Reserved31 = 31|0x100U, /*!< Reserved31 */ + kDmaRequestMux0Reserved32 = 32|0x100U, /*!< Reserved32 */ + kDmaRequestMux0Reserved33 = 33|0x100U, /*!< Reserved33 */ + kDmaRequestMux0CMP0 = 34|0x100U, /*!< CMP0 output */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADCA = 40|0x100U, /*!< ADC converter A end of scan */ + kDmaRequestMux0ADCB = 41|0x100U, /*!< ADC converter B end of scan */ + kDmaRequestMux0CMP1 = 42|0x100U, /*!< CMP1 output */ + kDmaRequestMux0CMP2 = 43|0x100U, /*!< CMP2 output */ + kDmaRequestMux0CMP3 = 44|0x100U, /*!< CMP3 output */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC buffer pointer reaches upper or lower limit */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0PDB0 = 47|0x100U, /*!< PDB0 channel 0 output trigger */ + kDmaRequestMux0PDB1 = 48|0x100U, /*!< PDB1 channel 0 output trigger */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Slot 58 is always enabled */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Slot 59 is always enabled */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Slot 60 is always enabled */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Slot 61 is always enabled */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Slot 62 is always enabled */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Slot 63 is always enabled */ +#elif defined(CPU_MKV45F128VLH15) || defined(CPU_MKV45F256VLH15) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMA requests are disabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0PWMA0WR = 6|0x100U, /*!< PWMA submodule 0 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA1WR = 7|0x100U, /*!< PWMA submodule 1 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA2WR = 8|0x100U, /*!< PWMA submodule 2 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA3WR = 9|0x100U, /*!< PWMA submodule 3 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA0CP = 10|0x100U, /*!< PWMA submodule 0 read request on capture FIFO marker */ + kDmaRequestMux0PWMA1CP = 11|0x100U, /*!< PWMA submodule 1 read request on capture FIFO marker */ + kDmaRequestMux0PWMA2CP = 12|0x100U, /*!< PWMA submodule 2 read request on capture FIFO marker */ + kDmaRequestMux0PWMA3CP = 13|0x100U, /*!< PWMA submodule 3 read request on capture FIFO marker */ + kDmaRequestMux0CAN0Rx = 14|0x100U, /*!< CAN0 reach receiever mailbox level */ + kDmaRequestMux0Reserved15 = 15|0x100U, /*!< Reserved15 */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI transmit complete */ + kDmaRequestMux0XBARAOut0 = 18|0x100U, /*!< XBARA output 0 */ + kDmaRequestMux0XBARAOut1 = 19|0x100U, /*!< XBARA output 1 */ + kDmaRequestMux0XBARAOut2 = 20|0x100U, /*!< XBARA output 2 */ + kDmaRequestMux0XBARAOut3 = 21|0x100U, /*!< XBARA output 3 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C transmission complete */ + kDmaRequestMux0Reserved23 = 23|0x100U, /*!< Reserved23 */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0CMP0 = 34|0x100U, /*!< CMP0 output */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADCA = 40|0x100U, /*!< ADC converter A end of scan */ + kDmaRequestMux0ADCB = 41|0x100U, /*!< ADC converter B end of scan */ + kDmaRequestMux0CMP1 = 42|0x100U, /*!< CMP1 output */ + kDmaRequestMux0CMP2 = 43|0x100U, /*!< CMP2 output */ + kDmaRequestMux0CMP3 = 44|0x100U, /*!< CMP3 output */ + kDmaRequestMux0Reserved45 = 45|0x100U, /*!< Reserved45 */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0PDB0 = 47|0x100U, /*!< PDB0 channel 0 output trigger */ + kDmaRequestMux0PDB1 = 48|0x100U, /*!< PDB1 channel 0 output trigger */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Slot 58 is always enabled */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Slot 59 is always enabled */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Slot 60 is always enabled */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Slot 61 is always enabled */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Slot 62 is always enabled */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Slot 63 is always enabled */ +#elif defined(CPU_MKV45F128VLL15) || defined(CPU_MKV45F256VLL15) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMA requests are disabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0PWMA0WR = 6|0x100U, /*!< PWMA submodule 0 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA1WR = 7|0x100U, /*!< PWMA submodule 1 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA2WR = 8|0x100U, /*!< PWMA submodule 2 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA3WR = 9|0x100U, /*!< PWMA submodule 3 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA0CP = 10|0x100U, /*!< PWMA submodule 0 read request on capture FIFO marker */ + kDmaRequestMux0PWMA1CP = 11|0x100U, /*!< PWMA submodule 1 read request on capture FIFO marker */ + kDmaRequestMux0PWMA2CP = 12|0x100U, /*!< PWMA submodule 2 read request on capture FIFO marker */ + kDmaRequestMux0PWMA3CP = 13|0x100U, /*!< PWMA submodule 3 read request on capture FIFO marker */ + kDmaRequestMux0CAN0Rx = 14|0x100U, /*!< CAN0 reach receiever mailbox level */ + kDmaRequestMux0CAN1Rx = 15|0x100U, /*!< CAN1 reach receiever mailbox level */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI transmit complete */ + kDmaRequestMux0XBARAOut0 = 18|0x100U, /*!< XBARA output 0 */ + kDmaRequestMux0XBARAOut1 = 19|0x100U, /*!< XBARA output 1 */ + kDmaRequestMux0XBARAOut2 = 20|0x100U, /*!< XBARA output 2 */ + kDmaRequestMux0XBARAOut3 = 21|0x100U, /*!< XBARA output 3 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C transmission complete */ + kDmaRequestMux0Reserved23 = 23|0x100U, /*!< Reserved23 */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0CMP0 = 34|0x100U, /*!< CMP0 output */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0FTM3Channel0 = 36|0x100U, /*!< FTM3 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel1 = 37|0x100U, /*!< FTM3 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel2 = 38|0x100U, /*!< FTM3 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel3 = 39|0x100U, /*!< FTM3 channel 3 event (CMP or CAP) */ + kDmaRequestMux0ADCA = 40|0x100U, /*!< ADC converter A end of scan */ + kDmaRequestMux0ADCB = 41|0x100U, /*!< ADC converter B end of scan */ + kDmaRequestMux0CMP1 = 42|0x100U, /*!< CMP1 output */ + kDmaRequestMux0CMP2 = 43|0x100U, /*!< CMP2 output */ + kDmaRequestMux0CMP3 = 44|0x100U, /*!< CMP3 output */ + kDmaRequestMux0Reserved45 = 45|0x100U, /*!< Reserved45 */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0PDB0 = 47|0x100U, /*!< PDB0 channel 0 output trigger */ + kDmaRequestMux0PDB1 = 48|0x100U, /*!< PDB1 channel 0 output trigger */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0FTM3Channel4 = 54|0x100U, /*!< FTM3 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel5 = 55|0x100U, /*!< FTM3 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel6 = 56|0x100U, /*!< FTM3 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel7 = 57|0x100U, /*!< FTM3 channel 7 event (CMP or CAP) */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Slot 58 is always enabled */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Slot 59 is always enabled */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Slot 60 is always enabled */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Slot 61 is always enabled */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Slot 62 is always enabled */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Slot 63 is always enabled */ +#elif defined(CPU_MKV46F128VLH15) || defined(CPU_MKV46F256VLH15) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMA requests are disabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0PWMA0WR = 6|0x100U, /*!< PWMA submodule 0 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA1WR = 7|0x100U, /*!< PWMA submodule 1 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA2WR = 8|0x100U, /*!< PWMA submodule 2 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA3WR = 9|0x100U, /*!< PWMA submodule 3 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA0CP = 10|0x100U, /*!< PWMA submodule 0 read request on capture FIFO marker */ + kDmaRequestMux0PWMA1CP = 11|0x100U, /*!< PWMA submodule 1 read request on capture FIFO marker */ + kDmaRequestMux0PWMA2CP = 12|0x100U, /*!< PWMA submodule 2 read request on capture FIFO marker */ + kDmaRequestMux0PWMA3CP = 13|0x100U, /*!< PWMA submodule 3 read request on capture FIFO marker */ + kDmaRequestMux0CAN0Rx = 14|0x100U, /*!< CAN0 reach receiever mailbox level */ + kDmaRequestMux0CAN1Rx = 15|0x100U, /*!< CAN1 reach receiever mailbox level */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI transmit complete */ + kDmaRequestMux0XBARAOut0 = 18|0x100U, /*!< XBARA output 0 */ + kDmaRequestMux0XBARAOut1 = 19|0x100U, /*!< XBARA output 1 */ + kDmaRequestMux0XBARAOut2 = 20|0x100U, /*!< XBARA output 2 */ + kDmaRequestMux0XBARAOut3 = 21|0x100U, /*!< XBARA output 3 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C transmission complete */ + kDmaRequestMux0Reserved23 = 23|0x100U, /*!< Reserved23 */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0CMP0 = 34|0x100U, /*!< CMP0 output */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADCA = 40|0x100U, /*!< ADC converter A end of scan */ + kDmaRequestMux0ADCB = 41|0x100U, /*!< ADC converter B end of scan */ + kDmaRequestMux0CMP1 = 42|0x100U, /*!< CMP1 output */ + kDmaRequestMux0CMP2 = 43|0x100U, /*!< CMP2 output */ + kDmaRequestMux0CMP3 = 44|0x100U, /*!< CMP3 output */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC buffer pointer reaches upper or lower limit */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0PDB0 = 47|0x100U, /*!< PDB0 channel 0 output trigger */ + kDmaRequestMux0PDB1 = 48|0x100U, /*!< PDB1 channel 0 output trigger */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0Reserved54 = 54|0x100U, /*!< Reserved54 */ + kDmaRequestMux0Reserved55 = 55|0x100U, /*!< Reserved55 */ + kDmaRequestMux0Reserved56 = 56|0x100U, /*!< Reserved56 */ + kDmaRequestMux0Reserved57 = 57|0x100U, /*!< Reserved57 */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Slot 58 is always enabled */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Slot 59 is always enabled */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Slot 60 is always enabled */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Slot 61 is always enabled */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Slot 62 is always enabled */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Slot 63 is always enabled */ +#elif defined(CPU_MKV46F128VLL15) || defined(CPU_MKV46F256VLL15) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMA requests are disabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 receive complete */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 transmit complete */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 receive complete */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 transmit complete */ + kDmaRequestMux0PWMA0WR = 6|0x100U, /*!< PWMA submodule 0 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA1WR = 7|0x100U, /*!< PWMA submodule 1 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA2WR = 8|0x100U, /*!< PWMA submodule 2 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA3WR = 9|0x100U, /*!< PWMA submodule 3 write request on beginning of reload cycle */ + kDmaRequestMux0PWMA0CP = 10|0x100U, /*!< PWMA submodule 0 read request on capture FIFO marker */ + kDmaRequestMux0PWMA1CP = 11|0x100U, /*!< PWMA submodule 1 read request on capture FIFO marker */ + kDmaRequestMux0PWMA2CP = 12|0x100U, /*!< PWMA submodule 2 read request on capture FIFO marker */ + kDmaRequestMux0PWMA3CP = 13|0x100U, /*!< PWMA submodule 3 read request on capture FIFO marker */ + kDmaRequestMux0CAN0Rx = 14|0x100U, /*!< CAN0 reach receiever mailbox level */ + kDmaRequestMux0CAN1Rx = 15|0x100U, /*!< CAN1 reach receiever mailbox level */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI receive complete */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI transmit complete */ + kDmaRequestMux0XBARAOut0 = 18|0x100U, /*!< XBARA output 0 */ + kDmaRequestMux0XBARAOut1 = 19|0x100U, /*!< XBARA output 1 */ + kDmaRequestMux0XBARAOut2 = 20|0x100U, /*!< XBARA output 2 */ + kDmaRequestMux0XBARAOut3 = 21|0x100U, /*!< XBARA output 3 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C transmission complete */ + kDmaRequestMux0Reserved23 = 23|0x100U, /*!< Reserved23 */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 channel 3 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 channel 7 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 channel 1 event (CMP or CAP) */ + kDmaRequestMux0CMP0 = 34|0x100U, /*!< CMP0 output */ + kDmaRequestMux0Reserved35 = 35|0x100U, /*!< Reserved35 */ + kDmaRequestMux0FTM3Channel0 = 36|0x100U, /*!< FTM3 channel 0 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel1 = 37|0x100U, /*!< FTM3 channel 1 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel2 = 38|0x100U, /*!< FTM3 channel 2 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel3 = 39|0x100U, /*!< FTM3 channel 3 event (CMP or CAP) */ + kDmaRequestMux0ADCA = 40|0x100U, /*!< ADC converter A end of scan */ + kDmaRequestMux0ADCB = 41|0x100U, /*!< ADC converter B end of scan */ + kDmaRequestMux0CMP1 = 42|0x100U, /*!< CMP1 output */ + kDmaRequestMux0CMP2 = 43|0x100U, /*!< CMP2 output */ + kDmaRequestMux0CMP3 = 44|0x100U, /*!< CMP3 output */ + kDmaRequestMux0DAC0 = 45|0x100U, /*!< DAC buffer pointer reaches upper or lower limit */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0PDB0 = 47|0x100U, /*!< PDB0 channel 0 output trigger */ + kDmaRequestMux0PDB1 = 48|0x100U, /*!< PDB1 channel 0 output trigger */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0FTM3Channel4 = 54|0x100U, /*!< FTM3 channel 4 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel5 = 55|0x100U, /*!< FTM3 channel 5 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel6 = 56|0x100U, /*!< FTM3 channel 6 event (CMP or CAP) */ + kDmaRequestMux0FTM3Channel7 = 57|0x100U, /*!< FTM3 channel 7 event (CMP or CAP) */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< Slot 58 is always enabled */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< Slot 59 is always enabled */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< Slot 60 is always enabled */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< Slot 61 is always enabled */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< Slot 62 is always enabled */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< Slot 63 is always enabled */ +#elif defined(MCU_MKL28T7) + kDmaRequestMux0Disable = 0|0x300U, /*!< DMA requests are disabled. */ + kDmaRequestMux0FLEXIOShifter0 = 1|0x300U, /*!< FLEXIO0 shifter0 */ + kDmaRequestMux0FLEXIOShifter1 = 2|0x300U, /*!< FLEXIO0 shifter1 */ + kDmaRequestMux0FLEXIOShifter2 = 3|0x300U, /*!< FLEXIO0 shifter2 */ + kDmaRequestMux0FLEXIOShifter3 = 4|0x300U, /*!< FLEXIO0 shifter3 */ + kDmaRequestMux0FLEXIOShifter4 = 5|0x300U, /*!< FLEXIO0 shifter4 */ + kDmaRequestMux0FLEXIOShifter5 = 6|0x300U, /*!< FLEXIO0 shifter5 */ + kDmaRequestMux0FLEXIOShifter6 = 7|0x300U, /*!< FLEXIO0 shifter6 */ + kDmaRequestMux0FLEXIOShifter7 = 8|0x300U, /*!< FLEXIO0 shifter7 */ + kDmaRequestMux0LPI2C0Rx = 9|0x300U, /*!< LPI2C0 receiver complete */ + kDmaRequestMux0LPI2C0Tx = 10|0x300U, /*!< LPI2C0 transmit complete */ + kDmaRequestMux0LPI2C1Rx = 11|0x300U, /*!< LPI2C1 receiver complete */ + kDmaRequestMux0LPI2C1Tx = 12|0x300U, /*!< LPI2C1 receiver complete */ + kDmaRequestMux0LPI2C2Rx = 13|0x300U, /*!< LPI2C2 receiver complete */ + kDmaRequestMux0LPI2C2Tx = 14|0x300U, /*!< LPI2C2 receiver complete */ + kDmaRequestMux0LPUART0Rx = 15|0x300U, /*!< LPUART0 receiver complete */ + kDmaRequestMux0LPUART0Tx = 16|0x300U, /*!< LPUART0 transmit complete */ + kDmaRequestMux0LPUART1Rx = 17|0x300U, /*!< LPUART1 receiver complete */ + kDmaRequestMux0LPUART1Tx = 18|0x300U, /*!< LPUART1 transmit complete */ + kDmaRequestMux0LPUART2Rx = 19|0x300U, /*!< LPUART2 receiver complete */ + kDmaRequestMux0LPUART2Tx = 20|0x300U, /*!< LPUART2 transmit complete */ + kDmaRequestMux0LPSPI0Rx = 21|0x300U, /*!< LPSPI0 receiver complete */ + kDmaRequestMux0LPSPI0Tx = 22|0x300U, /*!< LPSPI0 transmit complete */ + kDmaRequestMux0LPSPI1Rx = 23|0x300U, /*!< LPSPI1 receiver complete */ + kDmaRequestMux0LPSPI1Tx = 24|0x300U, /*!< LPSPI1 transmit complete */ + kDmaRequestMux0LPSPI2Rx = 25|0x300U, /*!< LPSPI2 receiver complete */ + kDmaRequestMux0LPSPI2Tx = 26|0x300U, /*!< LPSPI2 transmit complete */ + kDmaRequestMux0TPM0Channel0 = 27|0x300U, /*!< TPM0 channel 0 event */ + kDmaRequestMux0TPM0Channel1 = 28|0x300U, /*!< TPM0 channel 1 event */ + kDmaRequestMux0TPM0Channel2 = 29|0x300U, /*!< TPM0 channel 2 event */ + kDmaRequestMux0TPM0Channel3 = 30|0x300U, /*!< TPM0 channel 3 event */ + kDmaRequestMux0TPM0Channel4 = 31|0x300U, /*!< TPM0 channel 4 event */ + kDmaRequestMux0TPM0Channel5 = 32|0x300U, /*!< TPM0 channel 5 event */ + kDmaRequestMux0Reserved33 = 33|0x300U, /*!< Reserved33 */ + kDmaRequestMux0Reserved34 = 34|0x300U, /*!< Reserved34 */ + kDmaRequestMux0TPM0Overflow = 35|0x300U, /*!< TPM0 overflow event */ + kDmaRequestMux0TPM1Channel0 = 36|0x300U, /*!< TPM1 channel 0 event */ + kDmaRequestMux0TPM1Channel1 = 37|0x300U, /*!< TPM1 channel 1 event */ + kDmaRequestMux0TPM1Overflow = 38|0x300U, /*!< TPM1 overflow event */ + kDmaRequestMux0TPM2Channel0 = 39|0x300U, /*!< TPM2 channel 0 event */ + kDmaRequestMux0TPM2Channel1 = 40|0x300U, /*!< TPM2 channel 1 event */ + kDmaRequestMux0TPM2Overflow = 41|0x300U, /*!< TPM2 overflow event */ + kDmaRequestMux0PORTRPM = 42|0x300U, /*!< PORTRPM */ + kDmaRequestMux0EMVSIMRx = 43|0x300U, /*!< EMWSIM receive complete */ + kDmaRequestMux0EMVSIMTx = 44|0x300U, /*!< EMWSIM transmit complete */ + kDmaRequestMux0I2S0Rx = 45|0x300U, /*!< I2S0 receive */ + kDmaRequestMux0I2S0Tx = 46|0x300U, /*!< I2S0 transmit */ + kDmaRequestMux0PORTA = 47|0x300U, /*!< PORTA rising, falling or both edges */ + kDmaRequestMux0PORTB = 48|0x300U, /*!< PORTB rising, falling or both edges */ + kDmaRequestMux0PortC = 49|0x300U, /*!< PORTC rising, falling or both edges */ + kDmaRequestMux0PortD = 50|0x300U, /*!< PORTD rising, falling or both edges */ + kDmaRequestMux0PortE = 51|0x300U, /*!< PORTE rising, falling or both edges */ + kDmaRequestMux0ADC0 = 52|0x300U, /*!< ADC0 */ + kDmaRequestMux0Reserved53 = 53|0x300U, /*!< Reserved53 */ + kDmaRequestMux0DAC0 = 54|0x300U, /*!< DAC0 */ + kDmaRequestMux0Reserved55 = 55|0x300U, /*!< Reserved55 */ + kDmaRequestMux0CMP0 = 56|0x300U, /*!< CMP0 */ + kDmaRequestMux0CMP1 = 57|0x300U, /*!< CMP1 */ + kDmaRequestMux0Reserved58 = 58|0x300U, /*!< Reserved58 */ + kDmaRequestMux0Reserved59 = 59|0x300U, /*!< Reserved59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x300U, /*!< Slot 60 is always enabled */ + kDmaRequestMux0AlwaysOn61 = 61|0x300U, /*!< Slot 61 is always enabled */ + kDmaRequestMux0AlwaysOn62 = 62|0x300U, /*!< Slot 62 is always enabled */ + kDmaRequestMux0AlwaysOn63 = 63|0x300U, /*!< Slot 63 is always enabled */ +#elif defined(CPU_MKW21D256VHA5) || defined(CPU_MKW21D512VHA5) || defined(CPU_MKW22D512VHA5) || defined(CPU_MKW24D512VHA5) + kDmaRequestMux0Disable = 0|0x100U, /*!< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /*!< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /*!< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /*!< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /*!< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /*!< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /*!< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /*!< UART2 Transmit. */ + kDmaRequestMux0Reserved8 = 8|0x100U, /*!< Reserved8 */ + kDmaRequestMux0Reserved9 = 9|0x100U, /*!< Reserved9 */ + kDmaRequestMux0Reserved10 = 10|0x100U, /*!< Reserved10 */ + kDmaRequestMux0Reserved11 = 11|0x100U, /*!< Reserved11 */ + kDmaRequestMux0Reserved12 = 12|0x100U, /*!< Reserved12 */ + kDmaRequestMux0Reserved13 = 13|0x100U, /*!< Reserved13 */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /*!< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /*!< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /*!< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /*!< SPI0 Transmit. */ + kDmaRequestMux0SPI1Rx = 18|0x100U, /*!< SPI1 Receive. */ + kDmaRequestMux0SPI1Tx = 19|0x100U, /*!< SPI1 Transmit. */ + kDmaRequestMux0Reserved20 = 20|0x100U, /*!< Reserved20 */ + kDmaRequestMux0Reserved21 = 21|0x100U, /*!< Reserved21 */ + kDmaRequestMux0I2C0 = 22|0x100U, /*!< I2C0. */ + kDmaRequestMux0I2C1 = 23|0x100U, /*!< I2C1. */ + kDmaRequestMux0FTM0Channel0 = 24|0x100U, /*!< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 25|0x100U, /*!< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 26|0x100U, /*!< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 27|0x100U, /*!< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 28|0x100U, /*!< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 29|0x100U, /*!< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 30|0x100U, /*!< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 31|0x100U, /*!< FTM0 C7V. */ + kDmaRequestMux0FTM1Channel0 = 32|0x100U, /*!< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 33|0x100U, /*!< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 34|0x100U, /*!< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 35|0x100U, /*!< FTM2 C1V. */ + kDmaRequestMux0Reserved36 = 36|0x100U, /*!< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /*!< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /*!< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /*!< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /*!< ADC0. */ + kDmaRequestMux0Reserved41 = 41|0x100U, /*!< Reserved41 */ + kDmaRequestMux0CMP0 = 42|0x100U, /*!< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /*!< CMP1. */ + kDmaRequestMux0Reserved44 = 44|0x100U, /*!< Reserved44 */ + kDmaRequestMux0Reserved45 = 45|0x100U, /*!< Reserved45 */ + kDmaRequestMux0Reserved46 = 46|0x100U, /*!< Reserved46 */ + kDmaRequestMux0CMT = 47|0x100U, /*!< CMT. */ + kDmaRequestMux0PDB = 48|0x100U, /*!< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /*!< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /*!< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /*!< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /*!< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /*!< PTE. */ + kDmaRequestMux0AlwaysOn54 = 54|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn55 = 55|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn56 = 56|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn57 = 57|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /*!< DMAMUX Always Enabled_slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /*!< DMAMUX Always Enabled_slot. */ +#else + #error "No valid CPU defined!" +#endif +} dma_request_source_t; + +/* @} */ + +#endif /* __FSL_EDMA_REQUEST_H__ */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_enc_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_enc_driver.h new file mode 100755 index 0000000..bf3249a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_enc_driver.h @@ -0,0 +1,311 @@ +/******************************************************************************* +* +* Copyright [2014-]2014 Freescale Semiconductor, Inc. + +* +* This software is owned or controlled by Freescale Semiconductor. +* Use of this software is governed by the Freescale License +* distributed with this Material. +* See the LICENSE file distributed for more details. +* +* +*******************************************************************************/ + +#ifndef __FSL_ENC_DRIVER_H__ +#define __FSL_ENC_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> + +#include "fsl_enc_hal.h" +#include "fsl_os_abstraction.h" +#if FSL_FEATURE_SOC_ENC_COUNT + +/*! + * @addtogroup enc_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +extern ENC_Type* const g_encBase[]; +extern const IRQn_Type g_encCmpIrqId[ENC_INSTANCE_COUNT]; +extern const IRQn_Type g_encHomeIrqId[ENC_INSTANCE_COUNT]; +extern const IRQn_Type g_encWdtIrqId[ENC_INSTANCE_COUNT]; +extern const IRQn_Type g_encIndexIrqId[ENC_INSTANCE_COUNT]; +/*! + * @brief User configuration structure for ENC driver. + * + * Use an instance of this structure with the ENC_DRV_Init()function. This enables configuration of the + * most common settings of the ENC peripheral with a single function call. + * @internal gui name="ENC configuration" id="encCfg" + */ +typedef struct EncUserConfig { + uint32_t posCntInitValue; /*!< Value to put in Initialization Register. @internal gui name="Initialization register" id="InitReg" */ + uint32_t posCmpValue; /*!< Value to put in Position Compare Register. @internal gui name="Position compare register" id="PosCompReg" */ + uint32_t moduloValue; /*!< Value to put in Modulus Register. @internal gui name="Modulus register" id="ModReg" */ + uint16_t watchdogTimeout; /*!< Value to put in Watchdog Timeout Register. @internal gui name="Watchdog time-out register" id="WdogTimetReg" */ + uint8_t filterCount; /*!< Value represents the number of consecutive samples that must agree prior to the input filter accepting an input transition. @internal gui name="Filter sample count" id="FilterCount" */ + uint8_t filterPeriod; /*!< Value represents the sampling period (in IPBus clock cycles) of the decoder input signals. @internal gui name="Filter sample period" id="FilterPeriod" */ + enc_operation_mode_t operationMode; /*!< Operation mode: Normal mode, modulo counting mode or bypass (signal phase count) mode. @internal gui name="Operation mode" id="OpMode" */ + bool reverseCounting; /*!< Counting direction: Normal (false) or reverse (true) counting direction. @internal gui name="Reverse counting" id="ReverseCnt" */ + bool indexInputNegativeEdge; /*!< Type of transition edge of INDEX input signal: positive (false) or negative (true). @internal gui name="INDEX input signal" id="IdxNegEdge" */ + bool homeInputNegativeEdge; /*!< Type of transition edge of HOME input signal: positive (false) or negative (true). @internal gui name="HOME input signal" id="HomeNegEdge" */ + bool indexPulsePosInit; /*!< To use HOME (false) or INDEX (true) input to initialize position counter to value in Initialization Register. @internal gui name="Position counter init. type" id="IdxPulsePosInit" */ + bool triggerUpdateHoldRegEnable; /*!< Enable/disable updating hold registers on TRIGGER input. @internal gui name="Update hold registers" id="UpdateHoldReg" */ + bool triggerClearPosRegEnable; /*!< Enable/disable clear of position registers on TRIGGER input. @internal gui name="Clear position registers" id="ClearPosReg" */ + bool moduloRevolutionCounting; /*!< Type of revolution counter - index pulse counting (on false) or modulo counting (on true). @internal gui name="Revolution counter" id="TypeRevCnt" */ + bool outputControlOnReading; /*!< Used to control the behaviour of the POSMATCH output signal. True - output control on reading position register, false - OC on match position register. @internal gui name="POSMATCH output signal" id="PosMatchOut" */ +} enc_user_config_t; + +/*! + * @brief User configuration structure for ENC driver - ENC test module configuration. + * + * Use an instance of this structure with the ENC_DRV_TestInit()function. + * This enables configuration of the Test module of the ENC peripheral + * with a single function call. + */ +typedef struct EncTestConfig { + uint8_t testCount; /*!< Test count - holds the number of quadrature advances to generate. */ + uint8_t testPeriod; /*!< Test period - holds the period of quadrature phase in IPBus clock cycles. */ + bool testNegativeSignalEnable; /*!< Test signal type, positive (false) or negative (true). */ +} enc_test_config_t; + +/*! + * @brief Counter registers structure for ENC driver. + * + * Use an instance of this structure with the ENC_DRV_ReadHoldRegisters() or + * ENC_DRV_ReadCounters() functions. This reads counters and hold registers of + * Position, PositionDifference, Revolution Counter. + */ +typedef struct EncCounter { + int32_t position; /*!< Position Counter/Hold Register. */ + int16_t posDiff; /*!< Position Difference Counter/Hold Register. */ + int16_t revolution; /*!< Revolution Counter/Hold Register. */ +} enc_counter_t; + +/*! + * @brief Input monitor structure for ENC driver. + * + * Use an instance of this structure with the ENC_DRV_ReadInputMonitorRegister(). + * This reads Input Monitor register that contains the values of the raw or filtered + * PHASEA, PHASEB, INDEX and HOME input signals. + */ +typedef struct EncInputMonitor { + bool phaseA; /*!< PHASEA input. */ + bool phaseB; /*!< PHASEB input. */ + bool index; /*!< INDEX input. */ + bool home; /*!< HOME input. */ +} enc_input_monitor_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Configuration + * @{ + */ + +/*! + * @brief Fills the initial user configuration for the ENC module + * without the interrupts enablement. + * + * This function fills the initial user configuration. Calling the initialization + * function with the filled parameter configures the ENC module to function as + * a simple Quadrature Encoder. The settings are: + * + @code + encUserConfig.operationMode = kEncNormalMode; + encUserConfig.reverseCounting = false; + encUserConfig.indexInputNegativeEdge = false; + encUserConfig.homeInputNegativeEdge = false; + encUserConfig.indexPulsePosInit = true; + encUserConfig.posCntInitValue = 0U; + encUserConfig.posCmpValue = 0xFFFFU; + encUserConfig.moduloValue = 0U; + encUserConfig.triggerUpdateHoldRegEnable = false; + encUserConfig.triggerClearPosRegEnable = false; + encUserConfig.moduloRevolutionCounting = false; + encUserConfig.outputControlOnReading = false; + encUserConfig.watchdogTimeout = 0U; + encUserConfig.filterCount = 0U; + encUserConfig.filterPeriod = 0U; + @endcode + * + * @param userConfigPtr Pointer to the user configuration structure. + * @return Execution status. + */ +enc_status_t ENC_DRV_StructInitUserConfigNormal(enc_user_config_t * userConfigPtr); + +/*! + * @brief Initializes an ENC instance for operation. + * + * This function initializes the run-time state structure to un-gate the clock to the ENC module, + * initializes the module to user-defined settings and default settings, + * configures the IRQ state structure, and enables the module-level interrupt to the core. + * This example shows how to set up the enc_state_t and the + * enc_user_config_t parameters and how to call the ENC_DRV_Init function by passing + * in these parameters: + @code + enc_user_config_t encUserConfig; + encUserConfig.operationMode = kEncNormalMode; + encUserConfig.reverseCounting = false; + encUserConfig.indexInputNegativeEdge = false; + encUserConfig.homeInputNegativeEdge = false; + encUserConfig.indexPulsePosInit = true; + encUserConfig.posCntInitValue = 0U; + encUserConfig.posCmpValue = 0xFFFFU; + encUserConfig.moduloValue = 0U; + encUserConfig.triggerUpdateHoldRegEnable = false; + encUserConfig.triggerClearPosRegEnable = false; + encUserConfig.moduloRevolutionCounting = false; + encUserConfig.outputControlOnReading = false; + encUserConfig.watchdogTimeout = 0U; + encUserConfig.filterCount = 0U; + encUserConfig.filterPeriod = 0U; + ENC_DRV_Init(&encUserConfig); + @endcode + * + * @param instance ENC instance ID. + * @param userConfigPtr The user configuration structure of type enc_user_config_t. The user + * is responsible to fill out the members of this structure and to pass the pointer + * of this structure into this function. + * @return Execution status. + */ +enc_status_t ENC_DRV_Init(uint32_t instance, const enc_user_config_t *userConfigPtr); + +/*! + * @brief De-initializes the ENC peripheral. + * + * This function shuts down the ENC clock to reduce power consumption. + * + * @param instance ENC instance ID. + */ +void ENC_DRV_Deinit(uint32_t instance); + +/*! + * @brief Initializes an ENC test module. + * + * This function initializes the run-time state structure to enable the test module + * and sets the test period and test count values. + * This example shows how to set up the enc_test_config_t parameters and + * how to call the ENC_DRV_TestInit function by passing in these parameters: + @code + enc_test_config_t encTestConfig; + encTestConfig.testNegativeSignalEnable = false; + encTestConfig.testCount = 100; + encTestConfig.testPeriod = 10; + ENC_DRV_TestInit(&encTestConfig); + @endcode + * + * @param instance ENC instance ID. + * @param userConfigPtr The user configuration structure of type enc_test_config_t. + * @return Execution status. + */ +enc_status_t ENC_DRV_TestInit(uint32_t instance, const enc_test_config_t * userConfigPtr); + +/*! + * @brief Shuts down the ENC test module, disables test counter, + * and clears the test period and test count values. + * + * @param instance ENC instance ID. + */ +void ENC_DRV_TestDeinit(uint32_t instance); + +/*! + * @brief Enables/disables the selected ENC interrupt. + * + * The interrupt source is passing as argument of type enc_interrupt_source_t. + * + * @param instance ENC instance ID. + * @param intSrc The type of interrupt to enable/disable. + * @param enable Bool parameter to enable/disable. + * @return Execution status. + */ +enc_status_t ENC_DRV_SetIntMode + (uint32_t instance, enc_int_source_t intSrc, bool enable); + +/*! + * @brief Gets the configuration of the selected ENC interrupt. + * + * The interrupt type is passing as an argument of type enc_int_source_t. + * + * @param instance ENC instance ID. + * @param intSrc The type of interrupt to get configuration. + * @return Configuration of selected interrupt source. + */ +bool ENC_DRV_GetIntMode(uint32_t instance, enc_int_source_t intSrc); + +/*! + * @brief Gets the interrupt status flag of the selected interrupt source. + * + * @param instance ENC instance ID. + * @param flag Selected type of status flag. + * @return State of selected flag. + */ +bool ENC_DRV_GetStatusFlag(uint32_t instance, enc_status_flag_t flag); + +/*! + * @brief Clears the status flag of the selected status source. + * + * @param instance ENC instance ID. + * @param flag Selected type of status flag. + */ +void ENC_DRV_ClearStatusFlag(uint32_t instance, enc_status_flag_t flag); + +/*! + * @brief Reads the actual values of the ENC counter registers. + * + * @param instance ENC instance ID. + * @param countRegPtr The structure of ENC counter registers. + * @return Execution status. + */ +enc_status_t ENC_DRV_ReadCounters(uint32_t instance, enc_counter_t * countRegPtr); + +/*! + * @brief Reads the ENC hold registers. + * + * @param instance ENC instance ID. + * @param holdRegPtr The structure of ENC hold registers. + * @return Execution status. + */ +enc_status_t ENC_DRV_ReadHoldReg(uint32_t instance, enc_counter_t * holdRegPtr); + +/*! + * @brief Resets the ENC counter registers. + * + * @param instance ENC instance ID. + */ +void ENC_DRV_ResetCounters(uint32_t instance); + +/*! + * @brief Reads the ENC input monitor register. + * + * @param instance ENC instance ID. + * @param inputMonitorRaw The type of input monitor - raw (true) / filtered (false). + * @param inputMonitorPtr The structure of ENC Monitor register variables. + * @return Execution status. + */ +enc_status_t ENC_DRV_ReadInputMonitor + (uint32_t instance, bool inputMonitorRaw, enc_input_monitor_t * inputMonitorPtr); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif +#endif /* __FSL_ENC_DRIVER_H__*/ + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_enet_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_enet_driver.h new file mode 100755 index 0000000..06dc19c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_enet_driver.h @@ -0,0 +1,806 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_ENET_DRIVER_H__ +#define __FSL_ENET_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_enet_hal.h" +#include "fsl_os_abstraction.h" +#if FSL_FEATURE_SOC_ENET_COUNT +/*! + * @addtogroup enet_driver + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Array for ENET module register base address. */ +extern ENET_Type * const g_enetBase[]; + +/*! @brief Two-dimensional array for the ENET interrupt vector number. */ +extern const IRQn_Type g_enetTxIrqId[]; +extern const IRQn_Type g_enetRxIrqId[]; +extern const IRQn_Type g_enetTsIrqId[]; +extern const IRQn_Type g_enetErrIrqId[]; + +/******************************************************************************* + * Definitions + + ******************************************************************************/ +/*! @brief Defines the approach: ENET interrupt handler receive */ +#ifndef ENET_RECEIVE_ALL_INTERRUPT +#define ENET_RECEIVE_ALL_INTERRUPT 1 +#endif + +/*! @brief Defines the statistic enable macro.*/ +#ifndef ENET_ENABLE_DETAIL_STATS +#define ENET_ENABLE_DETAIL_STATS 0 +#endif + +/*! brief Defines the macro for converting constants from host byte order to network byte order*/ +#define ENET_HTONS(n) __REV16(n) +#define ENET_HTONL(n) __REV(n) +#define ENET_NTOHS(n) __REV16(n) +#define ENET_NTOHL(n) __REV(n) + +/*! @brief Defines the CRC-32 calculation constant. */ +#define ENET_ORIGINAL_CRC32 0xFFFFFFFFU /*!< CRC-32 Original data*/ +#define ENET_CRC32_POLYNOMIC 0xEDB88320U /*!< CRC-32 Polynomic*/ + +#if FSL_FEATURE_ENET_SUPPORT_PTP +/*! @brief Defines the PTP IOCTL macro.*/ +typedef enum _enet_ptp_ioctl +{ + kEnetPtpGetRxTimestamp = 0, /*!< ENET PTP gets receive timestamp*/ + kEnetPtpGetTxTimestamp, /*!< ENET PTP gets transmit timestamp*/ + kEnetPtpGetCurrentTime, /*!< ENET PTP gets current time*/ + kEnetPtpSetCurrentTime, /*!< ENET PTP sets current time*/ + kEnetPtpFlushTimestamp, /*!< ENET PTP flushes timestamp*/ + kEnetPtpCorrectTime, /*!< ENET PTP time correction*/ + kEnetPtpSendEthernetPtpV2, /*!< ENET PTPv2 sends Ethernet frame*/ + kEnetPtpReceiveEthernetPtpV2 /*!< ENET PTPv2 receives with Ethernet frame*/ +} enet_ptp_ioctl_t; + + +/*! @brief Defines the ENET PTP message related constant.*/ +typedef enum _enet_ptp_event_type +{ + kEnetPtpSourcePortIdLen = 10, /*!< PTP message sequence id length*/ + kEnetPtpEventMsgType = 3, /*!< PTP event message type*/ + kEnetPtpEventPort = 319, /*!< PTP event port number*/ + kEnetPtpGnrlPort = 320 /*!< PTP general port number*/ +} enet_ptp_event_type_t; + +/*! @brief Defines all ENET PTP content offsets in the IPv4 PTP UDP/IP multicast message.*/ +typedef enum _enet_ipv4_ptp_content_offset +{ + kEnetPtpIpVersionOffset = 0xe, /*!< IPv4 PTP message IP version offset*/ + kEnetPtpIpv4UdpProtocolOffset = 0x17, /*!< IPv4 PTP message UDP protocol offset*/ + kEnetPtpIpv4UdpPortOffset = 0x24, /*!< IPv4 PTP message UDP port offset*/ + kEnetPtpIpv4UdpMsgTypeOffset = 0x2a, /*!< IPv4 PTP message UDP message type offset*/ + kEnetPtpIpv4UdpVersionoffset = 0x2b, /*!< IPv4 PTP message UDP version offset*/ + kEnetPtpIpv4UdpClockIdOffset = 0x3e, /*!< IPv4 PTP message UDP clock id offset*/ + kEnetPtpIpv4UdpSequenIdOffset = 0x48, /*!< IPv4 PTP message UDP sequence id offset*/ + kEnetPtpIpv4UdpCtlOffset = 0x4a /*!< IPv4 PTP message UDP control offset*/ +} enet_ipv4_ptp_content_offset_t; + +/*! @brief Defines all ENET PTP content offset in THE IPv6 PTP UDP/IP multicast message.*/ +typedef enum _enet_ipv6_ptp_content_offset +{ + kEnetPtpIpv6UdpProtocolOffset = 0x14, /*!< IPv6 PTP message UDP protocol offset*/ + kEnetPtpIpv6UdpPortOffset = 0x38, /*!< IPv6 PTP message UDP port offset*/ + kEnetPtpIpv6UdpMsgTypeOffset = 0x3e, /*!< IPv6 PTP message UDP message type offset*/ + kEnetPtpIpv6UdpVersionOffset = 0x3f, /*!< IPv6 PTP message UDP version offset*/ + kEnetPtpIpv6UdpClockIdOffset = 0x52, /*!< IPv6 PTP message UDP clock id offset*/ + kEnetPtpIpv6UdpSequenceIdOffset = 0x5c, /*!< IPv6 PTP message UDP sequence id offset*/ + kEnetPtpIpv6UdpCtlOffset = 0x5e /*!< IPv6 PTP message UDP control offset*/ +} enet_ipv6_ptp_content_offset_t; + +/*! @brief Defines all ENET PTP content offset in the PTP Layer2 Ethernet message.*/ +typedef enum _enet_ethernetl2_ptpv2_content_offset +{ + kEnetPtpEtherL2PktTypeOffset = 0x0c, /*!< PTPv2 message Ethernet packet type offset*/ + kEnetPtpEtherL2MsgTypeOffset = 0x0e, /*!< PTPv2 message Ethernet message type offset*/ + kEnetPtpEtherL2VersionOffset = 0x0f, /*!< PTPv2 message Ethernet version type offset*/ + kEnetPtpEtherL2ClockIdOffset = 0x22, /*!< PTPv2 message Ethernet clock id offset*/ + kEnetPtpEtherL2SequenceIdOffset = 0x2c, /*!< PTPv2 message Ethernet sequence id offset*/ + kEnetPtpEtherL2CtlOffset = 0x2e /*!< PTPv2 message Ethernet control offset*/ +} enet_ethernetl2_ptpv2_content_offset_t; + +/*! @brief Defines the 1588 timer parameters.*/ +typedef enum _enet_ptp_timer_wrap_period +{ + kEnetPtpAtperValue = 1000000000, /*!< PTP timer wrap around one second */ + kEnetBaseIncreaseUnit = 2 /*!< PTP timer adjusts clock and increases value to 2*/ +} enet_ptp_timer_wrap_period_t; +#endif + +/*! @brief Defines the CRC data for a hash value calculation.*/ +typedef enum _enet_crc_parameter +{ + kEnetCrcOffset = 8, /*!< CRC-32 offset2*/ + kEnetCrcMask1 = 0x3F /*!< CRC-32 mask*/ +} enet_crc_parameter_t; + +/*! @brief Defines the ENET protocol type and main parameters.*/ +typedef enum _enet_protocol_type +{ + kEnetProtocoll2ptpv2 = 0x88F7, /*!< Packet type Ethernet ieee802.3*/ + kEnetProtocolIpv4 = 0x0800, /*!< Packet type IPv4*/ + kEnetProtocolIpv6 = 0x86dd, /*!< Packet type IPv6*/ + kEnetProtocol8021QVlan = 0x8100, /*!< Packet type VLAN*/ + kEnetPacketUdpVersion = 0x11, /*!< UDP protocol type*/ + kEnetPacketIpv4Version = 0x4, /*!< Packet IP version IPv4*/ + kEnetPacketIpv6Version = 0x6 /*!< Packet IP version IPv6*/ +} enet_protocol_type_t; + + +#if FSL_FEATURE_ENET_SUPPORT_PTP +/*! @brief Defines the ENET Mac PTP timestamp structure.*/ +typedef struct ENETMacPtpTime +{ + uint64_t second; /*!< Second*/ + uint32_t nanosecond; /*!< Nanosecond*/ +} enet_mac_ptp_time_t; + +/*! @brief Defines the ENET PTP timer drift structure.*/ +typedef struct ENETPtpDrift +{ + int32_t drift; /*!< Drift for the PTP timer to adjust*/ +} enet_ptp_drift_t; + +/*! @brief Defines the ENET Mac PTP time parameter.*/ +typedef struct ENETMacPtpMasterTime +{ + uint8_t masterPtpInstance;/*!< PTP master timer instance*/ + uint64_t second; /*!< PTP master timer second */ +} enet_mac_ptp_master_time_t; + +/*! @brief Defines the structure for the ENET PTP message data and timestamp data.*/ +typedef struct ENETMacPtpTsData +{ + uint8_t version; /*!< PTP version*/ + uint8_t sourcePortId[kEnetPtpSourcePortIdLen];/*!< PTP source port ID*/ + uint16_t sequenceId; /*!< PTP sequence ID*/ + uint8_t messageType; /*!< PTP message type*/ + enet_mac_ptp_time_t timeStamp;/*!< PTP timestamp*/ +} enet_mac_ptp_ts_data_t; + +/*! @brief Defines the ENET PTP ring buffer structure for the PTP message timestamp store.*/ +typedef struct ENETMacPtpTsRing +{ + uint32_t front; /*!< The first index of the ring*/ + uint32_t end; /*!< The end index of the ring*/ + uint32_t size; /*!< The size of the ring*/ + enet_mac_ptp_ts_data_t *ptpTsDataPtr;/*!< PTP message data structure*/ +} enet_mac_ptp_ts_ring_t; + +/*! @brief Defines the ENET data buffers for the PTP version2 message using the layer2 Ethernet frame.*/ +typedef struct ENETMacPtpL2buffer +{ + uint8_t packet[kEnetMaxFrameVlanSize]; /*!< Buffer for ptpv2 message*/ + uint16_t length; /*!< PTP message length*/ +} enet_mac_ptp_l2buffer_t; + +/*! @brief Defines the ENET PTPv2 packet queue using the layer2 Ethernet frame.*/ +typedef struct ENETMacPtpL2bufferqueue +{ + enet_mac_ptp_l2buffer_t *l2bufferPtr; /*!< PTP layer2 data buffers*/ + uint16_t l2bufferNum; /*!< PTP Layer2 buffer Numbers*/ + uint16_t writeIdx; /*!< Queue write index*/ + uint16_t readIdx; /*!< Queue read index*/ +} enet_mac_ptp_l2buffer_queue_t; + +/*! @brief Defines the ENET PTP layer2 Ethernet frame structure.*/ +typedef struct ENETMacPtpL2packet +{ + uint8_t *ptpMsg; /*!< PTP message*/ + uint16_t length; /*!< Length of the PTP message*/ + uint8_t hwAddr[kEnetMacAddrLen]; /*!< Destination hardware address*/ + uint16_t vlanId; /* VLAN id*/ + uint8_t vlanPrior; /* VLAN priority */ +} enet_mac_ptp_l2_packet_t; + +/*! @brief Defines the ENET PTP buffer structure for all 1588 data.*/ +typedef struct ENETPrivatePtpBuffer +{ + enet_mac_ptp_ts_ring_t rxTimeStamp;/*!< Data structure for receive message*/ + enet_mac_ptp_ts_ring_t txTimeStamp;/*!< Data structure for transmit timestamp*/ + enet_mac_ptp_l2buffer_queue_t layer2Queue;/*!< Data structure for layer2 Ethernet queue*/ + uint64_t masterSecond; /*!< PTP time second when it's master time*/ + bool firstflag; /* First flag for multicast transmit buffer descriptors*/ + volatile enet_bd_struct_t *firstBdPtr; /* First buffer descriptor for timestamp store*/ +} enet_private_ptp_buffer_t; +#endif + + +/*! @brief Defines the multicast group structure for the ENET device. */ +typedef struct ENETMulticastGroup +{ + uint8_t groupAdddr[kEnetMacAddrLen]; /*!< Multicast group address*/ + uint32_t hash; /*!< Hash value of the multicast group address*/ + struct ENETMulticastGroup *next; /*!< Pointer of the next group structure*/ + struct ENETMulticastGroup *prv; /*!< Pointer of the previous structure*/ +} enet_multicast_group_t; + +/*! @brief Defines the ENET header structure. */ +typedef struct ENETEthernetHeader +{ + uint8_t destAddr[kEnetMacAddrLen]; /*!< Destination address */ + uint8_t sourceAddr[kEnetMacAddrLen];/*!< Source address*/ + uint16_t type; /*!< Protocol type*/ +} enet_ethernet_header_t; + +/*! @brief Defines the ENET VLAN frame header structure. */ +typedef struct ENET8021vlanHeader +{ + uint8_t destAddr[kEnetMacAddrLen]; /*!< Destination address */ + uint8_t sourceAddr[kEnetMacAddrLen];/*!< Source address*/ + uint16_t tpidtag; /*!< ENET 8021tag header tag region*/ + uint16_t othertag; /*!< ENET 8021tag header type region*/ + uint16_t type; /*!< Protocol type*/ +} enet_8021vlan_header_t; + +/*! @brief Defines the structure for ENET buffer descriptors status.*/ +typedef struct ENETBuffDescripContext +{ + volatile enet_bd_struct_t * rxBdBasePtr; /*!< Receive buffer descriptor base address pointer*/ + volatile enet_bd_struct_t * rxBdCurPtr; /*!< Current receive buffer descriptor pointer*/ + volatile enet_bd_struct_t * rxBdDirtyPtr; /*!< Receive dirty buffer descriptor*/ + volatile enet_bd_struct_t * txBdBasePtr; /*!< Transmit buffer descriptor base address pointer*/ + volatile enet_bd_struct_t * txBdCurPtr; /*!< Current transmit buffer descriptor pointer*/ + volatile enet_bd_struct_t * txBdDirtyPtr; /*!< Last cleaned transmit buffer descriptor pointer*/ + bool isTxBdFull; /*!< Transmit buffer descriptor full*/ + bool isRxBdFull; /*!< Receive buffer descriptor full*/ + uint32_t rxBuffSizeAlign; /*!< Receive buffer size alignment*/ + uint32_t txBuffSizeAlign; /*!< Transmit buffer size alignment */ + uint8_t *extRxBuffQue; /*!< Extended Rx data buffer queue to update the data buff + in the receive buffer descriptor*/ + uint8_t extRxBuffNum; /*!< extended data buffer number */ +} enet_buff_descrip_context_t; + +/*! @brief Defines the ENET packets statistic structure.*/ +typedef struct ENETMacStats +{ + uint32_t statsRxTotal; /*!< Total number of receive packets*/ + uint32_t statsTxTotal; /*!< Total number of transmit packets*/ +#if ENET_ENABLE_DETAIL_STATS + uint32_t statsRxMissed; /*!< Total number of receive packets*/ + uint32_t statsRxDiscard; /*!< Receive discarded with error */ + uint32_t statsRxError; /*!< Receive discarded with error packets*/ + uint32_t statsTxMissed; /*!< Transmit missed*/ + uint32_t statsTxDiscard; /*!< Transmit discarded with error */ + uint32_t statsTxError; /*!< Transmit error*/ + uint32_t statsRxAlign; /*!< Receive non-octet alignment*/ + uint32_t statsRxFcs; /*!< Receive CRC error*/ + uint32_t statsRxTruncate;/*!< Receive truncate*/ + uint32_t statsRxLengthGreater; /*!< Receive length greater than RCR[MAX_FL] */ + uint32_t statsRxCollision; /*!< Receive collision*/ + uint32_t statsRxOverRun; /*!< Receive over run*/ + uint32_t statsTxOverFlow; /*!< Transmit overflow*/ + uint32_t statsTxLateCollision; /*!< Transmit late collision*/ + uint32_t statsTxExcessCollision;/*!< Transmit excess collision*/ + uint32_t statsTxUnderFlow; /*!< Transmit under flow*/ + uint32_t statsTxLarge; /*!< Transmit large packet*/ + uint32_t statsTxSmall; /*!< Transmit small packet*/ +#endif +} enet_stats_t; + +/*! @brief Defines the ENET MAC packet buffer structure.*/ +typedef struct ENETMacPacketBuffer +{ + uint8_t *data; /*!< Data buffer pointer*/ + uint16_t length; /*!< Data length*/ + struct ENETMacPacketBuffer *next; /*!< Next pointer*/ +} enet_mac_packet_buffer_t; + +#if ENET_RECEIVE_ALL_INTERRUPT +typedef uint32_t (* enet_netif_callback_t)(void *enetPtr, enet_mac_packet_buffer_t *packet); +#endif + +/*! @brief Defines the receive buffer descriptor configure structure.*/ +typedef struct ENETBuffConfig +{ + uint16_t rxBdNumber; /*!< Receive buffer descriptor number*/ + uint16_t txBdNumber; /*!< Transmit buffer descriptor number*/ + uint32_t rxBuffSizeAlign; /*!< Aligned receive buffer size and must be larger than 256*/ + uint32_t txBuffSizeAlign; /*!< Aligned transmit buffer size and must be larger than 256*/ + volatile enet_bd_struct_t *rxBdPtrAlign; /*!< Aligned receive buffer descriptor pointer */ + uint8_t *rxBufferAlign; /*!< Aligned receive data buffer pointer */ + volatile enet_bd_struct_t *txBdPtrAlign; /*!< Aligned transmit buffer descriptor pointer*/ + uint8_t *txBufferAlign; /*!< Aligned transmit buffer descriptor pointer*/ + uint8_t *extRxBuffQue; /*!< Extended Rx data buffer queue to update the data buff + in the receive buffer descriptor*/ + uint8_t extRxBuffNum; /*!< extended data buffer number */ +#if FSL_FEATURE_ENET_SUPPORT_PTP + uint32_t ptpTsRxBuffNum; /*!< Receive 1588 timestamp buffer number*/ + uint32_t ptpTsTxBuffNum; /*!< Transmit 1588 timestamp buffer number*/ + enet_mac_ptp_ts_data_t *ptpTsRxDataPtr; /*!< 1588 timestamp receive buffer pointer*/ + enet_mac_ptp_ts_data_t *ptpTsTxDataPtr; /*!< 1588 timestamp transmit buffer pointer*/ +#endif +} enet_buff_config_t; + + +/*! @brief Defines the ENET device data structure for the ENET.*/ +typedef struct ENETDevIf +{ + struct ENETDevIf *next; /*!< Next device structure address*/ + void *netIfPrivate; /*!< For upper layer private structure*/ + enet_multicast_group_t *multiGroupPtr; /*!< Multicast group chain*/ + uint32_t deviceNumber; /*!< Device number*/ + uint8_t macAddr[kEnetMacAddrLen]; /*!< Mac address */ + uint8_t phyAddr; /*!< PHY address connected to this device*/ + bool isInitialized; /*!< Device initialized*/ + uint16_t maxFrameSize; /*!< Mac maximum frame size*/ + bool isVlanTagEnabled; /*!< ENET VLAN-TAG frames enabled*/ + bool isTxCrcEnable; /*!< Transmit CRC enable in buffer descriptor*/ + bool isRxCrcFwdEnable; /*!< Receive CRC forward*/ + enet_buff_descrip_context_t bdContext; /*!< Mac buffer descriptors context pointer*/ +#if FSL_FEATURE_ENET_SUPPORT_PTP + enet_private_ptp_buffer_t privatePtp;/*!< PTP private buffer*/ +#endif + enet_stats_t stats; /*!< Packets statistic*/ +#if ENET_RECEIVE_ALL_INTERRUPT + enet_netif_callback_t enetNetifcall; /*!< Receive callback function to the upper layer*/ +#else + event_t enetReceiveSync; /*!< Receive sync signal*/ +#endif + mutex_t enetContextSync; /*!< Sync signal*/ +} enet_dev_if_t; + +/*! @brief Defines the ENET user configuration structure. */ +typedef struct ENETUserConfig +{ + const enet_mac_config_t* macCfgPtr; /*!< MAC configuration structure */ + const enet_buff_config_t* buffCfgPtr; /*!< ENET buffer configuration structure */ +} enet_user_config_t; + + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name ENET Driver + * @{ + */ + + +#if FSL_FEATURE_ENET_SUPPORT_PTP +/*! + * @brief Initializes the ENET PTP context structure with the basic configuration. + * + * @param enetIfPtr The ENET context structure. + * @param ptpTsRxDataPtr The PTP timestamp buffer pointer for received frames. + * @param rxBuffNum The PTP timestamp buffer numbers for received frames. + * @param ptpTsTxDataPtr The PTP timestamp buffer pointer for transmitted frames. + * @param txBuffNum The PTP timestamp buffer numbers for transmitted frames. + * @param isSlaveEnabled The flag to enable or disable slave mode. + * @return The execution status. + */ +enet_status_t ENET_DRV_1588Init(enet_dev_if_t *enetIfPtr, enet_mac_ptp_ts_data_t *ptpTsRxDataPtr,uint32_t rxBuffNum, + enet_mac_ptp_ts_data_t *ptpTsTxDataPtr, uint32_t txBuffNum, bool isSlaveEnabled); + +/*! + * @brief Frees all ring buffers. + * + * @param enetIfPtr The basic Ethernet structure pointer. + * @return The execution status. + */ +enet_status_t ENET_DRV_1588Deinit(enet_dev_if_t *enetIfPtr); + +/*! + * @brief Initializes the ENET PTP timer with the basic configuration. + * + * After the PTP starts, the 1588 timer also starts running. To make the 1588 timer + * the slave, enable the isSlaveEnabled flag. + * + * @param instance The ENET instance number. + * @param isSlaveEnabled The switch to enable or disable the PTP timer slave mode. + * @return The execution status. + */ +enet_status_t ENET_DRV_Start1588Timer(uint32_t instance, bool isSlaveEnabled); + +/*! + * @brief Stops the ENET PTP timer. + * + * @param instance The ENET instance number. + */ +void ENET_DRV_Stop1588Timer(uint32_t instance); + +/*! + * @brief Parses the ENET packet. + * + * Parses the ENET message and checks if it is a PTP message. If it is a PTP message, + * the message is stored in the PTP information structure. Message parsing + * decides whether timestamp processing is done after that. + * + * @param packet The ENET packet. + * @param ptpTsPtr The pointer to the PTP data structure. + * @param isPtpMsg The PTP message flag. + * @param isFastEnabled The fast operation flag. If set, only check if it is a PTP message + * and doesn't store any PTP message. + * @return The execution status. + */ +enet_status_t ENET_DRV_Parse1588Packet(uint8_t *packet, enet_mac_ptp_ts_data_t *ptpTsPtr, + bool *isPtpMsg, bool isFastEnabled); +/*! + * @brief Gets the current value of the ENET PTP time. + * + * @param ptpTimerPtr The PTP timer structure. + * @return The execution status. + */ +enet_status_t ENET_DRV_Get1588timer(enet_mac_ptp_time_t *ptpTimerPtr); + +/*! + * @brief Sets the current value of the ENET PTP time. + * + * @param ptpTimerPtr The PTP timer structure. + * @return The execution status. + */ +enet_status_t ENET_DRV_Set1588timer(enet_mac_ptp_time_t *ptpTimerPtr); + +/*! + * @brief Adjusts the ENET PTP time. + * + * @param instance The ENET instance number. + * @param drift The PTP timer drift value. + * @return The execution status. + */ +enet_status_t ENET_DRV_Adjust1588timer(uint32_t instance, int32_t drift); + +/*! + * @brief Stores the transmit timestamp. + * + * @param ptpBuffer The PTP buffer pointer. + * @param firstBdPtr The first buffer descriptor of the current transmit frame. + * @param lastBdPtr The last buffer descriptor of the current transmit frame. + * @return The execution status. + */ +enet_status_t ENET_DRV_GetTxTs(enet_private_ptp_buffer_t *ptpBuffer, volatile enet_bd_struct_t *firstBdPtr, volatile enet_bd_struct_t *lastBdPtr); + +/*! + * @brief Stores receive timestamp. + * + * @param ptpBuffer The PTP buffer pointer. + * @param packet The current receive packet. + * @param bdPtr The current receive buffer descriptor. + * @return The execution status. + */ +enet_status_t ENET_DRV_GetRxTs(enet_private_ptp_buffer_t *ptpBuffer, uint8_t *packet, volatile enet_bd_struct_t *bdPtr); + +/*! + * @brief Initializes the buffer queue for the PTP layer2 Ethernet packets. + * + * @param enetIfPtr The ENET context structure. + * @param ptpL2BufferPtr The PTP layer2 data buffer pointer, all allocated or distributed + * data buffers base address are stored here. + * @param ptpL2BuffNum The PTP layer2 buffer numbers. + * @return The execution status. + */ +enet_status_t ENET_DRV_1588l2queueInit(enet_dev_if_t *enetIfPtr, enet_mac_ptp_l2buffer_t *ptpL2BufferPtr, + uint32_t ptpL2BuffNum); + +/*! + * @brief Adds the PTP layer2 Ethernet packet to the PTP Ethernet packet queue. + * + * @param enetIfPtr The ENET context structure. + * @param packBuffer The packet buffer pointer. + * @return The execution status. + */ +enet_status_t ENET_DRV_Service_l2packet(enet_dev_if_t * enetIfPtr, enet_mac_packet_buffer_t *packBuffer); + +/*! + * @brief Sends the PTP layer2 Ethernet packet to the Net. + * + * @param enetIfPtr The ENET context structure. + * @param paramPtr The buffer from upper layer. + * @return The execution status. + */ +enet_status_t ENET_DRV_Send_l2packet(enet_dev_if_t * enetIfPtr, enet_mac_ptp_l2_packet_t *paramPtr); + +/*! + * @brief Receives the PTP layer2 Ethernet packet from the Net. + * + * @param enetIfPtr The ENET context structure. + * @param paramPtr The buffer receive from net and will send to upper layer. + * @return The execution status. + */ +enet_status_t ENET_DRV_Receive_l2packet(enet_dev_if_t * enetIfPtr, enet_mac_ptp_l2_packet_t *paramPtr); + +/*! + * @brief Provides the handler for the 1588 stack for the PTP IOCTL. + * + * @param enetIfPtr The ENET context structure. + * @param commandId The command ID. + * @param inOutPtr The data buffer. + * @return The execution status. + */ +enet_status_t ENET_DRV_1588Ioctl(enet_dev_if_t * enetIfPtr, uint32_t commandId, void * inOutPtr); + + +/*! + * @brief Checks whether the PTP ring buffer is full. + * + * @param ptpTsRingPtr The ENET PTP timestamp ring. + * @return True if the PTP ring buffer is full. Otherwise, false. + */ +bool ENET_DRV_Is1588TsBuffFull(enet_mac_ptp_ts_ring_t *ptpTsRingPtr); + +/*! + * @brief Updates the latest ring buffers. + * + * Adds the PTP message data to the PTP ring buffers and increases the + * PTP ring buffer index. + * + * @param ptpTsRingPtr The ENET PTP timestamp ring. + * @param data The PTP data buffer. + * @return The execution status. + */ +enet_status_t ENET_DRV_Update1588TsBuff(enet_mac_ptp_ts_ring_t *ptpTsRingPtr, enet_mac_ptp_ts_data_t *data); + +/*! + * @brief Searches the element in ring buffers with the message ID and Clock ID. + * + * @param ptpTsRingPtr The ENET PTP timestamp ring. + * @param data The PTP data buffer. + * @return The execution status. + */ +enet_status_t ENET_DRV_Search1588TsBuff(enet_mac_ptp_ts_ring_t *ptpTsRingPtr, enet_mac_ptp_ts_data_t *data); + +/*! + * @brief Calculates the ENET PTP 1588 timestamp ring buffer index. + * + * @param size The ring size. + * @param curIdx The current ring index. + * @param offset The offset index. + * @return The execution status. + */ +static inline uint32_t ENET_DRV_Incr1588TsBuffRing(uint32_t size, uint32_t curIdx, uint32_t offset) +{ + return ((curIdx + offset) % size); +} + +/*! + * @brief The ENET PTP time interrupt handler. + * + * @param instance The ENET instance number. + */ +void ENET_DRV_TsIRQHandler(uint32_t instance); +#endif + +/*! + * @brief Initializes the ENET with the basic configuration. + * + * @param enetIfPtr The pointer to the basic Ethernet structure. + * @param userConfig The ENET user configuration structure pointer. + * @return The execution status. + */ +enet_status_t ENET_DRV_Init(enet_dev_if_t * enetIfPtr, const enet_user_config_t* userConfig); + + +/*! + * @brief De-initializes the ENET device. + * + * @param enetIfPtr The ENET context structure. + * @return The execution status. + */ +enet_status_t ENET_DRV_Deinit(enet_dev_if_t * enetIfPtr); + +/*! + * @brief Updates the receive buffer descriptor. + * + * This function updates the used receive buffer descriptor ring to + * ensure that the used BDS is correctly used. It cleans + * the status region and sets the control region of the used receive buffer + * descriptor. If the isBufferUpdate flag is set, the data buffer in the + * buffer descriptor is updated. + * + * @param enetIfPtr The ENET context structure. + * @param isBuffUpdate The data buffer update flag. + * @return The execution status. + */ +enet_status_t ENET_DRV_UpdateRxBuffDescrip(enet_dev_if_t * enetIfPtr, bool isBuffUpdate); + +/*! + * @brief ENET transmit buffer descriptor cleanup. + * + * First, store the transmit frame error statistic and PTP timestamp of the transmitted packets. + * Second, clean up the used transmit buffer descriptors. + * If the PTP 1588 feature is open, this interface captures the 1588 timestamp. + * It is called by the transmit interrupt handler. + * + * @param enetIfPtr The ENET context structure. + * @return The execution status. + */ +enet_status_t ENET_DRV_CleanupTxBuffDescrip(enet_dev_if_t * enetIfPtr); + +/*! + * @brief Increases the receive buffer descriptor to the next one. + * + * @param enetIfPtr The ENET context structure. + * @param curBd The current buffer descriptor pointer. + * @return the increased received buffer descriptor. + */ +volatile enet_bd_struct_t * ENET_DRV_IncrRxBuffDescripIndex(enet_dev_if_t * enetIfPtr, volatile enet_bd_struct_t *curBd); + +/*! + * @brief Increases the transmit buffer descriptor to the next one. + * + * @param enetIfPtr The ENET context structure. + * @param curBd The current buffer descriptor pointer. + * @return the increased transmit buffer descriptor. + */ +volatile enet_bd_struct_t * ENET_DRV_IncrTxBuffDescripIndex(enet_dev_if_t * enetIfPtr, volatile enet_bd_struct_t *curBd); + +/*! + * @brief Processes the ENET receive frame error statistics. + * + * This interface gets the error statistics of the received frame. + * Because the error information is in the last BD of a frame, this interface + * should be called when processing the last BD of a frame. + * + * @param enetIfPtr The ENET context structure. + * @param curBd The current buffer descriptor. + * @return The frame error status. + * - True if the frame has an error. + * - False if the frame does not have an error. + */ +bool ENET_DRV_RxErrorStats(enet_dev_if_t * enetIfPtr, volatile enet_bd_struct_t *curBd); + +/*! + * @brief Processes the ENET transmit frame statistics. + * + * This interface gets the error statistics of the transmit frame. + * Because the error information is in the last BD of a frame, this interface + * should be called when processing the last BD of a frame. + * + * @param enetIfPtr The ENET context structure. + * @param curBd The current buffer descriptor. + */ +void ENET_DRV_TxErrorStats(enet_dev_if_t * enetIfPtr, volatile enet_bd_struct_t *curBd); + +#if !ENET_RECEIVE_ALL_INTERRUPT +/*! + * @brief Receives ENET packets. + * + * @param enetIfPtr The ENET context structure. + * @param packBuffer The received data buffer. + * @return The execution status. + */ +enet_status_t ENET_DRV_ReceiveData(enet_dev_if_t * enetIfPtr, enet_mac_packet_buffer_t *packBuffer); +#else +/*! + * @brief Receives ENET packets. + * + * @param enetIfPtr The ENET context structure. + * @return The execution status. + */ +enet_status_t ENET_DRV_ReceiveData(enet_dev_if_t * enetIfPtr); + +/*! + * @brief Installs ENET TCP/IP stack net interface callback function. + * + * @param enetIfPtr The ENET context structure. + * @param function The ENET TCP/IP stack net interface callback function. + * @return The execution status. + */ +enet_status_t ENET_DRV_InstallNetIfCall(enet_dev_if_t * enetIfPtr, enet_netif_callback_t function); +#endif + + +/*! + * @brief Transmits ENET packets. + * + * @param enetIfPtr The ENET context structure. + * @param dataLen The frame data length to be transmitted. + * @param bdNumUsed The buffer descriptor need to be used. + * @return The execution status. + */ +enet_status_t ENET_DRV_SendData(enet_dev_if_t * enetIfPtr, uint32_t dataLen, uint32_t bdNumUsed); + +/*! + * @brief The ENET receive interrupt handler. + * + * @param instance The ENET instance number. + */ +void ENET_DRV_RxIRQHandler(uint32_t instance); + +/*! + * @brief The ENET transmit interrupt handler. + * + * @param instance The ENET instance number. + */ +void ENET_DRV_TxIRQHandler(uint32_t instance); + +/*! + * @brief Calculates the CRC hash value. + * + * @param address The ENET Mac hardware address. + * @param crcValue The calculated CRC value of the Mac address. + */ +void ENET_DRV_CalculateCrc32(uint8_t *address, uint32_t *crcValue); + +/*! + * @brief Adds the ENET device to a multicast group. + * + * @param instance The ENET instance number. + * @param address The multicast group address. + * @param hash The hash value of the multicast group address. + * @return The execution status. + */ +enet_status_t ENET_DRV_AddMulticastGroup(uint32_t instance, uint8_t *address, uint32_t *hash); + +/*! + * @brief Moves the ENET device from a multicast group. + * + * @param instance The ENET instance number. + * @param address The multicast group address. + * @return The execution status. + */ +enet_status_t ENET_DRV_LeaveMulticastGroup(uint32_t instance, uint8_t *address); + +/*! + * @brief ENET buffer enqueue. + * + * @param queue The buffer queue address. + * @param buffer The buffer will add to the buffer queue. + */ +void enet_mac_enqueue_buffer( void **queue, void *buffer); + +/*! + * @brief ENET buffer dequeue. + * + * @param queue The buffer queue address. + * @return The buffer will be dequeued from the buffer queue. + */ +void *enet_mac_dequeue_buffer( void **queue); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif +#endif /* __FSL_ENET_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_ewm_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_ewm_driver.h new file mode 100755 index 0000000..8d6e51a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_ewm_driver.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_EWM_DRIVER_H__ +#define __FSL_EWM_DRIVER_H__ + +#include <assert.h> +#include <stdint.h> +#include <stdbool.h> +#include "fsl_ewm_hal.h" +#if FSL_FEATURE_SOC_EWM_COUNT + +/*! + * @addtogroup ewm_driver + * @{ + */ + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @brief Table of base addresses for EWM instances. */ +extern EWM_Type * const g_ewmBase[]; + +/*! @brief Table to save EWM IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_ewmIrqId[EWM_INSTANCE_COUNT]; + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name EWM Driver + * @{ + */ + + +/*! + * @brief Initializes the EWM. + * + * This function initializes the EWM. When called, the EWM + * runs according to the configuration. + * + * @param instance EWM instance ID + * @param ConfigPtr EWM user configure data structure, see #EWM_user_config_t + * @return Execution status. + */ +ewm_status_t EWM_DRV_Init(uint32_t instance, const ewm_config_t* ConfigPtr); + +/*! + * @brief Closes the clock for EWM. + * + * This function sets the run time array to zero and closes the clock. + * + * @param instance EWM instance ID + */ +void EWM_DRV_Deinit(uint32_t instance); + +/*! + * @brief Refreshes the EWM. + * + * This function feeds the EWM. It sets the EWM timer count to zero and + * should be called before the EWM timer times out. + * + * @param instance EWM instance ID + */ +void EWM_DRV_Refresh(uint32_t instance); + +/*! + * @brief Gets the EWM running status. + * + * This function gets the EWM running status. + * + * @param instance EWM instance ID + * @return EWM running status. False means not running. True means running + */ +bool EWM_DRV_IsRunning(uint32_t instance); + +/*! + * @brief Enables/disables the EWM interrupt. + * + * @param instance EWM instance ID. + * @param enable EWM interrupt enable/disable. + */ +void EWM_DRV_SetIntCmd(uint32_t instance, bool enable); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif +#endif /* __FSL_EWM_H__*/ +/******************************************************************************* + * EOF + *******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_flexbus_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_flexbus_driver.h new file mode 100755 index 0000000..bcabd3e --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_flexbus_driver.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_FLEXBUS_DRIVER_H__ +#define __FSL_FLEXBUS_DRIVER_H__ + +#include "fsl_flexbus_hal.h" +#if FSL_FEATURE_SOC_FB_COUNT + +/*! + * @addtogroup flexbus_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Table of base addresses for FlexBus instances. */ +extern FB_Type * const g_fbBase[]; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the FlexBus driver. + * + * @param instance The FlexBus peripheral instance number. + * @param fb_config FlexBus input user configuration + */ +flexbus_status_t FLEXBUS_DRV_Init(uint32_t instance, const flexbus_user_config_t *fb_config); + +/*! + * @brief Shuts down the FlexBus driver. + * + * @param instance The FlexBus peripheral instance number. + */ +flexbus_status_t FLEXBUS_DRV_Deinit(uint32_t instance); + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif +#endif /* __FSL_FLEXBUS_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_flexcan_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_flexcan_driver.h new file mode 100755 index 0000000..e74fa35 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_flexcan_driver.h @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_FLEXCAN_DRIVER_H__ +#define __FSL_FLEXCAN_DRIVER_H__ + +#include "fsl_flexcan_hal.h" +#include "fsl_os_abstraction.h" +#if FSL_FEATURE_SOC_FLEXCAN_COUNT + +/*! + * @addtogroup flexcan_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Table of base addresses for FlexCAN instances. */ +extern CAN_Type * const g_flexcanBase[]; + +/*! @brief Table to save RX Warning IRQ numbers for FlexCAN instances. */ +extern const IRQn_Type g_flexcanRxWarningIrqId[]; +/*! @brief Table to save TX Warning IRQ numbers for FlexCAN instances. */ +extern const IRQn_Type g_flexcanTxWarningIrqId[]; +/*! @brief Table to save wakeup IRQ numbers for FlexCAN instances. */ +extern const IRQn_Type g_flexcanWakeUpIrqId[]; +/*! @brief Table to save error IRQ numbers for FlexCAN instances. */ +extern const IRQn_Type g_flexcanErrorIrqId[]; +/*! @brief Table to save Bus off IRQ numbers for FlexCAN instances. */ +extern const IRQn_Type g_flexcanBusOffIrqId[]; +/*! @brief Table to save message buffer IRQ numbers for FlexCAN instances. */ +extern const IRQn_Type g_flexcanOredMessageBufferIrqId[]; + +/*! + * @brief Internal driver state information. + * + * @note The contents of this structure are internal to the driver and should not be + * modified by users. Also, contents of the structure are subject to change in + * future releases. + */ +typedef struct FlexCANState { + flexcan_msgbuff_t *fifo_message; /*!< The FlexCAN receive FIFO data*/ + flexcan_msgbuff_t *mb_message; /*!< The FlexCAN receive MB data*/ + volatile uint32_t rx_mb_idx; /*!< Index of the message buffer for receiving*/ + volatile uint32_t tx_mb_idx; /*!< Index of the message buffer for transmitting*/ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its TX business.*/ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its RX business.*/ + volatile bool isTxBusy; /*!< True if there is an active transmit. */ + volatile bool isRxBusy; /*!< True if there is an active receive. */ + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ +} flexcan_state_t; + +/*! @brief FlexCAN data info from user*/ +typedef struct FlexCANDataInfo { + flexcan_msgbuff_id_type_t msg_id_type; /*!< Type of message ID (standard or extended)*/ + uint32_t data_length; /*!< Length of Data in Bytes*/ +} flexcan_data_info_t; + +/*! @brief FlexCAN configuration + * @internal gui name="Common configuration" id="flexcanCfg" + */ +typedef struct FLEXCANUserConfig { + uint32_t max_num_mb; /*!< The maximum number of Message Buffers @internal gui name="Maximum number of message buffers" id="max_num_mb" */ + flexcan_rx_fifo_id_filter_num_t num_id_filters; /*!< The number of RX FIFO ID filters needed @internal gui name="Number of RX FIFO ID filters" id="num_id_filters" */ + bool is_rx_fifo_needed; /*!< 1 if needed; 0 if not. This controls whether the Rx FIFO feature is enabled or not. @internal gui name="Use rx fifo" id="is_rx_fifo_needed" */ + flexcan_operation_modes_t flexcanMode; /*!< User configurable FlexCAN operation modes. @internal gui name="Flexcan Operation Mode" id="flexcanMode"*/ +} flexcan_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Bit rate + * @{ + */ + +/*! + * @brief Sets the FlexCAN bit rate. + * + * @param instance A FlexCAN instance number + * @param bitrate A pointer to the FlexCAN bit rate settings. + * + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_SetBitrate(uint8_t instance, flexcan_time_segment_t *bitrate); + +/*! + * @brief Gets the FlexCAN bit rate. + * + * @param instance A FlexCAN instance number + * @param bitrate A pointer to a variable for returning the FlexCAN bit rate settings + * + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_GetBitrate(uint8_t instance, flexcan_time_segment_t *bitrate); + +/*@}*/ + +/*! + * @name Global mask + * @{ + */ + +/*! + * @brief Sets the RX masking type. + * + * @param instance A FlexCAN instance number + * @param type The FlexCAN RX mask type + */ +void FLEXCAN_DRV_SetRxMaskType(uint8_t instance, flexcan_rx_mask_type_t type); + +/*! + * @brief Sets the FlexCAN RX FIFO global standard or extended mask. + * + * @param instance A FlexCAN instance number + * @param id_type Standard ID or extended ID + * @param mask Mask value + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_SetRxFifoGlobalMask( + uint8_t instance, + flexcan_msgbuff_id_type_t id_type, + uint32_t mask); + +/*! + * @brief Sets the FlexCAN RX MB global standard or extended mask. + * + * @param instance A FlexCAN instance number + * @param id_type Standard ID or extended ID + * @param mask Mask value + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_SetRxMbGlobalMask( + uint8_t instance, + flexcan_msgbuff_id_type_t id_type, + uint32_t mask); + +/*! + * @brief Sets the FlexCAN RX individual standard or extended mask. + * + * @param instance A FlexCAN instance number + * @param id_type A standard ID or an extended ID + * @param mb_idx Index of the message buffer + * @param mask Mask value + * + * @return 0 if successful; non-zero failed. + */ +flexcan_status_t FLEXCAN_DRV_SetRxIndividualMask( + uint8_t instance, + flexcan_msgbuff_id_type_t id_type, + uint32_t mb_idx, + uint32_t mask); + +/*@}*/ + +/*! + * @name Initialization and Shutdown + * @{ + */ + +/*! + * @brief Initializes the FlexCAN peripheral. + * + * This function initializes + * @param instance A FlexCAN instance number + * @param state Pointer to the FlexCAN driver state structure. + * @param data The FlexCAN platform data + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_Init( + uint32_t instance, + flexcan_state_t *state, + const flexcan_user_config_t *data); + +/*! + * @brief Shuts down a FlexCAN instance. + * + * @param instance A FlexCAN instance number + * @return 0 if successful; non-zero failed + */ +uint32_t FLEXCAN_DRV_Deinit(uint8_t instance); + +/*@}*/ + +/*! + * @name Send configuration + * @{ + */ + +/*! + * @brief FlexCAN transmit message buffer field configuration. + * + * @param instance A FlexCAN instance number + * @param mb_idx Index of the message buffer + * @param tx_info Data info + * @param msg_id ID of the message to transmit + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_ConfigTxMb( + uint8_t instance, + uint32_t mb_idx, + flexcan_data_info_t *tx_info, + uint32_t msg_id); + +/*! + * @brief Sends FlexCAN messages. + * + * @param instance A FlexCAN instance number + * @param mb_idx Index of the message buffer + * @param tx_info Data info + * @param msg_id ID of the message to transmit + * @param mb_data Bytes of the FlexCAN message + * @param timeout_ms A timeout for the transfer in milliseconds. + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_SendBlocking( + uint8_t instance, + uint32_t mb_idx, + flexcan_data_info_t *tx_info, + uint32_t msg_id, + uint8_t *mb_data, + uint32_t timeout_ms); + +/*! + * @brief Sends FlexCAN messages. + * + * @param instance A FlexCAN instance number + * @param mb_idx Index of the message buffer + * @param tx_info Data info + * @param msg_id ID of the message to transmit + * @param mb_data Bytes of the FlexCAN message. + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_Send( + uint8_t instance, + uint32_t mb_idx, + flexcan_data_info_t *tx_info, + uint32_t msg_id, + uint8_t *mb_data); + + +/*@}*/ + +/*! + * @name Receive configuration + * @{ + */ + +/*! + * @brief FlexCAN receive message buffer field configuration + * + * @param instance A FlexCAN instance number + * @param mb_idx Index of the message buffer + * @param rx_info Data info + * @param msg_id ID of the message to transmit + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_ConfigRxMb( + uint8_t instance, + uint32_t mb_idx, + flexcan_data_info_t *rx_info, + uint32_t msg_id); + +/*! + * @brief FlexCAN RX FIFO field configuration + * + * @param instance A FlexCAN instance number + * @param id_format The format of the RX FIFO ID Filter Table Elements + * @param id_filter_table The ID filter table elements which contain RTR bit, IDE bit, + * and RX message ID + * @return 0 if successful; non-zero failed. + */ +flexcan_status_t FLEXCAN_DRV_ConfigRxFifo( + uint8_t instance, + flexcan_rx_fifo_id_element_format_t id_format, + flexcan_id_table_t *id_filter_table); + +/*! + * @brief FlexCAN is waiting to receive data from the message buffer. + * + * @param instance A FlexCAN instance number + * @param mb_idx Index of the message buffer + * @param data The FlexCAN receive message buffer data. + * @param timeout_ms A timeout for the transfer in milliseconds. + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_RxMessageBufferBlocking( + uint8_t instance, + uint32_t mb_idx, + flexcan_msgbuff_t *data, + uint32_t timeout_ms); + +/*! + * @brief FlexCAN is waiting to receive data from the message buffer. + * + * @param instance A FlexCAN instance number + * @param mb_idx Index of the message buffer + * @param data The FlexCAN receive message buffer data. + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_RxMessageBuffer( + uint8_t instance, + uint32_t mb_idx, + flexcan_msgbuff_t *data); + +/*! + * @brief FlexCAN is waiting to receive data from the message FIFO. + * + * @param instance A FlexCAN instance number + * @param data The FlexCAN receive message buffer data. + * @param timeout_ms A timeout for the transfer in milliseconds. + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_RxFifoBlocking( + uint8_t instance, + flexcan_msgbuff_t *data, + uint32_t timeout_ms); + +/*! + * @brief FlexCAN is waiting to receive data from the message FIFO. + * + * @param instance A FlexCAN instance number + * @param data The FlexCAN receive message buffer data. + * @return 0 if successful; non-zero failed + */ +flexcan_status_t FLEXCAN_DRV_RxFifo( + uint8_t instance, + flexcan_msgbuff_t *data); + +/*@}*/ + +/*! + * @brief Interrupt handler for a FlexCAN instance. + * + * @param instance The FlexCAN instance number. + */ +void FLEXCAN_DRV_IRQHandler(uint8_t instance); + +/*! + * @brief Returns whether the previous FLEXCAN transmit has finished. + * + * When performing an async transmit, call this function to ascertain the state of the + * current transmission: in progress (or busy) or complete (success). + * + * @param instance The FLEXCAN module base address. + * @return The transmit status. + * @retval kStatus_FLEXCAN_Success The transmit has completed successfully. + * @retval kStatus_FLEXCAN_TxBusy The transmit is still in progress. + */ +flexcan_status_t FLEXCAN_DRV_GetTransmitStatus(uint32_t instance); + +/*! + * @brief Returns whether the previous FLEXCAN receive is complete. + * + * When performing an async receive, call this function to find out the state of the + * current receive progress: in progress (or busy) or complete (success). + * + * @param instance The FLEXCAN module base address. + * @param bytesRemaining A pointer to a value that is filled in with the number of bytes which + * still need to be received in the active transfer. + * @return The receive status. + * @retval kStatus_FLEXCAN_Success The receive has completed successfully. + * @retval kStatus_FLEXCAN_RxBusy The receive is still in progress. + */ +flexcan_status_t FLEXCAN_DRV_GetReceiveStatus(uint32_t instance); + +#ifdef __cplusplus +} +#endif + +/*! @}*/ + +#endif +#endif /* __FSL_FLEXCAN_DRIVER_H__*/ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_driver.h new file mode 100755 index 0000000..af54754 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_driver.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_FLEXIO_DRIVER_H__ +#define __FSL_FLEXIO_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> + +#include "fsl_flexio_hal.h" +#if FSL_FEATURE_SOC_FLEXIO_COUNT + +/*! + * @addtogroup flexio_driver + * @{ + */ + +/******************************************************************************* +* Definitions +******************************************************************************/ +/*! +* @brief Defines the structure to configure the FlexIO module. +* @internal gui name="Common configuration" id="commonCfg" +*/ +typedef struct +{ + bool useInt; /*!< Enables supporting interrupt. @internal gui name="Interrupt" */ + bool onDozeEnable; /*!< Controls the FlexIO operation in Doze modes. @internal gui name="Operation in Doze modes" */ + bool onDebugEnable; /*!< Enables FlexIO operation when in Debug mode. @internal gui name="Operation in Debug modes" */ + bool fastAccessEnable; /*!< Enables fast register accesses to FlexIO registers. @internal gui name="Fast register access" */ +} flexio_user_config_t; +/*! @brief Shifter interrupt handler function type */ +typedef void (* flexio_shifter_int_handler_t)(void * param); +/*! +* @brief Defines the structure to register shifter callback and parameter. +*/ +typedef struct +{ + flexio_shifter_int_handler_t shifterIntHandler; + void *param; + +}flexio_shifter_callback_t; +/*! + * @brief Table of base addresses for FlexIO instances. + */ +extern FLEXIO_Type * const g_flexioBase[]; + +/*! + * @brief Table to save FlexIO IRQ enumeration numbers defined in the CMSIS header file. + */ +extern const IRQn_Type g_flexioIrqId[]; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name FlexIO Driver + * @{ + */ + +/*! + * @brief Initializes the FlexIO module before using the FlexIO module. + * + * @param instance FlexIO instance ID. + * @param userConfigPtr Pointer to the configuration structure. + * @return Execution status. + */ +flexio_status_t FLEXIO_DRV_Init(uint32_t instance, const flexio_user_config_t *userConfigPtr); + +/*! + * @brief Enables the FlexIO after configuring the FlexIO devices. + * + * @param instance FlexIO instance ID. + */ +void FLEXIO_DRV_Start(uint32_t instance); + +/*! + * @brief Disables the FlexIO during FlexIO device configuration. + * + * @param instance FlexIO instance ID. + */ +void FLEXIO_DRV_Pause(uint32_t instance); + +/*! + * @brief Registers the callback function into a shifter interrupt. + * + * @param instance FlexIO instance ID. + * @param shifterId Index of shifter. + * @param shifterIntHandler Callback function to be registered. + * @param param Parameter for callback function. + */ +void FLEXIO_DRV_RegisterCallback(uint32_t instance, uint32_t shifterId, + flexio_shifter_int_handler_t shifterIntHandler, + void *param); + +/*! + * @brief De-initializes the FlexIO module. + * + * @param instance FlexIO instance ID. + * @return Execution status. + */ +flexio_status_t FLEXIO_DRV_Deinit(uint32_t instance); + +/*! + * @brief IRQ hanlder for FLEXIO. + * + * @param instance FlexIO instance ID.. + */ +void FLEXIO_DRV_IRQHandler(uint32_t instance); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif +#endif /* __FSL_FLEXIO_DRIVER_H__ */ + +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_i2c_master_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_i2c_master_driver.h new file mode 100755 index 0000000..dad9751 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_i2c_master_driver.h @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_DRIVER_H +#define __FSL_FLEXIO_I2C_DRIVER_H + +#include "fsl_flexio_i2c_hal.h" +#include "fsl_flexio_driver.h" +#include "fsl_os_abstraction.h" +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL +#include "fsl_edma_driver.h" +#else +#include "fsl_dma_driver.h" +#endif + +#if FSL_FEATURE_SOC_FLEXIO_COUNT + +/*! + * @addtogroup flexio_i2c_master_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Error codes for the FlexIO I2C driver. */ +typedef enum flexio_i2c_status +{ + kStatus_FlexIO_I2C_Success = 0x00U, + kStatus_FlexIO_I2C_XBusy = 0x01U, + kStatus_FlexIO_I2C_NoTransmitInProgress = 0x02U, + kStatus_FlexIO_I2C_NoReceiveInProgress = 0x03U, + kStatus_FlexIO_I2C_Timeout = 0x04U, + kStatus_FlexIO_I2C_NoDataToDeal = 0x05U, + kStatus_FlexIO_I2C_InvalidParam = 0x06U, + kStatus_FlexIO_I2C_DmaRequestFail = 0x07U +} flexio_i2c_status_t; +/*! @brief Direction of master and slave transfers.*/ +typedef enum flexio_i2c_direction { + kFlexIOI2CWrite = 0U, /*!< Master transmit, slave receive.*/ + kFlexIOI2CRead = 1U /*!< Master receive, slave transmit.*/ +} flexio_i2c_direction_t; +/*! @brief I2C receive callback function type */ +typedef void (* flexio_i2c_rx_callback_t)(void * i2cState); +/*! @brief Structure for write/read data from a specific memory address*/ +typedef struct flexio_i2c_memrequest{ + const uint8_t * memAddress; + uint32_t memAddrSize; +}flexio_i2c_memrequest_t; +/*! + * @brief Runtime state structure for FlexIO I2C driver. + */ +typedef struct flexio_i2c_state { + flexio_i2c_dev_t i2cDev; /*!< FlexIO I2C Device configuration. */ + uint8_t *xBuff; /*!< Transmit/receive buffer */ + volatile size_t xSize; /*!< Transmit/receive size */ + volatile bool isXBusy; /*!< True if there is an active transmit. */ + volatile bool isXBlocking; /*!< True if transmit/receive is blocking transaction. */ + semaphore_t xIrqSync; /*!< Used to wait for ISR to complete its transfer business. */ + flexio_i2c_rx_callback_t rxCallback; /*!< Callback to invoke after receiving byte.*/ + void * rxCallbackParam; /*!< Receive callback parameter pointer.*/ + volatile bool isTxUseDma; /*!< True if Tx DMA channel has already been configured. */ + volatile bool isRxUseDma; /*!< True if Rx DMA channel has already been configured. */ +}flexio_i2c_state_t; +/*! + * @brief FlexIO I2C hardware resource configuration. + * + * These constants define the hardware resource used by FlexIO I2C master/slave device and include + * the external pin and internal shifter and timer. + * @internal gui name="I2C hardware configuration" id="i2cHwCfg" + */ +typedef struct flexio_i2c_hwconfig{ + uint32_t sdaPinIdx; /*!< Data line. @internal gui name="SDA pin" id="SdaPin" */ + uint32_t sclkPinIdx; /*!< Clock line. @internal gui name="SCL pin" id="SclPin" */ + uint32_t shifterIdx[2]; /*!< Shifter 0 is for transmit and shifter 1 + * is for receive. @internal gui name="Shifter" id="i2cShifter" */ + uint32_t timerIdx[2]; /*!< Timer 0 is used to generate clock for clock line. + * timer 1 is used to shift shifter @internal gui name="Timer" id="i2cTimer" */ +}flexio_i2c_hwconfig_t; +/*! + * @brief User configuration structure for the FlexIO I2C driver. + * + * Use an instance of this structure with the FLEXIO_I2C_DRV_Init()function. This enables configuration of the + * settings of the FlexIO I2C peripheral with a single function call. Settings include: + * I2C baud rate, data size, FlexIO I2C mode and FlexIO hardware resource + * resource. + * @internal gui name="I2C configuration" id="i2cCfg" + */ +typedef struct flexio_i2c_userconfig{ + uint32_t baudRate; /*!< Baudrate configuration. @internal gui name="Baudrate" id="i2cBaudrate" */ + flexio_i2c_hwconfig_t i2cHwConfig; /*!< FlexIO I2C Master Resource configuration. @internal gui name="Hardware configuration" */ +}flexio_i2c_userconfig_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name FlexIO I2C Driver + * @{ + */ + +/*! + * @brief Initializes a FlexIO-simulated I2C device. + * + * This function initializes the run-time state structure to keep track of + * the on-going transfers and the module to user defined settings and + * default settings. It also configures the underlying FlexIO pin, shifter, and timer. + * This is an example to set up the flexio_i2c_state_t and the + * flexio_i2c_userconfig_t parameters and to call the FLEXIO_I2C_DRV_Init function + @code + flexio_i2c_userconif_t i2cMasterConfig; + i2cMasterConfig.baudRate = 100000; + i2cMasterConfig.i2cHwConfig.sdaPinIdx = 0; + i2cMasterConfig.i2cHwConfig.sclkPinIdx = 1; + i2cMasterConfig.i2cHwConfig.shifterIdx = {0,1}; + i2cMasterConfig.i2cHwConfig.timerIdx = {0,1}; + @endcode + * + * @param instance The FlexIO instance number. + * @param i2cState A pointer to the global FlexIO I2C driver state structure memory. + * The user passes in the memory for the run-time state structure. The FlexIO I2C driver + * populates the members. This run-time state structure keeps track of the + * current transfer in progress. + * @param i2cMasterConfig The user configuration structure of type flexio_i2c_userconfig_t. + * The user populates the members of this structure and passes the pointer of this structure + * to this function. + * @return An error code or kStatus_FlexIO_I2C_Success. + */ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterInit(uint32_t instance, flexio_i2c_state_t * i2cState, + flexio_i2c_userconfig_t * i2cMasterConfig); +/*! + * @brief Shuts down the FlexIO I2C. + * + * This function disables the FlexIO-simulated I2C trigger. + * + * @param i2cState The run-time structure of FlexIO-simulated I2C. + */ +void FLEXIO_I2C_DRV_MasterDeinit(flexio_i2c_state_t * i2cState); + +/*! + * @brief Sends (transmits) data out through the FlexIO-simulated I2C module using a + * blocking method. + * @param i2cState The run-time structure of FlexIO-simulated I2C. + * @param slaveAddr 7-bit or 10-bit slave address. + * @param memRequest The memory request structure, including memory address and size, + * if the operation is not a memory request, could pass NULL. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_I2C_Success. + */ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterSendDataBlocking(flexio_i2c_state_t * i2cState, + uint16_t slaveAddr, + flexio_i2c_memrequest_t *memRequest, + uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the FlexIO-simulated I2C module using a + * non-blocking method. + * @param i2cState The run-time structure of FlexIO-simulated I2C. + * @param slaveAddr 7-bit or 10-bit slave address. + * @param memRequest The memory requests the structure, including memory address and size. + * If the operation is not a memory request, pass NULL. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_FlexIO_I2C_Success. + */ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterSendData(flexio_i2c_state_t * i2cState, + uint16_t slaveAddr, + flexio_i2c_memrequest_t *memRequest, + uint8_t * txBuff, + uint32_t txSize); +/*! + * @brief Sends (transmits) slave address and register address(if a memory is requested) + * through the FlexIO-simulated I2C device. + * @param i2cState The run-time structure of FlexIO-simulated I2C. + * @param direction The direction of I2C operation, Read or Write. + * @param slaveAddr 7-bit or 10-bit slave address. + * @param memRequest The memory requests the structure, including memory address and size. + * If the operation is not a memory request, pass NULL. + * @return An error code or kStatus_FlexIO_I2C_Success. + */ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterSendAddress(flexio_i2c_state_t *i2cState, + uint16_t slaveAddr, + flexio_i2c_direction_t direction, + flexio_i2c_memrequest_t *memRequest); +/*! + * @brief Returns whether the previous FlexIO-simulated I2C transmit has finished. + * + * @param i2cState The run-time structure of FlexIO-simulated I2C. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes that + * are remaining in the active transfer. + * @return An error code or kStatus_FlexIO_I2C_Success. + * @retval kStatus_FlexIO_I2C_Success The transmit has completed successfully. + * @retval kStatus_FlexIO_I2C_TxBusy The transmit is still in progress. @a bytesTransmitted is + * filled with the number of bytes which are transmitted up to that point. + */ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterGetTransmitStatus(flexio_i2c_state_t * i2cState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated I2C transmission early. + * + * @param i2cState The run-time structure of FlexIO-simulated I2C. + * @return An error code or kStatus_FlexIO_I2C_Success. + * @retval kStatus_FlexIO_I2C_Success The transmit was successful. + * @retval kStatus_FlexIO_I2C_NoTransmitInProgress No transmission is currently in progress. + */ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterAbortSendingData(flexio_i2c_state_t * i2cState); + +/*! + * @brief Gets (receives) data from the FlexIO-simulated I2C module using a blocking method. + * + * @param i2cState The run-time structure of FlexIO-simulated I2C. + * @param slaveAddr 7-bit or 10-bit slave address. + * @param memRequest The memory requests the structure, including memory address and size. + * If the operation is not a memory request, pass NULL. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_I2C_Success. + */ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterReceiveDataBlocking(flexio_i2c_state_t * i2cState, + uint16_t slaveAddr, + flexio_i2c_memrequest_t *memRequest, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout); +/*! + * @brief Gets (receives) data from the FlexIO-simulated I2C module using a non-blocking method. + * + * @param i2cState The run-time structure of FlexIO-simulated I2C. + * @param slaveAddr 7-bit or 10-bit slave address. + * @param memRequest The memory requests the structure, including memory address and size. + * If the operation is not a memory request, pass NULL. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_FlexIO_I2C_Success. + */ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterReceiveData(flexio_i2c_state_t * i2cState, + uint16_t slaveAddr, + flexio_i2c_memrequest_t *memRequest, + uint8_t * rxBuff, + uint32_t rxSize); + +/*! + * @brief Returns whether the previous FlexIO-simulated I2C receive is complete. + * + * @param i2cState The run-time structure of FlexIO-simulated I2C. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes which + * still need to be received in the active transfer. + * @return An error code or kStatus_FlexIO_I2C_Success. + * @retval kStatus_FlexIO_I2C_Success The receive has completed successfully. + * @retval kStatus_FlexIO_I2C_RxBusy The receive is still in progress. @a bytesReceived is + * filled with the number of bytes which are received up to that point. + */ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterGetReceiveStatus(flexio_i2c_state_t * i2cState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated I2C receive early. + * + * @param i2cState The run-time structure of FlexIO-simulated I2C. + * @return An error code or kStatus_I2C_Success. + * @retval kStatus_FlexIO_I2C_Success The receive was successful. + * @retval kStatus_FlexIO_I2C_NoTransmitInProgress No receive is currently in progress. + */ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterAbortReceivingData(flexio_i2c_state_t * i2cState); + +/*! + * @brief Interrupt handler for FlexIO-simulated I2C TX. + * @param param The run-time structure of FlexIO simulated I2C. + */ +void FLEXIO_I2C_DRV_TX_IRQHandler(void *param); + +/*! + * @brief Interrupt handler for FlexIO-simulated I2C RX. + * @param param The run-time structure of FlexIO simulated I2C. + */ +void FLEXIO_I2C_DRV_RX_IRQHandler(void *param); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif + +#endif diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_i2s_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_i2s_driver.h new file mode 100755 index 0000000..6f9bd69 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_i2s_driver.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_FLEXIO_I2S_DRIVER_H__ +#define __FSL_FLEXIO_I2S_DRIVER_H__ + + +#include "fsl_flexio_i2s_hal.h" +#include "fsl_os_abstraction.h" +#include "fsl_flexio_driver.h" +#include <stdbool.h> +#include <stdint.h> +#include <string.h> +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL +#include "fsl_edma_driver.h" +#else +#include "fsl_dma_driver.h" +#endif + +#if FSL_FEATURE_SOC_FLEXIO_COUNT + +/*! + * @addtogroup flexio_i2s_driver + * @{ + */ + +/*! @brief Callback function of I2S */ +typedef void (* i2s_callback) (void * param); + +/*! @brief FlexIO I2S status */ +typedef enum _flexio_i2s_status +{ + kStatus_FlexioI2S_Success = 0x0, + kStatus_FlexioI2S_DeviceBusy = 0x1, + kStatus_FlexioI2S_InvalidParameter = 0x2, + kStatus_FlexioI2S_Fail = 0x3 +} flexio_i2s_status_t; + +/*! @brief Master or slave enumeration */ +typedef enum _flexio_i2s_master_slave +{ + kFlexioI2SMaster = 0U,/*!< As an I2S master. @internal gui name="Master" */ + kFlexioI2SSlave = 1U /*!< As an I2S slave. @internal gui name="Slave" */ +} flexio_i2s_master_slave_t; + +/*! + * @brief Define the audio data format + * @internal gui name="I2S configuration" id="i2sCfg" + */ +typedef struct flexioI2SConfig +{ + uint32_t txPinIdx; /*!< Tx pin. Output for cases of both master and slave. @internal gui name="Tx pin" id="TxPin" */ + uint32_t rxPinIdx; /*!< Rx pin. Input for cases of both master and slave. @internal gui name="Rx pin" id="RxPin" */ + uint32_t sckPinIdx; /*!< Clock pin. Output for master, input for slave. @internal gui name="Sck pin" id="SckPin" */ + uint32_t wsPinIdx; /*!< Word select pin. Output for master, input for slave. @internal gui name="Word select pin" id="WsPin" */ + uint32_t shifterIdx[2]; /*!< Selects two shifters. @internal gui name="Shifter" id="i2sShifter" */ + uint32_t timerIdx[2]; /*!< Selects two timers. @internal gui name="Timer" id="i2sTimer" */ + flexio_i2s_master_slave_t master_slave; /*!< Acts as master or slave @internal gui name="Mode" */ + uint32_t sample_rate; /*!< Sample rate in Hz. @internal gui name="Sample rate" */ + uint32_t data_depth; /*!< Data depth, can be 8,16,24,32 bits @internal gui name="Bits" */ +} flexio_i2s_config_t; + +/*! @brief Define the operation handler */ +typedef struct FlexioI2SHandler +{ + flexio_i2s_dev_t device; /*!< Configure of FlexIO resource */ + uint8_t * tx_buffer; /*!< Tx data buffer address. */ + uint8_t * rx_buffer; /*!< Rx data buffer address. */ + uint32_t tx_length; /*!< Bytes to send. */ + uint32_t rx_length; /*!< Bytes to receive. */ + uint32_t tx_finished_bytes; /*!< Transferred bytes. */ + uint32_t rx_finished_bytes; /*!< Received bytes */ + uint32_t sample_rate; /*!< Audio sample rate.*/ + uint32_t bit_depth; /*!< Data depth. */ + semaphore_t tx_sem; /*!< Semaphore for the finish of data send. */ + semaphore_t rx_sem; /*!< Semaphore for the finish of data receive. */ + bool tx_active; /*!< Tx is sending data. */ + bool rx_active; /*!< Rx is receiving data. */ + i2s_callback tx_callback; /*!< Tx callback function. */ + i2s_callback rx_callback; /*!< Rx callback function. */ + void *tx_callback_param; /*!< Tx callback parameter. */ + void *rx_callback_param; /*!< Rx callback parameter. */ + bool tx_use_dma; /*!< If Tx use DMA. */ + bool rx_use_dma; /*!< If Rx use DMA. */ +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + edma_chn_state_t tx_edma_state; + edma_chn_state_t rx_edma_state; + edma_software_tcd_t tx_edma_tcd[2]; + edma_software_tcd_t rx_edma_tcd[2]; +#else + dma_channel_t tx_dma_chn; /*!< DMA Tx channel structure */ + dma_channel_t rx_dma_chn; /*!< DMA Rx channel structure. */ +#endif +} flexio_i2s_handler_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name FLEXIO I2S Driver + * @{ + */ + +/*! @brief Initializes the I2S transfer using the FlexIO. + * + * This interface transfers the FlexIO resource structure to a function which + * configures the pin/timer/shifter to act as an I2S master/slave. + * + * @param instance FlexIO i2s instance. + * @param handler FlexIO I2S handler, users need to transfer memory to + * driver, and this memory is used until the call of de-initialization function. + * @param userConfig The user configuration structure of type flexio_i2c_userconfig_t. + * The user populates the members of this structure and passes the pointer of this structure + * to this function. + * @return An error code or kStatus_FlexioI2S_Success. + */ +flexio_i2s_status_t FLEXIO_I2S_DRV_Init(uint32_t instance, flexio_i2s_handler_t *handler, + flexio_i2s_config_t *userConfig); + +/*! @brief De-initializes the FlexIO I2S. + * + * This function does not free the FlexIO resource. It only clears the internal state. + * @param handler FlexIO i2s handler. + * @return An error code or kStatus_FlexioI2S_Success. + */ +flexio_i2s_status_t FLEXIO_I2S_DRV_Deinit(flexio_i2s_handler_t *handler); + +/*! @brief Starts the I2S transfer. + * + * @param handler FlexIO i2s handler. + * @return An error code or kStatus_FlexioI2S_Success. + */ +flexio_i2s_status_t FLEXIO_I2S_DRV_TxStart(flexio_i2s_handler_t *handler); + +/*! @brief Starts the I2S receive. + * + * @param handler FlexIO i2s handler. + * @return An error code or kStatus_FlexioI2S_Success. + */ +flexio_i2s_status_t FLEXIO_I2S_DRV_RxStart(flexio_i2s_handler_t *handler); + +/*! @brief Stops the I2S transfer. + * + * @param handler FlexIO i2s handler. + * @return An error code or kStatus_FlexioI2S_Success. + */ +flexio_i2s_status_t FLEXIO_I2S_DRV_TxStop(flexio_i2s_handler_t *handler); + +/*! @brief Stops the I2S receive. + * + * @param handler FlexIO i2s handler. + * @return An error code or kStatus_FlexioI2S_Success. + */ +flexio_i2s_status_t FLEXIO_I2S_DRV_RxStop(flexio_i2s_handler_t *handler); + +/*! @brief Sends data as an interrupt. + * + * @param handler FlexIO i2s handler. + * @param addr Start address of data to send. + * @param len Bytes to send. + * @return An error code or kStatus_FlexioI2S_Success. + */ +flexio_i2s_status_t FLEXIO_I2S_DRV_SendDataInt(flexio_i2s_handler_t *handler, uint8_t *addr, uint32_t len); + +/*! @brief Receives data as an interrupt. + * + * @param handler FlexIO i2s handler. + * @param addr Start address of data to receive. + * @param len Bytes to receive. + * @return An error code or kStatus_FlexioI2S_Success. + */ +flexio_i2s_status_t FLEXIO_I2S_DRV_ReceiveDataInt(flexio_i2s_handler_t *handler, uint8_t *addr, uint32_t len); + +/*! @brief Sends data using the DMA. + * + * @param handler FlexIO i2s handler. + * @param addr Start address of data to transfer. + * @param len Bytes to transfer. + * @return An error code or kStatus_FlexioI2S_Success. + */ +flexio_i2s_status_t FLEXIO_I2S_DRV_SendDataDma(flexio_i2s_handler_t *handler, uint8_t *addr, uint32_t len); + +/*! @brief Receives data using the DMA. + * + * @param handler FlexIO i2s handler + * @param addr Start address of data to receive. + * @param len Bytes to receive. + * @return An error code or kStatus_FlexioI2S_Success. + */ +flexio_i2s_status_t FLEXIO_I2S_DRV_ReceiveDataDma(flexio_i2s_handler_t *handler, uint8_t *addr, uint32_t len); + +/*! @brief Installs the callback function for complete data sending. + * + * The user-defined callback function is called by the transmit interrupt handler or the transfer DMA/eDMA + * callback function. + * @param handler FlexIO i2s handler. + * @param callback User defined callback function pointer. + * @param param User defined callback function parameter. It should be an void pointer. + */ +void FLEXIO_I2S_DRV_TxInstallCallback(flexio_i2s_handler_t *handler, i2s_callback callback, + void *param); + +/*! @brief Installs the callback function for complete data receiving. + * + * The user defined callback function is called by the receive interrupt handler or the receive DMA/eDMA + * callback function. + * @param handler FlexIO i2s handler. + * @param callback User defined callback function pointer. + * @param param User defined callback function parameter. It should be an void pointer. + */ +void FLEXIO_I2S_DRV_RxInstallCallback(flexio_i2s_handler_t *handler, i2s_callback callback, + void *param); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif + +#endif /* __FSL_FLEXIO_I2S_DRIVER_H__ */ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_spi_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_spi_driver.h new file mode 100755 index 0000000..93721e6 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_spi_driver.h @@ -0,0 +1,603 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_DRIVER_H +#define __FSL_FLEXIO_SPI_DRIVER_H +#include "fsl_flexio_spi_hal.h" +#include "fsl_flexio_driver.h" +#include "fsl_os_abstraction.h" +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL +#include "fsl_edma_driver.h" +#else +#include "fsl_dma_driver.h" +#endif + +/*! + * @addtogroup flexio_spi_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Error codes for the FLEXIO SPI driver. */ +typedef enum flexio_spi_status +{ + kStatus_FlexIO_SPI_Success = 0x00U, + kStatus_FlexIO_SPI_TxBusy = 0x01U, + kStatus_FlexIO_SPI_RxBusy = 0x02U, + kStatus_FlexIO_SPI_XBusy = 0x03U, + kStatus_FlexIO_SPI_NoTransmitInProgress = 0x04U, + kStatus_FlexIO_SPI_NoReceiveInProgress = 0x05U, + kStatus_FlexIO_SPI_NoTransferInProgress = 0x06U, + kStatus_FlexIO_SPI_Timeout = 0x07U, + kStatus_FlexIO_SPI_NoDataToDeal = 0x08U, + kStatus_FlexIO_SPI_InvalidParam = 0x09U, + kStatus_FlexIO_SPI_DmaRequestFail = 0x0a +} flexio_spi_status_t; +/*! @brief FlexIO SPI master or slave configuration.*/ +typedef enum flexio_spi_master_slave_mode { + kFlexIOSpiMaster = 1, /*!< SPI peripheral operates in master mode. @internal gui name="Master" */ + kFlexIOSpiSlave = 0 /*!< SPI peripheral operates in slave mode. @internal gui name="Slave" */ +} flexio_spi_master_slave_mode_t; +/*! @brief FlexIO SPI data shifter direction options.*/ +typedef enum flexio_spi_shift_direction { + kFlexIOSpiMsbFirst = 0, /*!< Data transfers start with most significant bit. @internal gui name="MSB first" */ + kFlexIOSpiLsbFirst = 1 /*!< Data transfers start with least significant bit. @internal gui name="LSB first" */ +} flexio_spi_shift_direction_t; +/*! @brief FlexIO SPI clock phase configuration.*/ +typedef enum flexio_spi_clock_phase { + kFlexIOSpiClockPhase_FirstEdge = 0, /*!< First edge on SPSCK occurs at the middle of the first + * cycle of a data transfer. @internal gui name="First edge" */ + kFlexIOSpiClockPhase_SecondEdge = 1 /*!< First edge on SPSCK occurs at the start of the + * first cycle of a data transfer. @internal gui name="Second edge" */ +} flexio_spi_clock_phase_t; +/*! @brief SPI data length mode options.*/ +typedef enum flexio_spi_data_bitcount_mode { + kFlexIOSpi8BitMode = 8, /*!< 8-bit data transmission mode @internal gui name="8-bit" */ + kFlexIOSpi16BitMode = 16, /*!< 16-bit data transmission mode @internal gui name="16-bit" */ +} flexio_spi_data_bitcount_mode_t; +/*! @brief SPI receive callback function type */ +typedef void (* flexio_spi_rx_callback_t)(void * spiState); +/*! + * @brief Runtime state structure for FLEXIO SPI driver. + */ +typedef struct flexio_spi_state { + flexio_spi_master_slave_mode_t mode; + flexio_spi_data_bitcount_mode_t dataSize; + flexio_spi_shift_direction_t bitDirection; + flexio_spi_dev_t spiDev; + const uint8_t *txBuff; + uint8_t *rxBuff; + volatile size_t txSize; + volatile size_t rxSize; + volatile bool isTxBusy; /*!< True if there is an active transmit. */ + volatile bool isRxBusy; /*!< True if there is an active receive. */ + volatile bool isXBusy; /*!< True if there is an active transmit&receive simultaneously. */ + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + volatile bool isXBlocking; /*!< True if transmit&receive is blocking transaction. */ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its TX business. */ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its RX business. */ + semaphore_t xIrqSync; /*!< Used to wait for ISR to complete its TX&RX business. */ + flexio_spi_rx_callback_t rxCallback; /*!< Callback to invoke after receiving byte.*/ + void * rxCallbackParam; /*!< Receive callback parameter pointer.*/ + volatile bool isTxUseDma; /*!< True if Tx DMA channel has already been configured. */ + volatile bool isRxUseDma; /*!< True if Rx DMA channel has already been configured. */ + #if defined USING_EDMA + edma_chn_state_t edmaSpiTx; + edma_chn_state_t edmaSpiRx; + edma_software_tcd_t edmaTxTcd; + edma_software_tcd_t edmaRxTcd; + #else + dma_channel_t dmaSpiTx; /*!< DMA Tx channel structure */ + dma_channel_t dmaSpiRx; /*!< DMA Rx channel structure. */ + #endif +}flexio_spi_state_t; +/*! + * @brief FlexIO SPI hardware resource configuration. + * + * These constants define the hardware resource used by FlexIO SPI master/slave device and includes + * the external pin and internal shifter and timer. + * @internal gui name="SPI hardware configuration" id="spiHwCfg" + */ +typedef struct flexio_spi_hwconfig{ + uint32_t sdoPinIdx; /*!< Output pin index. @internal gui name="Data output pin" */ + uint32_t sdiPinIdx; /*!< Input pin index. @internal gui name="Data input pin" */ + uint32_t sclkPinIdx; /*!< Clock pin index. Output for master, input for slave. @internal gui name="Clock pin" */ + uint32_t csnPinIdx; /*!< Chip select pin index. Output for master, input for slave. @internal gui name="Chip select pin" */ + uint32_t shifterIdx[2]; /*!< Select two shifters. @internal gui name="Shifter" id="spiShifter" */ + uint32_t timerIdx[2]; /*!< timer 0 is available for both master and slave. + timer 1 would be only available for master + and not used in slave mode. @internal gui name="Timer" id="spiTimer" */ +}flexio_spi_hwconfig_t; +/*! + * @brief User configuration structure for the FlexIO SPI driver. + * + * Use an instance of this structure with the FLEXIO_SPI_DRV_Init()function. This enables configuration of the + * settings of the FlexIO SPI peripheral with a single function call. Settings include: + * SPI baud rate, data size, FlexIO SPI mode and FlexIO hardware resource + * resource. + * @internal gui name="SPI configuration" id="spiCfg" + */ +typedef struct flexio_spi_userconfig{ + flexio_spi_master_slave_mode_t spiMode; /*!< Selects Master or Slave mode. @internal gui name="Mode" id="spiMode" */ + uint32_t baudRate; /*!< Baudrate configuration. @internal gui name="Baudrate" id="spiBaudrate" */ + flexio_spi_clock_phase_t clkPhase; /*!< Clock phase configuration. @internal gui name="Clock phase" id="spiClockPhase" */ + flexio_spi_data_bitcount_mode_t dataSize; /*!< SPI data length mode. @internal gui name="Bits" id="spiBits" */ + flexio_spi_shift_direction_t bitDirection; /*!< SPI data shifter direction options. @internal gui name="Data direction" id="spiDirection" */ + flexio_spi_hwconfig_t spiHwConfig; /*!< FlexIO SPI Resource configuration. @internal gui name="Hardware configuration" */ +}flexio_spi_userconfig_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name FlexIO SPI Driver + * @{ + */ + +/*! + * @brief Initializes a FlexIO-simulated SPI device. + * + * This function initializes the run-time state structure to keep track of + * the on-going transfers and the module to user defined settings and + * default settings. It also configures the underlying FlexIO pin, shifter, and timer. + * This is an example to set up the flexio_spi_state_t and the + * flexio_spi_userconfig_t parameters and to call the FLEXIO_SPI_DRV_Init function + @code + flexio_spi_userconif_t spiConfig; + spiConfig.spiMode = kFlexIOSpiMaster; + spiConfig.baudRate = 100000; + spiConfig.clkPhase = kFlexIOSpiClockPhase_FirstEdge; + spiConfig.dataSize = kFlexIOSpi8BitMode; + spiConfig.spiHwConfig.sdoPinIdx = 0; + spiConfig.spiHwConfig.sdiPinIdx = 1; + spiConfig.spiHwConfig.sclkPinIdx = 2; + spiConfig.spiHwConfig.csnPinIdx = 3; + spiConfig.spiHwConfig.shifterIdx = {0,1}; + spiConfig.spiHwConfig.timerIdx = {0,1}; + @endcode + * + * @param instance The FlexIO instance number. + * @param spiState A pointer to the global FlexIO SPI driver state structure memory. + * The user passes in the memory for the run-time state structure. The FlexIO SPI driver + * populates the members. This run-time state structure keeps track of the + * current transfer in progress. + * @param spiConfig The user configuration structure of type flexio_spi_userconfig_t. + * The user populates the members of this structure and passes the pointer of this structure + * to this function. + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_Init(uint32_t instance, flexio_spi_state_t * spiState, + flexio_spi_userconfig_t * spiConfig); +/*! + * @brief Shuts down the FlexIO SPI. + * + * This function disables the FlexIO-simulated SPI trigger. + * + * @param spiState The run-time structure of FLEXIO simulated SPI. + */ +void FLEXIO_SPI_DRV_Deinit(flexio_spi_state_t * spiState); + +/*! + * @brief Sends (transmits) data out through the FlexIO-simulated SPI module using a + * blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_SendDataBlocking(flexio_spi_state_t * spiState, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the FlexIO-simulated SPI module using a + * non-blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_SendData(flexio_spi_state_t * spiState, + const uint8_t * txBuff, + uint32_t txSize); +/*! + * @brief Returns whether the previous FlexIO-simulated SPI transmit has finished. + * + * @param spiState The run-time structure of the FlexIO-simulated SPI. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes that + * are remaining in the active transfer. + * @return An error code or kStatus_FlexIO_SPI_Success. + * @retval kStatus_FlexIO_SPI_Success The transmit has completed successfully. + * @retval kStatus_FlexIO_SPI_TxBusy The transmit is still in progress. @a bytesTransmitted is + * filled with the number of bytes which are transmitted up to that point. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_GetTransmitStatus(flexio_spi_state_t * spiState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated SPI transmission early. + * + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @return An error code or kStatus_FlexIO_SPI_Success. + * @retval kStatus_FlexIO_SPI_Success The transmit was successful. + * @retval kStatus_FlexIO_SPI_NoTransmitInProgress No transmission is currently in progress. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_AbortSendingData(flexio_spi_state_t * spiState); + +/*! + * @brief Gets (receives) data from the FlexIO-simulated SPI module using a blocking method. + * + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_ReceiveDataBlocking(flexio_spi_state_t * spiState, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout); +/*! + * @brief Gets (receives) data from the FlexIO-simulated SPI module using a non-blocking method. + * + * @param spiState The run-time structure of the FlexIO-simulated SPI. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_ReceiveData(flexio_spi_state_t * spiState, + uint8_t * rxBuff, + uint32_t rxSize); + +/*! + * @brief Returns whether the previous FlexIO-simulated SPI receive is complete. + * + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes which + * still need to be received in the active transfer. + * @return An error code or kStatus_FlexIO_SPI_Success. + * @retval kStatus_FlexIO_SPI_Success The receive has completed successfully. + * @retval kStatus_FlexIO_SPI_RxBusy The receive is still in progress. @a bytesReceived is + * filled with the number of bytes which are received up to that point. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_GetReceiveStatus(flexio_spi_state_t * spiState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated SPI receive early. + * + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @return An error code or kStatus_SPI_Success. + * @retval kStatus_FlexIO_SPI_Success The receive was successful. + * @retval kStatus_FlexIO_SPI_NoTransmitInProgress No receive is currently in progress. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_AbortReceivingData(flexio_spi_state_t * spiState); +/*! + * @brief Transfers data through the FlexIO-simulated SPI module using a + * blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param xSize The number of bytes to send&receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_TransferDataBlocking(flexio_spi_state_t * spiState, + const uint8_t * txBuff, uint8_t *rxBuff, + uint32_t xSize, + uint32_t timeout); + +/*! + * @brief Transfers data through the FlexIO-simulated SPI module using a + * non-blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param xSize The number of bytes to send. + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_TransferData(flexio_spi_state_t * spiState, + const uint8_t * txBuff, uint8_t *rxBuff, + uint32_t xSize); + +/*! + * @brief Interrupt handler for the FlexIO-simulated SPI Tx. + * @param param The run-time structure of FlexIO simulated SPI. + */ +void FLEXIO_SPI_DRV_TX_IRQHandler(void *param); + +/*! + * @brief Interrupt handler for the FlexIO-simulated SPI Rx. + * @param param The run-time structure of FLEXIO simulated SPI. + */ +void FLEXIO_SPI_DRV_RX_IRQHandler(void *param); +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL +/*! + * @brief Sends (transmits) data out through the FlexIO-simulated SPI module using a + * EDMA blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaSendDataBlocking(flexio_spi_state_t * spiState, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the FlexIO-simulated SPI module using a + * eDMA non-blocking method. + * @param spiState The run-time structure of the FlexIO-simulated SPI. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaSendData(flexio_spi_state_t * spiState, + const uint8_t * txBuff, + uint32_t txSize); +/*! + * @brief Returns whether the previous FlexIO-simulated SPI-eDMA transmit has finished. + * + * @param spiState The run-time structure of the FlexIO-simulated SPI. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes that + * are remaining in the active transfer. + * @return An error code or kStatus_FlexIO_SPI_Success. + * @retval kStatus_FlexIO_SPI_Success The transmit has completed successfully. + * @retval kStatus_FlexIO_SPI_TxBusy The transmit is still in progress. @a bytesTransmitted is + * filled with the number of bytes which are transmitted up to that point. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaGetTransmitStatus(flexio_spi_state_t * spiState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated SPI-eDMA transmission early. + * + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @return An error code or kStatus_FlexIO_SPI_Success. + * @retval kStatus_FlexIO_SPI_Success The transmit was successful. + * @retval kStatus_FlexIO_SPI_NoTransmitInProgress No transmission is currently in progress. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaAbortSendingData(flexio_spi_state_t * spiState); + +/*! + * @brief Gets (receives) data from the FlexIO-simulated SPI module using an eDMA + * blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaReceiveDataBlocking(flexio_spi_state_t * spiState, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout); +/*! + * @brief Gets (receives) data from the FlexIO-simulated SPI module using an eDMA + * non-blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param rxBuff A pointer to the buffer containing 8-bit read data characters received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaReceiveData(flexio_spi_state_t * spiState, + uint8_t * rxBuff, + uint32_t rxSize); + +/*! + * @brief Returns whether the previous FlexIO-simulated SPI-eDMA receive is complete. + * + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes + * which still need to be received in the active transfer. + * @return An error code or kStatus_FlexIO_SPI_Success. + * @retval kStatus_FlexIO_SPI_Success The receive has completed successfully. + * @retval kStatus_FlexIO_SPI_RxBusy The receive is still in progress. @a bytesReceived + * is filled with the number of bytes which are received up to that point. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaGetReceiveStatus(flexio_spi_state_t * spiState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated SPI-eDMA receive early. + * + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @return An error code or kStatus_SPI_Success. + * @retval kStatus_FlexIO_SPI_Success The receive was successful. + * @retval kStatus_FlexIO_SPI_NoTransmitInProgress No receive is currently in progress. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaAbortReceivingData(flexio_spi_state_t * spiState); +/*! + * @brief Transfers data through the FlexIO-simulated SPI module using an eDMA + * blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param xSize The number of bytes to send&receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaTransferDataBlocking(flexio_spi_state_t * spiState, + const uint8_t * txBuff, uint8_t *rxBuff, + uint32_t xSize, + uint32_t timeout); + +/*! + * @brief Transfers data through the FlexIO-simulated SPI module using a + * EDMA non-blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param txBuff A pointer to the source buffer containing 8-bit data characters to send. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param xSize The number of bytes to send. + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaTransferData(flexio_spi_state_t * spiState, + const uint8_t * txBuff, uint8_t *rxBuff, + uint32_t xSize); +#else +/*! + * @brief Sends (transmits) data out through the FlexIO-simulated SPI module using a + * DMA blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param txBuff A pointer to the source buffer containing 8-bit data characters to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaSendDataBlocking(flexio_spi_state_t * spiState, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the FlexIO-simulated SPI module using a DMA + * non-blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaSendData(flexio_spi_state_t * spiState, + const uint8_t * txBuff, + uint32_t txSize); +/*! + * @brief Returns whether the previous FlexIO-simulated SPI-DMA transmit has finished. + * + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes + * that are remaining in the active transfer. + * @return An error code or kStatus_FlexIO_SPI_Success. + * @retval kStatus_FlexIO_SPI_Success The transmit has completed successfully. + * @retval kStatus_FlexIO_SPI_TxBusy The transmit is still in progress. @a bytesTransmitted + * is filled with the number of bytes which are transmitted up to that point. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaGetTransmitStatus(flexio_spi_state_t * spiState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated SPI-DMA transmission early. + * + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @return An error code or kStatus_FlexIO_SPI_Success. + * @retval kStatus_FlexIO_SPI_Success The transmit was successful. + * @retval kStatus_FlexIO_SPI_NoTransmitInProgress No transmission is currently in progress. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaAbortSendingData(flexio_spi_state_t * spiState); + +/*! + * @brief Gets (receives) data from the FlexIO-simulated SPI module using a + * DMA blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param rxBuff A pointer to the buffer containing 8-bit read data characters received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaReceiveDataBlocking(flexio_spi_state_t * spiState, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout); +/*! + * @brief Gets (receives) data from the FlexIO-simulated SPI module using a + * DMA non-blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param rxBuff A pointer to the buffer containing 8-bit read data characters received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaReceiveData(flexio_spi_state_t * spiState, + uint8_t * rxBuff, + uint32_t rxSize); + +/*! + * @brief Returns whether the previous FlexIO-simulated SPI-DMA receive is complete. + * + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes + * which still need to be received in the active transfer. + * @return An error code or kStatus_FlexIO_SPI_Success. + * @retval kStatus_FlexIO_SPI_Success The receive has completed successfully. + * @retval kStatus_FlexIO_SPI_RxBusy The receive is still in progress. @a bytesReceived is + * filled with the number of bytes which are received up to that point. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaGetReceiveStatus(flexio_spi_state_t * spiState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated SPI-DMA receive early. + * + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @return An error code or kStatus_SPI_Success. + * @retval kStatus_FlexIO_SPI_Success The receive was successful. + * @retval kStatus_FlexIO_SPI_NoTransmitInProgress No receive is currently in progress. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_AbortDmaReceivingData(flexio_spi_state_t * spiState); +/*! + * @brief Transfers data through the FlexIO-simulated SPI module using a + * DMA blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param txBuff A pointer to the source buffer containing 8-bit data characters to send. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param xSize The number of bytes to send&receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaTransferDataBlocking(flexio_spi_state_t * spiState, + const uint8_t * txBuff, uint8_t *rxBuff, + uint32_t xSize, + uint32_t timeout); + +/*! + * @brief Transfers data through the FlexIO-simulated SPI module using a + * DMA non-blocking method. + * @param spiState The run-time structure of FlexIO-simulated SPI. + * @param txBuff A pointer to the source buffer containing 8-bit data characters to send. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param xSize The number of bytes to send. + * @return An error code or kStatus_FlexIO_SPI_Success. + */ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaTransferData(flexio_spi_state_t * spiState, + const uint8_t * txBuff, uint8_t *rxBuff, + uint32_t xSize); +#endif +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_uart_dma_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_uart_dma_driver.h new file mode 100755 index 0000000..225c834 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_uart_dma_driver.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_DRIVER_H__ +#define __FSL_FLEXIO_UART_DMA_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_os_abstraction.h" +#include "fsl_flexio_uart_hal.h" +#include "fsl_dma_driver.h" +#include "fsl_flexio_driver.h" +#include "fsl_flexio_uart_share.h" +#if FSL_FEATURE_SOC_DMA_COUNT + +/*! + * @addtogroup flexio_uart_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @brief Runtime state structure for FlexIO UART driver with DMA. + */ +typedef struct flexio_uart_dmastate { + flexio_uart_mode_t mode; + flexio_uart_tx_dev_t txDev; + flexio_uart_rx_dev_t rxDev; + volatile bool isTxBusy; /*!< True if there is an active transmit. */ + volatile bool isRxBusy; /*!< True if there is an active receive. */ + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its TX business. */ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its RX business. */ + dma_channel_t dmaUartTx; /*!< DMA channel used for send. */ + dma_channel_t dmaUartRx; /*!< DMA channel used for receive. */ +} flexio_uart_dmastate_t; + +/*! + * @brief User configuration structure for the FlexIO UART driver with DMA. + * + * Use an instance of this structure with the FLEXIO_UART_DRV_DmaInit()function. This enables + * configuration of the most common settings of the UART peripheral with a single function call. + * Settings include: UART baud rate, UART parity mode: disabled (default), or even or odd, + * the number of stop bits, and the number of bits per data word. + */ +typedef struct flexio_uartdma_userconfig { + uint32_t baudRate; /*!< UART baud rate*/ + flexio_uart_bit_count_per_char_t bitCountPerChar; /*!< number of bits, 5/6/7/8 bits configurable*/ + flexio_uart_mode_t uartMode; /*!< FlexIO UART working modes: Tx only, Rx only, or both*/ + flexio_uart_hwconfig_t txConfig; /*!< FlexIO UART TX device hardware resource configuration*/ + flexio_uart_hwconfig_t rxConfig; /*!< FlexIO UART RX device hardware resource configuration*/ +} flexio_uartdma_userconfig_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name FlexIO UART DMA Driver + * @{ + */ + +/*! + * @brief Initializes a FlexIO-simulated UART device to work with DMA. + * + * This function initializes the run-time state structure to keep track of the on-going + * transfers and the module to user-defined settings and default settings. It also + * configures the underlying FlexIO pin, shifter, and timer resource, and enables the FlexIO + * simulated UART module DMA interrupt. + * This example shows how to set up the flexio_uartdma_state_t and the + * flexio_uartdma_userconfig_t parameters and how to call the FLEXIO_UART_DRV_DmaInit function + * by passing in these parameters: + @code + flexio_uartdma_userconfig_t uartDmaConfig; + uartDmaConfig.baudRate = 9600; + uartDmaConfig.bitCountPerChar = kUart8BitsPerChar; + uartDmaConfig.uartMode = flexioUART_TxRx; + @endcode + * + * @param instance The FlexIO instance number. + * @param uartDmaState A pointer to the global FlexIO UART driver state structure memory. + * The user passes in the memory for the run-time state structure. The FlexIO UART driver + * populates the members. This run-time state structure keeps track of the + * current transfer in progress. + * @param uartDmaConfig The user configuration structure of type flexio_uartdma_userconfig_t. + * The user populates the members of this structure and passes the pointer of this structure + * to this function. + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_DmaInit(uint32_t instance, flexio_uart_dmastate_t * uartDmaState, + const flexio_uartdma_userconfig_t * uartDmaConfig); +/*! + * @brief Shuts down the FlexIO UART. + * + * This function disables the FlexIO-simulated UART-DMA trigger. + * + * @param uartDmaState The run-time structure of FlexIO-simulated UART. + */ +void FLEXIO_UART_DRV_DmaDeinit(flexio_uart_dmastate_t * uartDmaState); + +/*! + * @brief Sends (transmits) data out through the FlexIO-simulated UART-DMA module using a + * blocking method. + * @param uartDmaState The run-time structure of FlexIO-simulated UART. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_DmaSendDataBlocking(flexio_uart_dmastate_t * uartDmaState, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the FlexIO-simulated UART-DMA module using a + * non-blocking method. + * @param uartDmaState The run-time structure of FlexIO-simulated UART. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_DmaSendData(flexio_uart_dmastate_t * uartDmaState, + const uint8_t * txBuff, + uint32_t txSize); +/*! + * @brief Returns whether the previous FlexIO-simulated UART-DMA transmit has finished. + * + * @param uartDmaState The run-time structure of FlexIO-simulated UART. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes that + * are remaining in the active transfer. + * @return An error code or kStatus_FlexIO_UART_Success. + * @retval kStatus_FlexIO_UART_Success The transmit has completed successfully. + * @retval kStatus_FlexIO_UART_TxBusy The transmit is still in progress. @a bytesTransmitted is + * filled with the number of bytes which are transmitted up to that point. + */ +flexio_uart_status_t FLEXIO_UART_DRV_DmaGetTransmitStatus(flexio_uart_dmastate_t * uartDmaState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated UART-DMA transmission early. + * + * @param uartDmaState The run-time structure of FlexIO-simulated UART. + * @return An error code or kStatus_FlexIO_UART_Success. + * @retval kStatus_FlexIO_UART_Success The transmit was successful. + * @retval kStatus_FlexIO_UART_NoTransmitInProgress No transmission is currently in progress. + */ +flexio_uart_status_t FLEXIO_UART_DRV_DmaAbortSendingData(flexio_uart_dmastate_t * uartDmaState); + +/*! + * @brief Gets (receives) data from the FlexIO-simulated UART-DMA module using a blocking method. + * + * @param uartDmaState The run-time structure of FlexIO-simulated UART. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_DmaReceiveDataBlocking(flexio_uart_dmastate_t * uartDmaState, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout); +/*! + * @brief Gets (receives) data from the FlexIO-simulated UART-DMA module using a non-blocking method. + * + * @param uartDmaState The run-time structure of FlexIO-simulated UART. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_DmaReceiveData(flexio_uart_dmastate_t * uartDmaState, + uint8_t * rxBuff, + uint32_t rxSize); + +/*! + * @brief Returns whether the previous FlexIO-simulated UART-DMA receive is complete. + * + * @param uartDmaState The run-time structure of FlexIO-simulated UART. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes which + * still need to be received in the active transfer. + * @return An error code or kStatus_FlexIO_UART_Success. + * @retval kStatus_FlexIO_UART_Success The receive has completed successfully. + * @retval kStatus_FlexIO_UART_RxBusy The receive is still in progress. @a bytesReceived is + * filled with the number of bytes which are received up to that point. + */ +flexio_uart_status_t FLEXIO_UART_DRV_DmaGetReceiveStatus(flexio_uart_dmastate_t * uartDmaState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated UART-DMA receive early. + * + * @param uartDmaState The run-time structure of FlexIO-simulated UART. + * @return An error code or kStatus_UART_Success. + * @retval kStatus_FlexIO_UART_Success The receive was successful. + * @retval kStatus_FlexIO_UART_NoTransmitInProgress No receive is currently in progress. + */ +flexio_uart_status_t FLEXIO_UART_DRV_DmaAbortReceivingData(flexio_uart_dmastate_t * uartDmaState); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif + +#endif /* __FSL_FLEXIO_UART_DMA_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_uart_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_uart_driver.h new file mode 100755 index 0000000..7dc1c63 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_uart_driver.h @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_DRIVER_H__ +#define __FSL_FLEXIO_UART_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_os_abstraction.h" +#include "fsl_flexio_uart_hal.h" +#include "fsl_flexio_driver.h" +#include "fsl_flexio_uart_share.h" +#if FSL_FEATURE_SOC_FLEXIO_COUNT + +/*! + * @addtogroup flexio_uart_driver + * @{ + */ + +/*! @brief UART receive callback function type */ +typedef void (* flexio_uart_rx_callback_t)(void * uartState); + +/*! + * @brief User configuration structure for the FlexIO UART driver. + * + * Use an instance of this structure with the FLEXIO_UART_DRV_Init()function. This enables configuration of the + * settings of the FlexIO UART peripheral with a single function call. Settings include: + * UART baud rate, the number of bits per data word, FlexIO UART mode, TX hardware resource and Rx hardware + * resource. + * @internal gui name="UART configuration" id="uartCfg" + */ +typedef struct flexio_uart_userconfig{ + uint32_t baudRate; /*!< UART baud rate @internal gui name="Baudrate" id="uartBaudrate" */ + flexio_uart_bit_count_per_char_t bitCounter; /*!< number of bits, 5/6/7/8 bits configurable @internal gui name="Bits" id="uartBits" */ + flexio_uart_mode_t uartMode; /*!< FLEXIO UART working modes: Tx Only,Rx Only or both @internal gui name="Mode" id="uartMode" */ + flexio_uart_hwconfig_t txConfig; /*!< FLEXIO UART TX device hardware resource config @internal gui name="Tx configuration" id="txConfig" */ + flexio_uart_hwconfig_t rxConfig; /*!< FLEXIO UART RX device hardware resource config @internal gui name="Rx configuration" id="rxConfig" */ +}flexio_uart_userconfig_t; +/*! + * @brief Runtime state of the FlexIO UART driver. + * + * This structure holds data that are used by the FlexIO UART peripheral driver to + * communicate between the transfer function and the interrupt handler. The + * interrupt handler also uses this information to keep track of its progress. + * The user passes in the memory for the run-time state structure and the + * FlexIO UART driver fills out the members. + */ +typedef struct flexio_uart_state{ + flexio_uart_mode_t mode; + flexio_uart_tx_dev_t txDev; + flexio_uart_rx_dev_t rxDev; + const uint8_t *txBuff; + uint8_t *rxBuff; + volatile size_t txSize; + volatile size_t rxSize; + volatile bool isTxBusy; + volatile bool isRxBusy; + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its TX business. */ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its RX business. */ + flexio_uart_rx_callback_t rxCallback; /*!< Callback to invoke after receiving byte.*/ + void * rxCallbackParam; /*!< Receive callback parameter pointer.*/ +}flexio_uart_state_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif +/*! + * @name FLEXIO UART Driver + * @{ + */ + +/*! + * @brief Initializes a FlexIO-simulated UART device . + * + * This function initializes the run-time state structure to keep track of the on-going + * transfers and the module to user-defined settings and default settings. It also + * configures the underlying FlexIO pin, shifter, and timer resource, and enables the FlexIO + * simulated UART module interrupt. + * This example shows how to set up the flexio_uart_state_t and the + * flexio_uart_userconfig_t parameters and how to call the FLEXIO_UART_DRV_Init function + * by passing in these parameters: + @code + flexio_uart_userconfig_t uartConfig; + uartConfig.baudRate = 9600; + uartConfig.bitCountPerChar = kUart8BitsPerChar; + uartConfig.uartMode = flexioUART_TxRx; + @endcode + * + * @param instance The FlexIO instance number. + * @param uartState A pointer to the global FlexIOs UART driver state structure memory. + * The user passes in the memory for the run-time state structure. The FlexIO UART driver + * populates the members. This run-time state structure keeps track of the + * current transfer in progress. + * @param uartConfig The user configuration structure of type flexio_uart_userconfig_t. + * The user populates the members of this structure and passes the pointer of this structure + * to this function. + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_Init(uint32_t instance, flexio_uart_state_t * uartState, + const flexio_uart_userconfig_t * uartConfig); +/*! + * @brief Shuts down the FlexIO UART. + * + * This function disables the FlexIO-simulated UART trigger. + * + * @param uartState The run-time structure of FlexIO-simulated UART. + */ +void FLEXIO_UART_DRV_Deinit(flexio_uart_state_t *uartState); +/*! + * @brief Installs callback function for the FlexIO-simulated UART receive. + * + * @note Once a callback is installed, it bypasses the UART driver logic. + * Therefore, the callback needs to handle the rxBuff and rxSize indexes. + * + * @param uartState The run-time structure of FlexIO-simulated UART. + * @param function The UART receive callback function. + * @param rxBuff The receive buffer used inside IRQHandler. This buffer must be kept as long as the callback is alive. + * @param callbackParam The UART receive callback parameter pointer. + * @param alwaysEnableRxIrq Whether always enable Rx IRQ or not. + * @return Former UART receive callback function pointer. + */ +flexio_uart_rx_callback_t FLEXIO_UART_DRV_InstallRxCallback(flexio_uart_state_t *uartState,flexio_uart_rx_callback_t function, + uint8_t * rxBuff,void * callbackParam,bool alwaysEnableRxIrq); +/*! + * @brief Sends (transmits) data out through the FlexIO-simulated UART module using a + * blocking method. + * @param uartState The run-time structure of FlexIO-simulated UART. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_SendDataBlocking(flexio_uart_state_t *uartState, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); +/*! + * @brief Sends (transmits) data through the FlexIO-simulated UART module using a + * non-blocking method. + * @param uartState The run-time structure of FlexIO-simulated UART. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_SendData(flexio_uart_state_t *uartState, + const uint8_t * txBuff, + uint32_t txSize); +/*! + * @brief Returns whether the previous FlexIO-simulated UART transmit has finished. + * + * @param uartState The run-time structure of FlexIO-simulated UART. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes that + * are remaining in the active transfer. + * @return An error code or kStatus_FlexIO_UART_Success. + * @retval kStatus_FlexIO_UART_Success The transmit has completed successfully. + * @retval kStatus_FlexIO_UART_TxBusy The transmit is still in progress. @a bytesTransmitted is + * filled with the number of bytes which are transmitted up to that point. + */ +flexio_uart_status_t FLEXIO_UART_DRV_GetTransmitStatus(flexio_uart_state_t *uartState, uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated UART transmission early. + * + * @param uartState The run-time structure of FlexIO-simulated UART. + * @return An error code or kStatus_FlexIO_UART_Success. + * @retval kStatus_FlexIO_UART_Success The transmit was successful. + * @retval kStatus_FlexIO_UART_NoTransmitInProgress No transmission is currently in progress. + */ +flexio_uart_status_t FLEXIO_UART_DRV_AbortSendingData(flexio_uart_state_t *uartState); +/*! + * @brief Gets (receives) data from the FlexIO-simulated UART module using a blocking method. + * + * @param uartState The run-time structure of FlexIO-simulated UART. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_ReceiveDataBlocking(flexio_uart_state_t *uartState, uint8_t * rxBuff, + uint32_t rxSize, uint32_t timeout); +/*! + * @brief Gets (receives) data from the FlexIO-simulated UART module using a non-blocking method. + * + * @param uartState The run-time structure of FlexIO-simulated UART. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_ReceiveData(flexio_uart_state_t *uartState, + uint8_t * rxBuff, + uint32_t rxSize); +/*! + * @brief Returns whether the previous FlexIO-simulated UART receive is complete. + * + * @param uartState The run-time structure of FlexIO-simulated UART. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes which + * still need to be received in the active transfer. + * @return An error code or kStatus_FlexIO_UART_Success. + * @retval kStatus_FlexIO_UART_Success The receive has completed successfully. + * @retval kStatus_FlexIO_UART_RxBusy The receive is still in progress. @a bytesReceived is + * filled with the number of bytes which are received up to that point. + */ +flexio_uart_status_t FLEXIO_UART_DRV_GetReceiveStatus(flexio_uart_state_t *uartState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated UART receive early. + * + * @param uartState The run-time structure of FlexIO-simulated UART. + * @return An error code or kStatus_UART_Success. + * @retval kStatus_FlexIO_UART_Success The receive was successful. + * @retval kStatus_FlexIO_UART_NoTransmitInProgress No receive is currently in progress. + */ +flexio_uart_status_t FLEXIO_UART_DRV_AbortReceivingData(flexio_uart_state_t *uartState); +/*! + * @brief Interrupt handler for FlexIO-simulated UART TX. + * @param param The run-time structure of FlexIO-simulated UART. + */ +void FLEXIO_UART_DRV_TX_IRQHandler(void *param); +/*! + * @brief Interrupt handler for FlexIO-simulated UART RX. + * @param param The run-time structure of FlexIO-simulated UART. + */ +void FLEXIO_UART_DRV_RX_IRQHandler(void *param); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif + +#endif /* __FSL_FLEXIO_UART_DRIVER_H__*/ diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_uart_edma_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_uart_edma_driver.h new file mode 100755 index 0000000..7afa535 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_uart_edma_driver.h @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_EDMA_DRIVER_H__ +#define __FSL_FLEXIO_UART_EDMA_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_os_abstraction.h" +#include "fsl_flexio_uart_hal.h" +#include "fsl_edma_driver.h" +#include "fsl_flexio_driver.h" +#include "fsl_flexio_uart_share.h" + +#if FSL_FEATURE_SOC_DMA_COUNT + +/*! + * @addtogroup flexio_uart_driver + * @{ + */ + +/*! + * @brief User configuration structure for the FlexIO UART driver. + * + * Use an instance of this structure with the FLEXIO_UART_DRV_Init()function. This enables configuration of the + * settings of the FlexIO UART peripheral with a single function call. Settings include: + * UART baud rate, the number of bits per data word, FlexIO UART mode, TX hardware resource and Rx hardware + * resource. + */ +typedef struct flexio_uartedma_userconfig{ + uint32_t baudRate; + flexio_uart_bit_count_per_char_t bitCounter; + flexio_uart_mode_t uartMode; + flexio_uart_hwconfig_t txConfig; + flexio_uart_hwconfig_t rxConfig; +}flexio_uartedma_userconfig_t; +/*! + * @brief Runtime state of the FlexIO UART driver. + * + * This structure holds data that are used by the FlexIO UART peripheral driver to + * communicate between the transfer function and the interrupt handler. The + * interrupt handler also uses this information to keep track of its progress. + * The user passes in the memory for the run-time state structure and the + * FlexIO UART driver fills out the members. + */ +typedef struct flexio_uart_edmastate{ + flexio_uart_mode_t mode; + flexio_uart_tx_dev_t txDev; + flexio_uart_rx_dev_t rxDev; + volatile bool isTxBusy; + volatile bool isRxBusy; + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its TX business. */ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its RX business. */ + edma_chn_state_t edmaUartTx; /*!< Structure definition for the EDMA channel */ + edma_chn_state_t edmaUartRx; /*!< Structure definition for the EDMA channel */ +}flexio_uart_edmastate_t; +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name FlexIO UART eDMA Driver + * @{ + */ + +/*! + * @brief Initializes a FlexIO-simulated UART device to work with eDMA. + * + * This function initializes the run-time state structure to keep track of the on-going + * transfers, initializes the module to user-defined settings and default settings, + * configures underlying FlexIO pin, shifter, and timer resource, and enables the FlexIO + * simulated UART module eDMA interrupt. + * This example shows how to set up the flexio_uartedma_state_t and the + * flexio_uartedma_userconfig_t parameters and how to call the FLEXIO_UART_DRV_EdmaInit function + * by passing in these parameters: + @code + flexio_uartedma_userconfig_t uartEdmaConfig; + uartEdmaConfig.baudRate = 9600; + uartEdmaConfig.bitCountPerChar = kUart8BitsPerChar; + uartEdmaConfig.uartMode = flexioUART_TxRx; + @endcode + * + * @param instance The FlexIO instance number. + * @param uartEdmaState A pointer to the global FlexIO UART driver state structure memory. + * The user passes in the memory for the run-time state structure. The FlexIO UART driver + * populates the members. This run-time state structure keeps track of the + * current transfer in progress. + * @param uartEdmaConfig The user configuration structure of type flexio_uartedma_userconfig_t. + * The user populates the members of this structure and passes the pointer of this structure + * to this function. + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaInit(uint32_t instance, flexio_uart_edmastate_t * uartEdmaState, + const flexio_uartedma_userconfig_t * uartEdmaConfig); +/*! + * @brief Shuts down the FlexIO UART. + * + * This function disables the FlexIO-simulated UART-eDMA trigger. + * + * @param uartEdmaState The run-time structure of FlexIO-simulated UART. + */ +void FLEXIO_UART_DRV_EdmaDeinit(flexio_uart_edmastate_t * uartEdmaState); + +/*! + * @brief Sends (transmits) data out through the FlexIO-simulated UART-EDMA module using a + * blocking method. + * @param uartEdmaState The run-time structure of FlexIO-simulated UART. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaSendDataBlocking(flexio_uart_edmastate_t * uartEdmaState, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the FlexIO-simulated UART-EDMA module using a + * non-blocking method. + * @param uartEdmaState The run-time structure of FlexIO-simulated UART. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaSendData(flexio_uart_edmastate_t * uartEdmaState, + const uint8_t * txBuff, + uint32_t txSize); +/*! + * @brief Returns whether the previous FlexIO-simulated UART-EDMA transmit has finished. + * + * @param uartEdmaState The run-time structure of FlexIO-simulated UART. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes that + * are remaining in the active transfer. + * @return An error code or kStatus_FlexIO_UART_Success. + * @retval kStatus_FlexIO_UART_Success The transmit has completed successfully. + * @retval kStatus_FlexIO_UART_TxBusy The transmit is still in progress. @a bytesTransmitted is + * filled with the number of bytes which are transmitted up to that point. + */ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaGetTransmitStatus(flexio_uart_edmastate_t * uartEdmaState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated UART-eDMA transmission early. + * + * @param uartEdmaState The run-time structure of FlexIO-simulated UART. + * @return An error code or kStatus_FlexIO_UART_Success. + * @retval kStatus_FlexIO_UART_Success The transmit was successful. + * @retval kStatus_FlexIO_UART_NoTransmitInProgress No transmission is currently in progress. + */ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaAbortSendingData(flexio_uart_edmastate_t * uartEdmaState); + +/*! + * @brief Gets (receives) data from the FlexIO-simulated UART-eDMA module using a blocking method. + * + * @param uartEdmaState The run-time structure of FlexIO-simulated UART. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaReceiveDataBlocking(flexio_uart_edmastate_t * uartEdmaState, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout); +/*! + * @brief Gets (receives) data from the FlexIO-simulated UART-eDMA module using a non-blocking method. + * + * @param uartEdmaState The run-time structure of FlexIO-simulated UART. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_FlexIO_UART_Success. + */ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaReceiveData(flexio_uart_edmastate_t * uartEdmaState, + uint8_t * rxBuff, + uint32_t rxSize); + +/*! + * @brief Returns whether the previous FlexIO-simulated UART-eDMA receive is complete. + * + * @param uartEdmaState The run-time structure of FlexIO-simulated UART. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes which + * still need to be received in the active transfer. + * @return An error code or kStatus_FlexIO_UART_Success. + * @retval kStatus_FlexIO_UART_Success The receive has completed successfully. + * @retval kStatus_FlexIO_UART_RxBusy The receive is still in progress. @a bytesReceived is + * filled with the number of bytes which are received up to that point. + */ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaGetReceiveStatus(flexio_uart_edmastate_t * uartEdmaState, + uint32_t * bytesRemaining); +/*! + * @brief Terminates a non-blocking FlexIO-simulated UART-eDMA receive early. + * + * @param uartEdmaState The run-time structure of FlexIO-simulated UART. + * @return An error code or kStatus_UART_Success. + * @retval kStatus_FlexIO_UART_Success The receive was successful. + * @retval kStatus_FlexIO_UART_NoTransmitInProgress No receive is currently in progress. + */ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaAbortReceivingData(flexio_uart_edmastate_t * uartEdmaState); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif + +#endif /* __FSL_FLEXIO_UART_DRIVER_H__*/ diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_uart_share.h b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_uart_share.h new file mode 100755 index 0000000..e80e277 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_flexio_uart_share.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_SHARE_H__ +#define __FSL_FLEXIO_UART_SHARE_H__ + +#include <stdint.h> +#include <stdbool.h> +#if FSL_FEATURE_SOC_FLEXIO_COUNT + +/*! + * @addtogroup flexio_uart_driver + * @{ + */ + +/*! @brief Error codes for the FLEXIO UART driver. */ +typedef enum flexio_uart_status +{ + kStatus_FlexIO_UART_Success = 0x00U, + kStatus_FlexIO_UART_TxBusy = 0x01U, + kStatus_FlexIO_UART_RxBusy = 0x02U, + kStatus_FlexIO_UART_NoTransmitInProgress = 0x03U, + kStatus_FlexIO_UART_NoReceiveInProgress = 0x04U, + kStatus_FlexIO_UART_Timeout = 0x05U, + kStatus_FlexIO_UART_NoDataToDeal = 0x06U, + kStatus_FlexIO_UART_TxUnderRun = 0x07U, + kStatus_FlexIO_UART_RxOverRun = 0x08U, + kStatus_FlexIO_UART_InvalidParam = 0x09U +} flexio_uart_status_t; +/*! + * @brief FlexIO UART number of bits in a character. + * + * These constants define the number of allowable data bits per UART character. Note, check the + * UART documentation to determine if the desired UART baseAddr supports the desired number + * of data bits per UART character. + */ +typedef enum flexio_uart_bit_count_per_char { + kFlexIOUart5BitsPerChar = 5U, /*!< 5-bit data characters @internal gui name="5" */ + kFlexIOUart6BitsPerChar = 6U, /*!< 6-bit data characters @internal gui name="6" */ + kFlexIOUart7BitsPerChar = 7U, /*!< 7-bit data characters @internal gui name="7" */ + kFlexIOUart8BitsPerChar = 8U /*!< 8-bit data characters @internal gui name="8" */ +} flexio_uart_bit_count_per_char_t; +/*! + * @brief FlexIO UART mode. + * + * These constants define the operation mode of FlexIO UART: Only enable transmit, only enable receive, + * or use both. + */ +typedef enum flexio_uart_mode +{ + flexioUART_TxOnly = 0x0U, /*!< Transmit mode only @internal gui name="Tx" */ + flexioUART_RxOnly = 0x1U, /*!< Receive mode only @internal gui name="Rx" */ + flexioUART_TxRx = 0x2U /*!< Both modes @internal gui name="Tx+Rx" */ +}flexio_uart_mode_t; +/*! + * @brief FlexIO UART hardware resource configuration. + * + * These constants define the hardware resource used by the FlexIO UART transmit/receive device and include + * the external pin and internal shifter and timer. + * @internal gui name="UART hardware configuration" id="uartHwCfg" + */ +typedef struct flexio_uart_hwconfig{ + uint32_t pinIdx; /*!< Data line pin. @internal gui name="Data pin" id="uartPin" */ + uint32_t shifterIdx; /*!< Shifter @internal gui name="Shifter" id="uartShifter" */ + uint32_t timerIdx; /*!< Timer @internal gui name="Timer" id="uartTimer" */ +}flexio_uart_hwconfig_t; + +/*! @}*/ + +#endif + +#endif /* __FSL_FLEXIO_UART_SHARE_H__*/ diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_ftm_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_ftm_driver.h new file mode 100755 index 0000000..eae2059 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_ftm_driver.h @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_FTM_DRIVER_H__ +#define __FSL_FTM_DRIVER_H__ + +#include "fsl_ftm_hal.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_FTM_COUNT + +/*! + * @addtogroup ftm_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Table of base addresses for FTM instances. */ +extern FTM_Type * const g_ftmBase[FTM_INSTANCE_COUNT]; + +/*! @brief Table to save FTM IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_ftmIrqId[FTM_INSTANCE_COUNT]; + +/*! @brief Configuration structure that the user needs to set + */ +typedef struct FtmUserConfig { + uint8_t tofFrequency; /*!< Select ratio between number of overflows to times TOF is set @internal gui name="Overflow frequency" id="OvFrequency" */ + ftm_bdm_mode_t BDMMode; /*!< Select FTM behavior in BDM mode @internal gui name="BDM mode" id="BdmMode" */ + bool isWriteProtection; /*!< true: enable write protection, false: write protection is disabled @internal gui name="Write protection" id="WriteProtection" */ + uint32_t syncMethod; /*!< Register synch options available in the ftm_sync_method_t enumeration @internal gui name="Triggers" id="Triggers" */ +} ftm_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the FTM driver. + * + * @param instance The FTM peripheral instance number. + * @param info The FTM user configuration structure, see #ftm_user_config_t. + * @return kStatusFtmSuccess means succees, otherwise means failed. + */ +ftm_status_t FTM_DRV_Init(uint32_t instance, const ftm_user_config_t *info); + +/*! + * @brief Shuts down the FTM driver. + * + * @param instance The FTM peripheral instance number. + */ +void FTM_DRV_Deinit(uint32_t instance); + +/*! + * @brief Stops the channel PWM. + * + * @param instance The FTM peripheral instance number. + * @param param FTM driver PWM parameter to configure PWM options + * @param channel The channel number. In combined mode, the code finds the channel + * pair associated with the channel number passed in. + */ +void FTM_DRV_PwmStop(uint32_t instance, ftm_pwm_param_t *param, uint8_t channel); + +/*! + * @brief Configures the duty cycle and frequency and starts outputting the PWM on a specified channel . + * + * @param instance The FTM peripheral instance number. + * @param param FTM driver PWM parameter to configure PWM options + * @param channel The channel number. In combined mode, the code finds the channel + * pair associated with the channel number passed in. + * @return kStatusFtmSuccess if the PWM setup was successful, + * kStatusFtmError on failure as the PWM counter is disabled + */ +ftm_status_t FTM_DRV_PwmStart(uint32_t instance, ftm_pwm_param_t *param, uint8_t channel); + +/*! + * @brief Configures the parameters and activates the quadrature decode mode. + * + * @param instance Instance number of the FTM module. + * @param phaseAParams Phase A configuration parameters + * @param phaseBParams Phase B configuration parameters + * @param quadMode Selects encoding mode used in quadrature decoder mode + */ +void FTM_DRV_QuadDecodeStart(uint32_t instance, ftm_phase_params_t *phaseAParams, + ftm_phase_params_t *phaseBParams, ftm_quad_decode_mode_t quadMode); + +/*! + * @brief De-activates the quadrature decode mode. + * + * @param instance Instance number of the FTM module. + */ +void FTM_DRV_QuadDecodeStop(uint32_t instance); + +/*! + * @brief Starts the FTM counter. + * + * This function provides access to the FTM counter. The counter can be run in + * up-counting and up-down counting modes. To run the counter in free running mode, + * choose the up-counting option and provide 0x0 for the countStartVal and 0xFFFF for + * countFinalVal. + * + * @param instance The FTM peripheral instance number. + * @param countMode The FTM counter mode defined by ftm_counting_mode_t. + * @param countStartVal The starting value that is stored in the CNTIN register. + * @param countFinalVal The final value that is stored in the MOD register. + * @param enableOverflowInt true: enable timer overflow interrupt; false: disable + */ +void FTM_DRV_CounterStart(uint32_t instance, ftm_counting_mode_t countMode, uint32_t countStartVal, + uint32_t countFinalVal, bool enableOverflowInt); + +/*! + * @brief Stops the FTM counter. + * + * @param instance The FTM peripheral instance number. + */ +void FTM_DRV_CounterStop(uint32_t instance); + +/*! + * @brief Reads back the current value of the FTM counter. + * + * @param instance The FTM peripheral instance number. + */ +uint32_t FTM_DRV_CounterRead(uint32_t instance); + +/*! + * @brief Set FTM clock source. + * + * This function will save the users clock source selection in the driver and + * uses this to set the clock source whenever the user decides to use features provided + * by this driver like counter, PWM generation etc. It will also set the clock divider. + * + * @param instance The FTM peripheral instance number. + * @param clock The clock source to use, cannot pick None. + * @param clockPs The clock divider value. + */ +void FTM_DRV_SetClock(uint8_t instance, ftm_clock_source_t clock, ftm_clock_ps_t clockPs); + +/*! + * @brief Retrieves the frequency of the clock source feeding the FTM counter. + * + * Function will return a 0 if no clock source is selected and the FTM counter is disabled + * + * @param instance The FTM peripheral instance number. + * @return The frequency of the clock source running the FTM counter, returns 0 if counter is disabled + */ +uint32_t FTM_DRV_GetClock(uint8_t instance); + +/*! + * @brief Enables or disables the timer overflow interrupt. + * + * @param instance The FTM peripheral instance number. + * @param overflowEnable true: enable the timer overflow interrupt, false: disable + */ +void FTM_DRV_SetTimeOverflowIntCmd(uint32_t instance, bool overflowEnable); + +/*! + * @brief Enables or disables the fault interrupt. + * + * @param instance The FTM peripheral instance number. + * @param faultEnable true: enable the fault interrupt, false: disable + */ +void FTM_DRV_SetFaultIntCmd(uint32_t instance, bool faultEnable); + +/*! + * @brief Enables capture of an input signal on the channel using the function parameters. + * + * When the edge specified in the captureMode argument occurs on the channel the FTM counter is captured into + * the CnV register. The user has to read the CnV register separately to get this value. The filter + * function is disabled if the filterVal argument passed in is 0. The filter function is available only for + * 0, 1, 2, 3 channels. + * + * @param instance The FTM peripheral instance number + * @param captureMode Specifies which edge to capture + * @param channel The channel number + * @param filterVal Filter value to be used, specify 0 to disable filter. Available only for channels 0-3 + */ +void FTM_DRV_SetupChnInputCapture(uint32_t instance, ftm_input_capture_edge_mode_t captureMode, + uint8_t channel, uint8_t filterVal); + +/*! + * @brief Configures the FTM to generate timed pulses. + * + * When the FTM counter matches the value of compareVal argument (this is written into CnV reg), the channel + * output is changed based on what is specified in the compareMode argument. + * + * @param instance The FTM peripheral instance number. + * @param compareMode Action to take on the channel output when the compare condition is met + * @param channel The channel number + * @param compareVal Value to be programmed in the CnV register. + */ +void FTM_DRV_SetupChnOutputCompare(uint32_t instance, ftm_output_compare_edge_mode_t compareMode, + uint8_t channel, uint32_t compareVal); + +/*! + * @brief Configures the dual edge capture mode of the FTM. + * + * This function sets up the dual edge capture mode on a channel pair. The capture edge for the channel + * pair and the capture mode (one-shot or continuous) is specified in the parameter argument. The filter function + * is disabled if the filterVal argument passed in is 0. The filter function is available only on + * channels 0 and 2. The user has to read the channel CnV registers separately to get the capture values. + * + * @param instance The FTM peripheral instance number. + * @param param Controls the dual edge capture function + * @param channel The channel number, the code finds the channel pair associated with the channel + * number passed in. + * @param filterVal Filter value to be used, specify 0 to disable filter. Available only for channels 0, 2 + */ +void FTM_DRV_SetupChnDualEdgeCapture(uint32_t instance, ftm_dual_edge_capture_param_t *param, + uint8_t channel, uint8_t filterVal); + +/*! + * @brief Action to take when an FTM interrupt is triggered. + * + * The timer overflow flag is checked and cleared if set. + * + * @param instance Instance number of the FTM module. + */ +void FTM_DRV_IRQHandler(uint32_t instance); + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* FSL_FEATURE_SOC_FTM_COUNT */ + +#endif /* __FSL_FTM_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_gpio_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_gpio_driver.h new file mode 100755 index 0000000..f68baf0 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_gpio_driver.h @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_GPIO_DRIVER_H__ +#define __FSL_GPIO_DRIVER_H__ + +#include <stdint.h> +#include <stdlib.h> +#include <stdbool.h> +#include "fsl_port_hal.h" +#include "fsl_gpio_hal.h" + +/*! + * @addtogroup gpio_driver + * @{ + */ + +/*! + * @file + * + * The GPIO driver uses the virtual GPIO name rather than an actual port and a + * pin number. By using the virtual name, each pin name is self-explanatory. + * To use the GPIO driver, an enumeration variable must be predefined in the + * user application files. The variable saves all GPIO pin information used + * in a project. + * + * This example shows how to define the enumeration variable. + @code + // This is the enumeration to define virtual GPIO pin names. + // These members are used by "uint32_t pinName" in + // gpio_output_pin_user_config_t + // and gpio_input_pin_user_config_t. Usually defined in a header file. + enum _gpio_pins + { + kGpioLED1 = GPIO_MAKE_PIN(GPIOA_IDX, 5), // Orange LED. + kGpioLED2 = GPIO_MAKE_PIN(GPIOA_IDX, 6), // Yellow LED. + kGpioLED3 = GPIO_MAKE_PIN(GPIOA_IDX, 7), // Green LED. + kGpioLED4 = GPIO_MAKE_PIN(GPIOB_IDX, 8), // Red LED. + }; + @endcode + * + * The port features such as "digital filter", "pull", are valid when + * they are available in one of the pins. That doesn't mean, however, that all pins have the + * capability to use such features. See the related reference manual for + * accurate pin features. + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for GPIO instances. */ +extern GPIO_Type * const g_gpioBase[GPIO_INSTANCE_COUNT]; + +/*! @brief Table of base addresses for PORT instances. */ +extern PORT_Type * const g_portBase[PORT_INSTANCE_COUNT]; + +/* Table to save PORT IRQ enumeration numbers defined in CMSIS header file */ +extern const IRQn_Type g_portIrqId[PORT_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @name GPIO Pin Macros + * @{ + */ + +/*! @brief Indicates the end of a pin configuration structure.*/ +#define GPIO_PINS_OUT_OF_RANGE (0xFFFFFFFFU) + +/*! @brief Bits shifted for the GPIO port number. */ +#define GPIO_PORT_SHIFT (0x8U) + +/*! @brief Combines the port number and the pin number into a single scalar value. */ +#define GPIO_MAKE_PIN(r,p) (((r)<< GPIO_PORT_SHIFT) | (p)) + +/*! @brief Extracts the port number from a combined port and pin value.*/ +#define GPIO_EXTRACT_PORT(v) (((v) >> GPIO_PORT_SHIFT) & 0xFFU) + +/*! @brief Extracts the pin number from a combined port and pin value.*/ +#define GPIO_EXTRACT_PIN(v) ((v) & 0xFFU) + +/* @} */ + +/*! + * @brief The GPIO input pin configuration structure. + * + * Although every pin is configurable, valid configurations depend on a specific + * device. Users should check the related reference manual to ensure that the + * specific feature is valid in an individual pin. A configuration of + * unavailable features is harmless, but takes no effect. + */ +typedef struct GpioInputPin { + #if FSL_FEATURE_PORT_HAS_PULL_ENABLE + bool isPullEnable; /*!< Enable or disable pull. */ + #endif + #if FSL_FEATURE_PORT_HAS_PULL_SELECTION + port_pull_t pullSelect; /*!< Select internal pull(up/down) resistor.*/ + #endif + #if FSL_FEATURE_PORT_HAS_PASSIVE_FILTER + bool isPassiveFilterEnabled; /*!< Enable or disable passive filter.*/ + #endif + #if FSL_FEATURE_PORT_HAS_DIGITAL_FILTER + /* Digital filter clock source and width should be pre-configured using the port HAL.*/ + bool isDigitalFilterEnabled; /*!< Enable or disable digital filter.*/ + #endif + #if FSL_FEATURE_GPIO_HAS_INTERRUPT_VECTOR + port_interrupt_config_t interrupt; /*!< Select interrupt/DMA request.*/ + #endif +} gpio_input_pin_t; + +/*! + * @brief The GPIO output pin configuration structure. + * + * Although every pin is configurable, valid configurations + * depend on a specific device. Users should check the related reference manual to + * ensure that the specific feature is valid in an individual pin. The configuration of + * unavailable features is harmless, but takes no effect. + */ +typedef struct GpioOutputPin { + uint32_t outputLogic; /*!< Set default output logic.*/ + #if FSL_FEATURE_PORT_HAS_SLEW_RATE + port_slew_rate_t slewRate; /*! Select fast/slow slew rate.*/ + #endif + #if FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH + port_drive_strength_t driveStrength;/*!< Select low/high drive strength.*/ + #endif + #if FSL_FEATURE_PORT_HAS_OPEN_DRAIN + bool isOpenDrainEnabled; /*!< Enable or disable open drain.*/ + #endif +} gpio_output_pin_t; + +/*! + * @brief The GPIO input pin structure. + * + * Although the pinName is defined as a uint32_t type, values assigned to the pinName + * should be the enumeration names defined in the enum _gpio_pins. + */ +typedef struct GpioInputPinUserConfig { + uint32_t pinName; /*!< Virtual pin name from enumeration defined by the user.*/ + gpio_input_pin_t config; /*!< Input pin configuration structure.*/ +} gpio_input_pin_user_config_t; + +/*! + * @brief The GPIO output pin structure. + * + * Although the pinName is defined as a uint32_t type, values assigned to the pinName + * should be the enumeration names defined in the enum _gpio_pins. + */ +typedef struct GpioOutputPinUserConfig { + uint32_t pinName; /*!< Virtual pin name from enumeration defined by the user.*/ + gpio_output_pin_t config;/*!< Input pin configuration structure.*/ +} gpio_output_pin_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization + * @{ + */ + +/*! + * @brief Initializes all GPIO pins used by the board. + * + * To initialize the GPIO driver, define two arrays similar to the gpio_input_pin_user_config_t + * inputPin[] array and the gpio_output_pin_user_config_t outputPin[] array in the user file. + * Then, call the GPIO_DRV_Init() function and pass in the two arrays. If the input or output + * pins are not needed, pass in a NULL. + * + * This is an example to define an input pin array: + @code + // Configure the kGpioPTA2 as digital input. + gpio_input_pin_user_config_t inputPin[] = { + { + .pinName = kGpioPTA2, + .config.isPullEnable = false, + .config.pullSelect = kPortPullDown, + .config.isPassiveFilterEnabled = false, + .config.interrupt = kPortIntDisabled, + }, + { + // Note: This pinName must be defined here to indicate the end of the array. + .pinName = GPIO_PINS_OUT_OF_RANGE, + } + }; + @endcode + * + * @param inputPins input GPIO pins pointer. + * @param outputPins output GPIO pins pointer. + */ +void GPIO_DRV_Init(const gpio_input_pin_user_config_t * inputPins, + const gpio_output_pin_user_config_t * outputPins); + +/*! + * @brief Initializes one GPIO input pin used by the board. + * + * @param inputPin input GPIO pins pointer. + */ +void GPIO_DRV_InputPinInit(const gpio_input_pin_user_config_t *inputPin); + +/*! + * @brief Initializes one GPIO output pin used by the board. + * + * @param outputPin output GPIO pins pointer. + */ +void GPIO_DRV_OutputPinInit(const gpio_output_pin_user_config_t *outputPin); + +/* @} */ + +/*! + * @name Pin Direction + * @{ + */ + +/*! + * @brief Gets the current direction of the individual GPIO pin. + * + * @param pinName GPIO pin name defined by the user in the GPIO pin enumeration list. + * @return GPIO directions. + * - kGpioDigitalInput: corresponding pin is set as digital input. + * - kGpioDigitalOutput: corresponding pin is set as digital output. + */ +gpio_pin_direction_t GPIO_DRV_GetPinDir(uint32_t pinName); + +/*! + * @brief Sets the current direction of the individual GPIO pin. + * + * @param pinName GPIO pin name defined by the user in the GPIO pin enumeration list. + * @param direction GPIO directions. + * - kGpioDigitalInput: corresponding pin is set as digital input. + * - kGpioDigitalOutput: corresponding pin is set as digital output. + */ + +void GPIO_DRV_SetPinDir(uint32_t pinName, gpio_pin_direction_t direction); +/* @} */ + +/*! + * @name Output Operations + * @{ + */ + +/*! + * @brief Sets the output level of the individual GPIO pin to the logic 1 or 0. + * + * @param pinName GPIO pin name defined by the user in the GPIO pin enumeration list. + * @param output pin output logic level. + * - 0: corresponding pin output low logic level. + * - Non-0: corresponding pin output high logic level. + */ +void GPIO_DRV_WritePinOutput(uint32_t pinName, uint32_t output); + +/*! + * @brief Sets the output level of the individual GPIO pin to the logic 1. + * + * @param pinName GPIO pin name defined by the user in the GPIO pin enumeration list. + */ +void GPIO_DRV_SetPinOutput(uint32_t pinName); + +/*! + * @brief Sets the output level of the individual GPIO pin to the logic 0. + * + * @param pinName GPIO pin name defined by the user in the GPIO pin enumeration list. + */ +void GPIO_DRV_ClearPinOutput(uint32_t pinName); + +/*! + * @brief Reverses current output logic of the individual GPIO pin. + * + * @param pinName GPIO pin name defined by the user in the GPIO pin enumeration list. + */ +void GPIO_DRV_TogglePinOutput(uint32_t pinName); + +/* @} */ + +/*! + * @name Input Operations + * @{ + */ + +/*! + * @brief Reads the current input value of the individual GPIO pin. + * + * @param pinName GPIO pin name defined by the user in the GPIO pin enumeration list. + * @return GPIO port input value. + * - 0: Pin logic level is 0, or is not configured for use by digital function. + * - 1: Pin logic level is 1. + */ +uint32_t GPIO_DRV_ReadPinInput(uint32_t pinName); + +#if FSL_FEATURE_PORT_HAS_DIGITAL_FILTER +/*! + * @brief Enables or disables the digital filter in a single port. + * + * Each bit of the 32-bit register represents one pin. + * + * @param pinName GPIO pin name defined by the user in the GPIO pin enumeration list. + * @param isDigitalFilterEnabled digital filter enable/disable. + * - false: digital filter is disabled on the corresponding pin. + * - true : digital filter is enabled on the corresponding pin. + */ +void GPIO_DRV_SetDigitalFilterCmd(uint32_t pinName, bool isDigitalFilterEnabled); +#endif + +/* @} */ + +/*! + * @name Interrupt + * @{ + */ + +/*! + * @brief Reads the individual pin-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 pinName GPIO pin name defined by the user in the GPIO pin enumeration list. + * @return current pin interrupt status flag + * - 0: interrupt is not detected. + * - 1: interrupt is detected. + */ +bool GPIO_DRV_IsPinIntPending(uint32_t pinName); + +/*! + * @brief Clears the individual GPIO pin interrupt status flag. + * + * @param pinName GPIO pin name defined by the user in the GPIO pin enumeration list. + */ +void GPIO_DRV_ClearPinIntFlag(uint32_t pinName); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* __FSL_GPIO_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_i2c_master_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_i2c_master_driver.h new file mode 100755 index 0000000..dc50ff3 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_i2c_master_driver.h @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_I2C_MASTER_DRIVER_H__ +#define __FSL_I2C_MASTER_DRIVER_H__ + +#include <stdlib.h> +#include <stdbool.h> +#include "fsl_i2c_hal.h" +#include "fsl_os_abstraction.h" + +/*! + * @addtogroup i2c_master + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for I2C instances. */ +extern I2C_Type * const g_i2cBase[I2C_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Information necessary to communicate with an I2C slave device. + * @internal gui name="Master configuration" id="i2cMasterCfg" + */ +typedef struct I2CDevice +{ + uint16_t address; /*!< Slave's 7-bit or 10-bit address. If 10-bit address, + the first 6 bits must be 011110 in binary. @internal gui name="Address" id="Address" */ + uint32_t baudRate_kbps; /*!< The baud rate in kbps to use by current slave device. @internal gui name="Baudrate" id="BaudRate" */ +} i2c_device_t; + +/*! + * @brief Internal driver state information. + * + * @note The contents of this structure are internal to the driver and should not be + * modified by users. Also, contents of the structure are subject to change in + * future releases. + */ +typedef struct I2CMasterState { + uint8_t * rxBuff; + volatile uint32_t rxSize; + const uint8_t * txBuff; + volatile uint32_t txSize; + volatile i2c_status_t status; + volatile bool i2cIdle; + bool isBlocking; + bool isRequesting; + uint32_t lastBaudRate_kbps; + semaphore_t irqSync; +} i2c_master_state_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name I2C Master + * @{ + */ + +/*! + * @brief Initializes the I2C master mode driver. + * + * @param instance The I2C peripheral instance number. + * @param master The pointer to the I2C master driver state structure. + * @return Error or success status returned by API. + */ +i2c_status_t I2C_DRV_MasterInit(uint32_t instance, i2c_master_state_t * master); + +/*! + * @brief Shuts down the driver. + * + * @param instance The I2C peripheral instance number. + * @return Error or success status returned by API. + */ +i2c_status_t I2C_DRV_MasterDeinit(uint32_t instance); + +/*! + * @brief Configures the I2C bus to access a device. + * + * @param instance The I2C peripheral instance number. + * @param device The pointer to the I2C device information structure. + */ +void I2C_DRV_MasterSetBaudRate(uint32_t instance, const i2c_device_t * device); + +/*! + * @brief Performs a blocking send transaction on the I2C bus. + * + * Both cmdBuff and txBuff are byte aligned, user needs to prepare these buffers + * according to related protocol if slave devices data are not byte-aligned. + * + * @param instance The I2C peripheral instance number. + * @param device The pointer to the I2C device information structure. + * @param cmdBuff The pointer to the commands to be transferred, could be NULL. + * @param cmdSize The length in bytes of the commands to be transferred, could be 0. + * @param txBuff The pointer to the data to be transferred, cannot be NULL. + * @param txSize The length in bytes of the data to be transferred, cannot be 0. + * @param timeout_ms A timeout for the transfer in microseconds. + * @return Error or success status returned by API. + */ +i2c_status_t I2C_DRV_MasterSendDataBlocking(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout_ms); + +/*! + * @brief Performs a non-blocking send transaction on the I2C bus. + * + * This function returns immediately when set buffer pointer and length to transfer buffer and + * transfer Size. The user must check the status of I2C to know the whether transmission + * is finished or not. + * Both cmdBuff and txBuff are byte aligned, user needs to prepare these buffers + * according to related protocol if slave devices data are not byte-aligned. + * + * @param instance The I2C peripheral instance number. + * @param device The pointer to the I2C device information structure. + * @param cmdBuff The pointer to the commands to be transferred,could be NULL. + * @param cmdSize The length in bytes of the commands to be transferred, could be 0. + * @param txBuff The pointer to the data to be transferred, cannot be NULL. + * @param txSize The length in bytes of the data to be transferred, cannot be 0. + * @return Error or success status returned by API. + */ +i2c_status_t I2C_DRV_MasterSendData(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + const uint8_t * txBuff, + uint32_t txSize); + +/*! + * @brief Gets the current status of the I2C master transmit. + * + * This function gets the current I2C status of the non-blocking transmit. + * + * @param instance Instance number of the I2C module. + * @param bytesRemaining The number of remaining bytes in the active I2C transmits. + * @return Current status of I2C transmission: in progress (busy) or complete (success). + */ +i2c_status_t I2C_DRV_MasterGetSendStatus(uint32_t instance, uint32_t *bytesRemaining); + +/*! + * @brief Terminates a non-blocking I2C Master transmission early. + * + * @param instance Instance number of the I2C module. + * @return Whether the aborting is success or not. + */ +i2c_status_t I2C_DRV_MasterAbortSendData(uint32_t instance); + +/*! + * @brief Performs a blocking receive transaction on the I2C bus. + * + * Both cmdBuff and rxBuff are byte aligned, user needs to prepare these buffers + * according to related protocol if slave devices data are not byte-aligned. + * + * @param instance The I2C peripheral instance number. + * @param device The pointer to the I2C device information structure. + * @param cmdBuff The pointer to the commands to be transferred, could be NULL. + * @param cmdSize The length in bytes of the commands to be transferred, could be 0. + * @param rxBuff The pointer to the data to be transferred, cannot be NULL. + * @param rxSize The length in bytes of the data to be transferred, cannot be 0. + * @param timeout_ms A timeout for the transfer in microseconds. + * @return Error or success status returned by API. + */ +i2c_status_t I2C_DRV_MasterReceiveDataBlocking(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout_ms); + +/*! + * @brief Performs a non-blocking receive transaction on the I2C bus. + * + * This function returns immediately after set buffer pointer and length to the receive buffer and + * the receive size. The user must check the status of I2C to know the whether the receiving + * is finished or not. + * Both cmdBuff and rxBuff are byte aligned, user needs to prepare these buffers + * according to related protocol if slave devices data are not byte-aligned. + * + * @param instance The I2C peripheral instance number. + * @param device The pointer to the I2C device information structure. + * @param cmdBuff The pointer to the commands to be transferred, could be NULL. + * @param cmdSize The length in bytes of the commands to be transferred, could be 0. + * @param rxBuff The pointer to the data to be transferred, cannot be NULL. + * @param rxSize The length in bytes of the data to be transferred, cannot be 0. + * @return Error or success status returned by API. + */ +i2c_status_t I2C_DRV_MasterReceiveData(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + uint8_t * rxBuff, + uint32_t rxSize); + +/*! + * @brief Gets the current status of the I2C master receive. + * + * This function is designed to get the current I2C status of a non-blocking receive. + * + * @param instance Instance number of the I2C module. + * @param bytesRemaining The number of remaining bytes in the active I2C transmits. + * @return Current status of I2C receive: in progress (busy) or complete (success). + */ +i2c_status_t I2C_DRV_MasterGetReceiveStatus(uint32_t instance, + uint32_t *bytesRemaining); + +/*! + * @brief Performs a polling receive transaction on the I2C bus. + * + * Both cmdBuff and rxBuff are byte aligned. The user needs to prepare these buffers + * according to the related protocol if the slave device data is not byte-aligned. + * + * @param instance Instance number of the I2C module. + * @param slaveAddr The slave address to communicate. + * @param cmdBuff The pointer to the commands to be transferred, could be NULL. + * @param cmdSize The length in bytes of the commands to be transferred, could be 0. + * @param rxBuff The pointer to the data to be transferred, cannot be NULL. + * @param rxSize The length in bytes of the data to be transferred, cannot be 0. + * @return Error or success status returned by API. + */ +static inline i2c_status_t I2C_DRV_MasterReceiveDataPolling(uint32_t instance, + uint16_t slaveAddr, + const uint8_t * cmdBuff, + uint32_t cmdSize, + uint8_t * rxBuff, + uint32_t rxSize) +{ + + return I2C_HAL_MasterReceiveDataPolling(g_i2cBase[instance], slaveAddr, + cmdBuff, cmdSize, rxBuff, rxSize); +} + +/*! + * @brief Performs a polling send transaction on the I2C bus. + * + * Both cmdBuff and txBuff are byte aligned. The user needs to prepare these buffers + * according to the related protocol if the slave device data is not byte-aligned. + * + * @param instance Instance number of the I2C module. + * @param slaveAddr The slave address to communicate. + * @param cmdBuff The pointer to the commands to be transferred, could be NULL. + * @param cmdSize The length in bytes of the commands to be transferred, could be 0. + * @param txBuff The pointer to the data to be transferred, cannot be NULL. + * @param txSize The length in bytes of the data to be transferred, cannot be 0. + * @return Error or success status returned by API. + */ +static inline i2c_status_t I2C_DRV_MasterSendDataPolling(uint32_t instance, + uint16_t slaveAddr, + const uint8_t * cmdBuff, + uint32_t cmdSize, + const uint8_t * txBuff, + uint32_t txSize) +{ + return I2C_HAL_MasterSendDataPolling(g_i2cBase[instance], slaveAddr, + cmdBuff, cmdSize, txBuff, txSize); + +} + +/*! + * @brief The interrupt handler for I2C master mode + * + * @param instance Instance number of the I2C module. + */ +void I2C_DRV_MasterIRQHandler(uint32_t instance); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __FSL_I2C_MASTER_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_i2c_shared_function.h b/KSDK_1.2.0/platform/drivers/inc/fsl_i2c_shared_function.h new file mode 100755 index 0000000..9cf652b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_i2c_shared_function.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_I2C_SHARED_FUNCTION_H__) +#define __FSL_I2C_SHARED_FUNCTION_H__ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to runtime state structure.*/ +extern void * g_i2cStatePtr[I2C_INSTANCE_COUNT]; + +/* Table to save I2C IRQ enumeration numbers defined in CMSIS header file. */ +extern const IRQn_Type g_i2cIrqId[I2C_INSTANCE_COUNT]; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Pass IRQ control to either the master or slave driver. + * + * The address of the IRQ handlers are checked to make sure they are non-zero before + * they are called. If the IRQ handler's address is zero, it means that driver was + * not present in the link (because the IRQ handlers are marked as weak). This would + * actually be a program error, because it means the master/slave configuration for the IRQ + * was set incorrectly. + * + * @param instance Instance number of the I2C module. + */ +void I2C_DRV_IRQHandler(uint32_t instance); + +#endif /* __FSL_I2C_SHARED_IRQS_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_i2c_slave_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_i2c_slave_driver.h new file mode 100755 index 0000000..4479ab1 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_i2c_slave_driver.h @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_I2C_SLAVE_H__ +#define __FSL_I2C_SLAVE_H__ + +#include <stdint.h> +#include "fsl_i2c_hal.h" +#include "fsl_os_abstraction.h" + + +/*! + * @addtogroup i2c_slave + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Table of base addresses for I2C instances. */ +extern I2C_Type * const g_i2cBase[I2C_INSTANCE_COUNT]; +extern void * g_i2cStatePtr[I2C_INSTANCE_COUNT]; +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @brief Internal driver state information. + * + * @note The contents of this structure are internal to the driver and should not be + * modified by users. Also, contents of the structure are subject to change in + * future releases. + */ + +/*! + * @brief Defines the type of flags for callback function + */ +typedef enum _i2c_slave_event +{ +#if FSL_FEATURE_I2C_HAS_START_STOP_DETECT + kI2CSlaveStartDetect = 0x01u, /*!< The slave I2C detecting START signal event. */ +#endif + kI2CSlaveTxReq = 0x02u, /*!< The slave I2C Transmitting Request event. */ + kI2CSlaveRxReq = 0x04u, /*!< The slave I2C Receiving Request event. */ + kI2CSlaveTxNAK = 0x08u, /*!< The slave I2C Transmitting NAK event. */ + kI2CSlaveTxEmpty = 0x10u, /*!< The slave I2C Transmitting Buffer Empty event. */ + kI2CSlaveRxFull = 0x20u, /*!< The slave I2C Receiving Buffer Full event. */ + kI2CSlaveAbort = 0x40u, /*!< The slave I2C Slave abort transaction event.*/ +#if (FSL_FEATURE_I2C_HAS_START_STOP_DETECT || FSL_FEATURE_I2C_HAS_STOP_DETECT) + kI2CSlaveStopDetect = 0x80u, /*!< The slave I2C detecting STOP signal event.*/ +#endif +} i2c_slave_event_t; + +/*! @brief I2C slave callback function */ +typedef void (*i2c_slave_callback_t)(uint8_t instance,i2c_slave_event_t slaveEvent,void *userData); + +/*! + * @brief Runtime state of the I2C Slave driver. + * + * This structure holds data used by the I2C Slave Peripheral driver to + * communicate between the transfer function and the interrupt handler. The + * interrupt handler also uses this information to keep track of its progress. + */ +typedef struct I2CSlaveState +{ + i2c_status_t status; /*!< The slave I2C status. */ + volatile uint32_t txSize; /*!< Size of the TX buffer.*/ + volatile uint32_t rxSize; /*!< Size of the RX buffer.*/ + const uint8_t *txBuff; /*!< Pointer to Tx Buffer.*/ + uint8_t *rxBuff; /*!< Pointer to Rx Buffer.*/ + bool isTxBusy; /*!< True if the driver is sending data.*/ + bool isRxBusy; /*!< True if the driver is receiving data.*/ + bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + bool isRxBlocking; /*!< True if receive is blocking transaction. */ + event_t irqEvent; /*!< Use to wait for ISR to complete its Tx, Rx business */ + bool slaveListening; /*!< True if slave is in listening mode. */ + i2c_slave_callback_t slaveCallback; /*!< Pointer to user callback function. */ + void *callbackParam; /*!< Pointer to user callback param. */ +} i2c_slave_state_t; + +/*! + * @brief Defines the structure to initialize the I2C Slave module. + * + * @note once slaveListening mode is selected, all send/receive + * blocking/non-blocking functions will be invalid. + * @internal gui name="Slave configuration" id="i2cSlaveCfg" + */ +typedef struct I2CSlaveUserConfig +{ + uint16_t address; /*!< Slave's 7-bit or 10-bit address. If 10-bit address, + the first 6 bits must be 011110 in binary. @internal gui name="Address" id="SlaveAddress" */ + bool slaveListening; /*!< The slave configuration mode. @internal gui name="Slave listening" id="SlaveListening" */ + i2c_slave_callback_t slaveCallback; /*!< The slave callback function. @internal gui name="Callback" id="SlaveCallback" */ + void *callbackParam; /*!< The slave callback data. @internal gui name="Callback parameter" id="SlaveCallbackParam" */ +#if FSL_FEATURE_I2C_HAS_START_STOP_DETECT + bool startStopDetect; /*!< The slave startStop detect configuration @internal gui name="Start and Stop detect" id="SlaveStartStopDetect" */ +#endif +#if FSL_FEATURE_I2C_HAS_STOP_DETECT + bool stopDetect; /*!< The slave Stop detect configuration @internal gui name="Stop detect" id="SlaveStopDetect" */ +#endif +}i2c_slave_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name I2C Slave + * @{ + */ + +/*! + * @brief Initializes the I2C module. + * + * Saves the application callback info, turns on the clock to the module, + * enables the device, and enables interrupts. Sets the I2C to slave mode. + * IOMUX should be handled in the init_hardware() function. + * + * @param instance Instance number of the I2C module. + * @param userConfigPtr Pointer of the user configuration structure + * @param slave Pointer of the slave run-time structure. + * @return Error or success status returned by API. + */ +i2c_status_t I2C_DRV_SlaveInit(uint32_t instance, + const i2c_slave_user_config_t * userConfigPtr, + i2c_slave_state_t * slave); + +/*! + * @brief Shuts down the I2C slave driver. + * + * Clears the control register and turns off the clock to the module. + * + * @param instance Instance number of the I2C module. + * @return Error or success status returned by API. + */ +i2c_status_t I2C_DRV_SlaveDeinit(uint32_t instance); + +/*! + * @brief Gets the I2C slave run-time state structure. + * + * This function gets the I2C slave run-time state structure. + * + * @param instance Instance number of the I2C module. + * + * @return Pointer to I2C slave run-time state structure. + */ +i2c_slave_state_t * I2C_DRV_SlaveGetHandler(uint32_t instance); + +/*! + * @brief Sends/transmits data by using a non-blocking method. + * + * This function returns immediately when the buffer pointer and length are set to the transfer buffer and + * transfer size. The user should check the status of I2C slave to find out whether the transmission + * is completed. The user can also wait the kI2CSlaveStop or the kI2CSlaveTxDone to ensure that + * the transmission is ended. + * + * @param instance Instance number of the I2C module. + * @param txBuff The pointer to sending the data buffer. + * @param txSize The number of bytes which the user wants to send. + * + * @return success (if I2C slave status is not error) or error code in others. + */ +i2c_status_t I2C_DRV_SlaveSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); + + +/*! + * @brief Sends (transmits) data by using a blocking method. + * + * This function sets the buffer pointer and length to the transfer buffer and the transfer size and waits until the + * transmission is ended (NAK is detected). + * + * @param instance Instance number of the I2C module. + * @param txBuff The pointer to sending the data buffer. + * @param txSize The number of bytes which the user wants to send. + * @param timeout_ms The maximum number of milliseconds to wait for transmit completed + * + * @return success (if I2C slave status is not error) or error code in others. + */ + +i2c_status_t I2C_DRV_SlaveSendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout_ms); + +/*! + * @brief Receives the data by using a non-blocking method. + * + * This function returns immediately when the buffer pointer and length are set to the receive buffer and + * the receive size. The user should check the status of the I2C slave to find out whether the transmission + * is completed. The user can also wait the kI2CSlaveStop or the kI2CSlaveRxDone to ensure that + * the transmission is ended. + * + * @param instance Instance number of the I2C module. + * @param rxBuff The pointer to the received data buffer. + * @param rxSize The number of bytes which the user wants to receive. + * + * @return success (if I2C slave status is not error) or error code in others. + */ +i2c_status_t I2C_DRV_SlaveReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize); + +/*! + * @brief Receives data by using a blocking method. + * + * This function sets the buffer pointer and length to the receive buffer and the receive size. Then, the function waits until the + * transmission is ended (all data is received or a STOP signal is detected). + * + * @param instance Instance number of the I2C module. + * @param rxBuff The pointer to the received data buffer. + * @param rxSize The number of bytes which the user wants to receive. + * @param timeout_ms The maximum number of milliseconds to wait for receive completed + * + * @return success (if I2C slave status is not error) or error code in others. + */ +i2c_status_t I2C_DRV_SlaveReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout_ms); + +/*! + * @brief Gets the current status of the I2C slave driver. + * + * @param instance Instance number of the I2C module. + * @param bytesRemaining The number of remaining bytes that I2C transmits. + * @return The current status of I2C instance: in progress (busy), + * complete (success) or idle (I2C bus is idle). + */ +i2c_status_t I2C_DRV_SlaveGetReceiveStatus(uint32_t instance, + uint32_t *bytesRemaining); + +/*! + * @brief Gets the current status of the I2C slave driver. + * + * @param instance Instance number of the I2C module. + * @param bytesRemaining The number of remaining bytes that I2C transmits. + * @return The current status of I2C instance: in progress (busy), + * complete (success) or idle (I2C bus is idle). + */ +i2c_status_t I2C_DRV_SlaveGetTransmitStatus(uint32_t instance, + uint32_t *bytesRemaining); + +/*! + * @brief Terminates a non-blocking receive of the I2C slave early. + * + * During an non-blocking receiving + * + * @param instance Instance number of the I2C module. + * @param rxSize The number of remaining bytes in I2C Rx Buffer. + * @return kStatus_I2C_Success if success + * kStatus_I2C_NoReceiveInProgress if none receiving is available. + * + */ +i2c_status_t I2C_DRV_SlaveAbortReceiveData(uint32_t instance, uint32_t *rxSize); + +/*! + * @brief Terminates a non-blocking send of the I2C slave early. + * + * During an non-blocking receiving + * + * @param instance Instance number of the I2C module. + * @param txSize The number of remaining bytes in I2C Tx Buffer. + * @return kStatus_I2C_Success if success + * kStatus_I2C_NoReceiveInProgress if none receiving is available. + * + */ +i2c_status_t I2C_DRV_SlaveAbortSendData(uint32_t instance, uint32_t *txSize); + +/*! + * @brief Gets the current status of the I2C slave bus. + * + * @param instance Instance number of the I2C module. + * @return True if the bus is busy + * False if the bus is idle + * + */ +static inline bool I2C_DRV_SlaveIsBusBusy(uint32_t instance) +{ + return I2C_HAL_GetStatusFlag(g_i2cBase[instance], kI2CBusBusy); +} + +/*! +* @brief Sends out multiple bytes of data using a polling method. +* +* @param instance Instance number of the I2C module. +* @param txBuff The buffer pointer which saves the data to be sent. +* @param txSize Size of data to be sent in bytes. +* @return Error or success status returned by API. +*/ +static inline i2c_status_t I2C_DRV_SlaveSendDataPolling(uint32_t instance, + const uint8_t* txBuff, + uint32_t txSize) +{ + return I2C_HAL_SlaveSendDataPolling(g_i2cBase[instance], txBuff, txSize); +} + +/*! +* @brief Receives multiple bytes of data using a polling method. +* +* @param instance Instance number of the I2C module. +* @param rxBuff The buffer pointer which saves the data to be received. +* @param rxSize Size of data need to be received in bytes. +* @return Error or success status returned by the API. +*/ +static inline i2c_status_t I2C_DRV_SlaveReceiveDataPolling(uint32_t instance, + uint8_t *rxBuff, + uint32_t rxSize) +{ + return I2C_HAL_SlaveReceiveDataPolling(g_i2cBase[instance], rxBuff, rxSize); +} + +/*! + * @brief The interrupt handler for I2C slave mode + * + * @param instance Instance number of the I2C module. + */ +void I2C_DRV_SlaveIRQHandler(uint32_t instance); + +/*@}*/ +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __FSL_I2C_SLAVE_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_lmem_cache_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_lmem_cache_driver.h new file mode 100755 index 0000000..29ba348 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_lmem_cache_driver.h @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_LMEM_CACHE_DRIVER_H__) +#define __FSL_LMEM_CACHE_DRIVER_H__ + +#include "fsl_lmem_cache_hal.h" + +#if FSL_FEATURE_SOC_LMEM_COUNT + +/*! + * @addtogroup local_memory_controller_cache_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Table of base addresses for the LMEM instances. */ +extern LMEM_Type * const g_lmemBase[LMEM_INSTANCE_COUNT]; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Processor Code Bus Cache Control Peripheral Driver + *@{ + */ + +/*! + * @brief Invalidates the processor code bus cache. + * + * This function invalidates the cache both ways, which means that + * it unconditionally clears valid bits and modifies bits of a cache entry. + * + * @param instance The instance number of the LMEM peripheral + */ +void LMEM_DRV_CodeCacheInvalidateAll(uint32_t instance); + +/*! + * @brief Pushes all modified lines in the processor code bus cache. + * + * This function pushes all modified lines in both ways (the entire cache). + * Pushes a cache entry if it is valid and modified, then clears the modify bit. If + * entry is not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + * @param instance The instance number of the LMEM peripheral + */ +void LMEM_DRV_CodeCachePushAll(uint32_t instance); + +/*! + * @brief Cears the processor code bus cache. + * + * This function clears the entire cache and pushes (flushes) and + * invalidates the operation. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If the entry is not valid or not modified, clear the valid bit. + * + * @param instance The instance number of the LMEM peripheral + */ +void LMEM_DRV_CodeCacheClearAll(uint32_t instance); + +/*! + * @brief Enables the processor code bus cache. + * + * This function enables the cache. The function first invalidates the entire cache, + * then enables both the cache and write buffer. + * + * @param instance The instance number of the LMEM peripheral + */ +void LMEM_DRV_CodeCacheEnable(uint32_t instance); + +/*! + * @brief Disables the processor code bus cache. + * + * This function disables the cache and write buffer. + * + * @param instance The instance number of the LMEM peripheral + */ +void LMEM_DRV_CodeCacheDisable(uint32_t instance); + +/*! + * @brief Invalidates a specific line in the processor code bus cache. + * + * This function invalidates a specific line in the cache + * based on the physical address passed in by the user. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + * @param instance The instance number of the LMEM peripheral + * @param addr The physical address of the cache line + */ +void LMEM_DRV_CodeCacheInvalidateLine(uint32_t instance, uint32_t addr); + +/*! + * @brief Invalidates multiple lines in the processor code bus cache. + * + * This function invalidates multiple lines in the cache + * based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half the + * cache, then the function performs an entire cache invalidate function which is + * more efficient than invalidating the cache line-by-line. + * The need to check half the total amount of cache is due to the fact that the cache consists of + * two ways and that line commands based on the physical address searches both ways. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + * @param instance The instance number of the LMEM peripheral + * @param addr The physical address of the cache line + * @param length The length in bytes of the total amount of cache lines + */ +void LMEM_DRV_CodeCacheInvalidateMultiLines(uint32_t instance, uint32_t addr, uint32_t length); + +/*! + * @brief Pushes a specific modified line in the processor code bus cache. + * + * This function pushes a specific modified line based on the physical address passed in + * by the user. + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * entry not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + * @param instance The instance number of the LMEM peripheral + * @param addr The physical address of the cache line + */ +void LMEM_DRV_CodeCachePushLine(uint32_t instance, uint32_t addr); + +/*! + * @brief Pushes multiple modified lines in the processor code bus cache. + * + * This function pushes multiple modified lines in the cache + * based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half of the + * cache, the function performs an cache push function (which is + * more efficient than pushing the modified lines in the cache line-by-line). + * The need to check half the total amount of cache is due to the fact that the cache consists of + * two ways and that line commands based on the physical address searches both ways. + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * entry not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + * @param instance The instance number of the LMEM peripheral + * @param addr The physical address of the cache line + * @param length The length in bytes of the total amount of cache lines + */ +void LMEM_DRV_CodeCachePushMultiLines(uint32_t instance, uint32_t addr, uint32_t length); + +/*! + * @brief Clears a specific line in the processor code bus cache. + * + * This function clears a specific line based on the physical address passed in + * by the user. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + * @param instance The instance number of the LMEM peripheral + * @param addr The physical address of the cache line + */ +void LMEM_DRV_CodeCacheClearLine(uint32_t instance, uint32_t addr); + +/*! + * @brief Clears multiple lines in the processor code bus cache. + * + * This function clears multiple lines in the cache + * based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half the total amount of + * cache, the function performs a cache clear function which is + * more efficient than clearing the lines in the cache line-by-line. + * The need to check half the total amount of cache is due to the fact that the cache consists of + * two ways and that line commands based on the physical address searches both ways. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + * @param instance The instance number of the LMEM peripheral + * @param addr The physical address of the cache line + * @param length The length in bytes of the total amount of cache lines + */ +void LMEM_DRV_CodeCacheClearMultiLines(uint32_t instance, uint32_t addr, uint32_t length); + +/*! + * @brief Demotes the cache mode of a region in processor code bus cache. + * + * This function allows the user to demote the cache mode of a region within the device's + * memory map. Demoting the cache mode reduces the cache function applied to a memory + * region from write-back to write-through to non-cacheable. The function checks to see + * if the requested cache mode is higher than or equal to the current cache mode, and if + * so, returns an error. After a region is demoted, its cache mode can only be raised + * by a reset, which returns it to its default state. + * To maintain cache coherency, changes to the cache mode should be completed while the + * address space being changed is not being accessed or the cache is disabled. Before a + * cache mode change, this function completes a cache clear all command to push and invalidate any + * cache entries that may have changed. + * + * @param instance The instance number of the LMEM peripheral + * @param region The desired region to demote of type lmem_cache_region_t + * @param cacheMode The new, demoted cache mode of type lmem_cache_mode_t + * + * @return kStatus_LMEM_CACHE_Success The cache clear operation was successful, or + * kStatus_LMEM_CACHE_Busy The cache is busy performing another operation + * kStatus_LMEM_CACHE_Error The requested cache mode is higher than or equal to the + * current cache mode + */ +lmem_cache_status_t LMEM_DRV_CodeCacheDemoteRegion(uint32_t instance, lmem_cache_region_t region, + lmem_cache_mode_t cacheMode); + +/*@}*/ + +#if FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE +/*! + * @name Processor System Bus Cache Control Peripheral Driver + *@{ + */ + +/*! + * @brief Invalidates the processor code bus cache. + * + * This function invalidates the entire cache both ways. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + * @param instance The instance number of the LMEM peripheral + */ +void LMEM_DRV_SystemCacheInvalidateAll(uint32_t instance); + +/*! + * @brief Pushes all modified lines in the processor code bus + * cache. + * + * This function pushes all modified lines in both ways (the entire cache). + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * entry is not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + * @param instance The instance number of the LMEM peripheral + */ +void LMEM_DRV_SystemCachePushAll(uint32_t instance); + +/*! + * @brief Clears the entire processor code bus cache. + * + * This function clears the entire cache, which is a push (flush) and + * invalidate operation. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + * @param instance The instance number of the LMEM peripheral + */ +void LMEM_DRV_SystemCacheClearAll(uint32_t instance); + +/*! + * @brief Enables the processor code bus cache. + * + * This function enables the cache. It first invalidates the entire cache, + * then enables both the cache and write buffer. + * + * @param instance The instance number of the LMEM peripheral + */ +void LMEM_DRV_SystemCacheEnable(uint32_t instance); + +/*! + * @brief Disables the processor code bus cache. + * + * This function disables the cache and write buffer. + * + * @param instance The instance number of the LMEM peripheral + */ +void LMEM_DRV_SystemCacheDisable(uint32_t instance); + +/*! + * @brief Invalidates a specific line in the processor code bus cache. + * + * This function invalidates a specific line in the cache + * based on the physical address passed in by the user. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + * @param instance The instance number of the LMEM peripheral + * @param addr The physical address of the cache line + */ +void LMEM_DRV_SystemCacheInvalidateLine(uint32_t instance, uint32_t addr); + +/*! + * @brief Invalidates multiple lines in the processor code bus cache. + * + * This function invalidates multiple lines in the cache + * based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half of the + * cache, the function performs an entire cache invalidate function (which is + * more efficient than invalidating the cache line-by-line). + * The need to check half the total amount of cache is due to the fact that the cache consists of + * two ways and that line commands based on the physical address searches both ways. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + * @param instance The instance number of the LMEM peripheral + * @param addr The physical address of the cache line + * @param length The length in bytes of the total amount of cache lines + */ +void LMEM_DRV_SystemCacheInvalidateMultiLines(uint32_t instance, uint32_t addr, uint32_t length); + +/*! + * @brief Pushes a specific modified line in the processor code bus + * cache. + * + * This function pushes a specific modified line based on the physical address passed in + * by the user. + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * entry not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + * @param instance The instance number of the LMEM peripheral + * @param addr The physical address of the cache line + */ +void LMEM_DRV_SystemCachePushLine(uint32_t instance, uint32_t addr); + +/*! + * @brief Pushes multiple modified lines in the processor code bus cache. + * + * This function pushes multiple modified lines in the cache + * based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half of the + * cache, the function performs an entire cache push function (which is + * more efficient than pushing the modified lines in the cache line-by-line). + * The need to check half the total amount of cache is due to the fact that the cache consists of + * two ways and that line commands based on the physical address searches both ways. + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * entry not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + * @param instance The instance number of the LMEM peripheral + * @param addr The physical address of the cache line + * @param length The length in bytes of the total amount of cache lines + */ +void LMEM_DRV_SystemCachePushMultiLines(uint32_t instance, uint32_t addr, uint32_t length); + +/*! + * @brief Clears a specific line in the processor code bus cache. + * + * This function clears a specific line based on the physical address passed in + * by the user. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + * @param instance The instance number of the LMEM peripheral + * @param addr The physical address of the cache line + */ +void LMEM_DRV_SystemCacheClearLine(uint32_t instance, uint32_t addr); + +/*! + * @brief Clears multiple lines in the processor code bus cache. + * + * This function clears multiple lines in the cache + * based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half of the + * cache, the function performs an entire cache clear function (which is + * more efficient than clearing the lines in the cache line-by-line). + * The need to check half the total amount of cache is due to the fact that the cache consists of + * two ways and that line commands based on the physical address searches both ways. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + * @param instance The instance number of the LMEM peripheral + * @param addr The physical address of the cache line + * @param length The length in bytes of the total amount of cache lines + */ +void LMEM_DRV_SystemCacheClearMultiLines(uint32_t instance, uint32_t addr, uint32_t length); + +/*! + * @brief Demotes the cache mode of a region in the processor code bus cache. + * + * This function allows the user to demote the cache mode of a region within the device's + * memory map. Demoting the cache mode reduces the cache function applied to a memory + * region from write-back to write-through to non-cacheable. The function checks to see + * if the requested cache mode is higher than or equal to the current cache mode, and if + * so, returns an error. After a region is demoted, its cache mode can only be raised + * by a reset, which returns it to its default state. + * To maintain cache coherency, changes to the cache mode should be completed while the + * address space being changed is not being accessed or the cache is disabled. Before a + * cache mode change, this function completes a cache clear all command to push and invalidate any + * cache entries that may have changed. + * + * @param instance The instance number of the LMEM peripheral + * @param region The desired region to demote of type lmem_cache_region_t + * @param cacheMode The new, demoted cache mode of type lmem_cache_mode_t + * + * @return kStatus_LMEM_CACHE_Success The cache clear operation was successful, or + * kStatus_LMEM_CACHE_Busy The cache is busy performing another operation + * kStatus_LMEM_CACHE_Error The requested cache mode is higher than or equal to the + * current cache mode + */ +lmem_cache_status_t LMEM_DRV_SystemCacheDemoteRegion(uint32_t instance, lmem_cache_region_t region, + lmem_cache_mode_t cacheMode); + +/*@}*/ +#endif /* #if FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* FSL_FEATURE_SOC_LMEM_COUNT */ +#endif /* __FSL_LMEM_CACHE_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_lpsci_dma_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_lpsci_dma_driver.h new file mode 100755 index 0000000..417cfe2 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_lpsci_dma_driver.h @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_LPSCI_DMA_DRIVER_H__ +#define __FSL_LPSCI_DMA_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_os_abstraction.h" +#include "fsl_lpsci_hal.h" +#include "fsl_dma_driver.h" +#include "fsl_clock_manager.h" + +/*! + * @addtogroup lpsci_driver + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for LPSCI instances. */ +extern UART0_Type * const g_lpsciBase[UART0_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @brief Runtime state structure for LPSCI driver with DMA. + */ +typedef struct LpsciDmaState { + volatile bool isTxBusy; /*!< True if there is an active transmit. */ + volatile bool isRxBusy; /*!< True if there is an active receive. */ + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its TX business. */ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its RX business. */ + dma_channel_t dmaLpsciTx; /*!< DMA channel used for send. */ + dma_channel_t dmaLpsciRx; /*!< DMA channel used for receive. */ +} lpsci_dma_state_t; + +/*! + * @brief User configuration structure for the LPSCI driver. + * + * Use an instance of this structure with the LPSCI_DRV_Init()function. This enables configuration of the + * most common settings of the LPSCI peripheral with a single function call. Settings include: + * LPSCI baud rate, LPSCI parity mode: disabled (default), or even or odd, the number of stop bits, and + * the number of bits per data word. + */ +typedef struct LpsciDmaUserConfig { + clock_lpsci_src_t clockSource; /*!< LPSCI clock source in fsl_sim_hal_<device>.h */ + uint32_t baudRate; /*!< LPSCI baud rate*/ + lpsci_parity_mode_t parityMode; /*!< parity mode, disabled (default), even, odd */ + lpsci_stop_bit_count_t stopBitCount; /*!< number of stop bits, 1 stop bit (default) or 2 stop bits */ + lpsci_bit_count_per_char_t bitCountPerChar; /*!< number of bits, 8-bit (default) or 9-bit in + a word (up to 10-bits in some LPSCI instances) */ +} lpsci_dma_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name LPSCI DMA Driver + * @{ + */ + +/*! + * @brief Initializes an LPSCI instance to work with DMA. + * + * This function initializes the run-time state structure to keep track of the on-going + * transfers, un-gates the clock to the LPSCI module, initializes the module + * to user-defined settings and default settings, configures the IRQ state structure, and enables + * the module-level interrupt to the core, the LPSCI module transmitter and receiver. + * This example shows how to set up the lpsci_dma_state_t and the + * lpsci_user_config_t parameters and how to call the LPSCI_DRV_DmaInit function by passing + * in these parameters: + @code + lpsci_user_config_t lpsciConfig; + lpsciConfig.baudRate = 9600; + lpsciConfig.bitCountPerChar = kLpsci8BitsPerChar; + lpsciConfig.parityMode = kLpsciParityDisabled; + lpsciConfig.stopBitCount = kLpsciOneStopBit; + lpsci_dma_state_t lpsciDmaState; + LPSCI_DRV_DmaInit(instance, &lpsciDmaState, &lpsciConfig); + @endcode + * + * @param instance The LPSCI instance number. + * @param lpsciDmaStatePtr A pointer to the LPSCI driver state structure memory. The user + * passes in the memory for the run-time state structure. The LPSCI driver + * populates the members. This run-time state structure keeps track of the + * current transfer in progress. + * @param lpsciUserConfig The user configuration structure of type lpsci_user_config_t. The user + * populates the members of this structure and passes the pointer of this structure + * to this function. + * @return An error code or kStatus_LPSCI_Success. + */ +lpsci_status_t LPSCI_DRV_DmaInit(uint32_t instance, lpsci_dma_state_t * lpsciDmaStatePtr, + const lpsci_dma_user_config_t * lpsciUserConfig); +/*! + * @brief Shuts down the LPSCI. + * + * This function disables the LPSCI-DMA trigger and disables the transmitter and receiver. + * + * @param instance The LPSCI instance number. + * @return An error code or kStatus_LPSCI_Success. + */ +lpsci_status_t LPSCI_DRV_DmaDeinit(uint32_t instance); + +/*! + * @brief Sends (transmits) data out through the LPSCI-DMA module using blocking method. + * + * @param instance The LPSCI instance number. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_LPSCI_Success. + */ +lpsci_status_t LPSCI_DRV_DmaSendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the LPSCI-DMA module using a non-blocking method. + * + * @param instance The LPSCI module base address. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_LPSCI_Success. + */ +lpsci_status_t LPSCI_DRV_DmaSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +/*! + * @brief Returns whether the previous LPSCI-DMA transmit has finished. + * + * @param instance The LPSCI module base address. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes that + * are remaining in the active transfer. + * @return An error code or kStatus_LPSCI_Success. + * @retval kStatus_LPSCI_Success The transmit has completed successfully. + * @retval kStatus_LPSCI_TxBusy The transmit is still in progress. @a bytesTransmitted is + * filled with the number of bytes which are transmitted up to that point. + */ +lpsci_status_t LPSCI_DRV_DmaGetTransmitStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates a non-blocking LPSCI-DMA transmission early. + * + * @param instance The LPSCI module base address. + * @return An error code or kStatus_LPSCI_Success. + * @retval kStatus_LPSCI_Success The transmit was successful. + * @retval kStatus_LPSCI_NoTransmitInProgress No transmission is currently in progress. + */ +lpsci_status_t LPSCI_DRV_DmaAbortSendingData(uint32_t instance); + +/*! + * @brief Gets (receives) data from the LPSCI-DMA module using a blocking method. + * + * @param instance The LPSCI module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_LPSCI_Success. + */ +lpsci_status_t LPSCI_DRV_DmaReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout); +/*! + * @brief Gets (receives) data from the LPSCI-DMA module using a non-blocking method. + * + * @param instance The LPSCI module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_LPSCI_Success. + */ +lpsci_status_t LPSCI_DRV_DmaReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize); + +/*! + * @brief Returns whether the previous LPSCI-DMA receive is complete. + * + * @param instance The LPSCI module base address. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes which + * still need to be received in the active transfer. + * @return An error code or kStatus_LPSCI_Success. + * @retval kStatus_LPSCI_Success The receive has completed successfully. + * @retval kStatus_LPSCI_RxBusy The receive is still in progress. @a bytesReceived is + * filled with the number of bytes which are received up to that point. + */ +lpsci_status_t LPSCI_DRV_DmaGetReceiveStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates a non-blocking LPSCI-DMA receive early. + * + * @param instance The LPSCI module base address. + * @return An error code or kStatus_LPSCI_Success. + * @retval kStatus_LPSCI_Success The receive was successful. + * @retval kStatus_LPSCI_NoTransmitInProgress No receive is currently in progress. + */ +lpsci_status_t LPSCI_DRV_DmaAbortReceivingData(uint32_t instance); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __FSL_LPSCI_DMA_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_lpsci_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_lpsci_driver.h new file mode 100755 index 0000000..0e18d0f --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_lpsci_driver.h @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_LPSCI_DRIVER_H__ +#define __FSL_LPSCI_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_os_abstraction.h" +#include "fsl_clock_manager.h" +#include "fsl_lpsci_hal.h" + +/*! + * @addtogroup lpsci_driver + * @{ + */ + +/*! + * @file + * + * This driver is for UART0 if UART0 is a separate chapter in the chip reference + * manual. For a common UART, use the UART driver. + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for LPSCI instances. */ +extern UART0_Type * const g_lpsciBase[UART0_INSTANCE_COUNT]; + +/*! @brief Table to save LPSCI IRQ enumeration numbers defined in CMSIS header file */ +extern const IRQn_Type g_lpsciRxTxIrqId[UART0_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief LPSCI receive callback function type. */ +typedef void (* lpsci_rx_callback_t)(uint32_t instance, void * lpsciState); + +/*! @brief LPSCI transmit callback function type */ +typedef void (* lpsci_tx_callback_t)(uint32_t instance, void * lpsciState); + +/*! + * @brief Runtime state of the LPSCI driver. + * + * This structure holds data used by the LPSCI peripheral driver to + * communicate between the transfer function and the interrupt handler. The + * interrupt handler also uses this information to keep track of its progress. + * The user passes in the memory for the run-time state structure. The + * LPSCI driver populates the members. + */ +typedef struct LpsciState { + const uint8_t * txBuff; /*!< The buffer of data being sent.*/ + uint8_t * rxBuff; /*!< The buffer of received data. */ + volatile size_t txSize; /*!< The remaining number of bytes to be transmitted. */ + volatile size_t rxSize; /*!< The remaining number of bytes to be received. */ + volatile bool isTxBusy; /*!< True if there is an active transmit. */ + volatile bool isRxBusy; /*!< True if there is an active receive. */ + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its TX business. */ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its RX business. */ + lpsci_rx_callback_t rxCallback; /*!< Callback to invoke after receiving byte.*/ + void * rxCallbackParam; /*!< Receive callback parameter pointer.*/ + lpsci_tx_callback_t txCallback; /*!< Callback to invoke after transmitting byte.*/ + void * txCallbackParam; /*!< Transmit callback parameter pointer.*/ +} lpsci_state_t; + +/*! @brief User configuration structure for the LPSCI driver + * @internal gui name="Configuration" id="Configuration" + */ +typedef struct LpsciUserConfig { + clock_lpsci_src_t clockSource; /*!< LPSCI clock source in fsl_sim_hal_'device'.h @internal gui name="Clock source" id="ClockSource" */ + uint32_t baudRate; /*!< LPSCI baud rate @internal gui name="Baud rate" id="BaudRate" */ + lpsci_parity_mode_t parityMode; /*!< parity mode, disabled (default), even, odd @internal gui name="Parity mode" id="Parity" */ + lpsci_stop_bit_count_t stopBitCount; /*!< number of stop bits, 1 stop bit (default) or 2 stop bits @internal gui name="Stop bits" id="StopBits" */ + lpsci_bit_count_per_char_t bitCountPerChar; /*!< number of bits, 8-bit (default) or 9-bit in + a word (up to 10-bits in some LPSCI instances) @internal gui name="Bits per char" id="DataBits" */ +} lpsci_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name LPSCI Interrupt Driver + * @{ + */ + +/*! + * @brief Initializes an LPSCI instance for operation. + * + * This function initializes the run-time state structure to keep track of the on-going + * transfers, un-gates the clock to the LPSCI module, initializes the module + * to user-defined settings and default settings, configures the IRQ state structure and enables + * the module-level interrupt to the core, and enables the LPSCI module transmitter and receiver. + * This example shows how to set up the lpsci_state_t and the + * lpsci_user_config_t parameters and how to call the LPSCI_DRV_Init function by passing + * in these parameters: + @code + lpsci_user_config_t lpsciConfig; + lpsciConfig.clockSource = kClockLpsciSrcPllFllSel; + lpsciConfig.baudRate = 9600; + lpsciConfig.bitCountPerChar = kLpsci8BitsPerChar; + lpsciConfig.parityMode = kLpsciParityDisabled; + lpsciConfig.stopBitCount = kLpsciOneStopBit; + lpsci_state_t lpsciState; + LPSCI_DRV_Init(instance, &lpsciState, &lpsciConfig); + @endcode + * + * @param instance The LPSCI instance number. + * @param lpsciStatePtr A pointer to the LPSCI driver state structure memory. The user + * passes in the memory for the run-time state structure. The LPSCI driver + * populates the members. The run-time state structure keeps track of the + * current transfer in progress. + * @param lpsciUserConfig The user configuration structure of type lpsci_user_config_t. The user + * populates the members of this structure and passes the pointer of the + * structure to the function. + * @return An error code or kStatus_LPSCI_Success. + */ +lpsci_status_t LPSCI_DRV_Init(uint32_t instance, + lpsci_state_t * lpsciStatePtr, + const lpsci_user_config_t * lpsciUserConfig); + +/*! + * @brief Shuts down the LPSCI by disabling interrupts and the transmitter/receiver. + * + * This function disables the LPSCI interrupts, disables the transmitter and receiver, and + * flushes the FIFOs (for modules that support FIFOs). + * + * @param instance The LPSCI instance number. + * @return An error code or kStatus_LPSCI_Success. + */ +lpsci_status_t LPSCI_DRV_Deinit(uint32_t instance); + +/*! + * @brief Installs callback function for the LPSCI receive. + * + * @param instance The LPSCI instance number. + * @param function The LPSCI receive callback function. + * @param rxBuff The receive buffer used inside IRQHandler. This buffer must be kept as long as the callback is functional. + * @param callbackParam The LPSCI receive callback parameter pointer. + * @param alwaysEnableRxIrq Whether always enable receive IRQ or not. + * @return Former LPSCI receive callback function pointer. + */ +lpsci_rx_callback_t LPSCI_DRV_InstallRxCallback(uint32_t instance, + lpsci_rx_callback_t function, + uint8_t * rxBuff, + void * callbackParam, + bool alwaysEnableRxIrq); +/*! + * @brief Installs callback function for the LPSCI transmit. + * + * @note After the callback is installed, it bypasses part of the LPSCI IRQHandler logic. + * Therefore, the callback needs to handle the indexes of txBuff and txSize. + * + * @param instance The LPSCI instance number. + * @param function The LPSCI transmit callback function. + * @param txBuff The transmit buffer used inside IRQHandler. This buffer must be kept as long as the callback is alive. + * @param callbackParam The LPSCI transmit callback parameter pointer. + * @return Former LPSCI transmit callback function pointer. + */ +lpsci_tx_callback_t LPSCI_DRV_InstallTxCallback(uint32_t instance, + lpsci_tx_callback_t function, + uint8_t * txBuff, + void * callbackParam); + +/*! + * @brief Sends (transmits) data out through the LPSCI module using a blocking method. + * + * A blocking (also known as synchronous) function means that the function does not return until + * the transmit is complete. This blocking function sends data through the LPSCI port. + * + * @param instance The LPSCI instance number. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_LPSCI_Success. + */ +lpsci_status_t LPSCI_DRV_SendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the LPSCI module using a non-blocking method. + * + * A non-blocking (also known as synchronous) function means that the function returns + * immediately after initiating the transmit function. The application has to get the + * transmit status to see when the transmit is complete. In other words, after calling non-blocking + * (asynchronous) send function, the application must get the transmit status to check if transmit + * is complete. + * The asynchronous method of transmitting and receiving allows the LPSCI to perform a full duplex + * operation (simultaneously transmit and receive). + * + * @param instance The LPSCI module base address. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_LPSCI_Success. + */ +lpsci_status_t LPSCI_DRV_SendData(uint32_t instance, const uint8_t * txBuff, uint32_t txSize); + +/*! + * @brief Returns whether the previous LPSCI transmit has finished. + * + * When performing an a-sync transmit, call this function to ascertain the state of the + * current transmission: in progress (or busy) or complete (success). If the + * transmission is still in progress, the user can obtain the number of words that have been + * transferred. + * + * @param instance The LPSCI module base address. + * @param bytesRemaining A pointer to a value that is filled in with the number of bytes that + * are remaining in the active transfer. + * @return Current transmission status. + * @retval kStatus_LPSCI_Success The transmit has completed successfully. + * @retval kStatus_LPSCI_TxBusy The transmit is still in progress. @a bytesRemaining is + * filled with the number of bytes which are transmitted up to that point. + */ +lpsci_status_t LPSCI_DRV_GetTransmitStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates an asynchronous LPSCI transmission early. + * + * During an a-sync LPSCI transmission, the user can terminate the transmission early + * if the transmission is still in progress. + * + * @param instance The LPSCI module base address. + * @return Whether the aborting was successful or not. + * @retval kStatus_LPSCI_Success The transmit was successful. + * @retval kStatus_LPSCI_NoTransmitInProgress No transmission is currently in progress. + */ +lpsci_status_t LPSCI_DRV_AbortSendingData(uint32_t instance); + +/*! + * @brief Gets (receives) data from the LPSCI module using a blocking method. + * + * A blocking (also known as synchronous) function does not return until + * the receive is complete. This blocking function sends data through the LPSCI port. + * + * @param instance The LPSCI module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_LPSCI_Success. + */ +lpsci_status_t LPSCI_DRV_ReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout); + +/*! + * @brief Gets (receives) data from the LPSCI module using a non-blocking method. + * + * A non-blocking (also known as synchronous) function returns + * immediately after initiating the receive function. The application has to get the + * receive status to see when the receive is complete. + * The asynchronous method of transmitting and receiving allows the LPSCI to perform a full duplex + * operation (simultaneously transmit and receive). + * + * @param instance The LPSCI module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_LPSCI_Success. + */ +lpsci_status_t LPSCI_DRV_ReceiveData(uint32_t instance, uint8_t * rxBuff, uint32_t rxSize); + +/*! + * @brief Returns whether the previous LPSCI receive is complete. + * + * When performing an a-sync receive, call this function to ascertain the state of the + * current receive progress: in progress (or busy) or complete (success). If the + * receive is still in progress, the user can obtain the number of words that have been + * received. + * + * @param instance The LPSCI module base address. + * @param bytesRemaining A pointer to a value that is filled in with the number of bytes which + * still need to be received in the active transfer. + * @return Current receive status. + * @retval kStatus_LPSCI_Success The receive has completed successfully. + * @retval kStatus_LPSCI_RxBusy The receive is still in progress. @a bytesRemaining is + * filled with the number of bytes which are received up to that point. + */ +lpsci_status_t LPSCI_DRV_GetReceiveStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates an asynchronous LPSCI receive early. + * + * During an a-sync LPSCI receive, the user can terminate the receive early + * if the receive is still in progress. + * + * @param instance The LPSCI module base address. + * @return Whether the action success or not. + * @retval kStatus_LPSCI_Success The receive was successful. + * @retval kStatus_LPSCI_NoTransmitInProgress No receive is currently in progress. + */ +lpsci_status_t LPSCI_DRV_AbortReceivingData(uint32_t instance); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __FSL_LPSCI_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_lptmr_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_lptmr_driver.h new file mode 100755 index 0000000..9ef2fae --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_lptmr_driver.h @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_LPTMR_DRIVER_H__ +#define __FSL_LPTMR_DRIVER_H__ + +#include <assert.h> +#include <stdint.h> +#include <stdbool.h> +#include "fsl_lptmr_hal.h" +#include "fsl_sim_hal.h" +#if FSL_FEATURE_SOC_LPTMR_COUNT + +/*! + * @addtogroup lptmr_driver + * @{ + */ + +/******************************************************************************* + * Definitions + *******************************************************************************/ +/*! @brief Table of base addresses for LPTMR instances. */ +extern LPTMR_Type * const g_lptmrBase[]; + +/*! @brief Table to save LPTMR IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_lptmrIrqId[LPTMR_INSTANCE_COUNT]; + +/*! + * @brief Data structure to initialize the LPTMR + * + * This structure is used when initializing the LPTMR during the LPTMR_DRV_Init function call. + * @internal gui name="LPTMR configuration" id="lptmrCfg" + */ +typedef struct LptmrUserConfig { + lptmr_timer_mode_t timerMode; /*!< Timer counter mode or pulse counter mode @internal gui name="Timer mode" */ + lptmr_pin_select_t pinSelect; /*!< LPTMR pulse input pin select @internal gui name="Pin select" */ + lptmr_pin_polarity_t pinPolarity; /*!< LPTMR pulse input pin polarity @internal gui name="Pin polarity" */ + bool freeRunningEnable; /*!< Free running configure. True means enable free running @internal gui name="Free running" */ + bool prescalerEnable; /*!< Prescaler enable configure. True means enable prescaler @internal gui name="Prescaler" */ + clock_lptmr_src_t prescalerClockSource; /*!< LPTMR clock source @internal gui name="Prescaler clock source" */ + lptmr_prescaler_value_t prescalerValue; /*!< Prescaler value @internal gui name="Prescaler value" */ + bool isInterruptEnabled; /*!< Timer interrupt 0-disable/1-enable @internal gui name="Interrupt" */ +} lptmr_user_config_t; + +/*! + * @brief Defines a type of the user-defined callback function. + */ +typedef void (*lptmr_callback_t)(void); + +/*! + * @brief Internal driver state information. + * + * The contents of this structure are internal to the driver and should not be + * modified by users. Contents of the structure are subject to change in + * future releases. + */ +typedef struct LptmrState { + lptmr_callback_t userCallbackFunc; /*!< Callback function that is executed in ISR. */ + uint32_t prescalerClockHz; +} lptmr_state_t; + + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name LPTMR Driver + * @{ + */ + +/*! + * @brief Initializes the LPTMR driver. + * + * This function initializes the LPTMR. The LPTMR can be initialized as a time counter or pulse counter, + * which is determined by the timerMode in the lptmr_user_config_t. pinSelect and pinPolarity do not need to be + * configured while working as a time counter. + * + * @param instance The LPTMR peripheral instance number. + * @param userStatePtr The pointer to the structure of the context memory, see #lptmr_state_t. + * @param userConfigPtr The pointer to the LPTMR user configure structure, see #lptmr_user_config_t. + * @return kStatus_LPTMR_Success means succeed, otherwise means failed. + */ +lptmr_status_t LPTMR_DRV_Init(uint32_t instance, lptmr_state_t *userStatePtr, const lptmr_user_config_t* userConfigPtr); + +/*! + * @brief De-initializes the LPTMR driver. + * + * This function de-initializes the LPTMR. It disables the interrupt and turns off the LPTMR clock. + * + * @param instance The LPTMR peripheral instance number. + * @return kStatus_LPTMR_Success means succeed, otherwise means failed. + */ +lptmr_status_t LPTMR_DRV_Deinit(uint32_t instance); + +/*! + * @brief Starts the LPTMR counter. + * + * This function starts the LPTMR counter. Ensure that all necessary + * configurations are set before calling this function. + * + * @param instance The LPTMR peripheral instance number. + * @return kStatus_LPTMR_Success means success. Otherwise, means failure. + */ +lptmr_status_t LPTMR_DRV_Start(uint32_t instance); + +/*! + * @brief Stops the LPTMR counter. + * + * This function stops the LPTMR counter. + * + * @param instance The LPTMR peripheral instance number. + * @return kStatus_LPTMR_Success means success. Otherwise, means failure. + */ +lptmr_status_t LPTMR_DRV_Stop(uint32_t instance); + +/*! + * @brief Configures the LPTMR timer period in microseconds. + * + * This function configures the LPTMR time period while the LPTMR is working as a + * time counter. After the time period in microseconds, the callback function is called. + * This function cannot be called while the LPTMR is working as a pulse counter. + * The value in microseconds (us) should be integer multiple of the clock source time slice. If the clock source + * is 1 kHz, then both 2000 us and 3000 us are valid while 2500 us gets the same result as the 2000 µs, + * because 2500 us cannot be generated in 1 kHz clock source. + * + * @param instance The LPTMR peripheral instance number. + * @param us time period in microseconds. + * @return kStatus_LPTMR_Success means success. Otherwise, means failure. + */ +lptmr_status_t LPTMR_DRV_SetTimerPeriodUs(uint32_t instance, uint32_t us); + + /*! + * @brief Gets the current LPTMR time in microseconds. + * + * This function gets the current time while operating as a time counter. + * This function cannot be called while operating as a pulse counter. + * + * @param instance The LPTMR peripheral instance number. + * @return current time in microsecond unit. + */ +uint32_t LPTMR_DRV_GetCurrentTimeUs(uint32_t instance); + +/*! + * @brief Sets the pulse period value. + * + * This function configures the pulse period of the LPTMR while working as a + * pulse counter. After the count of pulsePeriodValue pulse is captured, the callback function + * is called. + * This function cannot be called while operating as a time counter. + * + * @param instance The LPTMR peripheral instance number. + * @param pulsePeriodCount pulse period value. + * @return kStatus_LPTMR_Success means success. Otherwise, means failure. + */ +lptmr_status_t LPTMR_DRV_SetPulsePeriodCount(uint32_t instance, uint32_t pulsePeriodCount); + + /*! + * @brief Gets the current pulse count. + * + * This function gets the current pulse count captured on the pulse input pin. + * This function cannot be called while operating as a time counter. + * + * @param instance The LPTMR peripheral instance number. + * @return pulse count captured on the pulse input pin. + */ +uint32_t LPTMR_DRV_GetCurrentPulseCount(uint32_t instance); + +/*! + * @brief Installs the user-defined callback in the LPTMR module. + * + * This function installs the user-defined callback in the LPTMR module. + * When an LPTMR interrupt request is served, the callback is executed + * inside the ISR. + * + * @param instance LPTMR instance ID. + * @param userCallback User-defined callback function. + * @return kStatus_LPTMR_Success means success. Otherwise, means failure. + */ +lptmr_status_t LPTMR_DRV_InstallCallback(uint32_t instance, lptmr_callback_t userCallback); + +/*! + * @brief Driver-defined ISR in the LPTMR module. + * + * This function is the driver-defined ISR in LPTMR module. + * It includes the process for interrupt mode defined by driver. Currently, it + * is called inside the system-defined ISR. + * + * @param instance LPTMR instance ID. + */ +void LPTMR_DRV_IRQHandler(uint32_t instance); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif +#endif /* __FSL_LPTMR_H__*/ +/******************************************************************************* + * EOF + *******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_lpuart_dma_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_lpuart_dma_driver.h new file mode 100755 index 0000000..4284675 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_lpuart_dma_driver.h @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_LPUART_DMA_DRIVER_H__ +#define __FSL_LPUART_DMA_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_os_abstraction.h" +#include "fsl_lpuart_hal.h" +#include "fsl_dma_driver.h" +#include "fsl_clock_manager.h" + +/*! + * @addtogroup lpuart_driver + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for LPUART instances. */ +extern LPUART_Type * const g_lpuartBase[LPUART_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Runtime state structure for UART driver with DMA. + */ +typedef struct LpuartDmaState { + volatile bool isTxBusy; /*!< True if there is an active transmit. */ + volatile bool isRxBusy; /*!< True if there is an active receive. */ + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its TX business. */ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its RX business. */ + dma_channel_t dmaLpuartTx; /*!< Structure definition for the DMA channel */ + dma_channel_t dmaLpuartRx; /*!< Structure definition for the DMA channel */ +} lpuart_dma_state_t; + +/*! @brief LPUART configuration structure*/ +typedef struct LpuartDmaUserConfig { + clock_lpuart_src_t clockSource; /*!< LPUART clock source in fsl_sim_hal_<device>.h */ + uint32_t baudRate; /*!< LPUART baud rate*/ + lpuart_parity_mode_t parityMode; /*!< parity mode, disabled (default), even, odd */ + lpuart_stop_bit_count_t stopBitCount;/*!< number of stop bits, 1 stop bit (default) or 2 stop bits*/ + lpuart_bit_count_per_char_t bitCountPerChar; /*!< number of bits, 8-bit (default) or 9-bit in a + char (up to 10-bits in some LPUART instances.*/ +} lpuart_dma_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name LPUART DMA Driver + * @{ + */ + +/*! + * @brief Initializes an LPUART instance to work with DMA. + * + * This function initializes the run-time state structure to keep track of the on-going + * transfers, un-gates the clock to the LPUART module, initializes the module + * to user-defined settings and default settings, configures the IRQ state structure and enables + * the module-level interrupt to the core, and enables the LPUART module transmitter and receiver. + * This example shows how to set up the lpuart_dma_state_t and the + * lpuart_user_config_t parameters and how to call the LPUART_DRV_DmaInit function by passing + * in these parameters: + @code + lpuart_user_config_t lpuartConfig; + lpuartConfig.baudRate = 9600; + lpuartConfig.bitCountPerChar = kLpuart8BitsPerChar; + lpuartConfig.parityMode = kLpuartParityDisabled; + lpuartConfig.stopBitCount = kLpuartOneStopBit; + lpuart_dma_state_t lpuartDmaState; + LPUART_DRV_DmaInit(instance, &lpuartDmaState, &lpuartConfig); + @endcode + * + * @param instance The LPUART instance number. + * @param lpuartDmaStatePtr A pointer to the LPUART driver state structure memory. The user + * passes in the memory for the run-time state structure. The LPUART driver + * populates the members. This run-time state structure keeps track of the + * current transfer in progress. + * @param lpuartUserConfig The user configuration structure of type lpuart_user_config_t. The user + * populates the members of this structure and passes the pointer of this structure + * into this function. + * @return An error code or kStatus_LPUART_Success. + */ +lpuart_status_t LPUART_DRV_DmaInit(uint32_t instance, lpuart_dma_state_t * lpuartDmaStatePtr, + const lpuart_dma_user_config_t * lpuartUserConfig); +/*! + * @brief Shuts down the LPUART. + * + * This function disables the LPUART-DMA trigger, the transmitter, and the receiver. + * + * @param instance The LPUART instance number. + * @return An error code or kStatus_LPUART_Success. + */ +lpuart_status_t LPUART_DRV_DmaDeinit(uint32_t instance); + +/*! + * @brief Sends (transmits) data out through the LPUART-DMA module using a blocking method. + * + * @param instance The LPUART instance number. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_LPUART_Success. + */ +lpuart_status_t LPUART_DRV_DmaSendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the LPUART-DMA module using a non-blocking method. + * + * @param instance The LPUART module base address. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_LPUART_Success. + */ +lpuart_status_t LPUART_DRV_DmaSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +/*! + * @brief Returns whether the previous LPUART-DMA transmit has finished. + * + * @param instance The LPUART module base address. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes that + * are remaining in the active transfer. + * @return Current transmit status. + * @retval kStatus_LPUART_Success The transmit has completed successfully. + * @retval kStatus_LPUART_TxBusy The transmit is still in progress. @a bytesTransmitted is + * filled with the number of bytes which are transmitted up to that point. + */ +lpuart_status_t LPUART_DRV_DmaGetTransmitStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates a non-blocking LPUART-DMA transmission early. + * + * @param instance The LPUART module base address. + * @return Whether the abort of transmitting was successful or not. + * @retval kStatus_LPUART_Success The transmit was successful. + * @retval kStatus_LPUART_NoTransmitInProgress No transmission is currently in progress. + */ +lpuart_status_t LPUART_DRV_DmaAbortSendingData(uint32_t instance); + +/*! + * @brief Gets (receives) data from the LPUART-DMA module using a blocking method. + * + * @param instance The LPUART module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_LPUART_Success. + */ +lpuart_status_t LPUART_DRV_DmaReceiveDataBlocking(uint32_t instance, uint8_t * rxBuff, + uint32_t rxSize, uint32_t timeout); +/*! + * @brief Gets (receives) data from the LPUART-DMA module using a non-blocking method. + * + * @param instance The LPUART module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_LPUART_Success. + */ +lpuart_status_t LPUART_DRV_DmaReceiveData(uint32_t instance, uint8_t * rxBuff, uint32_t rxSize); + +/*! + * @brief Returns whether the previous LPUART-DMA receive is complete. + * + * @param instance The LPUART module base address. + * @param bytesRemaining A pointer to a value that populated with the number of bytes which + * still need to be received in the active transfer. + * @return Current receiving status. + * @retval kStatus_LPUART_Success The receive has completed successfully. + * @retval kStatus_LPUART_RxBusy The receive is still in progress. @a bytesReceived is + * filled with the number of bytes which are received up to that point. + */ +lpuart_status_t LPUART_DRV_DmaGetReceiveStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates a non-blocking LPUART-DMA receive early. + * + * @param instance The LPUART module base address. + * @return Whether the abort of receiving was successful or not. + * @retval kStatus_LPUART_Success The receive was successful. + * @retval kStatus_LPUART_NoTransmitInProgress No receive is currently in progress. + */ +lpuart_status_t LPUART_DRV_DmaAbortReceivingData(uint32_t instance); + +/*@}*/ + + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __FSL_LPUART_DMA_DRIVER_H__ */ +/******************************************************************************/ +/* EOF */ +/******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_lpuart_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_lpuart_driver.h new file mode 100755 index 0000000..abf6401 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_lpuart_driver.h @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_LPUART_DRIVER_H__ +#define __FSL_LPUART_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_os_abstraction.h" +#include "fsl_lpuart_hal.h" +#include "fsl_clock_manager.h" + +/*! + * @addtogroup lpuart_driver + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for LPUART instances. */ +extern LPUART_Type * const g_lpuartBase[LPUART_INSTANCE_COUNT]; + +/*! @brief Table to save LPUART IRQ enumeration numbers defined in the CMSIS header file */ +extern const IRQn_Type g_lpuartRxTxIrqId[LPUART_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief LPUART receive callback function type. */ +typedef void (* lpuart_rx_callback_t)(uint32_t instance, void * lpuartState); + +/*! @brief UART transmit callback function type */ +typedef void (* lpuart_tx_callback_t)(uint32_t instance, void * lpuartState); + +/*! + * @brief Runtime state of the LPUART driver. + * + * Note that the caller provides memory for the driver state structures during + * initialization because the driver does not statically allocate memory. + */ +typedef struct LpuartState { + const uint8_t * txBuff; /*!< The buffer of data being sent.*/ + uint8_t * rxBuff; /*!< The buffer of received data.*/ + volatile size_t txSize; /*!< The remaining number of bytes to be transmitted. */ + volatile size_t rxSize; /*!< The remaining number of bytes to be received. */ + volatile bool isTxBusy; /*!< True if there is an active transmit.*/ + volatile bool isRxBusy; /*!< True if there is an active receive.*/ + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its Tx business.*/ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its Rx business.*/ + lpuart_rx_callback_t rxCallback; /*!< Callback to invoke after receiving byte.*/ + void * rxCallbackParam; /*!< Receive callback parameter pointer.*/ + lpuart_tx_callback_t txCallback; /*!< Callback to invoke after transmitting byte.*/ + void * txCallbackParam; /*!< Transmit callback parameter pointer.*/ +} lpuart_state_t; + +/*! @brief LPUART configuration structure + * @internal gui name="Configuration" id="Configuration" + */ +typedef struct LpuartUserConfig { + clock_lpuart_src_t clockSource; /*!< LPUART clock source @internal gui name="Clock source" id="ClockSource" */ + uint32_t baudRate; /*!< LPUART baud rate @internal gui name="Baud rate" id="BaudRate" */ + lpuart_parity_mode_t parityMode; /*!< parity mode, disabled (default), even, odd @internal gui name="Parity mode" id="Parity" */ + lpuart_stop_bit_count_t stopBitCount;/*!< number of stop bits, 1 stop bit (default) or 2 stop bits @internal gui name="Stop bits" id="StopBits" */ + lpuart_bit_count_per_char_t bitCountPerChar; /*!< number of bits, 8-bit (default) or 9-bit in a + char (up to 10-bits in some LPUART instances. @internal gui name="Bits per char" id="DataBits" */ +} lpuart_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name LPUART Driver + * @{ + */ + +/*! + * @brief Initializes an LPUART operation instance. + * + * The caller provides memory for the driver state structures during initialization. + * The user must select the LPUART clock source in the application to initialize the LPUART. + * + * @param instance LPUART instance number + * @param lpuartUserConfig user configuration structure of type #lpuart_user_config_t + * @param lpuartStatePtr pointer to the LPUART driver state structure + * @return An error code or kStatus_LPUART_Success + */ +lpuart_status_t LPUART_DRV_Init(uint32_t instance, lpuart_state_t * lpuartStatePtr, + const lpuart_user_config_t * lpuartUserConfig); + +/*! + * @brief Shuts down the LPUART by disabling interrupts and transmitter/receiver. + * + * @param instance LPUART instance number + * @return An error code or kStatus_LPUART_Success + */ +lpuart_status_t LPUART_DRV_Deinit(uint32_t instance); + +/*! + * @brief Installs callback function for the LPUART receive. + * + * @note After a callback is installed, it bypasses part of the LPUART IRQHandler logic. + * Therefore, the callback needs to handle the indexes of txBuff and txSize. + * + * @param instance The LPUART instance number. + * @param function The LPUART receive callback function. + * @param rxBuff The receive buffer used inside IRQHandler. This buffer must be kept as long as the callback is alive. + * @param callbackParam The LPUART receive callback parameter pointer. + * @param alwaysEnableRxIrq Whether always enable receive IRQ or not. + * @return Former LPUART receive callback function pointer. + */ +lpuart_rx_callback_t LPUART_DRV_InstallRxCallback(uint32_t instance, + lpuart_rx_callback_t function, + uint8_t * rxBuff, + void * callbackParam, + bool alwaysEnableRxIrq); +/*! + * @brief Installs callback function for the LPUART transmit. + * + * @note After a callback is installed, it bypasses part of the LPUART IRQHandler logic. + * Therefore, the callback needs to handle the indexes of txBuff and txSize. + * + * @param instance The LPUART instance number. + * @param function The LPUART transmit callback function. + * @param txBuff The transmit buffer used inside IRQHandler. This buffer must be kept as long as the callback is alive. + * @param callbackParam The LPUART transmit callback parameter pointer. + * @return Former LPUART transmit callback function pointer. + */ +lpuart_tx_callback_t LPUART_DRV_InstallTxCallback(uint32_t instance, + lpuart_tx_callback_t function, + uint8_t * txBuff, + void * callbackParam); + +/*! + * @brief Sends data out through the LPUART module using a blocking method. + * + * Blocking means that the function does not return until the transmission is complete. + * + * @param instance LPUART instance number + * @param txBuff source buffer containing 8-bit data chars to send + * @param txSize the number of bytes to send + * @param timeout timeout value for RTOS abstraction sync control + * @return An error code or kStatus_LPUART_Success + */ +lpuart_status_t LPUART_DRV_SendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends data out through the LPUART module using a non-blocking method. + * This enables an a-sync method for transmitting data. When used with + * a non-blocking receive, the LPUART can perform a full duplex operation. + * Non-blocking means that the function returns immediately. + * The application has to get the transmit status to know when the transmit is complete. + * + * @param instance LPUART instance number + * @param txBuff source buffer containing 8-bit data chars to send + * @param txSize the number of bytes to send + * @return An error code or kStatus_LPUART_Success + */ +lpuart_status_t LPUART_DRV_SendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); + +/*! + * @brief Returns whether the previous transmit is complete. + * + * @param instance LPUART instance number + * @param bytesRemaining Pointer to value that is populated with the number of bytes that + * have been sent in the active transfer + * @return The transmit status. + * @retval kStatus_LPUART_Success The transmit has completed successfully. + * @retval kStatus_LPUART_TxBusy The transmit is still in progress. @a bytesTransmitted will be + * filled with the number of bytes that have been transmitted so far. + */ +lpuart_status_t LPUART_DRV_GetTransmitStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates a non-blocking transmission early. + * + * @param instance LPUART instance number + * @return Whether the aborting is successful or not. + */ +lpuart_status_t LPUART_DRV_AbortSendingData(uint32_t instance); + +/*! + * @brief Gets data from the LPUART module by using a blocking method. + * Blocking means that the function does not return until the + * receive is complete. + * + * @param instance LPUART instance number + * @param rxBuff buffer containing 8-bit read data chars received + * @param rxSize the number of bytes to receive + * @param timeout timeout value for RTOS abstraction sync control + * @return An error code or kStatus_LPUART_Success + */ +lpuart_status_t LPUART_DRV_ReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout); + +/*! + * @brief Gets data from the LPUART module by using a non-blocking method. + * This enables an a-sync method for receiving data. When used with + * a non-blocking transmission, the LPUART can perform a full duplex operation. + * Non-blocking means that the function returns immediately. + * The application has to get the receive status to know when the receive is complete. + * + * @param instance LPUART instance number + * @param rxBuff buffer containing 8-bit read data chars received + * @param rxSize the number of bytes to receive + * @return An error code or kStatus_LPUART_Success + */ +lpuart_status_t LPUART_DRV_ReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize); + +/*! + * @brief Returns whether the previous receive is complete. + * + * @param instance LPUART instance number + * @param bytesRemaining pointer to value that is filled with the number of bytes that + * still need to be received in the active transfer. + * @return The receive status. + * @retval kStatus_LPUART_Success the receive has completed successfully. + * @retval kStatus_LPUART_RxBusy the receive is still in progress. @a bytesReceived will be + * filled with the number of bytes that have been received so far. + */ +lpuart_status_t LPUART_DRV_GetReceiveStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates a non-blocking receive early. + * + * @param instance LPUART instance number + * + * @return Whether the receiving was successful or not. + */ +lpuart_status_t LPUART_DRV_AbortReceivingData(uint32_t instance); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __FSL_LPUART_DRIVER_H__ */ +/******************************************************************************/ +/* EOF */ +/******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_lpuart_edma_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_lpuart_edma_driver.h new file mode 100755 index 0000000..4814eb3 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_lpuart_edma_driver.h @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_LPUART_EDMA_DRIVER_H__ +#define __FSL_LPUART_EDMA_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_os_abstraction.h" +#include "fsl_lpuart_hal.h" +#include "fsl_edma_driver.h" +#include "fsl_clock_manager.h" + +/*! + * @addtogroup lpuart_driver + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for LPUART instances. */ +extern LPUART_Type * const g_lpuartBase[LPUART_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Runtime state structure for UART driver with DMA. + */ +typedef struct LpuartEdmaState { + volatile bool isTxBusy; /*!< True if there is an active transmit. */ + volatile bool isRxBusy; /*!< True if there is an active receive. */ + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its TX business. */ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its RX business. */ + edma_chn_state_t edmaLpuartTx; /*!< Structure definition for the eDMA channel */ + edma_chn_state_t edmaLpuartRx; /*!< Structure definition for the eDMA channel */ +} lpuart_edma_state_t; + +/*! @brief LPUART configuration structure*/ +typedef struct LpuartEdmaUserConfig { + clock_lpuart_src_t clockSource; /*!< LPUART clock source in fsl_sim_hal_<device>.h */ + uint32_t baudRate; /*!< LPUART baud rate*/ + lpuart_parity_mode_t parityMode; /*!< parity mode, disabled (default), even, odd */ + lpuart_stop_bit_count_t stopBitCount;/*!< number of stop bits, 1 stop bit (default) or 2 stop bits*/ + lpuart_bit_count_per_char_t bitCountPerChar; /*!< number of bits, 8-bit (default) or 9-bit in a + char (up to 10-bits in some LPUART instances.*/ +} lpuart_edma_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name LPUART DMA Driver + * @{ + */ + +/*! + * @brief Initializes an LPUART instance to work with DMA. + * + * This function initializes the run-time state structure to keep track of the on-going + * transfers, un-gates the clock to the LPUART module, initializes the module + * to user-defined settings and default settings, configures the IRQ state structure and enables + * the module-level interrupt to the core, and enables the LPUART module transmitter and receiver. + * This example shows how to set up the lpuart_edma_state_t and the + * lpuart_user_config_t parameters and how to call the LPUART_DRV_EdmaInit function by passing + * in these parameters: + @code + lpuart_user_config_t lpuartConfig; + lpuartConfig.baudRate = 9600; + lpuartConfig.bitCountPerChar = kLpuart8BitsPerChar; + lpuartConfig.parityMode = kLpuartParityDisabled; + lpuartConfig.stopBitCount = kLpuartOneStopBit; + lpuart_edma_state_t lpuartEdmaState; + LPUART_DRV_EdmaInit(instance, &lpuartEdmaState, &lpuartConfig); + @endcode + * + * @param instance The LPUART instance number. + * @param lpuartEdmaStatePtr A pointer to the LPUART driver state structure memory. The user + * passes in the memory for the run-time state structure. The LPUART driver + * populates the members. This run-time state structure keeps track of the + * current transfer in progress. + * @param lpuartUserConfig The user configuration structure of type lpuart_user_config_t. The user + * populates the members of this structure and passes the pointer of this structure + * into this function. + * @return An error code or kStatus_LPUART_Success. + */ +lpuart_status_t LPUART_DRV_EdmaInit(uint32_t instance, lpuart_edma_state_t * lpuartEdmaStatePtr, + const lpuart_edma_user_config_t * lpuartUserConfig); +/*! + * @brief Shuts down the LPUART. + * + * This function disables the LPUART-DMA trigger, the transmitter, and the receiver. + * + * @param instance The LPUART instance number. + * @return An error code or kStatus_LPUART_Success. + */ +lpuart_status_t LPUART_DRV_EdmaDeinit(uint32_t instance); + +/*! + * @brief Sends (transmits) data out through the LPUART-DMA module using a blocking method. + * + * @param instance The LPUART instance number. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_LPUART_Success. + */ +lpuart_status_t LPUART_DRV_EdmaSendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the LPUART-DMA module using a non-blocking method. + * + * @param instance The LPUART module base address. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_LPUART_Success. + */ +lpuart_status_t LPUART_DRV_EdmaSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +/*! + * @brief Returns whether the previous LPUART-DMA transmit has finished. + * + * @param instance The LPUART module base address. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes that + * are remaining in the active transfer. + * @return Current transmit status. + * @retval kStatus_LPUART_Success The transmit has completed successfully. + * @retval kStatus_LPUART_TxBusy The transmit is still in progress. @a bytesTransmitted is + * filled with the number of bytes which are transmitted up to that point. + */ +lpuart_status_t LPUART_DRV_EdmaGetTransmitStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates a non-blocking LPUART-DMA transmission early. + * + * @param instance The LPUART module base address. + * @return Whether the abort of transmitting was successful or not. + * @retval kStatus_LPUART_Success The transmit was successful. + * @retval kStatus_LPUART_NoTransmitInProgress No transmission is currently in progress. + */ +lpuart_status_t LPUART_DRV_EdmaAbortSendingData(uint32_t instance); + +/*! + * @brief Gets (receives) data from the LPUART-DMA module using a blocking method. + * + * @param instance The LPUART module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_LPUART_Success. + */ +lpuart_status_t LPUART_DRV_EdmaReceiveDataBlocking(uint32_t instance, uint8_t * rxBuff, + uint32_t rxSize, uint32_t timeout); +/*! + * @brief Gets (receives) data from the LPUART-DMA module using a non-blocking method. + * + * @param instance The LPUART module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_LPUART_Success. + */ +lpuart_status_t LPUART_DRV_EdmaReceiveData(uint32_t instance, uint8_t * rxBuff, uint32_t rxSize); + +/*! + * @brief Returns whether the previous LPUART-DMA receive is complete. + * + * @param instance The LPUART module base address. + * @param bytesRemaining A pointer to a value that populated with the number of bytes which + * still need to be received in the active transfer. + * @return Current receiving status. + * @retval kStatus_LPUART_Success The receive has completed successfully. + * @retval kStatus_LPUART_RxBusy The receive is still in progress. @a bytesReceived is + * filled with the number of bytes which are received up to that point. + */ +lpuart_status_t LPUART_DRV_EdmaGetReceiveStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates a non-blocking LPUART-DMA receive early. + * + * @param instance The LPUART module base address. + * @return Whether the abort of receiving was successful or not. + * @retval kStatus_LPUART_Success The receive was successful. + * @retval kStatus_LPUART_NoTransmitInProgress No receive is currently in progress. + */ +lpuart_status_t LPUART_DRV_EdmaAbortReceivingData(uint32_t instance); + +/*@}*/ + + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __FSL_LPUART_EDMA_DRIVER_H__ */ +/******************************************************************************/ +/* EOF */ +/******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_mpu_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_mpu_driver.h new file mode 100755 index 0000000..78b6128 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_mpu_driver.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_MPU_DRIVER_H__ +#define __FSL_MPU_DRIVER_H__ + +#include <assert.h> +#include <stdint.h> +#include <stdbool.h> +#include "fsl_mpu_hal.h" +#if FSL_FEATURE_SOC_MPU_COUNT + +/*! + * @addtogroup mpu_driver + * @{ + */ + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @brief Table of base addresses for MPU instances. */ +extern MPU_Type * const g_mpuBase[]; + + /*! @brief Table to save MPU IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_mpuIrqId[MPU_INSTANCE_COUNT]; + +/*! + * @brief Data The section describes the programming interface of the for MPU region initialization + * + * This structure is used when calling the MPU_DRV_Init function. + * + */ +typedef struct MpuUserConfig{ + mpu_region_config_t regionConfig; /*!< region access permission */ + struct MpuUserConfig *next; /*!< pointer to the next structure */ +}mpu_user_config_t; + +/*! + * @brief MPU driver user call back function. + * + * The contents of this structure provides a callback function. + */ + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name MPU Driver + * @{ + */ + + +/*! + * @brief Initializes the MPU driver. + * + * @param instance The MPU peripheral instance number. + * @param userConfigPtr The pointer to the MPU user configure structure, see #mpu_user_config_t. + * @param userStatePtr The pointer of run time structure. + * @return kStatus_MPU_Success means success. Otherwise, means failure. + */ + mpu_status_t MPU_DRV_Init(uint32_t instance, const mpu_user_config_t *userConfigPtr); + +/*! + * @brief De-initializes the MPU region. + * + * @param instance The MPU peripheral instance number. + * @return kStatus_MPU_Success means success. Otherwise, means failure. + */ +void MPU_DRV_Deinit(uint32_t instance); + +/*! + * @brief Configures the MPU region. + * + * @param instance The MPU peripheral instance number. + * @param regionConfigPtr The pointer to the MPU user configure structure, see #mpu_region_config_t. + * @return kStatus_MPU_Success means success. Otherwise, means failure. + */ +mpu_status_t MPU_DRV_SetRegionConfig(uint32_t instance, const mpu_region_config_t *regionConfigPtr); + +/*! + * @brief Sets region start address. + * + * @param instance The MPU peripheral instance number. + * @param regionNum The region number. + * @param startAddr Region start address. + * @param endAddr Region end address. + */ +void MPU_DRV_SetRegionAddr(uint32_t instance, mpu_region_num_t regionNum, uint32_t startAddr, uint32_t endAddr); + +/*! + * @brief Configures low master access permission. + * + * @param instance The MPU peripheral instance number. + * @param regionNum The MPU region number. + * @param masterNum The MPU master number. + * @param accessRightsPtr A pointer to access permission structure. + * @return kStatus_MPU_Success means success. Otherwise, means failure. + */ +mpu_status_t MPU_DRV_SetLowMasterAccessRights(uint32_t instance, mpu_region_num_t regionNum, mpu_master_t masterNum, const mpu_low_masters_access_rights_t *accessRightsPtr); + +/*! + * @brief Configures high master access permission. + * + * @param instance The MPU peripheral instance number. + * @param regionNum The MPU region number. + * @param masterNum The MPU master number. + * @param accessRightsPtr A pointer to access permission structure. + * @return kStatus_MPU_Success means success. Otherwise, means failure. + */ +mpu_status_t MPU_DRV_SetHighMasterAccessRights(uint32_t instance, mpu_region_num_t regionNum, mpu_master_t masterNum, const mpu_high_masters_access_rights_t *accessRightsPtr); + + /*! + * @brief Sets the MPU region valid. + * + * @param instance The MPU peripheral instance number. + * @param regionNum MPU region number. + * @param enable Enables or disables region. + */ +void MPU_DRV_SetRegionValidCmd(uint32_t instance, mpu_region_num_t regionNum, bool enable); + + /*! + * @brief Gets the MPU access error detail information. + * + * @param instance The MPU peripheral instance number. + * @param errInfoArrayPtr A pointer to access error info structure. + */ +mpu_status_t MPU_DRV_GetDetailErrorAccessInfo(uint32_t instance, mpu_access_err_info_t *errInfoArrayPtr); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif +#endif /* __FSL_MPU_H__*/ +/******************************************************************************* + * EOF + *******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_pdb_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_pdb_driver.h new file mode 100755 index 0000000..a658623 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_pdb_driver.h @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_PDB_DRIVER_H__ +#define __FSL_PDB_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_pdb_hal.h" +#if FSL_FEATURE_SOC_PDB_COUNT + +/*! + * @addtogroup pdb_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @brief Defines the type of structure for configuring ADC's pre_trigger. + * @internal gui name="ADC pre-trigger configuration" id="pdbAdcTrgCfg" + */ +typedef struct PdbAdcPreTriggerConfig +{ + uint32_t adcPreTriggerIdx; /*!< Setting pre_trigger's index. */ + bool preTriggerEnable; /*!< Enable the pre_trigger. */ + bool preTriggerOutputEnable; /*!< Enable the pre_trigger output. @internal gui name="Trigger output" id="AdcTriggerOutput" */ + bool preTriggerBackToBackEnable; /*!< Enable the back to back mode for ADC pre_trigger. @internal gui name="Back-To-Back mode" id="AdcBackToBackMode" */ +} pdb_adc_pretrigger_config_t; + +/*! + * @brief Defines the type of flag for PDB pre-trigger events. + * @internal gui name="DAC trigger configuration" id="pdbDacTrgCfg" + */ +typedef struct PdbDacIntervalConfig +{ + bool intervalTriggerEnable; /*!< Enable the DAC interval trigger. */ + bool extTriggerInputEnable; /*!< Enable DAC external trigger input . @internal gui name="External trigger" id="DacExternalTrigger" */ +} pdb_dac_interval_config_t; + +/*! @brief Table of base addresses for PDB instances. */ +extern PDB_Type * const g_pdbBase[]; + +/*! @brief Table to save PDB IRQ enumeration numbers defined in CMSIS header file. */ +extern const IRQn_Type g_pdbIrqId[PDB_INSTANCE_COUNT]; + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the PDB counter and triggers input. + * + * This function initializes the PDB counter and triggers the input. + * It resets PDB registers and enables the PDB clock. Therefore, it should be + * called before any other operation. After it is initialized, the PDB can + * act as a triggered timer, which enables other features in PDB module. + * + * @param instance PDB instance ID. + * @param userConfigPtr Pointer to the user configuration structure. See the "pdb_user_config_t". + * @return Execution status. + */ +pdb_status_t PDB_DRV_Init(uint32_t instance, const pdb_timer_config_t *userConfigPtr); + +/*! + * @brief De-initializes the PDB module. + * + * This function de-initializes the PDB module. + * Calling this function shuts down the PDB module and reduces the power consumption. + * + * @param instance PDB instance ID. + * @return Execution status. + */ +pdb_status_t PDB_DRV_Deinit(uint32_t instance); + +/*! + * @brief Triggers the PDB with a software trigger. + * + * This function triggers the PDB with a software trigger. + * When the PDB is set to use the software trigger as input, calling this function + * triggers the PDB. + * + * @param instance PDB instance ID. + */ +void PDB_DRV_SoftTriggerCmd(uint32_t instance); + +/*! + * @brief Gets the current counter value in the PDB module. + * + * This function gets the current counter value. + * + * @param instance PDB instance ID. + * @return Current PDB counter value. + */ +uint32_t PDB_DRV_GetTimerValue(uint32_t instance); + +/*! + * @brief Gets the PDB interrupt flag. + * + * This function gets the PDB interrupt flag. It is asserted if the PDB interrupt occurs. + * + * @param instance PDB instance ID. + * @return Assertion of indicated event. + */ +bool PDB_DRV_GetTimerIntFlag(uint32_t instance); + +/*! + * @brief Clears the interrupt flag. + * + * This function clears the interrupt flag. + * + * @param instance PDB instance ID. + */ +void PDB_DRV_ClearTimerIntFlag(uint32_t instance); + +/*! + * @brief Executes the command of loading values. + * + * This function executes the command of loading values. + * + * @param instance PDB instance ID. + * @param value Setting value. + */ +void PDB_DRV_LoadValuesCmd(uint32_t instance); + +/*! + * @brief Sets the value of timer modulus. + * + * This function sets the value of timer modulus. + * + * @param instance PDB instance ID. + * @param value Setting value. + */ +void PDB_DRV_SetTimerModulusValue(uint32_t instance, uint32_t value); + +/*! + * @brief Sets the value for the timer interrupt. + * + * This function sets the value for the timer interrupt. + * + * @param instance PDB instance ID. + * @param value Setting value. + */ +void PDB_DRV_SetValueForTimerInterrupt(uint32_t instance, uint32_t value); + +/*! + * @brief Configures the ADC pre_trigger in the PDB module. + * + * This function configures the ADC pre_trigger in the PDB module. + * + * @param instance PDB instance ID. + * @param chn ADC channel. + * @param configPtr Pointer to the user configuration structure. See the "pdb_adc_pretrigger_config_t". + * @return Execution status. + */ +pdb_status_t PDB_DRV_ConfigAdcPreTrigger(uint32_t instance, uint32_t chn, const pdb_adc_pretrigger_config_t *configPtr); + +/*! + * @brief Gets the ADC pre_trigger flag in the PDB module. + * + * This function gets the ADC pre_trigger flags in the PDB module. + * + * @param instance PDB instance ID. + * @param chn ADC channel. + * @param preChnMask ADC pre_trigger channels mask. + * @return Assertion of indicated flag. + */ +uint32_t PDB_DRV_GetAdcPreTriggerFlags(uint32_t instance, uint32_t chn, uint32_t preChnMask); + +/*! + * @brief Clears the ADC pre_trigger flag in the PDB module. + * + * This function clears the ADC pre_trigger flags in the PDB module. + * + * @param instance PDB instance ID. + * @param chn ADC channel. + * @param preChnMask ADC pre_trigger channels mask. + */ +void PDB_DRV_ClearAdcPreTriggerFlags(uint32_t instance, uint32_t chn, uint32_t preChnMask); + +/*! + * @brief Gets the ADC pre_trigger flag in the PDB module. + * + * This function gets the ADC pre_trigger flags in the PDB module. + * + * @param instance PDB instance ID. + * @param chn ADC channel. + * @param preChnMask ADC pre_trigger channels mask. + * @return Assertion of indicated flag. + */ +uint32_t PDB_DRV_GetAdcPreTriggerSeqErrFlags(uint32_t instance, uint32_t chn, uint32_t preChnMask); + +/*! + * @brief Clears the ADC pre_trigger flag in the PDB module. + * + * This function clears the ADC pre_trigger sequence error flags in the PDB module. + * + * @param instance PDB instance ID. + * @param chn ADC channel. + * @param preChnMask ADC pre_trigger channels mask. + */ +void PDB_DRV_ClearAdcPreTriggerSeqErrFlags(uint32_t instance, uint32_t chn, uint32_t preChnMask); + +/*! + * @brief Sets the ADC pre_trigger delay value in the PDB module. + * + * This function sets Set the ADC pre_trigger delay value in the PDB module. + * + * @param instance PDB instance ID. + * @param chn ADC channel. + * @param preChn ADC pre_channel. + * @param value Setting value. + */ +void PDB_DRV_SetAdcPreTriggerDelayValue(uint32_t instance, uint32_t chn, uint32_t preChn, uint32_t value); + +/*! + * @brief Configures the DAC interval in the PDB module. + * + * This function configures the DAC interval in the PDB module. + * + * @param instance PDB instance ID. + * @param dacChn DAC channel. + * @param configPtr Pointer to the user configuration structure. See the "pdb_dac_interval_config_t". + * @return Execution status. + */ +pdb_status_t PDB_DRV_ConfigDacInterval(uint32_t instance, uint32_t dacChn, const pdb_dac_interval_config_t *configPtr); + +/*! + * @brief Sets the DAC interval value in the PDB module. + * + * This function sets the DAC interval value in the PDB module. + * + * @param instance PDB instance ID. + * @param dacChn DAC channel. + * @param value Setting value. + */ +void PDB_DRV_SetDacIntervalValue(uint32_t instance, uint32_t dacChn, uint32_t value); + +/*! + * @brief Switches on/off the CMP pulse out in the PDB module. + * + * This function switches the CMP pulse on/off in the PDB module. + * + * @param instance PDB instance ID. + * @param pulseChnMask Pulse channel mask. + * @param enable Switcher to assert the feature. + */ +void PDB_DRV_SetCmpPulseOutEnable(uint32_t instance, uint32_t pulseChnMask, bool enable); + +/*! + * @brief Sets the CMP pulse out delay value for high in the PDB module. + * + * This function sets the CMP pulse out delay value for high in the PDB module. + * + * @param instance PDB instance ID. + * @param pulseChn Pulse channel. + * @param value Setting value. + */ +void PDB_DRV_SetCmpPulseOutDelayForHigh(uint32_t instance, uint32_t pulseChn, uint32_t value); + +/*! + * @brief Sets the CMP pulse out delay value for low in the PDB module. + * + * This function sets the CMP pulse out delay value for low in the PDB module. + * + * @param instance PDB instance ID. + * @param pulseChn Pulse channel. + * @param value Setting value. + */ +void PDB_DRV_SetCmpPulseOutDelayForLow(uint32_t instance, uint32_t pulseChn, uint32_t value); + +#if defined(__cplusplus) +} +#endif + +/*! + *@} + */ + +#endif +#endif /* __FSL_PDB_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_pit_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_pit_driver.h new file mode 100755 index 0000000..01d775a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_pit_driver.h @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_PIT_DRIVER_H__ +#define __FSL_PIT_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_pit_hal.h" + +/*! + * @addtogroup pit_driver + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for pit instances. */ +extern PIT_Type * const g_pitBase[]; + +/* Table to save pit IRQ enumeration numbers defined in the CMSIS header file */ +extern const IRQn_Type g_pitIrqId[]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief PIT timer configuration structure + * + * Defines a structure PitConfig and uses the PIT_DRV_InitChannel() function to make necessary + * initializations. You may also use the remaining functions for PIT configuration. + * + * @note The timer chain feature is not valid in all devices. Check the + * fsl_pit_features.h for accurate settings. If it's not valid, the value set here + * is bypassed inside the PIT_DRV_InitChannel() function. + * @internal gui name="PIT configuration" id="pitCfg" + */ +typedef struct PitUserConfig { + bool isInterruptEnabled; /*!< Timer interrupt 0-disable/1-enable @internal gui name="Interrupt" id="Interrupt" default="true" */ + uint32_t periodUs; /*!< Timer period in unit of microseconds @internal gui name="Period" id="Period" */ +} pit_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and Shutdown + * @{ + */ + +/*! + * @brief Initializes the PIT module. + * + * Call this function before calling all the other PIT driver functions. + * This function un-gates the PIT clock and enables the PIT module. The isRunInDebug + * passed into function affects all timer channels. + * + * @param instance PIT module instance number. + * @param isRunInDebug Timers run or stop in debug mode. + * - true: Timers continue to run in debug mode. + * - false: Timers stop in debug mode. + * @return Error or success status returned by API. + */ +pit_status_t PIT_DRV_Init(uint32_t instance, bool isRunInDebug); + +/*! + * @brief Disables the PIT module and gate control. + * + * This function disables all PIT interrupts and PIT clock. It then gates the + * PIT clock control. PIT_DRV_Init must be called if you want to use PIT again. + * + * @param instance PIT module instance number. + * @return Error or success status returned by API. + */ +pit_status_t PIT_DRV_Deinit(uint32_t instance); + +/*! + * @brief Initializes the PIT channel. + * + * This function initializes the PIT timers by using a channel. Pass in the timer number and its + * configuration structure. Timers do not start counting by default after calling this + * function. The function PIT_DRV_StartTimer must be called to start the timer counting. + * Call the PIT_DRV_SetTimerPeriodByUs to re-set the period. + * + * This is an example demonstrating how to define a PIT channel configuration structure: + @code + pit_user_config_t pitTestInit = { + .isInterruptEnabled = true, + // In unit of microseconds. + .periodUs = 1000, + }; + @endcode + * + * @param instance PIT module instance number. + * @param channel Timer channel number. + * @param config PIT channel configuration structure. + */ +void PIT_DRV_InitChannel(uint32_t instance, uint32_t channel, const pit_user_config_t * config); + +/* @} */ + +/*! + * @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 instance PIT module instance number. + * @param channel Timer channel number. + */ +void PIT_DRV_StartTimer(uint32_t instance, uint32_t channel); + +/*! + * @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 instance PIT module instance number. + * @param channel Timer channel number. + */ +void PIT_DRV_StopTimer(uint32_t instance, uint32_t channel); + +/* @} */ + +/*! + * @name Timer Period + * @{ + */ + +/*! + * @brief Sets the timer period in microseconds. + * + * The period range depends on the frequency of the PIT source clock. If the required period + * is out of range, use the lifetime timer if applicable. + * This function is only valid for one single channel. If channels are chained together, + * the period here makes no sense. + * + * @param instance PIT module instance number. + * @param channel Timer channel number. + * @param us Timer period in microseconds. + */ +void PIT_DRV_SetTimerPeriodByUs(uint32_t instance, uint32_t channel, uint32_t us); + +/*! + * @brief Gets the timer period in microseconds for one single channel. + * + * @param instance PIT module instance number. + * @param channel Timer channel number. + * @return Timer period in microseconds. + */ +uint32_t PIT_DRV_GetTimerPeriodByUs(uint32_t instance, uint32_t channel); + +/*! + * @brief Reads the current timer value in microseconds. + * + * This function returns an absolute time stamp in microseconds. + * One common use of this function is to measure the running time of a part of + * code. Call this function at both the beginning and end of code. The time + * difference between these two time stamps is the running time. Make sure the + * running time does not exceed the timer period. The time stamp returned is + * up-counting. + * + * @param instance PIT module instance number. + * @param channel Timer channel number. + * @return Current timer value in microseconds. + */ +uint32_t PIT_DRV_ReadTimerUs(uint32_t instance, uint32_t channel); + +/*! + * @brief Sets the timer period in units of count. + * + * Timers begin counting from the value set by this function. + * The counter period of a running timer can be modified by first stopping + * the timer, setting a new load value, and starting the timer again. If + * timers are not restarted, the new value is loaded after the next trigger + * event. + * + * @param instance PIT module instance number. + * @param channel Timer channel number + * @param count Timer period in units of count + */ +void PIT_DRV_SetTimerPeriodByCount(uint32_t instance, uint32_t channel, uint32_t count); + +/*! + * @brief Returns the current timer period in units of count. + * + * @param instance PIT module instance number. + * @param channel Timer channel number + * @return Timer period in units of count + */ +uint32_t PIT_DRV_GetTimerPeriodByCount(uint32_t instance, uint32_t channel); + +/*! + * @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. + * + * @param instance PIT module instance number. + * @param channel Timer channel number + * @return Current timer counting value + */ +uint32_t PIT_DRV_ReadTimerCount(uint32_t instance, uint32_t channel); + +#if FSL_FEATURE_PIT_HAS_LIFETIME_TIMER +/*! + * @brief Sets the lifetime timer period. + * + * Timer 1 must be chained with timer 0 before using the lifetime timer. The period + * range is restricted by "period * pitSourceClock < max of an uint64_t integer", + * or it may cause an overflow and be unable to set the correct period. + * + * @param instance PIT module instance number. + * @param us Lifetime timer period in microseconds. + */ +void PIT_DRV_SetLifetimeTimerPeriodByUs(uint32_t instance, uint64_t us); + +/*! + * @brief Reads the current lifetime value in microseconds. + * + * This feature returns an absolute time stamp in microseconds. The time stamp + * value does not exceed the timer period. The timer is up-counting. + * + * @param instance PIT module instance number. + * @return Current lifetime timer value in microseconds. + */ +uint64_t PIT_DRV_ReadLifetimeTimerUs(uint32_t instance); +#endif /*FSL_FEATURE_PIT_HAS_LIFETIME_TIMER*/ + +/* @} */ + +#if FSL_FEATURE_PIT_HAS_CHAIN_MODE +/*! + * @name Microseconds + * @{ + */ + +/*! + * @brief Initializes two PIT channels to serve as a microseconds unit. + * + * Because this function is in parallel with the PIT_DRV_InitChannel function, the two functions overwrite each other. + * The PIT_DRV_Init function must be called before calling this function. + * If the device has a dedicated lifetime timer, it is more effective than the set of timers. + * The microseconds unit uses two chained channels to simulate a lifetime timer. The + * channel number passed in and the "channel -1" channel are used. + * @note + * 1. These two channels are occupied and could not be used with other purposes. + * 2. The channel number passed in must be greater than 0. + * + * @param instance PIT module instance number. + * @param channel Timer channel number which is chained with the former channel. Must + * be greater than 0. + */ +void PIT_DRV_InitUs(uint32_t instance, uint32_t channel); + +/*! + * @brief Gets an absolute time stamp. + * + * This function gets the elapsed time in time A + * and calls it in time B. The elapsed time can be obtained by B-A. The result may have + * 3-5 microseconds error depending on the system clock frequency. + * + * @return Absolute time stamp from the chained lifetime timers in microsecond units. + */ +uint32_t PIT_DRV_GetUs(void); + +/*! + * @brief Delays the specific microseconds. + * + * The delay may have a 3-5 microseconds error depending on the system clock frequency. + * + * @param us Number of microseconds to delay. + */ +void PIT_DRV_DelayUs(uint32_t us); + +/* @} */ +#endif /* FSL_FEATURE_PIT_HAS_CHAIN_MODE */ + +/*! + * @name Interrupt + * @{ + */ + +/*! + * @brief Clears the timer interrupt flag. + * + * This function clears the timer interrupt flag after a timeout event + * occurs. + * + * @param instance PIT module instance number. + * @param channel Timer channel number + */ +void PIT_DRV_ClearIntFlag(uint32_t instance, uint32_t channel); + +/*! + * @brief Reads the current timer timeout flag. + * + * Every time the timer counts to 0, this flag is set. + * + * @param instance PIT module instance number. + * @param channel Timer channel number + * @return Current status of the timeout flag + * - true: Timeout has occurred. + * - false: Timeout has not yet occurred. + */ +bool PIT_DRV_IsIntPending(uint32_t instance, uint32_t channel); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __FSL_PIT_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_pwm_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_pwm_driver.h new file mode 100755 index 0000000..c02100c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_pwm_driver.h @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_PWM_DRIVER_H__ +#define __FSL_PWM_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> + +#include "fsl_pwm_hal.h" +#include "fsl_os_abstraction.h" + +#if FSL_FEATURE_SOC_PWM_COUNT + +/*! + * @addtogroup pwm_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! Used to indicate a particular pin in the submodule does NOT output a PWM signal */ +#define FLEXPWM_NO_PWM_OUT_SIGNAL (0) + +/*! @brief PWM Signal Type options */ +typedef enum _pwm_signal_type +{ + kFlexPwmSignedCenterAligned = 0U, /*!< Signed centered. @internal gui name="Signed center-aligned PWM" */ + kFlexPwmCenterAligned, /*!< Unsigned centered. @internal gui name="Center-aligned PWM" */ + kFlexPwmSignedEdgeAligned, /*!< Signed edge-aligned. @internal gui name="Signed edge-aligned PWM" */ + kFlexPwmEdgeAligned /*!< Unsigned edge-aligned. @internal gui name="Edge-aligned PWM" */ +} pwm_signal_type_t; + +/*! + * @brief Configuration structure for the user to define the PWM signal characteristics + * + * @internal gui name="PWM signal configuration" id="pwmSignalCfg" + */ +typedef struct PwmModuleSignalSetup { + uint32_t pwmPeriod; /*!< PWM period specified in microseconds. @internal gui name="PWM period" id="pwm_pwmPeriod" */ + pwm_signal_type_t pwmType; /*!< PWM type, edge or center; signed or unsigned. @internal gui name="PWM signal type" id="pwm_pwmType" */ + uint32_t pwmAPulseWidth; /*!< PWM A pulse width specified in microseconds. Specify FLEXPWM_NO_PWM_OUT_SIGNAL if no PWM output on this pin. @internal gui name="PWM-A pulse width" id="pwm_pwmAPulseWidth" */ + uint32_t pwmBPulseWidth; /*!< PWM B pulse width specified in microseconds. Specify FLEXPWM_NO_PWM_OUT_SIGNAL if no PWM output on this pin. @internal gui name="PWM-B pulse width" id="pwm_pwmBPulseWidth" */ + bool pwmAPolarity; /*!< true: if output is to be inverted; false: if no output inversion. @internal gui name="PWM-A signal polarity" id="pwm_pwmAPolarity" */ + bool pwmBPolarity; /*!< true: if output is to be inverted; false: if no output inversion. @internal gui name="PWM-B signal polarity" id="pwm_pwmBPolarity" */ +} pwm_module_signal_setup_t; + +/*! @brief Table of base addresses for PWM instances. */ +extern PWM_Type * const g_pwmBase[PWM_INSTANCE_COUNT]; + +/*! @brief Table to save PWM IRQ enumeration numbers defined in CMSIS header file. */ +extern const IRQn_Type g_pwmCmpIrqId[FSL_FEATURE_PWM_CMP_INT_HANDLER_COUNT]; +extern const IRQn_Type g_pwmReloadIrqId[FSL_FEATURE_PWM_RELOAD_INT_HANDLER_COUNT]; +extern const IRQn_Type g_pwmCapIrqId[FSL_FEATURE_PWM_CAP_INT_HANDLER_COUNT]; +extern const IRQn_Type g_pwmRerrIrqId[FSL_FEATURE_PWM_RERR_INT_HANDLER_COUNT]; +extern const IRQn_Type g_pwmFaultIrqId[FSL_FEATURE_PWM_FAULT_INT_HANDLER_COUNT]; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the PWM module. + * + * Enables the module clocks and interrupts in the interrupt controller. + * + * @param instance Instance number of the PWM module. + * @return kStatusPwmSuccess means succees, otherwise means failed. + */ +pwm_status_t PWM_DRV_Init(uint32_t instance); + +/*! + * @brief Shuts down the PWM driver. + * + * This function de-initializes the EflexPWM module and disables the clock for the submodules. + * Function disables the module-level interrupts. + * + * @param instance Instance number of the PWM module. + */ +void PWM_DRV_Deinit(uint32_t instance); + +/*! + * @brief Sets up the PWM signals from the FlewPWM module. + * + * The function initializes the submodule per the parameters passed in by the user. The function + * also sets up the value compare registers to match the PWM signal requirements. + * NOTE: If the deadtime insertion logic is enabled, the pulse period is reduced by the + * deadtime period specified by the user. + * + * @param instance Instance number of the PWM module. + * @param subModule The FlexPWM submodule that is configured + * @param moduleSetupParams The initialization values used to set up the submodule + * @param signalParams Signal parameters which generate the submodules PWM signals + * @return Returns an error if the requested submodule clock is wrong i.e request for kFlexPwmModule0 + * for submodule 0 or request for external clock without informing the driver of the external + * clock freqency by calling PWM_DVR_SetExternalClkFreq(). Success otherwise + */ +pwm_status_t PWM_DRV_SetupPwm(uint32_t instance, pwm_module_t subModule, pwm_module_setup_t *moduleSetupParams, + pwm_module_signal_setup_t *signalParams); + +/*! + * @brief Updates the PWM signal settings. + * + * The function updates the PWM signal to the new value that is passed in. + * NOTE: If the deadtime insertion logic is enabled then the pulse period is reduced by the + * deadtime period specified by the user. + * + * @param instance Instance number of the PWM module. + * @param subModule The FlexPWM submodule that is configured + * @param signalParams Signal parameters which generate the submodules PWM signals + */ +void PWM_DRV_UpdatePwmSignal(uint32_t instance, pwm_module_t subModule, + pwm_module_signal_setup_t *signalParams); + +/*! + * @brief Enables or disables the PWM output trigger. + * + * This function allows the user to enable or disable the PWM trigger. The PWM has 2 triggers. The trigger 0 + * is activated when the counter matches VAL 0, VAL 2, or VAL 4 register. The trigger 1 is activated + * when the counter matches VAL 1, VAL 3, or VAL 5. + * + * @param instance Instance number of the PWM module. + * @param subModule The FlexPWM submodule that is configured + * @param trigger Trigger number that the user wants to activate + * @param activate Enable or disable the trigger + */ +void PWM_DRV_SetTriggerCmd(uint32_t instance, pwm_module_t subModule, pwm_val_regs_t trigger, bool activate); + +/*! + * @brief Sets the PWM trigger value. + * + * This function sets the value in the compare register that generates a trigger. + * NOTE: User must make sure the value register being modified is not currently used to generate + * a PWM signal. + * + * @param instance Instance number of the PWM module. + * @param subModule The FlexPWM submodule that is configured + * @param trigger Trigger number that we wish to configure + * @param triggerVal Trigger value + */ +void PWM_DRV_SetTriggerVal(uint32_t instance, pwm_module_t subModule, pwm_val_regs_t trigger, uint16_t triggerVal); + +/*! + * @brief Sets up the PWM fault. + * + * This function configures a fault parameter and enables the fault for the appropriate + * sub-module signals. + * + * @param instance Instance number of the PWM module. + * @param subModule The FlexPWM submodule that is configured + * @param faultNum Fault that should be configured + * @param faultParams Parameters that configure the fault + * @param pwmA true: PWM A is disabled by this fault; false: PWM A is not affected by this fault + * @param pwmB true: PWM B is disabled by this fault; false: PWM A is not affected by this fault + * @param pwmX true: PWM X is disabled by this fault; false: PWM A is not affected by this fault + */ +void PWM_DRV_SetupFault(uint32_t instance, pwm_module_t subModule, pwm_fault_input_t faultNum, pwm_fault_setup_t *faultParams, + bool pwmA, bool pwmB, bool pwmX); + +/*! + * @brief Starts the PWM counter. + * + * This function starts the PWM submodule counters. + * + * @param instance Instance number of the PWM module. + * @param value Submodules to start; 4 bit value, 1-bit for each submodule + */ +void PWM_DRV_CounterStart(uint32_t instance, uint8_t value); + +/*! + * @brief Stops the PWM counter. + * + * This function stops the the PWM submodule counters. + * + * @param instance Instance number of the PWM module. + * @param value Submodules to stop; 4 bit value, 1-bit for each submodule + */ +void PWM_DRV_CounterStop(uint32_t instance, uint8_t value); + +/*! + * @brief Provides the frequency of the external clock source. + * + * When using an external signal as clock source, the user should provide the frequency + * of this clock source so that this driver can calculate the register values used to generate + * the requested PWM signal. + * + * @param instance Instance number of the PWM module. + * @param externalClkFreq External clock frequency (in Hz). + */ +void PWM_DRV_SetExternalClkFreq(uint32_t instance, uint32_t externalClkFreq); + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* FSL_FEATURE_SOC_PWM_COUNT */ + +#endif /* __FSL_PWM_DRIVER_H__*/ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_rnga_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_rnga_driver.h new file mode 100755 index 0000000..c00f5b7 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_rnga_driver.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_RNGA_DRIVER_H__ +#define __FSL_RNGA_DRIVER_H__ + +#include <assert.h> +#include <stdint.h> +#include <stdbool.h> +#include "fsl_rnga_hal.h" +#if FSL_FEATURE_SOC_RNG_COUNT +/*! + * @addtogroup rnga_driver + * @{ + */ + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @brief Table of base addresses for RNGA instances. */ +extern RNG_Type * const g_rngaBase[]; + +/*! @brief Table to save RNGA IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_rngaIrqId[RNG_INSTANCE_COUNT]; + +/*! + * @brief Data structure for the RNGA initialization + * + * This structure initializes the RNGA by calling the the rnga_init function. + * It contains all RNGA configurations. + * @internal gui name="Basic configuration" id="rngaCfg" + */ +typedef struct _rnga_user_config +{ + bool isIntMasked; /*!< Mask the triggering of error interrupt @internal gui name="Interrupt mask" id="isIntMasked" */ + bool highAssuranceEnable; /*!< Enable notification of security violations @internal gui name="High assurance" id="highAssurance" */ +} rnga_user_config_t; + + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the RNGA. + * + * This function initializes the RNGA. When called, the RNGA + * runs immediately according to the specifications in the configuration. + * + * @param instance, RNGA instance ID + * @param config, pointer to initialize configuration structure + * @return RNGA status + */ +rnga_status_t RNGA_DRV_Init(uint32_t instance, const rnga_user_config_t *config); + + +/*! + * @brief Shuts down the RNGA. + * + * This function shuts down the RNGA. + * + * @param instance, RNGA instance ID + */ +void RNGA_DRV_Deinit(uint32_t instance); + + +/*! + * @brief Sets the RNGA in normal mode or sleep mode. + * + * This function sets the RNGA in sleep mode or normal mode. + * + * @param instance, RNGA instance ID + * @param mode, normal mode or sleep mode + */ +static inline void RNGA_DRV_SetMode(uint32_t instance, rnga_mode_t mode) +{ + RNGA_HAL_SetWorkModeCmd(g_rngaBase[instance], mode); +} + + +/*! + * @brief Gets the RNGA working mode. + * + * This function gets the RNGA working mode. + * + * @param instance, RNGA instance ID + * @return normal mode or sleep mode + */ +static inline rnga_mode_t RNGA_DRV_GetMode(uint32_t instance) +{ + return RNGA_HAL_GetWorkMode(g_rngaBase[instance]); +} + + +/*! + * @brief Gets random data. + * + * This function gets random data from the RNGA. + * + * @param instance, RNGA instance ID + * @param data, pointer address used to store random data + * @return one random data + */ +static inline rnga_status_t RNGA_DRV_GetRandomData(uint32_t instance, uint32_t *data) +{ + return RNGA_HAL_GetRandomData(g_rngaBase[instance], data); +} + + +/*! + * @brief Feeds the RNGA module. + * + * This function inputs an entropy value that the RNGA uses to seed its + * pseudo-random algorithm. + * + * @param instance, RNGA instance ID + * @param seed, input seed value + */ +static inline void RNGA_DRV_Seed(uint32_t instance, uint32_t seed) +{ + RNGA_HAL_WriteSeed(g_rngaBase[instance],seed); +} + +/*! + * @brief RNGA interrupt handler. + * + * This function handles the error interrupt caused by the RNGA underflow. + * + * @param instance, RNGA instance ID + */ +void RNGA_DRV_IRQHandler(uint32_t instance); + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif +#endif /* __FSL_RNGA_H__*/ +/******************************************************************************* + * EOF + *******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_rtc_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_rtc_driver.h new file mode 100755 index 0000000..9958425 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_rtc_driver.h @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_RTC_DRIVER_H__) +#define __FSL_RTC_DRIVER_H__ + +#include <stdint.h> +#include "fsl_rtc_hal.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_RTC_COUNT + +/*! + * @addtogroup rtc_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Table of base addresses for RTC instances. */ +extern RTC_Type * const g_rtcBase[RTC_INSTANCE_COUNT]; + +/*! @brief Table to save RTC Alarm IRQ numbers for RTC instances. */ +extern const IRQn_Type g_rtcIrqId[RTC_INSTANCE_COUNT]; +/*! @brief Table to save RTC Seconds IRQ numbers for RTC instances. */ +extern const IRQn_Type g_rtcSecondsIrqId[RTC_INSTANCE_COUNT]; + +/*! + * @brief RTC repeated alarm information used by the RTC driver + */ +typedef struct RtcRepeatAlarmState +{ + rtc_datetime_t alarmTime; /*!< Set the RTC alarm time. */ + rtc_datetime_t alarmRepTime; /*!< Period for alarm to repeat, needs alarm interrupt be enabled.*/ +} rtc_repeat_alarm_state_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and De-initialization + * @{ + */ + +/*! + * @brief Initializes the RTC module. + * + * Enables the RTC clock and interrupts if requested by the user. + * + * @param instance The RTC peripheral instance number. + * @return kStatusRtcSuccess means succees, otherwise means failed. + */ +rtc_status_t RTC_DRV_Init(uint32_t instance); + +/*! + * @brief Disables the RTC module clock gate control. + * + * @param instance The RTC peripheral instance number. + */ +void RTC_DRV_Deinit(uint32_t instance); + +/* @} */ + +/*! + * @brief Checks whether the RTC is enabled. + * + * The function checks the TCE bit in the RTC control register. + * + * @param instance The RTC peripheral instance number. + * + * @return true: The RTC counter is enabled\n + * false: The RTC counter is disabled + */ +bool RTC_DRV_IsCounterEnabled(uint32_t instance); + +/*! + * @name RTC datetime set and get + * @{ + */ + +/*! + * @brief Sets the RTC date and time according to the given time structure. + * + * The RTC counter is started after the time is set. + * + * @param instance The RTC peripheral instance number. + * @param datetime [in] pointer to structure where the date and time + * details to set are stored. + * + * @return true: success in setting the time and starting the RTC\n + * false: failure. An error occurs because the datetime format is incorrect. + */ +bool RTC_DRV_SetDatetime(uint32_t instance, rtc_datetime_t *datetime); + +/*! + * @brief Gets the RTC time and stores it in the given time structure. + * + * @param instance The RTC peripheral instance number. + * @param datetime [out] pointer to structure where the date and time details are + * stored. + */ +void RTC_DRV_GetDatetime(uint32_t instance, rtc_datetime_t *datetime); +/* @} */ + +/*! + * @brief Enables or disables the RTC seconds interrupt. + * + * @param instance The RTC peripheral instance number. + * @param secondsEnable Takes true or false\n + * true: indicates seconds interrupt should be enabled\n + * false: indicates seconds interrupt should be disabled + */ +void RTC_DRV_SetSecsIntCmd(uint32_t instance, bool secondsEnable); + +/*! + * @name RTC alarm + * @{ + */ + +/*! + * @brief Sets the RTC alarm time and enables the alarm interrupt. + * + * The function checks if the specified alarm time is greater than the present + * time. If not, the function does not set the alarm and returns an error. + * + * @param instance The RTC peripheral instance number. + * @param alarmTime [in] pointer to structure where the alarm time is store. + * @param enableAlarmInterrupt Takes true of false\n + * true: indicates alarm interrupt should be enabled\n + * false: indicates alarm interrupt should be disabled + * + * @return true: success in setting the RTC alarm\n + * false: error in setting the RTC alarm. Error is because the alarm datetime format + * is incorrect. + */ +bool RTC_DRV_SetAlarm(uint32_t instance, rtc_datetime_t *alarmTime, bool enableAlarmInterrupt); + +/*! + * @brief Returns the RTC alarm time. + * + * @param instance The RTC peripheral instance number. + * @param date [out] pointer to structure where the alarm date and time + * details are stored. + */ +void RTC_DRV_GetAlarm(uint32_t instance, rtc_datetime_t *date); + +/*! + * @brief Initializes the RTC repeat alarm state structure. + * + * The RTC driver uses this user-provided structure to store the alarm state + * information. + * + * @param instance The RTC peripheral instance number. + * @param repeatAlarmState Pointer to structure where the alarm state is stored + */ +void RTC_DRV_InitRepeatAlarm(uint32_t instance, rtc_repeat_alarm_state_t *repeatAlarmState); + +/*! + * @brief Sets an alarm that is periodically repeated. + * + * @param instance The RTC peripheral instance number. + * @param alarmTime Pointer to structure where the alarm time is provided. + * @param alarmRepInterval pointer to structure with the alarm repeat interval. + * + * @return true: success in setting the RTC alarm\n + * false: error in setting the RTC alarm. Error is because the alarm datetime format + * is incorrect. + */ +bool RTC_DRV_SetAlarmRepeat(uint32_t instance, rtc_datetime_t *alarmTime, rtc_datetime_t *alarmRepInterval); + +/*! + * @brief De-initializes the RTC repeat alarm state structure. + * + * @param instance The RTC peripheral instance number. + */ +void RTC_DRV_DeinitRepeatAlarm(uint32_t instance); + +/* @} */ + +/*! + * @brief Enables or disables the alarm interrupt. + * + * @param instance The RTC peripheral instance number. + * @param alarmEnable Takes true or false\n + * true: indicates alarm interrupt should be enabled\n + * false: indicates alarm interrupt should be disabled + */ +void RTC_DRV_SetAlarmIntCmd(uint32_t instance, bool alarmEnable); + +/*! + * @brief Reads the alarm interrupt. + * + * @param instance The RTC peripheral instance number. + * + * @return true: indicates alarm interrupt is enabled\n + * false: indicates alarm interrupt is disabled + */ +bool RTC_DRV_GetAlarmIntCmd(uint32_t instance); + +/*! + * @brief Reads the alarm status to see if the alarm has triggered. + * + * @param instance The RTC peripheral instance number. + * + * @return returns alarm status, for example, returns whether the alarm triggered\n + * true: indicates alarm has occurred\n + * false: indicates alarm has not occurred + */ +bool RTC_DRV_IsAlarmPending(uint32_t instance); + +/*! + * @brief Writes the compensation value to the RTC compensation register. + * + * @param instance The RTC peripheral instance number. + * @param compensationInterval User specified compensation interval that is written + * to the CIR field in RTC Time Compensation Register (TCR) + * @param compensationTime User specified compensation time that is written + * to the TCR field in RTC Time Compensation Register (TCR) + */ +void RTC_DRV_SetTimeCompensation(uint32_t instance, uint32_t compensationInterval, + uint32_t compensationTime); + + +/*! + * @brief Reads the compensation value from the RTC compensation register. + * + * @param instance The RTC peripheral instance number. + * @param compensationInterval User specified pointer to store the compensation interval counter. This value + * is read from the CIC field in RTC Time Compensation Register (TCR) + * @param compensationTime User specified pointer to store the compensation time value. This value + * is read from the TCV field in RTC Time Compensation Register (TCR) + */ +void RTC_DRV_GetTimeCompensation(uint32_t instance, uint32_t *compensationInterval, + uint32_t *compensationTime); + + +#if FSL_FEATURE_RTC_HAS_MONOTONIC +/*! + * @name Increments monotonic counter + * @{ + */ + +/*! + * @brief Increments the monotonic counter by one. + * + * @param instance The RTC peripheral instance number. + * + * @return True: increment successful\n + * False: error invalid time found because of a tamper source enabled is detected + * and any write to the tamper time seconds counter is done. + */ +bool RTC_DRV_IncrementMonotonic(uint32_t instance); +/* @} */ +#endif + +/*! + * @name ISR Functions + * @{ + */ + +/*! + * @brief Implements the RTC alarm handler named in the startup code. + * + * Handles the RTC alarm interrupt and invokes any callback that is interested + * in the RTC alarm. + */ +void RTC_IRQHandler(void); + +/*! + * @brief Implements the RTC seconds handler named in the startup code. + * + * Handles the RTC seconds interrupt and invokes any callback that is interested + * in the RTC second tick. + */ +void RTC_Seconds_IRQHandler(void); + +/*! @}*/ + +/*! + * @brief Action to take when an RTC alarm interrupt is triggered. To receive + * alarms periodically, the RTC_TAR register is updated using the repeat interval. + * + * @param instance The RTC peripheral instance number. + */ +void RTC_DRV_AlarmIntAction(uint32_t instance); + +/*! + * @brief Action to take when an RTC seconds interrupt is triggered. + * + * Disables the time seconds interrupt (TSIE) bit. + * + * @param instance The RTC peripheral instance number. + */ +void RTC_DRV_SecsIntAction(uint32_t instance); + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* FSL_FEATURE_SOC_RTC_COUNT */ + +#endif /* __FSL_RTC_DRIVER_H__*/ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_sai_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_sai_driver.h new file mode 100755 index 0000000..c185c8b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_sai_driver.h @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __FSL_SAI_DRIVER_H__ +#define __FSL_SAI_DRIVER_H__ + +#include "fsl_sai_hal.h" +#include "fsl_os_abstraction.h" +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL +#include "fsl_edma_driver.h" +#else +#include "fsl_dma_driver.h" +#endif + +#if FSL_FEATURE_SOC_I2S_COUNT + +/*! + * @addtogroup sai_driver + * @{ + */ + +/*! @file */ + +/*! @brief SAI callback function */ +typedef void (*sai_callback_t)(void *parameter); +extern I2S_Type * const g_saiBase[I2S_INSTANCE_COUNT]; +extern const IRQn_Type g_saiTxIrqId[I2S_INSTANCE_COUNT]; +extern const IRQn_Type g_saiRxIrqId[I2S_INSTANCE_COUNT]; + +/*! @brief Status structure for SAI */ +typedef enum _sai_status +{ + kStatus_SAI_Success = 0U, + kStatus_SAI_Fail = 1U, + kStatus_SAI_DeviceBusy = 2U +} sai_status_t; + +/*! @brief Defines the PCM data format + * @internal gui name="Audio data configuration" id="saiDataCfg" + */ +typedef struct SaiAudioDataFormat +{ + uint32_t sample_rate;/*!< Sample rate of the PCM file. @internal gui name="Sample rate" id="SampleRate" */ + uint32_t mclk;/*!< Master clock frequency. @internal gui name="Master clock frequency" id="CfgMclk" */ + uint8_t bits;/*!< How many bits in a word. @internal gui name="Bits" id="Bits" */ + sai_mono_stereo_t mono_stereo;/*!< How many word in a frame. @internal gui name="Mode" id="Words" */ +} sai_data_format_t; + +/*! @brief SAI internal state +* Users should allocate and transfer memory to the PD during the initialization function. +* Note: During the SAI execution, users should not free the state. Otherwise, the driver malfunctions. +*/ +typedef struct sai_state +{ + sai_data_format_t format; + uint8_t * address; + uint32_t len; + uint32_t count; + sai_callback_t callback; + void * callback_param; + sai_sync_mode_t sync_mode; + uint32_t fifo_channel; +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + uint32_t watermark; +#endif + sai_master_slave_t master_slave; + sai_protocol_t protocol; +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + edma_chn_state_t edma_chn; + edma_software_tcd_t tcd[2]; +#else + dma_channel_t chn; +#endif + semaphore_t sem; + bool use_dma; + uint32_t dma_source; +} sai_state_t; + +/*! @brief The description structure for the SAI TX/RX module. + * @internal gui name="Basic configuration" id="saiCfg" + */ +typedef struct SaiUserConfig +{ + sai_mclk_source_t mclk_source;/*!< Master clock source. @internal gui name="MCLK source" id="CfgMclkSource" */ + uint8_t channel;/*!< Which FIFO is used to transfer. @internal gui name="Channel" id="Channel" */ + sai_sync_mode_t sync_mode;/*!< Synchronous or asynchronous. @internal gui name="Mode" id="Mode" */ + sai_protocol_t protocol;/*!< I2S left, I2S right or I2S type. @internal gui name="Protocol" id="BusType" */ + sai_master_slave_t slave_master;/*!< Master or slave. @internal gui name="Master / Slave mode" id="MasterSlave" */ + sai_bclk_source_t bclk_source;/*!< Bit clock from master clock or other modules. @internal gui name="Bit clock source" id="BclkSource" */ +#if FSL_FEATURE_SAI_FIFO_COUNT > 1 + uint32_t watermark;/*!< When to send interrupt or dma request. @internal gui name="Watermark" id="Watermark" */ +#endif + uint32_t dma_source; /*!< Dma request source. @internal gui name="DMA request value" id="DmaRequest" */ +} sai_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the SAI module. + * + * This function initializes the SAI registers according to the configuration + * structure. This function also initializes the basic SAI settings including + * board-relevant settings. + * Notice: This function does not initialize an entire SAI instance. It + * only initializes the transmit according to the value in the handler. + * @param instance SAI module instance. + * @param config The configuration structure of SAI. + * @param state Pointer of SAI run state structure. + * @return Return kStatus_SAI_Success while the initialize success and kStatus_SAI_Fail if failed. + */ +sai_status_t SAI_DRV_TxInit(uint32_t instance, sai_user_config_t * config, sai_state_t *state); + +/*! + * @brief Initializes the SAI receive module. + * + * This function initializes the SAI registers according to the configuration + * structure. This function also initializes the basic SAI settings including + * board-relevant settings. + * Note that this function does not initialize an entire SAI instance. This function + * only initializes the transmit according to the value in the handler. + * @param instance SAI module instance. + * @param config The configuration structure of SAI. + * @param state Pointer of SAI run state structure. + * @return Return kStatus_SAI_Success while the initialize success and kStatus_SAI_Fail if failed. + */ +sai_status_t SAI_DRV_RxInit(uint32_t instance, sai_user_config_t * config, sai_state_t *state); + +/*! @brief Gets the default setting of the user configuration. +* +* The default settings for SAI are: +* - Audio protocol is I2S format +* - Watermark is 4 +* - Use SAI0 +* - Channel is channel0 +* - SAI as master +* - MCLK from system core clock +* - Transmit is in an asynchronous mode +* @param config Pointer of user configure structure. +*/ +void SAI_DRV_TxGetDefaultSetting(sai_user_config_t *config); + +/*! @brief Gets the default setting of the user configuration. +* +* The default settings for SAI are: +* Audio protocol is I2S format +* Watermark is 4 +* Use SAI0 +* Data channel is channel0 +* SAI as master +* MCLK from system core clock +* Receive is in synchronous way +* @param config Pointer of user configure structure. +*/ +void SAI_DRV_RxGetDefaultSetting(sai_user_config_t *config); + +/*! + * @brief De-initializes the SAI transmit module. + * + * This function closes the SAI transmit device. It does not close the entire SAI instance. + * It only closes the clock gate while both transmit and receive are closed in the same instance. + * @param instance SAI module instance. + * @return Return kStatus_SAI_Success while the process success and kStatus_SAI_Fail if failed. + */ +sai_status_t SAI_DRV_TxDeinit(uint32_t instance); + +/*! + * @brief De-initializes the SAI receive module. + * + * This function closes the SAI receive device. It does not close the entire SAI instance. + * It only closes the clock gate while both transmit and receive are closed in the same instance. + * @param instance SAI module instance. + * @return Return kStatus_SAI_Success while the process success and kStatus_SAI_Fail if failed. + */ +sai_status_t SAI_DRV_RxDeinit(uint32_t instance); + +/*! + * @brief Configures audio data format of the transmit. + * + * The function configures an audio sample rate, data bits, and a channel number. + * @param instance SAI module instance. + * @param format PCM data format structure pointer. + * @return Return kStatus_SAI_Success while the process success and kStatus_SAI_Fail if failed. + */ +sai_status_t SAI_DRV_TxConfigDataFormat(uint32_t instance,sai_data_format_t *format); + +/*! + * @brief Configures audio data format of the receive. + * + * The function configures an audio sample rate, data bits, and a channel number. + * @param instance SAI module instance of the SAI module. + * @param format PCM data format structure pointer. + * @return Return kStatus_SAI_Success while the process success and kStatus_SAI_Fail if failed. + */ +sai_status_t SAI_DRV_RxConfigDataFormat(uint32_t instance,sai_data_format_t *format); + +/*! + * @brief Starts the transmit transfer. + * + * The function enables the interrupt/DMA request source and the transmit channel. + * @param instance SAI module instance. + */ +void SAI_DRV_TxStartModule(uint32_t instance); + +/*! + * @brief Starts the receive process. + * + * The function enables the interrupt/DMA request source and the transmit channel. + * @param instance SAI module instance of the SAI module. + */ +void SAI_DRV_RxStartModule(uint32_t instance); + +/*! + * @brief Stops writing data to FIFO to disable the DMA or the interrupt request bit. + * + * This function provides the method to pause writing data. + * @param instance SAI module instance. + */ +static inline void SAI_DRV_TxStopModule(uint32_t instance) +{ + I2S_Type * reg_base = g_saiBase[instance]; +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + SAI_HAL_TxSetIntCmd(reg_base,kSaiIntrequestFIFORequest,false); + SAI_HAL_TxSetDmaCmd(reg_base,kSaiDmaReqFIFORequest, false); +#else + SAI_HAL_TxSetIntCmd(reg_base,kSaiIntrequestFIFOWarning,false); + SAI_HAL_TxSetDmaCmd(reg_base,kSaiDmaReqFIFOWarning, false); +#endif +} + +/*! + * @brief Stops receiving data from FIFO to disable the DMA or the interrupt request bit. + * + * This function provides the method to pause writing data. + * @param instance SAI module instance. + */ +static inline void SAI_DRV_RxStopModule(uint32_t instance) +{ + I2S_Type * reg_base = g_saiBase[instance]; +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + SAI_HAL_RxSetIntCmd(reg_base,kSaiIntrequestFIFORequest,false); + SAI_HAL_RxSetDmaCmd(reg_base,kSaiDmaReqFIFORequest, false); +#else + SAI_HAL_RxSetIntCmd(reg_base,kSaiIntrequestFIFOWarning,false); + SAI_HAL_RxSetDmaCmd(reg_base,kSaiDmaReqFIFOWarning, false); +#endif +} + + +/*! @brief Enables or disables the transmit interrupt source. +* @param instance SAI module instance. +* @param enable True means enable interrupt source, false means disable interrupt source. +*/ +static inline void SAI_DRV_TxSetIntCmd(uint32_t instance, bool enable) +{ + I2S_Type * reg_base = g_saiBase[instance]; +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + SAI_HAL_TxSetIntCmd(reg_base,kSaiIntrequestFIFORequest,enable); +#else + SAI_HAL_TxSetIntCmd(reg_base,kSaiIntrequestFIFOWarning,enable); +#endif + SAI_HAL_TxSetIntCmd(reg_base, kSaiIntrequestFIFOError, enable); +} + +/*! @brief Enables or disables the receive interrupt source. +* @param instance SAI module instance. +* @param enable True means enable interrupt source, false means disable interrupt source. +*/ +static inline void SAI_DRV_RxSetIntCmd(uint32_t instance, bool enable) +{ + I2S_Type * reg_base = g_saiBase[instance]; +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + SAI_HAL_RxSetIntCmd(reg_base,kSaiIntrequestFIFORequest,enable); +#else + SAI_HAL_RxSetIntCmd(reg_base,kSaiIntrequestFIFOWarning,enable); +#endif + SAI_HAL_RxSetIntCmd(reg_base, kSaiIntrequestFIFOError,enable); +} + +/*! @brief Enables or disables the transmit DMA source. +* @param instance SAI module instance. +* @param enable True means enable DMA source, false means disable DMA source. +*/ +static inline void SAI_DRV_TxSetDmaCmd(uint32_t instance, bool enable) +{ + I2S_Type * reg_base = g_saiBase[instance]; + SAI_HAL_TxSetDmaCmd(reg_base, kSaiDmaReqFIFORequest,enable); + SAI_HAL_TxSetIntCmd(reg_base, kSaiIntrequestFIFOError,enable); +} + +/*! @brief Enables or disables the receive interrupt source. +* @param instance SAI module instance. +* @param enable True means enable DMA source, false means disable DMA source. +*/ +static inline void SAI_DRV_RxSetDmaCmd(uint32_t instance, bool enable) +{ + I2S_Type * reg_base = g_saiBase[instance]; + SAI_HAL_RxSetDmaCmd(reg_base, kSaiDmaReqFIFORequest,enable); + SAI_HAL_RxSetIntCmd(reg_base, kSaiIntrequestFIFOError,enable); +} + +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) +/*! @brief Sets the transmit watermark. +* +* While the data number in FIFO is less or equal to the watermark, an interrupt is generated. +* request or the DMA request. +* @param instance SAI module instance. +* @param watermark Watermark number needs to set. +*/ +void SAI_DRV_TxSetWatermark(uint32_t instance,uint32_t watermark); + +/*! @brief Sets the receive watermark. +* +* While the data number in FIFO is greater than or equal to the watermark, an interrupt is generated. +* request or the DMA request. +* @param instance SAI module instance. +* @param watermark Watermark number needs to set. +*/ +void SAI_DRV_RxSetWatermark(uint32_t instance,uint32_t watermark); + +/*! @brief Gets the transmit watermark. +* +* The watermark should be changed according to a different audio sample rate. +* @param instance SAI module instance. +* @return Watermark number in TCR1. +*/ +static inline uint32_t SAI_DRV_TxGetWatermark(uint32_t instance) +{ + I2S_Type * reg_base = g_saiBase[instance]; + return SAI_HAL_TxGetWatermark(reg_base); +} + +/*! @brief Gets the receive watermark. +* +* The watermark should be changed according to a different audio sample rate. +* @param instance SAI module instance. +* @return Watermark number in RCR1. +*/ +static inline uint32_t SAI_DRV_RxGetWatermark(uint32_t instance) +{ + I2S_Type * reg_base = g_saiBase[instance]; + return SAI_HAL_RxGetWatermark(reg_base); +} +#endif + +/*! + * @brief Gets the transmit FIFO address of the data channel. + * + * This function is mainly used for the DMA settings which the DMA + * configuration needs for the SAI source/destination address. + * @param instance SAI module instance of the SAI module. + * @param fifo_channel FIFO channel of SAI transmit. + * @return Returns the address of the data channel FIFO. + */ +static inline uint32_t SAI_DRV_TxGetFifoAddr(uint32_t instance, uint32_t fifo_channel) +{ + I2S_Type * reg_base = g_saiBase[instance]; + return SAI_HAL_TxGetFifoAddr(reg_base, fifo_channel); +} + +/*! + * @brief Gets the receive FIFO address of the data channel. + * + * This function is mainly used for the DMA settings which the DMA + * configuration needs for the SAI source/destination address. + * @param instance SAI module instance of the SAI module. + * @param fifo_channel FIFO channel of SAI receive. + * @return Returns the address of the data channel FIFO. + */ +static inline uint32_t SAI_DRV_RxGetFifoAddr(uint32_t instance, uint32_t fifo_channel) +{ + I2S_Type * reg_base = g_saiBase[instance]; + return SAI_HAL_RxGetFifoAddr(reg_base, fifo_channel); +} + +/*! + * @brief Sends data using interrupts. + * + * This function sends data to the transmit FIFO. This function + * starts the transfer, and, while finishing the transfer, calls the callback + * function registered by users. This function is an un-blocking function. + * @param instance SAI module instance of the SAI module. + * @param addr Address of the data which needs to be transferred. + * @param len The number of bytes which need to be sent. + * @return Returns the length which was sent. + */ +uint32_t SAI_DRV_SendDataInt(uint32_t instance, uint8_t *addr, uint32_t len); + +/*! + * @brief Receives data a certain length using interrupt way. + * + * This function receives the data from the receive FIFO. This function + * starts the transfer, and, while finishing the transfer, calls the callback + * function registered by the user. This function is an un-blocking function. + * @param instance SAI module instance. + * @param addr Address of the data which needs to be transferred. + * @param len The number of bytes to receive. + * @return Returns the length received. + */ +uint32_t SAI_DRV_ReceiveDataInt(uint32_t instance, uint8_t *addr, uint32_t len); + +/*! + * @brief Sends data of a certain length using the DMA way. + * + * This function sends the data to the transmit FIFO. This function + * starts the transfer, and, while finishing the transfer, calls the callback + * function registered by users. This function is an a-sync function. + * @param instance SAI module instance of the SAI module. + * @param addr Address of the data which needs to be transferred. + * @param len The number of bytes which need to be sent. + * @return Returns the length which was sent. + */ +uint32_t SAI_DRV_SendDataDma(uint32_t instance, uint8_t *addr, uint32_t len); + +/*! + * @brief Receives data using the DMA. + * + * This function receives the data from the receive FIFO. This function + * starts the transfer, and, while finishing the transfer, calls the callback + * function registered by the user. This function is an a-sync function. + * @param instance SAI module instance. + * @param addr Address of the data which needs to be transferred. + * @param len The number of bytes to receive. + * @return Returns the length received. + */ +uint32_t SAI_DRV_ReceiveDataDma(uint32_t instance, uint8_t *addr, uint32_t len); + +/*! + * @brief Registers the callback function after completing a send. + * + * This function tells the SAI which function needs to be called after a + * period length sending. This callback function is used for non-blocking sending. + * @param instance SAI module instance. + * @param callback Callback function defined by users. + * @param callback_param The parameter of the callback function. + */ +void SAI_DRV_TxRegisterCallback(uint32_t instance, sai_callback_t callback, void *callback_param); + +/*! + * @brief Registers the callback function after completing a receive. + * + * This function tells the SAI which function needs to be called after a + * period length receive. This callback function is used for non-blocking receiving. + * @param instance SAI module instance. + * @param callback Callback function defined by users. + * @param callback_param The parameter of the callback function. + */ +void SAI_DRV_RxRegisterCallback(uint32_t instance, sai_callback_t callback, void *callback_param); + +/*! + * @brief Default SAI transmit interrupt handler. + * + * This function sends data in the interrupt and checks the FIFO error. + * @param instance SAI module instance. + */ +void SAI_DRV_TxIRQHandler(uint32_t instance); + +/*! + * @brief Default SAI receive interrupt handler. + * + * This function receives data in the interrupt and checks the FIFO error. + * @param instance SAI module instance. + */ +void SAI_DRV_RxIRQHandler(uint32_t instance); + + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif +#endif/* __FSL_SAI_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_sdhc.h b/KSDK_1.2.0/platform/drivers/inc/fsl_sdhc.h new file mode 100755 index 0000000..42ef4bd --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_sdhc.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 __SDHC_H__ +#define __SDHC_H__ + +/*! @addtogroup sdhc_std_def */ +/*! @{ */ + +#define SDHC_DMA_ADDRESS (0x00U) /*!< SDHC DMA ADDRESS REG */ +#define SDHC_ARGUMENT2 SDHC_DMA_ADDRESS +#define SDHC_BLOCK_SIZE (0x04U) /*!< SDHC BLOCK SIZE REG */ +#define SDHC_BLOCK_COUNT (0x06U) /*!< SDHC BLOCK COUNT REG */ +#define SDHC_ARGUMENT (0x08U) /*!< SDHC ARGUMENT REG */ + +#define SDHC_TRANSFER_MODE (0x0C) /*!< SDHC TRANSFER MODE REG */ +#define SDHC_TRNSM_DMA_EN (0x01U) /*!< SDHC TRANSFER MODE DMA ENABLE BIT */ +#define SDHC_TRNSM_BLKCNT_EN (0x02U) /*!< SDHC TRANSFER MODE BLOCK COUNT ENABLE BIT */ +#define SDHC_TRNSM_AUTOCMD12 (0x04U) /*!< SDHC TRANSFER MODE AUTO CMD12 BIT */ +#define SDHC_TRNSM_AUTOCMD23 (0x08U) /*!< SDHC TRANSFER MODE AUTO CMD23 BIT */ +#define SDHC_TRNSM_READ (0x10U) /*!< SDHC TRANSFER MODE READ DATA BIT */ +#define SDHC_TRNSM_MULTI (0x20U) /*!< SDHC TRANSFER MODE MULTIBLOCK BIT */ + +#define SDHC_COMMAND (0x0E) /*!< SDHC COMMAND REG */ +#define SDHC_CMD_RESPTYPE_LSF (0U) /*!< SDHC COMMAND RESPONSE TYPE SHIFT */ +#define SDHC_CMD_RESPTYPE_MASK (0x03U) /*!< SDHC COMMAND RESPONSE MASK */ +#define SDHC_CMD_CRC_CHK (0x08U) /*!< SDHC COMMAND CRC CHEKCING BIT */ +#define SDHC_CMD_INDEX_CHK (0x10U) /*!< SDHC COMMAND INDEX CHECKING BIT */ +#define SDHC_CMD_DATA_PRSNT (0x20U) /*!< SDHC COMMAND DATA PRESENT BIT*/ +#define SDHC_CMD_CMDTYPE_LSF (6U) /*!< SDHC COMMAND COMMAND TYPE SHIFT */ +#define SDHC_CMD_CMDTYPE_MASK (0xC0U) /*!< SDHC COMMAND COMMAND TYPE MASK*/ +#define SDHC_CMD_CMDINDEX_LSF (8U) /*!< SDHC COMMAND COMMAND INDEX SHIFT */ +#define SDHC_CMD_CMDINDEX_MASK (0x3F) /*!< SDHC COMMAND COMMAND INDEX MASK */ + +#define SDHC_RESPONSE (0x10U) /*!< SDHC RESPONSE REG */ + +#define SDHC_BUFFER (0x20U) /*!< SDHC BUFFER REG */ + +#define SDHC_PRESENT_STATE (0x24U) /*!< SDHC PRESENT STATE REG */ +#define SDHC_PRST_CMD_INHIBIT (0x1U) /*!< SDHC PRESENT STATE CMD INHIBIT BIT */ +#define SDHC_PRST_DATA_INHIBIT (0x1 << 1) /*!< SDHC PRESENT STATE DATA INHIBIT BIT */ +#define SDHC_PRST_DLA (0x1 << 2) /*!< SDHC PRESENT STATE DATA LINE ACTIVE BIT */ +#define SDHC_PRST_RETUNE_REQ (0x1 << 3) /*!< SDHC PRESENT STATE RETUNE REQUEST BIT */ +#define SDHC_PRST_WR_TRANS_A (0x1 << 8) /*!< SDHC PRESENT STATE WRITE TRANSFER ACTIVE BIT */ +#define SDHC_PRST_RD_TRANS_A (0x1 << 9) /*!< SDHC PRESENT STATE READ TRANSFER ACTIVE BIT */ +#define SDHC_PRST_BUFF_WR (0x1 << 10) /*!< SDHC PRESENT STATE BUFFER WRITE ENABLE BIT */ +#define SDHC_PRST_BUFF_RD (0x1 << 11) /*!< SDHC PRESENT STATE BUFFER READ ENABLE BIT */ +#define SDHC_PRST_CARD_INSERTED (0x1 << 16) /*!< SDHC PRESENT STATE CARD INSERTED BIT */ +#define SDHC_PRST_CSS (0x1 << 17) /*!< SDHC PRESENT STATE CARD STATE STABLE BIT */ +#define SDHC_PRST_CD_LVL (0x1 << 18) /*!< SDHC PRESENT STATE CARD DETECT PIN LEVEL BIT */ +#define SDHC_PRST_WP_LVL (0x1 << 19) /*!< SDHC PRESENT STATE WRITE PROTECT PIN LEVEL BIT*/ +#define SDHC_PRST_DLSL_0_3_LSF (20U) /*!< SDHC PRESENT STATE DAT[3:0] LINE LEVEL SHIFT */ +#define SDHC_PRST_DLSL_0_3_MASK (0x0F000000U) /*!< SDHC PRESENT STATE DAT[3:0] LINE LEVEL MASK */ +#define SDHC_PRST_CMD_LVL (0x1 << 24) /*!< SDHC PRESENT STATE CMD LINE LEVEL BIT */ + +#define SDHC_HOST_CONTROL1 (0x28U) /*!< SDHC HOST CONTROL1 REG */ +#define SDHC_CTRL_LED (0x01U) /*!< SDHC HOST CONTROL1 LED CONTROL BIT */ +#define SDHC_CTRL_4BIT (0x02U) /*!< SDHC HOST CONTROL1 DATA TRANSFER WIDTH BIT */ +#define SDHC_CTRL_HISPD (0x04U) /*!< SDHC HOST CONTROL1 HIGH SPEED ENABLE BIT */ +#define SDHC_CTRL_DMA_LSF (0x3U) /*!< SDHC HOST CONTROL1 DMA SELECT SHIFT */ +#define SDHC_CTRL_DMA_MASK (0x18U) /*!< SDHC HOST CONTROL1 DMA SELECT MASK */ +#define SDHC_CTRL_DMA_SDMA (0x0U) /*!< SDHC HOST CONTROL1 DMA SELECT SDMA */ +#define SDHC_CTRL_DMA_ADMA32 (0x2U) /*!< SDHC HOST CONTROL1 DMA SELECT ADMA32 */ +#define SDHC_CTRL_DMA_ADMA64 (0x3U) /*!< SDHC HOST CONTROL1 DMA SELECT ADMA64 */ +#define SDHC_CTRL_8BIT (0x20U) /*!< SDHC HOST CONTROL1 EXTENDED DATA TRANSFER WIDTH BIT */ +#define SDHC_CTRL_CD_TEST_LVL (0x40U) /*!< SDHC HOST CONTROL1 CARD DETECT TEST LEVEL BIT */ +#define SDHC_CTRL_CD_SSELECT (0x80U) /*!< SDHC HOST CONTROL1 CARD DETECT SIGNAL SELECTION BIT*/ + +#define SDHC_POWER_CONTROL (0x29U) /*!< SDHC POWER CONTROL REG */ +#define SDHC_POWER_ON (0x01U) /*!< SDHC POWER CONTROL SD BUS POWER */ +#define SDHC_POWER_180 (0x0A) /*!< SDHC POWER CONTROL SD BUS POWER 1.8V */ +#define SDHC_POWER_300 (0x0C) /*!< SDHC POWER CONTROL SD BUS POWER 3.0V */ +#define SDHC_POWER_330 (0x0E) /*!< SDHC POWER CONTROL SD BUS POWER 3.3V */ + +#define SDHC_BLOCK_GAP_CTRL (0x2A) /*!< SDHC BLOCK GAP CONTROL REG */ +#define SDHC_BGCTRL_STPATGAPREQ (0x01U) /*!< SDHC BLOCK GAP CONTROL STOP AT BLOCK GAP BIT */ +#define SDHC_BGCTRL_CNTNREQ (0x02U) /*!< SDHC BLOCK GAP CONTROL CONTINUE REQUEST BIT */ +#define SDHC_BGCTRL_READWAIT (0x04U) /*!< SDHC BLOCK GAP CONTROL READ WAIT CONTROL BIT */ +#define SDHC_BGCTRL_INTRATGAP (0x08U) /*!< SDHC BLOCK GAP CONTROL INTERRUPT AT BLOCK GAP BIT */ + +#define SDHC_WAKEUP_CONTROL (0x2B) /*!< SDHC WAKEUP CONTROL REG */ +#define SDHC_WAKE_ON_INT (0x01U) /*!< SDHC WAKEUP CONTROL WAKEUP ON CARD INTERRUPT BIT */ +#define SDHC_WAKE_ON_INSERT (0x02U) /*!< SDHC WAKEUP CONTROL WAKEUP ON CARD INSERTION BIT */ +#define SDHC_WAKE_ON_REMOVE (0x04U) /*!< SDHC WAKEUP CONTROL WAKEUP ON CARD REMOVAL BIT */ + +#define SDHC_CLOCK_CONTROL (0x2C) /*!< SDHC CLOCK CONTROL REG */ +#define SDHC_CLK_INTCLK_EN (0x0001U) /*!< SDHC CLOCK CONTROL INTERNAL CLOCK ENABLE BIT */ +#define SDHC_CLK_INTCLK_STB (0x0002U) /*!< SDHC CLOCK CONTROL INTERNAL CLOCK STABLE BIT */ +#define SDHC_CLK_SDCLK_EN (0x0004U) /*!< SDHC CLOCK CONTROL SD CLOCK ENABLE BIT */ +#define SDHC_CLK_CLKGEN_PRG_SEL (0x0020U) /*!< SDHC CLOCK CONTROL CLOCK GENERATOR SELECTOR BIT */ +#define SDHC_CLK_FREQ_U_LSF (6U) /*!< SDHC CLOCK CONTROL UPPER BITS OF FREQUENCY SELECTOR SHIFT */ +#define SDHC_CLK_FREQ_U_MASK (0x00C0U) /*!< SDHC CLOCK CONTROL UPPER BITS OF FREQUENCY SELECTOR MASK */ +#define SDHC_CLK_FREQ_SEL_LSF (8U) /*!< SDHC CLOCK CONTROL FREQUENCY SELECTOR SHIFT */ +#define SDHC_CLK_FREQ_SEL_MASK (0xFF00U) /*!< SDHC CLOCK CONTROL FREQUENCY SELECTOR MASK */ + +#define SDHC_TIMEOUT_CONTROL (0x2E) /*!< SDHC TIMEOUT CONTROL REG */ + +#define SDHC_SOFTWARE_RESET (0x2F) /*!< SDHC SOFTWARE RESET REG */ +#define SDHC_RESET_ALL (0x01U) /*!< SDHC SOFTWARE RESET RESET FOR ALL*/ +#define SDHC_RESET_CMD (0x02U) /*!< SDHC SOFTWARE RESET RESET FOR CMD LINE */ +#define SDHC_RESET_DATA (0x04U) /*!< SDHC SOFTWARE RESET RESET FOR DATA LINE */ + +#define SDHC_INT_STATUS (0x30U) /*!< SDHC NORMAL INTERRUPT STATUS REG */ +#define SDHC_INT_ENABLE (0x34U) /*!< SDHC NORMAL INTERRUPT STATUS ENABLE REG */ +#define SDHC_SIGNAL_ENABLE (0x38U) /*!< SDHC NORMAL INTERRUPT SIGNAL REG */ +#define SDHC_INT_CMD_DONE (0x1U << 0) /*!< SDHC NORMAL INTERRUPT CMD COMPLETE EVENT BIT */ +#define SDHC_INT_TRANSFER_DONE (0x1U << 1) /*!< SDHC NORMAL INTERRUPT TRANSFER COMPLETE EVENT BIT */ +#define SDHC_INT_BLKGAP_EVENT (0x1U << 2) /*!< SDHC NORMAL INTERRUPT BLOCK GAP EVENT BIT */ +#define SDHC_INT_DMA (0x1U << 3) /*!< SDHC NORMAL INTERRUPT DMA EVENT BIT */ +#define SDHC_INT_WBUF_READY (0x1U << 4) /*!< SDHC NORMAL INTERRUPT WRITE BUFFER READY EVENT BIT */ +#define SDHC_INT_RBUF_READY (0x1U << 5) /*!< SDHC NORMAL INTERRUPT READ BUFFER READY EVENT BIT */ +#define SDHC_INT_CARD_INSERT (0x1U << 6) /*!< SDHC NORMAL INTERRUPT CARD INSERTION EVENT BIT */ +#define SDHC_INT_CARD_REMOVE (0x1U << 7) /*!< SDHC NORMAL INTERRUPT CARD REMOVAL EVENT BIT */ +#define SDHC_INT_CARD_INTR (0x1U << 8) /*!< SDHC NORMAL INTERRUPT CARD INTERRUPT BIT */ +#define SDHC_INT_INT_A (0x1U << 9) /*!< SDHC NORMAL INTERRUPT INT_A EVENT BIT */ +#define SDHC_INT_INT_B (0x1U << 10) /*!< SDHC NORMAL INTERRUPT INT_B EVENT BIT */ +#define SDHC_INT_INT_C (0x1U << 11) /*!< SDHC NORMAL INTERRUPT INT_C EVENT BIT */ +#define SDHC_INT_RETUNING (0x1U << 12) /*!< SDHC NORMAL INTERRUPT RETUNING EVENT BIT */ +#define SDHC_INT_ERROR_INTR (0x1U << 15) /*!< SDHC NORMAL INTERRUPT ERROR INTERRUPT BIT */ +#define SDHC_INT_E_CMD_TIMEOUT (0x1U << 16) /*!< SDHC NORMAL INTERRUPT CMD TIMEOUT ERROR BIT */ +#define SDHC_INT_E_CMD_CRC (0x1U << 17) /*!< SDHC NORMAL INTERRUPT CMD CRC ERROR BIT */ +#define SDHC_INT_E_CMD_END_BIT (0x1U << 18) /*!< SDHC NORMAL INTERRUPT CMD INDEX ERROR BIT */ +#define SDHC_INT_E_CMD_INDEX (0x1U << 19) /*!< SDHC NORMAL INTERRUPT CMD END BIT ERROR BIT */ +#define SDHC_INT_E_DATA_TIMEOUT (0x1U << 20) /*!< SDHC NORMAL INTERRUPT DATA TIMEOUT ERROR BIT */ +#define SDHC_INT_E_DATA_CRC (0x1U << 21) /*!< SDHC NORMAL INTERRUPT DATA CRC ERROR BIT */ +#define SDHC_INT_E_DATA_END_BIT (0x1U << 22) /*!< SDHC NORMAL INTERRUPT DATA END BIT ERROR BIT */ +#define SDHC_INT_E_CUR_LIMIT (0x1U << 23) /*!< SDHC NORMAL INTERRUPT CURRENT LIMIT ERROR BIT */ +#define SDHC_INT_E_AUTOCMD12 (0x1U << 24) /*!< SDHC NORMAL INTERRUPT AUTO CMD12 ERROR BIT */ +#define SDHC_INT_E_ADMA (0x1U << 25) /*!< SDHC NORMAL INTERRUPT ADMA ERROR BIT */ +#define SDHC_INT_E_TUNING (0x1U << 26) /*!< SDHC NORMAL INTERRUPT TUNING ERROR BIT */ + +#define SDHC_INT_CMD_MASK (SDHC_INT_CMD_DONE | SDHC_INT_E_CMD_TIMEOUT |\ + SDHC_INT_E_CMD_CRC | SDHC_INT_E_CMD_INDEX |\ + SDHC_INT_E_CMD_END_BIT) +#define SDHC_INT_DATA_MASK (SDHC_INT_TRANSFER_DONE | SDHC_INT_E_DATA_TIMEOUT |\ + SDHC_INT_E_DATA_CRC | SDHC_INT_E_DATA_END_BIT) +#define SDHC_INT_CARD_DET_MASK (SDHC_INT_CARD_REMOVE | SDHC_INT_CARD_INSERT) +#define SDHC_INT_NORMAL_MASK (0x00007FFFU) +#define SDHC_INT_ERROR_MASK (0xFFFF8000U) +#define SDHC_INT_ALL_MASK ((uint32_t)-1) + +#define SDHC_ACMD12_ERROR (0x3CU) /*!< SDHC AUTO CMD12 ERROR REG */ + +#define SDHC_HOST_CONTROL2 (0x3EU) /*!< SDHC HOST CONTROL2 REG */ +#define SDHC_CTRL2_UHS_MASK (0x0007U) /*!< SDHC HOST CONTROL2 UHS MODE MASK */ +#define SDHC_CTRL2_UHS_SDR12 (0x0000U) /*!< SDHC HOST CONTROL2 UHS-I SDR12 */ +#define SDHC_CTRL2_UHS_SDR25 (0x0001U) /*!< SDHC HOST CONTROL2 UHS-I SDR25 */ +#define SDHC_CTRL2_UHS_SDR50 (0x0002U) /*!< SDHC HOST CONTROL2 UHS-I SDR50 */ +#define SDHC_CTRL2_UHS_SDR104 (0x0003U) /*!< SDHC HOST CONTROL2 UHS-I SDR104 */ +#define SDHC_CTRL2_UHS_DDR50 (0x0004U) /*!< SDHC HOST CONTROL2 UHS-I DDR50 */ +#define SDHC_CTRL2_HS_SDR200 (0x0005U) /*!< SDHC HOST CONTROL2 HS SDR2000*/ +#define SDHC_CTRL2_VDD_180 (0x0008U) /*!< SDHC HOST CONTROL2 1.8V SINGALING ENABLE */ +#define SDHC_CTRL2_DRV_TYPE_MASK (0x0030U) /*!< SDHC HOST CONTROL2 DRIVE MASK */ +#define SDHC_CTRL2_DRV_TYPE_B (0x0000U) /*!< SDHC HOST CONTROL2 DRIVE TYPE B */ +#define SDHC_CTRL2_DRV_TYPE_A (0x0010U) /*!< SDHC HOST CONTROL2 DRIVE TYPE A */ +#define SDHC_CTRL2_DRV_TYPE_C (0x0020U) /*!< SDHC HOST CONTROL2 DRIVE TYPE C */ +#define SDHC_CTRL2_DRV_TYPE_D (0x0030U) /*!< SDHC HOST CONTROL2 DRIVE TYPE D */ +#define SDHC_CTRL2_EXEC_TUNING (0x0040U) /*!< SDHC HOST CONTROL2 EXECUTE TUNING */ +#define SDHC_CTRL2_TUNED_CLK (0x0080U) /*!< SDHC HOST CONTROL2 SAMPLING CLOCK SELECT */ +#define SDHC_CTRL2_ASNYC_INTR_EN (0x4000U) /*!< SDHC HOST CONTROL2 ASYNC INTERRUPT ENABLE*/ +#define SDHC_CTRL2_PRESET_VAL_EN (0x8000U) /*!< SDHC HOST CONTROL2 PRESET VALUE ENABLE */ + +#define SDHC_HOST_CAPABILITIES (0x40U) /*!< SDHC CAPABILITIES REG */ +#define SDHC_HCAP_TOCLKFREQ_MASK (0x0000003F) /*!< SDHC CAPABILITIES TIMEOUT CLOCK FREQUENCY */ +#define SDHC_HCAP_TOCKLUINT_MHZ (0x00000080U) /*!< SDHC CAPABILITIES TIMEOUT CLOCK UNIT */ +#define SDHC_HCAP_CLK_BASE_MASK (0x00003F00U) /*!< SDHC CAPABILITIES BASE CLOCK FREQUENCY FOR SD CLOCK MASK */ +#define SDHC_HCAP_MAX_BLK_LSF (16U) /*!< SDHC CAPABILITIES MAX BLOCK LENGTH SHIFT */ +#define SDHC_HCAP_MAX_BLK_MASK (0x00030000U) /*!< SDHC CAPABILITIES MAX BLOCK LENGTH MASK */ +#define SDHC_HCAP_MAXBLK_512 (0x0U) /*!< SDHC CAPABILITIES MAX BLOCK LENGTH 512B */ +#define SDHC_HCAP_MAXBLK_1024 (0x1U) /*!< SDHC CAPABILITIES MAX BLOCK LENGTH 1024B */ +#define SDHC_HCAP_MAXBLK_2048 (0x2U) /*!< SDHC CAPABILITIES MAX BLOCK LENGTH 2048B */ +#define SDHC_HCAP_SUPPORT_8BIT (0x00040000U) /*!< SDHC CAPABILITIES SUPPORT 8 BIT */ +#define SDHC_HCAP_SUPPORT_ADMA2 (0x00080000U) /*!< SDHC CAPABILITIES SUPPORT ADMA2 */ +#define SDHC_HCAP_SUPPORT_ADMA1 (0x00100000U) /*!< SDHC CAPABILITIES SUPPORT ADMA1 */ +#define SDHC_HCAP_SUPPORT_HISPD (0x00200000U) /*!< SDHC CAPABILITIES SUPPORT HIGH SPEED */ +#define SDHC_HCAP_SUPPORT_SDMA (0x00400000U) /*!< SDHC CAPABILITIES SUPPORT SDMA */ +#define SDHC_HCAP_SUPPORT_SUSPEND (0x00800000U) /*!< SDHC CAPABILITIES SUPPORT SUSPEND RESUME */ +#define SDHC_HCAP_SUPPORT_V330 (0x01000000U) /*!< SDHC CAPABILITIES SUPPORT 3.3V */ +#define SDHC_HCAP_SUPPORT_V300 (0x02000000U) /*!< SDHC CAPABILITIES SUPPORT 3.0V */ +#define SDHC_HCAP_SUPPORT_V180 (0x04000000U) /*!< SDHC CAPABILITIES SUPPORT 1.8V */ +#define SDHC_HCAP_SUPPORT_64BIT (0x10000000U) /*!< SDHC CAPABILITIES SUPPORT 64-BIT */ +#define SDHC_HCAP_SUPPORT_ASYNC (0x20000000U) /*!< SDHC CAPABILITIES SUPPORT ASYNC INTERRUPT */ +#define SDHC_HCAP_SLOT_TYPE_LSF (30U) /*!< SDHC CAPABILITIES SLOT TYPE SHIFT */ +#define SDHC_HCAP_SLOT_TYPE_MASK (0xC0000000U) /*!< SDHC CAPABILITIES SLOT TYPE MASK */ +#define SDHC_HCAP_SLOT_REMOVABLE (0x0U) /*!< SDHC CAPABILITIES SLOT TYPE REMOVABLE */ +#define SDHC_HCAP_SLOT_EMBEDDED (0x1U) /*!< SDHC CAPABILITIES SLOT TYPE EMBEDDED SLOT FOR ONE DEVICE */ +#define SDHC_HCAP_SLOT_SHARED (0x2U) /*!< SDHC CAPABILITIES SLOT TYPE SHARED BUS SLOT */ + +#define SDHC_HOST_CAPABILITIES_1 (0x44U) /*!< SDHC CAPABILITIES1 REG */ +#define SDHC_HCAP_SUPORT_SDR50 (0x00000001U) /*!< SDHC CAPABILITIES1 SUPPORT SDR50 */ +#define SDHC_HCAP_SUPORT_SDR104 (0x00000002U) /*!< SDHC CAPABILITIES1 SUPPORT SDR104 */ +#define SDHC_HCAP_SUPORT_DDR50 (0x00000004U) /*!< SDHC CAPABILITIES1 SUPPORT DDR50 */ +#define SDHC_HCAP_DRIVER_TYPE_A (0x00000010U) /*!< SDHC CAPABILITIES1 SUPPORT DRIVER TYPE A */ +#define SDHC_HCAP_DRIVER_TYPE_C (0x00000020U) /*!< SDHC CAPABILITIES1 SUPPORT DRIVER TYPE C */ +#define SDHC_HCAP_DRIVER_TYPE_D (0x00000040U) /*!< SDHC CAPABILITIES1 SUPPORT DRIVER TYPE D */ +#define SDHC_HCAP_RT_TMCNT_LSF (8U) /*!< SDHC CAPABILITIES1 TIMER COUNT FOR RETUNING SHIFT */ +#define SDHC_HCAP_RT_TMCNT_MASK (0x00000F00U) /*!< SDHC CAPABILITIES1 TIMER COUNT FOR RETUNING MASK */ +#define SDHC_HCAP_USE_SDR50_TUNE (0x00002000U) /*!< SDHC CAPABILITIES1 USE TUNING FOR SDR50 */ +#define SDHC_HCAP_RT_MODE_LSF (14U) /*!< SDHC CAPABILITIES1 RETUNE MODE SHIFT */ +#define SDHC_HCAP_RT_MODE_MASK (0x0000C000U) /*!< SDHC CAPABILITIES1 RETUNE MODE MASK */ +#define SDHC_HCAP_CLK_MUL_LSF (16U) /*!< SDHC CAPABILITIES1 CLOCK MULTIPLIER SHIFT */ +#define SDHC_HCAP_CLK_MUL_MASK (0x00FF0000U) /*!< SDHC CAPABILITIES1 CLOCK MULTIPLIER MASK */ + +#define SDHC_MAX_CURRENT (0x48U) /*!< SDHC MAX CURRENT REG */ +#define SDHC_MC_330_LSF (0U) /*!< SDHC MAX CURRENT MAXIMUM CURRENT FOR 3.3V SHIFT */ +#define SDHC_MC_330_MASK (0x0000FF) /*!< SDHC MAX CURRENT MAXIMUM CURRENT FOR 3.3V MASK */ +#define SDHC_MC_300_LSF (8U) /*!< SDHC MAX CURRENT MAXIMUM CURRENT FOR 3.0V SHIFT */ +#define SDHC_MC_300_MASK (0x00FF00U) /*!< SDHC MAX CURRENT MAXIMUM CURRENT FOR 3.0V MASK */ +#define SDHC_MC_180_LSF (16U) /*!< SDHC MAX CURRENT MAXIMUM CURRENT FOR 1.8V SHIFT */ +#define SDHC_MC_180_MASK (0xFF0000U) /*!< SDHC MAX CURRENT MAXIMUM CURRENT FOR 1.8V MASK */ + +#define SDHC_FRC_EVENT_AUTOCMD (0x50U) /*!< SDHC FORCE EVENT FOR AUTOCMD REG */ +#define SDHC_FEA_E_NO_ACMD12_EXEC (0x0001U) /*!< SDHC FORCE EVENT AUTO CMD12 NOT EXECUTED */ +#define SDHC_FEA_E_ACMD_TIMEOUT (0x002U) /*!< SDHC FORCE EVENT AUTO CMD TIMEOUT ERROR */ +#define SDHC_FEA_E_ACMD_CRC (0x0004U) /*!< SDHC FORCE EVENT AUTO CMD CRC ERROR */ +#define SDHC_FEA_E_ACMD_END (0x0008U) /*!< SDHC FORCE EVENT AUTO CMD END BIT ERROR */ +#define SDHC_FEA_E_ACMD_INDEX (0x0010U) /*!< SDHC FORCE EVENT AUTO CMD INDEX ERROR */ +#define SDHC_FEA_E_CMD_NOT_BY_ACMD12 (0x0080U) /*!< SDHC FORCE EVENT AUTO CMD NOT ISSUED ERROR */ + +#define SDHC_FRC_EVENT_ERROR_INTR (0x52U) /*!< SDHC FORCE EVENT FOR ERROR REG */ +#define SDHC_FEI_E_CMD_TIMEOUT (0x0001U) /*!< SDHC FORCE CMD TIMEOUT ERROR */ +#define SDHC_FEI_E_CMD_CRC (0x0002U) /*!< SDHC FORCE CMD CRC ERROR */ +#define SDHC_FEI_E_CMD_END_BIT (0x0004U) /*!< SDHC FORCE CMD END BIT ERROR */ +#define SDHC_FEI_E_DATA_TIMEOUT (0x0008U) /*!< SDHC FORCE DATA TIMEOUT ERROR */ +#define SDHC_FEI_E_DATA_CRC (0x0010U) /*!< SDHC FORCE DATA CRC ERROR */ +#define SDHC_FEI_E_DATA_END_BIT (0x0020U) /*!< SDHC FORCE DATA END BIT ERROR */ +#define SDHC_FEI_E_CURRENT_LIMIT (0x0040U) /*!< SDHC FORCE CURRENT LIMIT ERROR */ +#define SDHC_FEI_E_AUTO_CMD (0x0080U) /*!< SDHC FORCE AUTOCMD ERROR */ +#define SDHC_FEI_E_ADMA (0x0100U) /*!< SDHC FORCE ADMA ERROR */ + +#define SDHC_ADMA_ERROR (0x54U) /*!< SDHC ADMA ERROR REG */ +#define SDHC_ADMA_ADDRESS (0x58U) /*!< SDHC ADMA ADDRESS REG */ + +#define SDHC_SLOT_INT_STATUS (0xFCU) /*!< SDHC SLOT INTERRUPT STATUS REG */ +#define SDHC_HOST_VERSION (0xFEU) /*!< SDHC HOST CONTROLLER VERSION REG */ +#define SDHC_VENDOR_VER_LSF (8U) /*!< SDHC HOST CONTROLLER VERSION VENDOR VERSION SHIFT */ +#define SDHC_VENDOR_VER_MASK (0xFF00U) /*!< SDHC HOST CONTROLLER VERSION VENDOR VERSION MASK */ +#define SDHC_SPEC_VER_LSF (0U) /*!< SDHC HOST CONTROLLER VERSION SPEC VERSION SHIFT */ +#define SDHC_SPEC_VER_MASK (0x00FFU) /*!< SDHC HOST CONTROLLER VERSION SPEC VERSION MASK */ +#define SDHC_SPEC_100 (0U) /*!< SDHC HOST CONTROLLER VERSION SPEC VERSION 1.00 */ +#define SDHC_SPEC_200 (1U) /*!< SDHC HOST CONTROLLER VERSION SPEC VERSION 2.00 */ +#define SDHC_SPEC_300 (2U) /*!< SDHC HOST CONTROLLER VERSION SPEC VERSION 3.00 */ + +/*! @} */ +#endif + +/************************************************************************************************* + * EOF + ************************************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_sdhc_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_sdhc_driver.h new file mode 100755 index 0000000..c00a21b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_sdhc_driver.h @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_SDHC_H__ +#define __FSL_SDHC_H__ + +#include <stdio.h> +#include "fsl_os_abstraction.h" +#include "fsl_sdhc_hal.h" +#if FSL_FEATURE_SOC_SDHC_COUNT + +/*! @addtogroup sdhc_pd_data_types */ +/*! @{ */ + +/* + * These macros enables features of SDHC driver: + * + * BSP_FSL_SDHC_USING_IRQ + * - Enables IRQ on Initialization + * + * BSP_FSL_SDHC_ENABLE_ADMA1 + * - Enables the ADMA1 feature. As a result of the alignment limitation of the ADMA1, + * it falls back to PIO if the data size/address does not align. + * + * BSP_FSL_SDHC_ENABLE_AUTOCMD12 + * - Enables sending cmd12 automatically for multiple block R/W access. + * + * BSP_FSL_SDHC_USING_DYNALLOC + * - Enables dynamic allocate memory in SDHC/SDCARD driver + * + */ +#define BSP_FSL_SDHC_USING_IRQ +#define BSP_FSL_SDHC_ENABLE_AUTOCMD12 +#define BSP_FSL_SDHC_ENABLE_ADMA1 + +extern SDHC_Type * const g_sdhcBase[]; +extern const IRQn_Type g_sdhcIrqId[SDHC_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ +typedef enum _sdhc_status { + kStatus_SDHC_NoError = 0, /*!< No error */ + kStatus_SDHC_InitFailed, /*!< Driver initialization failed */ + kStatus_SDHC_SetClockFailed, /*!< Failed to set clock of host controller */ + kStatus_SDHC_SetCardToIdle, /*!< Failed to set card to idle */ + kStatus_SDHC_SetCardBlockSizeFailed, /*!< Failed to set card block size */ + kStatus_SDHC_SendAppOpCondFailed, /*!< Failed to send app_op_cond command */ + kStatus_SDHC_AllSendCidFailed, /*!< Failed to send all_send_cid command */ + kStatus_SDHC_SendRcaFailed, /*!< Failed to send send_rca command */ + kStatus_SDHC_SendCsdFailed, /*!< Failed to send send_csd command */ + kStatus_SDHC_SendScrFailed, /*!< Failed to send send_scr command */ + kStatus_SDHC_SelectCardFailed, /*!< Failed to send select_card command */ + kStatus_SDHC_SwitchHighSpeedFailed, /*!< Failed to switch to high speed mode */ + kStatus_SDHC_SetCardWideBusFailed, /*!< Failed to set card's bus mode */ + kStatus_SDHC_SetBusWidthFailed, /*!< Failed to set host's bus mode */ + kStatus_SDHC_SendCardStatusFailed, /*!< Failed to send card status */ + kStatus_SDHC_StopTransmissionFailed, /*!< Failed to stop transmission */ + kStatus_SDHC_CardEraseBlocksFailed, /*!< Failed to erase blocks */ + kStatus_SDHC_InvalidIORange, /*!< Invalid read/write/erase address range */ + kStatus_SDHC_BlockSizeNotSupportError, /*!< Unsupported block size */ + kStatus_SDHC_HostIsAlreadyInited, /*!< Host controller is already initialized */ + kStatus_SDHC_HostNotSupport, /*!< Host not error */ + kStatus_SDHC_HostIsBusyError, /*!< Bus busy error */ + kStatus_SDHC_DataPrepareError, /*!< Data preparation error */ + kStatus_SDHC_WaitTimeoutError, /*!< Wait timeout error */ + kStatus_SDHC_OutOfMemory, /*!< Out of memory error */ + kStatus_SDHC_IoError, /*!< General IO error */ + kStatus_SDHC_CmdIoError, /*!< CMD I/O error */ + kStatus_SDHC_DataIoError, /*!< Data I/O error */ + kStatus_SDHC_InvalidParameter, /*!< Invalid parameter error */ + kStatus_SDHC_RequestFailed, /*!< Request failed */ + kStatus_SDHC_RequestCardStatusError, /*!< Status error */ + kStatus_SDHC_SwitchFailed, /*!< Switch failed */ + kStatus_SDHC_NotSupportYet, /*!< Not support */ + kStatus_SDHC_TimeoutError, /*!< Timeout error*/ + kStatus_SDHC_CardNotSupport, /*!< Card does not support */ + kStatus_SDHC_CmdError, /*!< CMD error */ + kStatus_SDHC_DataError, /*!< Data error */ + kStatus_SDHC_DmaAddressError, /*!< DMA address error */ + kStatus_SDHC_Failed, /*!< General failed */ + kStatus_SDHC_NoMedium, /*!< No medium error */ + kStatus_SDHC_UnknownStatus /*!< Unknown if card is present */ +} sdhc_status_t; + +typedef enum _sdhc_card_detect_type { + kSdhcCardDetectGpio = 1, /*!< Use GPIO for card detection. @internal gui name="GPIO" */ + kSdhcCardDetectDat3, /*!< Use DAT3 for card detection. @internal gui name="DAT3" */ + kSdhcCardDetectCdPin, /*!< Use host controller dedicate CD pin for card detection. @internal gui name="HOST" */ + kSdhcCardDetectPollDat3, /*!< Poll DAT3 for card detection. @internal gui name="Poll-DAT3" */ + kSdhcCardDetectPollCd, /*!< Poll host controller dedicate CD pin for card detection. @internal gui name="Poll-HOST" */ +} sdhc_cd_type_t; + +typedef enum _sdhc_power_mode { + kSdhcPowerModeRunning = 0, /*!< SDHC is running */ + kSdhcPowerModeSuspended, /*!< SDHC is suspended */ + kSdhcPowerModeStopped, /*!< SDHC is stopped */ +} sdhc_power_mode_t; + +typedef enum _sdhc_buswidth { + kSdhcBusWidth1Bit = 1, /*!< 1-bit bus width. @internal gui name="1-bit bus width" */ + kSdhcBusWidth4Bit, /*!< 4-bit bus width. @internal gui name="4-bit bus width" */ + kSdhcBusWidth8Bit, /*!< 8-bit bus width. @internal gui name="8-bit bus width" */ +} sdhc_buswidth_t; + +typedef enum _sdhc_transfer_mode { + kSdhcTransModePio = 1, /*!< Transfer mode: PIO. @internal gui name="PIO" */ + kSdhcTransModeSdma, /*!< Transfer mode: SDMA. @internal gui name="SDMA" */ + kSdhcTransModeAdma1, /*!< Transfer mode: ADMA1. @internal gui name="ADMA1" */ + kSdhcTransModeAdma2, /*!< Transfer mode: ADMA2. @internal gui name="ADMA2" */ +} sdhc_transfer_mode_t; + +#define FSL_SDHC_REQ_RSPTYPE_PRESENT (1 << 1) /* response presented */ +#define FSL_SDHC_REQ_RSPTYPE_136BITS (1 << 2) /* response with 136 bits length */ +#define FSL_SDHC_REQ_RSPTYPE_CRC (1 << 3) /* response checking CRC */ +#define FSL_SDHC_REQ_RSPTYPE_BUSY (1 << 4) /* response with busy */ +#define FSL_SDHC_REQ_RSPTYPE_CHK_IDX (1 << 5) /* response with checking command index*/ + +#define FSL_SDHC_REQ_RSPTYPE_NONE (0U) +#define FSL_SDHC_REQ_RSPTYPE_R1 (FSL_SDHC_REQ_RSPTYPE_PRESENT | \ + FSL_SDHC_REQ_RSPTYPE_CRC | \ + FSL_SDHC_REQ_RSPTYPE_CHK_IDX) /* Response 1 */ +#define FSL_SDHC_REQ_RSPTYPE_R1B (FSL_SDHC_REQ_RSPTYPE_PRESENT | \ + FSL_SDHC_REQ_RSPTYPE_CRC | \ + FSL_SDHC_REQ_RSPTYPE_CHK_IDX | \ + FSL_SDHC_REQ_RSPTYPE_BUSY) /* Response 1 with busy */ +#define FSL_SDHC_REQ_RSPTYPE_R2 (FSL_SDHC_REQ_RSPTYPE_PRESENT | \ + FSL_SDHC_REQ_RSPTYPE_136BITS | \ + FSL_SDHC_REQ_RSPTYPE_CRC) /* Response 2 */ +#define FSL_SDHC_REQ_RSPTYPE_R3 (FSL_SDHC_REQ_RSPTYPE_PRESENT) /* Response 3 */ +#define FSL_SDHC_REQ_RSPTYPE_R4 (FSL_SDHC_REQ_RSPTYPE_PRESENT) /* Response 4 */ +#define FSL_SDHC_REQ_RSPTYPE_R5 (FSL_SDHC_REQ_RSPTYPE_PRESENT | \ + FSL_SDHC_REQ_RSPTYPE_CRC | \ + FSL_SDHC_REQ_RSPTYPE_CHK_IDX) /* Response 5 */ +#define FSL_SDHC_REQ_RSPTYPE_R5B (FSL_SDHC_REQ_RSPTYPE_PRESENT | \ + FSL_SDHC_REQ_RSPTYPE_CRC | \ + FSL_SDHC_REQ_RSPTYPE_CHK_IDX | \ + FSL_SDHC_REQ_RSPTYPE_BUSY) /* Response 5 with busy */ +#define FSL_SDHC_REQ_RSPTYPE_R6 (FSL_SDHC_REQ_RSPTYPE_PRESENT | \ + FSL_SDHC_REQ_RSPTYPE_CRC | \ + FSL_SDHC_REQ_RSPTYPE_CHK_IDX) /* Response 6 */ +#define FSL_SDHC_REQ_RSPTYPE_R7 (FSL_SDHC_REQ_RSPTYPE_PRESENT | \ + FSL_SDHC_REQ_RSPTYPE_CRC | \ + FSL_SDHC_REQ_RSPTYPE_CHK_IDX) /* Response 7 */ + +static const uint32_t g_req_resp_flags[] = { + FSL_SDHC_REQ_RSPTYPE_NONE, /*!< R0 flags */ + FSL_SDHC_REQ_RSPTYPE_R1, /*!< R1 flags */ + FSL_SDHC_REQ_RSPTYPE_R1B, /*!< R1b flags */ + FSL_SDHC_REQ_RSPTYPE_R2, /*!< R2 flags */ + FSL_SDHC_REQ_RSPTYPE_R3, /*!< R3 flags */ + FSL_SDHC_REQ_RSPTYPE_R4, /*!< R4 flags */ + FSL_SDHC_REQ_RSPTYPE_R5, /*!< R5 flags */ + FSL_SDHC_REQ_RSPTYPE_R5B, /*!< R5b flags */ + FSL_SDHC_REQ_RSPTYPE_R6, /*!< R6 flags */ + FSL_SDHC_REQ_RSPTYPE_R7, /*!< R7 flags */ +}; + +typedef enum _sdhc_resp_type { + kSdhcRespTypeNone = 0, /*!< Response type: none */ + kSdhcRespTypeR1, /*!< Response type: R1 */ + kSdhcRespTypeR1b, /*!< Response type: R1b */ + kSdhcRespTypeR2, /*!< Response type: R2 */ + kSdhcRespTypeR3, /*!< Response type: R3 */ + kSdhcRespTypeR4, /*!< Response type: R4 */ + kSdhcRespTypeR5, /*!< Response type: R5 */ + kSdhcRespTypeR5b, /*!< Response type: R5b */ + kSdhcRespTypeR6, /*!< Response type: R6 */ + kSdhcRespTypeR7, /*!< Response type: R7 */ +} sdhc_resp_type_t; + + +/*! + * @brief SDHC Initialization Configuration Structure + * + * Defines the configuration data structure to initialize the SDHC. + * @internal gui name="Basic Configuration" id="sdhcCfg" + */ +typedef struct SdhcUserConfig +{ + uint32_t clock; /*!< Clock rate @internal gui name="Bus clock" id="BusClock" */ + sdhc_transfer_mode_t transMode; /*!< SDHC transfer mode @internal gui name="Transfer mode" id="transferMode" */ + sdhc_cd_type_t cdType; /*!< Card detection type @internal gui name="Card detection type" id="cardDetection" */ + void (*cardDetectCallback)(bool inserted); /*!< Callback function for card detect occurs @internal gui name="Card detect callback function" id="CardDetectCallback" type="callback" */ + void (*cardIntCallback)(void); /*!< Callback function for card interrupt occurs @internal gui name="Card interrupt callback function" id="CardInterruptCallback" type="callback" */ + void (*blockGapCallback)(void); /*!< Callback function for block gap occurs @internal gui name="Card block gap callback function" id="CardBlockGapCallback" type="callback" */ +} sdhc_user_config_t; + +/*! + * @brief SDHC Host Device Structure + * + * Defines the Host device structure which includes both the static and the runtime SDHC information. + */ +typedef struct SdhcHostDevice +{ + uint32_t instance; /*!< Host instance index */ + sdhc_cd_type_t cdType; /*!< Host controller card detection type */ + sdhc_hal_endian_t endian; /*!< Endian mode the host's working at */ + uint32_t swFeature; /*!< Host controller driver features */ +#define FSL_SDHC_HOST_SW_FEATURE_NODMA (1 << 0) /*!< No DMA supported in driver */ + uint32_t flags; /*!< Host flags */ +#define FSL_SDHC_HOST_FLAGS_CARD_PRESENTED (1 << 0) /*!< Card presented */ + sdhc_transfer_mode_t mode; + uint32_t busWidth; /*!< Current busWidth */ + uint32_t caps; /*!< Host capability */ +#define FSL_SDHC_HOST_CAPS_SUPPORT_V180 (1 << 0) /*!< Host support 1.8v */ +#define FSL_SDHC_HOST_CAPS_SUPPORT_HIGHSPEED (1 << 1) /*!< Host support highspeed mode */ +#define FSL_SDHC_HOST_CAPS_SUPPORT_4BITS (1 << 2) /*!< Host support 4-bit bus width */ +#define FSL_SDHC_HOST_CAPS_SUPPORT_DMA (1 << 3) /*!< Host support DMA mode */ +#define FSL_SDHC_HOST_CAPS_SUPPORT_ADMA (1 << 4) /*!< Host support ADMA mode */ +#define FSL_SDHC_HOST_CAPS_SUPPORT_EXDMA (1 << 5) /*!< Host support ExDMA mode */ +#define FSL_SDHC_HOST_CAPS_SUPPORT_SRS (1 << 6) /*!< Host support suspend resume mode*/ + uint32_t ocrSupported; /*!< Supported OCR */ + uint32_t clock; /*!< Current clock frequency */ + sdhc_power_mode_t powerMode; /*!< Current power mode */ + uint32_t maxClock; /*!< Maximum clock supported */ + uint32_t maxBlockSize; /*!< Maximum block size supported */ + uint32_t maxBlockCount; /*!< Maximum block count supported */ + uint32_t *admaTableAddress; /*!< ADMA table address */ +#if defined BSP_FSL_SDHC_USING_DYNALLOC + uint32_t admaTableMaxEntries; /*!< Maximum entries can be held in table */ +#endif + struct SdhcRequest * currentReq; /*!< Associated request */ + void (*cardIntCallback)(void); /*!< Callback function for card interrupt occurs */ + void (*cardDetectCallback)(bool inserted); /*!< Callback function for card detect occurs */ + void (*blockGapCallback)(void); /*!< Callback function for block gap occurs */ +} sdhc_host_t; + +#define DOES_HOST_SUPPORT_HIGHSPEED(x) (x->caps & FSL_SDHC_HOST_CAPS_SUPPORT_HIGHSPEED) +#define DOES_HOST_SUPPORT_4BITS(x) (x->caps & FSL_SDHC_HOST_CAPS_SUPPORT_4BITS) + +/*! + * @brief SDHC Data Structure + * + * Defines the SDHC data structure including the block size/count and flags. + */ +typedef struct SdhcData +{ + struct SdhcRequest *req; /*!< Associated request */ + uint32_t blockSize; /*!< Block size */ + uint32_t blockCount; /*!< Block count */ + uint32_t bytesTransferred; /*!< Transferred buffer */ + uint32_t *buffer; /*!< Data buffer */ +} sdhc_data_t; + +/*! + * @brief SDHC Request Structure + * + * Defines the SDHC request structure including the command index, argument, flags, response, and data. + */ +typedef struct SdhcRequest +{ + uint32_t cmdIndex; /*!< Command index */ + uint32_t argument; /*!< Command argument */ + uint32_t flags; /*!< Flags */ +#define FSL_SDHC_REQ_FLAGS_DATA_READ (1 << 0) /*!< Request will read data */ +#define FSL_SDHC_REQ_FLAGS_USE_DMA (1 << 1) /*!< Request will use DMA for data transferring */ +#define FSL_SDHC_REQ_FLAGS_STOP_TRANS (1 << 2) /*!< Request to stop transmition */ + sdhc_resp_type_t respType; /*!< Response type */ + volatile uint32_t error; /*!< Command error code */ +#define FSL_SDHC_REQ_ERR_HOST_BUSY (1 << 0) /*!< Host is busy */ +#define FSL_SDHC_REQ_ERR_SEND_CMD (1 << 1) /*!< Send command error */ +#define FSL_SDHC_REQ_ERR_CMD_CRC (1 << 2) /*!< Command CRC error */ +#define FSL_SDHC_REQ_ERR_CMD_INDEX (1 << 3) /*!< Command index error */ +#define FSL_SDHC_REQ_ERR_CMD_END_BIT (1 << 4) /*!< Command end bit error */ +#define FSL_SDHC_REQ_ERR_CMD_TIMEOUT (1 << 5) /*!< Command timeout error */ +#define FSL_SDHC_REQ_ERR_CARD_REMOVED (1 << 6) /*!< Card removed */ +#define FSL_SDHC_REQ_ERR_RSPBUSY_TIMEOUT (1 << 7) /*!< Response busy timeout error */ +#define FSL_SDHC_REQ_ERR_DAT_TIMEOUT (1 << 8) /*!< Data timeout error */ +#define FSL_SDHC_REQ_ERR_DATA_CRC (1 << 9) /*!< Data CRC error */ +#define FSL_SDHC_REQ_ERR_DATA_END_BIT (1 << 10) /*!< Data end bit error */ +#define FSL_SDHC_REQ_ERR_AUTO_CMD12 (1 << 11) /*!< Auto cmd12 error */ +#define FSL_SDHC_REQ_ERR_DMA (1 << 12) /*!< DMA error */ +#define FSL_SDHC_REQ_ERR_TIMEOUT (1 << 13) /*!< Request timeout error */ +#define FSL_SDHC_REQ_ERR_DATA_PREPARE (1 << 14) /*!< Data preparation error */ + uint32_t cardErrStatus; /*!< Card error status from response 1 */ + uint32_t response[4]; /*!< Response for this command */ + semaphore_t *complete; /*!< Request completion sync object */ + struct SdhcData *data; /*!< Data associated with request */ +} sdhc_request_t; + +/*! @} */ + +/*! @addtogroup sdhc_pd */ +/*! @{ */ + +/************************************************************************************************* + * API + ************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif +/*! @name SDHC PD FUNCTION */ +/*@{ */ + +/*! + * @brief Initializes the Host controller with a specific instance index. + * + * This function initializes the SDHC module according to the given + * initialization configuration structure including the clock frequency, + * bus width, and card detect callback. + * + * @param instance the specific instance index + * @param host pointer to a place storing the sdhc_host_t structure + * @param config initialization configuration data + * @return kStatus_SDHC_NoError if success + */ +sdhc_status_t SDHC_DRV_Init(uint32_t instance, sdhc_host_t *host, const sdhc_user_config_t *config); + +/*! + * @brief Destroys the host controller. + * + * @param instance the instance index of host controller + * @return kStatus_SDHC_NoError if success + */ +sdhc_status_t SDHC_DRV_Shutdown(uint32_t instance); + +/*! + * @brief Checks whether the card is present on a specified host controller. + * + * This function checks if there's a card inserted in the SDHC. + * + * @param instance the instance index of host controller + * @return kStatus_SDHC_NoError on success + */ +sdhc_status_t SDHC_DRV_DetectCard(uint32_t instance); + +/*! + * @brief Sets the clock frequency of the host controller. + * + * @param instance the instance index of host controller + * @param clock the desired frequency to be set to controller + * + * @return kStatus_SDHC_NoError on success + */ +sdhc_status_t SDHC_DRV_ConfigClock(uint32_t instance, uint32_t clock); + +/*! + * @brief Sets the bus width of the host controller. + * + * @param instance the instance index of host controller + * @param busWidth the desired bus width to be set to controller + * + * @return kStatus_SDHC_NoError on success + */ +sdhc_status_t SDHC_DRV_SetBusWidth(uint32_t instance, sdhc_buswidth_t busWidth); + +/*! + * @brief Issues the request on a specific host controller and returns on completion. + * + * This function issues the request to the card on a specific SDHC. + * The command is sent and is blocked as long as + * the response/data is sending back from the card. + * + * @param instance the instance index of host controller + * @param req the pointer to the request + * @param timeoutInMs timeout value in microseconds + * @return kStatus_SDHC_NoError on success + */ +sdhc_status_t SDHC_DRV_IssueRequestBlocking(uint32_t instance, sdhc_request_t *req, uint32_t timeoutInMs); + +#if defined BSP_FSL_SDHC_USING_IRQ +/*! + * @brief IRQ handler for SDHC + * + * This function deals with IRQs on the given host controller. + * + * @param instance the instance index of host controller + */ +void SDHC_DRV_DoIrq(uint32_t instance); +#endif + +/*@} */ +#if defined(__cplusplus) +} +#endif +/*! @} */ +#endif +#endif /* __FSL_SDHC_H__ */ + +/************************************************************************************************* + * EOF + ************************************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_spi_dma_master_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_spi_dma_master_driver.h new file mode 100755 index 0000000..05b6e76 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_spi_dma_master_driver.h @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_SPI_MASTER_DMA_DRIVER_H__) +#define __FSL_SPI_DMA_MASTER_DRIVER_H__ + +#include "fsl_spi_hal.h" +#include "fsl_os_abstraction.h" +#include "fsl_dma_driver.h" + +#if FSL_FEATURE_SOC_SPI_COUNT + +/*! @addtogroup SPI_DRV_MasterDriver*/ +/*! @{*/ + +/*! @brief Table of base pointers for SPI instances. */ +extern SPI_Type * const g_spiBase[SPI_INSTANCE_COUNT]; + +/*! @brief Table to save SPI IRQ enumeration numbers defined in CMSIS header file. */ +extern const IRQn_Type g_spiIrqId[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +enum _spi_dma_timeouts +{ + /*! Waits forever for a transfer to complete.*/ + kSpiDmaWaitForever = 0x7fffffff +}; + +/*! + * @brief Information about a device on the SPI bus with DMA. + */ +typedef struct SpiDmaUserConfig { + uint32_t bitsPerSec; /*!< SPI baud rate in bits per sec */ + spi_clock_polarity_t polarity; + spi_clock_phase_t phase; + spi_shift_direction_t direction; + + /* 16-bit support related members */ +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + spi_data_bitcount_mode_t bitCount; /*!< Number of bits (8 or 16) in a transfer */ +#endif +} spi_dma_master_user_config_t; + +/*! + * @brief Runtime state of the SPI master driver with DMA. + * + * This structure holds data that are used by the SPI master peripheral driver to + * communicate between the transfer function and the interrupt handler. The + * interrupt handler also uses this information to keep track of its progress. + */ +typedef struct SpiDmaMasterState { + uint32_t spiSourceClock; /*!< Module source clock*/ + volatile bool isTransferInProgress; /*!< True if there is an active transfer.*/ + const uint8_t * sendBuffer; /*!< The buffer being sent.*/ + uint8_t * receiveBuffer; /*!< The buffer into which received bytes are placed.*/ + volatile size_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ + volatile size_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ + volatile size_t transferredByteCount; /*!< Number of bytes transferred so far.*/ + volatile bool isTransferBlocking; /*!< True if transfer is a blocking transaction. */ + semaphore_t irqSync; /*!< Used to wait for ISR to complete its business.*/ + bool extraByte; /*!< Flag used for 16-bit transfers with odd byte count */ + dma_channel_t dmaReceive; /*!< The DMA channel used for receive */ + dma_channel_t dmaTransmit; /*!< The DMA channel used for transmit */ + uint32_t transferByteCnt; /*!< Number of bytes to transfer.*/ +} spi_dma_master_state_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! @name Initialization and shutdown*/ +/*@{*/ + +/*! + * + * @brief Initializes a SPI instance for master mode operation to work with DMA. + * + * This function uses a DMA-driven method for transferring data. + * This function initializes the run-time state structure to track the ongoing + * transfers, un-gates the clock to the SPI module, resets the SPI module, initializes the module + * to user defined settings and default settings, configures the IRQ state structure, enables + * the module-level interrupt to the core, and enables the SPI module. + * + * This initialization function also configures the DMA module by requesting channels for DMA + * operation. + * + * @param instance The instance number of the SPI peripheral. + * @param spiDmaState The pointer to the SPI DMA master driver state structure. The user + * must pass the memory for this run-time state structure and the SPI master driver + * fills out the members. This run-time state structure keeps track of the + * transfer in progress. + * @return kStatus_SPI_Success indicating successful initialization + */ +spi_status_t SPI_DRV_DmaMasterInit(uint32_t instance, spi_dma_master_state_t * spiDmaState); + +/*! + * @brief Shuts down a SPI instance with DMA support. + * + * This function resets the SPI peripheral, gates its clock, disables any used interrupts to + * the core, and releases any used DMA channels. + * + * @param instance The instance number of the SPI peripheral. + * @return kStatus_SPI_Success indicating successful de-initialization + */ +spi_status_t SPI_DRV_DmaMasterDeinit(uint32_t instance); + +/*@}*/ + +/*! @name Bus configuration*/ +/*@{*/ + +/*! + * @brief Configures the SPI port to access a device on the bus with DMA support. + * + * The term "device" is used to indicate the SPI device for which the SPI master is communicating. + * The user has two options to configure the device parameters: either pass in the + * pointer to the device configuration structure to the desired transfer function or pass it in to + * the SPI_DRV_DmaMasterConfigureBus function. The user can pass in a device structure to the + * transfer function which contains the parameters for the bus (the transfer function then calls + * this function). However, the user has the option to call this function directly especially + * to get the calculated baud rate, at which point they may pass in NULL for the device + * structure in the transfer function (assuming they have called this configure bus function + * first). + * + * @param instance The instance number of the SPI peripheral. + * @param device Pointer to the device information structure. This structure contains the settings + * for SPI bus configurations. + * @param calculatedBaudRate The calculated baud rate passed back to the user to determine + * if the calculated baud rate is close enough to meet the needs. The baud rate never exceeds + * the desired baud rate unless the baud rate requested is less than the absolute minimum in + * which case the minimum baud rate will be returned. + */ +void SPI_DRV_DmaMasterConfigureBus(uint32_t instance, + const spi_dma_master_user_config_t * device, + uint32_t * calculatedBaudRate); + +/*@}*/ + +/*! @name Blocking transfers*/ +/*@{*/ + +/*! + * @brief Performs a blocking SPI master mode transfer with DMA support. + * + * This function simultaneously sends and receives data on the SPI bus, as SPI is naturally + * a full-duplex bus. The function does return until the transfer is complete. + * + * @param instance The instance number of the SPI peripheral. + * @param device Pointer to the device information structure. This structure contains the settings + * for the SPI bus configuration for this transfer. You may pass NULL for this + * parameter, in which case the current bus configuration is used unmodified. + * @param sendBuffer Buffer of data to send. You may pass NULL for this parameter, in which case + * bytes with a value of 0 (zero) are sent. + * @param receiveBuffer Buffer where received bytes are stored. If you pass NULL for this parameter, + * the received bytes are ignored. + * @param transferByteCount The number of bytes to send and receive. + * @param timeout A timeout for the transfer in microseconds. If the transfer takes longer than + * this amount of time, the transfer is aborted and a #kStatus_SPI_Timeout error is + * returned. + * + * @return #kStatus_Success The transfer was successful. + * #kStatus_SPI_Busy Cannot perform another transfer because one is already in progress. + * #kStatus_SPI_Timeout The transfer timed out and was aborted. + */ +spi_status_t SPI_DRV_DmaMasterTransferBlocking(uint32_t instance, + const spi_dma_master_user_config_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount, + uint32_t timeout); + +/*@}*/ + +/*! @name Non-blocking transfers*/ +/*@{*/ + +/*! + * @brief Performs a non-blocking SPI master mode transfer with DMA support. + * + * This function returns immediately. It is the user's responsibility to check back to + * ascertain if the transfer is complete (using the SPI_DRV_DmaMasterGetTransferStatus function). + * This function simultaneously sends and receives data on the SPI bus, as SPI is naturally + * a full-duplex bus. The function does return until the transfer is complete. + * + * @param instance The instance number of the SPI peripheral. + * @param device Pointer to the device information structure. This structure contains the settings + * for the SPI bus configuration for this transfer. You may pass NULL for this + * parameter, in which case the current bus configuration is used unmodified. + * @param sendBuffer Buffer of data to send. You may pass NULL for this parameter, in which case + * bytes with a value of 0 (zero) is sent. + * @param receiveBuffer Buffer where received bytes are stored. If you pass NULL for this parameter, + * the received bytes are ignored. + * @param transferByteCount The number of bytes to send and receive. + * + * @return #kStatus_Success The transfer was successful. + * #kStatus_SPI_Busy Cannot perform another transfer because one is already in progress. + * #kStatus_SPI_Timeout The transfer timed out and was aborted. + */ +spi_status_t SPI_DRV_DmaMasterTransfer(uint32_t instance, + const spi_dma_master_user_config_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount); + +/*! + * @brief Returns whether the previous transfer finished with DMA support. + * + * When performing an a-sync transfer, the user can call this function to ascertain the state of the + * current transfer: in progress (or busy) or complete (success). In addition, if the transfer + * is still in progress, the user can get the number of words that have been + * transferred up to now. + * + * @param instance The instance number of the SPI peripheral. + * @param bytesTransferred Pointer to a value that is filled in with the number of bytes that + * were sent in the active transfer + * + * @return kStatus_Success The transfer has completed successfully. + * kStatus_SPI_Busy The transfer is still in progress. @a bytesTransferred is filled + * with the number of bytes that have been transferred so far. + */ +spi_status_t SPI_DRV_DmaMasterGetTransferStatus(uint32_t instance, + uint32_t * bytesTransferred); + +/*! + * @brief Terminates an asynchronous transfer early with DMA support. + * + * During an a-sync transfer, the user has the option to terminate the transfer early if the transfer + * is still in progress. + * + * @param instance The instance number of the SPI peripheral. + * @return kStatus_SPI_Success The transfer was successful. + * kStatus_SPI_NoTransferInProgress No transfer is currently in progress. + */ +spi_status_t SPI_DRV_DmaMasterAbortTransfer(uint32_t instance); + +/*! + * @brief Interrupt handler for SPI master mode. + * This handler is used when the extraByte flag is set to retrieve the received last byte. + * + * @param instance The instance number of the SPI peripheral. + */ +void SPI_DRV_DmaMasterIRQHandler(uint32_t instance); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* FSL_FEATURE_SOC_SPI_COUNT */ +#endif /* __FSL_SPI_MASTER_DMA_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_spi_dma_shared_function.h b/KSDK_1.2.0/platform/drivers/inc/fsl_spi_dma_shared_function.h new file mode 100755 index 0000000..6a25b87 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_spi_dma_shared_function.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_SPI_DMA_SHARED_FUNCTION_H__) +#define __FSL_SPI_DMA_SHARED_FUNCTION_H__ + +#include <stdbool.h> +#include "fsl_device_registers.h" +#include "fsl_spi_hal.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to runtime state structure.*/ +extern void *g_spiStatePtr[SPI_INSTANCE_COUNT]; + +/*! @brief Table to save SPI IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_spiIrqId[SPI_INSTANCE_COUNT]; +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief The function SPI_DRV_DmaIRQHandler passes IRQ control to either the master or + * slave driver. + * + * The address of the IRQ handlers are checked to make sure they are non-zero before + * they are called. If the IRQ handler's address is zero, it means that driver was + * not present in the link (because the IRQ handlers are marked as weak). This would + * actually be a program error, because it means the master/slave config for the IRQ + * was set incorrectly. + * @param instance The instance number of the SPI peripheral. + */ +void SPI_DRV_DmaIRQHandler(uint32_t instance); + +#endif /* __FSL_SPI_DMA_SHARED_FUNCTION_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_spi_dma_slave_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_spi_dma_slave_driver.h new file mode 100755 index 0000000..2a3af0d --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_spi_dma_slave_driver.h @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_SPI_DMA_SLAVE_DRIVER_H__) +#define __FSL_SPI_DMA_SLAVE_DRIVER_H__ + +#include "fsl_spi_hal.h" +#include "fsl_dma_driver.h" +#include "fsl_os_abstraction.h" + +#if FSL_FEATURE_SOC_SPI_COUNT + +/*! + * @addtogroup spi_slave_driver + * @{ + */ + +/*! @brief Table of base pointers for SPI instances. */ +extern SPI_Type * const g_spiBase[SPI_INSTANCE_COUNT]; + +/*! @brief Table to save SPI IRQ enumeration numbers defined in CMSIS header file. */ +extern const IRQn_Type g_spiIrqId[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define SPI_DMA_DEFAULT_DUMMY_PATTERN (0x0U) /*!< Dummy pattern, that SPI slave sends when transmit data was not configured */ + +/*! + * @brief User configuration structure for the SPI slave driver. + */ +typedef struct SPIDmaSlaveUserConfig { + spi_clock_phase_t phase; /*!< Clock phase setting. */ + spi_clock_polarity_t polarity; /*!< Clock polarity setting.*/ + spi_shift_direction_t direction; /*!< Either LSB or MSB first.*/ +/* 16-bit support related members */ +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + spi_data_bitcount_mode_t bitCount; /*!< Number of bits (8 or 16) in a transfer */ +#endif + uint16_t dummyPattern; /*!< Dummy data value */ +} spi_dma_slave_user_config_t; + +/*! + * @brief Runtime state of the SPI slave driver. + * + * This structure holds data that is used by the SPI slave peripheral driver to + * communicate between the transfer function and the interrupt handler. The user + * needs to pass in the memory for this structure and the driver fills out + * the members. + */ +typedef struct SPIDmaSlaveState { + spi_status_t status; /*!< Current state of slave */ + event_t event; /*!< Event to notify waiting task */ + uint16_t errorCount; /*!< Driver error count */ + uint32_t dummyPattern; /*!< Dummy data is sent when there is no data in the transmit buffer */ + volatile bool isTransferInProgress; /*!< True if there is an active transfer.*/ + const uint8_t * sendBuffer; /*!< Pointer to transmit buffer */ + uint8_t * receiveBuffer; /*!< Pointer to receive buffer */ + volatile int32_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ + volatile int32_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ + volatile int32_t transferredByteCount; /*!< Number of bytes transferred so far.*/ + bool isSync; /*!< Indicates the function call is sync or a-sync */ + bool hasExtraByte; /*!< Indicates the reception has extra byte */ + dma_channel_t dmaReceive; /*!< The DMA channel used for receive */ + dma_channel_t dmaTransmit; /*!< The DMA channel used for transmit */ +} spi_dma_slave_state_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and shutdown + * @{ + */ + +/*! + * @brief Initializes a SPI instance for a slave mode operation, using interrupt mechanism. + * + * This function un-gates the clock to the SPI module, initializes the SPI for + * slave mode. Once initialized, the SPI module is configured in slave mode and + * user can start transmit, receive data by calls send, receive, transfer functions. + * This function indicates SPI slave uses an interrupt mechanism. + * + * @param instance The instance number of the SPI peripheral. + * @param spiState The pointer to the SPI slave driver state structure. + * @param slaveConfig The configuration structure spi_slave_user_config_t which + * configures the data bus format. + * + * @return An error code or kStatus_SPI_Success. + */ + +spi_status_t SPI_DRV_DmaSlaveInit(uint32_t instance, + spi_dma_slave_state_t * spiState, + const spi_dma_slave_user_config_t * slaveConfig); + +/*! + * @brief Shuts down a SPI instance - interrupt mechanism. + * + * Disables the SPI module, gates its clock, change SPI slave driver state to NonInit for + * SPI slave module which is initialized with interrupt mechanism. After de-initialized, + * user can re-initialize SPI slave module with other mechanisms. + * + * @param instance The instance number of the SPI peripheral. + * @return kStatus_SPI_Success indicating successful de-initialization + */ +spi_status_t SPI_DRV_DmaSlaveDeinit(uint32_t instance); + +/*! @} */ + +/*! + * @name Blocking transfers + * @{ + */ + +/*! + * @brief Transfers data on SPI bus using interrupt and blocking call + * + * This function check driver status, mechanism and transmit/receive data through SPI + * bus. If sendBuffer is NULL, transmit process is ignored. If the receiveBuffer is NULL, the + * receive process is ignored. If both the receiveBuffer and the sendBuffer are available, the transmit and the + * receive progress are processed. If only the receiveBuffer available, the receive is + * processed. Otherwise, the transmit is processed. This function returns when its + * processes are completed. This function uses interrupt mechanism. + * + * @param instance The instance number of SPI peripheral + * @param sendBuffer The pointer to data that user wants to transmit. + * @param receiveBuffer The pointer to data that user wants to store received data. + * @param transferByteCount The number of bytes to send and receive. + * @param timeout The maximum number of milliseconds that function waits before + * timed out reached. + * + * @return kStatus_SPI_Success if driver starts to send/receive data successfully. + * kStatus_SPI_Error if driver is error and needs to clean error. + * kStatus_SPI_Busy if driver is receiving/transmitting data and not available. + * kStatus_SPI_Timeout if time out reached while transferring is in progress. + */ +spi_status_t SPI_DRV_DmaSlaveTransferBlocking(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount, + uint32_t timeout); + +/*@}*/ + +/*! + * @name Non-blocking transfers + * @{ + */ + +/*! + * @brief Starts transfer data on the SPI bus using an interrupt and a non-blocking call + * + * This function checks the driver status then set buffer pointers to receive and transmit + * SPI data. If the sendBuffer is NULL, the transmit process is ignored. If the receiveBuffer + * is NULL, the receive process is ignored. If both the receiveBuffer and the sendBuffer available, + * transfer is done when the kDspiTxDone and kDspiRxDone are set. If only the receiveBuffer is + * available, the transfer is done when the kDspiRxDone flag is set. Otherwise, the transfer is done + * when the kDspiTxDone was set. This function uses an interrupt mechanism. + * + * @param instance The instance number of SPI peripheral + * @param sendBuffer The pointer to data that user wants to transmit. + * @param receiveBuffer The pointer to data that user wants to store received data. + * @param transferByteCount The number of bytes to send and receive. + * + * @return kStatus_SPI_Success if driver starts to send/receive data successfully. + * kStatus_SPI_Error if driver is error and needs to clean error. + * kStatus_SPI_Busy if driver is receiving/transmitting data and not + * available. + */ +spi_status_t SPI_DRV_DmaSlaveTransfer(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount); + +/*! + * @brief Aborts the transfer that started by a non-blocking call transfer function. + * + * This function stops the transfer which was started by the SPI_DRV_SlaveTransfer() function. + * + * @param instance The instance number of SPI peripheral + * + * @return kStatus_SPI_Success if everything is OK. + * kStatus_SPI_InvalidMechanism if the current transaction does not use + * interrupt mechanism. + */ +spi_status_t SPI_DRV_DmaSlaveAbortTransfer(uint32_t instance); + +/*! + * @brief Returns whether the previous transfer is finished. + * + * When performing an a-sync transfer, the user can call this function to ascertain + * the state of the current transfer: in progress (or busy) or complete (success). + * In addition, if the transfer is still in progress, the user can get the number + * of words that have been transferred up to now. + * + * @param instance The instance number of the SPI peripheral. + * @param framesTransferred Pointer to value that is filled in with the number of + * frames that have been sent in the active transfer. A frame is defined as the + * number of bits per frame. + * + * @return kStatus_SPI_Success The transfer has completed successfully, or + * kStatus_SPI_Busy The transfer is still in progress. framesTransferred + * is filled with the number of words that have been transferred so far. + */ +spi_status_t SPI_DRV_DmaSlaveGetTransferStatus(uint32_t instance, + uint32_t * framesTransferred); + +/*! + * @brief Interrupt handler for SPI slave mode. + * This handler is used when the hasExtraByte flag is set to retrieve the received last byte. + * + * @param instance The instance number of the SPI peripheral. + */ +void SPI_DRV_DmaSlaveIRQHandler(uint32_t instance); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* FSL_FEATURE_SOC_SPI_COUNT */ +#endif /* __FSL_SPI_DMA_SLAVE_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_spi_master_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_spi_master_driver.h new file mode 100755 index 0000000..6e974cd --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_spi_master_driver.h @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_SPI_MASTER_DRIVER_H__) +#define __FSL_SPI_MASTER_DRIVER_H__ + +#include "fsl_spi_hal.h" +#include "fsl_os_abstraction.h" + +#if FSL_FEATURE_SOC_SPI_COUNT + +/*! @addtogroup SPI_DRV_MasterDriver*/ +/*! @{*/ + +/*! @brief Table of base pointers for SPI instances. */ +extern SPI_Type * const g_spiBase[SPI_INSTANCE_COUNT]; + +/*! @brief Table to save SPI IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_spiIrqId[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +enum _spi_timeouts +{ + /*! Waits forever for a transfer to complete.*/ + kSpiWaitForever = 0x7fffffff +}; + +/*! + * @brief Information about a device on the SPI bus. + * @internal gui name="Master configuration" id="spiMasterCfg" + */ +typedef struct SPIUserConfig { + uint32_t bitsPerSec; /*!< SPI baud rate in bits per sec @internal gui name="Clock rate" id="MasterBaudRate" */ + spi_clock_polarity_t polarity; /*!< Active high or low clock polarity @internal gui name="Polarity" id="MasterPolarity" */ + spi_clock_phase_t phase; /*!< Clock phase setting to change and capture data @internal gui name="Phase" id="MasterPhase" */ + spi_shift_direction_t direction; /*!< MSB or LSB data shift direction @internal gui name="Direction" id="MasterDirection" */ + + /* 16-bit support related members */ +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + spi_data_bitcount_mode_t bitCount; /*!< Number of bits (8 or 16) in a transfer @internal gui name="Bit count" id="MasterBitCount" */ +#endif +} spi_master_user_config_t; + +/*! + * @brief Runtime state of the SPI master driver. + * + * This structure holds data that are used by the SPI master peripheral driver to + * communicate between the transfer function and the interrupt handler. The + * interrupt handler also uses this information to keep track of its progress. + */ +typedef struct SPIMasterState { + uint32_t spiSourceClock; /*!< Module source clock*/ + volatile bool isTransferInProgress; /*!< True if there is an active transfer.*/ + const uint8_t * sendBuffer; /*!< The buffer being sent.*/ + uint8_t * receiveBuffer; /*!< The buffer into which received bytes are placed.*/ + volatile size_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ + volatile size_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ + volatile size_t transferredByteCount; /*!< Number of bytes transferred so far.*/ + volatile bool isTransferBlocking; /*!< True if transfer is a blocking transaction. */ + semaphore_t irqSync; /*!< Used to wait for ISR to complete its business.*/ + bool extraByte; /*!< Flag used for 16-bit transfers with odd byte count */ +} spi_master_state_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! @name Initialization and shutdown*/ +/*@{*/ + +/*! + * @brief Initializes an SPI instance for master mode operation. + * + * This function uses a CPU interrupt driven method for transferring data. + * It initializes the run-time state structure to track the ongoing + * transfers, un-gates the clock to the SPI module, resets and initializes the module + * to default settings, configures the IRQ state structure, enables + * the module-level interrupt to the core, and enables the SPI module. + * + * @param instance The instance number of the SPI peripheral. + * @param spiState The pointer to the SPI master driver state structure. The user + * passes the memory for the run-time state structure and the SPI master driver + * populates the members. This run-time state structure keeps track of the + * transfer in progress. + * @return kStatus_SPI_Success indicating successful initialization + */ +spi_status_t SPI_DRV_MasterInit(uint32_t instance, spi_master_state_t * spiState); + +/*! + * @brief Shuts down an SPI instance. + * + * This function resets the SPI peripheral, gates its clock, and disables the interrupt to + * the core. + * + * @param instance The instance number of the SPI peripheral. + * @return kStatus_SPI_Success indicating successful de-initialization + */ +spi_status_t SPI_DRV_MasterDeinit(uint32_t instance); + +/*@}*/ + +/*! @name Bus configuration*/ +/*@{*/ + +/*! + * @brief Configures the SPI port to access a device on the bus. + * + * The term "device" is used to indicate the SPI device for which the SPI master is communicating. + * The user has two options to configure the device parameters: either pass in the + * pointer to the device configuration structure to the desired transfer function (see + * SPI_DRV_MasterTransferDataBlocking or SPI_DRV_MasterTransferData) or pass it in to the + * SPI_DRV_MasterConfigureBus function. The user can pass in a device structure to the transfer + * function which contains the parameters for the bus (the transfer function then calls + * this function). However, the user has the option to call this function directly especially + * to get the calculated baud rate, at which point they may pass in NULL for the device + * structure in the transfer function (assuming they have called this configure bus function + * first). + * + * @param instance The instance number of the SPI peripheral. + * @param device Pointer to the device information structure. This structure contains the settings + * for SPI bus configurations. + * @param calculatedBaudRate The calculated baud rate passed back to the user to determine + * if the calculated baud rate is close enough to meet the needs. The baud rate never exceeds + * the desired baud rate unless the baud rate requested is less than the absolute minimum in + * which case the minimum baud rate is returned. + */ +void SPI_DRV_MasterConfigureBus(uint32_t instance, + const spi_master_user_config_t * device, + uint32_t * calculatedBaudRate); + +/*@}*/ + +/*! @name Blocking transfers*/ +/*@{*/ + +/*! + * @brief Performs a blocking SPI master mode transfer. + * + * This function simultaneously sends and receives data on the SPI bus, because the SPI is + * a full-duplex bus, and does not return until the transfer is complete. + * + * @param instance The instance number of the SPI peripheral. + * @param device Pointer to the device information structure. This structure contains the settings + * for the SPI bus configuration for this transfer. You may pass NULL for this + * parameter, in which case the current bus configuration is used unmodified. + * @param sendBuffer Buffer of data to send. You may pass NULL for this parameter, in which case + * bytes with a value of 0 (zero) are sent. + * @param receiveBuffer Buffer where received bytes are stored. If you pass NULL for this parameter, + * the received bytes are ignored. + * @param transferByteCount The number of bytes to send and receive. + * @param timeout A timeout for the transfer in microseconds. If the transfer takes longer than + * this amount of time, the transfer is aborted and a #kStatus_SPI_Timeout error is + * returned. + * + * @return #kStatus_Success The transfer was successful. + * #kStatus_SPI_Busy Cannot perform another transfer because one is already in progress. + * #kStatus_SPI_Timeout The transfer timed out and was aborted. + */ +spi_status_t SPI_DRV_MasterTransferBlocking(uint32_t instance, + const spi_master_user_config_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount, + uint32_t timeout); + +/*@}*/ + +/*! @name Non-blocking transfers*/ +/*@{*/ + +/*! + * @brief Performs a non-blocking SPI master mode transfer. + * + * This function returns immediately. The user should check back to + * find out if the transfer is complete (using the SPI_DRV_MasterGetTransferStatus function). + * This function simultaneously sends and receives data on the SPI bus, because the SPI is + * a full-duplex bus, and does not return until the transfer is complete. + * + * @param instance The instance number of the SPI peripheral. + * @param device Pointer to the device information structure. This structure contains the settings + * for the SPI bus configuration for this transfer. You may pass NULL for this + * parameter, in which case the current bus configuration is used unmodified. + * @param sendBuffer Buffer of data to send. You may pass NULL for this parameter, in which case + * bytes with a value of 0 (zero) is sent. + * @param receiveBuffer Buffer where received bytes are stored. If you pass NULL for this parameter, + * the received bytes are ignored. + * @param transferByteCount The number of bytes to send and receive. + * + * @return #kStatus_Success The transfer was successful. + * #kStatus_SPI_Busy Cannot perform another transfer because one is already in progress. + * #kStatus_SPI_Timeout The transfer timed out and was aborted. + */ +spi_status_t SPI_DRV_MasterTransfer(uint32_t instance, + const spi_master_user_config_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount); + +/*! + * @brief Returns whether the previous transfer is completed. + * + * When performing an a-sync transfer, calling this function shows the state of the + * current transfer: in progress (or busy) or complete (success). In addition, if the transfer + * is still in progress, the user can get the number of words that have been + * transferred up to now. + * + * @param instance The instance number of the SPI peripheral. + * @param bytesTransferred Pointer to a value that is filled in with the number of bytes that + * were sent in the active transfer + * + * @return kStatus_Success The transfer has completed successfully. + * kStatus_SPI_Busy The transfer is still in progress. @a bytesTransferred is filled + * with the number of bytes that have been transferred so far. + */ +spi_status_t SPI_DRV_MasterGetTransferStatus(uint32_t instance, + uint32_t * bytesTransferred); + +/*! + * @brief Terminates an asynchronous transfer early. + * + * During an a-sync transfer, the user has the option to terminate the transfer early if the transfer + * is still in progress. + * + * @param instance The instance number of the SPI peripheral. + * @return kStatus_SPI_Success The transfer was successful. + * kStatus_SPI_NoTransferInProgress No transfer is currently in progress. + */ +spi_status_t SPI_DRV_MasterAbortTransfer(uint32_t instance); + +/*! + * @brief Interrupt handler for SPI master mode. + * This handler uses the buffers stored in the spi_master_state_t structs to transfer data. + * + * @param instance The instance number of the SPI peripheral. + */ +void SPI_DRV_MasterIRQHandler(uint32_t instance); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* FSL_FEATURE_SOC_SPI_COUNT */ +#endif /* __FSL_SPI_MASTER_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_spi_shared_function.h b/KSDK_1.2.0/platform/drivers/inc/fsl_spi_shared_function.h new file mode 100755 index 0000000..4a0d344 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_spi_shared_function.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_SPI_SHARED_FUNCTION_H__) +#define __FSL_SPI_SHARED_FUNCTION_H__ + +#include <stdbool.h> +#include "fsl_device_registers.h" +#include "fsl_spi_hal.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to runtime state structure.*/ +extern void * g_spiStatePtr[SPI_INSTANCE_COUNT]; + +/*! @brief Table to save SPI IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_spiIrqId[SPI_INSTANCE_COUNT]; +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief The function SPI_DRV_IRQHandler passes IRQ control to either the master or + * slave driver. + * + * The address of the IRQ handlers are checked to make sure they are non-zero before + * they are called. If the IRQ handler's address is zero, it means that driver was + * not present in the link (because the IRQ handlers are marked as weak). This would + * actually be a program error, because it means the master/slave config for the IRQ + * was set incorrectly. + * @param instance The instance number of the SPI peripheral. + */ +void SPI_DRV_IRQHandler(uint32_t instance); + +#endif /* __FSL_SPI_SHARED_FUNCTION_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_spi_slave_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_spi_slave_driver.h new file mode 100755 index 0000000..5e3eda8 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_spi_slave_driver.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_SPI_SLAVE_DRIVER_H__) +#define __FSL_SPI_SLAVE_DRIVER_H__ + +#include "fsl_spi_hal.h" +#include "fsl_os_abstraction.h" + +#if FSL_FEATURE_SOC_SPI_COUNT + +/*! + * @addtogroup spi_slave_driver + * @{ + */ + +/*! @brief Table of base pointers for SPI instances. */ +extern SPI_Type * const g_spiBase[SPI_INSTANCE_COUNT]; + +/*! @brief Table to save SPI IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_spiIrqId[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define SPI_DEFAULT_DUMMY_PATTERN (0x0U) /*!< Dummy pattern, that SPI slave sends when transmit data was not configured */ + +/*! + * @brief User configuration structure for the SPI slave driver. + * @internal gui name="Slave configuration" id="spiSlaveCfg" + */ +typedef struct SPISlaveUserConfig { + spi_clock_phase_t phase; /*!< Clock phase setting. @internal gui name="Phase" id="SlavePhase" */ + spi_clock_polarity_t polarity; /*!< Clock polarity setting. @internal gui name="Polarity" id="SlavePolarity" */ + spi_shift_direction_t direction; /*!< Either LSB or MSB first.@internal gui name="Direction" id="SlaveDirection" */ + /* 16-bit support related members */ +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + spi_data_bitcount_mode_t bitCount; /*!< Number of bits (8 or 16) in a transfer @internal gui name="Bit count" id="SlaveBitCount" */ +#endif + uint16_t dummyPattern; /*!< Dummy data value @internal gui name="Data pattern" id="dummyValue" */ +} spi_slave_user_config_t; + +/*! + * @brief Runtime state of the SPI slave driver. + * + * This structure holds data that is used by the SPI slave peripheral driver to + * communicate between the transfer function and the interrupt handler. The user + * needs to pass in the memory for this structure and the driver fills out + * the members. + */ +typedef struct SPISlaveState { + spi_status_t status; /*!< Current state of slave */ + event_t event; /*!< Event to notify waiting task */ + uint16_t errorCount; /*!< Driver error count */ + uint32_t dummyPattern; /*!< Dummy data is sent when there is no data in the transmit buffer */ + volatile bool isTransferInProgress; /*!< True if there is an active transfer.*/ + const uint8_t * sendBuffer; /*!< Pointer to transmit buffer */ + uint8_t * receiveBuffer; /*!< Pointer to receive buffer */ + volatile int32_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ + volatile int32_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ + volatile int32_t transferredByteCount; /*!< Number of bytes transferred so far.*/ + bool isSync; /*!< Indicates the function call is sync or a-sync */ +} spi_slave_state_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and shutdown + * @{ + */ + +/*! + * @brief Initializes a SPI instance for a slave mode operation, using interrupt mechanism. + * + * This function un-gates the clock to the SPI module, initializes the SPI for + * slave mode. After it is initialized, the SPI module is configured in slave mode and the + * user can start transmitting and receiving data by calling send, receive, and transfer functions. + * This function indicates SPI slave uses an interrupt mechanism. + * + * @param instance The instance number of the SPI peripheral. + * @param spiState The pointer to the SPI slave driver state structure. + * @param slaveConfig The configuration structure spi_slave_user_config_t which + * configures the data bus format. + * + * @return An error code or kStatus_SPI_Success. + */ + +spi_status_t SPI_DRV_SlaveInit(uint32_t instance, + spi_slave_state_t * spiState, + const spi_slave_user_config_t * slaveConfig); + +/*! + * @brief Shuts down an SPI instance interrupt mechanism. + * + * Disables the SPI module, gates its clock, and changes the SPI slave driver state to NonInit for the + * SPI slave module which is initialized with interrupt mechanism. After de-initialization, the + * user can re-initialize the SPI slave module with other mechanisms. + * + * @param instance The instance number of the SPI peripheral. + * @return An error code or kStatus_SPI_Success. + */ +spi_status_t SPI_DRV_SlaveDeinit(uint32_t instance); + +/*! @} */ + +/*! + * @name Blocking transfers + * @{ + */ + +/*! + * @brief Transfers data on SPI bus using interrupt and a blocking call. + * + * This function checks the driver status and mechanism, and transmits/receives data through the SPI + * bus. If the sendBuffer is NULL, the transmit process is ignored. If the receiveBuffer is NULL, the + * receive process is ignored. If both the receiveBuffer and the sendBuffer are available, the transmit and the + * receive progress is processed. If only the receiveBuffer is available, the receive is + * processed. Otherwise, the transmit is processed. This function only returns when the + * processes are completed. This function uses an interrupt mechanism. + * + * @param instance The instance number of SPI peripheral + * @param sendBuffer The pointer to data that user wants to transmit. + * @param receiveBuffer The pointer to data that user wants to store received data. + * @param transferByteCount The number of bytes to send and receive. + * @param timeout The maximum number of milliseconds that function waits before + * timed out reached. + * + * @return kStatus_SPI_Success if driver starts to send/receive data successfully. + * kStatus_SPI_Error if driver is error and needs to clean error. + * kStatus_SPI_Busy if driver is receiving/transmitting data and not available. + * kStatus_SPI_Timeout if time out reached while transferring is in progress. + */ +spi_status_t SPI_DRV_SlaveTransferBlocking(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount, + uint32_t timeout); + +/*@}*/ + +/*! + * @name Non-blocking transfers + * @{ + */ + +/*! + * @brief Starts the transfer data on SPI bus using an interrupt and a non-blocking call. + * + * This function checks the driver status and sets buffer pointers to receive and transmit + * SPI data. If the sendBuffer is NULL, the transmit process is ignored. If the receiveBuffer + * is NULL, the receive process is ignored. If both the receiveBuffer and the sendBuffer are available, + * the transfer is done when the kDspiTxDone and kDspiRxDone are set. If only the receiveBuffer is + * available, the transfer is done when the kDspiRxDone flag is set. Otherwise, the transfer is done + * when the kDspiTxDone was set. This function uses an interrupt mechanism. + * + * @param instance The instance number of SPI peripheral + * @param sendBuffer The pointer to data that user wants to transmit. + * @param receiveBuffer The pointer to data that user wants to store received data. + * @param transferByteCount The number of bytes to send and receive. + * + * @return kStatus_SPI_Success if driver starts to send/receive data successfully. + * kStatus_SPI_Error if driver is error and needs to clean error. + * kStatus_SPI_Busy if driver is receiving/transmitting data and not + * available. + */ +spi_status_t SPI_DRV_SlaveTransfer(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount); + +/*! + * @brief Aborts the transfer that started by a non-blocking call transfer function. + * + * This function stops the transfer which was started by the calling the SPI_DRV_SlaveTransfer() function. + * + * @param instance The instance number of SPI peripheral + * + * @return kStatus_SPI_Success if everything is OK. + * kStatus_SPI_InvalidMechanism if the current transaction does not use + * interrupt mechanism. + */ +spi_status_t SPI_DRV_SlaveAbortTransfer(uint32_t instance); + +/*! + * @brief Returns whether the previous transfer is finished. + * + * When performing an a-sync transfer, the user can call this function to ascertain + * the state of the current transfer: in progress (or busy) or complete (success). + * In addition, if the transfer is still in progress, the user can get the number + * of words that have been transferred up to now. + * + * @param instance The instance number of the SPI peripheral. + * @param framesTransferred Pointer to value that is filled in with the number of + * frames that have been sent in the active transfer. A frame is defined as the + * number of bits per frame. + * + * @return kStatus_SPI_Success The transfer has completed successfully, or + * kStatus_SPI_Busy The transfer is still in progress. framesTransferred + * is filled with the number of words that have been transferred so far. + */ +spi_status_t SPI_DRV_SlaveGetTransferStatus(uint32_t instance, + uint32_t * framesTransferred); + +/*! + * @brief SPI Slave Generic IRQ handler. + * + * @param instance Instance number of the SPI module. + */ +void SPI_DRV_SlaveIRQHandler(uint32_t instance); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* FSL_FEATURE_SOC_SPI_COUNT */ +#endif /* __FSL_SPI_SLAVE_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_tpm_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_tpm_driver.h new file mode 100755 index 0000000..4d3ab6a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_tpm_driver.h @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_TPM_DRIVER_H__ +#define __FSL_TPM_DRIVER_H__ + +#include "fsl_tpm_hal.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_TPM_COUNT + +/*! + * @addtogroup tpm_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Table of base addresses for TPM instances. */ +extern TPM_Type * const g_tpmBase[TPM_INSTANCE_COUNT]; + +/*! @brief Table to save TPM IRQ numbers for TPM instances. */ +extern const IRQn_Type g_tpmIrqId[TPM_INSTANCE_COUNT]; + +/*! @brief TPM clock source selection.*/ +typedef enum _tpm_clock_source +{ + kTpmClockSourcNone = 0, /*!< TPM clock source, None */ + kTpmClockSourceModuleHighFreq, /*!< TPM clock source, IRC48MHz or FLL/PLL depending on SoC */ + kTpmClockSourceModuleOSCERCLK, /*!< TPM clock source, OSCERCLK */ + kTpmClockSourceModuleMCGIRCLK, /*!< TPM clock source, MCGIRCLK */ + kTpmClockSourceExternalCLKIN0, /*!< TPM clock source, TPM_CLKIN0 */ + kTpmClockSourceExternalCLKIN1, /*!< TPM clock source, TPM_CLKIN1 */ + kTpmClockSourceReserved /*!< TPM clock source, Reserved */ +}tpm_clock_source_t; + +/*! @brief Internal driver state information grouped by naming. User needs to set the relevant ones. + * @internal gui name="Basic configuration" id="tpmCfg" + */ +typedef struct TpmGeneralConfig { + bool isDBGMode; /*!< DBGMode behavioral, false to pause, true to continue run in DBG mode @internal gui name="Debug mode" id="DebugMode" */ + bool isGlobalTimeBase; /*!< If Global time base enabled, true to enable, false to disable @internal gui name="Global time base" id="GlobalTimeBase" */ + bool isTriggerMode; /*!< If Trigger mode enabled, true to enable, false to disable @internal gui name="Trigger mode" id="TriggerMode" */ + bool isStopCountOnOveflow; /*!< True to stop counter after overflow, false to continue running @internal gui name="Stop count on overflow" id="StopOnOvf" */ + bool isCountReloadOnTrig; /*!< True to reload counter on trigger, false means counter is not reloaded @internal gui name="Reload counter on trigger" id="ReloadOnTrigger" */ + tpm_trigger_source_t triggerSource; /*!< Trigger source if trigger mode enabled @internal gui name="Trigger source" id="TriggerSource" */ +}tpm_general_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the TPM driver. + * + * @param instance The TPM peripheral instance number. + * @param info Pointer to the TPM user configuration structure, see #tpm_general_config_t. + * @return kStatusTpmSuccess means succees, otherwise means failed. + */ +tpm_status_t TPM_DRV_Init(uint32_t instance, const tpm_general_config_t * info); + +/*! + * @brief Stops the channel PWM. + * + * @param instance The TPM peripheral instance number. + * @param param PWM parameter to configure PWM options + * @param channel The channel number. + */ +void TPM_DRV_PwmStop(uint32_t instance, tpm_pwm_param_t *param, uint8_t channel); + +/*! + * @brief Configures duty cycle and frequency, and starts outputting PWM on a specified channel. + * + * @param instance The TPM peripheral instance number. + * @param param PWM parameter to configure PWM options, see #tpm_pwm_param_t. + * @param channel The channel number. + * + * @return kStatusTpmSuccess means succees, otherwise means failed. + */ +tpm_status_t TPM_DRV_PwmStart(uint32_t instance, tpm_pwm_param_t *param, uint8_t channel); + +/*! + * @brief Enables or disables the timer overflow interrupt. + * + * @param instance The TPM peripheral instance number. + * @param overflowEnable true: enable the timer overflow interrupt, false: disable + */ +void TPM_DRV_SetTimeOverflowIntCmd(uint32_t instance, bool overflowEnable); + +/*! + * @brief Enables or disables the channel interrupt. + * + * @param instance The TPM peripheral instance number. + * @param channelNum The channel number. + * @param enable true: enable the channel interrupt, false: disable + */ +void TPM_DRV_SetChnIntCmd(uint32_t instance, uint8_t channelNum, bool enable); + +/*! + * @brief Sets the TPM clock source. + * + * @param instance The TPM peripheral instance number. + * @param clock The TPM peripheral clock selection, see #tpm_clock_source_t. + * @param clockPs The TPM peripheral clock prescale factor, see #tpm_clock_ps_t. + */ +void TPM_DRV_SetClock(uint32_t instance, tpm_clock_source_t clock, tpm_clock_ps_t clockPs); + +/*! + * @brief Gets the TPM clock frequency. + * + * @param instance The TPM peripheral instance number. + * @return The function returns the frequency of the TPM clock. + */ +uint32_t TPM_DRV_GetClock(uint32_t instance); + +/*! + * @brief Starts the TPM counter. + * + * This function provides access to the TPM counter. The counter can be run in + * up-counting and up-down counting modes. + * + * @param instance The TPM peripheral instance number. + * @param countMode The TPM counter mode defined by tpm_counting_mode_t. + * @param countFinalVal The final value that is stored in the MOD register. + * @param enableOverflowInt true: enable timer overflow interrupt; false: disable + */ +void TPM_DRV_CounterStart(uint32_t instance, tpm_counting_mode_t countMode, uint32_t countFinalVal, + bool enableOverflowInt); + +/*! + * @brief Stops the TPM counter. + * + * @param instance The TPM peripheral instance number. + */ +void TPM_DRV_CounterStop(uint32_t instance); + +/*! + * @brief Reads back the current value of the TPM counter. + * + * @param instance The TPM peripheral instance number. + * @return The current value of the TPM counter. + */ +uint32_t TPM_DRV_CounterRead(uint32_t instance); + +/*! + * @brief TPM input capture mode setup. + * + * @param instance The TPM peripheral instance number. + * @param channel The channel number. + * @param mode The TPM input mode defined by #tpm_input_capture_mode_t. + * @param countFinalVal The final value that is stored in the MOD register. + * @param intEnable true: enable channel interrupt; false: disable + */ +void TPM_DRV_InputCaptureEnable(uint32_t instance, uint8_t channel, tpm_input_capture_mode_t mode, + uint32_t countFinalVal, bool intEnable); + +/*! + * @brief Reads back the current value of the TPM channel value. + * + * @param instance The TPM peripheral instance number. + * @param channel The channel number. + * @return The current value of the TPM channel value. + */ +uint32_t TPM_DRV_GetChnVal(uint32_t instance, uint8_t channel); + +/*! + * @brief TPM output compare mode setup. + * + * @param instance The TPM peripheral instance number. + * @param channel The channel number. + * @param mode The TPM output mode defined by #tpm_output_compare_mode_t. + * @param countFinalVal The final value that is stored in the MOD register. + * @param matchVal The channel compare value stored in the CnV register + * @param intEnable true: enable channel interrupt; false: disable + */ +void TPM_DRV_OutputCompareEnable(uint32_t instance, uint8_t channel, tpm_output_compare_mode_t mode, + uint32_t countFinalVal, uint32_t matchVal, bool intEnable); + +/*! + * @brief Shuts down the TPM driver. + * + * @param instance The TPM peripheral instance number. + */ +void TPM_DRV_Deinit(uint32_t instance); + +/*! + * @brief Action to take when an TPM interrupt is triggered. + * + * The timer overflow flag is checked and cleared if set. + * + * @param instance Instance number of the TPM module. + */ +void TPM_DRV_IRQHandler(uint32_t instance); + +/*Other API functions are for input capture, output compare, dual edge capture, and quadrature. */ +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* FSL_FEATURE_SOC_TPM_COUNT */ + +#endif /* __FSL_TPM_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_tsi_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_tsi_driver.h new file mode 100755 index 0000000..af1ade7 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_tsi_driver.h @@ -0,0 +1,576 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FSL_TSI_DRIVER_H__ +#define __FSL_TSI_DRIVER_H__ + +#include <stdint.h> +#include <stdlib.h> +#include <stdbool.h> +#include "fsl_os_abstraction.h" +#include "fsl_tsi_hal.h" +#if FSL_FEATURE_SOC_TSI_COUNT + +/*! + * @addtogroup tsi_driver + * @{ + */ + +/*! + * @file + * + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! +* @brief Call back routine of TSI driver. +* +* The function is called on end of the measure of the TSI driver. The function +* can be called from interrupt, so the code inside the callback should be short +* and fast. +* @param instance - instance of the TSI peripheral +* @param usrData - user data (type is void*), the user data are specified by function @ref TSI_DRV_SetCallBackFunc +* @return - none +*/ +typedef void (*tsi_callback_t)(uint32_t instance, void* usrData); + +/*! +* @brief User configuration structure for TSI driver. +* +* Use an instance of this structure with TSI_DRV_Init(). This allows you to configure the +* most common settings of the TSI peripheral with a single function call. Settings include: +* +*/ +typedef struct TsiUserConfig { + tsi_config_t *config; /**< A pointer to hardware configuration. Can't be NULL. */ + tsi_callback_t pCallBackFunc; /**< A pointer to call back function of end of measurement. */ + void * usrData; /**< A user data of call back function. */ +} tsi_user_config_t; + +/*! +* @brief Driver operation mode definition. +* +* The operation name definition used for TSI driver. +* +*/ +typedef enum TsiModes +{ + tsi_OpModeNormal = 0, /**< The normal mode of TSI. */ + tsi_OpModeProximity, /**< The proximity sensing mode of TSI. */ + tsi_OpModeLowPower, /**< The low power mode of TSI. */ + tsi_OpModeNoise, /**< The noise mode of TSI. This mode is not valid with TSI HW, valid only for the TSIL HW. */ + tsi_OpModeCnt, /**< Count of TSI modes - for internal use. */ + tsi_OpModeNoChange /**< The special value of operation mode that allows call for example @ref TSI_DRV_DisableLowPower function without change of operation mode. */ +}tsi_modes_t; + +/*! +* @brief Driver operation mode data hold structure. +* +* This is the operation mode data hold structure. The structure is keep all needed data +* to be driver able to switch the operation modes and properly set up HW peripheral. +* +*/ +typedef struct TsiOperationMode +{ + uint16_t enabledElectrodes; /**< The back up of enabled electrodes for operation mode */ + tsi_config_t config; /**< A hardware configuration. */ +}tsi_operation_mode_t; + +/*! +* @brief Driver data storage place. +* +* It must be created by the application code and the pointer is handled by the @ref TSI_DRV_Init function +* to driver. The driver keeps all context data for itself run. Settings include: +* +*/ +typedef struct TsiState { + tsi_status_t status; /**< Current status of the driver. */ + tsi_callback_t pCallBackFunc; /**< A pointer to call back function of end of measurement. */ + void *usrData; /**< A user data pointer handled by call back function. */ + semaphore_t irqSync; /**< Used to wait for ISR to complete its measure business. */ + mutex_t lock; /**< Used by whole driver to secure the context data integrity. */ + mutex_t lockChangeMode; /**< Used by change mode function to secure the context data integrity. */ + bool isBlockingMeasure; /**< Used to internal indication of type of measurement. */ + tsi_modes_t opMode; /**< Storage of current operation mode. */ + tsi_operation_mode_t opModesData[tsi_OpModeCnt]; /**< Data storage of individual operational modes. */ + uint16_t counters[FSL_FEATURE_TSI_CHANNEL_COUNT]; /**< The mirror of last state of counter registers */ +}tsi_state_t; + + +/*! @brief Table of base addresses for TSI instances. */ +extern TSI_Type * const g_tsiBase[]; + +/*! @brief Table to save TSI IRQ enumeration numbers defined in CMSIS header file. */ +extern const IRQn_Type g_tsiIrqId[TSI_INSTANCE_COUNT]; + +/*! @brief Table to save pointers to context data. */ +extern tsi_state_t * g_tsiStatePtr[TSI_INSTANCE_COUNT]; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization + * @{ + */ + +/*! +* @brief Initializes a TSI instance for operation. +* +* This function initializes the run-time state structure and prepares the +* entire peripheral to measure the capacitances on electrodes. + @code + + static tsi_state_t myTsiDriverStateStructure; + + tsi_user_config_t myTsiDriveruserConfig = + { + .config = + { + ... + }, + .pCallBackFunc = APP_myTsiCallBackFunc, + .usrData = myData, + }; + + if(TSI_DRV_Init(0, &myTsiDriverStateStructure, &myTsiDriveruserConfig) != kStatus_TSI_Success) + { + // Error, the TSI is not initialized + } + @endcode +* +* @param instance The TSI module instance. +* @param tsiState A pointer to the TSI driver state structure memory. The user is only +* responsible to pass in the memory for this run-time state structure where the TSI driver +* will take care of filling out the members. This run-time state structure keeps track of the +* current TSI peripheral and driver state. +* @param tsiUserConfig The user configuration structure of type tsi_user_config_t. The user +* populates the members of this structure and passes the pointer of this structure +* into the function. +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_Init(uint32_t instance, tsi_state_t * tsiState, const tsi_user_config_t * tsiUserConfig); + +/*! +* @brief Shuts down the TSI by disabling interrupts and the peripheral. +* +* This function disables the TSI interrupts and the peripheral. +* + @code + if(TSI_DRV_DeInit(0) != kStatus_TSI_Success) + { + // Error, the TSI is not de-initialized + } + @endcode +* @param instance The TSI module instance. +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_DeInit(uint32_t instance); + +/*! +* @brief Enables/disables one electrode of the TSI module. +* +* Function must be called for each used electrodes after initialization of TSI driver. +* + @code + // On the TSI instance 0, enable electrode with index 5 + if(TSI_DRV_EnableElectrode(0, 5, TRUE) != kStatus_TSI_Success) + { + // Error, the TSI 5'th electrode is not enabled + } + @endcode +* @param instance The TSI module instance. +* @param channel Index of TSI channel. +* @param enable TRUE - for channel enable, FALSE for disable. +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_EnableElectrode(uint32_t instance, const uint32_t channel, const bool enable); + +/*! +* @brief Returns a mask of the enabled electrodes of the TSI module. +* +* The function returns the mask of the enabled electrodes of the current mode. +* + @code + uint32_t enabledElectrodeMask; + enabledElectrodeMask = TSI_DRV_GetEnabledElectrodes(0); + @endcode +* @param instance The TSI module instance. +* @return Mask of enabled electrodes for current mode. +*/ +uint32_t TSI_DRV_GetEnabledElectrodes(uint32_t instance); + +/*! +* @brief Starts the measure cycle of the enabled electrodes. +* +* The function is non blocking. Therefore, the results can be obtained after the driver completes the measure cycle. +* The end of the measure cycle can be checked by pooling the @ref TSI_DRV_GetStatus function or wait for registered callback function by using the +* @ref TSI_DRV_SetCallBackFunc or @ref TSI_DRV_Init. +* + @code + // Example of the pooling style of use of TSI_DRV_Measure() function + if(TSI_DRV_Measure(0) != kStatus_TSI_Success) + { + // Error, the TSI 5'th electrode is not enabled + } + + while(TSI_DRV_GetStatus(0) != kStatus_TSI_Initialized) + { + // Do something useful - don't waste the CPU cycle time + } + + @endcode +* @param instance The TSI module instance. +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_Measure(uint32_t instance); + +/*! +* @brief Starts the measure cycle of the enabled electrodes in blocking mode. +* +* This function is blocking. Therefore, after the function call, the result of measured electrodes +* is available and can be obtained by calling the @ref TSI_DRV_GetCounter function. +* + @code + // Example of the TSI_DRV_Measure() function pooling style + if(TSI_DRV_MeasureBlocking(0) != kStatus_TSI_Success) + { + // Error, the TSI 5'th electrode is not enabled + }else + { + // Get the result by TSI_DRV_GetCounter function + } + @endcode +* @param instance The TSI module instance. +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_MeasureBlocking(uint32_t instance); + +/*! +* @brief Aborts the measure cycle in non standard use of the driver. +* +* This function aborts the running measure cycle. It is designed for +* unexpected situations and not targeted for standard use. +* + @code + // Start measure by @ref TSI_DRV_Measure() function + if(TSI_DRV_Measure(0) != kStatus_TSI_Success) + { + // Error, the TSI 5'th electrode is not enabled + } + + if(isNeededAbort) // I need abort measure from any application reason + { + TSI_DRV_AbortMeasure(0); + } + + @endcode +* @param instance The TSI module instance. +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_AbortMeasure(uint32_t instance); + +/*! +* @brief Returns the last measured value. +* +* This function returns the last measured value in the previous measure cycle. +* The data is buffered inside the driver. +* + @code + // Get the counter value from TSI instance 0 and 5th channel + + uint32_t result; + + if(TSI_DRV_GetCounter(0, 5, &result) != kStatus_TSI_Success) + { + // Error, the TSI 5'th electrode is not read + } + + @endcode +* @param instance The TSI module instance. +* @param channel The TSI electrode index. +* @param counter The pointer to 16 bit value where will be stored channel counter value. +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_GetCounter(uint32_t instance, const uint32_t channel, uint16_t * counter); + +/*! +* @brief Returns the current status of the driver. +* +* This function returns the current working status of the driver. +* + @code + // Get the current status of TSI driver + + tsi_status_t status; + + status = TSI_DRV_GetStatus(0); + + + @endcode +* @param instance The TSI module instance. +* @return An current status of the driver. +*/ +tsi_status_t TSI_DRV_GetStatus(uint32_t instance); + +/*! +* @brief Enters the low power mode of the TSI driver. +* +* This function switches the driver to low power mode and immediately enables the +* low power functionality of the TSI peripheral. Before calling this +* function, the low power mode must be configured - Enable the right electrode +* and recalibrate the low power mode to get the best performance for this mode. +* + @code + // Switch the driver to the low power mode + uint16_t signal; + + // The first time is needed to configure the low power mode configuration + + (void)TSI_DRV_ChangeMode(0, tsi_OpModeLowPower); // I don't check the result because I believe in. + // Enable the right one electrode for low power AKE up operation + (void)TSI_DRV_EnableElectrode(0, 5, true); + // Recalibrate the mode to get the best performance for this one electrode + (void)TSI_DRV_Recalibrate(0, &signal); + + if(TSI_DRV_EnableLowPower(0) != kStatus_TSI_Success) + { + // Error, the TSI driver can't go to low power mode + } + + + @endcode +* @param instance The TSI module instance. +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_EnableLowPower(uint32_t instance); + +/*! +* @brief This function returns back the TSI driver from the low power to standard operation +* +* Function switch the driver back form low power mode and it can immediately change +* the operation mode to any other or keep the driver in low power +* configuration, to be able go back to low power state. +* + @code + // Switch the driver from the low power mode + + if(TSI_DRV_DisableLowPower(0, tsi_OpModeNormal) != kStatus_TSI_Success) + { + // Error, the TSI driver can't go from low power mode + } + + + @endcode +* @param instance The TSI module instance. +* @param mode The new operation mode request +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_DisableLowPower(uint32_t instance, const tsi_modes_t mode); + +/*! +* @brief Automatically recalibrates all important TSI settings. +* +* This function forces the driver to start the recalibration procedure +* for the current operation mode to get the best possible TSI hardware settings. +* The computed setting is stored into the operation mode data and can be +* loaded and saved by the @ref TSI_DRV_LoadConfiguration or the @ref TSI_DRV_SaveConfiguration +* functions. +* +* @warning The function could take more time to return +* and is blocking. +* + @code + // Recalibrate current mode + uint16_t signal; + + // Recalibrate the mode to get the best performance for this one electrode + + if(TSI_DRV_Recalibrate(0, &signal) != kStatus_TSI_Success) + { + // Error, the TSI driver can't recalibrate this mode + } + + + @endcode +* @param instance The TSI module instance. +* @param lowestSignal The pointer to variable where will be store the lowest signal of all electrodes +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_Recalibrate(uint32_t instance, uint32_t * lowestSignal); + +/*! +* @brief Sets the callback function that is called when the measure cycle ends. +* +* This function sets up or clears, (parameter pFuncCallBack = NULL), the callback function pointer +* which is called after each measure cycle ends. The user can also set the custom user data, +* that is handled by the parameter to a call back function. One function can be called by more sources. +* + @code + // Clear previous call back function + + if(TSI_DRV_SetCallBackFunc(0, NULL, NULL) != kStatus_TSI_Success) + { + // Error, the TSI driver can't set up the call back function at the moment + } + + // Set new call back function + + if(TSI_DRV_SetCallBackFunc(0, myFunction, (void*)0x12345678) != kStatus_TSI_Success) + { + // Error, the TSI driver can't set up the call back function at the moment + } + + + @endcode +* @param instance The TSI module instance. +* @param pFuncCallBack The pointer to application call back function +* @param usrData The user data pointer +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_SetCallBackFunc(uint32_t instance, const tsi_callback_t pFuncCallBack, void * usrData); + +/*! +* @brief Changes the current working operation mode. +* +* This function changes the working operation mode of the driver. +* + @code + // Change operation mode to low power + + if(TSI_DRV_ChangeMode(0, tsi_OpModeLowPower) != kStatus_TSI_Success) + { + // Error, the TSI driver can't change the operation mode into low power + } + + @endcode +* @param instance The TSI module instance. +* @param mode The requested new operation mode +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_ChangeMode(uint32_t instance, const tsi_modes_t mode); + +/*! +* @brief Returns the current working operation mode. +* +* This function returns the current working operation mode of the driver. +* + @code + // Gets current operation mode of TSI driver + tsi_modes_t mode; + + mode = TSI_DRV_GetMode(0); + + @endcode +* @param instance The TSI module instance. +* @return An current operation mode of TSI driver. +*/ +tsi_modes_t TSI_DRV_GetMode(uint32_t instance); + +/*! +* @brief Loads the new configuration into a specific mode. +* +* This function loads the new configuration into a specific mode. +* This can be used when the calibrated data are stored in any NVM +* to load after startup of the MCU to avoid run recalibration that takes +* more time. +* + @code + // Load operation mode configuration + + extern const tsi_operation_mode_t * myTsiNvmLowPowerConfiguration; + + if(TSI_DRV_LoadConfiguration(0, tsi_OpModeLowPower, myTsiNvmLowPowerConfiguration) != kStatus_TSI_Success) + { + // Error, the TSI driver can't load the configuration + } + + @endcode +* @param instance The TSI module instance. +* @param mode The requested new operation mode +* @param operationMode The pointer to storage place of the configuration that should be loaded +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_LoadConfiguration(uint32_t instance, const tsi_modes_t mode, const tsi_operation_mode_t * operationMode); + +/*! +* @brief Saves the TSI driver configuration for a specific mode. +* +* This function saves the configuration of a specific mode. +* This can be used when the calibrated data should be stored in any backup memory +* to load after the start of the MCU to avoid running the recalibration that takes +* more time. +* + @code + // Save operation mode configuration + + extern tsi_operation_mode_t myTsiNvmLowPowerConfiguration; + + if(TSI_DRV_SaveConfiguration(0, tsi_OpModeLowPower, &myTsiNvmLowPowerConfiguration) != kStatus_TSI_Success) + { + // Error, the TSI driver can't save the configuration + } + + @endcode +* @param instance The TSI module instance. +* @param mode The requested new operation mode +* @param operationMode The pointer to storage place of the configuration that should be save +* @return An error code or kStatus_TSI_Success. +*/ +tsi_status_t TSI_DRV_SaveConfiguration(uint32_t instance, const tsi_modes_t mode, tsi_operation_mode_t * operationMode); +/* @} */ + +/*! + * @name Interrupt + * @{ + */ + + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif +#endif /* __FSL_TSI_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_uart_dma_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_uart_dma_driver.h new file mode 100755 index 0000000..3566c65 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_uart_dma_driver.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_UART_DMA_DRIVER_H__ +#define __FSL_UART_DMA_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_os_abstraction.h" +#include "fsl_uart_hal.h" +#include "fsl_dma_driver.h" + +#if FSL_FEATURE_SOC_DMA_COUNT && FSL_FEATURE_SOC_UART_COUNT + +/*! + * @addtogroup uart_driver + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for UART instances. */ +extern UART_Type * const g_uartBase[UART_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @brief Runtime state structure for UART driver with DMA. + */ +typedef struct UartDmaState { + volatile bool isTxBusy; /*!< True if there is an active transmit. */ + volatile bool isRxBusy; /*!< True if there is an active receive. */ + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its transmit. */ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its receive. */ + dma_channel_t dmaUartTx; /*!< DMA channel used for send. */ + dma_channel_t dmaUartRx; /*!< DMA channel used for receive. */ +} uart_dma_state_t; + +/*! + * @brief User configuration structure for the UART driver. + * + * Use an instance of this structure with the UART_DRV_Init()function. This enables configuration of the + * most common settings of the UART peripheral with a single function call. Settings include: + * UART baud rate, UART parity mode: disabled (default), or even or odd, the number of stop bits, and + * the number of bits per data word. + */ +typedef struct UartDmaUserConfig { + uint32_t baudRate; /*!< UART baud rate*/ + uart_parity_mode_t parityMode; /*!< parity mode, disabled (default), even, odd */ + uart_stop_bit_count_t stopBitCount; /*!< number of stop bits, 1 stop bit (default) or 2 stop bits */ + uart_bit_count_per_char_t bitCountPerChar; /*!< number of bits, 8-bit (default) or 9-bit in + a word (up to 10-bits in some UART instances) */ +} uart_dma_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name UART DMA Driver + * @{ + */ + +/*! + * @brief Initializes a UART instance to work with the DMA. + * + * This function initializes the run-time state structure to keep track of the on-going + * transfers, un-gates the clock to the UART module, initializes the module + * to user-defined settings and default settings, configures the IRQ state structure and enables + * the module-level interrupt to the core, and the UART module transmitter and receiver. + * This example shows how to set up the uart_dma_state_t and the + * uart_user_config_t parameters and how to call the UART_DRV_DmaInit function by passing + * in these parameters: + @code + uart_user_config_t uartConfig; + uartConfig.baudRate = 9600; + uartConfig.bitCountPerChar = kUart8BitsPerChar; + uartConfig.parityMode = kUartParityDisabled; + uartConfig.stopBitCount = kUartOneStopBit; + uart_dma_state_t uartDmaState; + UART_DRV_DmaInit(instance, &uartDmaState, &uartConfig); + @endcode + * + * @param instance The UART instance number. + * @param uartDmaStatePtr A pointer to the UART driver state structure memory. The user + * passes in the memory for the run-time state structure. The UART driver + * populates the members. This run-time state structure keeps track of the + * current transfer in progress. + * @param uartUserConfig The user configuration structure of type uart_user_config_t. The user + * populates the members of this structure and passes the pointer of this structure + * to this function. + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_DmaInit(uint32_t instance, uart_dma_state_t * uartDmaStatePtr, + const uart_dma_user_config_t * uartUserConfig); +/*! + * @brief Shuts down the UART. + * + * This function disables the UART-DMA trigger and disables the transmitter and receiver. + * + * @param instance The UART instance number. + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_DmaDeinit(uint32_t instance); + +/*! + * @brief Sends (transmits) data out through the UART-DMA module using a blocking method. + * + * @param instance The UART instance number. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_DmaSendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the UART-DMA module using a non-blocking method. + * + * @param instance The UART module base address. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_DmaSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +/*! + * @brief Returns whether the previous UART-DMA transmit has finished. + * + * @param instance The UART module base address. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes that + * are remaining in the active transfer. + * @return An error code or kStatus_UART_Success. + * @retval kStatus_UART_Success The transmit has completed successfully. + * @retval kStatus_UART_TxBusy The transmit is still in progress. @a bytesTransmitted is + * filled with the number of bytes which are transmitted up to that point. + */ +uart_status_t UART_DRV_DmaGetTransmitStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates a non-blocking UART-DMA transmission early. + * + * @param instance The UART module base address. + * @return An error code or kStatus_UART_Success. + * @retval kStatus_UART_Success The transmit was successful. + * @retval kStatus_UART_NoTransmitInProgress No transmission is currently in progress. + */ +uart_status_t UART_DRV_DmaAbortSendingData(uint32_t instance); + +/*! + * @brief Gets (receives) data from the UART-DMA module using a blocking method. + * + * @param instance The UART module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_DmaReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout); +/*! + * @brief Gets (receives) data from the UART-DMA module using a non-blocking method. + * + * @param instance The UART module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_DmaReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize); + +/*! + * @brief Returns whether the previous UART-DMA receive is complete. + * + * @param instance The UART module base address. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes which + * still need to be received in the active transfer. + * @return An error code or kStatus_UART_Success. + * @retval kStatus_UART_Success The receive has completed successfully. + * @retval kStatus_UART_RxBusy The receive is still in progress. @a bytesReceived is + * filled with the number of bytes which are received up to that point. + */ +uart_status_t UART_DRV_DmaGetReceiveStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates a non-blocking UART-DMA receive early. + * + * @param instance The UART module base address. + * @return An error code or kStatus_UART_Success. + * @retval kStatus_UART_Success The receive was successful. + * @retval kStatus_UART_NoTransmitInProgress No receive is currently in progress. + */ +uart_status_t UART_DRV_DmaAbortReceivingData(uint32_t instance); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* FSL_FEATURE_SOC_DMA_COUNT && FSL_FEATURE_SOC_UART_COUNT */ +#endif /* __FSL_UART_DMA_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_uart_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_uart_driver.h new file mode 100755 index 0000000..0cbff9b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_uart_driver.h @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_UART_DRIVER_H__ +#define __FSL_UART_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_os_abstraction.h" +#include "fsl_uart_hal.h" + +/*! + * @addtogroup uart_driver + * @{ + */ + +/*! + * @file + * + * Some devices count the UART instances with LPUART(e.g, KL27) or UART0(e.g, + * KL25) together. However, they are different IPs with separate drivers: + * LPSCI for UART0, LPUART for LPUART. In such cases, this UART driver + * only works with specific UART instances. + * + * For example, in KL27, there is LPUART0, LPUART1 and UART2. For LPUART0 and + * LPUART1, use the LPUART driver. For UART2, use this driver and + * pass in 2 as the instance number. 0 and 1 are not valid. + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for UART instances. */ +extern UART_Type * const g_uartBase[UART_INSTANCE_COUNT]; + +/*! @brief Table to save UART IRQ enumeration numbers defined in the CMSIS header file */ +extern const IRQn_Type g_uartRxTxIrqId[UART_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief UART receive callback function type */ +typedef void (* uart_rx_callback_t)(uint32_t instance, void * uartState); + +/*! @brief UART transmit callback function type */ +typedef void (* uart_tx_callback_t)(uint32_t instance, void * uartState); + +/*! + * @brief Runtime state of the UART driver. + * + * This structure holds data that are used by the UART peripheral driver to + * communicate between the transfer function and the interrupt handler. The + * interrupt handler also uses this information to keep track of its progress. + * The user passes in the memory for the run-time state structure and the + * UART driver fills out the members. + */ +typedef struct UartState { + uint8_t txFifoEntryCount; /*!< Number of data word entries in TX FIFO. */ + const uint8_t * txBuff; /*!< The buffer of data being sent.*/ + uint8_t * rxBuff; /*!< The buffer of received data. */ + volatile size_t txSize; /*!< The remaining number of bytes to be transmitted. */ + volatile size_t rxSize; /*!< The remaining number of bytes to be received. */ + volatile bool isTxBusy; /*!< True if there is an active transmit. */ + volatile bool isRxBusy; /*!< True if there is an active receive. */ + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its TX business. */ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its RX business. */ + uart_rx_callback_t rxCallback; /*!< Callback to invoke after receiving byte.*/ + void * rxCallbackParam; /*!< Receive callback parameter pointer.*/ + uart_tx_callback_t txCallback; /*!< Callback to invoke after transmitting byte.*/ + void * txCallbackParam; /*!< Transmit callback parameter pointer.*/ +} uart_state_t; + +/*! + * @brief User configuration structure for the UART driver. + * + * Use an instance of this structure with the UART_DRV_Init()function. This enables configuration of the + * most common settings of the UART peripheral with a single function call. Settings include: + * UART baud rate, UART parity mode: disabled (default), or even or odd, the number of stop bits, and + * the number of bits per data word. + * @internal gui name="UART configuration" id="Configuration" + */ +typedef struct UartUserConfig { + uint32_t baudRate; /*!< UART baud rate @internal gui name="Baud rate" id="BaudRate" */ + uart_parity_mode_t parityMode; /*!< parity mode, disabled (default), even, odd @internal gui name="Parity mode" id="Parity" */ + uart_stop_bit_count_t stopBitCount; /*!< number of stop bits, 1 stop bit (default) or 2 stop bits @internal gui name="Stop bits" id="StopBits" */ + uart_bit_count_per_char_t bitCountPerChar; /*!< number of bits, 8-bit (default) or 9-bit in + a word (up to 10-bits in some UART instances) @internal gui name="Bits per char" id="DataBits" */ +} uart_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name UART Interrupt Driver + * @{ + */ + +/*! + * @brief Initializes an UART instance for operation. + * + * This function initializes the run-time state structure to keep track of the on-going + * transfers, un-gates the clock to the UART module, initializes the module + * to user-defined settings and default settings, configures the IRQ state structure, and enables + * the module-level interrupt to the core, and the UART module transmitter and receiver. + * This example shows how to set up the uart_state_t and the + * uart_user_config_t parameters and how to call the UART_DRV_Init function by passing + * in these parameters: + @code + uart_user_config_t uartConfig; + uartConfig.baudRate = 9600; + uartConfig.bitCountPerChar = kUart8BitsPerChar; + uartConfig.parityMode = kUartParityDisabled; + uartConfig.stopBitCount = kUartOneStopBit; + uart_state_t uartState; + UART_DRV_Init(instance, &uartState, &uartConfig); + @endcode + * + * @param instance The UART instance number. + * @param uartStatePtr A pointer to the UART driver state structure memory. The user + * passes in the memory for this run-time state structure. The UART driver + * populates the members. The run-time state structure keeps track of the + * current transfer in progress. + * @param uartUserConfig The user configuration structure of type uart_user_config_t. The user + * populates the members of this structure and passes the pointer of this structure + * to this function. + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_Init(uint32_t instance, uart_state_t * uartStatePtr, + const uart_user_config_t * uartUserConfig); + +/*! + * @brief Shuts down the UART by disabling interrupts and the transmitter/receiver. + * + * This function disables the UART interrupts, the transmitter and receiver, and + * flushes the FIFOs (for modules that support FIFOs). + * + * @param instance The UART instance number. + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_Deinit(uint32_t instance); + +/*! + * @brief Installs the callback function for the UART receive. + * + * @note After a callback is installed, it bypasses part of the UART IRQHandler logic. + * So, the callback needs to handle the indexes of rxBuff, rxSize. + * + * @param instance The UART instance number. + * @param function The UART receive callback function. + * @param rxBuff The receive buffer used inside IRQHandler. This buffer must be kept as long as the callback is alive. + * @param callbackParam The UART receive callback parameter pointer. + * @param alwaysEnableRxIrq Whether always enable receive IRQ or not. + * @return Former UART receive callback function pointer. + */ +uart_rx_callback_t UART_DRV_InstallRxCallback(uint32_t instance, + uart_rx_callback_t function, + uint8_t * rxBuff, + void * callbackParam, + bool alwaysEnableRxIrq); +/*! + * @brief Installs the callback function for the UART transmit. + * + * @note After a callback is installed, it bypasses part of the UART IRQHandler logic. + * Therefore, the callback needs to handle the txBuff and txSize indexes. + * + * @param instance The UART instance number. + * @param function The UART transmit callback function. + * @param txBuff The transmit buffer used inside IRQHandler. This buffer must be kept as long as the callback is alive. + * @param callbackParam The UART transmit callback parameter pointer. + * @return Former UART transmit callback function pointer. + */ +uart_tx_callback_t UART_DRV_InstallTxCallback(uint32_t instance, + uart_tx_callback_t function, + uint8_t * txBuff, + void * callbackParam); + +/*! + * @brief Sends (transmits) data out through the UART module using a blocking method. + * + * A blocking (also known as synchronous) function means that the function does not return until + * the transmit is complete. This blocking function is used to send data through the UART port. + * + * @param instance The UART instance number. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_SendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the UART module using a non-blocking method. + * + * A non-blocking (also known as synchronous) function means that the function returns + * immediately after initiating the transmit function. The application has to get the + * transmit status to see when the transmit is complete. In other words, after calling non-blocking + * (asynchronous) send function, the application must get the transmit status to check if transmit + * is complete. + * The asynchronous method of transmitting and receiving allows the UART to perform a full duplex + * operation (simultaneously transmit and receive). + * + * @param instance The UART module base address. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_SendData(uint32_t instance, const uint8_t * txBuff, uint32_t txSize); + +/*! + * @brief Returns whether the previous UART transmit has finished. + * + * When performing an a-sync transmit, call this function to ascertain the state of the + * current transmission: in progress (or busy) or complete (success). If the + * transmission is still in progress, the user can obtain the number of words that have been + * transferred. + * + * @param instance The UART module base address. + * @param bytesRemaining A pointer to a value that is filled in with the number of bytes that + * are remaining in the active transfer. + * @return The transmit status. + * @retval kStatus_UART_Success The transmit has completed successfully. + * @retval kStatus_UART_TxBusy The transmit is still in progress. @a bytesTransmitted is + * filled with the number of bytes which are transmitted up to that point. + */ +uart_status_t UART_DRV_GetTransmitStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates an asynchronous UART transmission early. + * + * During an a-sync UART transmission, the user can terminate the transmission early + * if the transmission is still in progress. + * + * @param instance The UART module base address. + * @return Whether the aborting success or not. + * @retval kStatus_UART_Success The transmit was successful. + * @retval kStatus_UART_NoTransmitInProgress No transmission is currently in progress. + */ +uart_status_t UART_DRV_AbortSendingData(uint32_t instance); + +/*! + * @brief Gets (receives) data from the UART module using a blocking method. + * + * A blocking (also known as synchronous) function means that the function does not return until + * the receive is complete. This blocking function sends data through the UART port. + * + * @param instance The UART module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_ReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout); + +/*! + * @brief Gets (receives) data from the UART module using a non-blocking method. + * + * A non-blocking (also known as synchronous) function means that the function returns + * immediately after initiating the receive function. The application has to get the + * receive status to see when the receive is complete. In other words, after calling non-blocking + * (asynchronous) get function, the application must get the receive status to check if receive + * is completed or not. + * The asynchronous method of transmitting and receiving allows the UART to perform a full duplex + * operation (simultaneously transmit and receive). + * + * @param instance The UART module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_ReceiveData(uint32_t instance, uint8_t * rxBuff, uint32_t rxSize); + +/*! + * @brief Returns whether the previous UART receive is complete. + * + * When performing an a-sync receive, call this function to find out the state of the + * current receive progress: in progress (or busy) or complete (success). In addition, if the + * receive is still in progress, the user can obtain the number of words that have been + * currently received. + * + * @param instance The UART module base address. + * @param bytesRemaining A pointer to a value that is filled in with the number of bytes which + * still need to be received in the active transfer. + * @return The receive status. + * @retval kStatus_UART_Success The receive has completed successfully. + * @retval kStatus_UART_RxBusy The receive is still in progress. @a bytesReceived is + * filled with the number of bytes which are received up to that point. + */ +uart_status_t UART_DRV_GetReceiveStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates an asynchronous UART receive early. + * + * During an a-sync UART receive, the user can terminate the receive early + * if the receive is still in progress. + * + * @param instance The UART module base address. + * @return Whether the aborting success or not. + * @retval kStatus_UART_Success The receive was successful. + * @retval kStatus_UART_NoTransmitInProgress No receive is currently in progress. + */ +uart_status_t UART_DRV_AbortReceivingData(uint32_t instance); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __FSL_UART_DRIVER_H__*/ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_uart_edma_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_uart_edma_driver.h new file mode 100755 index 0000000..408259d --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_uart_edma_driver.h @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_UART_EDMA_DRIVER_H__ +#define __FSL_UART_EDMA_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_os_abstraction.h" +#include "fsl_uart_hal.h" +#include "fsl_edma_driver.h" + +#if FSL_FEATURE_SOC_EDMA_COUNT && FSL_FEATURE_SOC_UART_COUNT + +/*! + * @addtogroup uart_driver + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for UART instances. */ +extern UART_Type * const g_uartBase[UART_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @brief Runtime state structure for UART driver with EDMA. + */ +typedef struct UartEdmaState { + volatile bool isTxBusy; /*!< True if there is an active transmit. */ + volatile bool isRxBusy; /*!< True if there is an active receive. */ + volatile bool isTxBlocking; /*!< True if transmit is blocking transaction. */ + volatile bool isRxBlocking; /*!< True if receive is blocking transaction. */ + semaphore_t txIrqSync; /*!< Used to wait for ISR to complete its TX business. */ + semaphore_t rxIrqSync; /*!< Used to wait for ISR to complete its RX business. */ + edma_chn_state_t edmaUartTx; /*!< Structure definition for the EDMA channel */ + edma_chn_state_t edmaUartRx; /*!< Structure definition for the EDMA channel */ +} uart_edma_state_t; + +/*! + * @brief User configuration structure for the UART driver. + * + * Use an instance of this structure with the UART_DRV_Init()function. This enables configuration of the + * most common settings of the UART peripheral with a single function call. Settings include: + * UART baud rate, UART parity mode: disabled (default), or even or odd, the number of stop bits, and + * the number of bits per data word. + */ +typedef struct UartEdmaUserConfig { + uint32_t baudRate; /*!< UART baud rate*/ + uart_parity_mode_t parityMode; /*!< parity mode, disabled (default), even, odd */ + uart_stop_bit_count_t stopBitCount; /*!< number of stop bits, 1 stop bit (default) or 2 stop bits */ + uart_bit_count_per_char_t bitCountPerChar; /*!< number of bits, 8-bit (default) or 9-bit in + a word (up to 10-bits in some UART instances) */ +} uart_edma_user_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name UART EDMA Driver + * @{ + */ + +/*! + * @brief Initializes an UART instance to work with EDMA. + * + * This function initializes the run-time state structure to keep track of the on-going + * transfers, un-gates the clock to the UART module, initializes the module + * to user-defined settings and default settings, configures the IRQ state structure and enables + * the module-level interrupt to the core, and enables the UART module transmitter and receiver. + * This example shows how to set up the uart_edma_state_t and the + * uart_user_config_t parameters and how to call the UART_DRV_EdmaInit function by passing + * in these parameters: + @code + uart_user_config_t uartConfig; + uartConfig.baudRate = 9600; + uartConfig.bitCountPerChar = kUart8BitsPerChar; + uartConfig.parityMode = kUartParityDisabled; + uartConfig.stopBitCount = kUartOneStopBit; + uart_edma_state_t uartEdmaState; + UART_DRV_EdmaInit(instance, &uartEdmaState, &uartConfig); + @endcode + * + * @param instance The UART instance number. + * @param uartEdmaStatePtr A pointer to the UART driver state structure memory. The user + * passes in the memory for the run-time state structure. The UART driver + * populates the members. This run-time state structure keeps track of the + * current transfer in progress. + * @param uartUserConfig The user configuration structure of type uart_user_config_t. The user + * populates the members of this structure and passes the pointer of this structure + * to this function. + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_EdmaInit(uint32_t instance, uart_edma_state_t * uartEdmaStatePtr, + const uart_edma_user_config_t * uartUserConfig); +/*! + * @brief Shuts down the UART. + * + * This function disables the UART-EDMA trigger and disables the transmitter and receiver. + * + * @param instance The UART instance number. + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_EdmaDeinit(uint32_t instance); + +/*! + * @brief Sends (transmits) data out through the UART-EDMA module using a blocking method. + * + * @param instance The UART instance number. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_EdmaSendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout); + +/*! + * @brief Sends (transmits) data through the UART-EDMA module using a non-blocking method. + * + * @param instance The UART module base address. + * @param txBuff A pointer to the source buffer containing 8-bit data chars to send. + * @param txSize The number of bytes to send. + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_EdmaSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +/*! + * @brief Returns whether the previous UART-EDMA transmit has finished. + * + * @param instance The UART module base address. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes that + * are remaining in the active transfer. + * @return The transmit status. + * @retval kStatus_UART_Success The transmit has completed successfully. + * @retval kStatus_UART_TxBusy The transmit is still in progress. @a bytesTransmitted is + * filled with the number of bytes which are transmitted up to that point. + */ +uart_status_t UART_DRV_EdmaGetTransmitStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates a non-blocking UART-EDMA transmission early. + * + * @param instance The UART module base address. + * @return Whether the aborting success or not. + * @retval kStatus_UART_Success The transmit was successful. + * @retval kStatus_UART_NoTransmitInProgress No transmission is currently in progress. + */ +uart_status_t UART_DRV_EdmaAbortSendingData(uint32_t instance); + +/*! + * @brief Gets (receives) data from the UART-EDMA module using a blocking method. + * + * @param instance The UART module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @param timeout A timeout value for RTOS abstraction sync control in milliseconds (ms). + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_EdmaReceiveDataBlocking(uint32_t instance, uint8_t * rxBuff, + uint32_t rxSize, uint32_t timeout); +/*! + * @brief Gets (receives) data from the UART-EDMA module using a non-blocking method. + * + * @param instance The UART module base address. + * @param rxBuff A pointer to the buffer containing 8-bit read data chars received. + * @param rxSize The number of bytes to receive. + * @return An error code or kStatus_UART_Success. + */ +uart_status_t UART_DRV_EdmaReceiveData(uint32_t instance, uint8_t * rxBuff, uint32_t rxSize); + +/*! + * @brief Returns whether the previous UART-EDMA receive is complete. + * + * @param instance The UART module base address. + * @param bytesRemaining A pointer to a value that is populated with the number of bytes which + * still need to be received in the active transfer. + * @return The receive status. + * @retval kStatus_UART_Success The receive has completed successfully. + * @retval kStatus_UART_RxBusy The receive is still in progress. @a bytesReceived is + * filled with the number of bytes which are received up to that point. + */ +uart_status_t UART_DRV_EdmaGetReceiveStatus(uint32_t instance, uint32_t * bytesRemaining); + +/*! + * @brief Terminates a non-blocking UART-EDMA receive early. + * + * @param instance The UART module base address. + * @return Whether the aborting success or not. + * @retval kStatus_UART_Success The receive was successful. + * @retval kStatus_UART_NoTransmitInProgress No receive is currently in progress. + */ +uart_status_t UART_DRV_EdmaAbortReceivingData(uint32_t instance); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif +#endif /* __FSL_UART_EDMA_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_vref_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_vref_driver.h new file mode 100755 index 0000000..3daba3f --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_vref_driver.h @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __FSL_VREF_DRIVER_H__ +#define __FSL_VREF_DRIVER_H__ + +#include "fsl_vref_hal.h" +#if FSL_FEATURE_SOC_VREF_COUNT + +/*! + * @addtogroup vref_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for VREF instances. */ +extern VREF_Type * const g_vrefBase[]; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the VREF module. + * + * @param instance VREF instance. + * @param userConfigPtr Pointer to the initialization structure. See the "vref_user_config_t". + * + * @return Execution status. + */ +vref_status_t VREF_DRV_Init(uint32_t instance, const vref_user_config_t *userConfigPtr); + +/*! + * @brief De-initializes the VREF module. + * + * @param instance VREF instance. + * @return Execution status. + */ +vref_status_t VREF_DRV_Deinit(uint32_t instance); + +#if FSL_FEATURE_VREF_HAS_CHOP_OSC +/*! + * @brief Enables or disables the chop oscillator. + * + * When set, internal chopping operation is enabled and the internal analog offset is + * be minimized. + * This bit is set during factory trimming of the VREF voltage and should be written to 1 + * to achieve the performance stated in the data sheet. + * + * @param instance VREF instance. + * @param enable Enables or disables chop oscillator + * - true : Chop oscillator enable + * - false: Chop oscillator disable + * + * @return Execution status. + */ +static inline vref_status_t VREF_DRV_SetChopOsc(uint32_t instance, bool enable) +{ + assert(instance < VREF_INSTANCE_COUNT); + VREF_Type * base = g_vrefBase[instance]; + + VREF_HAL_SetChopOscillatorCmd(base, enable); + + return kStatus_VREF_Success; +} +#endif + +/*! + * @brief Sets the TRIM bits value. + * + * These bits change the resulting VREF by approximately +/- 0.5 mV for each step. + * For minimum and maximum voltage reference output values, see the Data Sheet for this chip. + * + * @param instance VREF instance. + * @param trimValue TRIM bits value. + * + * @return Execution status. + */ +vref_status_t VREF_DRV_SetTrimValue(uint32_t instance, uint8_t trimValue); + +/*! + * @brief Get TRIM bits value was set. + * + * @param instance VREF instance. + * + * @return Actual TRIM bits value. + */ +static inline uint8_t VREF_DRV_GetTrimValue(uint32_t instance) +{ + assert(instance < VREF_INSTANCE_COUNT); + VREF_Type * base = g_vrefBase[instance]; + + return VREF_HAL_GetTrimVal(base); +} + +/*! + * @brief Enables or disables the regulator. + * + * This bit is used to enable the internal 1.75 V regulator to produce a constant internal voltage + * supply to reduce the sensitivity to the external supply noise and variation. + * To keep the regulator enabled in very low power modes, see + * the Chip Configuration details for a description. + * This bit is set during factory trimming of the VREF voltage and should be written to 1 + * to achieve the performance stated in the data sheet. + * + * @param instance VREF instance. + * @param enable Enables or disables internal regulator + * - true : Internal regulator enable + * - false: Internal regulator disable + * + * @return Execution status. + */ +static inline vref_status_t VREF_DRV_SetRegulator(uint32_t instance, bool enable) +{ + assert(instance < VREF_INSTANCE_COUNT); + VREF_Type * base = g_vrefBase[instance]; + + VREF_HAL_SetInternalRegulatorCmd(base, enable); + + return kStatus_VREF_Success; +} + +#if FSL_FEATURE_VREF_HAS_COMPENSATION +/*! + * @brief Enables or disables the second order curvature compensation. + * + * This bit is set during the factory trimming of the VREF voltage and should be written to 1 + * to achieve the performance stated in the data sheet. + * + * @param instance VREF instance. + * @param enable Enables or disables second order curvature compensation. + * - true: Second order curvature compensation enabled + * - false: Second order curvature compensation disabled + * + * @return Execution status. + */ +static inline vref_status_t VREF_DRV_SetIcomp(uint32_t instance, bool enable) +{ + assert(instance < VREF_INSTANCE_COUNT); + VREF_Type * base = g_vrefBase[instance]; + + VREF_HAL_SetSecondOrderCurvatureCompensationCmd(base, enable); + + return kStatus_VREF_Success; +} +#endif + +/*! + * @brief Sets the buffer mode. + * + * These bits select the buffer modes for the Voltage Reference module. + * - Buffer mode = 0x00: The internal VREF bandgap is enabled to generate an accurate 1.2 V output + * that can be trimmed with the TRM register TRIM[5:0] bit field. + * The bandgap requires some time for startup and stabilization. SC[VREFST] can be monitored + * to determine if the stabilization and startup is complete. + * - Buffer mode = 0x01: The internal VREF bandgap is on. The high power buffer is enabled + * to generate a buffered 1.2 V voltage to VREF_OUT. + * - Buffer mode = 0x02: The internal VREF bandgap is on. The high power buffer is enabled + * to generate a buffered 1.2 V voltage to VREF_OUT. + + * VREF_OUT generated by high and low buffer modes can also be used as a reference + * to internal analog peripherals such as an ADC channel or analog comparator input. + * If those modes is entered from the standby mode, there is a delay before + * the buffer output is settled at the final value. A 100 nF capacitor is required to connect + * between the VREF_OUT pin and VSSA. + * + * @param instance VREF instance. + * @param bufferMode Buffer mode value. + * + * @return Execution status. + */ +static inline vref_status_t VREF_DRV_SetBufferMode(uint32_t instance, vref_buffer_mode_t bufferMode) +{ + assert(instance < VREF_INSTANCE_COUNT); + VREF_Type * base = g_vrefBase[instance]; + + VREF_HAL_SetBufferMode(base, bufferMode); + + return kStatus_VREF_Success; +} + +#if FSL_FEATURE_VREF_HAS_LOW_REFERENCE +/*! + * @brief Selects the voltage reference between the internal and external 1.2 V reference. + * + * @param instance VREF instance. + * @param ref Defines reference to be set. + * - kVrefReferenceInternal: Select internal reference + * - kVrefReferenceExternal: Select external reference + * + * @return Execution status. + */ + +static inline vref_status_t VREF_DRV_SetVoltageReference(uint32_t instance, vref_voltage_reference_t ref) +{ + assert(instance < VREF_INSTANCE_COUNT); + VREF_Type * base = g_vrefBase[instance]; + + VREF_HAL_SetVoltageReference(base, ref); + + return kStatus_VREF_Success; +} + +/*! + * @brief Enables or disables the VREFL (0.4 V) reference buffer. + * + * @param instance VREF instance. + * @param enable Enables or disables VREFL (0.4 V) reference buffer + * - true : Enable VREFL (0.4 V) reference buffer + * - false: Disable VREFL (0.4 V) reference buffer + * + * @return Execution status. + */ +static inline vref_status_t VREF_DRV_SetLowReference(uint32_t instance, bool enable) +{ + assert(instance < VREF_INSTANCE_COUNT); + VREF_Type * base = g_vrefBase[instance]; + + VREF_HAL_SetLowReference(base, enable); + + return kStatus_VREF_Success; +} + +/*! + * @brief Sets the trim value for low voltage reference. + * + * @param instance VREF instance. + * @param trimValue Value of trim register to set output low reference voltage (max 0x07 (3-bit)). + * + * @return Execution status. + */ +vref_status_t VREF_DRV_SetLowReferenceTrimVal(uint32_t instance, uint8_t trimValue); + +/*! + * @brief Reads the value of trim meaning output voltage. + * + * @param instance VREF instance. + * @return Three-bit value of trim setting. + */ +static inline uint8_t VREF_DRV_GetLowReferenceTrimVal(uint32_t instance) +{ + assert(instance < VREF_INSTANCE_COUNT); + VREF_Type * base = g_vrefBase[instance]; + + return VREF_HAL_GetLowReferenceTrimVal(base); +} +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif +#endif/* __FSL_VREF_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_wdog_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_wdog_driver.h new file mode 100755 index 0000000..bc3975f --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_wdog_driver.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_WDOG_DRIVER_H__ +#define __FSL_WDOG_DRIVER_H__ + +#include <assert.h> +#include <stdint.h> +#include <stdbool.h> +#include "fsl_wdog_hal.h" +#if FSL_FEATURE_SOC_WDOG_COUNT + +/*! + * @addtogroup wdog_driver + * @{ + */ +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for WDOG instances. */ +extern WDOG_Type * const g_wdogBase[]; + +/* Table to save WDOG IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_wdogIrqId[WDOG_INSTANCE_COUNT]; + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! + * @brief Data structure for Watchdog initialization + * + * This structure is used when initializing the WDOG during the wdog_init function call. + * It contains all WDOG configurations. + * @internal gui name="Common configuration" id="wdogCfg" + */ + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Watchdog Driver + * @{ + */ + + +/*! + * @brief Initializes the Watchdog. + * + * This function initializes the WDOG. When called, the WDOG + * runs according to the requirements of the configuration. + * + * @param userConfigPtr Watchdog user configure data structure, see #wdog_user_config_t. + * + */ +wdog_status_t WDOG_DRV_Init(const wdog_config_t* userConfigPtr); + +/*! + * @brief Shuts down the Watchdog. + * + * This function shuts down the WDOG. + * + */ +wdog_status_t WDOG_DRV_Deinit(void); + +/*! + * @brief Refreshes the Watchdog. + * + * This function feeds the WDOG. It sets the WDOG timer count to zero and + * should be called before the Watchdog timer times out. Otherwise, a reset is asserted. + * Enough time should be allowed for the + * refresh sequence to be detected by the Watchdog timer on the Watchdog clock. + * + */ +void WDOG_DRV_Refresh(void); + +/*! + * @brief Gets the Watchdog running status. + * + * This function gets the WDOG running status. + * + * @return watchdog running status, false means not running, true means running + */ +bool WDOG_DRV_IsRunning(void); + +/*! + * @brief Resets the MCU by the Watchdog. + * + * This function resets the MCU by using the WDOG. + * + */ +void WDOG_DRV_ResetSystem(void); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif +#endif /* __FSL_WDOG_H__*/ +/******************************************************************************* + * EOF + *******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/inc/fsl_xbar_driver.h b/KSDK_1.2.0/platform/drivers/inc/fsl_xbar_driver.h new file mode 100755 index 0000000..6438af9 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/inc/fsl_xbar_driver.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if !defined(__FSL_XBAR_DRIVER_H__) +#define __FSL_XBAR_DRIVER_H__ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_xbar_signals.h" +#include "fsl_xbar_hal.h" +#if FSL_FEATURE_SOC_XBAR_COUNT + +/*! + * @addtogroup xbar_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Table of base addresses for XBAR instances. */ +extern XBARA_Type * const g_xbaraBase[]; +#if !defined(FSL_FEATURE_XBAR_HAS_SINGLE_MODULE) +extern XBARB_Type * const g_xbarbBase[]; +#endif + +/*! @brief Table to save XBAR IRQ enumeration numbers defined in the CMSIS header file. */ +extern const IRQn_Type g_xbarIrqId[]; + +/*! + * @brief Defines the type of the user-defined callback function. + * + * A prototype for the callback function registered into the XBAR driver. + */ +typedef void (*xbar_callback_t)(void * param); + +/*! + * @brief Defines the XBAR DMA and interrupt configurations. + */ +/*! + * @brief Defines the XBAR DMA and interrupt configurations. + */ +typedef enum _xbar_ien_den_req +{ + kXbarReqDis = 0U, /*!< Interrupt and DMA are disabled. */ + kXbarReqIen = 1U, /*!< Interrupt enabled, DMA disabled. */ + kXbarReqDen = 2U /*!< DMA enabled, interrupt disabled. */ +} xbar_ien_den_req_t; + +/*! + * @brief Defines the configuration structure of the XBAR control register. + * + * This structure keeps the configuration of XBAR control register for one output. + * Control registers are available only for a few outputs. Not every XBAR module has + * control registers. + */ +typedef struct XbarControlConfig +{ + xbar_active_edge_t activeEdge; /*!< Active edge to be detected. */ + xbar_ien_den_req_t intDmaReq; /*!< Selects DMA/Interrupt request. */ +} xbar_control_config_t; + +/*! + * @brief Internal driver state information. + * + * The contents of this structure are internal to the driver and should not be + * modified by users. + */ +typedef struct XbarState +{ + xbar_callback_t userCallbackFunct[FSL_FEATURE_XBARA_INTERRUPT_COUNT]; /*!< Keep the user-defined callback function. */ + void * xbarCallbackParam[FSL_FEATURE_XBARA_INTERRUPT_COUNT]; /*!< XBAR callback parameter pointer.*/ +} xbar_state_t; + +/*! + * @brief Macro defines XBARA module number. + */ +#define XBARA_MODULE 0U + +/*! + * @brief Macro defines XBARB module number. + */ +#define XBARB_MODULE 1U + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the XBAR modules. + * + * This function initializes the XBAR module to a reset state. + * + * @param xbarStatePtr XBAR input signal. + * @return An error code or kStatus_XBAR_Success. + */ +xbar_status_t XBAR_DRV_Init(xbar_state_t * xbarStatePtr); + +/*! + * @brief De-initializes the XBAR module. + * + * This function clears all configurations and shuts down the XBAR by disabling interrupt + * and the clock signal to the modules. + */ +void XBAR_DRV_Deinit(void); + +/*! + * @brief Configures connection between the selected XBAR_IN[*] input and the XBAR_OUT[*] output signal. + * + * This function configures which XBAR input is connected to the selected XBAR output. + * If more than one XBAR module is available, only the inputs and outputs from the same module + * can be connected. + * + * Example: + @code + xbar_status_t status; + + // Configure connection between XBARA_OUT16(CMP0) output and XBARA_IN1(VDD) input. + status = XBARA_HAL_ConfigSignalConnection(kXbaraInputVDD, kXbaraOutputCMP0); + switch (status) + { + //... + } + @endcode + * + * @param input XBAR input signal. + * @param output XBAR output signal. + * @return An error code or kStatus_XBAR_Success. + */ +xbar_status_t XBAR_DRV_ConfigSignalConnection(xbar_input_signal_t input, xbar_output_signal_t output); + +/*! + * @brief Configures the XBAR control register. + * + * This function configures an XBAR control register. The active edge detection + * and the DMA/IRQ function on the corresponding XBAR output can be set. + * + * Example: + @code + xbar_status_t status; + + // Set the DMA function on XBAR_OUT2 to rising and falling active edges. + xbar_control_config_t controlOut2; + + controlOut2.activeEdge = kXbarEdgeRisingAndFalling; + controlOut2.intDmaReq = kXbarReqDen; + + status = XBAR_DRV_ConfigOutControl(2, controlOut2); + switch (status) + { + //... + } + @endcode + * + * @param outIndex XBAR output number. + * @param controlConfigPtr Pointer to structure that keeps configuration of control register. + * @return An error code or kStatus_XBAR_Success. + */ +xbar_status_t XBAR_DRV_ConfigOutControl(uint32_t outIndex, const xbar_control_config_t * controlConfigPtr); + +/*! + * @brief Gets the active edge detection status. + * + * This function gets the active edge detect status of the desired XBAR_OUT. If the + * active edge occurs, the return value is asserted. When the interrupt or the DMA + * functionality is enabled for the XBAR_OUTx, this field is 1 when the interrupt + * or DMA request is asserted and 0 when the interrupt or DMA request has been + * cleared. + * + * @param outIndex XBAR output number. + * @return Assertion of edge detection status. + */ +bool XBAR_DRV_GetEdgeDetectionStatus(uint32_t outIndex); + +/*! + * @brief Clears the status flag of the edge detection status flag for a desired XBAR_OUT. + * + * This function clears the status flag of edge detection status flag of the XBAR_OUTx. + * + * @param outIndex XBAR output number. + * @return An error code or kStatus_XBAR_Success. + */ +xbar_status_t XBAR_DRV_ClearEdgeDetectionStatus(uint32_t outIndex); + +/*! + * @brief Installs the callback function for the XBAR module. + * + * This function installs the user-defined callback. + * When the XBAR interrupt request is configured, the callback is executed + * inside the ISR. + * + * @param userCallback User-defined callback function. + * @param callbackParam The XBAR callback parameter pointer. + * @return An error code or kStatus_XBAR_Success. + */ +xbar_status_t XBAR_DRV_InstallCallback(uint32_t outIndex, xbar_callback_t userCallback, void * callbackParam); + +/*! + * @brief Driver-defined ISR in XBAR module. + * + * This function is the driver-defined ISR in XBAR module. + * It includes the process for interrupt mode defined by the driver. Currently, it + * is called inside the system-defined ISR. + * + */ +void XBAR_DRV_IRQHandler(void); + +#if defined(__cplusplus) +} +#endif + +/* + * @} + */ + +#endif +#endif /* __FSL_XBAR_DRIVER_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/adc16/fsl_adc16_common.c b/KSDK_1.2.0/platform/drivers/src/adc16/fsl_adc16_common.c new file mode 100755 index 0000000..8e34dd4 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/adc16/fsl_adc16_common.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for ADC instances. */ +ADC_Type * const g_adcBase[] = ADC_BASE_PTRS; + +/* Table to save ADC IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_adcIrqId[ADC_INSTANCE_COUNT] = ADC_IRQS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/adc16/fsl_adc16_driver.c b/KSDK_1.2.0/platform/drivers/src/adc16/fsl_adc16_driver.c new file mode 100755 index 0000000..cf1096a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/adc16/fsl_adc16_driver.c @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include "fsl_adc16_driver.h" +#include "fsl_adc16_hal.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_ADC16_COUNT + +#if FSL_FEATURE_ADC16_HAS_CALIBRATION + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_GetAutoCalibrationParam + * Description : Execute the the process of auto calibration and fetch + * the calibration parameters that would be kept in "adc16_calibration_param_t" + * type variable. When executing the process of auto calibration, the ADC + * has been configured internally to work in the situation with highest + * precision. Since this API may be called before the initialization, it enables + * the ADC clock internally. + * + *END*************************************************************************/ +adc16_status_t ADC16_DRV_GetAutoCalibrationParam(uint32_t instance, adc16_calibration_param_t *paramPtr) +{ + assert(instance < ADC_INSTANCE_COUNT); + + ADC_Type * base = g_adcBase[instance]; + volatile uint16_t dummy; + + /* Launch the auto-calibration. */ + ADC16_HAL_SetAutoCalibrationCmd(base, true); /* Launch auto calibration. */ + while ( !ADC16_HAL_GetChnConvCompletedFlag(base, 0U) ) + { + if ( ADC16_HAL_GetAutoCalibrationFailedFlag(base) ) + { + ADC16_HAL_SetAutoCalibrationCmd(base, false); + return kStatus_ADC16_Failed; + } + } + /* Read parameters that generated by auto calibration. */ +#if FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION + paramPtr->offsetValue = ADC16_HAL_GetOffsetValue(base); +#endif /* FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION */ + paramPtr->plusSideGainValue = ADC16_HAL_GetAutoPlusSideGainValue(base); +#if FSL_FEATURE_ADC16_HAS_DIFF_MODE + paramPtr->minusSideGainValue = ADC16_HAL_GetAutoMinusSideGainValue(base); +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ + dummy = ADC16_HAL_GetChnConvValue(base, 0U); /* Clear the flags. */ + dummy = dummy; /* Avoid the warning. */ + + /* Terminal the auot-calibration. */ + ADC16_HAL_SetAutoCalibrationCmd(base, false); + + return kStatus_ADC16_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_SetCalibrationParam + * Description : Set the calibration parameters for ADC module. These + * parameters can be fetched by launching the process of auto calibration + * or to use some predefined values that filled in the structure of + * "adc16_calibration_param_t". For higher precision, it is recommended to + * execute the process of calibration before initializing the ADC module. + * Since this API may be called before the initialization, it enables the ADC + * clock internally. + * + *END*************************************************************************/ +adc16_status_t ADC16_DRV_SetCalibrationParam(uint32_t instance, const adc16_calibration_param_t *paramPtr) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_adcBase[instance]; + + if (!paramPtr) + { + return kStatus_ADC16_InvalidArgument; + } + +#if FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION + ADC16_HAL_SetOffsetValue(base, paramPtr->offsetValue); +#endif /* FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION */ + ADC16_HAL_SetPlusSideGainValue(base, paramPtr->plusSideGainValue); +#if FSL_FEATURE_ADC16_HAS_DIFF_MODE + ADC16_HAL_SetMinusSideGainValue(base, paramPtr->minusSideGainValue); +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ + + return kStatus_ADC16_Success; +} + +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_StructInitUserConfigDefault + * Description : Fills the initial user configuration defaultly for a one-time + * trigger mode. Calling the initialization function with the filled parameter + * configures the ADC module work as one-time trigger mode. + * + *END*************************************************************************/ +adc16_status_t ADC16_DRV_StructInitUserConfigDefault(adc16_converter_config_t *userConfigPtr) +{ + if ( !userConfigPtr ) + { + return kStatus_ADC16_InvalidArgument; + } + + /* Special configuration for highest accuracy. */ + userConfigPtr->lowPowerEnable = true; + userConfigPtr->clkDividerMode = kAdc16ClkDividerOf8; + userConfigPtr->longSampleTimeEnable = true; + userConfigPtr->resolution = kAdc16ResolutionBitOfSingleEndAs12; + userConfigPtr->clkSrc = kAdc16ClkSrcOfAsynClk; + userConfigPtr->asyncClkEnable = true; + userConfigPtr->highSpeedEnable = false; + userConfigPtr->longSampleCycleMode = kAdc16LongSampleCycleOf24; + userConfigPtr->hwTriggerEnable = false; + userConfigPtr->refVoltSrc = kAdc16RefVoltSrcOfVref; + userConfigPtr->continuousConvEnable = false; +#if FSL_FEATURE_ADC16_HAS_DMA + userConfigPtr->dmaEnable = false; +#endif /* FSL_FEATURE_ADC16_HAS_DMA */ + + return kStatus_ADC16_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_Init + * Description : Initialize the comparator in ADC module. No mater if the + * calibration has been done for the device, this API with initial configuration + * should be called before any other operations to the ADC module. In fact, + * these initial configure are mainly for the comparator itself. For advanced + * feature, responding APIs would be called after this function. + * + *END*************************************************************************/ +adc16_status_t ADC16_DRV_Init(uint32_t instance, const adc16_converter_config_t *userConfigPtr) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_adcBase[instance]; + + if (!userConfigPtr) + { + return kStatus_ADC16_InvalidArgument; + } + /* Enable clock for ADC. */ + CLOCK_SYS_EnableAdcClock(instance); + + /* Reset all the register to a known state. */ + ADC16_HAL_Init(base); + ADC16_HAL_ConfigConverter(base, userConfigPtr); + + /* Enable ADC interrupt in NVIC level.*/ + INT_SYS_EnableIRQ(g_adcIrqId[instance] ); + + return kStatus_ADC16_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_Deinit + * Description : De-initialize the comparator in ADC module. It will gate + * the clock to ADC module. When ADC is no long used in application, calling + * this API will shut down the device to reduce power consumption. + * + *END*************************************************************************/ +adc16_status_t ADC16_DRV_Deinit(uint32_t instance) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_adcBase[instance]; + + /* Disable ADC interrupt in NVIC level. */ + INT_SYS_DisableIRQ( g_adcIrqId[instance] ); + + ADC16_HAL_Init(base); + + /* Disable clock for ADC. */ + CLOCK_SYS_DisableAdcClock(instance); + + return kStatus_ADC16_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_ConfigHwCompare + * Description : Initialize the feature of long sample mode in ADC + * module. This API would enable the feature of hardware compare with + * indicated configuration. Launch the hardware compare would make the + * conversion result in predefined range can be only accepted. Values out of + * range would be ignored during conversion. + * + *END*************************************************************************/ +adc16_status_t ADC16_DRV_ConfigHwCompare(uint32_t instance, const adc16_hw_cmp_config_t *configPtr) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_adcBase[instance]; + + if (!configPtr) + { + return kStatus_ADC16_InvalidArgument; + } + + ADC16_HAL_ConfigHwCompare(base, configPtr); + + return kStatus_ADC16_Success; +} + +#if FSL_FEATURE_ADC16_HAS_HW_AVERAGE + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_ConfigHwAverage + * Description : Configure the feature of hardware average in ADC module. + * + *END*************************************************************************/ +adc16_status_t ADC16_DRV_ConfigHwAverage(uint32_t instance, const adc16_hw_average_config_t *configPtr) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_adcBase[instance]; + + if (!configPtr) + { + return kStatus_ADC16_InvalidArgument; + } + + ADC16_HAL_ConfigHwAverage(base, configPtr); + + return kStatus_ADC16_Success; +} + +#endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ + +#if FSL_FEATURE_ADC16_HAS_PGA + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_ConfigPga + * Description : Configure the feature of Programmable Gain Amplifier + * (PGA) in ADC module. + * + *END*************************************************************************/ +adc16_status_t ADC16_DRV_ConfigPga(uint32_t instance, const adc16_pga_config_t *configPtr) +{ + + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_adcBase[instance]; + + if ( !configPtr) + { + return kStatus_ADC16_InvalidArgument; + } + + ADC16_HAL_ConfigPga(base, configPtr); + + return kStatus_ADC16_Success; +} + +#endif /* FSL_FEATURE_ADC16_HAS_PGA */ + +#if FSL_FEATURE_ADC16_HAS_MUX_SELECT +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_SetChnMux + * Description : Switch the channel mux. + * + *END*************************************************************************/ +void ADC16_DRV_SetChnMux(uint32_t instance, adc16_chn_mux_mode_t chnMuxMode) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_adcBase[instance]; + + ADC16_HAL_SetChnMuxMode(base, chnMuxMode); +} +#endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */ + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_ConfigConvChn + * Description : Configure the conversion channel. When ADC module has + * been initialized by enabling software trigger (disable hardware trigger), + * calling this API will trigger the conversion. + * + *END*************************************************************************/ +adc16_status_t ADC16_DRV_ConfigConvChn(uint32_t instance, + uint32_t chnGroup, const adc16_chn_config_t *configPtr) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_adcBase[instance]; + + if (!configPtr) + { + return kStatus_ADC16_InvalidArgument; + } + + ADC16_HAL_ConfigChn(base, chnGroup, configPtr); + + return kStatus_ADC16_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_WaitConvDone + * Description : Wait the latest conversion for its complete. When + * trigger the conversion by configuring the available channel, the converter + * would launch to work, this API should be called to wait for the conversion's + * complete when no interrupt or DMA mode is used for ADC module. After the + * waiting, the available data of conversion result could be fetched then. + * The complete flag would not be cleared until the result data would be read. + * + *END*************************************************************************/ +void ADC16_DRV_WaitConvDone(uint32_t instance, uint32_t chnGroup) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_adcBase[instance]; + + while ( !ADC16_HAL_GetChnConvCompletedFlag(base, chnGroup) ) + {} +} + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_PauseConv + * Description : Pause current conversion setting by software. + * + *END*************************************************************************/ +void ADC16_DRV_PauseConv(uint32_t instance, uint32_t chnGroup) +{ + assert(instance < ADC_INSTANCE_COUNT); + adc16_chn_config_t configStruct; + + configStruct.chnIdx = kAdc16Chn31; + configStruct.convCompletedIntEnable = false; +#if FSL_FEATURE_ADC16_HAS_DIFF_MODE + configStruct.diffConvEnable = false; +#endif + ADC16_DRV_ConfigConvChn(instance, chnGroup, &configStruct); +} + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_GetConvValueRAW + * Description : Get the conversion value from the ADC module. + * + *END*************************************************************************/ +uint16_t ADC16_DRV_GetConvValueRAW(uint32_t instance, uint32_t chnGroup) +{ + + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_adcBase[instance]; + + return ADC16_HAL_GetChnConvValue(base, chnGroup); +} + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_GetConvValueSigned + * Description : Get the latest conversion value with signed. + * + *END*************************************************************************/ +int16_t ADC16_DRV_GetConvValueSigned(uint32_t instance, uint32_t chnGroup) +{ + return (int16_t)ADC16_DRV_GetConvValueRAW(instance, chnGroup); +} + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_GetConvFlag + * Description : Get the status of event of ADC converter. + * If the event is asserted, it will return "true", otherwise will be "false". + * + *END*************************************************************************/ +bool ADC16_DRV_GetConvFlag(uint32_t instance, adc16_flag_t flag) +{ + + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_adcBase[instance]; + + bool bRet = false; + switch (flag) + { + case kAdcConvActiveFlag: + bRet = ADC16_HAL_GetConvActiveFlag(base); + break; +#if FSL_FEATURE_ADC16_HAS_CALIBRATION + case kAdcCalibrationFailedFlag: + bRet = ADC16_HAL_GetAutoCalibrationFailedFlag(base); + break; + case kAdcCalibrationActiveFlag: + bRet = ADC16_HAL_GetAutoCalibrationActiveFlag(base); + break; +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ + default: + break; + } + return bRet; + +} + +/*FUNCTION********************************************************************* + * + * Function Name : ADC16_DRV_GetChnFlag + * Description : Get the status of event of each ADC channel group. + * If the event is asserted, it will return "true", otherwise will be "false". + * + *END*************************************************************************/ +bool ADC16_DRV_GetChnFlag(uint32_t instance, uint32_t chnGroup, adc16_flag_t flag) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_adcBase[instance]; + + bool bRet = false; + switch (flag) + { + case kAdcChnConvCompleteFlag: + bRet = ADC16_HAL_GetChnConvCompletedFlag(base, chnGroup); + break; + default: + break; + } + return bRet; + +} +#endif + +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/adc16/fsl_adc16_irq.c b/KSDK_1.2.0/platform/drivers/src/adc16/fsl_adc16_irq.c new file mode 100755 index 0000000..274760b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/adc16/fsl_adc16_irq.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013 -2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_adc16_driver.h" +#if FSL_FEATURE_SOC_ADC_COUNT + +/****************************************************************************** + * IRQ Handlers + *****************************************************************************/ +/* ADC16 IRQ handler that would cover the same name's APIs in startup code */ +void ADC0_IRQHandler(void) +{ + /* Add user-defined ISR for ADC0. */ +} + +#if (ADC_INSTANCE_COUNT > 1U) +void ADC1_IRQHandler(void) +{ + /* Add user-defined ISR for ADC1. */ +} +#endif + +#if (ADC_INSTANCE_COUNT > 2U) +void ADC2_IRQHandler(void) +{ + /* Add user-defined ISR for ADC2. */ +} +#endif + +#if (ADC_INSTANCE_COUNT > 3U) +void ADC3_IRQHandler(void) +{ + /* Add user-defined ISR for ADC3. */ +} +#endif +#endif + +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/adc16/fsl_adc16_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/adc16/fsl_adc16_lpm_callback.c new file mode 100755 index 0000000..de11bff --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/adc16/fsl_adc16_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_ADC_COUNT + +power_manager_error_code_t adc16_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t adc16_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/aoi/fsl_aoi_common.c b/KSDK_1.2.0/platform/drivers/src/aoi/fsl_aoi_common.c new file mode 100755 index 0000000..7dc09c2 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/aoi/fsl_aoi_common.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_AOI_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for AOI instances. */ +AOI_Type* const g_aoiBase[] = AOI_BASE_PTRS; + +#endif /* FSL_FEATURE_SOC_AOI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/aoi/fsl_aoi_driver.c b/KSDK_1.2.0/platform/drivers/src/aoi/fsl_aoi_driver.c new file mode 100755 index 0000000..730a91a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/aoi/fsl_aoi_driver.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_aoi_driver.h" +#include "fsl_clock_manager.h" + +#if FSL_FEATURE_SOC_AOI_COUNT + +/*FUNCTION********************************************************************* + * + * Function Name : AOI_DRV_Init + * Description : Initialize the AOI module to the reset state. + * This API should be called before any operation of the AOI module. + * + *END*************************************************************************/ +aoi_status_t AOI_DRV_Init(uint32_t instance) +{ + AOI_Type* base = g_aoiBase[instance]; + + /* Enable the clock gate from clock manager. */ + bool mEnable = CLOCK_SYS_GetAoiGateCmd(0); + if (!mEnable) + { + CLOCK_SYS_EnableAoiClock(0); + } + + /* Init registers of the AOI module to the reset state. */ + AOI_HAL_Init(base); + + return kStatus_AOI_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : AOI_DRV_Deinit + * Description : De-initialize the AOI module. It shuts down the AOI module + * clock to reduce the power consumption and resets the registers configuration. + * + *END*************************************************************************/ +aoi_status_t AOI_DRV_Deinit(uint32_t instance) +{ + AOI_Type* base = g_aoiBase[instance]; + + /*Get module to the reset state - clears all configurations*/ + AOI_HAL_Init(base); + + /*Disable clock to the AOI module*/ + CLOCK_SYS_DisableAoiClock(0); + + return kStatus_AOI_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : AOI_DRV_ConfigEventLogic + * Description : Configures selected event output of the AOI module. It will configure + * the event output of the AOI module itself according the eventConfig structure. + * This function configures all of the inputs (A, B, C, and D) + * of all of the product terms (0, 1, 2, and 3) of a desired event. + * + *END*************************************************************************/ +aoi_status_t AOI_DRV_ConfigEventLogic(uint32_t instance, + aoi_event_index_t event, + const aoi_event_config_t * eventConfigPtr) +{ + AOI_Type* base = g_aoiBase[instance]; + + if(!eventConfigPtr) + { + return kStatus_AOI_InvalidArgument; + } + + /* Set the selected AOI module event registers according eventConfigPtr target structure */ + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm0, kAoiInputA, eventConfigPtr->PT0AC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm0, kAoiInputB, eventConfigPtr->PT0BC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm0, kAoiInputC, eventConfigPtr->PT0CC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm0, kAoiInputD, eventConfigPtr->PT0DC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm1, kAoiInputA, eventConfigPtr->PT1AC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm1, kAoiInputB, eventConfigPtr->PT1BC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm1, kAoiInputC, eventConfigPtr->PT1CC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm1, kAoiInputD, eventConfigPtr->PT1DC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm2, kAoiInputA, eventConfigPtr->PT2AC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm2, kAoiInputB, eventConfigPtr->PT2BC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm2, kAoiInputC, eventConfigPtr->PT2CC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm2, kAoiInputD, eventConfigPtr->PT2DC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm3, kAoiInputA, eventConfigPtr->PT3AC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm3, kAoiInputB, eventConfigPtr->PT3BC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm3, kAoiInputC, eventConfigPtr->PT3CC); + AOI_HAL_SetSignalLogicUnit(base, event, kAoiTerm3, kAoiInputD, eventConfigPtr->PT3DC); + + return kStatus_AOI_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : AOI_DRV_ConfigProductTermLogic + * Description : Configuration of one of the AOI module product term in a specific event. + * This function configures one of the AOI module product terms for a specific event. The user has + * to select the event and the product term which will be configured and fill the + * AoiProductTermConfig configuration structure. + * + *END*************************************************************************/ +aoi_status_t AOI_DRV_ConfigProductTermLogic(uint32_t instance, + aoi_event_index_t event, + aoi_product_term_t productTerm, + const aoi_product_term_config_t * productTermConfigPtr) +{ + AOI_Type* base = g_aoiBase[instance]; + + if(!productTermConfigPtr) + { + return kStatus_AOI_InvalidArgument; + } + + /* Set the selected AOI module event product term registers according eventConfigPtr target + * structure + */ + AOI_HAL_SetSignalLogicUnit(base, event, productTerm, kAoiInputA, productTermConfigPtr->PTAC); + AOI_HAL_SetSignalLogicUnit(base, event, productTerm, kAoiInputB, productTermConfigPtr->PTBC); + AOI_HAL_SetSignalLogicUnit(base, event, productTerm, kAoiInputC, productTermConfigPtr->PTCC); + AOI_HAL_SetSignalLogicUnit(base, event, productTerm, kAoiInputD, productTermConfigPtr->PTDC); + + return kStatus_AOI_Success; +} + +#endif /* FSL_FEATURE_SOC_AOI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/aoi/fsl_aoi_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/aoi/fsl_aoi_lpm_callback.c new file mode 100755 index 0000000..ed93b32 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/aoi/fsl_aoi_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_AOI_COUNT + +power_manager_error_code_t aoi_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t aoi_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/cmp/fsl_cmp_common.c b/KSDK_1.2.0/platform/drivers/src/cmp/fsl_cmp_common.c new file mode 100755 index 0000000..3ab576d --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/cmp/fsl_cmp_common.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for CMP instances. */ +CMP_Type * const g_cmpBase[] = CMP_BASE_PTRS; + +/* Table to save CMP IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_cmpIrqId[CMP_INSTANCE_COUNT] = CMP_IRQS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/cmp/fsl_cmp_driver.c b/KSDK_1.2.0/platform/drivers/src/cmp/fsl_cmp_driver.c new file mode 100755 index 0000000..f58c6e9 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/cmp/fsl_cmp_driver.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "assert.h" +#include "fsl_cmp_driver.h" +#include "fsl_cmp_hal.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_CMP_COUNT + +/*! @brief Table of pointers to internal state structure for CMP instances. */ +static cmp_state_t * volatile g_cmpStatePtr[CMP_INSTANCE_COUNT]; + +/*FUNCTION********************************************************************* + * + * Function Name : CMP_DRV_StructInitUserConfigDefault + * Description : Fill initial user configuration for default setting. + * The default setting will make the CMP module at least to be an comparator. + * It includes the setting of : + * .hystersisMode = kCmpHystersisOfLevel0 + * .pinoutEnable = true + * .pinoutUnfilteredEnable = true + * .invertEnable = false + * .highSpeedEnable = false + * .dmaEnable = false + * .risingIntEnable = false + * .fallingIntEnable = false + * .triggerEnable = false + * However, it is still recommended to fill some fields of structure such as + * channel mux according to application. Note that this API will not set the + * configuration to hardware. + * + *END*************************************************************************/ +cmp_status_t CMP_DRV_StructInitUserConfigDefault(cmp_comparator_config_t *userConfigPtr, + cmp_chn_mux_mode_t plusInput, cmp_chn_mux_mode_t minusInput) +{ + if (!userConfigPtr) + { + return kStatus_CMP_InvalidArgument; + } + + userConfigPtr->hystersisMode = kCmpHystersisOfLevel0; + userConfigPtr->pinoutEnable = true; + userConfigPtr->pinoutUnfilteredEnable = false; + userConfigPtr->invertEnable = false; + userConfigPtr->highSpeedEnable = false; +#if FSL_FEATURE_CMP_HAS_DMA + userConfigPtr->dmaEnable = false; +#endif /* FSL_FEATURE_CMP_HAS_DMA */ + userConfigPtr->risingIntEnable = false; + userConfigPtr->fallingIntEnable = false; + userConfigPtr->plusChnMux = plusInput; + userConfigPtr->minusChnMux = minusInput; +#if FSL_FEATURE_CMP_HAS_TRIGGER_MODE + userConfigPtr->triggerEnable = false; +#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */ + + return kStatus_CMP_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : CMP_DRV_Init + * Description : Initialize the CMP module. It will enable the clock and + * set the interrupt switcher for CMP module. And the CMP module will be + * configured for the basic comparator. + * + *END*************************************************************************/ +cmp_status_t CMP_DRV_Init(uint32_t instance, cmp_state_t *userStatePtr, + const cmp_comparator_config_t *userConfigPtr) +{ + + assert(instance < CMP_INSTANCE_COUNT); + CMP_Type * base = g_cmpBase[instance]; + + if ( (!userConfigPtr) || (!userStatePtr) ) + { + return kStatus_CMP_InvalidArgument; + } + + /* Enable clock for CMP. */ + if (!CLOCK_SYS_GetCmpGateCmd(instance) ) + { + CLOCK_SYS_EnableCmpClock(instance); + } + + /* Reset all the registers. */ + CMP_HAL_Init(base); + CMP_HAL_ConfigComparator(base, userConfigPtr); + + /* Configure the NVIC. */ + if ( (userConfigPtr->risingIntEnable) || (userConfigPtr->fallingIntEnable) ) + { + /* Enable the CMP interrupt in NVIC. */ + INT_SYS_EnableIRQ(g_cmpIrqId[instance] ); + } + else + { + /* Disable the CMP interrupt in NVIC. */ + INT_SYS_DisableIRQ(g_cmpIrqId[instance] ); + } + + userStatePtr->isInUsed = true; /* Mark it as in used. */ + g_cmpStatePtr[instance] = userStatePtr; /* Linked the user-provided memory into context record. */ + + return kStatus_CMP_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : CMP_DRV_Deinit + * Description : De-initialize the CMP module. It will shutdown the CMP's + * clock and disable the interrupt. This API should be called when CMP is no + * longer used in application and it will help to reduce the power consumption. + * + *END*************************************************************************/ +cmp_status_t CMP_DRV_Deinit(uint32_t instance) +{ + assert(instance < CMP_INSTANCE_COUNT); + + uint32_t i; + CMP_Type * base = g_cmpBase[instance]; + + /* Be sure to disable the CMP module. */ + CMP_HAL_Disable(base); + CMP_HAL_Init(base); + + /* Disable the CMP interrupt in NVIC. */ + INT_SYS_DisableIRQ(g_cmpIrqId[instance] ); + + /* Unmask the CMP not in use. */ + g_cmpStatePtr[instance]->isInUsed = false; + + /* Disable the clock if necessary. */ + for (i = 0U; i < CMP_INSTANCE_COUNT; i++) + { + if ( (g_cmpStatePtr[i]) && (g_cmpStatePtr[i]->isInUsed) ) + { + /* There are still some CMP instances in used. */ + break; + } + } + if (i == CMP_INSTANCE_COUNT) + { + /* Disable the shared clock. */ + CLOCK_SYS_DisableCmpClock(instance); + } + + g_cmpStatePtr[instance] = NULL; + + return kStatus_CMP_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : CMP_DRV_Start + * Description : Start the CMP module. The configuration would not take + * effect until the module is started. + * + *END*************************************************************************/ +void CMP_DRV_Start(uint32_t instance) +{ + assert(instance < CMP_INSTANCE_COUNT); + + CMP_Type * base = g_cmpBase[instance]; + CMP_HAL_Enable(base); +} + +/*FUNCTION********************************************************************* + * + * Function Name : CMP_DRV_Stop + * Description : Stop the CMP module. Note that this API would shutdown + * the module, but only pauses the features tenderly. + * + *END*************************************************************************/ +void CMP_DRV_Stop(uint32_t instance) +{ + assert(instance < CMP_INSTANCE_COUNT); + + CMP_Type * base = g_cmpBase[instance]; + CMP_HAL_Disable(base); +} + +/*FUNCTION********************************************************************* + * + * Function Name : CMP_DRV_ConfigDacChn + * Description : Enable the internal DAC in CMP module. It will take + * effect actually only when internal DAC has been chosen as one of input + * channel for comparator. Then the DAC channel can be programmed to provide + * a reference voltage level. + * + *END*************************************************************************/ +cmp_status_t CMP_DRV_ConfigDacChn(uint32_t instance, const cmp_dac_config_t *dacConfigPtr) +{ + assert(instance < CMP_INSTANCE_COUNT); + CMP_Type * base = g_cmpBase[instance]; + + if (!dacConfigPtr) + { + return kStatus_CMP_InvalidArgument; + } + /* Configure the DAC Control Register. */ + CMP_HAL_ConfigDacChn(base, dacConfigPtr); + + return kStatus_CMP_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : CMP_DRV_ConfigSampleFilter + * Description : Configure the CMP working in Sample\Filter modes. These + * modes are some advanced features beside the basic comparator. They may + * be about Windowed Mode, Filter Mode and so on. See to + * "cmp_sample_filter_config_t" for detailed description. + * + *END*************************************************************************/ +cmp_status_t CMP_DRV_ConfigSampleFilter(uint32_t instance, const cmp_sample_filter_config_t *configPtr) +{ + assert(instance < CMP_INSTANCE_COUNT); + CMP_Type * base = g_cmpBase[instance]; + + if (!configPtr) + { + return kStatus_CMP_InvalidArgument; + } + CMP_HAL_ConfigSampleFilter(base, configPtr); + + return kStatus_CMP_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : CMP_DRV_GetOutputLogic + * Description : Get the output of CMP module. + * The output source depends on the configuration when initializing the comparator. + * When cmp_user_config_t.pinoutUnfilteredEnable = false, the output will be + * processed by filter. Otherwise, the output would be the signal did not pass + * the filter. + * + *END*************************************************************************/ +bool CMP_DRV_GetOutputLogic(uint32_t instance) +{ + assert(instance < CMP_INSTANCE_COUNT); + CMP_Type * base = g_cmpBase[instance]; + + return CMP_HAL_GetOutputLogic(base); +} + +/*FUNCTION********************************************************************* + * + * Function Name : CMP_DRV_GetFlag + * Description : Get the state of CMP module. It will return if indicated + * event has been detected. + * + *END*************************************************************************/ +bool CMP_DRV_GetFlag(uint32_t instance, cmp_flag_t flag) +{ + assert(instance < CMP_INSTANCE_COUNT); + + bool bRet; + CMP_Type * base = g_cmpBase[instance]; + + switch(flag) + { + case kCmpFlagOfCoutRising: + bRet = CMP_HAL_GetOutputRisingFlag(base); + break; + case kCmpFlagOfCoutFalling: + bRet = CMP_HAL_GetOutputFallingFlag(base); + break; + default: + bRet = false; + break; + } + return bRet; +} + +/*FUNCTION********************************************************************* + * + * Function Name : CMP_DRV_ClearFlag + * Description : Clear event record of CMP module. + * + *END*************************************************************************/ +void CMP_DRV_ClearFlag(uint32_t instance, cmp_flag_t flag) +{ + assert(instance < CMP_INSTANCE_COUNT); + + CMP_Type * base = g_cmpBase[instance]; + + switch(flag) + { + case kCmpFlagOfCoutRising: + CMP_HAL_ClearOutputRisingFlag(base); + break; + case kCmpFlagOfCoutFalling: + CMP_HAL_ClearOutputFallingFlag(base); + break; + default: + break; + } +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/cmp/fsl_cmp_irq.c b/KSDK_1.2.0/platform/drivers/src/cmp/fsl_cmp_irq.c new file mode 100755 index 0000000..9ba8bf7 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/cmp/fsl_cmp_irq.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_cmp_driver.h" +#if FSL_FEATURE_SOC_CMP_COUNT + +/****************************************************************************** + * IRQ Handlers + *****************************************************************************/ +/* CMP IRQ handler that would cover the same name's APIs in startup code. */ +#if CMP_INSTANCE_COUNT > 0 +void CMP0_IRQHandler(void) +{ + /* Add user-defined ISR for CMP0. */ + + /* Clear flags. */ + if ( CMP_DRV_GetFlag(0U, kCmpFlagOfCoutRising) ) + { + CMP_DRV_ClearFlag(0U, kCmpFlagOfCoutRising); + } + if ( CMP_DRV_GetFlag(0U, kCmpFlagOfCoutFalling) ) + { + CMP_DRV_ClearFlag(0U, kCmpFlagOfCoutFalling); + } +} +#endif /* CMP_INSTANCE_COUNT > 0 */ + +#if CMP_INSTANCE_COUNT > 1 +void CMP1_IRQHandler(void) +{ + /* Add user-defined ISR for CMP1. */ + + /* Clear flags. */ + if ( CMP_DRV_GetFlag(1U, kCmpFlagOfCoutRising) ) + { + CMP_DRV_ClearFlag(1U, kCmpFlagOfCoutRising); + } + if ( CMP_DRV_GetFlag(1U, kCmpFlagOfCoutFalling) ) + { + CMP_DRV_ClearFlag(1U, kCmpFlagOfCoutFalling); + } +} +#endif /* CMP_INSTANCE_COUNT > 1 */ + +#if CMP_INSTANCE_COUNT > 2 +void CMP2_IRQHandler(void) +{ + /* Add user-defined ISR for CMP2. */ + + /* Clear flags. */ + if ( CMP_DRV_GetFlag(2U, kCmpFlagOfCoutRising) ) + { + CMP_DRV_ClearFlag(2U, kCmpFlagOfCoutRising); + } + if ( CMP_DRV_GetFlag(2U, kCmpFlagOfCoutFalling) ) + { + CMP_DRV_ClearFlag(2U, kCmpFlagOfCoutFalling); + } +} +#endif /* CMP_INSTANCE_COUNT > 2 */ +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ +
\ No newline at end of file diff --git a/KSDK_1.2.0/platform/drivers/src/cmp/fsl_cmp_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/cmp/fsl_cmp_lpm_callback.c new file mode 100755 index 0000000..e87dd85 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/cmp/fsl_cmp_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_CMP_COUNT + +power_manager_error_code_t cmp_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t cmp_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/cop/fsl_cop_common.c b/KSDK_1.2.0/platform/drivers/src/cop/fsl_cop_common.c new file mode 100755 index 0000000..d14c7f1 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/cop/fsl_cop_common.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for COP instances. */ + +SIM_Type * const g_copBase[] = SIM_BASE_PTRS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + + diff --git a/KSDK_1.2.0/platform/drivers/src/cop/fsl_cop_driver.c b/KSDK_1.2.0/platform/drivers/src/cop/fsl_cop_driver.c new file mode 100755 index 0000000..d67861c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/cop/fsl_cop_driver.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_driver.h" +#include "fsl_interrupt_manager.h" + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/******************************************************************************* + * Code + *******************************************************************************/ + +/*FUNCTION**************************************************************** + * + * Function Name : cop_init + * Description : Initialize COP. + * This function is used to initialize the COP, after called, the COP + * will run immediately according to the configure. + * + *END*********************************************************************/ +cop_status_t COP_DRV_Init(uint32_t instance, const cop_config_t* initPtr) +{ + SIM_Type * base = g_copBase[instance]; + if(!initPtr) + { + return kStatus_COP_NullArgument; + } + COP_HAL_SetConfig(base, initPtr); + return kStatus_COP_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name : COP_DRV_Deinit + * Description : Disable COP watchdog at reset. + * This function is used to shutdown the COP. + * + *END*********************************************************************/ +void COP_DRV_Disable(uint32_t instance) +{ + SIM_Type * base = g_copBase[instance]; + + COP_HAL_Disable(base); +} + +/*FUNCTION**************************************************************** + * + * Function Name : COP_DRV_IsRunning + * Description : Get COP running status. + * This function is used to get the COP running status. + * @retval true COP watchdog is running. + * @retval false COP watchdog is disabled. + * + *END*********************************************************************/ +bool COP_DRV_IsRunning(uint32_t instance) +{ + SIM_Type * base = g_copBase[instance]; + + return COP_HAL_IsEnable(base); +} + +/*FUNCTION**************************************************************** + * + * Function Name : cop_refresh + * Description : Refresh COP. + * This function is used to feed the COP, it will set the COP timer count to zero and + * should be called before COP timer is timeout, otherwise a RESET will assert. + * + *END*********************************************************************/ +void COP_DRV_Refresh(uint32_t instance) +{ + SIM_Type * base = g_copBase[instance]; + + INT_SYS_DisableIRQGlobal(); + + COP_HAL_Refresh(base); + + INT_SYS_EnableIRQGlobal(); +} + +/*FUNCTION**************************************************************** + * + * Function Name : cop_refresh + * Description : Refresh COP. + * This function is used to feed the COP, it will set the COP timer count to zero and + * should be called before COP timer is timeout, otherwise a RESET will assert. + * + *END*********************************************************************/ +void COP_DRV_ResetSystem(uint32_t instance) +{ + SIM_Type * base = g_copBase[instance]; + COP_HAL_ResetSystem(base); +} +/******************************************************************************* + * EOF + *******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/cop/fsl_cop_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/cop/fsl_cop_lpm_callback.c new file mode 100755 index 0000000..3dd9f3a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/cop/fsl_cop_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t cop_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t cop_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/crc/fsl_crc_common.c b/KSDK_1.2.0/platform/drivers/src/crc/fsl_crc_common.c new file mode 100755 index 0000000..4973609 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/crc/fsl_crc_common.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for crc instances. */ +CRC_Type * const g_crcBase[CRC_INSTANCE_COUNT] = CRC_BASE_PTRS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/crc/fsl_crc_driver.c b/KSDK_1.2.0/platform/drivers/src/crc/fsl_crc_driver.c new file mode 100755 index 0000000..5d56244 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/crc/fsl_crc_driver.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_crc_driver.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_CRC_COUNT + +/*FUNCTION********************************************************************* + * + * Function Name : CRC_DRV_Init + * Description : Initialize the CRC module. This API with initial configuration + * should be called before any other operations to the CRC module. + * + *END*************************************************************************/ +crc_status_t CRC_DRV_Init(uint32_t instance, const crc_user_config_t *userConfigPtr) +{ + if (!userConfigPtr) + { + return kStatus_CRC_InvalidArgument; + } + /* Enable clock for CRC. */ + if (!CLOCK_SYS_GetCrcGateCmd(instance)) + { + CLOCK_SYS_EnableCrcClock(instance); + } + + return CRC_DRV_Configure(instance, userConfigPtr); +} + +/*FUNCTION********************************************************************** + * + * Function Name : CRC_DRV_Deinit + * Description : Shutdown a CRC instance. + * + *END**************************************************************************/ +void CRC_DRV_Deinit(uint32_t instance) +{ + /* Gate the clock for CRC.*/ + CLOCK_SYS_DisableCrcClock(instance); +} + +/*FUNCTION********************************************************************** + * + * Function Name : CRC_DRV_GetCrcBlock + * Description : This method appends block of bytes to current CRC calculation + * and returns new result + * + *END**************************************************************************/ +uint32_t CRC_DRV_GetCrcBlock(uint32_t instance, uint8_t *data, uint32_t dataLen) +{ + crc_transpose_t oldInputTranspose; + uint32_t *data32; + uint8_t *data8; + uint32_t result; + + assert(data != NULL); + assert(dataLen != 0); + + /* flip bytes because of little endian architecture */ + oldInputTranspose = CRC_HAL_GetWriteTranspose(g_crcBase[instance]); + + switch (oldInputTranspose) { + case kCrcNoTranspose: + CRC_HAL_SetWriteTranspose(g_crcBase[instance], kCrcTransposeBytes); + break; + case kCrcTransposeBits: + CRC_HAL_SetWriteTranspose(g_crcBase[instance], kCrcTransposeBoth); + break; + case kCrcTransposeBoth: + CRC_HAL_SetWriteTranspose(g_crcBase[instance], kCrcTransposeBits); + break; + case kCrcTransposeBytes: + CRC_HAL_SetWriteTranspose(g_crcBase[instance], kCrcNoTranspose); + break; + default: + break; + } + + /* Start the checksum calculation */ + /* If address is not word-aligned, then read initial bytes in 8bit mode till word-aligned */ + while (((uint32_t)data & 3U) && (dataLen > 0)) + { + CRC_HAL_SetDataLLReg(g_crcBase[instance], *(data++)); + dataLen--; + } + + data32 = (uint32_t *)data; + while (dataLen >= sizeof(uint32_t)) + { + CRC_HAL_SetDataReg(g_crcBase[instance], *(data32++)); /* 32bit access */ + dataLen -= sizeof(uint32_t); + } + + data8 = (uint8_t *)data32; + + switch(dataLen) + { + case 3U: + CRC_HAL_SetDataLReg(g_crcBase[instance], *(uint16_t *)data8); /* 16 bit */ + CRC_HAL_SetDataLLReg(g_crcBase[instance], *(data8 + 2U)); /* 8 bit */ + break; + case 2U: + CRC_HAL_SetDataLReg(g_crcBase[instance], *(uint16_t *)data8); /* 16 bit */ + break; + case 1U: + CRC_HAL_SetDataLLReg(g_crcBase[instance], *data8); /* 8 bit */ + break; + default: + break; + } + + result = CRC_HAL_GetCrcResult(g_crcBase[instance]); + CRC_HAL_SetWriteTranspose(g_crcBase[instance], oldInputTranspose); + + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : CRC_DRV_Configure + * Description : Configure CRC module from a user configuration. + * + *END**************************************************************************/ +crc_status_t CRC_DRV_Configure(uint32_t instance, const crc_user_config_t *userConfigPtr) +{ + if((!userConfigPtr)) + { + return kStatus_CRC_InvalidArgument; + } + + /* 1. set 16 or 32-bit crc width */ + CRC_HAL_SetProtocolWidth(g_crcBase[instance], userConfigPtr->crcWidth); + + /* 2. set transpose and complement options */ + CRC_HAL_SetWriteTranspose(g_crcBase[instance], userConfigPtr->writeTranspose); + CRC_HAL_SetReadTranspose(g_crcBase[instance], userConfigPtr->readTranspose); + CRC_HAL_SetXorMode(g_crcBase[instance], userConfigPtr->complementRead); + + /* 3. Write polynomial */ + CRC_HAL_SetPolyReg(g_crcBase[instance], userConfigPtr->polynomial); + + /* 4. Set seed value */ + CRC_HAL_SetSeedOrDataMode(g_crcBase[instance], true); + CRC_HAL_SetDataReg(g_crcBase[instance], userConfigPtr->seed); + CRC_HAL_SetSeedOrDataMode(g_crcBase[instance], false); + + return kStatus_CRC_Success; +} +#endif + +/****************************************************************************** + * EOF + *****************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/crc/fsl_crc_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/crc/fsl_crc_lpm_callback.c new file mode 100755 index 0000000..3acd9a0 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/crc/fsl_crc_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_CRC_COUNT + +power_manager_error_code_t crc_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t crc_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/cyclicAdc/fsl_cadc_common.c b/KSDK_1.2.0/platform/drivers/src/cyclicAdc/fsl_cadc_common.c new file mode 100755 index 0000000..d4484cb --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/cyclicAdc/fsl_cadc_common.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for ADC instances. */ +/* const uint32_t g_cadcBaseAddr[] = ADC_BASES; */ +const uint32_t g_cadcBaseAddr[] = ADC_BASE_ADDRS; + +/* Table to save ADC IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_cadcErrIrqId[ADC_INSTANCE_COUNT] = { ADC_ERR_IRQn }; +const IRQn_Type g_cadcConvAIrqId[ADC_INSTANCE_COUNT] = { ADCA_IRQn }; +const IRQn_Type g_cadcConvBIrqId[ADC_INSTANCE_COUNT] = { ADCB_IRQn }; + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/cyclicAdc/fsl_cadc_driver.c b/KSDK_1.2.0/platform/drivers/src/cyclicAdc/fsl_cadc_driver.c new file mode 100755 index 0000000..56f6b76 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/cyclicAdc/fsl_cadc_driver.c @@ -0,0 +1,481 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_cadc_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_CADC_COUNT + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_StructInitUserConfigDefault + * Description : Help user to fill the cadc_user_config_t structure with + * default setting, which can be used in polling mode for ADC conversion. + * + *END**************************************************************************/ +cadc_status_t CADC_DRV_StructInitUserConfigDefault(cadc_controller_config_t *userConfigPtr) +{ + if (!userConfigPtr) + { + return kStatus_CADC_InvalidArgument; + } + userConfigPtr->zeroCrossingIntEnable = false; + userConfigPtr->lowLimitIntEnable = false; + userConfigPtr->highLimitIntEnable = false; + userConfigPtr->scanMode = kCAdcScanOnceSequential; + userConfigPtr->parallelSimultModeEnable = false; + userConfigPtr->dmaSrc = kCAdcDmaTriggeredByEndOfScan; + userConfigPtr->autoStandbyEnable = false; + userConfigPtr->powerUpDelayCount = 0x2AU; + userConfigPtr->autoPowerDownEnable = false; + + return kStatus_CADC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_Init + * Description : Configure the CyclicADC module for the global configuraion + * which are shared by all the converter. + * + *END**************************************************************************/ +cadc_status_t CADC_DRV_Init(uint32_t instance, const cadc_controller_config_t *userConfigPtr) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_cadcBaseAddr[instance]; + + if (!userConfigPtr) + { + return kStatus_CADC_InvalidArgument; + } + /* Ungate the clock for the ADC module. */ + CLOCK_SYS_EnableAdcClock(instance); + + /* Configure the common setting for ADC module. */ + CADC_HAL_Init(base); + + CADC_HAL_ConfigController(base, userConfigPtr); + + INT_SYS_EnableIRQ(g_cadcErrIrqId[instance]); + INT_SYS_EnableIRQ(g_cadcConvAIrqId[instance]); + INT_SYS_EnableIRQ(g_cadcConvBIrqId[instance]); + return kStatus_CADC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_Deinit + * Description : Deinit the CADC module. This function would disable all the + * interrupts and clock. + * + *END**************************************************************************/ +cadc_status_t CADC_DRV_Deinit(uint32_t instance) +{ + INT_SYS_DisableIRQ(g_cadcErrIrqId[instance]); + INT_SYS_DisableIRQ(g_cadcConvAIrqId[instance]); + INT_SYS_DisableIRQ(g_cadcConvBIrqId[instance]); + + /* Gate the access to ADC module. */ + CLOCK_SYS_DisableAdcClock(instance); /* BW_SIM_SCGC5_ADC(SIM_BASE,0U); */ + + return kStatus_CADC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_StructInitConvConfigDefault + * Description : Configure each converter in CyclicADC module. However, when + * the multiple converter are co-working, the setting for converters would + * be related with each other. For detailed information, please see to SOC's + * Reference Manual document. + * + *END**************************************************************************/ +cadc_status_t CADC_DRV_StructInitConvConfigDefault(cadc_converter_config_t *configPtr) +{ + if (!configPtr) + { + return kStatus_CADC_InvalidArgument; + } + + configPtr->dmaEnable = false; + configPtr->stopEnable = false; /* Release the converter. */ + configPtr->syncEnable = false; /* No hardware trigger. */ + + configPtr->endOfScanIntEnable = false; + configPtr->clkDivValue = 0x3FU; + configPtr->useChnInputAsVrefH = false; + configPtr->useChnInputAsVrefL = false; + configPtr->speedMode = kCAdcConvClkLimitBy25MHz; + configPtr->sampleWindowCount = 0U; + + return kStatus_CADC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_ConfigConverter + * Description : Configure each converter in CyclicADC module. However, when + * the multiple converter are co-working, the setting for converters would + * be related with each other. For detailed information, please see to SOC's + * Reference Manual document. + * + *END**************************************************************************/ +cadc_status_t CADC_DRV_ConfigConverter(uint32_t instance, cadc_conv_id_t convId, + const cadc_converter_config_t *configPtr) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_cadcBaseAddr[instance]; + + if (!configPtr) + { + return kStatus_CADC_InvalidArgument; + } + + /* Configure the ADC converter. */ + switch (convId) + { + case kCAdcConvA: + CADC_HAL_ConfigConvA(base, configPtr); + CADC_HAL_SetConvAPowerDownCmd(base, false); + break; + case kCAdcConvB: + CADC_HAL_ConfigConvB(base, configPtr); + CADC_HAL_SetConvBPowerDownCmd(base, false); + break; + default: + break; + } + + return kStatus_CADC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_ConfigSampleChn + * Description : Configure input channel for ADC conversion. The CyclicADC + * module's input channels are gathered in pairs. Here the configuration can + * be set for each of channel in the pair. + * + *END**************************************************************************/ +cadc_status_t CADC_DRV_ConfigSampleChn(uint32_t instance, const cadc_chn_config_t *configPtr) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_cadcBaseAddr[instance]; + + if (!configPtr) + { + return kStatus_CADC_InvalidArgument; + } + + CADC_HAL_ConfigChn(base, configPtr); + + return kStatus_CADC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_ConfigSeqSlot + * Description : Configure each slot in ADC conversion sequence. ADC conversion + * sequence is the basic execution unit in this CyclicADC module. However, the + * sequence should be configured slot by slot. The end of the sequence is a + * slot that is configured as disable. + * + *END**************************************************************************/ +cadc_status_t CADC_DRV_ConfigSeqSlot(uint32_t instance, uint32_t slotIdx, + const cadc_slot_config_t *configPtr) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_cadcBaseAddr[instance]; + + if (!configPtr) + { + return kStatus_CADC_InvalidArgument; + } + + CADC_HAL_ConfigSeqSlot(base, slotIdx, configPtr); + + return kStatus_CADC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_SoftTriggerConv + * Description : trigger the ADC conversion by executing software command. It + * will start the conversion if no other SYNC input (hardware trigger) is needed. + * + *END**************************************************************************/ +void CADC_DRV_SoftTriggerConv(uint32_t instance, cadc_conv_id_t convId) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_cadcBaseAddr[instance]; + + switch (convId) + { + case kCAdcConvA: + CADC_HAL_SetConvAStartCmd(base); + break; + case kCAdcConvB: + CADC_HAL_SetConvBStartCmd(base); + break; + default: + break; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_GetSeqSlotConvValue + * Description : Read the conversion value from each slot in conversion sequence. + * + *END**************************************************************************/ +uint16_t CADC_DRV_GetSeqSlotConvValue(uint32_t instance, uint32_t slotIdx) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_cadcBaseAddr[instance]; + + return CADC_HAL_GetSampleValue(base, slotIdx); +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_GetFlag + * Description : Help to get the global flag of CyclicADC module. + * + *END**************************************************************************/ +bool CADC_DRV_GetFlag(uint32_t instance, cadc_flag_t flag) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_cadcBaseAddr[instance]; + bool bRet = false; + + switch(flag) + { + case kCAdcZeroCrossingInt: + bRet = CADC_HAL_GetZeroCrossingIntFlag(base); + break; + case kCAdcLowLimitInt: + bRet = CADC_HAL_GetLowLimitIntFlag(base); + break; + case kCAdcHighLimitInt: + bRet = CADC_HAL_GetHighLimitIntFlag(base); + break; + default: + break; + } + return bRet; +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_ClearFlag + * Description : Clear the global flag of CyclicADC module. + * + *END**************************************************************************/ +void CADC_DRV_ClearFlag(uint32_t instance, cadc_flag_t flag) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_cadcBaseAddr[instance]; + + switch(flag) + { + case kCAdcZeroCrossingInt: + CADC_HAL_ClearSlotZeroCrossingFlag(base, 0xFFFF); + break; + case kCAdcLowLimitInt: + CADC_HAL_ClearSlotLowLimitFlag(base, 0xFFFF); + break; + case kCAdcHighLimitInt: + CADC_HAL_ClearSlotHighLimitFlag(base, 0xFFFF); + break; + default: + break; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_GetConvFlag + * Description : Help to get the flag of each converter's event. + * + *END**************************************************************************/ +bool CADC_DRV_GetConvFlag(uint32_t instance, cadc_conv_id_t convId, cadc_flag_t flag) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_cadcBaseAddr[instance]; + bool bRet = false; + + switch (flag) + { + case kCAdcConvInProgress: + switch (convId) + { + case kCAdcConvA: + bRet = CADC_HAL_GetConvAInProgressFlag(base); + break; + case kCAdcConvB: + bRet = CADC_HAL_GetConvBInProgressFlag(base); + break; + default: + break; + } + break; + case kCAdcConvEndOfScanInt: + switch (convId) + { + case kCAdcConvA: + bRet = CADC_HAL_GetConvAEndOfScanIntFlag(base); + break; + case kCAdcConvB: + bRet = CADC_HAL_GetConvBEndOfScanIntFlag(base); + break; + default: + break; + } + break; + case kCAdcConvPowerDown: + switch (convId) + { + case kCAdcConvA: + bRet = CADC_HAL_GetConvAPowerDownFlag(base); + break; + case kCAdcConvB: + bRet = CADC_HAL_GetConvBPowerDownFlag(base); + break; + default: + break; + } + break; + default: + break; + } + return bRet; +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_ClearConvFlag + * Description : help to clear the flag of each converter's event. + * + *END**************************************************************************/ +void CADC_DRV_ClearConvFlag(uint32_t instance, cadc_conv_id_t convId, cadc_flag_t flag) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_cadcBaseAddr[instance]; + + switch (flag) + { + case kCAdcConvEndOfScanInt: + switch (convId) + { + case kCAdcConvA: + CADC_HAL_ClearConvAEndOfScanIntFlag(base); + break; + case kCAdcConvB: + CADC_HAL_ClearConvBEndOfScanIntFlag(base); + break; + default: + break; + } + break; + default: + break; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_GetSlotFlag + * Description : Help to get the flag of each slot's event in conversion in + * sequence. + * + *END**************************************************************************/ +uint16_t CADC_DRV_GetSlotFlag(uint32_t instance, uint16_t slotIdxMask, cadc_flag_t flag) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_cadcBaseAddr[instance]; + + uint16_t mskRet = 0U; + switch (flag) + { + case kCAdcSlotReady: + mskRet = CADC_HAL_GetSlotReadyFlag(base, slotIdxMask); + break; + case kCAdcSlotLowLimitEvent: + mskRet = CADC_HAL_GetSlotLowLimitFlag(base, slotIdxMask); + break; + case kCAdcSlotHighLimitEvent: + mskRet = CADC_HAL_GetSlotHighLimitFlag(base, slotIdxMask); + break; + case kCAdcSlotCrossingEvent: + mskRet = CADC_HAL_GetSlotZeroCrossingFlag(base, slotIdxMask); + break; + default: + break; + } + return mskRet; +} + +/*FUNCTION********************************************************************** + * + * Function Name : CADC_DRV_ClearSlotFlag + * Description : Help to clear the flag of each slot's event in conversion in + * sequence. + * + *END**************************************************************************/ +void CADC_DRV_ClearSlotFlag(uint32_t instance, uint16_t slotIdxMask, cadc_flag_t flag) +{ + assert(instance < ADC_INSTANCE_COUNT); + ADC_Type * base = g_cadcBaseAddr[instance]; + + switch (flag) + { + case kCAdcSlotLowLimitEvent: + CADC_HAL_ClearSlotLowLimitFlag(base, slotIdxMask); + break; + case kCAdcSlotHighLimitEvent: + CADC_HAL_ClearSlotHighLimitFlag(base, slotIdxMask); + break; + case kCAdcSlotCrossingEvent: + CADC_HAL_ClearSlotZeroCrossingFlag(base, slotIdxMask); + break; + default: + break; + } +} +#endif + +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/cyclicAdc/fsl_cyclicAdc_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/cyclicAdc/fsl_cyclicAdc_lpm_callback.c new file mode 100755 index 0000000..4715b8a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/cyclicAdc/fsl_cyclicAdc_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_ADC_COUNT + +power_manager_error_code_t cyclicAdc_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t cyclicAdc_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/dac/fsl_dac_common.c b/KSDK_1.2.0/platform/drivers/src/dac/fsl_dac_common.c new file mode 100755 index 0000000..65a8b5d --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dac/fsl_dac_common.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for DAC instances. */ +DAC_Type * const g_dacBase[] = DAC_BASE_PTRS; + +/* Table to save DAC IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_dacIrqId[DAC_INSTANCE_COUNT] = DAC_IRQS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + + diff --git a/KSDK_1.2.0/platform/drivers/src/dac/fsl_dac_driver.c b/KSDK_1.2.0/platform/drivers/src/dac/fsl_dac_driver.c new file mode 100755 index 0000000..43b8e53 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dac/fsl_dac_driver.c @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include "fsl_dac_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_DAC_COUNT + +/*FUNCTION********************************************************************* + * + * Function Name : DAC_DRV_StructInitUserConfigNormal + * Description : Fill the initial user configuration for DAC module + * without the feature of interrupt and buffer. Then call initialization + * function with the filled parameter would configure + * the DAC module work as a common and simple converter. + * + *END*************************************************************************/ +dac_status_t DAC_DRV_StructInitUserConfigNormal(dac_converter_config_t *userConfigPtr) +{ + if (!userConfigPtr) + { + return kStatus_DAC_InvalidArgument; + } + userConfigPtr->dacRefVoltSrc = kDacRefVoltSrcOfVref2; /* Vdda */ + userConfigPtr->lowPowerEnable = false; + return kStatus_DAC_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : DAC_DRV_Init + * Description : Initialize the converter in DAC module. It will just + * configure the DAC converter itself but not including advanced features like + * interrupt and internal buffer. This API should be called before any + * operation to DAC module. After initialized, the DAC module can work at + * least as a common simple DAC converter. + * + *END*************************************************************************/ +dac_status_t DAC_DRV_Init(uint32_t instance, const dac_converter_config_t *userConfigPtr) +{ + assert(instance < DAC_INSTANCE_COUNT); + DAC_Type * base = g_dacBase[instance]; + + CLOCK_SYS_EnableDacClock(instance); + + /* Reset the registers for DAC module to reset state. */ + DAC_HAL_Init(base); + DAC_HAL_Enable(base); + DAC_HAL_ConfigConverter(base, userConfigPtr); + + /* Enable DAC interrupt in NVIC level.*/ + INT_SYS_EnableIRQ(g_dacIrqId[instance] ); + + return kStatus_DAC_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : DAC_DRV_Deinit + * Description : De-initialize the converter in DAC module. It will disable + * DAC module and shut down its clock to reduce the power consumption. + * + *END*************************************************************************/ +dac_status_t DAC_DRV_Deinit(uint32_t instance) +{ + assert(instance < DAC_INSTANCE_COUNT); + DAC_Type * base = g_dacBase[instance]; + + INT_SYS_DisableIRQ(g_dacIrqId[instance] ); + DAC_HAL_Disable(base); + DAC_HAL_Init(base); + CLOCK_SYS_DisableDacClock(instance); + + return kStatus_DAC_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : DAC_DRV_Output + * Description : Drive the converter to output DAC value. It will force + * the buffer index to be the first one, load the setting value to this item. + * Then the converter will output the voltage indicated by the indicated value + * immediately. + * + *END*************************************************************************/ +void DAC_DRV_Output(uint32_t instance, uint16_t value) +{ + assert(instance < DAC_INSTANCE_COUNT); + DAC_Type * base = g_dacBase[instance]; + + DAC_HAL_SetBuffValue(base, 0U, value); + DAC_HAL_SetBuffCurIdx(base, 0U); +} + +/*FUNCTION********************************************************************* + * + * Function Name : DAC_DRV_ConfigBuffer + * Description : Configure the feature of internal buffer for DAC module. + * By default, the feature of buffer is disabled. Calling this API will enable + * the buffer and configure it. + * + *END*************************************************************************/ +dac_status_t DAC_DRV_ConfigBuffer(uint32_t instance, const dac_buffer_config_t *configPtr) +{ + assert(instance < DAC_INSTANCE_COUNT); + DAC_Type * base = g_dacBase[instance]; + + if (!configPtr) + { + return kStatus_DAC_InvalidArgument; + } + DAC_HAL_ConfigBuffer(base, configPtr); + + return kStatus_DAC_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : DAC_DRV_SetBuffValue + * Description : Set values into DAC's internal buffer. Note the buffer + * size is defined by MACRO "FSL_FEATURE_DAC_BUFFER_SIZE" and the available + * value is 12-bit. + * + *END*************************************************************************/ +dac_status_t DAC_DRV_SetBuffValue(uint32_t instance, uint8_t start, uint8_t offset, uint16_t arr[]) +{ + assert(instance < DAC_INSTANCE_COUNT); + DAC_Type * base = g_dacBase[instance]; + + uint8_t i; + + if ( (!arr) || (start + offset > DAC_DATL_COUNT) ) + { + return kStatus_DAC_InvalidArgument; + } + + for (i = 0; i < offset; i++) + { + DAC_HAL_SetBuffValue(base, start+i, arr[i]); + } + + return kStatus_DAC_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : DAC_DRV_SoftTriggerBuffCmd + * Description : Trigger the buffer by software and return the current + * value. After triggered, the buffer index will update according to work mode. + * Then the value kept inside the pointed item will be output immediately. + * + *END*************************************************************************/ +void DAC_DRV_SoftTriggerBuffCmd(uint32_t instance) +{ + assert(instance < DAC_INSTANCE_COUNT); + DAC_Type * base = g_dacBase[instance]; + + DAC_HAL_SetSoftTriggerCmd(base); +} + +/*FUNCTION********************************************************************* + * + * Function Name : DAC_DRV_SetBuffCurIdx + * Description : Set the current read pointer in DAC buffer. + * + *END*************************************************************************/ +void DAC_DRV_SetBuffCurIdx(uint32_t instance, uint8_t idx) +{ + assert(instance < DAC_INSTANCE_COUNT); + DAC_Type * base = g_dacBase[instance]; + + DAC_HAL_SetBuffCurIdx(base, idx); +} + +/*FUNCTION********************************************************************* + * + * Function Name : DAC_DRV_GetBuffCurIdx + * Description : Get the current read pointer in DAC buffer. + * + *END*************************************************************************/ +uint8_t DAC_DRV_GetBuffCurIdx(uint32_t instance) +{ + assert(instance < DAC_INSTANCE_COUNT); + DAC_Type * base = g_dacBase[instance]; + + return DAC_HAL_GetBuffCurIdx(base); + +} + +/*FUNCTION********************************************************************* + * + * Function Name : DAC_DRV_ClearBuffFlag + * Description : Clear the flag for indicated event causing interrupt. + * + *END*************************************************************************/ +void DAC_DRV_ClearBuffFlag(uint32_t instance, dac_flag_t flag) +{ + assert(instance < DAC_INSTANCE_COUNT); + DAC_Type * base = g_dacBase[instance]; + + switch (flag) + { + case kDacBuffIndexStartFlag: + DAC_HAL_ClearBuffIdxStartFlag(base); + break; +#if FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION + case kDacBuffIndexWatermarkFlag: + DAC_HAL_ClearBuffIdxWatermarkFlag(base); + break; +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + case kDacBuffIndexUpperFlag: + DAC_HAL_ClearBuffIdxUpperFlag(base); + break; + default: + DAC_HAL_ClearBuffIdxStartFlag(base); +#if FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION + DAC_HAL_ClearBuffIdxWatermarkFlag(base); +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + DAC_HAL_ClearBuffIdxUpperFlag(base); + break; + } +} + +/*FUNCTION********************************************************************* + * + * Function Name : DAC_DRV_GetBuffFlag + * Description : Get the flag for indicated event causing interrupt. + * If the event occurs, the return value will be asserted. + * + *END*************************************************************************/ +bool DAC_DRV_GetBuffFlag(uint32_t instance, dac_flag_t flag) +{ + assert(instance < DAC_INSTANCE_COUNT); + DAC_Type * base = g_dacBase[instance]; + bool bRet = true; + + switch (flag) + { + case kDacBuffIndexStartFlag: + bRet = DAC_HAL_GetBuffIdxStartFlag(base); + break; +#if FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION + case kDacBuffIndexWatermarkFlag: + bRet = DAC_HAL_GetBuffIdxWatermarkFlag(base); + break; +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + case kDacBuffIndexUpperFlag: + bRet = DAC_HAL_GetBuffIdxUpperFlag(base); + break; + default: + bRet = false; + break; + } + return bRet; +} + +/****************************************************************************** + * EOF + *****************************************************************************/ + +#endif diff --git a/KSDK_1.2.0/platform/drivers/src/dac/fsl_dac_irq.c b/KSDK_1.2.0/platform/drivers/src/dac/fsl_dac_irq.c new file mode 100755 index 0000000..ccd84a9 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dac/fsl_dac_irq.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_dac_driver.h" + +#if FSL_FEATURE_SOC_DAC_COUNT + +/****************************************************************************** + * IRQ Handlers + *****************************************************************************/ +/* DAC IRQ handler that would cover the same name's APIs in startup code. */ +void DAC0_IRQHandler(void) +{ + /* Add user-defined ISR for DAC0. */ +} + +#if (DAC_INSTANCE_COUNT > 1U) +void DAC1_IRQHandler(void) +{ + /* Add user-defined ISR for DAC1. */ +} + +#endif +/******************************************************************************* + * EOF + ******************************************************************************/ + +#endif diff --git a/KSDK_1.2.0/platform/drivers/src/dac/fsl_dac_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/dac/fsl_dac_lpm_callback.c new file mode 100755 index 0000000..665dc58 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dac/fsl_dac_lpm_callback.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +#if FSL_FEATURE_SOC_DAC_COUNT + +power_manager_error_code_t dac_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t dac_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + + +#endif diff --git a/KSDK_1.2.0/platform/drivers/src/dma/fsl_dma_common.c b/KSDK_1.2.0/platform/drivers/src/dma/fsl_dma_common.c new file mode 100755 index 0000000..bfdba0c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dma/fsl_dma_common.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <stdint.h> +#include "fsl_device_registers.h" + +DMA_Type * const g_dmaBase[DMA_INSTANCE_COUNT] = DMA_BASE_PTRS; +DMAMUX_Type * const g_dmamuxBase[DMAMUX_INSTANCE_COUNT] = DMAMUX_BASE_PTRS; +const IRQn_Type g_dmaIrqId[DMA_INSTANCE_COUNT][FSL_FEATURE_DMA_DMAMUX_CHANNELS] = +{ + {DMA0_IRQn, DMA1_IRQn, DMA2_IRQn, DMA3_IRQn} +}; + + +/******************************************************************************* +* EOF +******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/dma/fsl_dma_driver.c b/KSDK_1.2.0/platform/drivers/src/dma/fsl_dma_driver.c new file mode 100755 index 0000000..2fa6ebe --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dma/fsl_dma_driver.c @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string.h> +#include "fsl_dma_driver.h" +#include "fsl_interrupt_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_DMA_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Global DMA management data structure. */ +dma_state_t *g_dma; + +/*! @brief Macro for EDMA driver lock mechanism. */ +#if (USE_RTOS) + #define DMA_DRV_LOCK() OSA_MutexLock(&g_dma->lock, OSA_WAIT_FOREVER) + #define DMA_DRV_UNLOCK() OSA_MutexUnlock(&g_dma->lock) +#else + #define DMA_DRV_LOCK() do {}while(0) + #define DMA_DRV_UNLOCK() do {}while(0) +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_DRV_Init + * Description : Initialize DMA. + * + *END**************************************************************************/ +dma_status_t DMA_DRV_Init(dma_state_t *state) +{ + uint8_t i; + g_dma = state; + memset(g_dma, 0, sizeof(dma_state_t)); +#if (USE_RTOS) + OSA_MutexCreate(&state->lock); +#endif + /* Enable DMA clock. */ + for (i = 0; i < DMA_INSTANCE_COUNT; i ++) + { + CLOCK_SYS_EnableDmaClock(i); + } + + /* Enable DMAMUX clock and init. */ + for (i = 0; i < DMAMUX_INSTANCE_COUNT; i++) + { + CLOCK_SYS_EnableDmamuxClock(i); + DMAMUX_HAL_Init(g_dmamuxBase[i]); + } + + return kStatus_DMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_DRV_Deinit + * Description : Deinitilize DMA + * + *END**************************************************************************/ +dma_status_t DMA_DRV_Deinit(void) +{ + uint8_t i; + + /* Disable DMA clock and free channel. */ + for (i = 0; i < FSL_FEATURE_DMA_DMAMUX_CHANNELS; i++) + { + /* Free all requested channels. */ + if (g_dma->dmaChan[i]) + { + DMA_DRV_FreeChannel(g_dma->dmaChan[i]); + } + } + + /* Disable DMA clcok. */ + for (i = 0; i < DMA_INSTANCE_COUNT; i++) + { + CLOCK_SYS_DisableDmaClock(i); + } + + /* Disable DMAMUX clock. */ + for (i = 0; i < DMAMUX_INSTANCE_COUNT; i++) + { + CLOCK_SYS_DisableDmaClock(i); + } +#if USE_RTOS + OSA_MutexDestroy(&g_dma->lock); +#endif + + return kStatus_DMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_DRV_RegisterCallback + * Description : Register callback function and parameter. + * + *END**************************************************************************/ +dma_status_t DMA_DRV_RegisterCallback( + dma_channel_t *chn, dma_callback_t callback, void *para) +{ + chn->callback = callback; + chn->parameter = para; + + return kStatus_DMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_DRV_RequestChannel + * Description : Request a DMA channel. + * + *END**************************************************************************/ +uint32_t DMA_DRV_RequestChannel( + uint32_t channel, dma_request_source_t source, dma_channel_t *chn) +{ + uint8_t i = 0, j; + + /*Check if dynamically allocation is requested */ + if (channel == kDmaAnyChannel) + { + uint32_t map = ((uint32_t)source >> 8U); + while (map != 0) + { + if (map & (1U << i)) + { + for (j = i * FSL_FEATURE_DMAMUX_MODULE_CHANNEL; j < (i + 1) * FSL_FEATURE_DMAMUX_MODULE_CHANNEL; j++) + { + DMA_DRV_LOCK(); + if (!g_dma->dmaChan[j]) + { + g_dma->dmaChan[j] = chn; + DMA_DRV_UNLOCK(); + DMA_DRV_ClaimChannel(j, source, chn); + return j; + } + DMA_DRV_UNLOCK(); + } + + } + map &= ~(0x1U << i); + i++; + } + + return kDmaInvalidChannel; + } + + /*static allocation */ + DMA_DRV_LOCK(); + if (!g_dma->dmaChan[channel]) + { + DMA_DRV_UNLOCK(); + DMA_DRV_ClaimChannel(channel, source, chn); + return channel; + } + DMA_DRV_UNLOCK(); + + return kDmaInvalidChannel; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_DRV_ClaimChannel + * Description : claim DMA channel. + * + *END**************************************************************************/ +dma_status_t DMA_DRV_ClaimChannel( + uint32_t channel, dma_request_source_t source, dma_channel_t *chn) +{ + IRQn_Type irqNumber; + uint32_t dmaInstance = channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS; + DMAMUX_Type * dmamuxBaseAddr = g_dmamuxBase[channel/FSL_FEATURE_DMAMUX_MODULE_CHANNEL]; + memset(chn, 0, sizeof(dma_channel_t)); + + DMA_DRV_LOCK(); + g_dma->dmaChan[channel] = chn; + DMA_DRV_UNLOCK(); + + chn->channel = channel % FSL_FEATURE_DMA_DMAMUX_CHANNELS; + chn->dmamuxChannel = channel % FSL_FEATURE_DMAMUX_MODULE_CHANNEL; + chn->dmamuxModule = channel / FSL_FEATURE_DMAMUX_MODULE_CHANNEL; + + chn->parameter = 0; + chn->callback = NULL; + + chn->status = kDmaNormal; + + /*Enable the interrupt */ + irqNumber = g_dmaIrqId[dmaInstance][chn->channel]; + INT_SYS_EnableIRQ(irqNumber); + + /*Configure the DMAMUX for EDMA channel */ + DMAMUX_HAL_SetChannelCmd(dmamuxBaseAddr, chn->dmamuxChannel, false); + DMAMUX_HAL_SetTriggerSource( + dmamuxBaseAddr, chn->dmamuxChannel, (uint32_t)source % (uint32_t)kDmamuxDmaRequestSource); + DMAMUX_HAL_SetChannelCmd(dmamuxBaseAddr, chn->dmamuxChannel,true); + + return kStatus_DMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_DRV_FreeChannel + * Description : Free DMA channel's hardware and software resource. + * + *END**************************************************************************/ +dma_status_t DMA_DRV_FreeChannel(dma_channel_t *chn) +{ + /* Stop channel firstly. */ + DMA_DRV_StopChannel(chn); + + DMA_DRV_LOCK(); + /* Unregister channel from global structure. */ + g_dma->dmaChan[chn->channel] = NULL; + DMA_DRV_UNLOCK(); + memset(chn, 0x1, sizeof(dma_channel_t)); + + return kStatus_DMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_DRV_StartChannel + * Description : Start a DMA channel. + * + *END**************************************************************************/ +dma_status_t DMA_DRV_StartChannel(dma_channel_t *chn) +{ + DMA_Type * dmaBaseAddr = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + DMA_HAL_SetDmaRequestCmd(dmaBaseAddr, chn->channel, true); + return kStatus_DMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_DRV_StopChannel + * Description : Stop a DMA channel. + * + *END**************************************************************************/ +dma_status_t DMA_DRV_StopChannel(dma_channel_t *chn) +{ + DMA_Type * dmaBaseAddr = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + DMA_HAL_SetDmaRequestCmd(dmaBaseAddr, chn->channel, false); + return kStatus_DMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_DRV_GetDescriptorStatus + * Description : Get the left bytes to be transferred. + * + *END**************************************************************************/ +uint32_t DMA_DRV_GetUnfinishedBytes(dma_channel_t *chn) +{ + DMA_Type * dmaBaseAddr = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + return DMA_HAL_GetUnfinishedByte(dmaBaseAddr, chn->channel); +} + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_DRV_IRQhandler + * Description : IRQ handler for DMA channel. + * + *END**************************************************************************/ +void DMA_DRV_IRQhandler(uint32_t channel) +{ + dma_channel_t *chn = g_dma->dmaChan[channel]; + DMA_Type * dmaBaseAddr = g_dmaBase[channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + dma_error_status_t status; + + if (!chn) + { + return; + } + + status = DMA_HAL_GetStatus(dmaBaseAddr, channel); + + if ((status.dmaConfigError) || (status.dmaDestBusError) || (status.dmaSourceBusError)) + { + chn->status = kDmaError; + status = DMA_HAL_GetStatus(dmaBaseAddr, channel); + } + + DMA_HAL_ClearStatus(dmaBaseAddr, channel); + + + if (chn->callback) + { + chn->callback(chn->parameter, chn->status); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_DRV_ConfigTransfer + * Description : Configure transfer for DMA. + * + *END**************************************************************************/ +dma_status_t DMA_DRV_ConfigTransfer( + dma_channel_t *chn, dma_transfer_type_t type, uint32_t size, + uint32_t sourceAddr, uint32_t destAddr, uint32_t length) +{ + DMA_Type * dmaBaseAddr = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + dma_transfer_size_t transfersize; + switch (size) + { + case 1: + transfersize = kDmaTransfersize8bits; + break; + case 2: + transfersize = kDmaTransfersize16bits; + break; + case 4: + transfersize = kDmaTransfersize32bits; + break; + default: + return kStatus_DMA_InvalidArgument; + } + + DMA_HAL_ConfigTransfer( + dmaBaseAddr,chn->channel,transfersize,type,sourceAddr,destAddr,length); + + return kStatus_DMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_DRV_ConfigChanLink + * Description : Configure channel link for dma. + * + *END**************************************************************************/ +dma_status_t DMA_DRV_ConfigChanLink( + dma_channel_t * chn,dma_channel_link_config_t * link_config) +{ + uint32_t channel = chn->channel; + DMA_Type * base = g_dmaBase[channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + DMA_HAL_SetChanLink(base, channel,link_config); + return kStatus_DMA_Success; +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/dma/fsl_dma_irq.c b/KSDK_1.2.0/platform/drivers/src/dma/fsl_dma_irq.c new file mode 100755 index 0000000..d7cc5cc --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dma/fsl_dma_irq.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_dma_driver.h" +#if FSL_FEATURE_SOC_DMA_COUNT + +/******************************************************************************* + * Code + ******************************************************************************/ + +/* DMA IRQ handler with the same name in startup code*/ +void DMA0_IRQHandler(void) +{ + DMA_DRV_IRQhandler(0); +} + +/* DMA IRQ handler with the same name in startup code*/ +void DMA1_IRQHandler(void) +{ + DMA_DRV_IRQhandler(1); +} + +/* DMA IRQ handler with the same name in startup code*/ +void DMA2_IRQHandler(void) +{ + DMA_DRV_IRQhandler(2); +} + +/* DMA IRQ handler with the same name in startup code*/ +void DMA3_IRQHandler(void) +{ + DMA_DRV_IRQhandler(3); +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + + diff --git a/KSDK_1.2.0/platform/drivers/src/dma/fsl_dma_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/dma/fsl_dma_lpm_callback.c new file mode 100755 index 0000000..f63c316 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dma/fsl_dma_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_DMA_COUNT + +power_manager_error_code_t dma_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t dma_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_common.c b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_common.c new file mode 100755 index 0000000..97c7b64 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_common.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/* Pointer to runtime state structure.*/ +void * g_dspiStatePtr[SPI_INSTANCE_COUNT] = { NULL }; + +/*! @brief Table of base pointers for SPI instances. */ +SPI_Type * const g_dspiBase[SPI_INSTANCE_COUNT] = SPI_BASE_PTRS; + +/*! @brief Table of SPI FIFO sizes per instance. */ +const uint32_t g_dspiFifoSize[SPI_INSTANCE_COUNT] = FSL_FEATURE_DSPI_FIFO_SIZEx; + +/*! + * @brief Table to save DSPI IRQ enum numbers defined in CMSIS files. + * + * This is used by DSPI master and slave init functions to enable or disable DSPI interrupts. + * This table is indexed by the module instance number and returns DSPI IRQ numbers. + */ +const IRQn_Type g_dspiIrqId[] = SPI_IRQS; + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +/******************************************************************************* +* EOF +******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_edma_irq.c b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_edma_irq.c new file mode 100755 index 0000000..841aa95 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_edma_irq.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <stdbool.h> +#include "fsl_device_registers.h" + +/*! + * @addtogroup dspi_irq + * @{ + */ + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if (SPI_INSTANCE_COUNT == 1) +/*! + * @brief This function is the implementation of SPI0 handler named in startup code. + * + * It passes the instance to the shared DSPI IRQ handler. + */ +void SPI0_IRQHandler(void) +{ + DSPI_DRV_EdmaIRQHandler(SPI0_IDX); +} + +#elif (SPI_INSTANCE_COUNT == 2) +/*! + * @brief This function is the implementation of SPI0 handler named in startup code. + * + * It passes the instance to the shared DSPI IRQ handler. + */ +void SPI0_IRQHandler(void) +{ + DSPI_DRV_EdmaIRQHandler(SPI0_IDX); +} + +/*! + * @brief This function is the implementation of SPI1 handler named in startup code. + * + * It passes the instance to the shared DSPI IRQ handler. + */ +void SPI1_IRQHandler(void) +{ + DSPI_DRV_EdmaIRQHandler(SPI1_IDX); +} + +#else +/*! + * @brief This function is the implementation of SPI0 handler named in startup code. + * + * It passes the instance to the shared DSPI IRQ handler. + */ +void SPI0_IRQHandler(void) +{ + DSPI_DRV_EdmaIRQHandler(SPI0_IDX); +} + +/*! + * @brief This function is the implementation of SPI1 handler named in startup code. + * + * It passes the instance to the shared DSPI IRQ handler. + */ +void SPI1_IRQHandler(void) +{ + DSPI_DRV_EdmaIRQHandler(SPI1_IDX); +} + +/*! + * @brief This function is the implementation of SPI2 handler named in startup code. + * + * It passes the instance to the shared DSPI IRQ handler. + */ +void SPI2_IRQHandler(void) +{ + DSPI_DRV_EdmaIRQHandler(SPI2_IDX); +} + +#endif + +/*! @} */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_edma_master_driver.c b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_edma_master_driver.c new file mode 100755 index 0000000..0eb2338 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_edma_master_driver.c @@ -0,0 +1,1339 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string.h> +#include "fsl_dspi_edma_master_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Pointer to runtime state structure.*/ +extern void * g_dspiStatePtr[SPI_INSTANCE_COUNT]; + +/* For storing DMA intermediate buffers between the source buffer and TX FIFO */ +static uint32_t s_cmdData; /* Intermediate 16-bit command and 16-bit data buffer */ +static uint32_t s_lastCmdData; /* Consists of the last command and the final source data */ +static uint16_t s_wordToSend; /* Word to send, if no send buffer, this variable is used + as the word to send, which should be initialized to 0. Needs + to be static and stored in data section as this variable + address is the source address if no source buffer. */ +static uint8_t s_rxBuffIfNull; /* If no receive buffer provided, direct rx DMA channel to this + destination */ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static dspi_status_t DSPI_DRV_EdmaMasterStartTransfer(uint32_t instance, + const dspi_edma_device_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount); + +static void DSPI_DRV_EdmaMasterCompleteTransfer(uint32_t instance); + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaMasterInit + * Description : Initializes a DSPI instance for master mode operation to work with EDMA. + * This function uses a dma driven method for transferring data. + * This function initializes the run-time state structure to track the ongoing + * transfers, ungates the clock to the DSPI module, resets the DSPI module, initializes the module + * to user defined settings and default settings, configures the IRQ state structure, enables + * the module-level interrupt to the core, and enables the DSPI module. + * The CTAR parameter is special in that it allows the user to have different SPI devices + * connected to the same DSPI module instance in addition to different peripheral chip + * selects. Each CTAR contains the bus attributes associated with that particular SPI device. + * For most use cases where only one SPI device is connected per DSPI module + * instance, use CTAR0. + * This is an example to set up and call the DSPI_DRV_EdmaMasterInit function by passing + * in these parameters: + * dspi_edma_master_state_t dspiEdmaState; <- the user simply allocates memory for this struct + * uint32_t calculatedBaudRate; + * dspi_edma_master_user_config_t userConfig; <- the user fills out members for this struct + * userConfig.isChipSelectContinuous = false; + * userConfig.isSckContinuous = false; + * userConfig.pcsPolarity = kDspiPcs_ActiveLow; + * userConfig.whichCtar = kDspiCtar0; + * userConfig.whichPcs = kDspiPcs0; + * DSPI_DRV_EdmaMasterInit(masterInstance, &dspiEdmaState, &userConfig); + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaMasterInit(uint32_t instance, + dspi_edma_master_state_t * dspiEdmaState, + const dspi_edma_master_user_config_t * userConfig, + edma_software_tcd_t * stcdSrc2CmdDataLast) +{ + uint32_t dspiSourceClock; + SPI_Type *base = g_dspiBase[instance]; + + /* Check parameter pointers to make sure there are not NULL */ + if ((dspiEdmaState == NULL) || (userConfig == NULL) || (stcdSrc2CmdDataLast == NULL)) + { + return kStatus_DSPI_InvalidParameter; + } + + /* Check to see if stcdSrc2CmdDataLast is aligned to a 32-byte boundary */ + if ((uint32_t)stcdSrc2CmdDataLast & 0x1FU) + { + return kStatus_DSPI_EdmaStcdUnaligned32Error; + } + + /* Clear the run-time state struct for this instance.*/ + memset(dspiEdmaState, 0, sizeof(* dspiEdmaState)); + + /* Note, remember to first enable clocks to the DSPI module before making any register accesses + * Enable clock for DSPI + */ + CLOCK_SYS_EnableSpiClock(instance); + /* Get module clock freq*/ + dspiSourceClock = CLOCK_SYS_GetSpiFreq(instance); + + /* Configure the run-time state struct with the DSPI source clock */ + dspiEdmaState->dspiSourceClock = dspiSourceClock; + + /* Configure the run-time state struct with the data command parameters*/ + dspiEdmaState->whichCtar = userConfig->whichCtar; /* set the dspiEdmaState struct CTAR*/ + dspiEdmaState->whichPcs = userConfig->whichPcs; /* set the dspiEdmaState struct whichPcs*/ + dspiEdmaState->isChipSelectContinuous = userConfig->isChipSelectContinuous; /* continuous PCS*/ + + /* Initialize the DSPI module registers to default value, which disables the module */ + DSPI_HAL_Init(base); + + /* Init the interrupt sync object.*/ + if (OSA_SemaCreate(&dspiEdmaState->irqSync, 0) != kStatus_OSA_Success) + { + return kStatus_DSPI_Error; + } + + /* Initialize the DSPI module with user config */ + + /* Set to master mode.*/ + DSPI_HAL_SetMasterSlaveMode(base, kDspiMaster); + + /* Configure for continuous SCK operation*/ + DSPI_HAL_SetContinuousSckCmd(base, userConfig->isSckContinuous); + + /* Configure for peripheral chip select polarity*/ + DSPI_HAL_SetPcsPolarityMode(base, userConfig->whichPcs, userConfig->pcsPolarity); + + /* Enable fifo operation (regardless of FIFO depth) */ + DSPI_HAL_SetFifoCmd(base, true, true); + + /* Initialize the configurable delays: PCS-to-SCK, prescaler = 0, scaler = 1 */ + DSPI_HAL_SetDelay(base, userConfig->whichCtar, 0, 1, kDspiPcsToSck); + + /* Save runtime structure pointers to irq handler can point to the correct state structure*/ + g_dspiStatePtr[instance] = dspiEdmaState; + + /* enable the interrupt*/ + INT_SYS_EnableIRQ(g_dspiIrqId[instance]); + + /* DSPI system enable */ + DSPI_HAL_Enable(base); + + + /* Request DMA channels from the EDMA peripheral driver. + * Note, some MCUs have a separate RX and TX DMA request for each DSPI instance, while + * other MCUs have a separate RX and TX DMA request for DSPI instance 0 only and shared DMA + * requests for all other instances. Therefore, use the DSPI feature file to distinguish + * how to request DMA channels between the various MCU DSPI instances. + * For DSPI instances with shared RX/TX DMA requests, we'll use the RX DMA request to + * trigger ongoing transfers and will link to the TX DMA channel from the RX DMA channel. + */ + if (instance == 0) + { + /* Set up channels for separate RX/TX DMA requests */ + /* This channel transfers data from RX FIFO to receiveBuffer */ + if (EDMA_DRV_RequestChannel(kEDMAAnyChannel, + kDmaRequestMux0SPI0Rx, + &dspiEdmaState->dmaFifo2Receive) == kEDMAInvalidChannel) + { + return kStatus_DSPI_DMAChannelInvalid; + } + + /* Intermediate command/data to TX FIFO (PUSHR). */ + if (EDMA_DRV_RequestChannel(kEDMAAnyChannel, + kDmaRequestMux0SPI0Tx, + &dspiEdmaState->dmaCmdData2Fifo) == kEDMAInvalidChannel) + { + return kStatus_DSPI_DMAChannelInvalid; + } + } + + else if (instance == 1) + { +#if (SPI_INSTANCE_COUNT > 1) /* Continue only if the MCU has another DSPI instance */ + /* Set up channels for separate RX/TX DMA requests */ +#if FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(1) + { + /* This channel transfers data from RX FIFO to receiveBuffer */ + if (EDMA_DRV_RequestChannel(kEDMAAnyChannel, + kDmaRequestMux0SPI1Rx, + &dspiEdmaState->dmaFifo2Receive) == kEDMAInvalidChannel) + { + return kStatus_DSPI_DMAChannelInvalid; + } + + /* Intermediate command/data to TX FIFO (PUSHR). */ + if (EDMA_DRV_RequestChannel(kEDMAAnyChannel, + kDmaRequestMux0SPI1Tx, + &dspiEdmaState->dmaCmdData2Fifo) == kEDMAInvalidChannel) + { + return kStatus_DSPI_DMAChannelInvalid; + } + } +#else /* Set up channels for shared RX/TX DMA request */ + { + /* This channel transfers data from RX FIFO to receiveBuffer */ + if (EDMA_DRV_RequestChannel(kEDMAAnyChannel, + kDmaRequestMux0SPI1, + &dspiEdmaState->dmaFifo2Receive) == kEDMAInvalidChannel) + { + return kStatus_DSPI_DMAChannelInvalid; + } + + /* Intermediate command/data to TX FIFO (PUSHR) linked from RX channel. + * This channel is not activated by dma request, but by channel link from RX. + */ + if (EDMA_DRV_RequestChannel(kEDMAAnyChannel, + kDmaRequestMux0Disable, + &dspiEdmaState->dmaCmdData2Fifo) == kEDMAInvalidChannel) + { + return kStatus_DSPI_DMAChannelInvalid; + } + } +#endif + +#else + return kStatus_DSPI_InvalidInstanceNumber; +#endif + } + + else + { +#if (SPI_INSTANCE_COUNT > 2) /* Continue only if the MCU has another DSPI instance */ + /* Set up channels for separate RX/TX DMA requests */ +#if (FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(2)) + { + /* This channel transfers data from RX FIFO to receiveBuffer */ + if (EDMA_DRV_RequestChannel(kEDMAAnyChannel, + kDmaRequestMux0SPI2Rx, + &dspiEdmaState->dmaFifo2Receive) == kEDMAInvalidChannel) + { + return kStatus_DSPI_DMAChannelInvalid; + } + + /* Intermediate command/data to TX FIFO (PUSHR). */ + if (EDMA_DRV_RequestChannel(kEDMAAnyChannel, + kDmaRequestMux0SPI2Tx, + &dspiEdmaState->dmaCmdData2Fifo) == kEDMAInvalidChannel) + { + return kStatus_DSPI_DMAChannelInvalid; + } + } +#else /* Set up channels for shared RX/TX DMA request */ + { + /* This channel transfers data from RX FIFO to receiveBuffer */ + if (EDMA_DRV_RequestChannel(kEDMAAnyChannel, + kDmaRequestMux0SPI2, + &dspiEdmaState->dmaFifo2Receive) == kEDMAInvalidChannel) + { + return kStatus_DSPI_DMAChannelInvalid; + } + + /* Intermediate command/data to TX FIFO (PUSHR) linked from RX channel. + * This channel is not activated by dma request, but by channel link from RX. + */ + if (EDMA_DRV_RequestChannel(kEDMAAnyChannel, + kDmaRequestMux0Disable, + &dspiEdmaState->dmaCmdData2Fifo) == kEDMAInvalidChannel) + { + return kStatus_DSPI_DMAChannelInvalid; + } + } +#endif + +#else + return kStatus_DSPI_InvalidInstanceNumber; +#endif + } + + /* Source buffer to intermediate command/data + * This channel is not activated by dma request, but by channel link. + */ + if (EDMA_DRV_RequestChannel(kEDMAAnyChannel, + kDmaRequestMux0Disable, + &dspiEdmaState->dmaSrc2CmdData) == kEDMAInvalidChannel) + { + return kStatus_DSPI_DMAChannelInvalid; + } + + /************************************************************************************** + * Update run-time state struct with the pointer to Software Transfer Control Descriptor + **************************************************************************************/ + dspiEdmaState->stcdSrc2CmdDataLast = stcdSrc2CmdDataLast; + + /* Start the transfer process in the hardware */ + DSPI_HAL_StartTransfer(base); + + return kStatus_DSPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaMasterDeinit + * Description : Shuts down a DSPI instance with EDMA support. + * + * This function resets the DSPI peripheral, gates its clock, disables any used interrupts to + * the core, and releases any used DMA channels. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaMasterDeinit(uint32_t instance) +{ + /* instantiate local variable of type dspi_edma_master_state_t and point to global state */ + dspi_edma_master_state_t * dspiEdmaState = (dspi_edma_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + /* First stop transfers */ + DSPI_HAL_StopTransfer(base); + + /* Restore the module to defaults then power it down. This also disables the DSPI module.*/ + DSPI_HAL_Init(base); + + /* destroy the interrupt sync object.*/ + OSA_SemaDestroy(&dspiEdmaState->irqSync); + + /* disable the interrupt*/ + INT_SYS_DisableIRQ(g_dspiIrqId[instance]); + + /* Gate the clock for DSPI.*/ + CLOCK_SYS_DisableSpiClock(instance); + + /* Release all of the DMA channels used in the driver. DMA channel structures are stored in + * the run-time state structure. + */ + EDMA_DRV_ReleaseChannel(&dspiEdmaState->dmaCmdData2Fifo); + EDMA_DRV_ReleaseChannel(&dspiEdmaState->dmaSrc2CmdData); + EDMA_DRV_ReleaseChannel(&dspiEdmaState->dmaFifo2Receive); + + /* Clear state pointer. */ + g_dspiStatePtr[instance] = NULL; + + return kStatus_DSPI_Success; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaMasterSetDelay + * Description : Configures the DSPI master mode bus timing delay options with EDMA support. + * + * This function allows the user to take advantage of the DSPI module's delay options in order to + * "fine tune" some of the signal timings to match the timing needs of a slower peripheral device. + * This is an optional function that can be called after the DSPI module has been initialized for + * master mode. + * The bus timing delays that can be adjusted are listed below: + * + * PCS to SCK Delay: Adjustable delay option between the assertion of the PCS signal to the + * first SCK edge. + * + * After SCK Delay: Adjustable delay option between the last edge of SCK to the de-assertion + * of the PCS signal. + * + * Delay after Transfer: Adjustable delay option between the de-assertion of the PCS signal for a + * frame to the assertion of the PCS signal for the next frame. Note this + * is not adjustable for continuous clock mode as this delay is fixed at + * one SCK period. + * + * Each of the above delay parameters use both a pre-scalar and scalar value to calculate the + * needed delay. This function takes in as a parameter the desired delay type and the + * delay value (in nanoseconds), calculates the values needed for the prescaler and scaler. + * Returning the actual calculated delay as an exact delay match may not be possible. In this + * case, the closest match is calculated without going below the desired delay value input. + * It is possible to input a very large delay value that exceeds the capability of the part, in + * which case the maximum supported delay is returned. In addition, the function returns + * an out-of-range status. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaMasterSetDelay(uint32_t instance, dspi_delay_type_t whichDelay, + uint32_t delayInNanoSec, uint32_t * calculatedDelay) +{ + /* instantiate local variable of type dspi_edma_master_state_t and point to global state */ + dspi_edma_master_state_t * dspiEdmaState = (dspi_edma_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + dspi_status_t errorCode = kStatus_DSPI_Success; + + *calculatedDelay = DSPI_HAL_CalculateDelay(base, dspiEdmaState->whichCtar, whichDelay, + dspiEdmaState->dspiSourceClock, delayInNanoSec); + + /* If the desired delay exceeds the capability of the device, alert the user */ + if (*calculatedDelay < delayInNanoSec) + { + errorCode = kStatus_DSPI_OutOfRange; + } + + return errorCode; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaMasterConfigureBus + * Description : Configures the DSPI port physical parameters to access a device on the bus with + * EDMA support. + * + * The term "device" is used to indicate the SPI device for which the DSPI master is communicating. + * The user has two options to configure the device parameters: either pass in the + * pointer to the device configuration structure to the desired transfer function (see + * DSPI_DRV_EdmaMasterTransferBlocking or DSPI_DRV_EdmaMasterTransfer) or pass it in to the + * DSPI_DRV_EdmaMasterConfigureBus function. The user can pass in a device structure to the + * transfer function which contains the parameters for the bus (the transfer function then calls + * this function). However, the user has the option to call this function directly especially + * to get the calculated baud rate, at which point they may pass in NULL for the device + * structure in the transfer function (assuming they have called this configure bus function + * first). This is an example to set up the dspi_device_t structure to call + * the DSPI_DRV_EdmaMasterConfigureBus function by passing in these parameters: + * dspi_edma_device_t spiDevice; + * spiDevice.dataBusConfig.bitsPerFrame = 16; + * spiDevice.dataBusConfig.clkPhase = kDspiClockPhase_FirstEdge; + * spiDevice.dataBusConfig.clkPolarity = kDspiClockPolarity_ActiveHigh; + * spiDevice.dataBusConfig.direction = kDspiMsbFirst; + * spiDevice.bitsPerSec = 50000; + * DSPI_DRV_EdmaMasterConfigureBus(instance, &spiDevice, &calculatedBaudRate); + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaMasterConfigureBus(uint32_t instance, + const dspi_edma_device_t * device, + uint32_t * calculatedBaudRate) +{ + assert(device); + /* instantiate local variable of type dspi_edma_master_state_t and point to global state */ + dspi_edma_master_state_t * dspiEdmaState = (dspi_edma_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + dspi_status_t errorCode = kStatus_DSPI_Success; + + /* Configure the bus to access the provided device.*/ + *calculatedBaudRate = DSPI_HAL_SetBaudRate(base, dspiEdmaState->whichCtar, + device->bitsPerSec, dspiEdmaState->dspiSourceClock); + + errorCode = DSPI_HAL_SetDataFormat(base, dspiEdmaState->whichCtar, &device->dataBusConfig); + + /* Check bits/frame number */ + if (device->dataBusConfig.bitsPerFrame > 16) + { + errorCode = kStatus_DSPI_OutOfRange; + } + else + { + dspiEdmaState->bitsPerFrame = device->dataBusConfig.bitsPerFrame; /* update bits/frame */ + } + + return errorCode; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaMasterTransferBlocking + * Description : Performs a blocking SPI master mode transfer with EDMA support. + * + * This function simultaneously sends and receives data on the SPI bus, as SPI is naturally + * a full-duplex bus. The function does not return until the transfer is complete. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaMasterTransferBlocking(uint32_t instance, + const dspi_edma_device_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount, + uint32_t timeout) +{ + /* instantiate local variable of type dspi_edma_master_state_t and point to global state */ + dspi_edma_master_state_t * dspiEdmaState = (dspi_edma_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + dspi_status_t error = kStatus_DSPI_Success; + + dspiEdmaState->isTransferBlocking = true; /* Indicates this is a blocking transfer */ + + /* If the transfer count is zero, then return immediately.*/ + if (transferByteCount == 0) + { + return error; + } + + /* If using a shared RX/TX DMA request, then this limits the amount of data we can transfer + * due to the linked channel. The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame + */ + if (!FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(instance)) + { + if (dspiEdmaState->bitsPerFrame > 8) + { + if (transferByteCount > 1022) + { + return kStatus_DSPI_OutOfRange; + } + } + else + { + if (transferByteCount > 511) + { + return kStatus_DSPI_OutOfRange; + } + } + } + + /* As this is a synchronous transfer, set up the sync status variable*/ + osa_status_t syncStatus; + + if (DSPI_DRV_EdmaMasterStartTransfer(instance, device, sendBuffer, receiveBuffer, + transferByteCount) == kStatus_DSPI_Busy) + { + return kStatus_DSPI_Busy; + } + + /* As this is a synchronous transfer, wait until the transfer is complete.*/ + do + { + syncStatus = OSA_SemaWait(&dspiEdmaState->irqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + /* If a timeout occurs, stop the transfer by setting the isTransferInProgress to false and + * disabling DMA requests and interrupts, then return the timeout error status. + */ + if (syncStatus != kStatus_OSA_Success) + { + /* The transfer is complete.*/ + dspiEdmaState->isTransferInProgress = false; + + /* Disable the Receive FIFO Drain DMA Request */ + DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateDmaReq, false); + + /* Disable TFFF DMA request */ + DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateDmaReq, false); + + /* Disable End of Queue request */ + DSPI_HAL_SetIntMode(base, kDspiEndOfQueue, false); + + error = kStatus_DSPI_Timeout; + } + + return error; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaMasterTransfer + * Description : Performs a non-blocking SPI master mode transfer with EDMA support. + * + * This function returns immediately. The user must check back to + * check whether the transfer is complete (using the DSPI_DRV_EdmaMasterGetTransferStatus function). + * This function simultaneously sends and receives data on the SPI bus, as SPI is naturally + * a full-duplex bus. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaMasterTransfer(uint32_t instance, + const dspi_edma_device_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount) +{ + /* instantiate local variable of type dspi_edma_master_state_t and point to global state */ + dspi_edma_master_state_t * dspiEdmaState = (dspi_edma_master_state_t *)g_dspiStatePtr[instance]; + + dspiEdmaState->isTransferBlocking = false; /* Indicates this is not a blocking transfer */ + + /* If the transfer count is zero, then return immediately.*/ + if (transferByteCount == 0) + { + return kStatus_DSPI_Success; + } + + /* If using a shared RX/TX DMA request, then this limits the amount of data we can transfer + * due to the linked channel. The max bytes is 511. + */ + if (!FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(instance)) + { + if (dspiEdmaState->bitsPerFrame > 8) + { + if (transferByteCount > 1022) + { + return kStatus_DSPI_OutOfRange; + } + } + else + { + if (transferByteCount > 511) + { + return kStatus_DSPI_OutOfRange; + } + } + } + + /* start the transfer process*/ + if (DSPI_DRV_EdmaMasterStartTransfer(instance, device, sendBuffer, receiveBuffer, + transferByteCount) == kStatus_DSPI_Busy) + { + return kStatus_DSPI_Busy; + } + + /* Else, return immediately as this is an async transfer */ + return kStatus_DSPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaMasterGetTransferStatus + * Description : Returns whether the previous transfer is finished with EDMA support. + * + * When performing an a-sync transfer, the user can call this function to ascertain the state of the + * current transfer: in progress (or busy) or complete (success). In addition, if the transfer + * is still in progress, the user can get the number of words that have been + * transferred up to now. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaMasterGetTransferStatus(uint32_t instance, uint32_t * framesTransferred) +{ + /* instantiate local variable of type dspi_edma_master_state_t and point to global state */ + dspi_edma_master_state_t * dspiEdmaState = (dspi_edma_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + /* Fill in the bytes transferred.*/ + if (framesTransferred) + { + *framesTransferred = DSPI_HAL_GetTransferCount(base); + } + + return (dspiEdmaState->isTransferInProgress ? kStatus_DSPI_Busy : kStatus_DSPI_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaMasterAbortTransfer + * Description : Terminates an asynchronous transfer early with EDMA support. + * + * During an async transfer, the user has the option to terminate the transfer early if the transfer + * is still in progress. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaMasterAbortTransfer(uint32_t instance) +{ + /* instantiate local variable of type dspi_edma_master_state_t and point to global state */ + dspi_edma_master_state_t * dspiEdmaState = (dspi_edma_master_state_t *)g_dspiStatePtr[instance]; + + /* Check if a transfer is running.*/ + if (!dspiEdmaState->isTransferInProgress) + { + return kStatus_DSPI_NoTransferInProgress; + } + + /* Stop the running transfer.*/ + DSPI_DRV_EdmaMasterCompleteTransfer(instance); + + return kStatus_DSPI_Success; +} + +/*! + * @brief Initiate (start) a transfer using DMA. This is not a public API as it is called from + * other driver functions + */ +static dspi_status_t DSPI_DRV_EdmaMasterStartTransfer(uint32_t instance, + const dspi_edma_device_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount) +{ + /* instantiate local variable of type dspi_edma_master_state_t and point to global state */ + dspi_edma_master_state_t * dspiEdmaState = (dspi_edma_master_state_t *)g_dspiStatePtr[instance]; + /* For temporarily storing DMA instance and channel */ + DMA_Type * dmaBaseAddr; + uint32_t dmaChannel; + uint32_t calculatedBaudRate; + dspi_command_config_t command; /* create an instance of the data command struct*/ + SPI_Type *base = g_dspiBase[instance]; + edma_transfer_config_t config; + uint32_t txTransferByteCnt = 0; + uint32_t rxTransferByteCnt = 0; + + /* Initialize s_wordToSend */ + s_wordToSend = 0; + + /* Check that we're not busy.*/ + if (dspiEdmaState->isTransferInProgress) + { + return kStatus_DSPI_Busy; + } + + /* Configure bus for this device. If NULL is passed, we assume the caller has + * preconfigured the bus using DSPI_DRV_EdmaMasterConfigureBus(). + * Do nothing for calculatedBaudRate. If the user wants to know the calculatedBaudRate + * then they can call this function separately. + */ + if (device) + { + DSPI_DRV_EdmaMasterConfigureBus(instance, device, &calculatedBaudRate); + dspiEdmaState->bitsPerFrame = device->dataBusConfig.bitsPerFrame; /*update bits/frame*/ + } + + /* Check the transfer byte count. If bits/frame > 8, meaning 2 bytes, and if + * the transfer byte count is an odd count we'll have to increase the TX transfer byte count + * by one and assert a flag to indicate to the send functions that it will + * need to handle an extra byte. + * For receive, we actually round down the transfer count to the next lowest even number. + * Then in the interrupt handler, we take care of geting this last byte. + */ + if ((dspiEdmaState->bitsPerFrame > 8) && (transferByteCount & 1UL)) + { + dspiEdmaState->extraByte = true; + txTransferByteCnt = transferByteCount + 1U; /* Increment to next even byte count */ + rxTransferByteCnt = transferByteCount & ~1U; /* Decrement to next even byte count */ + } + else + { + dspiEdmaState->extraByte = false; + txTransferByteCnt = transferByteCount; + rxTransferByteCnt = transferByteCount; + } + /* Store the receiveBuffer pointer and receive byte count to the run-time state struct + * for later use in the interrupt handler. + */ + dspiEdmaState->rxBuffer = (uint8_t *)receiveBuffer; + dspiEdmaState->rxTransferByteCnt = rxTransferByteCnt; + + /* Save information about the transfer for use by the ISR.*/ + dspiEdmaState->isTransferInProgress = true; + + /* Reset the transfer counter to 0. Normally this is done via the PUSHR[CTCNT], but as we + * are under DMA controller, we won't be able to change this bit dynamically after the + * first word is transferred. + */ + DSPI_HAL_PresetTransferCount(base, 0); + + /* flush the fifos*/ + DSPI_HAL_SetFlushFifoCmd(base, true, true); + + /* Clear status flags that may have been set from previous transfers */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxComplete); + DSPI_HAL_ClearStatusFlag(base, kDspiEndOfQueue); + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoUnderflow); + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest); + DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoOverflow); + DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoDrainRequest); + + /* Enable the End Of Queue interrupt, which will set when DSPI sees EOQ bit set in the + * last data word being sent. The ISR should clear this flag. + */ + DSPI_HAL_SetIntMode(base, kDspiEndOfQueue, true); + + /* Each DMA channel's CSR[DONE] bit may be set if a previous transfer occurred. The DONE + * bit, as the name implies, sets when the channel is finished (completed it's MAJOR + * LOOP). The DONE needs to be cleared before programming the channel's TCDs for the next + * transfer. + */ + dmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiEdmaState->dmaCmdData2Fifo.channel); + dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiEdmaState->dmaCmdData2Fifo.channel); + EDMA_HAL_ClearDoneStatusFlag(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel); + EDMA_HAL_HTCDClearReg(dmaBaseAddr, dmaChannel); + + dmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiEdmaState->dmaSrc2CmdData.channel); + dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiEdmaState->dmaSrc2CmdData.channel); + EDMA_HAL_ClearDoneStatusFlag(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel); + EDMA_HAL_HTCDClearReg(dmaBaseAddr, dmaChannel); + + dmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiEdmaState->dmaFifo2Receive.channel); + dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiEdmaState->dmaFifo2Receive.channel); + EDMA_HAL_ClearDoneStatusFlag(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel); + EDMA_HAL_HTCDClearReg(dmaBaseAddr, dmaChannel); + + /************************************************************************************ + * Set up the RX DMA channel Transfer Control Descriptor (TCD) + * Do this before filling the TX FIFO. + * Note, if there is no remaining receive count, then bypass RX DMA set up. + * This means we only have one byte to read of a 16-bit data word and will read this + * in the complete transfer function. + ***********************************************************************************/ + /* If a receive buffer is used and if rxTransferByteCnt > 0 */ + if (rxTransferByteCnt) + { + /* For each transfer control descriptor set up, save off DMA instance and channel number + * to simplified variable names to make code cleaner + */ + dmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiEdmaState->dmaFifo2Receive.channel); + dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiEdmaState->dmaFifo2Receive.channel); + + /* Source addr, RX FIFO */ + EDMA_HAL_HTCDSetSrcAddr(dmaBaseAddr,dmaChannel, DSPI_HAL_GetPoprRegAddr(base)); + + /* Source addr offset is 0 as source addr never increments */ + EDMA_HAL_HTCDSetSrcOffset(dmaBaseAddr, dmaChannel, 0); + + /* The source and destination attributes (bit size) depends on bits/frame setting */ + if (dspiEdmaState->bitsPerFrame <= 8) + { + /* Source size is one byte, destination size is one byte */ + EDMA_HAL_HTCDSetAttribute( + dmaBaseAddr, dmaChannel, + kEDMAModuloDisable, kEDMAModuloDisable, + kEDMATransferSize_1Bytes,kEDMATransferSize_1Bytes); + + /* Transfer 1 byte from RX FIFO to receive buffer */ + EDMA_HAL_HTCDSetNbytes(dmaBaseAddr, dmaChannel, 1); + + /* Set MAJOR count to remaining receive byte count. Configure both the + * CITER and BITER fields. + */ + EDMA_HAL_HTCDSetMajorCount(dmaBaseAddr, dmaChannel, (uint32_t)rxTransferByteCnt); + } + else /* For 16-bit words, but the receive buffer is still an 8-bit buffer */ + { + /* Source size is 2 byte, destination size is one byte */ + EDMA_HAL_HTCDSetAttribute( + dmaBaseAddr, dmaChannel, + kEDMAModuloDisable, kEDMAModuloDisable, + kEDMATransferSize_2Bytes,kEDMATransferSize_1Bytes); + + /* Transfer 2 bytes from RX FIFO to receive buffer */ + EDMA_HAL_HTCDSetNbytes(dmaBaseAddr, dmaChannel, 2); + + /* Set MAJOR count to remaining receive byte count. Configure both the + * CITER and BITER fields. Divide by 2 to account for minor loop of 2 bytes + */ + EDMA_HAL_HTCDSetMajorCount(dmaBaseAddr, dmaChannel, (uint32_t)rxTransferByteCnt/2); + } + + /* Don't increment source address, it is constant */ + EDMA_HAL_HTCDSetSrcLastAdjust(dmaBaseAddr, dmaChannel, 0); + + /* If no receive buffer then disable incrementing the destination and set the destination + * to a temporary location. Always handle rx operations to avoid rx overrun. + */ + if (!receiveBuffer) + { + /* Destination is the "throw away" receive buffer */ + EDMA_HAL_HTCDSetDestAddr(dmaBaseAddr, dmaChannel, (uint32_t)(&s_rxBuffIfNull)); + /* Dest addr offset, do not increment to the next byte */ + EDMA_HAL_HTCDSetDestOffset(dmaBaseAddr, dmaChannel, 0); + } + else /* Receive buffer is used */ + { + /* Destination is the receive buffer */ + EDMA_HAL_HTCDSetDestAddr(dmaBaseAddr, dmaChannel, (uint32_t)(receiveBuffer)); + /* Dest addr offset, increment to the next byte */ + EDMA_HAL_HTCDSetDestOffset(dmaBaseAddr, dmaChannel, 1); + } + + /* For DSPI instances with shared RX/TX DMA requests, we'll use the RX DMA request to + * trigger ongoing transfers and will link to the TX DMA channel from the RX DMA channel. + */ + if (FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(instance)) + { + /* Disable channel linking since we have separate RX and TX DMA requests */ + EDMA_HAL_HTCDSetChannelMinorLink(dmaBaseAddr, dmaChannel, 0, false); + } + else /* For shared RX/TX DMA Requests */ + { + /* Enable channel linking to TX channel (at the end of each minor loop) */ + EDMA_HAL_HTCDSetChannelMinorLink( + dmaBaseAddr, + dmaChannel, + VIRTUAL_CHN_TO_EDMA_CHN(dspiEdmaState->dmaCmdData2Fifo.channel), + true); + /* Enable MAJOR link and link to TX DMA channel. This is needed to perform one more + * channel link when the major loop is exhausted. + */ + EDMA_HAL_HTCDSetChannelMajorLink( + dmaBaseAddr, + dmaChannel, + VIRTUAL_CHN_TO_EDMA_CHN(dspiEdmaState->dmaCmdData2Fifo.channel), + true); + } + + /* No adjustment needed for destination addr */ + EDMA_HAL_HTCDSetDestLastAdjust(dmaBaseAddr,dmaChannel, 0); + + /* Disable ERQ request at end of major count so that we don't keep servicing requests */ + EDMA_HAL_HTCDSetDisableDmaRequestAfterTCDDoneCmd(dmaBaseAddr, dmaChannel, true); + + /* Now that TCD was set up, enable the DSPI Peripheral Hardware request for the RX FIFO */ + EDMA_HAL_SetDmaRequestCmd(dmaBaseAddr,(edma_channel_indicator_t)dmaChannel, true); + + /* Enable the Receive FIFO Drain Request as a DMA request */ + DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateDmaReq, true); + } + + /************************************************************************************ + * Set up the Last Command/data Word Intermediate Buffer and fill up the TX FIFO. + ***********************************************************************************/ + /* Before sending the data, we first need to initialize the data command struct + * Configure the data command attributes for the desired PCS, CTAR, and continuous PCS + * which are derived from the run-time state struct + */ + command.whichPcs = dspiEdmaState->whichPcs; + command.whichCtar = dspiEdmaState->whichCtar; + command.clearTransferCount = false; /* don't clear the transfer count */ + + /************************************************************************ + * Next, set up the Last Command/data Word Intermediate Buffer before + * filling up the TX FIFO + * Create a 32-bit word with the final 16-bit command settings. This means + * that EOQ = 1 and CONT = 0. + * This 32-bit word will also be initialized with the final data byte/word + * from the send source buffer and then the entire 32-bit word will be + * transferred to the DSPI PUSHR. + ************************************************************************/ + /* Declare a variable for storing the last send data (either 8- or 16-bit) */ + uint32_t lastWord = 0; + + /* If a send buffer was provided, the word comes from there. Otherwise we just send + * a zero (initialized above). + */ + if (sendBuffer) + { + /* Store the last byte from the send buffer */ + if (dspiEdmaState->bitsPerFrame <= 8) + { + lastWord = sendBuffer[txTransferByteCnt-1]; /* Last byte */ + } + /* Store the last two bytes the send buffer */ + else + { + /* If 16-bit transfers and odd transfer byte count then an extra byte was added + * to the transfer byte count, but we cannot access more of the send buffer + */ + if(!dspiEdmaState->extraByte) + { + lastWord = sendBuffer[txTransferByteCnt-1] ; /* Save off the last byte */ + lastWord = lastWord << 8U; /* Shift to MSB (separate step due to MISHA) */ + } + lastWord |= sendBuffer[txTransferByteCnt-2]; /* OR with next to last byte */ + } + } + + /* Now, build the last command/data word intermediate buffer */ + command.isChipSelectContinuous = false; /* Always clear CONT for last data word */ + command.isEndOfQueue = true; /* Set EOQ for last data word */ + s_lastCmdData = DSPI_HAL_GetFormattedCommand(base, &command) | lastWord; + /************************************************************************ + * Begin TX DMA channels transfer control descriptor set up. + * 1. First, set up intermediate buffers which contain 16-bit commands. + * 2. Set up the DMA Software Transfer Control Descriptors (STCD) for various + * scenarios: + * - Channel for intermediate buffer to TX FIFO + * - Channel for source buffer to intermediate buffer + * - STCD for scatter/gather for end of previous channel to replace + * intermediate buffer with last-command buffer. + ************************************************************************/ + + /************************************************************************ + * Intermediate Buffer + * Create a 32-bit word with the 16-bit command settings. Data from + * the send source buffer will be transferred here and then the entire + * 32-bit word will be transferred to the DSPI PUSHR. + * This buffer will be preloaded with the next data word in the send buffer + ************************************************************************/ + /* restore the isChipSelectContinuous setting to the original value as it was cleared above */ + command.isChipSelectContinuous = dspiEdmaState->isChipSelectContinuous; + command.isEndOfQueue = 0; /* Clear End of Queue (previously set for last cmd/data word)*/ + s_cmdData = DSPI_HAL_GetFormattedCommand(base, &command); + + /* Place the next data from the send buffer into the intermediate buffer (preload it) + * based on whether it is one byte or two. + */ + if (dspiEdmaState->bitsPerFrame <= 8) + { + /* If a send buffer was provided, the word comes from there. Otherwise we just send + * a zero (initialized above). + */ + if (sendBuffer) + { + s_wordToSend = *sendBuffer; /* queue up the next data */ + ++sendBuffer; /* increment to next data word*/ + } + --txTransferByteCnt; /* decrement txTransferByteCnt*/ + } + else + { + /* If a send buffer was provided, the word comes from there. Otherwise we just send + * a zero (initialized above). + */ + if (sendBuffer) + { + s_wordToSend = *sendBuffer; + ++sendBuffer; /* increment to next data byte */ + + /* Note, if the extraByte flag is set and we're down to the last two bytes we can still + * do this even though we're going past the sendBuffer size. We're just reading data we + * don't care about anyways since it is dummy data to make up for the last byte. + */ + s_wordToSend |= (unsigned)(*sendBuffer) << 8U; + ++sendBuffer; /* increment to next data byte */ + + } + txTransferByteCnt -= 2; /* decrement txTransferByteCnt by 2 bytes */ + } + + s_cmdData |= s_wordToSend; /* write s_wordToSend to intermediate buffer */ + + /************************************************************************************ + * Transfer Control Descriptor set up for Intermediate command/data to TX + * FIFO (PUSHR). AKA "Channel 1" + * Note, actual channel number may very depending on DMA system usage. + * This channels links to "Channel 1" on completion of MAJOR loop. "Channel 1" is + * the channel that transfers data from the send source buffer to the intermediate + * command/data buffer. + * Note that the channel linking is based on the MAJOR loop complete and not on minor + * loop. This is because we are only sending one 32-bit word so when the minor loop + * completes, the MAJOR loop also completes. The eDMA does not channel link on the + * last iteration of the MAJOR loop using the ELINK mechanism, hence we have to link + * on the MAJOR loop completion using MAJORLINK channel linking. + ************************************************************************************/ + /* For each transfer control descriptor set up, save off DMA instance and channel number + * to simplified variable names to make code cleaner + */ + dmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiEdmaState->dmaCmdData2Fifo.channel); + dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiEdmaState->dmaCmdData2Fifo.channel); + + /* If txTransferByteCnt is 0, then send last command/data since this is the + * last data word to send + */ + if (txTransferByteCnt == 0) + { + /* Source address is the last command/data intermediate buffer */ + EDMA_HAL_HTCDSetSrcAddr(dmaBaseAddr, dmaChannel,(uint32_t)(&s_lastCmdData)); + + /* Disable ERQ request at end of major count */ + EDMA_HAL_HTCDSetDisableDmaRequestAfterTCDDoneCmd(dmaBaseAddr, dmaChannel, true); + + /* Disable majorlink request */ + EDMA_HAL_HTCDSetChannelMajorLink(dmaBaseAddr, dmaChannel, 0, false); + } + /* Else, send the intermediate buffer */ + else + { + /* Source addr, intermediate command/data*/ + EDMA_HAL_HTCDSetSrcAddr(dmaBaseAddr, dmaChannel,(uint32_t)(&s_cmdData)); + + /* Set the MAJOR link channel to link to the next channel that will pull data from + * the source buffer into the intermediate command/data buffer and enable MAJOR link + */ + EDMA_HAL_HTCDSetChannelMajorLink(dmaBaseAddr, dmaChannel, + VIRTUAL_CHN_TO_EDMA_CHN(dspiEdmaState->dmaSrc2CmdData.channel), true); + + /* Do not disable ERQ request at end of major count */ + EDMA_HAL_HTCDSetDisableDmaRequestAfterTCDDoneCmd(dmaBaseAddr, dmaChannel, false); + } + + /* Source addr offset is 0 as source addr never increments */ + EDMA_HAL_HTCDSetSrcOffset(dmaBaseAddr, dmaChannel, 0); + + /* source size 32-bits */ + /* destination size 32bits*/ + /* Clear the SMOD and DMOD fields */ + EDMA_HAL_HTCDSetAttribute(dmaBaseAddr, dmaChannel, + kEDMAModuloDisable, kEDMAModuloDisable, + kEDMATransferSize_4Bytes, kEDMATransferSize_4Bytes); + + /* Transfer 4 bytes or one word */ + EDMA_HAL_HTCDSetNbytes(dmaBaseAddr, dmaChannel, 4); + + /* Don't increment source address, it is constant */ + EDMA_HAL_HTCDSetSrcLastAdjust(dmaBaseAddr, dmaChannel, 0); + + /* Destination is SPI PUSHR TX FIFO */ + EDMA_HAL_HTCDSetDestAddr(dmaBaseAddr, dmaChannel, DSPI_HAL_GetMasterPushrRegAddr(base)); + + /* No dest addr offset, since we never increment the dest addr */ + EDMA_HAL_HTCDSetDestOffset(dmaBaseAddr, dmaChannel, 0); + + /* We are only sending one 32-bit word, so MAJOR count is "1". Do not use "ELINK" + * to link channels, use MAJORLINK in CSR, therefore disable minor link (ELINK=0) + */ + EDMA_HAL_HTCDSetChannelMinorLink(dmaBaseAddr, dmaChannel, 0, false); + EDMA_HAL_HTCDSetMajorCount(dmaBaseAddr, dmaChannel, 1); + + /* No adjustment needed for destination addr or scatter/gather */ + EDMA_HAL_HTCDSetScatterGatherCmd(dmaBaseAddr, dmaChannel, false); + + /* Implement the following DMA channel set up only if we still have data yet to send + * Otherwise, bypass this and enable the DSPI Transmit DMA request. + */ + if (txTransferByteCnt != 0) + { + /************************************************************************************ + * Scatter/gather STCD set up + * STCD ONLY for Last intermediate command/data to PUSHR. Do not call + * edma_hal_stcd_push_to_htcd as this is used for "Channel 2" scatter/gather. + * Hence we will call this "Channel 2 prime". This needs to be defined before + * setting up "Channel 2" as it needs the address for this STCD. + * + * IMPORTANT: Per eDMA spec, the pointer address for this STCD structure needs to be + * aligned on 32-byte boundaries. + ************************************************************************************/ + /* This channel should use scatter gather method, first configure the last STCD */ + memset(&config, 0, sizeof(edma_transfer_config_t)); + memset(dspiEdmaState->stcdSrc2CmdDataLast, 0, sizeof(edma_software_tcd_t)); + + /* Fill out members of the EDMA transfer config structure and then use this structure to + * prepare the software transfer control descriptor stcdSrc2CmdDataLast + */ + config.srcAddr = (uint32_t)(&s_lastCmdData); /* Source addr is last data + last command */ + config.srcOffset = 0; + config.srcTransferSize = kEDMATransferSize_4Bytes; + config.destTransferSize = kEDMATransferSize_4Bytes; + config.destAddr = (uint32_t)(&s_cmdData); /* Destination is the command/data buffer */ + config.destOffset = 0; + config.destLastAddrAdjust = 0; + config.srcLastAddrAdjust = 0; + config.destModulo = kEDMAModuloDisable; + config.srcModulo = kEDMAModuloDisable; + config.majorLoopCount = 1; /* We are only sending one 32-bit word, so MAJOR count is "1" */ + config.minorLoopCount = 4; /* Transfer 4 bytes or one word */ + EDMA_DRV_PrepareDescriptorTransfer(&dspiEdmaState->dmaSrc2CmdData, + dspiEdmaState->stcdSrc2CmdDataLast, &config,false,true); + + /* If at this point we are left with only sending one more data byte/word, then this + * is the last command/data to send. So the transfer control descriptor should move the + * last command/data word into the intermediate buffer and this will get transferred to the + * DSPI when the FIFO is ready for this. + */ + if (((dspiEdmaState->bitsPerFrame <= 8) && ((txTransferByteCnt-1) == 0)) || + ((dspiEdmaState->bitsPerFrame > 8) && ((txTransferByteCnt-2) == 0))) + { + /* push the contents of the SW TCD to the HW TCD registers */ + EDMA_DRV_PushDescriptorToReg(&dspiEdmaState->dmaSrc2CmdData, + dspiEdmaState->stcdSrc2CmdDataLast); + } + /* Otherwise, we are left with more data to send, so use the transfer control + * descriptor that will move data from the send source buffer to the intermediate + * command/data buffer. + */ + else + { + /************************************************************************************ + * Transfer Control Descriptor set up for Source buffer to intermediate + * command/data (this is a linked channel). AKA "Channel 2" + * Note, actual channel number may very depending on DMA system usage + * This channel is triggered by the completion of "Channel 1". It transfers data from + * the send source buffer to the intermediate command/data word. When the source + * buffer transfers the word before the last data word, the MAJOR loop completes + * and triggers the scatter/gather (ESG = 1) and loads the STCD that is set up to + * transfer the last command/data word to the PUSHR. + ************************************************************************************/ + dmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiEdmaState->dmaSrc2CmdData.channel); + dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiEdmaState->dmaSrc2CmdData.channel); + + /* If a send buffer was provided, the word comes from there. Otherwise we set + * the source address to point to the s_wordToSend variable that was set to 0. + */ + if (sendBuffer) + { + /* Source addr is the "send" data buffer */ + EDMA_HAL_HTCDSetSrcAddr(dmaBaseAddr, dmaChannel, (uint32_t)(sendBuffer)); + /* Increment the source address by one byte after every transfer */ + EDMA_HAL_HTCDSetSrcOffset(dmaBaseAddr, dmaChannel, 1); + } + else + { + /* Source addr is the "send" data buffer */ + EDMA_HAL_HTCDSetSrcAddr(dmaBaseAddr, dmaChannel, + (uint32_t)(&s_wordToSend)); + /* Don't increment the source address */ + EDMA_HAL_HTCDSetSrcOffset(dmaBaseAddr, dmaChannel, 0); + } + + if (dspiEdmaState->bitsPerFrame <= 8) + { + /* Source and destination size: byte */ + EDMA_HAL_HTCDSetAttribute(dmaBaseAddr, dmaChannel, + kEDMAModuloDisable, kEDMAModuloDisable, + kEDMATransferSize_1Bytes, kEDMATransferSize_1Bytes); + + /* minor byte transfer: 1 byte (8-bit word) */ + EDMA_HAL_HTCDSetNbytes(dmaBaseAddr, dmaChannel, 1); + + /* Major loop count is equal to remaining number of bytes to send minus 1. + * That is because the last data byte/word is written to the last command/data + * intermediate buffer. + */ + EDMA_HAL_HTCDSetMajorCount(dmaBaseAddr, dmaChannel, (txTransferByteCnt-1)); + } + else + { + /* Source size: byte and destination size: halfword */ + EDMA_HAL_HTCDSetAttribute(dmaBaseAddr, dmaChannel, + kEDMAModuloDisable, kEDMAModuloDisable, + kEDMATransferSize_1Bytes, kEDMATransferSize_2Bytes); + + /* minor byte transfer: 2 bytes (16-bit word) */ + EDMA_HAL_HTCDSetNbytes(dmaBaseAddr, dmaChannel, 2); + + /* Major loop count is equal to remaining number of 16-bit words to send + * hence need to convert remainingSendByteCount from byte to 16-bit word + */ + EDMA_HAL_HTCDSetMajorCount(dmaBaseAddr, dmaChannel, (txTransferByteCnt-2)/2); + } + + /* Diable minor loop linking */ + EDMA_HAL_HTCDSetChannelMinorLink(dmaBaseAddr, dmaChannel, 0, false); + + /* Set SLAST to 0 */ + EDMA_HAL_HTCDSetSrcLastAdjust(dmaBaseAddr, dmaChannel, 0); + + /* Destination addr is the intermediate command/data buffer */ + EDMA_HAL_HTCDSetDestAddr(dmaBaseAddr, dmaChannel,(uint32_t)(&s_cmdData)); + + /* No dest addr offset, since we never increment the dest addr */ + EDMA_HAL_HTCDSetDestOffset(dmaBaseAddr, dmaChannel, 0); + + /* Place the address of the scatter/gather in order to reload STCD for the final + * last command/data word to be loaded to the intermediate buffer. + * IMPORTANT: This address needs to be 32-byte aligned. + */ + EDMA_HAL_HTCDSetScatterGatherLink(dmaBaseAddr, dmaChannel, + (edma_software_tcd_t *)(dspiEdmaState->stcdSrc2CmdDataLast)); + } + } + + dmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiEdmaState->dmaCmdData2Fifo.channel); + dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiEdmaState->dmaCmdData2Fifo.channel); + + /* For DSPI instances with separate RX/TX DMA requests, we'll use the TX DMA request to + * trigger the TX DMA channel hence we'll enable the TX channel DMA request. + */ + if (FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(instance)) + { + /* Now that the TCD was set up for each channel, enable the DSPI peripheral hardware request + * for the first TX DMA channel. + */ + EDMA_HAL_SetDmaRequestCmd(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel, true); + + /* Enable TFFF request in the DSPI module */ + DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateDmaReq, true); + } + /* For DSPI instances with shared RX/TX DMA requests, we'll use the RX DMA request to + * trigger ongoing transfers that will link to the TX DMA channel from the RX DMA channel. + * So, we'll disable the TX channel DMA request and then we'll have to manually start the + * TX DMA channel to get the tranfer process started, where the RX DMA channel will take care + * of the ongoing transfers from there. + */ + else /* For shared RX/TX DMA requests */ + { + /* Disable the DSPI TX peripheral hardware request*/ + EDMA_HAL_SetDmaRequestCmd(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel, false); + + /* Disable TFFF request in the DSPI module */ + DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateDmaReq, false); + + /* Manually start the TX DMA channel to get the process going */ + EDMA_HAL_TriggerChannelStart(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel); + } + + return kStatus_DSPI_Success; +} + +/*! + * @brief Finish up a transfer. + * Cleans up after a transfer is complete. Interrupts are disabled, and the DSPI module + * is disabled. This is not a public API as it is called from other driver functions. + */ +static void DSPI_DRV_EdmaMasterCompleteTransfer(uint32_t instance) +{ + /* instantiate local variable of type dspi_edma_master_state_t and point to global state */ + dspi_edma_master_state_t * dspiEdmaState = (dspi_edma_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + /* If an odd transfer count was provided when bits/frame > 8, then there will be an extra byte + * received. Get this byte now and put it into the receive buffer if a receive buffer was + * provided. + */ + if ((dspiEdmaState->extraByte) && (dspiEdmaState->rxBuffer)) + { + /* copy the final byte from the DSPI data register to the receive buffer */ + dspiEdmaState->rxBuffer[dspiEdmaState->rxTransferByteCnt] = DSPI_HAL_ReadData(base); + } + + /* The transfer is complete.*/ + dspiEdmaState->isTransferInProgress = false; + + /* Disable the Receive FIFO Drain DMA Request */ + DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateDmaReq, false); + + /* Disable TFFF DMA request */ + DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateDmaReq, false); + + /* Disable End of Queue request */ + DSPI_HAL_SetIntMode(base, kDspiEndOfQueue, false); + + if (dspiEdmaState->isTransferBlocking) + { + /* Signal the synchronous completion object */ + OSA_SemaPost(&dspiEdmaState->irqSync); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaMasterIRQHandler + * Description : Interrupt handler for DSPI master mode. + * This handler uses the buffers stored in the dspi_master_state_t structs to transfer data. + * + *END**************************************************************************/ +void DSPI_DRV_EdmaMasterIRQHandler(uint32_t instance) +{ + SPI_Type *base = g_dspiBase[instance]; + + /* If the interrupt is due to an end-of-queue, then complete. This interrupt is + * is used during DMA operations and we want to handle this interrupt only + * when DMA is being used. + */ + if (DSPI_HAL_GetStatusFlag(base, kDspiEndOfQueue)) + { + /* Complete the transfer. This disables the interrupts, so we don't wind up in + * the ISR again. + */ + DSPI_DRV_EdmaMasterCompleteTransfer(instance); + } +} + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_edma_shared_function.c b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_edma_shared_function.c new file mode 100755 index 0000000..de68e6e --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_edma_shared_function.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include "fsl_dspi_edma_shared_function.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Extern for the DSPI master driver's interrupt handler.*/ +extern void DSPI_DRV_EdmaMasterIRQHandler(uint32_t instance); + +/* Extern for the SPI slave driver's interrupt handler.*/ +extern void DSPI_DRV_EdmaSlaveIRQHandler(uint32_t instance); + +/******************************************************************************* + * Code + ******************************************************************************/ +/*! + * @brief The function DSPI_DRV_EdmaIRQHandler passes IRQ control to either the master or + * slave driver. + * + * The address of the IRQ handlers are checked to make sure they are non-zero before + * they are called. If the IRQ handler's address is zero, it means that driver was + * not present in the link (because the IRQ handlers are marked as weak). This would + * actually be a program error, because it means the master/slave config for the IRQ + * was set incorrectly. + */ +void DSPI_DRV_EdmaIRQHandler(uint32_t instance) +{ + assert(instance < SPI_INSTANCE_COUNT); + SPI_Type *base = g_dspiBase[instance]; + + if (DSPI_HAL_IsMaster(base)) + { + /* Master mode.*/ + DSPI_DRV_EdmaMasterIRQHandler(instance); + } + else + { + /* Slave mode.*/ + DSPI_DRV_EdmaSlaveIRQHandler(instance); + } +} + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_edma_slave_driver.c b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_edma_slave_driver.c new file mode 100755 index 0000000..b3c5209 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_edma_slave_driver.c @@ -0,0 +1,1157 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string.h> +#include <assert.h> +#include "fsl_dspi_edma_slave_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @brief Flags of DSPI slave event. + * + * DSPI event used to notify user that it finishes the task. + */ +typedef enum _dspi_edma_event_flags { + kDspiEdmaTransferDone = 0x01, /*!< Transferring done flag */ +} dspi_edma_event_flag_t; + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to runtime state structure.*/ +extern void * g_dspiStatePtr[SPI_INSTANCE_COUNT]; + +/* Table of SPI FIFO sizes per instance. */ +extern const uint32_t g_dspiFifoSize[SPI_INSTANCE_COUNT]; + +/* For storing DMA intermediate buffers between the source buffer and TX FIFO */ +static uint32_t s_dataToSend; /* Word to send, if no send buffer, this variable is used + as the word to send, which should be initialized to 0. Needs + to be static and stored in data section as this variable + address is the source address if no source buffer. */ +static uint32_t s_rxBuffIfNull; /* If no receive buffer provided, direct rx DMA channel to this + destination */ + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief DSPI receive done callback function + * @details This function is called when receiving is done. + * + * @param param pointer to parameter + * @param status current status of eDMA channel + */ +static void DSPI_DRV_EdmaRxCallback(void *param, edma_chn_status_t status); + +/*! + * @brief DSPI transmit done callback function + * @details This function is called when transmitting is done. + * + * @param param pointer to parameter + * @param status current status of eDMA channel + */ +static void DSPI_DRV_EdmaTxCallback(void *param, edma_chn_status_t status); + +/*! + * @brief Finish the current DSPI transfer + * @details This function stop the DSPI transfer + * + * @param instance The instance of DSPI hardware + */ +static void DSPI_DRV_EdmaCompleteTransfer(uint32_t instance); + +/*! + * @brief Start slave transferring. + * @details This function make starting the transfer. + * + * @param instance The instance number of DSPI peripheral + * @param sendBuffer The pointer to transmit buffer + * @param receiveBuffer The pointer to receive buffer + * @param transferByteCount The transfer size + */ +static void DSPI_DRV_EdmaSlaveStartTransfer(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount); + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaSlaveInit + * Description : Initialize a DSPI slave instance. + * Un-gate DSPI's clock, setup the default value and initializes the required + * resources. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaSlaveInit(uint32_t instance, + dspi_edma_slave_state_t * dspiState, + const dspi_edma_slave_user_config_t * slaveConfig) +{ + dspi_status_t result = kStatus_DSPI_Success; + dma_request_source_t dspiTxEdmaRequest = kDmaRequestMux0Disable; + dma_request_source_t dspiRxEdmaRequest = kDmaRequestMux0Disable; + SPI_Type *base = g_dspiBase[instance]; + + /* Check parameter pointer is not NULL */ + if ((dspiState == NULL) || (slaveConfig == NULL)) + { + return kStatus_DSPI_InvalidParameter; + } + + /* Check DSPI slave instance is already initialized */ + if (g_dspiStatePtr[instance]) + { + return kStatus_DSPI_Initialized; + } + + /* Check if bits/frame size is valid, if not return error. */ + if (slaveConfig->dataConfig.bitsPerFrame > 16) + { + return kStatus_DSPI_OutOfRange; + } + + /* Clear the run-time state struct for this instance. */ + memset(dspiState, 0, sizeof(* dspiState)); + + /* Initial default value slave state structure */ + dspiState->status = kStatus_DSPI_Success; + dspiState->errorCount = 0; + dspiState->dummyPattern = slaveConfig->dummyPattern; + dspiState->remainingSendByteCount = 0; + dspiState->remainingReceiveByteCount = 0; + dspiState->isTransferInProgress = false; + dspiState->extraReceiveByte = 0; + + if (kStatus_OSA_Success != OSA_EventCreate(&dspiState->event, kEventAutoClear)) + { + /* Create event error */ + dspiState->status = kStatus_DSPI_Error; + return kStatus_DSPI_Error; + } + + /* configure the run-time state struct with the nubmer of bits/frame */ + dspiState->bitsPerFrame = slaveConfig->dataConfig.bitsPerFrame; + + /* Enable clock for DSPI */ + CLOCK_SYS_EnableSpiClock(instance); + + /* Reset the DSPI module, which also disables the DSPI module */ + DSPI_HAL_Init(base); + + /* Set to slave mode. */ + DSPI_HAL_SetMasterSlaveMode(base, kDspiSlave); + + /* Set slave data format */ + result = DSPI_HAL_SetDataFormat(base, kDspiCtar0, &slaveConfig->dataConfig); + + /* Enable fifo operation (regardless of FIFO depth) */ + DSPI_HAL_SetFifoCmd(base, true, true); + + /* flush the fifos */ + DSPI_HAL_SetFlushFifoCmd(base, true, true); + + switch (instance) + { + case 0: + /* SPI0 */ +#if FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(0) + dspiRxEdmaRequest = kDmaRequestMux0SPI0Rx; + dspiTxEdmaRequest = kDmaRequestMux0SPI0Tx; +#else + dspiRxEdmaRequest = kDmaRequestMux0SPI0; + dspiTxEdmaRequest = kDmaRequestMux0Disable; +#endif + break; +#if (SPI_INSTANCE_COUNT > 1) + case 1: + /* SPI1 */ +#if FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(1) + dspiRxEdmaRequest = kDmaRequestMux0SPI1Rx; + dspiTxEdmaRequest = kDmaRequestMux0SPI1Tx; +#else + dspiRxEdmaRequest = kDmaRequestMux0SPI1; + dspiTxEdmaRequest = kDmaRequestMux0Disable; +#endif + break; +#endif +#if (SPI_INSTANCE_COUNT > 2) + case 2: + /* SPI2 */ +#if FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(2) + dspiRxEdmaRequest = kDmaRequestMux0SPI2Rx; + dspiTxEdmaRequest = kDmaRequestMux0SPI2Tx; +#else + dspiRxEdmaRequest = kDmaRequestMux0SPI2; + dspiTxEdmaRequest = kDmaRequestMux0Disable; +#endif + break; +#endif + default : + return kStatus_DSPI_InvalidInstanceNumber; + } + + /* This channel transfers data from RX FIFO to receiveBuffer */ + if (kEDMAInvalidChannel == EDMA_DRV_RequestChannel(kEDMAAnyChannel, + dspiRxEdmaRequest, + &dspiState->edmaRxChannel)) + { + dspiState->status = kStatus_DSPI_Error; + return kStatus_DSPI_DMAChannelInvalid; + } + + /* This channel transfers data from transmitBuffer to TX FIFO */ + if (kEDMAInvalidChannel == EDMA_DRV_RequestChannel(kEDMAAnyChannel, + dspiTxEdmaRequest, + &dspiState->edmaTxChannel)) + { + dspiState->status = kStatus_DSPI_Error; + return kStatus_DSPI_DMAChannelInvalid; + } + + /* Configure IRQ state structure, so irq handler can point to the correct state structure */ + g_dspiStatePtr[instance] = dspiState; + + /* Enable the interrupt */ + INT_SYS_EnableIRQ(g_dspiIrqId[instance]); + + /* DSPI module enable */ + DSPI_HAL_Enable(base); + + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaSlaveDeinit + * Description : Shutdown a DSPI instance. + * Resets the DSPI peripheral, disables the interrupt to the core, and gates its clock. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaSlaveDeinit(uint32_t instance) +{ + SPI_Type *base = g_dspiBase[instance]; + dspi_edma_slave_state_t * dspiState = (dspi_edma_slave_state_t *)g_dspiStatePtr[instance]; + + /* Validate function parameters */ + assert(instance < SPI_INSTANCE_COUNT); + + if (!dspiState) + { + return kStatus_DSPI_NonInit; + } + + /* disable the interrupt */ + INT_SYS_DisableIRQ(g_dspiIrqId[instance]); + + /* Stop the transfer process in the slave */ + DSPI_HAL_StopTransfer(base); + + /* Wait until the DSPI run status signals that is has halted before shutting down the module + * and before gating off the DSPI clock source. Otherwise, if the DSPI is shut down before + * it has halted it's internal processes, it may be left in an unknown state. + */ + /* Note that if the master slave select is still asserted, the run status will never clear. + * Hence, ensure before shutting down the slave that the master has de-asserted the slave + * select signal (it should be high if slave select active low or it should be low if + * slave select is active high). + */ + while((DSPI_HAL_GetStatusFlag(base, kDspiTxAndRxStatus))) { } + + /* Restore the module to defaults then power it down. This also disables the DSPI module. */ + DSPI_HAL_Init(base); + + /* Gate the clock for DSPI. */ + CLOCK_SYS_DisableSpiClock(instance); + + /* Destroy event */ + OSA_EventDestroy(&dspiState->event); + + EDMA_DRV_ReleaseChannel(&dspiState->edmaTxChannel); + EDMA_DRV_ReleaseChannel(&dspiState->edmaRxChannel); + + dspiState->status = kStatus_DSPI_NonInit; + + /* Clear state pointer. */ + g_dspiStatePtr[instance] = NULL; + + return kStatus_DSPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaSlaveStartTransfer + * Description : Starts transfer data on SPI bus using eDMA and non-blocking call + * Start DSPI transfering, update transmit/receive information into slave state structure + * + *END**************************************************************************/ +static void DSPI_DRV_EdmaSlaveStartTransfer(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount) +{ + DMA_Type * dmaBaseAddr; + uint32_t dmaChannel; + uint32_t majorIteration; + SPI_Type *base = g_dspiBase[instance]; + dspi_edma_slave_state_t * dspiState = (dspi_edma_slave_state_t *)g_dspiStatePtr[instance]; + uint8_t nBytes = dspiState->bitsPerFrame / 8; + uint32_t txTransferByteCnt = 0; + uint32_t rxTransferByteCnt = 0; + uint32_t sendData = 0; + + /* Calculate number of bytes in frame */ + if (dspiState->bitsPerFrame % 8 != 0) + { + nBytes ++; + } + + /* Set dataToSend variable to dummy pattern */ + s_dataToSend = dspiState->dummyPattern; + + /* Stop the transfer first */ + DSPI_HAL_StopTransfer(base); + + /* Reset the transfer counter to 0. */ + DSPI_HAL_PresetTransferCount(base, 0); + + /* flush the fifos */ + DSPI_HAL_SetFlushFifoCmd(base, true, true); + + /* Clear DSPI flags */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxComplete); + DSPI_HAL_ClearStatusFlag(base, kDspiTxAndRxStatus); + DSPI_HAL_ClearStatusFlag(base, kDspiEndOfQueue); + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoUnderflow); + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest); + DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoOverflow); + DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoDrainRequest); + + /* Start DSPI transfers, set to running state */ + DSPI_HAL_StartTransfer(base); + /* Wait util TFFF set */ + while(!DSPI_HAL_GetStatusFlag(base,kDspiTxFifoFillRequest)) + {} + /* Firstly, fill one TX FIFO register to ensure the data will be transmitted to master. */ + if (sendBuffer) + { + if (nBytes == 1) + { + sendData = *sendBuffer; + sendBuffer ++; + } + else + { + sendData = *sendBuffer; + sendBuffer ++; + sendData |= (uint32_t)(*sendBuffer) << 8; + sendBuffer++; + } + } + else + { + sendData = s_dataToSend; + } + DSPI_HAL_WriteDataSlavemode(base, sendData); + /* try to clear TFFF by writing a one to it; it will not clear if TX FIFO not full */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest); + + /* Calculate number of byte to transmit & receive */ + if ((nBytes > 1) && ((transferByteCount % nBytes) != 0)) + { + rxTransferByteCnt = (transferByteCount/nBytes) * nBytes; + dspiState->extraReceiveByte = transferByteCount - rxTransferByteCnt; + /* Update remaining send byte count */ + dspiState->remainingSendByteCount = (transferByteCount/nBytes + 1) * nBytes; + } + else + { + dspiState->extraReceiveByte = 0; + rxTransferByteCnt = transferByteCount; + /* Update remaining send byte count */ + dspiState->remainingSendByteCount = transferByteCount; + } + /* Tx transfer byte count is FIFO size more than Rx count */ + txTransferByteCnt = rxTransferByteCnt; + + /* Update remaining receive byte count */ + dspiState->remainingReceiveByteCount = rxTransferByteCnt; + + /* Store send buffer */ + dspiState->sendBuffer = sendBuffer; + if (txTransferByteCnt) + { + /* Configure for transmit */ + dmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiState->edmaTxChannel.channel); + dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiState->edmaTxChannel.channel); + EDMA_HAL_ClearDoneStatusFlag(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel); + EDMA_HAL_HTCDClearReg(dmaBaseAddr, dmaChannel); + + if (sendBuffer) + { + /* Source addr, TX Send buffer */ + EDMA_HAL_HTCDSetSrcAddr(dmaBaseAddr, dmaChannel,(uint32_t)(sendBuffer)); + } + else + { + /* Source address is static dummy data */ + EDMA_HAL_HTCDSetSrcAddr(dmaBaseAddr, dmaChannel,(uint32_t)(&s_dataToSend)); + } + + /* Source address adjust last: don't increment source address */ + EDMA_HAL_HTCDSetSrcLastAdjust(dmaBaseAddr, dmaChannel, 0); + + + /* Destination is the TX FIFO */ + EDMA_HAL_HTCDSetDestAddr(dmaBaseAddr, dmaChannel, + DSPI_HAL_GetSlavePushrRegAddr(base)); + + /* Dest addr offset don't increment as it is a FIFO */ + EDMA_HAL_HTCDSetDestOffset(dmaBaseAddr, dmaChannel, 0); + + /* No adjustment needed for destination addr */ + EDMA_HAL_HTCDSetDestLastAdjust(dmaBaseAddr, dmaChannel, 0); + + /* * The source and destination attributes (bit size) depends on bits/frame setting */ + if (dspiState->bitsPerFrame <= 8) + { + if (sendBuffer) + { + /* Source addr offset is 1 as send buffer pointer is incremented 1 bytes + * for each write + */ + EDMA_HAL_HTCDSetSrcOffset(dmaBaseAddr, dmaChannel, 1); + } + else + { + /* Source address does not increase if send buffer is null */ + EDMA_HAL_HTCDSetSrcOffset(dmaBaseAddr, dmaChannel, 0); + } + + /* Destination size is always one byte, source size varies depending on bits/frame */ + EDMA_HAL_HTCDSetAttribute(dmaBaseAddr, dmaChannel, + kEDMAModuloDisable, kEDMAModuloDisable, + kEDMATransferSize_1Bytes, kEDMATransferSize_1Bytes); + + /* Transfer 1 byte from RX FIFO to receive buffer */ + EDMA_HAL_HTCDSetNbytes(dmaBaseAddr, dmaChannel, 1); + + /* Adjust majorIteration to 1 byte per transfer */ + majorIteration = txTransferByteCnt; + } + /* Source size is two bytes */ + else + { + if (sendBuffer) + { + /* Source addr offset is 2 as send buffer pointer is incremented 2 bytes + * for each write + */ + EDMA_HAL_HTCDSetSrcOffset(dmaBaseAddr, dmaChannel, 2); + } + else + { + /* Source address does not increase if send buffer is null */ + EDMA_HAL_HTCDSetSrcOffset(dmaBaseAddr, dmaChannel, 0); + } + + /* Destination size is always one byte, source size varies depending on bits/frame */ + EDMA_HAL_HTCDSetAttribute(dmaBaseAddr, dmaChannel, + kEDMAModuloDisable, kEDMAModuloDisable, + kEDMATransferSize_2Bytes, kEDMATransferSize_2Bytes); + + /* Transfer 2 bytes from transmit buffer to TX FIFO */ + EDMA_HAL_HTCDSetNbytes(dmaBaseAddr, dmaChannel, 2); + + /* Adjust majorIteration to 2 bytes per transfer */ + majorIteration = txTransferByteCnt/2; + } + + /* Configure CITER and BITER fields and clear the ELINK field (disable channel linking) */ + EDMA_HAL_HTCDSetChannelMinorLink(dmaBaseAddr, dmaChannel, 0, false); + EDMA_HAL_HTCDSetMajorCount(dmaBaseAddr, dmaChannel, majorIteration); + + /* Now that the TCD was set up, enable the DSPI Peripheral Hardware request for the */ + /* TX FIFO */ + EDMA_HAL_SetDmaRequestCmd(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel, true); + + /* Enable interrupt */ + EDMA_HAL_HTCDSetIntCmd(dmaBaseAddr, dmaChannel, true); + } + else + { + /* Transmission FIFO fill request interrupt disable */ + DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateIntReq, false); + } + + /* Store receive buffer */ + dspiState->receiveBuffer = receiveBuffer; + if (rxTransferByteCnt) + { + /* Configure for receive */ + dmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiState->edmaRxChannel.channel); + dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiState->edmaRxChannel.channel); + EDMA_HAL_ClearDoneStatusFlag(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel); + EDMA_HAL_HTCDClearReg(dmaBaseAddr, dmaChannel); + + /* Source addr, RX FIFO */ + EDMA_HAL_HTCDSetSrcAddr(dmaBaseAddr, dmaChannel, + DSPI_HAL_GetPoprRegAddr(base)); + + /* Source addr offset is 0 as source addr never increments */ + EDMA_HAL_HTCDSetSrcOffset(dmaBaseAddr, dmaChannel, 0); + + /* Source address adjust last: don't increment source address, it is constant */ + EDMA_HAL_HTCDSetSrcLastAdjust(dmaBaseAddr, dmaChannel, 0); + + if (receiveBuffer) + { + /* Destination is the receive buffer */ + EDMA_HAL_HTCDSetDestAddr(dmaBaseAddr, dmaChannel, (uint32_t)(receiveBuffer)); + } + else + { + /* Destination is the static buffer */ + EDMA_HAL_HTCDSetDestAddr(dmaBaseAddr, dmaChannel, (uint32_t)(&s_rxBuffIfNull)); + } + + /* No adjustment needed for destination addr for most bits/frame. */ + EDMA_HAL_HTCDSetDestLastAdjust(dmaBaseAddr, dmaChannel, 0); + + /* The source and destination attributes (bit size) depends on bits/frame setting */ + if (dspiState->bitsPerFrame <= 8) + { + if (receiveBuffer) + { + /* Dest addr offset, always increment to the next byte */ + EDMA_HAL_HTCDSetDestOffset(dmaBaseAddr, dmaChannel, 1); + } + else + { + /* Dest addr offset, do not increase the destination address */ + EDMA_HAL_HTCDSetDestOffset(dmaBaseAddr, dmaChannel, 0); + } + + /* Destination size is always one byte, source size varies depending on bits/frame */ + EDMA_HAL_HTCDSetAttribute(dmaBaseAddr, dmaChannel, + kEDMAModuloDisable, kEDMAModuloDisable, + kEDMATransferSize_1Bytes, kEDMATransferSize_1Bytes); + + /* Transfer 1 byte from RX FIFO to receive buffer */ + EDMA_HAL_HTCDSetNbytes(dmaBaseAddr, dmaChannel, 1); + + /* Adjust majorIteration to 1 byte per transfer */ + majorIteration = rxTransferByteCnt; + } + else + /* Source size is two bytes */ + { + if (receiveBuffer) + { + /* Dest addr offset, always increment to the next byte */ + EDMA_HAL_HTCDSetDestOffset(dmaBaseAddr, dmaChannel, 2); + } + else + { + /* Dest addr offset, do not increase the destination address */ + EDMA_HAL_HTCDSetDestOffset(dmaBaseAddr, dmaChannel, 0); + } + + /* Destination size is always one byte, source size varies depending on bits/frame */ + EDMA_HAL_HTCDSetAttribute(dmaBaseAddr, dmaChannel, + kEDMAModuloDisable, kEDMAModuloDisable, + kEDMATransferSize_2Bytes, kEDMATransferSize_2Bytes); + + /* Transfer 2 bytes from RX FIFO to receive buffer */ + EDMA_HAL_HTCDSetNbytes(dmaBaseAddr, dmaChannel, 2); + + /* Adjust majorIteration to 2 bytes per transfer */ + majorIteration = rxTransferByteCnt/2; + } + + /* For DSPI instances with shared RX/TX DMA requests, we'll use the RX DMA request to + * trigger ongoing transfers and will link to the TX DMA channel from the RX DMA channel. + */ + if (FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(instance)) + { + /* Disable channel linking since we have separate RX and TX DMA requests */ + EDMA_HAL_HTCDSetChannelMinorLink(dmaBaseAddr, dmaChannel, 0, false); + } + else /* For shared RX/TX DMA Requests */ + { + /* Enable channel linking to TX channel (at the end of each minor loop) */ + EDMA_HAL_HTCDSetChannelMinorLink( + dmaBaseAddr, + dmaChannel, + VIRTUAL_CHN_TO_EDMA_CHN(dspiState->edmaTxChannel.channel), + true); + /* Enable MAJOR link and link to TX DMA channel. This is needed to perform one more + * channel link when the major loop is exhausted. + */ + EDMA_HAL_HTCDSetChannelMajorLink( + dmaBaseAddr, + dmaChannel, + VIRTUAL_CHN_TO_EDMA_CHN(dspiState->edmaTxChannel.channel), + true); + } + EDMA_HAL_HTCDSetMajorCount(dmaBaseAddr, dmaChannel, majorIteration); + + /* Now that the TCD was set up, enable the DSPI Peripheral Hardware request for the + * RX FIFO + */ + EDMA_HAL_SetDmaRequestCmd(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel, true); + + /* Due to MISRA 11.1 rule: + * Conversions shall not be performed between a pointer to a function + * and any type other than an integral type. + * We first have to typecast the callback function pointer as a uint32_t before typecasting + * as a void pointer. + */ + EDMA_DRV_InstallCallback(&dspiState->edmaRxChannel, + DSPI_DRV_EdmaRxCallback,(void *)instance); + + /* Enable interrupt */ + EDMA_HAL_HTCDSetIntCmd(dmaBaseAddr, dmaChannel, true); + } + else if (dspiState->extraReceiveByte) + { + /* Slave receive length is less than bits/frame number of bytes */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxComplete); + DSPI_HAL_SetIntMode(base, kDspiTxComplete, true); + } + else + { + /* Reception FIFO fill request interrupt disable */ + DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateIntReq, false); + } + + if(txTransferByteCnt) + { + /* Check if number of send bytes is smaller than FIFO deepth, enable transmit completed + * interrupt to know when transferring is done + */ + if (dspiState->remainingSendByteCount <= (g_dspiFifoSize[instance] * nBytes)) + { + DSPI_HAL_ClearStatusFlag(base, kDspiTxComplete); + DSPI_HAL_SetIntMode(base, kDspiTxComplete, true); + } + else + { + DSPI_HAL_SetIntMode(base, kDspiTxComplete, false); + } + dmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiState->edmaTxChannel.channel); + dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiState->edmaTxChannel.channel); + + /* For DSPI instances with separate RX/TX DMA requests, we'll use the TX DMA request to + * trigger the TX DMA channel hence we'll enable the TX channel DMA request. + */ + if (FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(instance)) + { + /* Set up eDMA callback */ + /* Due to MISRA 11.1 rule: + * Conversions shall not be performed between a pointer to a function + * and any type other than an integral type. + * We first have to typecast the callback function pointer as a uint32_t before typecasting + * as a void pointer. + */ + EDMA_DRV_InstallCallback(&dspiState->edmaTxChannel, + DSPI_DRV_EdmaTxCallback,(void *)instance); + /* Now that the TCD was set up for each channel, enable the DSPI peripheral hardware + * request for the first TX DMA channel. + */ + EDMA_HAL_SetDmaRequestCmd(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel, true); + + /* Enable TFFF request in the DSPI module */ + DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateDmaReq, true); + } + /* For DSPI instances with shared RX/TX DMA requests, we'll use the RX DMA request to + * trigger ongoing transfers that will link to the TX DMA channel from the RX DMA channel. + * So, we'll disable the TX channel DMA request and then we'll have to manually start the + * TX DMA channel to get the tranfer process started, where the RX DMA channel will take care + * of the ongoing transfers from there. + */ + else /* For shared RX/TX DMA requests */ + { + /* Disable the DSPI TX peripheral hardware request */ + EDMA_HAL_SetDmaRequestCmd(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel, false); + + /* Disable TFFF request in the DSPI module */ + DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateDmaReq, false); + + /* Manually start the TX DMA channel to get the process going */ + EDMA_HAL_TriggerChannelStart(dmaBaseAddr, (edma_channel_indicator_t)dmaChannel); + } + } + if(dspiState->remainingReceiveByteCount > 0) + { + /* Enable the Receive FIFO Drain Request as a DMA request */ + DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateDmaReq, true); + } + + /* Update state */ + dspiState->isTransferInProgress = true; + dspiState->status = kStatus_DSPI_Busy; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaSlaveAbortTransfer + * Description : Abort tranfer + * Abort data transfer, using after function DSPI_DRV_EdmaSlaveTransfer() to abort + * transfering data. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaSlaveAbortTransfer(uint32_t instance) +{ + dspi_edma_slave_state_t * dspiState = (dspi_edma_slave_state_t *)g_dspiStatePtr[instance]; + + /* Check driver initialized */ + if (!dspiState) + { + return kStatus_DSPI_NonInit; + } + + /* Check current status */ + if (!dspiState->isTransferInProgress) + { + return kStatus_DSPI_NoTransferInProgress; + } + + /* Force complete the transfer */ + DSPI_DRV_EdmaCompleteTransfer(instance); + + return kStatus_DSPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaCompleteTransfer + * Description : Finish the transfer + * Called when transfer is finished + * + *END**************************************************************************/ +static void DSPI_DRV_EdmaCompleteTransfer(uint32_t instance) +{ + dspi_edma_slave_state_t * dspiState = (dspi_edma_slave_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + DMA_Type * edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiState->edmaRxChannel.channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiState->edmaRxChannel.channel); + uint32_t readData; + + /* Disable Rx DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(edmaBaseAddr, edmaChannel, false); + + /* Stop Rx DMA channel. */ + EDMA_HAL_SetDmaRequestCmd(edmaBaseAddr, (edma_channel_indicator_t)edmaChannel, false); + + edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiState->edmaTxChannel.channel); + edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiState->edmaTxChannel.channel); + + /* Disable Tx DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(edmaBaseAddr, edmaChannel, false); + + /* Stop Tx DMA channel. */ + EDMA_HAL_SetDmaRequestCmd(edmaBaseAddr, (edma_channel_indicator_t)edmaChannel, false); + + /* Stop transfer */ + DSPI_HAL_StopTransfer(base); + + /* Disable the transmit FIFO fill request */ + DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateDmaReq, false); + /* Disable the Receive FIFO Drain Request */ + DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateDmaReq, false); + /* Disable transmit complete interrupt request */ + DSPI_HAL_SetIntMode(base, kDspiTxComplete, false); + + /* Update extra receive bytes */ + if((dspiState->extraReceiveByte > 0) && (dspiState->receiveBuffer)) + { + /* Read data from FIFO and clear flag */ + readData = DSPI_HAL_ReadData(base); + + /* First byte */ + dspiState->receiveBuffer[dspiState->remainingReceiveByteCount] = (uint8_t)readData; + if ((dspiState->extraReceiveByte > 0) &&(--dspiState->extraReceiveByte > 0)) + { + /* Second byte if available */ + dspiState->receiveBuffer[dspiState->remainingReceiveByteCount + 1] = (uint8_t)(readData >> 8); + } + } + + /* Update status */ + dspiState->status = kStatus_DSPI_Success; + dspiState->isTransferInProgress = false; + dspiState->sendBuffer = NULL; + dspiState->receiveBuffer = NULL; + dspiState->remainingSendByteCount = 0; + dspiState->remainingReceiveByteCount = 0; + dspiState->extraReceiveByte = 0; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaSlaveGetTransferStatus + * Description : Returns whether the previous transfer has finished yet. + * When performing an async transfer, the user can call this function to ascertain the state of the + * current transfer: in progress (or busy) or complete (success). In addition, if the transfer + * is still in progress, the user can obtain the number of words that have been currently + * transferred. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaSlaveGetTransferStatus(uint32_t instance, uint32_t * framesTransferred) +{ + /* instantiate local variable of type dspi_edma_slave_state_t and point to global state */ + dspi_edma_slave_state_t * dspiState = (dspi_edma_slave_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + /* Fill in the bytes transferred. */ + if (framesTransferred) + { + *framesTransferred = DSPI_HAL_GetTransferCount(base); + } + + return ((dspiState->isTransferInProgress) ? kStatus_DSPI_Busy : kStatus_DSPI_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaSlaveTransfer + * Description : Transfer data to master + * Start transfer data to master + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaSlaveTransfer(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount) +{ + dspi_edma_slave_state_t * dspiState = (dspi_edma_slave_state_t *)g_dspiStatePtr[instance]; + + assert(instance < SPI_INSTANCE_COUNT); + + /* Check if DSPI is not initialized */ + if (!dspiState) + { + return kStatus_DSPI_NonInit; + } + + /* Check if buffers and length is empty */ + if (((!sendBuffer) && (!receiveBuffer)) || + (!transferByteCount)) + { + return kStatus_DSPI_InvalidParameter; + } + + /* Check if driver does not idle */ + if (dspiState->status != kStatus_DSPI_Success) + { + return dspiState->status; + } + + /* If using a shared RX/TX DMA request, then this limits the amount of data we can transfer + * due to the linked channel. The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame + */ + if (!FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(instance)) + { + if (dspiState->bitsPerFrame > 8) + { + if (transferByteCount > 1022) + { + return kStatus_DSPI_OutOfRange; + } + } + else + { + if (transferByteCount > 511) + { + return kStatus_DSPI_OutOfRange; + } + } + } + + dspiState->isSync = false; + + DSPI_DRV_EdmaSlaveStartTransfer(instance, sendBuffer, receiveBuffer, transferByteCount); + + return kStatus_DSPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaSlaveTransferBlocking + * Description : Transfer data - blocking + * Transfer data - blocking + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_EdmaSlaveTransferBlocking(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount, + uint32_t timeOut) +{ + dspi_edma_slave_state_t * dspiState = (dspi_edma_slave_state_t *)g_dspiStatePtr[instance]; + dspi_status_t result = kStatus_DSPI_Success; + event_flags_t setFlags = 0; + osa_status_t osaStatus = kStatus_OSA_Success; + + /* Check if DSPI is not initialized */ + if (!dspiState) + { + return kStatus_DSPI_NonInit; + } + + /* Check if buffers and length is empty */ + if (((!sendBuffer) && (!receiveBuffer)) || + (!transferByteCount)) + { + return kStatus_DSPI_InvalidParameter; + } + + /* Check if driver does not idle */ + if (dspiState->status != kStatus_DSPI_Success) + { + return dspiState->status; + } + + /* If using a shared RX/TX DMA request, then this limits the amount of data we can transfer + * due to the linked channel. The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame + */ + if (!FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(instance)) + { + if (dspiState->bitsPerFrame > 8) + { + if (transferByteCount > 1022) + { + return kStatus_DSPI_OutOfRange; + } + } + else + { + if (transferByteCount > 511) + { + return kStatus_DSPI_OutOfRange; + } + } + } + + dspiState->isSync = true; + + /* Clear the event flags */ + OSA_EventClear(&dspiState->event, kDspiEdmaTransferDone); + + DSPI_DRV_EdmaSlaveStartTransfer(instance, sendBuffer, receiveBuffer, transferByteCount); + + /* wait transfer finished */ + do + { + osaStatus = OSA_EventWait(&dspiState->event, kDspiEdmaTransferDone, true, timeOut, &setFlags); + } while(osaStatus == kStatus_OSA_Idle); + + /* Check status of OSA wait event */ + switch (osaStatus) + { + case kStatus_OSA_Success: + result = kStatus_DSPI_Success; + break; + case kStatus_OSA_Timeout: + result = kStatus_DSPI_Timeout; + break; + case kStatus_OSA_Error: + default: + result = kStatus_DSPI_Error; + break; + } + + if (result != kStatus_DSPI_Success) + { + /* Abort the transfer */ + DSPI_DRV_EdmaSlaveAbortTransfer(instance); + } + + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaRxCallback + * Description : Callback function, this called when eDMA receiving data + * completed + * + *END**************************************************************************/ +static void DSPI_DRV_EdmaRxCallback(void *param, edma_chn_status_t status) +{ + uint32_t instance = (uint32_t)param; + SPI_Type *base = g_dspiBase[instance]; + dspi_edma_slave_state_t * dspiState = (dspi_edma_slave_state_t *)g_dspiStatePtr[instance]; + DMA_Type * edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiState->edmaRxChannel.channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiState->edmaRxChannel.channel); + + if (dspiState->extraReceiveByte != 0) + { + /* Enable transmit complete interrupt */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxComplete); + DSPI_HAL_SetIntMode(base, kDspiTxComplete, true); + } + + /* Disable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(edmaBaseAddr, edmaChannel, false); + + /* Stop DMA channel. */ + EDMA_HAL_SetDmaRequestCmd(edmaBaseAddr, (edma_channel_indicator_t)edmaChannel, false); + + /* Disable Rx Fifo drain interrupt */ + DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateDmaReq, false); + + /* If transmission completed, stop the transferring */ + if ((dspiState->isTransferInProgress) && + (!FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(instance)) && + (dspiState->extraReceiveByte == 0)) + { + DSPI_DRV_EdmaCompleteTransfer(instance); + + /* Notify event */ + if(dspiState->isSync) + { + OSA_EventSet(&dspiState->event, kDspiEdmaTransferDone); + } + } + else if ((dspiState->isTransferInProgress) && + (dspiState->remainingSendByteCount <= 0) && + (dspiState->extraReceiveByte == 0)) + { + DSPI_DRV_EdmaCompleteTransfer(instance); + + /* Notify event */ + if(dspiState->isSync) + { + OSA_EventSet(&dspiState->event, kDspiEdmaTransferDone); + } + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaTxCallback + * Description : Callback function, this called when eDMA transmitting data + * completed + * + *END**************************************************************************/ +static void DSPI_DRV_EdmaTxCallback(void *param, edma_chn_status_t status) +{ + uint32_t instance = (uint32_t)param; + SPI_Type *base = g_dspiBase[instance]; + dspi_edma_slave_state_t * dspiState = (dspi_edma_slave_state_t *)g_dspiStatePtr[instance]; + DMA_Type * edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(dspiState->edmaTxChannel.channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(dspiState->edmaTxChannel.channel); + uint8_t nBytes; + + nBytes = dspiState->bitsPerFrame / 8; + if (dspiState->bitsPerFrame % 8 != 0) + { + nBytes += 1; + } + + /* Check if send bytes count is greater than FIFO size, update this count and enable + * transmit completed interrupt. + */ + if (dspiState->remainingSendByteCount > (g_dspiFifoSize[instance] * nBytes)) + { + /* Enable transmit complete interrupt */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxComplete); + DSPI_HAL_SetIntMode(base, kDspiTxComplete, true); + } + + /* Disable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(edmaBaseAddr, edmaChannel, false); + + /* Stop DMA channel. */ + EDMA_HAL_SetDmaRequestCmd(edmaBaseAddr, (edma_channel_indicator_t)edmaChannel, false); + + /* Disable Tx Fifo fill interrupt */ + DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateDmaReq, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_EdmaSlaveIRQHandler + * Description : DSPI slave interrupt handler + * This function is DSPI slave interrupt handler using eDMA mechanism. The + * pupose of this interrupt handler is indicates when the transfer is really + * finished. The eDMA only used to copy data from/to RX FIFO/TX FIFO, but it + * not sure the data was transmitted to the master. So must have to enable + * this interrupt to do it. This interrupt only be enabled when the last + * four FIFO will be transmitted. + * + *END**************************************************************************/ +void DSPI_DRV_EdmaSlaveIRQHandler(uint32_t instance) +{ + SPI_Type *base = g_dspiBase[instance]; + dspi_edma_slave_state_t * dspiState = (dspi_edma_slave_state_t *)g_dspiStatePtr[instance]; + uint8_t nBytes; + + nBytes = dspiState->bitsPerFrame / 8; + if (dspiState->bitsPerFrame % 8 != 0) + { + nBytes += 1; + } + + /* Catch Tx complete interrupt */ + if ((DSPI_HAL_GetIntMode(base, kDspiTxComplete)) && + (DSPI_HAL_GetStatusFlag(base, kDspiTxComplete))) + { + /* Clear this flag first */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxComplete); + + /* Check if number of transfered bytes is greater or equals user request */ + if(dspiState->remainingSendByteCount <= (DSPI_HAL_GetTransferCount(base) * nBytes)) + { + /* Complete the transfer */ + DSPI_DRV_EdmaCompleteTransfer(instance); + /* Notify to wait task */ + if(dspiState->isSync) + { + OSA_EventSet(&dspiState->event, kDspiEdmaTransferDone); + } + } + } +} + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_irq.c b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_irq.c new file mode 100755 index 0000000..695d17a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_irq.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <stdbool.h> +#include "fsl_dspi_shared_function.h" +#include "fsl_device_registers.h" + +/*! + * @addtogroup dspi_irq + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if (SPI_INSTANCE_COUNT == 1) +/*! + * @brief This function is the implementation of SPI0 handler named in startup code. + * + * It passes the instance to the shared DSPI IRQ handler. + */ +void SPI0_IRQHandler(void) +{ + DSPI_DRV_IRQHandler(SPI0_IDX); +} + +#elif (SPI_INSTANCE_COUNT == 2) +/*! + * @brief This function is the implementation of SPI0 handler named in startup code. + * + * It passes the instance to the shared DSPI IRQ handler. + */ +void SPI0_IRQHandler(void) +{ + DSPI_DRV_IRQHandler(SPI0_IDX); +} + +/*! + * @brief This function is the implementation of SPI1 handler named in startup code. + * + * It passes the instance to the shared DSPI IRQ handler. + */ +void SPI1_IRQHandler(void) +{ + DSPI_DRV_IRQHandler(SPI1_IDX); +} + +#else +/*! + * @brief This function is the implementation of SPI0 handler named in startup code. + * + * It passes the instance to the shared DSPI IRQ handler. + */ +void SPI0_IRQHandler(void) +{ + DSPI_DRV_IRQHandler(SPI0_IDX); +} + +/*! + * @brief This function is the implementation of SPI1 handler named in startup code. + * + * It passes the instance to the shared DSPI IRQ handler. + */ +void SPI1_IRQHandler(void) +{ + DSPI_DRV_IRQHandler(SPI1_IDX); +} + +/*! + * @brief This function is the implementation of SPI2 handler named in startup code. + * + * It passes the instance to the shared DSPI IRQ handler. + */ +void SPI2_IRQHandler(void) +{ + DSPI_DRV_IRQHandler(SPI2_IDX); +} + +#endif + +/*! @} */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_lpm_callback.c new file mode 100755 index 0000000..0cdaed5 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t dspi_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t dspi_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_master_driver.c b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_master_driver.c new file mode 100755 index 0000000..311b489 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_master_driver.c @@ -0,0 +1,850 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string.h> +#include "fsl_dspi_master_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Pointer to runtime state structure.*/ +extern void * g_dspiStatePtr[SPI_INSTANCE_COUNT]; + +/* Table of SPI FIFO sizes per instance. */ +extern const uint32_t g_dspiFifoSize[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static dspi_status_t DSPI_DRV_MasterStartTransfer(uint32_t instance, + const dspi_device_t * device); + +static void DSPI_DRV_MasterCompleteTransfer(uint32_t instance); + +static void DSPI_DRV_MasterFillupTxFifo(uint32_t instance); + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_MasterInit + * Description : Initialize a DSPI instance for master mode operation. + * This function uses a CPU interrupt driven method for transferring data. + * This function will initialize the run-time state structure to keep track of the on-going + * transfers, ungate the clock to the DSPI module, reset the DSPI module, initialize the module + * to user defined settings and default settings, configure the IRQ state structure and enable + * the module-level interrupt to the core, and enable the DSPI module. + * The CTAR parameter is special in that it allows the user to have different SPI devices + * connected to the same DSPI module instance in conjunction with different peripheral chip + * selects. Each CTAR contains the bus attributes associated with that particular SPI device. + * For simplicity and for most use cases where only one SPI device is connected per DSPI module + * instance, it is recommended to use CTAR0. + * The following is an example of how to set up the dspi_master_state_t and the + * dspi_master_user_config_t parameters and how to call the DSPI_DRV_MasterInit function by passing + * in these parameters: + * dspi_master_state_t dspiMasterState; <- the user simply allocates memory for this struct + * uint32_t calculatedBaudRate; + * dspi_master_user_config_t userConfig; <- the user fills out members for this struct + * userConfig.isChipSelectContinuous = false; + * userConfig.isSckContinuous = false; + * userConfig.pcsPolarity = kDspiPcs_ActiveLow; + * userConfig.whichCtar = kDspiCtar0; + * userConfig.whichPcs = kDspiPcs0; + * DSPI_DRV_MasterInit(masterInstance, &dspiMasterState, &userConfig); + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_MasterInit(uint32_t instance, + dspi_master_state_t * dspiState, + const dspi_master_user_config_t * userConfig) +{ + uint32_t dspiSourceClock; + dspi_status_t errorCode = kStatus_DSPI_Success; + + SPI_Type *base = g_dspiBase[instance]; + + /* Clear the run-time state struct for this instance.*/ + memset(dspiState, 0, sizeof(* dspiState)); + + /* Note, remember to first enable clocks to the DSPI module before making any register accesses + * Enable clock for DSPI + */ + CLOCK_SYS_EnableSpiClock(instance); + /* Get module clock freq*/ + dspiSourceClock = CLOCK_SYS_GetSpiFreq(instance); + + /* Configure the run-time state struct with the DSPI source clock */ + dspiState->dspiSourceClock = dspiSourceClock; + + /* Configure the run-time state struct with the data command parameters*/ + dspiState->whichCtar = userConfig->whichCtar; /* set the dspiState struct CTAR*/ + dspiState->whichPcs = userConfig->whichPcs; /* set the dspiState struct whichPcs*/ + dspiState->isChipSelectContinuous = userConfig->isChipSelectContinuous; /* continuous PCS*/ + + /* Initialize the DSPI module registers to default value, which disables the module */ + DSPI_HAL_Init(base); + + /* Init the interrupt sync object.*/ + OSA_SemaCreate(&dspiState->irqSync, 0); + + /* Initialize the DSPI module with user config */ + + /* Set to master mode.*/ + DSPI_HAL_SetMasterSlaveMode(base, kDspiMaster); + + /* Configure for continuous SCK operation*/ + DSPI_HAL_SetContinuousSckCmd(base, userConfig->isSckContinuous); + + /* Configure for peripheral chip select polarity*/ + DSPI_HAL_SetPcsPolarityMode(base, userConfig->whichPcs, userConfig->pcsPolarity); + + /* Enable fifo operation (regardless of FIFO depth) */ + DSPI_HAL_SetFifoCmd(base, true, true); + + /* Initialize the configurable delays: PCS-to-SCK, prescaler = 0, scaler = 1 */ + DSPI_HAL_SetDelay(base, userConfig->whichCtar, 0, 1, kDspiPcsToSck); + + /* Save runtime structure pointers to irq handler can point to the correct state structure*/ + g_dspiStatePtr[instance] = dspiState; + + /* enable the interrupt*/ + INT_SYS_EnableIRQ(g_dspiIrqId[instance]); + + /* DSPI system enable */ + DSPI_HAL_Enable(base); + + /* Start the transfer process in the hardware */ + DSPI_HAL_StartTransfer(base); + + return errorCode; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_MasterDeinit + * Description : Shutdown a DSPI instance. + * This function resets the DSPI peripheral, gates its clock, and disables the interrupt to + * the core. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_MasterDeinit(uint32_t instance) +{ + /* instantiate local variable of type dspi_master_state_t and point to global state */ + dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + /* First stop transfers */ + DSPI_HAL_StopTransfer(base); + + /* Restore the module to defaults then power it down. This also disables the DSPI module.*/ + DSPI_HAL_Init(base); + + /* destroy the interrupt sync object.*/ + OSA_SemaDestroy(&dspiState->irqSync); + + /* disable the interrupt*/ + INT_SYS_DisableIRQ(g_dspiIrqId[instance]); + + /* Gate the clock for DSPI.*/ + CLOCK_SYS_DisableSpiClock(instance); + + /* Clear state pointer. */ + g_dspiStatePtr[instance] = NULL; + + return kStatus_DSPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_MasterSetDelay + * Description : Configures the DSPI master mode bus timing delay options. + * This function allows the user to take advantage of the DSPI module's delay options in order to + * "fine tune" some of the signal timings to match the timing needs of a slower peripheral device. + * This is an optional function that can be called after the DSPI module has been initialized for + * master mode. + * The bus timing delays that can be adjusted are listed below: + * + * PCS to SCK Delay: Adjustable delay option between the assertion of the PCS signal to the + * first SCK edge. + * + * After SCK Delay: Adjustable delay option between the last edge of SCK to the de-assertion + * of the PCS signal. + * + * Delay after Transfer: Adjustable delay option between the de-assertion of the PCS signal for a + * frame to the assertion of the PCS signal for the next frame. Note this + * is not adjustable for continuous clock mode as this delay is fixed at + * one SCK period. + * + * Each of the above delay parameters use both a pre-scalar and scalar value to calculate the + * needed delay. This function will take in as a parameter the desired delay type and the + * delay value (in nano-seconds) and will calculate the values needed for the prescaler and scaler + * and return the actual calculated delay as an exact delay match may not be acheivable. In this + * case, the closest match will be calculated without going below the desired delay value input. + * It is possible to input a very large delay value that exceeds the capability of the part, in + * which case the maximum supported delay will be returned. In addition the function will return + * an out-of-range status to alert the user. + *END**************************************************************************/ +dspi_status_t DSPI_DRV_MasterSetDelay(uint32_t instance, dspi_delay_type_t whichDelay, + uint32_t delayInNanoSec, uint32_t * calculatedDelay) +{ + /* instantiate local variable of type dspi_master_state_t and point to global state */ + dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + dspi_status_t errorCode = kStatus_DSPI_Success; + + *calculatedDelay = DSPI_HAL_CalculateDelay(base, dspiState->whichCtar, whichDelay, + dspiState->dspiSourceClock, delayInNanoSec); + + /* If the desired delay exceeds the capability of the device, alert the user */ + if (*calculatedDelay < delayInNanoSec) + { + errorCode = kStatus_DSPI_OutOfRange; + } + + return errorCode; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_MasterConfigureBus + * Description : Configures the DSPI port physical parameters to access a device on the bus. + * The term "device" is used to indicate the SPI device for which the DSPI master is communicating. + * The user has two options to configure the device parameters: either pass in the + * pointer to the device configuration structure to the desired transfer function (see + * DSPI_DRV_MasterTransferBlocking or DSPI_DRV_MasterTransfer) or pass it in to the + * DSPI_DRV_MasterConfigureBus function. The user can pass in a device structure to the transfer + * function which will contain the parameters for the bus (the transfer function will then call + * this function). However, the user has the option to call this function directly especially if + * they wish to obtain the calculated baud rate, at which point they may pass in NULL for the device + * struct in the transfer function (assuming they have called this configure bus function + * first). The following is an example of how to set up the dspi_device_t structure and how to call + * the DSPI_DRV_MasterConfigureBus function by passing in these parameters: + * dspi_device_t spiDevice; + * spiDevice.dataBusConfig.bitsPerFrame = 16; + * spiDevice.dataBusConfig.clkPhase = kDspiClockPhase_FirstEdge; + * spiDevice.dataBusConfig.clkPolarity = kDspiClockPolarity_ActiveHigh; + * spiDevice.dataBusConfig.direction = kDspiMsbFirst; + * spiDevice.bitsPerSec = 50000; + * DSPI_DRV_MasterConfigureBus(instance, &spiDevice, &calculatedBaudRate); + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_MasterConfigureBus(uint32_t instance, + const dspi_device_t * device, + uint32_t * calculatedBaudRate) +{ + assert(device); + /* instantiate local variable of type dspi_master_state_t and point to global state */ + dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + dspi_status_t errorCode = kStatus_DSPI_Success; + + /* Configure the bus to access the provided device.*/ + *calculatedBaudRate = DSPI_HAL_SetBaudRate(base, dspiState->whichCtar, device->bitsPerSec, + dspiState->dspiSourceClock); + errorCode = DSPI_HAL_SetDataFormat(base, dspiState->whichCtar, + &device->dataBusConfig); + dspiState->bitsPerFrame = device->dataBusConfig.bitsPerFrame; /* update dspiState bits/frame */ + + return errorCode; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_MasterTransferBlocking + * Description : Perform a blocking SPI master mode transfer. + * This function simultaneously sends and receives data on the SPI bus, as SPI is naturally + * a full-duplex bus. The function will not return until the transfer is complete. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_MasterTransferBlocking(uint32_t instance, + const dspi_device_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount, + uint32_t timeout) +{ + /* instantiate local variable of type dspi_master_state_t and point to global state */ + dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + dspi_status_t error = kStatus_DSPI_Success; + + /* If the transfer count is zero, then return immediately.*/ + if (transferByteCount == 0) + { + return error; + } + + /* As this is a synchronous transfer, set up the sync status variable*/ + osa_status_t syncStatus; + + /* fill in members of the run-time state struct*/ + dspiState->isTransferBlocking = true; /* Indicates this is a blocking transfer */ + dspiState->sendBuffer = (const uint8_t *)sendBuffer; + dspiState->receiveBuffer = (uint8_t *)receiveBuffer; + dspiState->remainingSendByteCount = transferByteCount; + dspiState->remainingReceiveByteCount = transferByteCount; + + /* start the transfer process*/ + if (DSPI_DRV_MasterStartTransfer(instance, device) == kStatus_DSPI_Busy) + { + return kStatus_DSPI_Busy; + } + + /* As this is a synchronous transfer, wait until the transfer is complete.*/ + do + { + syncStatus = OSA_SemaWait(&dspiState->irqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + /* If a timeout occurs, stop the transfer by setting the isTransferInProgress to false and + * disabling interrupts, then return the timeout error status. + */ + if (syncStatus != kStatus_OSA_Success) + { + /* The transfer is complete.*/ + dspiState->isTransferInProgress = false; + + /* Disable interrupt requests*/ + /* RX FIFO Drain request: RFDF_RE */ + DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateIntReq, false); + + /* Disable TX FIFO Fill request */ + DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateIntReq, false); + + error = kStatus_DSPI_Timeout; + } + + return error; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_MasterTransfer + * Description : Perform a non-blocking SPI master mode transfer. + * This function will return immediately. It is the user's responsiblity to check back to + * ascertain if the transfer is complete (using the DSPI_DRV_MasterGetTransferStatus function). This + * function simultaneously sends and receives data on the SPI bus, as SPI is naturally + * a full-duplex bus. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_MasterTransfer(uint32_t instance, + const dspi_device_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount) +{ + /* instantiate local variable of type dspi_master_state_t and point to global state */ + dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance]; + + /* If the transfer count is zero, then return immediately.*/ + if (transferByteCount == 0) + { + return kStatus_DSPI_Success; + } + + /* fill in members of the run-time state struct*/ + dspiState->isTransferBlocking = false; /* Indicates this is not a blocking transfer */ + dspiState->sendBuffer = sendBuffer; + dspiState->receiveBuffer = (uint8_t *)receiveBuffer; + dspiState->remainingSendByteCount = transferByteCount; + dspiState->remainingReceiveByteCount = transferByteCount; + + /* start the transfer process*/ + if (DSPI_DRV_MasterStartTransfer(instance, device) == kStatus_DSPI_Busy) + { + return kStatus_DSPI_Busy; + } + + /* Else, return immediately as this is an async transfer */ + return kStatus_DSPI_Success; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_MasterGetTransferStatus + * Description : Returns whether the previous transfer has finished yet. + * When performing an async transfer, the user can call this function to ascertain the state of the + * current transfer: in progress (or busy) or complete (success). In addition, if the transfer + * is still in progress, the user can obtain the number of words that have been currently + * transferred. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_MasterGetTransferStatus(uint32_t instance, uint32_t * framesTransferred) +{ + /* instantiate local variable of type dspi_master_state_t and point to global state */ + dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + /* Fill in the bytes transferred.*/ + if (framesTransferred) + { + *framesTransferred = DSPI_HAL_GetTransferCount(base); + } + + return (dspiState->isTransferInProgress ? kStatus_DSPI_Busy : kStatus_DSPI_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_MasterAbortTransfer + * Description : Terminates an asynchronous transfer early. + * During an async transfer, the user has the option to terminate the transfer early if the transfer + * is still in progress. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_MasterAbortTransfer(uint32_t instance) +{ + /* instantiate local variable of type dspi_master_state_t and point to global state */ + dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance]; + + /* Check if a transfer is running.*/ + if (!dspiState->isTransferInProgress) + { + return kStatus_DSPI_NoTransferInProgress; + } + + /* Stop the running transfer.*/ + DSPI_DRV_MasterCompleteTransfer(instance); + + return kStatus_DSPI_Success; +} + +/*! + * @brief Initiate (start) a transfer. This is not a public API as it is called from other + * driver functions + */ +static dspi_status_t DSPI_DRV_MasterStartTransfer(uint32_t instance, + const dspi_device_t * device) +{ + /* instantiate local variable of type dspi_master_state_t and point to global state */ + dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + uint32_t calculatedBaudRate; + + /* Check that we're not busy.*/ + if (dspiState->isTransferInProgress) + { + return kStatus_DSPI_Busy; + } + + /* Configure bus for this device. If NULL is passed, we assume the caller has + * preconfigured the bus using DSPI_DRV_MasterConfigureBus(). + * Do nothing for calculatedBaudRate. If the user wants to know the calculatedBaudRate + * then they can call this function separately. + */ + if (device) + { + DSPI_DRV_MasterConfigureBus(instance, device, &calculatedBaudRate); + dspiState->bitsPerFrame = device->dataBusConfig.bitsPerFrame;/*update dspiState bits/frame*/ + } + + /* Check the transfer byte count. If bits/frame > 8, meaning 2 bytes and if + * the transfer byte count is an odd count we'll have to increase the transfer byte count + * by one and assert a flag to indicate to the send and receive functions that it will + * need to handle an extra byte. + */ + if ((dspiState->bitsPerFrame > 8) && (dspiState->remainingSendByteCount & 1UL)) + { + dspiState->remainingSendByteCount += 1; + dspiState->remainingReceiveByteCount += 1; + dspiState->extraByte = true; + } + else + { + dspiState->extraByte = false; + } + + + /* Save information about the transfer for use by the ISR.*/ + dspiState->isTransferInProgress = true; + + /* Restart the transfer by stop then start again, this will clear out the shift register */ + DSPI_HAL_StopTransfer(base); + + /* flush the fifos*/ + DSPI_HAL_SetFlushFifoCmd(base, true, true); + + /* Clear status flags that may have been set from previous transfers */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxComplete); + DSPI_HAL_ClearStatusFlag(base, kDspiEndOfQueue); + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoUnderflow); + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest); + DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoOverflow); + DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoDrainRequest); + + /* Clear the transfer count */ + DSPI_HAL_PresetTransferCount(base, 0); + + /* Start the transfer, make sure to do this before filling the FIFO */ + DSPI_HAL_StartTransfer(base); + + /* Fill up the DSPI FIFO (even if one word deep, data still written to data buffer) */ + DSPI_DRV_MasterFillupTxFifo(instance); + + /* RX FIFO Drain request: RFDF_RE to enable RFDF interrupt + * Since SPI is a synchronous interface, we only need to enable the RX interrupt. + * The IRQ handler will get the status of RX and TX interrupt flags. + */ + DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateIntReq, true); + + return kStatus_DSPI_Success; +} + +/*! + * @brief Fill up the TX FIFO with data. + * This function fills up the TX FIFO with initial data for start of transfers where it will + * first clear the transfer count. Otherwise, if the TX FIFO fill is part of an ongoing transfer + * then do not clear the transfer count. The param "isInitialData" is used to determine if this + * is an initial data fill. + * This is not a public API as it is called from other driver functions. + */ +static void DSPI_DRV_MasterFillupTxFifo(uint32_t instance) +{ + /* instantiate local variable of type dspi_master_state_t and point to global state */ + dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + dspi_command_config_t command; /* create an instance of the data command struct*/ + uint32_t cmd; /* Command word to be OR'd with data word */ + uint16_t wordToSend = 0; + /* Declare variables for storing volatile data later in the code */ + uint32_t remainingReceiveByteCount, remainingSendByteCount; + + /* Before sending the data, we first need to initialize the data command struct + * Configure the data command attributes for the desired PCS, CTAR, and continuous PCS + * which are derived from the run-time state struct + */ + command.whichPcs = dspiState->whichPcs; + command.whichCtar = dspiState->whichCtar; + command.isChipSelectContinuous = dspiState->isChipSelectContinuous; + command.isEndOfQueue = 0; + command.clearTransferCount = 0; + + /* "Build" the command word. Only do this once since the commad word members don't + * change until the last word sent (which is when the end of queue flag gets set). + */ + cmd = DSPI_HAL_GetFormattedCommand(base, &command); + + /* Store the DSPI state struct volatile member variables into temporary + * non-volatile variables to allow for MISRA compliant calculations + */ + remainingSendByteCount = dspiState->remainingSendByteCount; + remainingReceiveByteCount = dspiState->remainingReceiveByteCount; + + /* Architectural note: When developing the TX FIFO fill functionality, it was found that to + * achieve more efficient run-time performance, it was better to first check the bits/frame + * setting and then proceed with the FIFO fill management process, rather than to clutter the + * FIFO fill process with continual checks of the bits/frame setting. + */ + + /* If bits/frame is greater than one byte */ + if (dspiState->bitsPerFrame > 8) + { + /* Fill the fifo until it is full or until the send word count is 0 or until the difference + * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth. + * The reason for checking the difference is to ensure we only send as much as the + * RX FIFO can receive. + * For this case where bitsPerFrame > 8, each entry in the FIFO contains 2 bytes of the + * send data, hence the difference between the remainingReceiveByteCount and + * remainingSendByteCount must be divided by 2 to convert this difference into a + * 16-bit (2 byte) value. + */ + while((DSPI_HAL_GetStatusFlag(base, kDspiTxFifoFillRequest) == 1) && + ((remainingReceiveByteCount - remainingSendByteCount)/2 < + g_dspiFifoSize[instance])) + { + /* On the last word to be sent, set the end of queue flag in the data command struct + * and ensure that the CONT bit in the PUSHR is also cleared even if it was cleared to + * begin with. If CONT is set it means continuous chip select operation and to ensure + * the chip select is de-asserted, this bit must be cleared on the last data word. + */ + if (dspiState->remainingSendByteCount == 2) + { + command.isEndOfQueue = 1; + command.isChipSelectContinuous = 0; + cmd = DSPI_HAL_GetFormattedCommand(base, &command); + + /* If there is an extra byte to send due to an odd byte count, prepare the final + * wordToSend here + */ + if (dspiState->sendBuffer) + { + if (dspiState->extraByte) + { + wordToSend = *(dspiState->sendBuffer); + } + else + { + wordToSend = *(dspiState->sendBuffer); + ++dspiState->sendBuffer; /* increment to next data byte */ + wordToSend |= (unsigned)(*(dspiState->sendBuffer)) << 8U; + } + } + } + /* For all words except the last word */ + else + { + /* If a send buffer was provided, the word comes from there. Otherwise we just send + * a zero (initialized above). + */ + if (dspiState->sendBuffer) + { + wordToSend = *(dspiState->sendBuffer); + ++dspiState->sendBuffer; /* increment to next data byte */ + wordToSend |= (unsigned)(*(dspiState->sendBuffer)) << 8U; + ++dspiState->sendBuffer; /* increment to next data byte */ + } + } + DSPI_HAL_WriteCmdDataMastermode(base, cmd|wordToSend); + + /* Try to clear the TFFF; if the TX FIFO is full this will clear */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest); + + dspiState->remainingSendByteCount -= 2; /* decrement remainingSendByteCount by 2 */ + + /* exit loop if send count is zero, else update local variables for next loop */ + if (dspiState->remainingSendByteCount == 0) + { + break; + } + else + { + /* Store the DSPI state struct volatile member variables into temporary + * non-volatile variables to allow for MISRA compliant calculations + */ + remainingSendByteCount = dspiState->remainingSendByteCount; + } + } /* End of TX FIFO fill while loop */ + } + /* Optimized for bits/frame less than or equal to one byte. */ + else + { + /* Fill the fifo until it is full or until the send word count is 0 or until the difference + * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth. + * The reason for checking the difference is to ensure we only send as much as the + * RX FIFO can receive. + */ + while((DSPI_HAL_GetStatusFlag(base, kDspiTxFifoFillRequest) == 1) && + ((remainingReceiveByteCount - remainingSendByteCount) < + g_dspiFifoSize[instance])) + { + /* On the last word to be sent, set the end of queue flag in the data command struct + * and ensure that the CONT bit in the PUSHR is also cleared even if it was cleared to + * begin with. If CONT is set it means continuous chip select operation and to ensure + * the chip select is de-asserted, this bit must be cleared on the last data word. + */ + if (dspiState->remainingSendByteCount == 1) + { + command.isEndOfQueue = 1; + command.isChipSelectContinuous = 0; + cmd = DSPI_HAL_GetFormattedCommand(base, &command); + } + + /* If a send buffer was provided, the word comes from there. Otherwise we just send + * a zero (initialized above). + */ + if (dspiState->sendBuffer) + { + wordToSend = *(dspiState->sendBuffer); + ++dspiState->sendBuffer; /* increment to next data word*/ + } + DSPI_HAL_WriteCmdDataMastermode(base, cmd|wordToSend); + + /* Try to clear the TFFF; if the TX FIFO is full this will clear */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest); + + --dspiState->remainingSendByteCount; /* decrement remainingSendByteCount*/ + + /* exit loop if send count is zero, else update local variables for next loop */ + if (dspiState->remainingSendByteCount == 0) + { + break; + } + else + { + /* Store the DSPI state struct volatile member variables into temporary + * non-volatile variables to allow for MISRA compliant calculations + */ + remainingSendByteCount = dspiState->remainingSendByteCount; + } + } /* End of TX FIFO fill while loop */ + } +} + +/*! + * @brief Finish up a transfer. + * Cleans up after a transfer is complete. Interrupts are disabled, and the DSPI module + * is disabled. This is not a public API as it is called from other driver functions. + */ +static void DSPI_DRV_MasterCompleteTransfer(uint32_t instance) +{ + /* instantiate local variable of type dspi_master_state_t and point to global state */ + dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + /* The transfer is complete.*/ + dspiState->isTransferInProgress = false; + + /* Disable interrupt requests*/ + /* RX FIFO Drain request: RFDF_RE */ + DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateIntReq, false); + + /* Disable TX FIFO Fill request */ + DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateIntReq, false); + + if (dspiState->isTransferBlocking) + { + /* Signal the synchronous completion object */ + OSA_SemaPost(&dspiState->irqSync); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_MasterIRQHandler + * Description : Interrupt handler for DSPI master mode. + * This handler uses the buffers stored in the dspi_master_state_t structs to transfer data. + * This is not a public API as it is called whenever an interrupt occurs. + * + *END**************************************************************************/ +void DSPI_DRV_MasterIRQHandler(uint32_t instance) +{ + /* instantiate local variable of type dspi_master_state_t and point to global state */ + dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance]; + + SPI_Type *base = g_dspiBase[instance]; + + /* RECEIVE IRQ handler: Check read buffer only if there are remaining bytes to read. */ + if(dspiState->remainingReceiveByteCount) + { + /* Check read buffer.*/ + uint16_t wordReceived; /* Maximum supported data bit length in master mode is 16-bits */ + + /* If bits/frame is greater than one byte */ + if (dspiState->bitsPerFrame > 8) + { + while (DSPI_HAL_GetStatusFlag(base, kDspiRxFifoDrainRequest)) + { + wordReceived = DSPI_HAL_ReadData(base); + /* clear the rx fifo drain request, needed for non-DMA applications as this flag + * will remain set even if the rx fifo is empty. By manually clearing this flag, it + * either remain clear if no more data is in the fifo, or it will set if there is + * more data in the fifo. + */ + DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoDrainRequest); + + /* Store read bytes into rx buffer only if a buffer pointer was provided */ + if(dspiState->receiveBuffer) + { + /* For the last word received, if there is an extra byte due to the odd transfer + * byte count, only save the the last byte and discard the upper byte + */ + if ((dspiState->remainingReceiveByteCount == 2) && (dspiState->extraByte)) + { + *dspiState->receiveBuffer = wordReceived; /* Write first data byte */ + } + else + { + *dspiState->receiveBuffer = wordReceived; /* Write first data byte */ + ++dspiState->receiveBuffer; /* increment to next data byte */ + *dspiState->receiveBuffer = wordReceived >> 8; /* Write second data byte */ + ++dspiState->receiveBuffer; /* increment to next data byte */ + } + } + dspiState->remainingReceiveByteCount -= 2; + + if (dspiState->remainingReceiveByteCount == 0) + { + break; + } + } /* End of RX FIFO drain while loop */ + } + /* Optimized for bits/frame less than or equal to one byte. */ + else + { + while (DSPI_HAL_GetStatusFlag(base, kDspiRxFifoDrainRequest)) + { + wordReceived = DSPI_HAL_ReadData(base); + /* clear the rx fifo drain request, needed for non-DMA applications as this flag + * will remain set even if the rx fifo is empty. By manually clearing this flag, it + * either remain clear if no more data is in the fifo, or it will set if there is + * more data in the fifo. + */ + DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoDrainRequest); + + /* Store read bytes into rx buffer only if a buffer pointer was provided */ + if(dspiState->receiveBuffer) + { + *dspiState->receiveBuffer = wordReceived; + ++dspiState->receiveBuffer; + } + + --dspiState->remainingReceiveByteCount; + + if (dspiState->remainingReceiveByteCount == 0) + { + break; + } + } /* End of RX FIFO drain while loop */ + } + } + + /* Check write buffer. We always have to send a word in order to keep the transfer + * moving. So if the caller didn't provide a send buffer, we just send a zero. + */ + if (dspiState->remainingSendByteCount) + { + DSPI_DRV_MasterFillupTxFifo(instance); + } + + /* Check if we're done with this transfer.*/ + if ((dspiState->remainingSendByteCount == 0) && (dspiState->remainingReceiveByteCount == 0)) + { + /* Complete the transfer and disable the interrupts */ + DSPI_DRV_MasterCompleteTransfer(instance); + } +} + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_shared_function.c b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_shared_function.c new file mode 100755 index 0000000..33eed8b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_shared_function.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include "fsl_dspi_shared_function.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Extern for the DSPI master driver's interrupt handler.*/ +extern void DSPI_DRV_MasterIRQHandler(uint32_t instance); + +/* Extern for the SPI slave driver's interrupt handler.*/ +extern void DSPI_DRV_SlaveIRQHandler(uint32_t instance); + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief The function DSPI_DRV_IRQHandler passes IRQ control to either the master or + * slave driver. + * + * The address of the IRQ handlers are checked to make sure they are non-zero before + * they are called. If the IRQ handler's address is zero, it means that driver was + * not present in the link (because the IRQ handlers are marked as weak). This would + * actually be a program error, because it means the master/slave config for the IRQ + * was set incorrectly. + */ +void DSPI_DRV_IRQHandler(uint32_t instance) +{ + assert(instance < SPI_INSTANCE_COUNT); + SPI_Type *base = g_dspiBase[instance]; + + if (DSPI_HAL_IsMaster(base)) + { + /* Master mode.*/ + DSPI_DRV_MasterIRQHandler(instance); + } + else + { + /* Slave mode.*/ + DSPI_DRV_SlaveIRQHandler(instance); + } +} + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_slave_driver.c b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_slave_driver.c new file mode 100755 index 0000000..59d9ef6 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/dspi/fsl_dspi_slave_driver.c @@ -0,0 +1,779 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string.h> +#include <assert.h> +#include "fsl_dspi_slave_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_DSPI_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @brief Flags of DSPI slave event. + * + * DSPI event used to notify user that it finishes the task. + */ +typedef enum _dspi_event_flags { + kDspiTransferDone = 0x01, /*!< Transferring done flag */ +} dspi_event_flag_t; + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to runtime state structure.*/ +extern void * g_dspiStatePtr[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Code + ******************************************************************************/ +/*! + * @brief Finish up a transfer. + * Cleans up after a transfer is complete. Interrupts are disabled, and the DSPI module + * is disabled. This is not a public API as it is called from other driver functions. + */ +static void DSPI_DRV_SlaveCompleteTransfer(uint32_t instance); +/*! + * @brief DSPI Slave Generic IRQ handler. + * + * This handler check errors of driver and it puts data into Tx FIFO, gets data + * from Rx FIFO whenever data transmitting/received. + * This is not a public API as it is called whenever an interrupt occurs. + */ +static void DSPI_DRV_SlaveStartTransfer(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferCount); +/*! + * @brief Fill up the TX FIFO with data. + * This function fills up the TX FIFO with initial data for start of transfers where + * it will first clear the transfer count. Otherwise, if the TX FIFO fill is part + * of an ongoing transfer then do not clear the transfer count. + * This is not a public API as it is called from other driver functions. + */ +static void DSPI_DRV_SlaveFillUpTxFifo(uint32_t instance); + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_SlaveIRQHandler + * Description : DSPI Slave Generic IRQ handler. + * + * This handler check errors of driver and it puts data into Tx FIFO, gets data + * from Rx FIFO whenever data transmitting/received. + * + *END**************************************************************************/ +void DSPI_DRV_SlaveIRQHandler(uint32_t instance) +{ + SPI_Type *base = g_dspiBase[instance]; + dspi_slave_state_t *dspiState = (dspi_slave_state_t *)g_dspiStatePtr[instance]; + uint8_t nBytes; + + /* Calculate number of bytes in a frame */ + nBytes = dspiState->bitsPerFrame >> 3; /* Number of bytes is bits/frame divide 8 */ + if ((dspiState->bitsPerFrame & 0x07) != 0) /* Bits/frame module 8 is not zero */ + { + nBytes += 1; + } + + /* Because SPI protocol is synchronous, the number of bytes that that slave received from the + * master is the actual number of bytes that the slave transmitted to the master. So we only + * monitor the received size to know when the transfer is complete. + */ + if (dspiState->remainingReceiveByteCount > 0) + { + /* Read data if remaining receive byte > 0 */ + uint32_t dataReceived; + uint32_t dataSend = 0; + + while (DSPI_HAL_GetStatusFlag(base, kDspiRxFifoDrainRequest)) + { + /* Have received data in the buffer. */ + dataReceived = DSPI_HAL_ReadData(base); + /* clear the rx fifo drain request, needed for non-DMA applications as this flag + * will remain set even if the rx fifo is empty. By manually clearing this flag, it + * either remain clear if no more data is in the fifo, or it will set if there is + * more data in the fifo. + */ + DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoDrainRequest); + + /* If bits/frame is one byte */ + if (nBytes == 1) + { + if (dspiState->receiveBuffer) + { + /* Receive buffer is not null, store data into it */ + *dspiState->receiveBuffer = dataReceived; + ++dspiState->receiveBuffer; + } + if (dspiState->sendBuffer) + { + dataSend = *dspiState->sendBuffer; + ++dspiState->sendBuffer; + } + + /* Descrease remaining receive byte count */ + --dspiState->remainingReceiveByteCount; + --dspiState->remainingSendByteCount; + } + /* If bits/frame is 2 bytes */ + else + { + /* With multibytes frame receiving, we only receive till the received size + * matches user request. Other bytes will be ignored. + */ + if (dspiState->receiveBuffer) + { + /* Receive buffer is not null, store first byte into it */ + *dspiState->receiveBuffer = dataReceived; + ++dspiState->receiveBuffer; + + if (--dspiState->remainingReceiveByteCount > 0) + { + /* Receive buffer is not null, store second byte into it */ + *dspiState->receiveBuffer = dataReceived >> 8; + ++dspiState->receiveBuffer; + } + + /* Decrease remaining receive byte count */ + --dspiState->remainingReceiveByteCount; + } + else + { + /* receive buffer is null, just decrease remaining byte count */ + dspiState->remainingReceiveByteCount -= 2; + } + if (dspiState->sendBuffer) + { + dataSend = *dspiState->sendBuffer; + ++dspiState->sendBuffer; + dataSend |= (uint32_t)(*dspiState->sendBuffer) << 8; + ++dspiState->sendBuffer; + } + dspiState->remainingSendByteCount -= 2; + } + + if (dspiState->sendBuffer == NULL) + { + dataSend = dspiState->dummyPattern; + } + /* Write the data to the DSPI data register */ + DSPI_HAL_WriteDataSlavemode(base, dataSend); + /* try to clear TFFF by writing a one to it; it will not clear if TX FIFO not full */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest); + if (dspiState->remainingReceiveByteCount <= 0) + { + break; + } + } + } + /* Check if remaining receive byte count matches user request */ + if (dspiState->remainingReceiveByteCount <= 0) + { + /* Other cases, stop the transfer. */ + DSPI_DRV_SlaveCompleteTransfer(instance); + return; + } + + /* catch tx fifo underflow conditions, service only if tx under flow interrupt enabled */ + if ((DSPI_HAL_GetStatusFlag(base, kDspiTxFifoUnderflow)) && + (DSPI_HAL_GetIntMode(base, kDspiTxFifoUnderflow))) + { + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoUnderflow); + /* Change state to error and clear flag */ + dspiState->status = kStatus_DSPI_Error; + dspiState->errorCount++; + } + /* catch rx fifo overflow conditions, service only if rx over flow interrupt enabled */ + if ((DSPI_HAL_GetStatusFlag(base, kDspiRxFifoOverflow)) && + (DSPI_HAL_GetIntMode(base, kDspiRxFifoOverflow))) + { + DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoOverflow); + /* Change state to error and clear flag */ + dspiState->status = kStatus_DSPI_Error; + dspiState->errorCount++; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_SlaveInit + * Description : Initialize a DSPI slave instance. + * Un-gate its clock, initialize required resources. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_SlaveInit(uint32_t instance, + dspi_slave_state_t * dspiState, + const dspi_slave_user_config_t * slaveConfig) +{ + dspi_status_t errorCode = kStatus_DSPI_Success; + SPI_Type *base = g_dspiBase[instance]; + + /* Check parameter pointer is not NULL */ + if ((dspiState == NULL) || (slaveConfig == NULL)) + { + return kStatus_DSPI_InvalidParameter; + } + + /* Check DSPI slave instance is already initialized */ + if (g_dspiStatePtr[instance]) + { + return kStatus_DSPI_Initialized; + } + + /* Check bits/frame number */ + if (slaveConfig->dataConfig.bitsPerFrame > 16) + { + return kStatus_DSPI_OutOfRange; + } + + /* Clear the run-time state struct for this instance. */ + memset(dspiState, 0, sizeof(* dspiState)); + + /* Initial default value for ring buffer */ + dspiState->status = kStatus_DSPI_Success; + dspiState->errorCount = 0; + dspiState->dummyPattern = slaveConfig->dummyPattern; + dspiState->remainingSendByteCount = 0; + dspiState->remainingReceiveByteCount = 0; + dspiState->isTransferInProgress = false; + dspiState->receiveBuffer = NULL; + dspiState->sendBuffer = NULL; + + if (kStatus_OSA_Success != OSA_EventCreate(&dspiState->event, kEventAutoClear)) + { + /* Create event error */ + return kStatus_DSPI_Error; + } + + /* configure the run-time state struct with the nubmer of bits/frame */ + dspiState->bitsPerFrame = slaveConfig->dataConfig.bitsPerFrame; + + /* Enable clock for DSPI */ + CLOCK_SYS_EnableSpiClock(instance); + + /* Reset the DSPI module, which also disables the DSPI module */ + DSPI_HAL_Init(base); + + /* Set to slave mode. */ + DSPI_HAL_SetMasterSlaveMode(base, kDspiSlave); + + errorCode = DSPI_HAL_SetDataFormat(base, kDspiCtar0, &slaveConfig->dataConfig); + + /* Enable fifo operation (regardless of FIFO depth) */ + DSPI_HAL_SetFifoCmd(base, true, true); + + /* DSPI system enable */ + DSPI_HAL_Enable(base); + + /* flush the fifos */ + DSPI_HAL_SetFlushFifoCmd(base, true, true); + + /* Configure IRQ state structure, so irq handler can point to the correct state structure */ + g_dspiStatePtr[instance] = dspiState; + + /* Clear the Tx FIFO Fill Flag (TFFF) status bit */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest); + + /* Enable the interrupt */ + INT_SYS_EnableIRQ(g_dspiIrqId[instance]); + + /* Enable the module */ + DSPI_HAL_Enable(base); + + /* Start the transfer process in the hardware */ + DSPI_HAL_StartTransfer(base); + + return errorCode; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_SlaveDeinit + * Description : Shutdown a DSPI instance. + * Resets the DSPI peripheral, disables the interrupt to the core, and gates its clock. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_SlaveDeinit(uint32_t instance) +{ + /* instantiate local variable of type dspi_slave_state_t and equate it to the + * pointer to state + */ + dspi_slave_state_t * dspiState = (dspi_slave_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + /* Validate function parameters */ + assert(instance < SPI_INSTANCE_COUNT); + + if (!dspiState) + { + return kStatus_DSPI_NonInit; + } + + /* disable the interrupt */ + INT_SYS_DisableIRQ(g_dspiIrqId[instance]); + + /* Stop the transfer process in the slave */ + DSPI_HAL_StopTransfer(base); + + /* Wait until the DSPI run status signals that is has halted before shutting + * down the module and before gating off the DSPI clock source. Otherwise, if the DSPI + * is shut down before it has halted it's internal processes, it may be left in an unknown + * state. + */ + /* Note that if the master slave select is still asserted, the run status will never clear. + * Hence, ensure before shutting down the slave that the master has de-asserted the slave + * select signal (it should be high if slave select active low or it should be low if + * slave select is active high). + */ + while((DSPI_HAL_GetStatusFlag(base, kDspiTxAndRxStatus))) { } + + /* Restore the module to defaults then power it down. This also disables the DSPI module. */ + DSPI_HAL_Init(base); + + /* Gate the clock for DSPI. */ + CLOCK_SYS_DisableSpiClock(instance); + + /* Destroy event */ + OSA_EventDestroy(&dspiState->event); + + /* Clear state pointer. */ + g_dspiStatePtr[instance] = NULL; + + return kStatus_DSPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_SlaveFillUpTxFifo + * Description : This function fills up the TX FIFO with initial data for start of transfers + * where it will first clear the transfer count. Otherwise, if the TX FIFO fill is part of an + * ongoing transfer then do not clear the transfer count. The param "isInitialData" is used + * to determine if this is an initial data fill. + *END**************************************************************************/ +static void DSPI_DRV_SlaveFillUpTxFifo(uint32_t instance) +{ + dspi_slave_state_t * dspiState = (dspi_slave_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + uint32_t transmitData = 0; /* Maximum supported data bit length in slave mode is 32-bits */ + uint8_t nBytes = 0; + + /* Calculate number of bytes in a frame */ + nBytes = dspiState->bitsPerFrame >> 3; + if ((dspiState->bitsPerFrame & 0x07) != 0) + { + nBytes += 1; + } + + /* Service the transmitter, if transmit buffer provided, transmit the data, + * else transmit dummy pattern + */ + while(DSPI_HAL_GetStatusFlag(base, kDspiTxFifoFillRequest)) + { + /* transmit data */ + if(dspiState->remainingSendByteCount > 0) + { + /* Have data to transmit, update the transmit data and push to FIFO */ + if(nBytes == 1) + { + /* bits/frame is 1 byte */ + if (dspiState->sendBuffer) + { + /* Update transmit data and transmit pointer */ + transmitData = *dspiState->sendBuffer; + dspiState->sendBuffer++; + } + else + { + transmitData = dspiState->dummyPattern; + } + + /* Decrease remaining size */ + --dspiState->remainingSendByteCount; + } + /* bits/frame is 2 bytes */ + else + { + /* With multibytes per frame transmission, the transmit frame contains data from + * transmit buffer until sent size matches user request. Other bytes will set to + * dummy pattern value. + */ + + if (dspiState->sendBuffer) + { + /* Update first byte of transmit data and transmit pointer */ + transmitData = *dspiState->sendBuffer; + dspiState->sendBuffer++; + + /* Check if send completed, decrease remaining size */ + if(--dspiState->remainingSendByteCount > 0) + { + /* Update second byte of transmit data and transmit pointer */ + transmitData |= (uint32_t)(*dspiState->sendBuffer) << 8; + dspiState->sendBuffer++; + } + else + { + /* Update second byte of transmit data to second byte of dummy pattern */ + transmitData |= dspiState->dummyPattern & 0xFF00; + } + + /* Decrease remaining size */ + --dspiState->remainingSendByteCount; + } + else + { + /* Decrease remaining size */ + dspiState->remainingSendByteCount -= 2; + transmitData = dspiState->dummyPattern; + } + } + } + else + { + /* Nothing to transmit, send dummy pattern to master */ + transmitData = dspiState->dummyPattern; + } + + /* Write the data to the DSPI data register */ + DSPI_HAL_WriteDataSlavemode(base, transmitData); + /* try to clear TFFF by writing a one to it; it will not clear if TX FIFO not full */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_SlaveStartTransfer + * Description : Starts transfer data on SPI bus using interrupt and non-blocking call + * Start DSPI transfering, update transmit/receive information into slave state structure + * + *END**************************************************************************/ +static void DSPI_DRV_SlaveStartTransfer(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferCount) +{ + dspi_slave_state_t * dspiState = (dspi_slave_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + /* Save information about the transfer for use by the ISR. */ + dspiState->isTransferInProgress = true; + + /* Store transfer information */ + dspiState->sendBuffer = sendBuffer; + dspiState->receiveBuffer = receiveBuffer; + dspiState->remainingSendByteCount = transferCount; + dspiState->remainingReceiveByteCount = transferCount; + dspiState->errorCount = 0; + + /* Restart the transfer by stop then start again, this will clear out the shift register */ + DSPI_HAL_StopTransfer(base); + + /* flush the fifos */ + DSPI_HAL_SetFlushFifoCmd(base, true, true); + + /* Clear status flags that may have been set from previous transfers */ + DSPI_HAL_ClearStatusFlag(base, kDspiTxComplete); + DSPI_HAL_ClearStatusFlag(base, kDspiEndOfQueue); + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoUnderflow); + DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest); + DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoOverflow); + DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoDrainRequest); + + /* Clear the transfer count */ + DSPI_HAL_PresetTransferCount(base, 0); + + /* Start the transfer, make sure to do this before filling the FIFO */ + DSPI_HAL_StartTransfer(base); + + /* Prepare data to transmit */ + DSPI_DRV_SlaveFillUpTxFifo(instance); + + /* Enable RX FIFO drain request, the slave only use this interrupt */ + DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateIntReq, true); + if(receiveBuffer) + { + /* RX FIFO overflow request enable */ + DSPI_HAL_SetIntMode(base, kDspiRxFifoOverflow, true); + } + if (sendBuffer) + { + /* TX FIFO underflow request enable */ + DSPI_HAL_SetIntMode(base, kDspiTxFifoUnderflow, true); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_SlaveCompleteTransfer + * Description : Finish the transfer + * Called when transfer is finished + * + *END**************************************************************************/ +static void DSPI_DRV_SlaveCompleteTransfer(uint32_t instance) +{ + dspi_slave_state_t * dspiState = (dspi_slave_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + /* The transfer is complete. */ + dspiState->isTransferInProgress = false; + dspiState->sendBuffer = NULL; + dspiState->receiveBuffer = NULL; + dspiState->remainingReceiveByteCount = 0; + dspiState->remainingSendByteCount = 0; + + /* Disable interrupt requests */ + /* RX FIFO Drain request: RFDF_RE */ + DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateIntReq, false); + + /* Disable TX FIFO Fill request */ + DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateIntReq, false); + + /* TX FIFO underflow request disable */ + DSPI_HAL_SetIntMode(base, kDspiTxFifoUnderflow, false); + + /* RX FIFO overflow request disable */ + DSPI_HAL_SetIntMode(base, kDspiRxFifoOverflow, false); + + /* Update DSPI status */ + dspiState->status = kStatus_DSPI_Success; + + /* Notify the event */ + OSA_EventSet(&dspiState->event, kDspiTransferDone); +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_SlaveTransfer + * Description : Transfer data to master + * Start transfer data to master + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_SlaveTransfer(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount) +{ + dspi_slave_state_t * dspiState = (dspi_slave_state_t *)g_dspiStatePtr[instance]; + + /* Check validation of parameters */ + assert(instance < SPI_INSTANCE_COUNT); + + /* Check driver initialization and idle */ + if(!dspiState) + { + return kStatus_DSPI_NonInit; + } + if (kStatus_DSPI_Success != dspiState->status) + { + return dspiState->status; + } + + /* If receive length is zero */ + if (transferByteCount == 0) + { + return kStatus_DSPI_InvalidParameter; + } + + /* If both send buffer and receive buffer is null */ + if ((!sendBuffer) && (!receiveBuffer)) + { + return kStatus_DSPI_InvalidParameter; + } + + /* If DSPI is in transmitting or receving process, return busy */ + if (dspiState->isTransferInProgress) + { + return kStatus_DSPI_Busy; + } + + /* Marks function to async */ + dspiState->isSync = false; + + DSPI_DRV_SlaveStartTransfer(instance, sendBuffer, receiveBuffer, transferByteCount); + return kStatus_DSPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_SlaveTransferBlocking + * Description : Transfer data - blocking + * Transfer data - blocking + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_SlaveTransferBlocking(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount, + uint32_t timeout) +{ + dspi_slave_state_t * dspiState = (dspi_slave_state_t *)g_dspiStatePtr[instance]; + osa_status_t osaStatus = kStatus_OSA_Success; + event_flags_t setFlags = 0; + dspi_status_t result = kStatus_DSPI_Success; + + /* Check validation of parameters */ + assert(instance < SPI_INSTANCE_COUNT); + + /* Check driver initialization and idle */ + if(!dspiState) + { + return kStatus_DSPI_NonInit; + } + if (kStatus_DSPI_Success != dspiState->status) + { + return dspiState->status; + } + + /* If receive length is zero, return success immediately without any data */ + if (transferByteCount == 0) + { + return kStatus_DSPI_InvalidParameter; + } + + /* If both send buffer and receive buffer is null */ + if ((!sendBuffer) && (!receiveBuffer)) + { + return kStatus_DSPI_InvalidParameter; + } + + /* If DSPI is in transmitting or receving process, return busy */ + if (dspiState->isTransferInProgress) + { + return kStatus_DSPI_Busy; + } + + /* Marks function to sync */ + dspiState->isSync = true; + + /* Clear the event flags */ + OSA_EventClear(&dspiState->event, kDspiTransferDone); + + /* Start transfer */ + DSPI_DRV_SlaveStartTransfer(instance, sendBuffer, receiveBuffer, transferByteCount); + + /* wait transfer finished */ + do + { + osaStatus = OSA_EventWait(&dspiState->event, kDspiTransferDone, true, timeout, &setFlags); + } while(osaStatus == kStatus_OSA_Idle); + + /* Check status of OSA wait event */ + switch (osaStatus) + { + case kStatus_OSA_Success: + result = kStatus_DSPI_Success; + break; + case kStatus_OSA_Timeout: + result = kStatus_DSPI_Timeout; + break; + case kStatus_OSA_Error: + default: + result = kStatus_DSPI_Error; + break; + } + + /* Abort the transfer if it is failed */ + if (result != kStatus_DSPI_Success) + { + DSPI_DRV_SlaveAbortTransfer(instance); + } + + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_SlaveAbortTransfer + * Description : Abort tranfer + * Abort data transfer, using after function DSPI_DRV_SlaveTransfer() to abort + * transfering data + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_SlaveAbortTransfer(uint32_t instance) +{ + dspi_slave_state_t * dspiState = (dspi_slave_state_t *)g_dspiStatePtr[instance]; + + /* Check instance is valid or not */ + assert(instance < SPI_INSTANCE_COUNT); + + /* Check driver is initialized */ + if (!dspiState) + { + return kStatus_DSPI_NonInit; + } + + /* Check transfer is in progress */ + if (!dspiState->isTransferInProgress) + { + return kStatus_DSPI_NoTransferInProgress; + } + + /* Stop transfer */ + DSPI_DRV_SlaveCompleteTransfer(instance); + + return kStatus_DSPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : DSPI_DRV_SlaveGetTransferStatus + * Description : Returns whether the previous transfer has finished yet. + * When performing an async transfer, the user can call this function to ascertain the state of the + * current transfer: in progress (or busy) or complete (success). In addition, if the transfer + * is still in progress, the user can obtain the number of words that have been currently + * transferred. + * + *END**************************************************************************/ +dspi_status_t DSPI_DRV_SlaveGetTransferStatus(uint32_t instance, uint32_t * framesTransferred) +{ + /* instantiate local variable of type dspi_slave_state_t and point to global state */ + dspi_slave_state_t * dspiState = (dspi_slave_state_t *)g_dspiStatePtr[instance]; + SPI_Type *base = g_dspiBase[instance]; + + /* Fill in the bytes transferred if required */ + if (framesTransferred) + { + *framesTransferred = DSPI_HAL_GetTransferCount(base); + } + + /* return success if non transferring is in progress */ + return ((dspiState->isTransferInProgress) ? kStatus_DSPI_Busy : kStatus_DSPI_Success); +} + +#endif /* FSL_FEATURE_SOC_DSPI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/edma/fsl_edma_common.c b/KSDK_1.2.0/platform/drivers/src/edma/fsl_edma_common.c new file mode 100755 index 0000000..5468054 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/edma/fsl_edma_common.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <stdint.h> +#include "fsl_device_registers.h" + +DMA_Type * const g_edmaBase[] = DMA_BASE_PTRS; +DMAMUX_Type * const g_dmamuxBase[] = DMAMUX_BASE_PTRS; +const IRQn_Type g_edmaIrqId[DMA_INSTANCE_COUNT][FSL_FEATURE_EDMA_MODULE_CHANNEL] = +{ + DMA_CHN_IRQS +}; + +#if !defined FSL_FEATURE_EDMA_HAS_ERROR_IRQ +const IRQn_Type g_edmaErrIrqId[DMA_INSTANCE_COUNT] = DMA_ERROR_IRQS; +#endif + +/******************************************************************************* +* EOF +******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/edma/fsl_edma_driver.c b/KSDK_1.2.0/platform/drivers/src/edma/fsl_edma_driver.c new file mode 100755 index 0000000..65ed6b7 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/edma/fsl_edma_driver.c @@ -0,0 +1,700 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <string.h> +#include "fsl_edma_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_EDMA_COUNT + +/******************************************************************************* + * Variabled + ******************************************************************************/ +/*! @brief EDMA global structure to maintain EDMA resource */ +edma_state_t *g_edma = NULL; + +/******************************************************************************* + * PROTOTYPES + ******************************************************************************/ +static edma_status_t EDMA_DRV_ClaimChannel( + uint8_t channel, dma_request_source_t source, edma_chn_state_t *chn); +static void EDMA_DRV_ClearIntStatus(uint8_t channel); + +/*! @brief Macro for EDMA driver lock mechanism. */ +#if (USE_RTOS) + #define EDMA_DRV_LOCK() OSA_MutexLock(&g_edma->lock, OSA_WAIT_FOREVER) + #define EDMA_DRV_UNLOCK() OSA_MutexUnlock(&g_edma->lock) +#else + #define EDMA_DRV_LOCK() do {}while(0) + #define EDMA_DRV_UNLOCK() do {}while(0) +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_Init + * Description : Initializes all eDMA modules in SOC. + * + *END**************************************************************************/ +edma_status_t EDMA_DRV_Init(edma_state_t *edmaState, const edma_user_config_t *userConfig) +{ + uint32_t i, j; + DMA_Type * edmaRegBase; + DMAMUX_Type * dmamuxRegBase; + IRQn_Type irqNumber; + + if (g_edma) + { + return kStatus_EDMA_Success; + } + + g_edma = edmaState; + memset(g_edma, 0, sizeof(edma_state_t)); +#if (USE_RTOS) + /* Init mutex object for the access control of edma data structure. */ + OSA_MutexCreate(&g_edma->lock); +#endif + + for (i = 0; i < DMA_INSTANCE_COUNT; i++) + { + edmaRegBase = g_edmaBase[i]; + /* Enable clock gate of eDMA module. */ + CLOCK_SYS_EnableDmaClock(i); + + /* Init eDMA module in hardware level. */ + EDMA_HAL_Init(edmaRegBase); + + EDMA_HAL_SetChannelArbitrationMode(edmaRegBase, userConfig->chnArbitration); +#if (FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 0x1U) + EDMA_HAL_SetGroupArbitrationMode(edmaRegBase, userConfig->groupArbitration); + EDMA_HAL_SetGroupPriority(edmaRegBase, userConfig->groupPriority); +#endif + EDMA_HAL_SetHaltOnErrorCmd(edmaRegBase, !userConfig->notHaltOnError); + +#if !defined FSL_FEATURE_EDMA_HAS_ERROR_IRQ + /* Enable the error interrupt for eDMA module. */ + irqNumber = g_edmaErrIrqId[i]; + INT_SYS_EnableIRQ(irqNumber); +#endif + + /* Register all edma channl interrupt handler into vector table. */ + for (j = 0; j < FSL_FEATURE_EDMA_MODULE_CHANNEL; j++) + { + /* Enable channel interrupt ID. */ + irqNumber = g_edmaIrqId[i][j]; + INT_SYS_EnableIRQ(irqNumber); + } + } + + for (i = 0; i < DMAMUX_INSTANCE_COUNT; i++) + { + dmamuxRegBase = g_dmamuxBase[i]; + /* Enable dmamux clock gate */ + CLOCK_SYS_EnableDmamuxClock(i); + + /* Init dmamux module in hardware level */ + DMAMUX_HAL_Init(dmamuxRegBase); + } + + return kStatus_EDMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_Deinit + * Description : Deinitilize EDMA. + * + *END**************************************************************************/ +edma_status_t EDMA_DRV_Deinit(void) +{ + uint32_t i, j; + IRQn_Type irqNumber; + edma_chn_state_t *chn; + + /* Release all edma channel. */ + for (i = 0; i < DMA_INSTANCE_COUNT; i++) + { +#if !defined FSL_FEATURE_EDMA_HAS_ERROR_IRQ + /* Disable the error interrupt for eDMA module. */ + irqNumber = g_edmaErrIrqId[i]; + INT_SYS_DisableIRQ(irqNumber); +#endif + + for (j = i * FSL_FEATURE_EDMA_MODULE_CHANNEL; j < (i + 1) * FSL_FEATURE_EDMA_MODULE_CHANNEL; j++) + { + /* Release all channel. */ + chn = g_edma->chn[j]; + if (chn) + { + EDMA_DRV_ReleaseChannel(chn); + } + + /* Enable channel interrupt ID. */ + irqNumber = g_edmaIrqId[i][j]; + INT_SYS_DisableIRQ(irqNumber); + } + + /* Disable edma clock gate. */ + CLOCK_SYS_DisableDmaClock(i); + } + + /* Disable dmamux clock gate. */ + for (i = 0; i < DMAMUX_INSTANCE_COUNT; i++) + { + CLOCK_SYS_DisableDmamuxClock(i); + } + +#if (USE_RTOS) + OSA_MutexDestroy(&g_edma->lock); +#endif + + g_edma = NULL; + + return kStatus_EDMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_InstallCallback + * Description : Register callback function and parameter. + * + *END**************************************************************************/ +edma_status_t EDMA_DRV_InstallCallback( + edma_chn_state_t *chn, edma_callback_t callback, void *parameter) +{ + chn->callback = callback; + chn->parameter = parameter; + + return kStatus_EDMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_RequestChannel + * Description : Request an eDMA channel. + * + *END**************************************************************************/ +uint8_t EDMA_DRV_RequestChannel( + uint8_t channel, dma_request_source_t source, edma_chn_state_t *chn) +{ + + /*Check if dynamically allocation is requested */ + if (channel == kEDMAAnyChannel) + { + uint32_t i = 0, j; + uint32_t map; + map = ((uint32_t)source >> 8); + + while (map != 0) + { + if (map & (1U << i)) + { + for (j = i * FSL_FEATURE_DMAMUX_MODULE_CHANNEL; j < (i + 1) * FSL_FEATURE_DMAMUX_MODULE_CHANNEL; j++) + { + EDMA_DRV_LOCK(); + if (!g_edma->chn[j]) + { + g_edma->chn[j] = chn; + EDMA_DRV_UNLOCK(); + EDMA_DRV_ClaimChannel(j, source, chn); + return j; + } + EDMA_DRV_UNLOCK(); + } + + } + map &= ~(0x1U << i); + i++; + } + + /* No available channel. */ + return kEDMAInvalidChannel; + } + + /* static allocation */ + EDMA_DRV_LOCK(); + if (!g_edma->chn[channel]) + { + g_edma->chn[channel] = chn; + EDMA_DRV_UNLOCK(); + EDMA_DRV_ClaimChannel(channel, source, chn); + return channel; + } + EDMA_DRV_UNLOCK(); + + return kEDMAInvalidChannel; +} + +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_ClaimChannel + * Description : Claim an edma channel. + * + *END**************************************************************************/ +static edma_status_t EDMA_DRV_ClaimChannel( + uint8_t channel, dma_request_source_t source, edma_chn_state_t *chn) +{ + uint8_t src = (uint32_t)source & 0xFF; + DMA_Type * edmaRegBase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(channel); + DMAMUX_Type * dmamuxRegBase = VIRTUAL_CHN_TO_DMAMUX_MODULE_REGBASE(channel); + uint32_t dmamuxChannel = VIRTUAL_CHN_TO_DMAMUX_CHN(channel); + + /* Reset the channel state structure to default value. */ + memset(chn, 0, sizeof(edma_chn_state_t)); + + /* Init the channel state structure to the allocated channel number. */ + chn->channel = channel; + + /* Enable error interrupt for this channel */ + EDMA_HAL_SetErrorIntCmd(edmaRegBase, true, (edma_channel_indicator_t)edmaChannel); + + /* Configure the DMAMUX for edma channel */ + DMAMUX_HAL_SetChannelCmd(dmamuxRegBase, dmamuxChannel, false); + DMAMUX_HAL_SetTriggerSource(dmamuxRegBase, dmamuxChannel, src%(uint8_t)kDmamuxDmaRequestSource); + DMAMUX_HAL_SetChannelCmd(dmamuxRegBase, dmamuxChannel, true); + + /* Clear the TCD registers for this channel */ + EDMA_HAL_HTCDClearReg(edmaRegBase, edmaChannel); + + return kStatus_EDMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_ReleaseChannel + * Description : Free eDMA channel's hardware and software resource. + * + *END**************************************************************************/ +edma_status_t EDMA_DRV_ReleaseChannel(edma_chn_state_t *chn) +{ + uint32_t channel = chn->channel; + DMA_Type * edmaRegBase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(channel); + + if (!g_edma->chn[channel]) + { + return kStatus_EDMA_InvalidArgument; + } + + /* Stop edma channel. */ + EDMA_HAL_SetDmaRequestCmd(edmaRegBase,(edma_channel_indicator_t)edmaChannel, false); + + memset(chn, 0x0, sizeof(edma_chn_state_t)); + + EDMA_DRV_LOCK(); + g_edma->chn[channel] = NULL; + EDMA_DRV_UNLOCK(); + return kStatus_EDMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_ClearIntStatus + * Description : Clear done and interrupt status. + * + *END**************************************************************************/ +static void EDMA_DRV_ClearIntStatus(uint8_t channel) +{ + DMA_Type * edmaRegBase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(channel); + + EDMA_HAL_ClearDoneStatusFlag(edmaRegBase, (edma_channel_indicator_t)edmaChannel); + EDMA_HAL_ClearIntStatusFlag(edmaRegBase, (edma_channel_indicator_t)edmaChannel); +} + +#if (FSL_FEATURE_EDMA_MODULE_CHANNEL <= 16U) +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_IRQ_HANDLER + * Description : EDMA IRQ handler. + * + *END**************************************************************************/ +void EDMA_DRV_IRQHandler(uint8_t channel) +{ + edma_chn_state_t *chn = g_edma->chn[channel]; + + if (!chn) + { + return; + } + + EDMA_DRV_ClearIntStatus(channel); + + if (chn->callback) + { + chn->callback(chn->parameter, chn->status); + } +} +#else +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_IRQ_HANDLER + * Description : EDMA IRQ handler.This handler is for EDMA module in which + * channel n share the irq number with channel (n + 16) + * + *END**************************************************************************/ +void EDMA_DRV_IRQHandler(uint8_t channel) +{ + edma_chn_state_t *chn = g_edma->chn[channel]; + DMA_Type * edmaRegBase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(channel); + + while (channel < 32) + { + chn = g_edma->chn[channel]; + + if ((chn != NULL) && (EDMA_HAL_GetIntStatusFlag(edmaRegBase, edmaChannel) != 0)) + { + EDMA_DRV_ClearIntStatus(channel); + if (chn->callback) + { + chn->callback(chn->parameter, chn->status); + } + } + channel += 16; + edmaRegBase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(channel); + edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(channel); + } +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : DMA_ERR_IRQHandler + * Description : EDMA error handler + * + *END**************************************************************************/ +void EDMA_DRV_ErrorIRQHandler(uint8_t instance) +{ + uint32_t channel, error, j = 0; + DMA_Type * edmaRegBase = g_edmaBase[instance]; + edma_chn_state_t *chn; + + error = EDMA_HAL_GetErrorIntStatusFlag(edmaRegBase); + + while (error && (j < FSL_FEATURE_EDMA_MODULE_CHANNEL)) + { + if (error & 1U) + { + channel = instance * FSL_FEATURE_EDMA_MODULE_CHANNEL + j; + EDMA_HAL_SetDmaRequestCmd(edmaRegBase, (edma_channel_indicator_t)j, false); + chn = g_edma->chn[channel]; + if (chn) + { + EDMA_DRV_ClearIntStatus(channel); + chn->status = kEDMAChnError; + if (chn->callback) + { + chn->callback(chn->parameter, chn->status); + } + } + } + error = error >> 1U; + j++; + } + EDMA_HAL_SetHaltCmd(edmaRegBase, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_ConfigLoopTransfer + * Description : Configures the DMA transfer in a loop. + * + *END**************************************************************************/ +edma_status_t EDMA_DRV_ConfigLoopTransfer( + edma_chn_state_t *chn, edma_software_tcd_t *stcd, + edma_transfer_type_t type, + uint32_t srcAddr, uint32_t destAddr, uint32_t size, + uint32_t bytesOnEachRequest, uint32_t totalLength, uint8_t number) +{ + assert(stcd); + + uint8_t i; + edma_software_tcd_t *stcdAddr = (edma_software_tcd_t *)STCD_ADDR(stcd); + edma_transfer_size_t transfersize; + edma_transfer_config_t config; + + /* Set the software TCD memory to default value. */ + memset(stcdAddr, 0, number * sizeof(edma_software_tcd_t)); + + /* translate the transfer size to eDMA allowed transfer size enum type. */ + switch(size) + { + case 1: + transfersize = kEDMATransferSize_1Bytes; + break; + case 2: + transfersize = kEDMATransferSize_2Bytes; + break; + case 4: + transfersize = kEDMATransferSize_4Bytes; + break; + case 16: + transfersize = kEDMATransferSize_16Bytes; + break; + case 32: + transfersize = kEDMATransferSize_32Bytes; + break; + default: + return kStatus_EDMA_InvalidArgument; + } + + /* Configure the software TCD one by one.*/ + config.srcLastAddrAdjust = 0; + config.destLastAddrAdjust = 0; + config.srcModulo = kEDMAModuloDisable; + config.destModulo = kEDMAModuloDisable; + config.srcTransferSize = transfersize; + config.destTransferSize = transfersize; + config.minorLoopCount = bytesOnEachRequest; + config.majorLoopCount = totalLength / (bytesOnEachRequest * number); + for(i = 0; i < number; i++) + { + switch (type) + { + case kEDMAPeripheralToMemory: + /* Configure Source Read. */ + config.srcAddr = srcAddr; + config.srcOffset = 0; + + /* Configure Dest Write. */ + config.destAddr = destAddr + i * (totalLength/number); + config.destOffset = size; + break; + case kEDMAMemoryToPeripheral: + /* Configure Source Read. */ + config.srcAddr = srcAddr + i * (totalLength/number); + config.srcOffset = size; + + /* Configure Dest Write. */ + config.destAddr = destAddr; + config.destOffset = 0; + break; + case kEDMAMemoryToMemory: + /* Configure Source Read. */ + config.srcAddr = srcAddr + i * (totalLength/number); + config.srcOffset = size; + + /* Configure Dest Write. */ + config.destAddr = destAddr + i * (totalLength/number); + config.destOffset = size; + break; + default: + return kStatus_EDMA_InvalidArgument; + } + + EDMA_DRV_PrepareDescriptorTransfer(chn, &stcdAddr[i], &config, true, false); + EDMA_DRV_PrepareDescriptorScatterGather(&stcdAddr[i], &stcdAddr[(i+1)%number]); + } + + EDMA_DRV_PushDescriptorToReg(chn, &stcdAddr[0]); + + return kStatus_EDMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_ConfigScatterGatherTransfer + * Description : User friendly interface to configure single end descritptor chain. + * + *END**************************************************************************/ +edma_status_t EDMA_DRV_ConfigScatterGatherTransfer( + edma_chn_state_t *chn, edma_software_tcd_t *stcd, + edma_transfer_type_t type, + uint32_t size, uint32_t bytesOnEachRequest, + edma_scatter_gather_list_t *srcList, edma_scatter_gather_list_t *destList, + uint8_t number) +{ + assert(stcd); + uint8_t i; + edma_transfer_size_t transfersize; + edma_software_tcd_t *stcdAddr = (edma_software_tcd_t *)STCD_ADDR(stcd); + edma_transfer_config_t config; + + if (number > 1) + { + memset(stcdAddr, 0, number * sizeof(edma_software_tcd_t)); + } + + switch(size) + { + case 1: + transfersize = kEDMATransferSize_1Bytes; + break; + case 2: + transfersize = kEDMATransferSize_2Bytes; + break; + case 4: + transfersize = kEDMATransferSize_4Bytes; + break; + case 16: + transfersize = kEDMATransferSize_16Bytes; + break; + case 32: + transfersize = kEDMATransferSize_32Bytes; + break; + default: + return kStatus_EDMA_InvalidArgument; + } + + + /* Configure the software TCD one by one.*/ + config.srcLastAddrAdjust = 0; + config.destLastAddrAdjust = 0; + config.srcModulo = kEDMAModuloDisable; + config.destModulo = kEDMAModuloDisable; + config.srcTransferSize = transfersize; + config.destTransferSize = transfersize; + config.minorLoopCount = bytesOnEachRequest; + + for (i = 0; i < number; i++) + { + config.srcAddr = srcList[i].address; + config.destAddr = destList[i].address; + if (srcList[i].length != destList[i].length) + { + return kStatus_EDMA_InvalidArgument; + } + config.majorLoopCount = srcList[i].length/bytesOnEachRequest; + + switch (type) + { + case kEDMAPeripheralToMemory: + /* Configure Source Read. */ + config.srcOffset = 0; + + /* Configure Dest Write. */ + config.destOffset = size; + break; + case kEDMAMemoryToPeripheral: + /* Configure Source Read. */ + config.srcOffset = size; + + /* Configure Dest Write. */ + config.destOffset = 0; + break; + case kEDMAMemoryToMemory: + /* Configure Source Read. */ + config.srcOffset = size; + + /* Configure Dest Write. */ + config.destOffset = size; + break; + default: + return kStatus_EDMA_InvalidArgument; + } + + if (number == 1) + { + /* If only one TCD is required, only hardware TCD is required and user + * is not required to prepare the software TCD memory. */ + edma_software_tcd_t temp[2]; + edma_software_tcd_t *tempTCD = STCD_ADDR(temp); + memset((void*) tempTCD,0, sizeof(edma_software_tcd_t)); + EDMA_DRV_PrepareDescriptorTransfer(chn, tempTCD, &config, true, true); + EDMA_DRV_PushDescriptorToReg(chn, tempTCD); + } + else if (i == (number - 1)) + { + EDMA_DRV_PrepareDescriptorTransfer(chn, &stcdAddr[i], &config, true, true); + EDMA_DRV_PushDescriptorToReg(chn, &stcdAddr[0]); + } + else + { + EDMA_DRV_PrepareDescriptorTransfer(chn, &stcdAddr[i], &config, false, false); + EDMA_DRV_PrepareDescriptorScatterGather(&stcdAddr[i], &stcdAddr[i+1]); + } + } + + return kStatus_EDMA_Success; + +} + +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_StartChannel + * Description : Starts an eDMA channel. + * + *END**************************************************************************/ +edma_status_t EDMA_DRV_StartChannel(edma_chn_state_t *chn) +{ + uint32_t channel = chn->channel; + DMA_Type * edmaRegBase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(channel); + + EDMA_HAL_SetDmaRequestCmd(edmaRegBase,(edma_channel_indicator_t)edmaChannel,true); + + return kStatus_EDMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_StopChannel + * Description : Stops an eDMA channel. + * + *END**************************************************************************/ +edma_status_t EDMA_DRV_StopChannel(edma_chn_state_t *chn) +{ + uint32_t channel = chn->channel; + DMA_Type * edmaRegBase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(channel); + + EDMA_HAL_SetDmaRequestCmd(edmaRegBase,(edma_channel_indicator_t)edmaChannel, false); + + return kStatus_EDMA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : EDMA_DRV_PushDescriptorToReg + * Description : Copy the software TCD configuration to the hardware TCD. + * + *END**************************************************************************/ +edma_status_t EDMA_DRV_PushDescriptorToReg(edma_chn_state_t *chn, edma_software_tcd_t *stcd) +{ + uint32_t channel = chn->channel; + DMA_Type * edmaRegBase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(channel); + + EDMA_HAL_HTCDClearReg(edmaRegBase, edmaChannel); + EDMA_HAL_PushSTCDToHTCD(edmaRegBase, edmaChannel, stcd); + + return kStatus_EDMA_Success; +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/edma/fsl_edma_irq.c b/KSDK_1.2.0/platform/drivers/src/edma/fsl_edma_irq.c new file mode 100755 index 0000000..a1f7c5b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/edma/fsl_edma_irq.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_edma_driver.h" +#if FSL_FEATURE_SOC_DMA_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/*! @brief Edma Handler*/ +#if (FSL_FEATURE_EDMA_MODULE_CHANNEL == 4) + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA0_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(0); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA1_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(1); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA2_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(2); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA3_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(3); +} + +#elif (FSL_FEATURE_EDMA_MODULE_CHANNEL <= 16) +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA0_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(0); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA1_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(1); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA2_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(2); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA3_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(3); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA4_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(4); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA5_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(5); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA6_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(6); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA7_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(7); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA8_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(8); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA9_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(9); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA10_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(10); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA11_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(11); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA12_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(12); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA13_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(13); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA14_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(14); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA15_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(15); +} + +#else +void DMA0_DMA16_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(0); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA1_DMA17_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(1); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA2_DMA18_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(2); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA3_DMA19_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(3); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA4_DMA20_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(4); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA5_DMA21_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(5); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA6_DMA22_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(6); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA7_DMA23_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(7); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA8_DMA24_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(8); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA9_DMA25_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(9); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA10_DMA26_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(10); +} + + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA11_DMA27_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(11); +} + + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA12_DMA28_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(12); +} + + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA13_DMA29_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(13); +} + + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA14_DMA30_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(14); +} + +/*! @brief EDMA IRQ handler with the same name in the startup code*/ +void DMA15_DMA31_IRQHandler(void) +{ + EDMA_DRV_IRQHandler(15); +} +#endif + +#if FSL_FEATURE_EDMA_HAS_ERROR_IRQ +/*! @brief EDMA ERROR IRQ handler with the same name in the startup code*/ +void DMA_Error_IRQHandler(void) +{ + EDMA_DRV_ErrorIRQHandler(0); +} +#endif +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/edma/fsl_edma_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/edma/fsl_edma_lpm_callback.c new file mode 100755 index 0000000..14e3557 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/edma/fsl_edma_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_DMA_COUNT + +power_manager_error_code_t edma_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t edma_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/enc/fsl_enc_common.c b/KSDK_1.2.0/platform/drivers/src/enc/fsl_enc_common.c new file mode 100755 index 0000000..cc6165e --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/enc/fsl_enc_common.c @@ -0,0 +1,31 @@ +/******************************************************************************* +* +* Copyright [2014-]2014 Freescale Semiconductor, Inc. + +* +* This software is owned or controlled by Freescale Semiconductor. +* Use of this software is governed by the Freescale License +* distributed with this Material. +* See the LICENSE file distributed for more details. +* +* +*******************************************************************************/ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for ENC instances. */ +ENC_Type* const g_encBase[] = ENC_BASE_PTRS; + +/* Table to save ENC IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_encCmpIrqId[ENC_INSTANCE_COUNT] = {ENC_COMPARE_IRQn}; +const IRQn_Type g_encHomeIrqId[ENC_INSTANCE_COUNT] = {ENC_HOME_IRQn}; +const IRQn_Type g_encWdtIrqId[ENC_INSTANCE_COUNT] = {ENC_WDOG_SAB_IRQn}; +const IRQn_Type g_encIndexIrqId[ENC_INSTANCE_COUNT] = {ENC_INDEX_IRQn}; + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/enc/fsl_enc_driver.c b/KSDK_1.2.0/platform/drivers/src/enc/fsl_enc_driver.c new file mode 100755 index 0000000..053abd1 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/enc/fsl_enc_driver.c @@ -0,0 +1,666 @@ +/******************************************************************************* +* +* Copyright [2014-]2014 Freescale Semiconductor, Inc. + +* +* This software is owned or controlled by Freescale Semiconductor. +* Use of this software is governed by the Freescale License +* distributed with this Material. +* See the LICENSE file distributed for more details. +* +* +*******************************************************************************/ + +#include <assert.h> +#include <string.h> +#include "fsl_enc_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_ENC_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************* + * + * Function Name : ENC_DRV_StructInitUserConfigNormal + * Description : This function fills the initial user configuration. + * Calling the initialization function with the filled parameter configures + * the ENC module to function as a simple Quadrature Encoder. + * + *END*************************************************************************/ +enc_status_t ENC_DRV_StructInitUserConfigNormal(enc_user_config_t * userConfigPtr) +{ + /* Test structure pointer. */ + if (!userConfigPtr) + { + return kStatus_ENC_InvalidArgument; + } + + /* Normal Encoder mode. */ + userConfigPtr->operationMode = kEncNormalMode; + + /* Reverse counting disabled. */ + userConfigPtr->reverseCounting = false; + + /* Positive edge of INDEX pulse. */ + userConfigPtr->indexInputNegativeEdge = false; + + /* Positive edge of HOME signal. */ + userConfigPtr->homeInputNegativeEdge = false; + + /* Init position register by INDEX pulse. */ + userConfigPtr->indexPulsePosInit = true; + + /* Initialization register value set to 0U. */ + userConfigPtr->posCntInitValue = 0U; + + /* Position compare register value set to 0xFFFFU. */ + userConfigPtr->posCmpValue = 0xFFFFU; + + /* Modulus register value set to 0U. */ + userConfigPtr->moduloValue = 0U; + + /* Update HOLD registers on trigger input disabled. */ + userConfigPtr->triggerUpdateHoldRegEnable = false; + + /* Clear position counter on trigger input disabled. */ + userConfigPtr->triggerClearPosRegEnable = false; + + /* Modulo counting revolution register disabled. */ + userConfigPtr->moduloRevolutionCounting = false; + + /* POSMATCH pulses when match occurs between position register and compare register value. */ + userConfigPtr->outputControlOnReading = false; + + /* Watchdog disabled. */ + userConfigPtr->watchdogTimeout = 0U; + + /* Filter number of counts set to 0. */ + userConfigPtr->filterCount = 0U; + + /* Filter period set to 0U. */ + userConfigPtr->filterPeriod = 0U; + + /* Return success status code. */ + return kStatus_ENC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : ENC_DRV_Init + * Description : This function initializes a ENC instance for operation. + * This function initializes the run-time state structure to ungate the clock to the ENC module, + * initializes the module to user-defined settings and default settings, + * configures the IRQ state structure and enables the module-level interrupt to the core. + * This example shows how to set up the enc_state_t and the + * enc_user_config_t parameters and how to call the ENC_DRV_Init function by passing + * in these parameters: + enc_user_config_t encUserConfig; + encUserConfig.operationMode = kEncNormalMode; + encUserConfig.reverseCounting = false; + encUserConfig.indexInputNegativeEdge = false; + encUserConfig.homeInputNegativeEdge = false; + encUserConfig.indexPulsePosInit = true; + encUserConfig.posCntInitValue = 0U; + encUserConfig.posCmpValue = 0xFFFFU; + encUserConfig.moduloValue = 0U; + encUserConfig.triggerUpdateHoldRegEnable = false; + encUserConfig.triggerClearPosRegEnable = false; + encUserConfig.moduloRevolutionCounting = false; + encUserConfig.outputControlOnReading = false; + encUserConfig.watchdogTimeout = 0U; + encUserConfig.filterCount = 0U; + encUserConfig.filterPeriod = 0U; + ENC_DRV_Init(instance, &encUserConfig); + * + *END**************************************************************************/ +enc_status_t ENC_DRV_Init(uint32_t instance, const enc_user_config_t *userConfigPtr) +{ + assert(instance < ENC_INSTANCE_COUNT); + ENC_Type* base = g_encBase[instance]; + bool mEnable; + + /* Test structure pointer. */ + if (!userConfigPtr) + { + return kStatus_ENC_InvalidArgument; + } + + /* Enable Clock to Quadrature Encoder peripheral. */ + mEnable = CLOCK_SYS_GetEncGateCmd(instance); + if (!mEnable) + { + CLOCK_SYS_EnableEncClock(instance); + } + + /* Reset the registers for ENC module to reset state. */ + ENC_HAL_Init(base); + + /* Set operation mode. */ + switch(userConfigPtr->operationMode) + { + case kEncModuloCountingMode: + ENC_HAL_SetModuloCountingCmd(base, true); + break; + + case kEncSignalPhaseCountMode: + ENC_HAL_SetSignalPhaseCountModeCmd(base, true); + break; + + case kEncNormalMode: + ENC_HAL_SetModuloCountingCmd(base, false); + ENC_HAL_SetSignalPhaseCountModeCmd(base, false); + break; + + default: + return kStatus_ENC_Error; + } + + /* Set directiong of counting. */ + ENC_HAL_SetReverseCountingCmd(base, userConfigPtr->reverseCounting); + + /* INDEX input transition edge setting. */ + ENC_HAL_SetIndexPulseNegativeEdgeCmd(base, userConfigPtr->indexInputNegativeEdge); + + /* HOME input transition edge setting. */ + ENC_HAL_SetHomeSignalNegativeEdgeCmd(base, userConfigPtr->homeInputNegativeEdge); + + /* Position counter init signal. */ + ENC_HAL_SetIndexInitPosCmd(base, userConfigPtr->indexPulsePosInit); + ENC_HAL_SetHomeInitPosCmd(base, !userConfigPtr->indexPulsePosInit); + + /* Position counter init value. */ + ENC_HAL_SetInitReg(base, userConfigPtr->posCntInitValue); + + /* Position compare init value. */ + ENC_HAL_SetCmpReg(base, userConfigPtr->posCmpValue); + + /* Modulo value. */ + ENC_HAL_SetModulusReg(base, userConfigPtr->moduloValue); + + /* Enable/disable update hold registers on input trigger. */ + ENC_HAL_SetTriggerUpdateHoldRegCmd(base, userConfigPtr->triggerUpdateHoldRegEnable); + + /* Enable/disable clear position registers on input trigger. */ + ENC_HAL_SetTriggerClearPosRegCmd(base, userConfigPtr->triggerClearPosRegEnable); + + /* Set revolution counting type - Index pulse or Modulus counting rollover, rollunder. */ + ENC_HAL_SetModulusRevCounterCmd(base, userConfigPtr->moduloRevolutionCounting); + + /* POSMATCH output control. */ + ENC_HAL_SetPosmatchOnReadingCmd(base, userConfigPtr->outputControlOnReading); + + /* Setting watchdog timeout. */ + if (userConfigPtr->watchdogTimeout == 0) + { + ENC_HAL_SetWatchdogCmd(base, false); + } + else + { + ENC_HAL_SetWatchdogCmd(base, true); + ENC_HAL_SetWatchdogTimeout(base, userConfigPtr->watchdogTimeout); + } + + /* Set Filter values. */ + ENC_HAL_SetInputFilterSampleCount(base, userConfigPtr->filterCount); + ENC_HAL_SetInputFilterSamplePeriod(base, userConfigPtr->filterPeriod); + + /* Clear position difference and revolution counter. */ + ENC_HAL_SetRevolutionCounterReg(base, 0); + ENC_HAL_SetPosDiffCounterReg(base, 0); + ENC_HAL_SetPosCounterReg(base, 0); + + /* Enable ENC interrupt on NVIC level. */ + INT_SYS_EnableIRQ(g_encCmpIrqId[instance]); + INT_SYS_EnableIRQ(g_encWdtIrqId[instance]); + INT_SYS_EnableIRQ(g_encHomeIrqId[instance]); + INT_SYS_EnableIRQ(g_encIndexIrqId[instance]); + + /* Return succes status code. */ + return kStatus_ENC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : ENC_DRV_Deinit + * Description : De-initialize the Quadrature Encoder module. It will + * shut down its clock to reduce the power consumption. + * + *END**************************************************************************/ +void ENC_DRV_Deinit(uint32_t instance) +{ + assert(instance < ENC_INSTANCE_COUNT); + + /* Disables Clock to Quadrature Encoder peripheral. */ + CLOCK_SYS_DisableEncClock(instance); + + /* Disable ENC interrupt on NVIC level. */ + INT_SYS_DisableIRQ(g_encCmpIrqId[instance]); + INT_SYS_DisableIRQ(g_encWdtIrqId[instance]); + INT_SYS_DisableIRQ(g_encHomeIrqId[instance]); + INT_SYS_DisableIRQ(g_encIndexIrqId[instance]); +} + +/*FUNCTION********************************************************************** + * + * Function Name : ENC_DRV_TestInit + * Description : This function initializes a Test Module of ENC. + * This function initializes the run-time state structure to enable Test Module, + * and sets the test period and test count values. + * This example shows how to set up the enc_test_config_t parameters and + * how to call the ENC_DRV_TestInit function by passing + * in these parameters: + enc_test_config_t encTestConfig; + encTestConfig.testNegativeSignalEnable = false; + encTestConfig.testCount = 100; + encTestConfig.testPeriod = 10; + ENC_DRV_TestInit(&encTestConfig); + * + *END**************************************************************************/ +enc_status_t ENC_DRV_TestInit(uint32_t instance, const enc_test_config_t * userConfigPtr) +{ + assert(instance < ENC_INSTANCE_COUNT); + ENC_Type* base = g_encBase[instance]; + + /* Test structure pointer. */ + if (!userConfigPtr) + { + return kStatus_ENC_InvalidArgument; + } + + /* Enable settings of Test Module. */ + ENC_HAL_SetNegativeTestSignalCmd(base, userConfigPtr->testNegativeSignalEnable); + ENC_HAL_SetTestPeriod(base, userConfigPtr->testPeriod); + ENC_HAL_SetTestCount(base, userConfigPtr->testCount); + + /* Enable Test Module. */ + ENC_HAL_SetTestModuleCmd(base, true); + ENC_HAL_SetTestCounterCmd(base, true); + + /* Return succes status code. */ + return kStatus_ENC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : ENC_DRV_TestDeinit + * Description : This function shuts down the ENC test module, disable test counter + * and clears the test period and test count. + * + *END**************************************************************************/ +void ENC_DRV_TestDeinit(uint32_t instance) +{ + assert(instance < ENC_INSTANCE_COUNT); + ENC_Type* base = g_encBase[instance]; + + /* Disable Test Module. */ + ENC_HAL_SetTestModuleCmd(base, false); + ENC_HAL_SetTestCounterCmd(base, false); + + /* Clear settings of Test Module. */ + ENC_HAL_SetTestPeriod(base, 0); + ENC_HAL_SetTestCount(base, 0); +} + +/*FUNCTION********************************************************************** + * + * Function Name : ENC_DRV_SetIntMode + * Description : This function enables any ENC interrupt. + * + *END**************************************************************************/ +enc_status_t ENC_DRV_SetIntMode(uint32_t instance, enc_int_source_t intSrc, bool enable) +{ + assert(instance < ENC_INSTANCE_COUNT); + ENC_Type* base = g_encBase[instance]; + + /* Switch to relevant ENC interrupt source. */ + switch(intSrc) + { + /* Encoder Compare interrupt enable/disable. */ + case kEncIntCmp: + ENC_HAL_SetCmpIntCmd(base, enable); + break; + + /* Encoder Watchdog timeout enable/disable. */ + case kEncIntWatchdogTimeout: + ENC_HAL_SetWatchdogIntCmd(base, enable); + break; + + /* Encoder Home Signal interrupt enable/disable. */ + case kEncIntHomeSignal: + ENC_HAL_SetHomeSignalIntCmd(base, enable); + break; + + /* Encoder Index Pulse interrupt enable/disable. */ + case kEncIntIndexPulse: + ENC_HAL_SetIndexPulseIntCmd(base, enable); + break; + + /* Encoder Roll-under interrupt enable/disable. */ + case kEncIntRollunder: + ENC_HAL_SetRollunderIntCmd(base, enable); + break; + + /* Encoder Roll-over interrupt enable/disable. */ + case kEncIntRollover: + ENC_HAL_SetRolloverIntCmd(base, enable); + break; + + /* Encoder Simultaneous interrupt enable/disable. */ + case kEncIntSimultaneous: + ENC_HAL_SetSimultaneousIntCmd(base, enable); + break; + + /* Default. */ + default: return kStatus_ENC_Error; + } + + /* Return succes status code. */ + return kStatus_ENC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : ENC_DRV_GetIntMode + * Description : This function gets configuration of any ENC interrupt. + * + *END**************************************************************************/ +bool ENC_DRV_GetIntMode(uint32_t instance, enc_int_source_t intSrc) +{ + assert(instance < ENC_INSTANCE_COUNT); + ENC_Type* base = g_encBase[instance]; + bool bRet; + + /* Switch to relevant ENC interrupt source. */ + switch(intSrc) + { + /* Encoder Compare interrupt enable/disable. */ + case kEncIntCmp: + bRet = ENC_HAL_GetCmpIntCmd(base); + break; + + /* Encoder Watchdog timeout enable/disable. */ + case kEncIntWatchdogTimeout: + bRet = ENC_HAL_GetWatchdogIntCmd(base); + break; + + /* Encoder Home Signal interrupt enable/disable. */ + case kEncIntHomeSignal: + bRet = ENC_HAL_GetHomeSignalIntCmd(base); + break; + + /* Encoder Index Pulse interrupt enable/disable. */ + case kEncIntIndexPulse: + bRet = ENC_HAL_GetIndexPulseIntCmd(base); + break; + + /* Encoder Roll-under interrupt enable/disable. */ + case kEncIntRollunder: + bRet = ENC_HAL_GetRollunderIntCmd(base); + break; + + /* Encoder Roll-over interrupt enable/disable. */ + case kEncIntRollover: + bRet = ENC_HAL_GetRolloverIntCmd(base); + break; + + /* Encoder Simultaneous interrupt enable/disable. */ + case kEncIntSimultaneous: + bRet = ENC_HAL_GetSimultaneousIntCmd(base); + break; + + /* Default. */ + default: + bRet = false; + break; + } + + /* Return value of interrupt status. */ + return bRet; +} + +/*FUNCTION********************************************************************** + * + * Function Name : ENC_DRV_GetStatusFlag + * Description : This function gets status flag of selected status. + * + *END**************************************************************************/ +bool ENC_DRV_GetStatusFlag(uint32_t instance, enc_status_flag_t flag) +{ + assert(instance < ENC_INSTANCE_COUNT); + ENC_Type* base = g_encBase[instance]; + bool bRet; + + /* Switch to relevant ENC interrupt source. */ + switch(flag) + { + /* Encoder Compare interrupt flag. */ + case kEncCmpFlag: + bRet = ENC_HAL_GetCmpIntFlag(base); + break; + + /* Encoder Watchdog timeout flag. */ + case kEncWatchdogTimeoutFlag: + bRet = ENC_HAL_GetWatchdogIntFlag(base); + break; + + /* Encoder Home Signal interrupt flag. */ + case kEncHomeSignalFlag: + bRet = ENC_HAL_GetHomeSignalIntFlag(base); + break; + + /* Encoder Index Pulse interrupt flag. */ + case kEncIndexPulseFlag: + bRet = ENC_HAL_GetIndexPulseIntFlag(base); + break; + + /* Encoder Roll-under interrupt flag. */ + case kEncRollunderFlag: + bRet = ENC_HAL_GetRollunderIntFlag(base); + break; + + /* Encoder Roll-over interrupt flag. */ + case kEncRolloverFlag: + bRet = ENC_HAL_GetRolloverIntFlag(base); + break; + + /* Encoder Simultaneous interrupt flag. */ + case kEncSimultaneousFlag: + bRet = ENC_HAL_GetSimultaneousIntFlag(base); + break; + + /* Encoder last count direction flag. */ + case kEncCountDirectionFlag: + bRet = ENC_HAL_GetLastCountDirectionFlag(base); + break; + + default: + bRet = false; + break; + } + + /* Return value of interrupt status flag. */ + return bRet; +} + +/*FUNCTION********************************************************************** + * + * Function Name : ENC_DRV_ClearStatusFlag + * Description : This function clears status flag of selected status. + * + *END**************************************************************************/ +void ENC_DRV_ClearStatusFlag(uint32_t instance, enc_status_flag_t flag) +{ + assert(instance < ENC_INSTANCE_COUNT); + ENC_Type* base = g_encBase[instance]; + + /* Switch to relevant ENC interrupt source. */ + switch(flag) + { + /* Encoder Compare interrupt flag. */ + case kEncCmpFlag: + ENC_HAL_ClearCmpIntFlag(base); + break; + + /* Encoder Watchdog timeout flag. */ + case kEncWatchdogTimeoutFlag: + ENC_HAL_ClearWatchdogIntFlag(base); + break; + + /* Encoder Home Signal interrupt flag. */ + case kEncHomeSignalFlag: + ENC_HAL_ClearHomeSignalIntFlag(base); + break; + + /* Encoder Index Pulse interrupt flag. */ + case kEncIndexPulseFlag: + ENC_HAL_ClearIndexPulseIntFlag(base); + break; + + /* Encoder Roll-under interrupt flag. */ + case kEncRollunderFlag: + ENC_HAL_ClearRollunderIntFlag(base); + break; + + /* Encoder Roll-over interrupt flag. */ + case kEncRolloverFlag: + ENC_HAL_ClearRolloverIntFlag(base); + break; + + /* Encoder Simultaneous interrupt flag. */ + case kEncSimultaneousFlag: + ENC_HAL_ClearSimultaneousIntFlag(base); + break; + + default: + break; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : ENC_DRV_ReadCounters + * Description : This function reads the ENC Registers of Counters. + * + *END**************************************************************************/ +enc_status_t ENC_DRV_ReadCounters(uint32_t instance, enc_counter_t * countRegPtr) +{ + assert(instance < ENC_INSTANCE_COUNT); + ENC_Type* base = g_encBase[instance]; + + /* Test structure pointer. */ + if (!countRegPtr) + { + return kStatus_ENC_InvalidArgument; + } + + /* At first read position difference COUNTER register. */ + countRegPtr->posDiff = ENC_HAL_GetPosDiffCounterReg(base); + + /* Other counter registers are automatically triggered to HOLD registers. */ + countRegPtr->position = ENC_HAL_GetPosHoldReg(base); + countRegPtr->revolution = ENC_HAL_GetRevolutionHoldReg(base); + + /* Return succes status code. */ + return kStatus_ENC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : ENC_DRV_ReadHoldReg + * Description : This function reads the ENC Hold Registers of counters. + * + *END**************************************************************************/ +enc_status_t ENC_DRV_ReadHoldReg(uint32_t instance, enc_counter_t * holdRegPtr) +{ + assert(instance < ENC_INSTANCE_COUNT); + ENC_Type* base = g_encBase[instance]; + + /* Test structure pointer. */ + if (!holdRegPtr) + { + return kStatus_ENC_InvalidArgument; + } + + /* Read Hold registers. */ + holdRegPtr->position = ENC_HAL_GetPosHoldReg(base); + holdRegPtr->posDiff = ENC_HAL_GetPosDiffHoldReg(base); + holdRegPtr->revolution = ENC_HAL_GetRevolutionHoldReg(base); + + /* Return succes status code. */ + return kStatus_ENC_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : ENC_DRV_ResetCounters + * Description : This function resets the ENC Position registers. + * + *END**************************************************************************/ +void ENC_DRV_ResetCounters(uint32_t instance) +{ + assert(instance < ENC_INSTANCE_COUNT); + ENC_Type* base = g_encBase[instance]; + + /* Re-init position counter. */ + ENC_HAL_InitPosCounter(base); + + /* Clear position difference and revolution counter. */ + ENC_HAL_SetRevolutionCounterReg(base, 0); + ENC_HAL_SetPosDiffCounterReg(base, 0); +} + +/*FUNCTION********************************************************************** + * + * Function Name : ENC_DRV_ReadInputMonitor + * Description : This function reads the ENC Input Monitor register. + * + *END**************************************************************************/ +enc_status_t ENC_DRV_ReadInputMonitor + (uint32_t instance, bool inputMonitorRaw, enc_input_monitor_t * inputMonitorPtr) +{ + assert(instance < ENC_INSTANCE_COUNT); + ENC_Type* base = g_encBase[instance]; + + /* Test structure pointer. */ + if (!inputMonitorPtr) + { + return kStatus_ENC_InvalidArgument; + } + + /* Switch to raw or filtered type of input monitor. */ + if (inputMonitorRaw) + { + /* Get raw inputs. */ + inputMonitorPtr->phaseA = ENC_HAL_GetRawPhaseAInput(base); + inputMonitorPtr->phaseB = ENC_HAL_GetRawPhaseBInput(base); + inputMonitorPtr->index = ENC_HAL_GetRawIndexInput(base); + inputMonitorPtr->home = ENC_HAL_GetRawHomeInput(base); + } + else + { + /* Get filtered inputs. */ + inputMonitorPtr->phaseA = ENC_HAL_GetFilteredPhaseAInput(base); + inputMonitorPtr->phaseB = ENC_HAL_GetFilteredPhaseBInput(base); + inputMonitorPtr->index = ENC_HAL_GetFilteredIndexInput(base); + inputMonitorPtr->home = ENC_HAL_GetFilteredHomeInput(base); + } + + /* Return succes status code. */ + return kStatus_ENC_Success; +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/enc/fsl_enc_irq.c b/KSDK_1.2.0/platform/drivers/src/enc/fsl_enc_irq.c new file mode 100755 index 0000000..fc179f2 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/enc/fsl_enc_irq.c @@ -0,0 +1,149 @@ +/******************************************************************************* +* +* Copyright [2014-]2014 Freescale Semiconductor, Inc. + +* +* This software is owned or controlled by Freescale Semiconductor. +* Use of this software is governed by the Freescale License +* distributed with this Material. +* See the LICENSE file distributed for more details. +* +* +*******************************************************************************/ + +#include "fsl_device_registers.h" +#include "fsl_enc_driver.h" +#if FSL_FEATURE_SOC_ENC_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +extern void ENC_ISR_Index(void); /* Callback function of INDEX interrupt. */ +extern void ENC_ISR_Home(void); /* Callback function of HOME interrupt. */ +extern void ENC_ISR_Rollover(void); /* Callback function of roll-over interrupt. */ +extern void ENC_ISR_Rollunder(void); /* Callback function of roll-under interrupt. */ +extern void ENC_ISR_Compare(void); /* Callback function of compare interrupt. */ +extern void ENC_ISR_Watchdog(void); /* Callback function of WDT interrupt. */ +extern void ENC_ISR_Simult(void); /* Callback function of Simult-change interrupt. */ + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if ((defined(KV40F15_SERIES)) || (defined(KV43F15_SERIES)) || (defined(KV44F15_SERIES)) || (defined(KV45F15_SERIES)) || (defined(KV46F15_SERIES))) + + +/*! + * @brief Implementation of ENC Compare handler named in startup code. + * + * Passes instance to generic ENC IRQ handler. + */ +void ENC_COMPARE_IRQHandler(void) +{ + /* Get Compare Interrupt request. */ + if (ENC_DRV_GetStatusFlag(0U, kEncCmpFlag)) + { + /* Call callback function. */ + ENC_ISR_Compare(); + + /* Clear Compare Interrupt pending bit. */ + ENC_DRV_ClearStatusFlag(0U, kEncCmpFlag); + } +} + +/*! + * @brief Implementation of HOME Signal handler named in startup code. + * + * Passes instance to generic ENC IRQ handler. + */ +void ENC_HOME_IRQHandler(void) +{ + /* Get Home signal Interrupt request. */ + if (ENC_DRV_GetStatusFlag(0U, kEncHomeSignalFlag)) + { + /* Call callback function. */ + ENC_ISR_Home(); + + /* Clear HOME Signal Interrupt Flag. */ + ENC_DRV_ClearStatusFlag(0U, kEncHomeSignalFlag); + } +} + +/*! + * @brief Implementation of INDEX Pulse handler and Roll-over, Roll-under + * named in startup code. + * + * Passes instance to generic ENC IRQ handler. + */ +void ENC_INDEX_IRQHandler(void) +{ + /* Get Index pulse Interrupt request. */ + if ( ENC_DRV_GetStatusFlag(0U, kEncIndexPulseFlag) & ENC_DRV_GetIntMode(0U, kEncIntIndexPulse) ) + { + /* Call callback function. */ + ENC_ISR_Index(); + + /* Clear interrupt pending bit. */ + ENC_DRV_ClearStatusFlag(0U, kEncIndexPulseFlag); + } + + /* Get Roll-over Interrupt request. */ + if ( ENC_DRV_GetStatusFlag(0U, kEncRolloverFlag) & ENC_DRV_GetIntMode(0U, kEncIntRollover)) + { + /* Call callback function. */ + ENC_ISR_Rollover(); + + /* Clear interrupt pending bit. */ + ENC_DRV_ClearStatusFlag(0U, kEncRolloverFlag); + } + + /* Get Roll-under Interrupt request. */ + if ( ENC_DRV_GetStatusFlag(0U, kEncRollunderFlag) & ENC_DRV_GetIntMode(0U, kEncIntRollunder)) + { + /* Call callback function. */ + ENC_ISR_Rollunder(); + + /* Clear interrupt pending bit. */ + ENC_DRV_ClearStatusFlag(0U, kEncRollunderFlag); + } +} + +/*! + * @brief Implementation of Watchdog timeout handler named in startup code. + * + * Passes instance to generic ENC IRQ handler. + */ +void ENC_WDOG_SAB_IRQHandler(void) +{ + /* Get Watchdog Timeout Interrupt request. */ + if (ENC_DRV_GetStatusFlag(0U, kEncWatchdogTimeoutFlag)) + { + /* Call callback function. */ + ENC_ISR_Watchdog(); + + /* Clear Watchdog Timeout Interrupt Flag. */ + ENC_DRV_ClearStatusFlag(0U, kEncWatchdogTimeoutFlag); + } + + /* Get Simultaneous change Interrupt request. */ + if (ENC_DRV_GetStatusFlag(0U, kEncSimultaneousFlag)) + { + /* Call callback function. */ + ENC_ISR_Simult(); + + /* Clear Simultaneous Interrupt Flag. */ + ENC_DRV_ClearStatusFlag(0U, kEncSimultaneousFlag); + } +} + +#else + #error "No valid CPU defined!" +#endif +#endif +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/enc/fsl_enc_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/enc/fsl_enc_lpm_callback.c new file mode 100755 index 0000000..1fb40a5 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/enc/fsl_enc_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_ENC_COUNT + +power_manager_error_code_t enc_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t enc_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/enet/fsl_enet_common.c b/KSDK_1.2.0/platform/drivers/src/enet/fsl_enet_common.c new file mode 100755 index 0000000..a6664da --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/enet/fsl_enet_common.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 <stdint.h> +#include "fsl_device_registers.h" + +/*! @brief Table of base addresses for Enet instances. */ +ENET_Type * const g_enetBase[] = ENET_BASE_PTRS; + +/*! @brief Table to save enet IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_enetTxIrqId[] = ENET_Transmit_IRQS; +const IRQn_Type g_enetRxIrqId[] = ENET_Receive_IRQS; +const IRQn_Type g_enetTsIrqId[] = ENET_1588_Timer_IRQS; +const IRQn_Type g_enetErrIrqId[] = ENET_Error_IRQS; + +/******************************************************************************* +* EOF +******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/enet/fsl_enet_driver.c b/KSDK_1.2.0/platform/drivers/src/enet/fsl_enet_driver.c new file mode 100755 index 0000000..12dae65 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/enet/fsl_enet_driver.c @@ -0,0 +1,2105 @@ +/* +* Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (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 <assert.h> +#include <string.h> +#include "fsl_enet_driver.h" +#include "fsl_enet_hal.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_ENET_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Define global value for ISR input parameter*/ +enet_dev_if_t *enetIfHandle[ENET_INSTANCE_COUNT]; + +#if FSL_FEATURE_ENET_SUPPORT_PTP +/*! @brief Define ptp mastertimer information*/ +enet_mac_ptp_master_time_t g_ptpMasterTime; +/*! @brief Define clk frequency for 1588 timer*/ +uint32_t g_ptpClkFrq; +#if FSL_FEATURE_ENET_PTP_TIMER_CHANNEL_INTERRUPT_ERRATA_2579 +#define ENET_TIMER_CHANNEL_NUM kEnetTimerChannel3 +#endif +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if FSL_FEATURE_ENET_SUPPORT_PTP +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_1588Init + * Return Value: The execution status. + * Description:Initialize the ENET private ptp(Precision Time Synchronization Protocol) + * data structure. + * + *END*********************************************************************/ +enet_status_t ENET_DRV_1588Init(enet_dev_if_t *enetIfPtr, enet_mac_ptp_ts_data_t *ptpTsRxDataPtr,uint32_t rxBuffNum, + enet_mac_ptp_ts_data_t *ptpTsTxDataPtr, uint32_t txBuffNum, bool isSlaveEnabled) +{ + enet_private_ptp_buffer_t *privatePtpPtr; + + /* Check the input parameters */ + if ((!enetIfPtr) || (!ptpTsRxDataPtr) || (!ptpTsTxDataPtr)) + { + return kStatus_ENET_InvalidInput; + } + + privatePtpPtr = &enetIfPtr->privatePtp; + enetIfPtr->privatePtp.firstflag = true; + + /* Initialize ptp receive and transmit ring buffers*/ + privatePtpPtr->rxTimeStamp.ptpTsDataPtr = ptpTsRxDataPtr; + privatePtpPtr->rxTimeStamp.size = rxBuffNum; + privatePtpPtr->rxTimeStamp.front = 0; + privatePtpPtr->rxTimeStamp.end = 0; + privatePtpPtr->txTimeStamp.ptpTsDataPtr = ptpTsTxDataPtr; + privatePtpPtr->txTimeStamp.size = txBuffNum; + privatePtpPtr->txTimeStamp.front = 0; + privatePtpPtr->txTimeStamp.end = 0; + + /* Start 1588 timer and enable timer interrupt*/ + ENET_DRV_Start1588Timer(enetIfPtr->deviceNumber, isSlaveEnabled); + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_1588Deinit + * Return Value: The execution status. + * Description:Initialize the ENET private ptp(Precision Time Synchronization Protocol) + * data structure. + * + *END*********************************************************************/ +enet_status_t ENET_DRV_1588Deinit(enet_dev_if_t *enetIfPtr) +{ + /* Check the input parameters */ + if (!enetIfPtr) + { + return kStatus_ENET_InvalidInput; + } + + /* Initialize ptp receive and transmit ring buffers*/ + enetIfPtr->privatePtp.rxTimeStamp.ptpTsDataPtr = NULL; + enetIfPtr->privatePtp.rxTimeStamp.size = 0; + enetIfPtr->privatePtp.rxTimeStamp.front = 0; + enetIfPtr->privatePtp.rxTimeStamp.end = 0; + enetIfPtr->privatePtp.txTimeStamp.ptpTsDataPtr = NULL; + enetIfPtr->privatePtp.txTimeStamp.size = 0; + enetIfPtr->privatePtp.txTimeStamp.front = 0; + enetIfPtr->privatePtp.txTimeStamp.end = 0; + + ENET_DRV_Stop1588Timer(enetIfPtr->deviceNumber); + + return kStatus_ENET_Success; +} + + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Start1588Timer + * Return Value: The execution status. + * Description: Start the ENET ptp(Precision Time Synchronization Protocol) + * timer. After this, the timer is ready for 1588 synchronization. + * + *END*********************************************************************/ +enet_status_t ENET_DRV_Start1588Timer(uint32_t instance, bool isSlaveEnabled) +{ + uint32_t clockFreq = 0; + ENET_Type * base; + enet_config_ptp_timer_t ptpCfg; + + /* Check if this is the master ptp timer*/ + if (!isSlaveEnabled) + { + g_ptpMasterTime.masterPtpInstance = instance; + } + + base = g_enetBase[instance]; + + /* Initialize ptp timer */ + clockFreq = CLOCK_SYS_GetEnetTimeStampFreq(instance); + if (!clockFreq) + { + return kStatus_ENET_GetClockFreqFail; + } + ptpCfg.isSlaveEnabled = isSlaveEnabled; + ptpCfg.period = kEnetPtpAtperValue; + ptpCfg.clockIncease = ptpCfg.period/clockFreq; +#if FSL_FEATURE_ENET_PTP_TIMER_CHANNEL_INTERRUPT_ERRATA_2579 + ptpCfg.channel = ENET_TIMER_CHANNEL_NUM; +#endif + ENET_HAL_Start1588Timer(base, &ptpCfg); + + /* Set the gloabl 1588 timer frequency*/ + g_ptpClkFrq = clockFreq; + + /* Enable master ptp timer interrupt */ + if (!ptpCfg.isSlaveEnabled) + { + ENET_HAL_SetIntMode(base, kEnetTsTimerInterrupt, true); + INT_SYS_EnableIRQ(g_enetTsIrqId[instance]); + } + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Stop1588Timer + * Return Value: None. + * Description:Stop ENET ptp timer. + * + *END*********************************************************************/ +void ENET_DRV_Stop1588Timer(uint32_t instance) +{ + ENET_Type * base; + + base = g_enetBase[instance]; + /* Disable ptp timer*/ + ENET_HAL_Stop1588Timer(base); +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Get1588timer + * Return Value: None. + * Description: Get current ENET ptp time. + * This interface is use by 1588 stack to get the current value from the ptp timer + * through ioctl interface. + *END*********************************************************************/ +enet_status_t ENET_DRV_Get1588timer(enet_mac_ptp_time_t *ptpTimerPtr) +{ + ENET_Type * base; + + /* Check input parameters*/ + if (!ptpTimerPtr) + { + return kStatus_ENET_InvalidInput; + } + base = g_enetBase[g_ptpMasterTime.masterPtpInstance]; + + /* Interrupt disable*/ + INT_SYS_DisableIRQGlobal(); + + /* Get the current value of the master time*/ + ptpTimerPtr->second = g_ptpMasterTime.second; + ptpTimerPtr->nanosecond = ENET_HAL_Get1588TimerCurrentTime(base); + + /* Enable interrupt*/ + INT_SYS_EnableIRQGlobal(); + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Set1588timer + * Return Value: None. + * Description: Set ENET ptp time. + * This interface is use by 1588 stack to set the current ptp timer + * through ioctl interface. + *END*********************************************************************/ +enet_status_t ENET_DRV_Set1588timer(enet_mac_ptp_time_t *ptpTimerPtr) +{ + ENET_Type * base; + /* Check input parameters*/ + if (!ptpTimerPtr) + { + return kStatus_ENET_InvalidInput; + } + + /* Disable interrupt*/ + INT_SYS_DisableIRQGlobal(); + /* Set ptp timer*/ + g_ptpMasterTime.second = ptpTimerPtr->second; + base = g_enetBase[g_ptpMasterTime.masterPtpInstance]; + ENET_HAL_Set1588TimerNewTime(base, ptpTimerPtr->nanosecond); + + /* Enable interrupt*/ + INT_SYS_EnableIRQGlobal(); + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Adjust1588timer + * Return Value: The execution status. + * Description: Adjust ENET ptp timer. + * This interface is mainly the adjust algorithm for ptp timer synchronize. + * this function is used to adjust ptp timer to synchronize with master timer. + *END*********************************************************************/ +enet_status_t ENET_DRV_Adjust1588timer(uint32_t instance, int32_t drift) +{ + uint32_t clockIncrease,adjIncrease,corrPeriod = 0,corrIncrease = 0,count = 0; + uint32_t gapMax = 0xFFFFFFFF,gapTemp,adjPeriod = 1; + ENET_Type * base; + base = g_enetBase[instance]; + + /* Calculate clock period of the ptp timer*/ + clockIncrease = kEnetPtpAtperValue / g_ptpClkFrq ; + + if (drift != 0) + { + if (abs(drift) >= g_ptpClkFrq) + { + /* Drift is greater than the 1588 clock frequency the correction should be done every tick of the timer*/ + corrPeriod = 1; + corrIncrease = (uint32_t)(abs(drift)/g_ptpClkFrq); + } + else + { + /* Drift is smaller than the 1588 clock frequency*/ + if (abs(drift) > (g_ptpClkFrq / clockIncrease)) + { + adjIncrease = clockIncrease / kEnetBaseIncreaseUnit; + } + else if (abs(drift) > (g_ptpClkFrq / (2*kEnetBaseIncreaseUnit*clockIncrease))) + { + adjIncrease = clockIncrease / (2*kEnetBaseIncreaseUnit); + adjPeriod = kEnetBaseIncreaseUnit; + } + else + { + adjIncrease = clockIncrease / (2*kEnetBaseIncreaseUnit); + adjPeriod = 2*kEnetBaseIncreaseUnit; + } + for(count = 1; count < adjIncrease; count++) + { + gapTemp = (g_ptpClkFrq * adjPeriod * count) % abs(drift); + if (!gapTemp) + { + corrIncrease = count; + corrPeriod = (uint32_t)((g_ptpClkFrq * adjPeriod * count) / abs(drift)); + break; + } + else if (gapTemp < gapMax) + { + corrIncrease = count; + corrPeriod = (uint32_t)((g_ptpClkFrq * adjPeriod * count) / abs(drift)); + gapMax = gapTemp; + } + } + } + /* Calculate the clock correction increase value*/ + if (drift < 0) + { + corrIncrease = clockIncrease - corrIncrease; + } + else + { + corrIncrease = clockIncrease + corrIncrease; + } + /* Adjust the ptp timer*/ + ENET_HAL_Adjust1588Timer(base, corrPeriod, corrIncrease); + } + else + { + /* Adjust the ptp timer*/ + ENET_HAL_Adjust1588Timer(base, 0, clockIncrease); + } + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: enet_ptp_store_tx_timestamp + * Return Value: The execution status. + * Description: Store the transmit ptp timestamp. + * This interface is to store transmit ptp timestamp and is called by transmit function. + *END*********************************************************************/ +enet_status_t ENET_DRV_GetTxTs(enet_private_ptp_buffer_t *ptpBuffer, volatile enet_bd_struct_t *firstBdPtr, volatile enet_bd_struct_t *lastBdPtr) +{ + bool isPtpMsg,ptpTimerWrap; + enet_mac_ptp_ts_data_t ptpTsData; + enet_mac_ptp_time_t ptpTimerPtr; + uint8_t * bdBufferPtr; + enet_status_t result = kStatus_ENET_Success; + ENET_Type * base; + uint64_t mask = 0; + enet_bd_attr_t bdAttr; + + /* Check input parameter*/ + if (!ptpBuffer) + { + return kStatus_ENET_InvalidInput; + } + /* Parse the message packet to check if there is a ptp message*/ + bdBufferPtr = ENET_HAL_GetBuffDescripData(firstBdPtr); + result = ENET_DRV_Parse1588Packet(bdBufferPtr, &ptpTsData, &isPtpMsg, false); + if (result != kStatus_ENET_Success) + { + return result; + } + + /* Store transmit timestamp of the ptp message*/ + if (isPtpMsg) + { + base = g_enetBase[g_ptpMasterTime.masterPtpInstance]; + /* Get transmit timestamp nanosecond*/ + mask |= ENET_BD_TIMESTAMP_MASK; + ENET_HAL_GetBufDescripAttr(lastBdPtr, mask, &bdAttr); + ptpTsData.timeStamp.nanosecond = bdAttr.bdTimestamp; + + /* Get current ptp timer nanosecond value*/ + ENET_DRV_Get1588timer(&ptpTimerPtr); + INT_SYS_DisableIRQGlobal(); + + /* Get ptp timer wrap event */ + ptpTimerWrap = ENET_HAL_GetIntStatusFlag(base, kEnetTsTimerInterrupt); + + /* Get transmit timestamp second */ + if ((ptpTimerPtr.nanosecond > ptpTsData.timeStamp.nanosecond) || + ((ptpTimerPtr.nanosecond < ptpTsData.timeStamp.nanosecond) && ptpTimerWrap)) + { + ptpTsData.timeStamp.second = g_ptpMasterTime.second; + } + else + { + ptpTsData.timeStamp.second = g_ptpMasterTime.second - 1; + } + + INT_SYS_EnableIRQGlobal(); + + /* Add the new timestamp data into the ptp ring buffer*/ + result = ENET_DRV_Update1588TsBuff(&(ptpBuffer->txTimeStamp), &ptpTsData); + } + + return result; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_GetRxTs + * Return Value: The execution status. + * Description: Store the receive ptp packet timestamp. + * This interface is to store receive ptp packet timestamp and is called by receive function. + *END*********************************************************************/ +enet_status_t ENET_DRV_GetRxTs(enet_private_ptp_buffer_t *ptpBuffer, uint8_t *packet, volatile enet_bd_struct_t *bdPtr) +{ + enet_mac_ptp_ts_data_t ptpTsData; + enet_mac_ptp_time_t ptpTimerPtr; + bool isPtpMsg = false, ptpTimerWrap; + enet_status_t result; + ENET_Type * base; + uint64_t mask = 0; + enet_bd_attr_t bdAttr; + + /* Check input parameter*/ + if ((!ptpBuffer) || (!packet) || (!bdPtr)) + { + return kStatus_ENET_InvalidInput; + } + + /* Check if the message is a ptp message */ + result = ENET_DRV_Parse1588Packet(packet, &ptpTsData, &isPtpMsg, false); + if (result != kStatus_ENET_Success) + { + return result; + } + + /* Store the receive timestamp of the ptp message*/ + if (isPtpMsg) + { + base = g_enetBase[g_ptpMasterTime.masterPtpInstance]; + + /* Get the timestamp from the bd buffer*/ + mask |= ENET_BD_TIMESTAMP_MASK; + ENET_HAL_GetBufDescripAttr(bdPtr, mask, &bdAttr); + ptpTsData.timeStamp.nanosecond = bdAttr.bdTimestamp; + + /* Get current ptp timer nanosecond value*/ + ENET_DRV_Get1588timer(&ptpTimerPtr); + + INT_SYS_DisableIRQGlobal(); + + /* Get ptp timer wrap event*/ + ptpTimerWrap = ENET_HAL_GetIntStatusFlag(base, kEnetTsTimerInterrupt); + + /* Get transmit timestamp second*/ + if ((ptpTimerPtr.nanosecond > ptpTsData.timeStamp.nanosecond) || + ((ptpTimerPtr.nanosecond < ptpTsData.timeStamp.nanosecond) && ptpTimerWrap)) + { + ptpTsData.timeStamp.second = g_ptpMasterTime.second; + } + else + { + ptpTsData.timeStamp.second = g_ptpMasterTime.second - 1; + } + INT_SYS_EnableIRQGlobal(); + + /* Add the new timestamp data into the ptp ring buffer*/ + result = ENET_DRV_Update1588TsBuff(&(ptpBuffer->rxTimeStamp), &ptpTsData); + + } + + return result; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Parse1588Packet + * Return Value: The execution status. + * Description: Parse the message and store the ptp message information if + * it is a ptp message. this is called by the tx/rx store timestamp interface. + * + *END*********************************************************************/ +enet_status_t ENET_DRV_Parse1588Packet(uint8_t *packet, enet_mac_ptp_ts_data_t *ptpTsPtr, + bool *isPtpMsg, bool isFastEnabled) +{ + uint8_t *buffer = packet; + uint16_t ptpType; + + /* Check input parameter*/ + if((!packet) || (!isPtpMsg) || ((!ptpTsPtr) && (!isFastEnabled))) + { + return kStatus_ENET_InvalidInput; + } + + *isPtpMsg = false; + + /* Check for vlan frame*/ + if (*(uint16_t *)(buffer + kEnetPtpEtherL2PktTypeOffset) == ENET_HTONS(kEnetProtocol8021QVlan)) + { + buffer += (sizeof(enet_8021vlan_header_t) - kEnetEthernetHeadLen); + } + + ptpType = *(uint16_t *)(buffer + kEnetPtpEtherL2PktTypeOffset); + switch(ENET_HTONS(ptpType)) + { + case kEnetProtocoll2ptpv2: + if (*(uint8_t *)(buffer + kEnetPtpEtherL2MsgTypeOffset) <= kEnetPtpEventMsgType) + { + /* Set the ptp message flag*/ + *isPtpMsg = true; + if(!isFastEnabled) + { + /* It's a ptpv2 message and store the ptp header information*/ + ptpTsPtr->version = (*(uint8_t *)(buffer + kEnetPtpEtherL2VersionOffset))&0x0F; + ptpTsPtr->messageType = (*(uint8_t *)(buffer + kEnetPtpEtherL2MsgTypeOffset))& 0x0F; + ptpTsPtr->sequenceId = ENET_HTONS(*(uint16_t *)(buffer + kEnetPtpEtherL2SequenceIdOffset)); + memcpy((void *)&ptpTsPtr->sourcePortId[0],(void *)(buffer + kEnetPtpEtherL2ClockIdOffset),kEnetPtpSourcePortIdLen); + } + } + break; + + case kEnetProtocolIpv4: + if ((*(uint8_t *)(buffer + kEnetPtpIpVersionOffset) >> 4 ) == kEnetPacketIpv4Version) + { + if (((*(uint16_t *)(buffer + kEnetPtpIpv4UdpPortOffset)) == ENET_HTONS(kEnetPtpEventPort))&& + (*(uint8_t *)(buffer + kEnetPtpIpv4UdpProtocolOffset) == kEnetPacketUdpVersion)) + { + /* Set the ptp message flag*/ + *isPtpMsg = true; + if(!isFastEnabled) + { + /* It's a IPV4 ptp message and store the ptp header information*/ + ptpTsPtr->version = (*(uint8_t *)(buffer + kEnetPtpIpv4UdpVersionoffset))&0x0F; + ptpTsPtr->messageType = (*(uint8_t *)(buffer + kEnetPtpIpv4UdpMsgTypeOffset))& 0x0F; + ptpTsPtr->sequenceId = ENET_HTONS(*(uint16_t *)(buffer + kEnetPtpIpv4UdpSequenIdOffset)); + memcpy(( void *)&ptpTsPtr->sourcePortId[0],( void *)(buffer + kEnetPtpIpv4UdpClockIdOffset),kEnetPtpSourcePortIdLen); + } + } + } + break; + case kEnetProtocolIpv6: + if ((*(uint8_t *)(buffer + kEnetPtpIpVersionOffset) >> 4 ) == kEnetPacketIpv6Version) + { + if (((*(uint16_t *)(buffer + kEnetPtpIpv6UdpPortOffset)) == ENET_HTONS(kEnetPtpEventPort))&& + (*(uint8_t *)(buffer + kEnetPtpIpv6UdpProtocolOffset) == kEnetPacketUdpVersion)) + { + /* Set the ptp message flag*/ + *isPtpMsg = true; + if(!isFastEnabled) + { + /* It's a IPV6 ptp message and store the ptp header information*/ + ptpTsPtr->version = (*(uint8_t *)(buffer + kEnetPtpIpv6UdpVersionOffset))&0x0F; + ptpTsPtr->messageType = (*(uint8_t *)(buffer + kEnetPtpIpv6UdpMsgTypeOffset))& 0x0F; + ptpTsPtr->sequenceId = ENET_HTONS(*(uint16_t *)(buffer + kEnetPtpIpv6UdpSequenceIdOffset)); + memcpy(( void *)&ptpTsPtr->sourcePortId[0],( void *)(buffer + kEnetPtpIpv6UdpClockIdOffset),kEnetPtpSourcePortIdLen); + } + } + } + break; + default: + break; + + } + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: enet_ptp_l2queue_init + * Return Value: The execution status. + * Description: Initialize dara buffer queue for ptp Ethernet layer2 packets. + *END*********************************************************************/ +enet_status_t ENET_DRV_1588l2queueInit(enet_dev_if_t *enetIfPtr, enet_mac_ptp_l2buffer_t *ptpL2BufferPtr, + uint32_t ptpL2BuffNum) +{ + uint32_t index; + enet_mac_ptp_l2buffer_queue_t *ptpL2queuePtr; + /* Check input parameters*/ + if ((!enetIfPtr) || (!ptpL2BufferPtr)) + { + return kStatus_ENET_InvalidInput; + } + + ptpL2queuePtr = &enetIfPtr->privatePtp.layer2Queue; + + /* Initialize the queue*/ + ptpL2queuePtr->l2bufferPtr = ptpL2BufferPtr; + ptpL2queuePtr->l2bufferNum = ptpL2BuffNum; + ptpL2queuePtr->writeIdx = 0; + ptpL2queuePtr->readIdx = 0; + for (index = 0; index < ptpL2BuffNum; index++) + { + ptpL2queuePtr->l2bufferPtr[index].length = 0; + } + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Service_l2packet + * Return Value: The execution status. + * Description: Add the ptp layer2 Ethernet packet to the queue. + * This interface is the call back for Ethernet 1588 layer2 packets to + * add queue for ptp layer2 Ethernet packets. + *END*********************************************************************/ +enet_status_t ENET_DRV_Service_l2packet(enet_dev_if_t * enetIfPtr, enet_mac_packet_buffer_t *packBuffer) +{ + enet_mac_ptp_l2buffer_queue_t * ptpQuePtr; + uint16_t type, length = 0; + enet_mac_packet_buffer_t *frame; + /* Check input parameter*/ + if ((!enetIfPtr) || (!packBuffer)) + { + return kStatus_ENET_InvalidInput; + } + ptpQuePtr = &enetIfPtr->privatePtp.layer2Queue; + + if(!ptpQuePtr->l2bufferPtr) + { + return kStatus_ENET_Layer2UnInitialized; + } + /* Check for protocol type*/ + type = ((enet_ethernet_header_t *)(packBuffer->data))->type; + if(ENET_NTOHS(type) == kEnetProtocol8021QVlan) + { + type = ((enet_8021vlan_header_t *)(packBuffer->data))->type; + } + if(ENET_NTOHS(type) != kEnetProtocoll2ptpv2) + { + return kStatus_ENET_Layer2TypeError; + } + + /* Check if the queue is full*/ + if (ptpQuePtr->l2bufferPtr[ptpQuePtr->writeIdx].length != 0 ) + { + return kStatus_ENET_Layer2BufferFull; + } + + frame = packBuffer; + do + { + /* Store the packet*/ + memcpy((void *)(ptpQuePtr->l2bufferPtr[ptpQuePtr->writeIdx].packet + length), (void *)(frame->data), length); + length += frame->length; + frame = frame->next; + }while(frame != NULL); + ptpQuePtr->l2bufferPtr[ptpQuePtr->writeIdx].length = length; + + /* Increase the index to the next one*/ + ptpQuePtr->writeIdx = (ptpQuePtr->writeIdx + 1) % enetIfPtr->privatePtp.layer2Queue.l2bufferNum; + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: enet_ptp_send_l2packet + * Return Value: The execution status. + * Description: Send the ptp layer2 Ethernet packet to the net. + * This interface is used to send the ptp layer2 Ethernet packet and + * this interface is called by 1588 stack. + *END*********************************************************************/ +enet_status_t ENET_DRV_Send_l2packet(enet_dev_if_t * enetIfPtr, enet_mac_ptp_l2_packet_t *paramPtr) +{ + uint32_t datalen, dataoffset = 0; + uint8_t headlen; + uint16_t vlanTag, bdNumUsed = 0; + volatile enet_bd_struct_t *bdTemp; + uint8_t *packet; + /* Check input parameters*/ + if ((!enetIfPtr) || (!paramPtr)) + { + return kStatus_ENET_InvalidInput; + } + + bdTemp = enetIfPtr->bdContext.txBdCurPtr; + packet = ENET_HAL_GetBuffDescripData(bdTemp); + /* Add Ethernet MAC address*/ + memcpy(packet, &(paramPtr->hwAddr[0]), kEnetMacAddrLen); + memcpy(packet + kEnetMacAddrLen, enetIfPtr->macAddr, kEnetMacAddrLen); + + if(!enetIfPtr->isVlanTagEnabled) + { + headlen = kEnetEthernetHeadLen; + ((enet_ethernet_header_t *)packet)->type = ENET_HTONS(kEnetProtocoll2ptpv2); + } + else + { + headlen = kEnetEthernetVlanHeadLen; + vlanTag = (uint16_t)((uint16_t)paramPtr->vlanPrior << 13) | paramPtr->vlanId; + ((enet_8021vlan_header_t *)packet)->tpidtag = ENET_HTONS(kEnetProtocol8021QVlan); + ((enet_8021vlan_header_t *)packet)->othertag = ENET_HTONS(vlanTag); + ((enet_8021vlan_header_t *)packet)->type = ENET_HTONS(kEnetProtocoll2ptpv2); + } + + datalen = paramPtr->length + headlen; + /* Check transmit packets*/ + if (datalen > enetIfPtr->maxFrameSize) + { +#if ENET_ENABLE_DETAIL_STATS + enetIfPtr->stats.statsTxLarge++; + enetIfPtr->stats.statsTxDiscard++; +#endif + return kStatus_ENET_Layer2OverLarge; + } + /* Send a whole frame with a signal buffer*/ + if(datalen <= enetIfPtr->bdContext.txBuffSizeAlign) + { + bdNumUsed = 1; + memcpy((void *)(packet + headlen), (void *)(paramPtr->ptpMsg), paramPtr->length); + /* Send packet to the device*/ + return ENET_DRV_SendData(enetIfPtr, datalen, bdNumUsed); + } + /* Send a whole frame with multiple buffer descriptors*/ + while((datalen - bdNumUsed * enetIfPtr->bdContext.txBuffSizeAlign) > enetIfPtr->bdContext.txBuffSizeAlign) + { + if(bdNumUsed == 0) + { + memcpy((void *)(packet + headlen), (void *)(paramPtr->ptpMsg), enetIfPtr->bdContext.txBuffSizeAlign - headlen); + dataoffset += enetIfPtr->bdContext.txBuffSizeAlign - headlen; + } + else + { + memcpy((void *)packet, (void *)(paramPtr->ptpMsg + dataoffset), enetIfPtr->bdContext.txBuffSizeAlign); + dataoffset += enetIfPtr->bdContext.txBuffSizeAlign; + } + /* Incremenet the buffer descriptor*/ + bdTemp = ENET_DRV_IncrTxBuffDescripIndex(enetIfPtr, bdTemp); + packet = ENET_HAL_GetBuffDescripData(bdTemp); + bdNumUsed ++; + } + memcpy((void *)packet, (void *)(paramPtr->ptpMsg + dataoffset), + datalen - bdNumUsed* enetIfPtr->bdContext.txBuffSizeAlign); + bdNumUsed ++; + + /* Send packet to the device*/ + return ENET_DRV_SendData(enetIfPtr, datalen, bdNumUsed); +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Receive_l2packet + * Return Value: The execution status. + * Description: Receive the ptp layer2 Ethernet packet to the net. + * This interface is used to receive the ptp layer2 Ethernet packet and + * this interface is called by 1588 stack. + *END*********************************************************************/ +enet_status_t ENET_DRV_Receive_l2packet(enet_dev_if_t * enetIfPtr, enet_mac_ptp_l2_packet_t *paramPtr) +{ + enet_private_ptp_buffer_t *ptpBuffer; + enet_status_t result = kStatus_ENET_Success; + uint16_t len; + + /* Check input parameters*/ + if ((!enetIfPtr) || (!paramPtr)) + { + return kStatus_ENET_InvalidInput; + } + + ptpBuffer = &(enetIfPtr->privatePtp); + + /* Check if the queue is full*/ + if (ptpBuffer->layer2Queue.readIdx == ptpBuffer->layer2Queue.writeIdx) + { + result = kStatus_ENET_Layer2BufferFull; + } + else + { + /* Data process*/ + len = ptpBuffer->layer2Queue.l2bufferPtr[ptpBuffer->layer2Queue.readIdx].length; + memcpy((void *)paramPtr->ptpMsg, (void *)ptpBuffer->layer2Queue.l2bufferPtr[ptpBuffer->layer2Queue.readIdx].packet, len); + + /* Clear the queue parameter*/ + ptpBuffer->layer2Queue.l2bufferPtr[ptpBuffer->layer2Queue.readIdx].length = 0; + ptpBuffer->layer2Queue.readIdx = + (ptpBuffer->layer2Queue.readIdx + 1)% enetIfPtr->privatePtp.layer2Queue.l2bufferNum; + } + + memcpy(&(paramPtr->hwAddr[0]), enetIfPtr->macAddr, kEnetMacAddrLen); + + return result; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Update1588TsBuff + * Return Value: The execution status. + * Description: Update the ring buffers. + * + *END*********************************************************************/ +enet_status_t ENET_DRV_Update1588TsBuff(enet_mac_ptp_ts_ring_t *ptpTsRingPtr, enet_mac_ptp_ts_data_t *data) +{ + /* Check input parameter*/ + if ((!ptpTsRingPtr) || (!data)) + { + return kStatus_ENET_InvalidInput; + } + + /* Return if the buffers ring is full*/ + if (ENET_DRV_Is1588TsBuffFull(ptpTsRingPtr)) + { + return kStatus_ENET_PtpringBufferFull; + } + + /* Copy the new data into the buffer*/ + memcpy((ptpTsRingPtr->ptpTsDataPtr + ptpTsRingPtr->end), data, + sizeof(enet_mac_ptp_ts_data_t)); + + /* Increase the buffer pointer to the next empty one*/ + ptpTsRingPtr->end = ENET_DRV_Incr1588TsBuffRing(ptpTsRingPtr->size, ptpTsRingPtr->end, 1); + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Search1588TsBuff + * Return Value: The execution status. + * Description: Search the element in the ring buffers with the message + * sequence Id, Clock Id, ptp message version etc. + * + *END*********************************************************************/ +enet_status_t ENET_DRV_Search1588TsBuff(enet_mac_ptp_ts_ring_t *ptpTsRingPtr, enet_mac_ptp_ts_data_t *data) +{ + uint32_t index,size; + + /* Check input parameter*/ + if ((!ptpTsRingPtr) || (!data)) + { + return kStatus_ENET_InvalidInput; + } + + /* Check the ring buffer*/ + if (ptpTsRingPtr->front == ptpTsRingPtr->end) + { + return kStatus_ENET_PtpringBufferEmpty; + } + + /* Search the element in the ring buffer*/ + index = ptpTsRingPtr->front; + size = ptpTsRingPtr->size; + while (index != ptpTsRingPtr->end) + { + if (((ptpTsRingPtr->ptpTsDataPtr + index)->sequenceId == data->sequenceId)&& + (!memcmp((( void *)&(ptpTsRingPtr->ptpTsDataPtr + index)->sourcePortId[0]), + ( void *)&data->sourcePortId[0],kEnetPtpSourcePortIdLen))&& + ((ptpTsRingPtr->ptpTsDataPtr + index)->version == data->version)&& + ((ptpTsRingPtr->ptpTsDataPtr + index)->messageType == data->messageType)) + { + break; + } + + /* Increase the ptp ring index*/ + index = ENET_DRV_Incr1588TsBuffRing(size, index, 1); + } + + if (index == ptpTsRingPtr->end) + { + /* Check if buffers is full*/ + if (ENET_DRV_Is1588TsBuffFull(ptpTsRingPtr)) + { + /* Drop one in the front*/ + ptpTsRingPtr->front = ENET_DRV_Incr1588TsBuffRing(size, ptpTsRingPtr->front, 1); + } + return kStatus_ENET_PtpringBufferFull; + } + + /* Get the right timestamp of the required ptp message*/ + data->timeStamp.second = (ptpTsRingPtr->ptpTsDataPtr + index)->timeStamp.second; + data->timeStamp.nanosecond = + (ptpTsRingPtr->ptpTsDataPtr + index)->timeStamp.nanosecond; + + /* Increase the index*/ + ptpTsRingPtr->front = ENET_DRV_Incr1588TsBuffRing(size, index, 1); + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Is1588TsBuffFull + * Return Value: true if the ptp ring is full, false if not. + * Description: Calculate the number of used ring buffers to see if the + * ring buffer queue is full. + * + *END*********************************************************************/ +bool ENET_DRV_Is1588TsBuffFull(enet_mac_ptp_ts_ring_t *ptpTsRingPtr) +{ + uint32_t availBuffer = 0; + + if (ptpTsRingPtr->end > ptpTsRingPtr->front) + { + availBuffer = ptpTsRingPtr->end - ptpTsRingPtr->front; + } + else if (ptpTsRingPtr->end < ptpTsRingPtr->front) + { + availBuffer = ptpTsRingPtr->size - (ptpTsRingPtr->front - ptpTsRingPtr->end); + } + + if (availBuffer == (ptpTsRingPtr->size - 1)) + { + return true; + } + else + { + return false; + } +} + + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_1588Ioctl + * Return Value: The execution status. + * Description: The function provides the handler for 1588 stack to do ptp ioctl. + * This interface provides ioctl for 1588 stack to get or set timestamp and do ptp + * version2 packets process. Additional user specified driver functionality may be + * added if necessary. This api will be changed to stack adapter. + *END*********************************************************************/ +enet_status_t ENET_DRV_1588Ioctl(enet_dev_if_t * enetIfPtr, uint32_t commandId, void *inOutPtr) +{ + + enet_status_t result = kStatus_ENET_Success; + enet_private_ptp_buffer_t *buffer; + enet_mac_ptp_time_t ptpTimer; + + /*Check input parameters*/ + if (!enetIfPtr) + { + return kStatus_ENET_InvalidInput; + } + + /*Check private PTP buffer*/ + buffer = &enetIfPtr->privatePtp; + if (!buffer) + { + return kStatus_ENET_InvalidInput; + } + + switch (commandId) + { + case kEnetPtpGetRxTimestamp: + /* Get receive timestamp*/ + result = ENET_DRV_Search1588TsBuff(&buffer->rxTimeStamp, + (enet_mac_ptp_ts_data_t *)inOutPtr); + break; + case kEnetPtpGetTxTimestamp: + /* Get transmit timestamp*/ + result = ENET_DRV_Search1588TsBuff(&buffer->txTimeStamp, + (enet_mac_ptp_ts_data_t *)inOutPtr); + break; + case kEnetPtpGetCurrentTime: + /* Get current time*/ + result = ENET_DRV_Get1588timer(&ptpTimer); + inOutPtr = (enet_mac_ptp_time_t *)&ptpTimer; + break; + case kEnetPtpSetCurrentTime: + /* Set current time*/ + ptpTimer.second = ((enet_mac_ptp_time_t *)inOutPtr)->second; + ptpTimer.nanosecond = ((enet_mac_ptp_time_t *)inOutPtr)->nanosecond; + result = ENET_DRV_Set1588timer(&ptpTimer); + break; + case kEnetPtpFlushTimestamp: + /* Reset receive and transmit buffer*/ + buffer->rxTimeStamp.end = 0; + buffer->rxTimeStamp.front = 0; + buffer->txTimeStamp.end = 0; + buffer->txTimeStamp.front = 0; + break; + case kEnetPtpCorrectTime: + /* Adjust time*/ + result = ENET_DRV_Adjust1588timer(enetIfPtr->deviceNumber, + ((enet_ptp_drift_t *)inOutPtr)->drift); + break; + case kEnetPtpSendEthernetPtpV2: + /* Send layer2 packet*/ + result = ENET_DRV_Send_l2packet(enetIfPtr, (enet_mac_ptp_l2_packet_t*)inOutPtr); + break; + case kEnetPtpReceiveEthernetPtpV2: + /* Receive layer2 packet*/ + result = ENET_DRV_Receive_l2packet(enetIfPtr, (enet_mac_ptp_l2_packet_t*)inOutPtr); + break; + default: + result = kStatus_ENET_UnknownCommand; + break; + } + return result; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_TsIRQHandler + * Description: ENET timer ISR. + * This interface is the ptp timer interrupt handler. + *END*********************************************************************/ +void ENET_DRV_TsIRQHandler(uint32_t instance) +{ + ENET_Type * base; + enet_dev_if_t *enetIfPtr; + + enetIfPtr = enetIfHandle[instance]; + /*Check input parameter*/ + if (!enetIfPtr) + { + return; + } + base = g_enetBase[instance]; + /*Get interrupt status*/ + if (ENET_HAL_GetIntStatusFlag(base, kEnetTsTimerInterrupt)) + { +#if FSL_FEATURE_ENET_PTP_TIMER_CHANNEL_INTERRUPT_ERRATA_2579 + ENET_HAL_Rst1588TimerCmpValAndClrFlag(base, ENET_TIMER_CHANNEL_NUM, \ + (kEnetPtpAtperValue - kEnetPtpAtperValue/g_ptpClkFrq)); +#else + /*Clear interrupt events*/ + ENET_HAL_ClearIntStatusFlag(base, kEnetTsTimerInterrupt); +#endif + /* Increase timer second counter*/ + g_ptpMasterTime.second++; + } +} + +#endif + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Init + * Return Value: The execution status. + * Description:Initialize the ENET device with the basic configuration + * When ENET is used, this function need to be called by the NET initialize + * interface. + *END*********************************************************************/ +enet_status_t ENET_DRV_Init(enet_dev_if_t * enetIfPtr, const enet_user_config_t* userConfig) +{ + enet_status_t result; + uint32_t frequency; + ENET_Type * base; + uint32_t statusMask = 0; + enet_cur_status_t curStatus; + const enet_mac_config_t* macCfgPtr = userConfig->macCfgPtr; + const enet_buff_config_t* buffCfgPtr = userConfig->buffCfgPtr; + + enet_bd_config bdConfig = {0}; + /* Check the input parameters*/ + if ((!enetIfPtr) || (!macCfgPtr) || (!buffCfgPtr)) + { + return kStatus_ENET_InvalidInput; + } +#if !ENET_RECEIVE_ALL_INTERRUPT + /* POLL mode needs the extended buffer for data buffer update*/ + if((!buffCfgPtr->extRxBuffQue) || (!buffCfgPtr->extRxBuffNum)) + { + return kStatus_ENET_InvalidInput; + } +#endif + base = g_enetBase[enetIfPtr->deviceNumber]; + + /* Store the global ENET structure for ISR input parameter*/ + enetIfHandle[enetIfPtr->deviceNumber] = enetIfPtr; + + /* Turn on ENET module clock gate */ + CLOCK_SYS_EnableEnetClock( 0U); + frequency = CLOCK_SYS_GetSystemClockFreq(); + bdConfig.rxBds = buffCfgPtr->rxBdPtrAlign; + bdConfig.rxBuffer = buffCfgPtr->rxBufferAlign; + bdConfig.rxBdNumber = buffCfgPtr->rxBdNumber; + bdConfig.rxBuffSizeAlign = buffCfgPtr->rxBuffSizeAlign; + bdConfig.txBds = buffCfgPtr->txBdPtrAlign; + bdConfig.txBuffer = buffCfgPtr->txBufferAlign; + bdConfig.txBdNumber = buffCfgPtr->txBdNumber; + bdConfig.txBuffSizeAlign = buffCfgPtr->txBuffSizeAlign; + /* Init ENET MAC to reset status*/ + ENET_HAL_Init(base); + /* Configure MAC controller*/ + ENET_HAL_Config(base, macCfgPtr, frequency, &bdConfig); + +#if FSL_FEATURE_ENET_SUPPORT_PTP + result = ENET_DRV_1588Init(enetIfPtr, buffCfgPtr->ptpTsRxDataPtr, buffCfgPtr->ptpTsRxBuffNum, + buffCfgPtr->ptpTsTxDataPtr, buffCfgPtr->ptpTsTxBuffNum, macCfgPtr->isSlaveMode); + if(result != kStatus_ENET_Success) + { + return result; + } +#endif + /* Enable Ethernet rx and tx interrupt*/ + ENET_HAL_SetIntMode(base, kEnetTxByteInterrupt, true); + ENET_HAL_SetIntMode(base, kEnetRxFrameInterrupt, true); + + INT_SYS_EnableIRQ(g_enetRxIrqId[enetIfPtr->deviceNumber]); + INT_SYS_EnableIRQ(g_enetTxIrqId[enetIfPtr->deviceNumber]); + + /* Enable Ethernet module after all configuration except the bd active*/ + ENET_HAL_Enable(base); + + /* Active Receive buffer descriptor must be done after module enable*/ + ENET_HAL_SetRxBdActive(base); + + /* Store data in bdContext*/ + /* Set crc enable when tx crc forward disable and tx buffer descriptor crc enabled*/ + if((!(macCfgPtr->macCtlConfigure & kEnetTxCrcFwdEnable))&&(macCfgPtr->macCtlConfigure & kEnetTxCrcBdEnable)) + { + enetIfPtr->isTxCrcEnable = true; + } + else + { + enetIfPtr->isTxCrcEnable = false; + } + enetIfPtr->isRxCrcFwdEnable = (macCfgPtr->macCtlConfigure & kEnetRxCrcFwdEnable) ? 1U : 0U; + memcpy(enetIfPtr->macAddr, macCfgPtr->macAddr, kEnetMacAddrLen); + enetIfPtr->isVlanTagEnabled = (macCfgPtr->macCtlConfigure & kEnetVlanTagEnabled) ? 1U : 0U; + enetIfPtr->bdContext.rxBdBasePtr = buffCfgPtr->rxBdPtrAlign; + enetIfPtr->bdContext.rxBdCurPtr = buffCfgPtr->rxBdPtrAlign; + enetIfPtr->bdContext.rxBdDirtyPtr = buffCfgPtr->rxBdPtrAlign; + enetIfPtr->bdContext.txBdBasePtr = buffCfgPtr->txBdPtrAlign; + enetIfPtr->bdContext.txBdCurPtr = buffCfgPtr->txBdPtrAlign; + enetIfPtr->bdContext.txBdDirtyPtr = buffCfgPtr->txBdPtrAlign; + enetIfPtr->bdContext.rxBuffSizeAlign = buffCfgPtr->rxBuffSizeAlign; + enetIfPtr->bdContext.txBuffSizeAlign = buffCfgPtr->txBuffSizeAlign; + statusMask |= ENET_GET_MAX_FRAME_LEN_MASK; + ENET_HAL_GetStatus(base, statusMask, &curStatus); + enetIfPtr->maxFrameSize = curStatus.maxFrameLen; + /* Extend buffer for data buffer update*/ + if(buffCfgPtr->extRxBuffQue != NULL) + { + uint16_t counter = 0; + enetIfPtr->bdContext.extRxBuffQue = NULL; + for(counter = 0; counter < buffCfgPtr->extRxBuffNum; counter++) + { + enet_mac_enqueue_buffer((void **)&enetIfPtr->bdContext.extRxBuffQue, + (buffCfgPtr->extRxBuffQue + counter * buffCfgPtr->rxBuffSizeAlign)); + } + enetIfPtr->bdContext.extRxBuffNum = buffCfgPtr->extRxBuffNum; + } + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Deinit + * Return Value: The execution status. + * Description: Close ENET device. + * This function is used to shut down ENET device. + *END*********************************************************************/ +enet_status_t ENET_DRV_Deinit(enet_dev_if_t * enetIfPtr) +{ + ENET_Type * base; + + /*Check input parameter*/ + if (!enetIfPtr) + { + return kStatus_ENET_InvalidInput; + } + base = g_enetBase[enetIfPtr->deviceNumber]; + /* Reset ENET module and disable ENET module*/ + ENET_HAL_Init(base); +#if FSL_FEATURE_ENET_SUPPORT_PTP + ENET_DRV_1588Deinit(enetIfPtr); +#endif + /* Disable irq*/ + INT_SYS_DisableIRQ(g_enetTxIrqId[enetIfPtr->deviceNumber]); + INT_SYS_DisableIRQ(g_enetRxIrqId[enetIfPtr->deviceNumber]); + INT_SYS_DisableIRQ(g_enetTsIrqId[enetIfPtr->deviceNumber]); + INT_SYS_DisableIRQ(g_enetErrIrqId[enetIfPtr->deviceNumber]); + + /* Clear the global ENET structure*/ + enetIfHandle[enetIfPtr->deviceNumber] = NULL; + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_UpdateRxBuffDescrip + * Return Value: The execution status. + * Description: ENET receive buffer descriptor update. + * This interface provides the receive buffer descriptor update and increase + * the current buffer descriptor pointer to the next one. + *END*********************************************************************/ +enet_status_t ENET_DRV_UpdateRxBuffDescrip(enet_dev_if_t * enetIfPtr, bool isBuffUpdate) +{ + ENET_Type * base; + uint8_t *bufferTemp = NULL; + base = g_enetBase[enetIfPtr->deviceNumber]; + + while((enetIfPtr->bdContext.rxBdDirtyPtr != enetIfPtr->bdContext.rxBdCurPtr) || + (enetIfPtr->bdContext.isRxBdFull)) + { + if(isBuffUpdate) + { + /* get the data buffer for update*/ + bufferTemp = (unsigned char*)enet_mac_dequeue_buffer((void **)&enetIfPtr->bdContext.extRxBuffQue); + if(!bufferTemp) + { + return kStatus_ENET_NoRxBufferLeft; + } + } + + ENET_HAL_ClrRxBdAfterHandled(enetIfPtr->bdContext.rxBdDirtyPtr, bufferTemp, isBuffUpdate); + + /* Increase the buffer descriptor to the next one*/ + enetIfPtr->bdContext.rxBdDirtyPtr = + ENET_DRV_IncrRxBuffDescripIndex(enetIfPtr, enetIfPtr->bdContext.rxBdDirtyPtr); + enetIfPtr->bdContext.isRxBdFull = false; + + /* Active the receive buffer descriptor*/ + ENET_HAL_SetRxBdActive(base); + } + + return kStatus_ENET_Success; +} +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_CleanupTxBuffDescrip + * Return Value: The execution status. + * Description: First, store transmit frame error statistic and ptp timestamp + * of transmitted packets. Second, clean up the used transmit buffer descriptors. + * If the ptp 1588 feature is open, this interface will do capture 1588 timestamp. + * It is called by transmit interrupt handler. + *END*********************************************************************/ +enet_status_t ENET_DRV_CleanupTxBuffDescrip(enet_dev_if_t * enetIfPtr) +{ + volatile enet_bd_struct_t *curBd; + uint64_t mask = 0; + enet_bd_attr_t bdAttr; + mask |= (ENET_TX_BD_READY_FLAG_MASK | ENET_TX_BD_LAST_FLAG_MASK | ENET_TX_BD_TIMESTAMP_FLAG_MASK); + + while ((enetIfPtr->bdContext.txBdDirtyPtr != enetIfPtr->bdContext.txBdCurPtr) + || (enetIfPtr->bdContext.isTxBdFull)) + { + curBd = enetIfPtr->bdContext.txBdDirtyPtr; + /* Get the control status data, If the bd has not been processed break out*/ + ENET_HAL_GetBufDescripAttr(curBd, mask, &bdAttr); + if(bdAttr.flags & ENET_TX_BD_READY_FLAG) + { + break; + } +#if FSL_FEATURE_ENET_SUPPORT_PTP + if(enetIfPtr->privatePtp.firstflag) + { + enetIfPtr->privatePtp.firstBdPtr = curBd; + enetIfPtr->privatePtp.firstflag = false; + } +#endif + /* If the transmit buffer descriptor is ready, store packet statistic*/ + if(bdAttr.flags & ENET_TX_BD_LAST_FLAG) + { +#if ENET_ENABLE_DETAIL_STATS + ENET_DRV_TxErrorStats(enetIfPtr,curBd); +#endif +#if FSL_FEATURE_ENET_SUPPORT_PTP + /* Do ptp timestamp store*/ + if (bdAttr.flags & ENET_TX_BD_TIMESTAMP_FLAG) + { + ENET_DRV_GetTxTs(&enetIfPtr->privatePtp, enetIfPtr->privatePtp.firstBdPtr, curBd); + enetIfPtr->privatePtp.firstflag = true; + } +#endif + } + + /* Clear the buffer descriptor buffer address*/ + ENET_HAL_ClrTxBdAfterSend(curBd); + + /* Update the buffer address*/ + enetIfPtr->bdContext.txBdDirtyPtr = + ENET_DRV_IncrTxBuffDescripIndex(enetIfPtr, enetIfPtr->bdContext.txBdDirtyPtr); + + /* Clear the buffer full flag*/ + enetIfPtr->bdContext.isTxBdFull = false; + } + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_IncrRxBuffDescripIndex + * Return Value: The new rx buffer descriptor which number is increased one from old buffer descriptor. + * Description: Increases the receive buffer descriptor to the next one. + *END*********************************************************************/ +volatile enet_bd_struct_t * ENET_DRV_IncrRxBuffDescripIndex(enet_dev_if_t * enetIfPtr, volatile enet_bd_struct_t *curBd) +{ + assert(enetIfPtr); + assert(curBd); + uint64_t mask = 0; + enet_bd_attr_t bdAttr; + mask |= ENET_RX_BD_WRAP_FLAG_MASK; + ENET_HAL_GetBufDescripAttr(curBd, mask, &bdAttr); + /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer*/ + if (bdAttr.flags & ENET_RX_BD_WRAP_FLAG) + { + curBd = enetIfPtr->bdContext.rxBdBasePtr; + } + else + { + curBd ++; + } + return curBd; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_IncrTxBuffDescripIndex + * Return Value: The new tx buffer descriptor which number is increased one from old buffer descriptor.. + * Description: Increases the transmit buffer descriptor to the next one. + *END*********************************************************************/ +volatile enet_bd_struct_t * ENET_DRV_IncrTxBuffDescripIndex(enet_dev_if_t * enetIfPtr, volatile enet_bd_struct_t *curBd) +{ + /* Increase the buffer descriptor*/ + uint64_t mask = 0; + enet_bd_attr_t bdAttr; + mask |= ENET_TX_BD_WRAP_FLAG_MASK; + ENET_HAL_GetBufDescripAttr(curBd, mask, &bdAttr); + if (bdAttr.flags & ENET_TX_BD_WRAP_FLAG) + { + curBd = enetIfPtr->bdContext.txBdBasePtr; + } + else + { + curBd ++; + } + return curBd; +} +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_TxErrorStats + * Return Value: None. + * Description: ENET frame receive stats process. + * This interface is used to process packet error statistic + * in the last buffer descriptor of each frame. + *END*********************************************************************/ +void ENET_DRV_TxErrorStats(enet_dev_if_t * enetIfPtr, volatile enet_bd_struct_t *curBd) +{ +#if ENET_ENABLE_DETAIL_STATS + uint64_t mask = 0; + enet_bd_attr_t bdAttr; + mask.b.txBdTxErr = mask.b.txBdExcColErr = mask.b.txBdLateColErr \ + = mask.b.txBdTxUnderFlowErr = mask.b.txBdOverFlowErr = 1; + mask |= (ENET_TX_BD_TX_ERR_FLAG_MASK | ENET_TX_BD_EXC_COL_FLAG_MASK | \ + ENET_TX_BD_LATE_COL_FLAG_MASK | ENET_TX_BD_UNDERFLOW_FLAG_MASK | ENET_TX_BD_OVERFLOW_FLAG_MASK); + ENET_HAL_GetBufDescripAttr(curBd, mask, &bdAttr); + + if (bdAttr.flags & ENET_TX_BD_TX_ERR_FLAG) + { + /* Transmit error*/ + enetIfPtr->stats.statsTxError++; + + if (bdAttr.flags & ENET_TX_BD_EXC_COL_FLAG) + { + /* Transmit excess collision*/ + enetIfPtr->stats.statsTxExcessCollision++; + } + else if (bdAttr.flags & ENET_TX_BD_LATE_COL_FLAG) + { + /* Transmit late collision*/ + enetIfPtr->stats.statsTxLateCollision++; + } + else if (bdAttr.flags & ENET_TX_BD_UNDERFLOW_FLAG) + { + /* Transmit underflow*/ + enetIfPtr->stats.statsTxUnderFlow++; + } + else if (bdAttr.flags & ENET_TX_BD_OVERFLOW_FLAG) + { + /* Transmit overflow*/ + enetIfPtr->stats.statsTxOverFlow++; + } + } +#endif + enetIfPtr->stats.statsTxTotal++; +} +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_RxErrorStats + * Return Value: true if the frame is error else false. + * Description: ENET frame receive stats process. + * This interface is used to process packet statistic in the last buffer + * descriptor of each frame. + *END*********************************************************************/ +bool ENET_DRV_RxErrorStats(enet_dev_if_t * enetIfPtr, volatile enet_bd_struct_t *curBd) +{ + assert(enetIfPtr); + assert(curBd); + uint64_t mask = 0; + enet_bd_attr_t bdAttr; + /* The last bd in the frame check the stauts of the received frame*/ + mask |= (ENET_RX_BD_OVERRUN_FLAG_MASK | ENET_RX_BD_LEN_VIOLAT_FLAG_MASK | \ + ENET_RX_BD_NO_OCTET_FLAG_MASK | ENET_RX_BD_CRC_ERR_FLAG_MASK | ENET_RX_BD_COLLISION_FLAG_MASK); + ENET_HAL_GetBufDescripAttr(curBd, mask, &bdAttr); + + if ((bdAttr.flags & ENET_RX_BD_OVERRUN_FLAG) || (bdAttr.flags & ENET_RX_BD_LEN_VIOLAT_FLAG) \ + || (bdAttr.flags & ENET_RX_BD_NO_OCTET_FLAG) || (bdAttr.flags & ENET_RX_BD_CRC_ERR_FLAG)\ + || (bdAttr.flags & ENET_RX_BD_COLLISION_FLAG)) + { +#if ENET_ENABLE_DETAIL_STATS + /* Discard error packets*/ + enetIfPtr->stats.statsRxError++; + enetIfPtr->stats.statsRxDiscard++; + + /* Receive error*/ + if (bdAttr.flags & ENET_RX_BD_OVERRUN_FLAG) + { + /* Receive over run*/ + enetIfPtr->stats.statsRxOverRun++; + } + else if (bdAttr.flags & ENET_RX_BD_LEN_VIOLAT_FLAG) + { + /* Receive length greater than max frame*/ + enetIfPtr->stats.statsRxLengthGreater++; + } + else if (bdAttr.flags & ENET_RX_BD_NO_OCTET_FLAG) + { + /* Receive non-octet aligned frame*/ + enetIfPtr->stats.statsRxAlign++; + } + else if (bdAttr.flags & ENET_RX_BD_CRC_ERR_FLAG) + { + /* Receive crc error*/ + enetIfPtr->stats.statsRxFcs++; + } + else if (bdAttr.flags & ENET_RX_BD_COLLISION_FLAG) + { + /* late collision frame discard*/ + enetIfPtr->stats.statsRxCollision++; + } +#endif + return true; + } + else + { + /* Add the right packets*/ + enetIfPtr->stats.statsRxTotal++; + return false; + } +} + +#if ENET_RECEIVE_ALL_INTERRUPT +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_ReceiveData + * Return Value: The execution status. + * Description: ENET frame receive function. + * This interface receive the frame from ENET deviece and returns the address + * of the received data. This is used to do receive data in receive interrupt + * handler. This is the pure interrupt mode + *END*********************************************************************/ +enet_status_t ENET_DRV_ReceiveData(enet_dev_if_t * enetIfPtr) +{ + volatile enet_bd_struct_t *curBd; + uint16_t bdNumTotal = 0, lenTotal = 0; + uint64_t mask = 0; + enet_bd_attr_t bdAttr; + enet_mac_packet_buffer_t packetBuffer[kEnetMaxFrameBdNumbers] = {{0}}; + /* Check input parameters*/ + if ((!enetIfPtr) || (!enetIfPtr->bdContext.rxBdCurPtr)) + { + return kStatus_ENET_InvalidInput; + } + + /* Check the current buffer descriptor address*/ + curBd = enetIfPtr->bdContext.rxBdCurPtr; + /* Return if the current buffer descriptor is empty*/ + mask |= (ENET_RX_BD_EMPTY_FLAG_MASK | ENET_RX_BD_TRUNC_FLAG_MASK | ENET_RX_BD_LAST_FLAG_MASK | ENET_BD_LEN_MASK); + ENET_HAL_GetBufDescripAttr(curBd, mask, &bdAttr); + while(!(bdAttr.flags & ENET_RX_BD_EMPTY_FLAG)) + { + /* Check if receive buffer is full*/ + if(enetIfPtr->bdContext.isRxBdFull) + { +#if ENET_ENABLE_DETAIL_STATS + enetIfPtr->stats.statsRxDiscard++; +#endif + ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, false); + return kStatus_ENET_RxBdFull; + } + + /* Increase current buffer descriptor to the next one*/ + enetIfPtr->bdContext.rxBdCurPtr = + ENET_DRV_IncrRxBuffDescripIndex(enetIfPtr, enetIfPtr->bdContext.rxBdCurPtr); + /* Check if the buffer is full*/ + if (enetIfPtr->bdContext.rxBdCurPtr == enetIfPtr->bdContext.rxBdDirtyPtr) + { + enetIfPtr->bdContext.isRxBdFull = true; + } + + /* Discard packets with truncate error*/ + if (bdAttr.flags & ENET_RX_BD_TRUNC_FLAG) + { +#if ENET_ENABLE_DETAIL_STATS + enetIfPtr->stats.statsRxTruncate++; + enetIfPtr->stats.statsRxDiscard++; +#endif + ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, false); + return kStatus_ENET_RxbdTrunc; + } + + if (bdAttr.flags & ENET_RX_BD_LAST_FLAG) + { + /* The last bd in the frame check the stauts of the received frame*/ + if (ENET_DRV_RxErrorStats(enetIfPtr, curBd)) + { + ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, false); + return kStatus_ENET_RxbdError; + } + else + { + packetBuffer[bdNumTotal].data = ENET_HAL_GetBuffDescripData(curBd); + packetBuffer[bdNumTotal].length = bdAttr.bdLen - lenTotal; + /* Crc length check */ + if(enetIfPtr->isRxCrcFwdEnable) + { + packetBuffer[bdNumTotal].length -= kEnetFrameFcsLen; + } + packetBuffer[bdNumTotal].next = NULL; +#if FSL_FEATURE_ENET_SUPPORT_PTP + ENET_DRV_GetRxTs(&enetIfPtr->privatePtp, + packetBuffer[0].data, curBd); +#endif + if(enetIfPtr->enetNetifcall) + { + enetIfPtr->enetNetifcall(enetIfPtr, &packetBuffer[0]); + } + + /* Update receive buffer descriptor*/ + ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, false); + bdNumTotal = 0; + } + } + else + { + packetBuffer[bdNumTotal].data = ENET_HAL_GetBuffDescripData(curBd); + packetBuffer[bdNumTotal].length = enetIfPtr->bdContext.rxBuffSizeAlign; + lenTotal += packetBuffer[bdNumTotal].length; + packetBuffer[bdNumTotal].next = &packetBuffer[bdNumTotal + 1]; + bdNumTotal ++; + /* Check a frame with total bd numbers */ + if (bdNumTotal == kEnetMaxFrameBdNumbers) + { +#if ENET_ENABLE_DETAIL_STATS + enetIfPtr->stats.statsRxDiscard++; +#endif + ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, false); + return kStatus_ENET_SmallRxBuffSize; + } + } + + /* Check the current buffer descriptor address*/ + curBd = enetIfPtr->bdContext.rxBdCurPtr; + ENET_HAL_GetBufDescripAttr(curBd, mask, &bdAttr); + } + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_InstallNetIfCall + * Return Value: The execution status. + * Description: Install ENET TCP/IP stack net interface callback function . + * This interface call the net interface of the TCP/IP stack to deliver the + * received data to stack. + *END*********************************************************************/ +enet_status_t ENET_DRV_InstallNetIfCall(enet_dev_if_t * enetIfPtr, enet_netif_callback_t function) +{ + if(!enetIfPtr) + { + return kStatus_ENET_InvalidInput; + } + + enetIfPtr->enetNetifcall = function; + return kStatus_ENET_Success; +} + +#else +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_ReceiveData + * Return Value: The execution status. + * Description: ENET frame receive function. + * This interface receive the frame from ENET device and returns the address + * of the received data. This is used to do receive data on polling + + * interrupt mode. + * we recommend to use the sync signal in receive interrupt handler to + * wakeup the blocked polling or for sync signal flag check when receive + * data on polling mode. + * To avoid the receive buffer descriptor overflow due to the latency + * of the stack process task, extended data buffers in enetIfPtr->bdContext.extRxBuffQue + * are used to update the receive buffer descriptor. please make sure + * the data buffers are immediately enqueued back to the enetIfPtr->bdContext.extRxBuffQue + * after the data is copied to upper layer buffer. enet_mac_enqueue_buffer should be + * called to do the data buffer enqueue process in your receive adaptor application. + * + *END*********************************************************************/ +enet_status_t ENET_DRV_ReceiveData(enet_dev_if_t * enetIfPtr, enet_mac_packet_buffer_t *packBuffer) +{ + volatile enet_bd_struct_t *curBd; + bool isLastFrame = true; + uint16_t totalLen = 0; + uint64_t mask = 0; + enet_bd_attr_t bdAttr; + enet_mac_packet_buffer_t *TempBuff = NULL; + /* Check input parameters*/ + if ((!enetIfPtr) || (!packBuffer) || (!enetIfPtr->bdContext.rxBdCurPtr)) + { + return kStatus_ENET_InvalidInput; + } + mask |= (ENET_RX_BD_EMPTY_FLAG_MASK | ENET_RX_BD_TRUNC_FLAG_MASK | ENET_RX_BD_LAST_FLAG_MASK | ENET_BD_LEN_MASK); + /* Check if the bd is full*/ + if (!enetIfPtr->bdContext.isRxBdFull) + { + /* Check the current buffer descriptor's empty flag*/ + curBd = enetIfPtr->bdContext.rxBdCurPtr; + ENET_HAL_GetBufDescripAttr(curBd, mask, &bdAttr); + if (bdAttr.flags & ENET_RX_BD_EMPTY_FLAG) + { + return kStatus_ENET_RxbdEmpty; + } + + /* Increase current buffer descriptor to the next one*/ + enetIfPtr->bdContext.rxBdCurPtr = + ENET_DRV_IncrRxBuffDescripIndex(enetIfPtr, enetIfPtr->bdContext.rxBdCurPtr); + if (enetIfPtr->bdContext.rxBdCurPtr == enetIfPtr->bdContext.rxBdDirtyPtr) + { + enetIfPtr->bdContext.isRxBdFull = true; + } + + /* Discard packets with truncate error*/ + if (bdAttr.flags & ENET_RX_BD_TRUNC_FLAG) + { +#if ENET_ENABLE_DETAIL_STATS + enetIfPtr->stats.statsRxTruncate++; + enetIfPtr->stats.statsRxDiscard++; +#endif + ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, false); + return kStatus_ENET_RxbdTrunc; + } + + if (bdAttr.flags & ENET_RX_BD_LAST_FLAG) + { + /*This is valid frame */ + isLastFrame = true; + + /* The last bd in the frame check the status of the received frame*/ + if (!ENET_DRV_RxErrorStats(enetIfPtr, curBd)) + { + packBuffer->data = ENET_HAL_GetBuffDescripData(curBd); + packBuffer->length = bdAttr.bdLen; + /* Crc length check */ + if(enetIfPtr->isRxCrcFwdEnable) + { + packBuffer->length -= kEnetFrameFcsLen; + } +#if FSL_FEATURE_ENET_SUPPORT_PTP + ENET_DRV_GetRxTs(&enetIfPtr->privatePtp, packBuffer->data, curBd); +#endif + /* Update receive buffer descriptor*/ + return ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, true); + } + else + { + ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, false); + return kStatus_ENET_RxbdError; + } + } + else + { + /* Store the fragments of a frame on several buffer descriptors*/ + isLastFrame = false; + packBuffer->data = ENET_HAL_GetBuffDescripData(curBd); + packBuffer->length = enetIfPtr->bdContext.rxBuffSizeAlign; + totalLen = packBuffer->length; + if(packBuffer->next) + { + TempBuff = packBuffer->next; + } + else + { +#if ENET_ENABLE_DETAIL_STATS + enetIfPtr->stats.statsRxMissed++; +#endif + return kStatus_ENET_NoEnoughRxBuffers; + } + } + } + else + { +#if ENET_ENABLE_DETAIL_STATS + enetIfPtr->stats.statsRxMissed++; +#endif + ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, false); + return kStatus_ENET_RxBdFull; + } + + /*process the frame stored on several bds*/ + while (!isLastFrame) + { + if (!enetIfPtr->bdContext.isRxBdFull) + { + /* Get the current buffer descriptor address*/ + curBd = enetIfPtr->bdContext.rxBdCurPtr; + ENET_HAL_GetBufDescripAttr(curBd, mask, &bdAttr); + if (bdAttr.flags & ENET_RX_BD_EMPTY_FLAG) + { + return kStatus_ENET_RxbdEmpty; + } + + /* Increase current buffer descriptor to the next one*/ + enetIfPtr->bdContext.rxBdCurPtr = + ENET_DRV_IncrRxBuffDescripIndex(enetIfPtr, enetIfPtr->bdContext.rxBdCurPtr); + if (enetIfPtr->bdContext.rxBdCurPtr == enetIfPtr->bdContext.rxBdDirtyPtr) + { + enetIfPtr->bdContext.isRxBdFull = true; + } + + /* Discard packets with truncate error*/ + if (bdAttr.flags & ENET_RX_BD_TRUNC_FLAG) + { +#if ENET_ENABLE_DETAIL_STATS + enetIfPtr->stats.statsRxTruncate++; + enetIfPtr->stats.statsRxDiscard++; +#endif + ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, false); + return kStatus_ENET_RxbdTrunc; + } + + if (bdAttr.flags & ENET_RX_BD_LAST_FLAG) + { + /*This is the last bd in a frame*/ + isLastFrame = true; + + /* The last bd in the frame check the status of the received frame*/ + if (ENET_DRV_RxErrorStats(enetIfPtr, curBd)) + { + ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, false); + return kStatus_ENET_RxbdError; + } + else + { + TempBuff->data = ENET_HAL_GetBuffDescripData(curBd); + TempBuff->length = bdAttr.bdLen - totalLen; + /* Crc length check */ + if(enetIfPtr->isRxCrcFwdEnable) + { + TempBuff->length -= kEnetFrameFcsLen; + } + /* Delivery the last part data to the packet*/ +#if FSL_FEATURE_ENET_SUPPORT_PTP + ENET_DRV_GetRxTs(&enetIfPtr->privatePtp, packBuffer->data, curBd); +#endif + /* Update receive buffer descriptor*/ + return ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, true); + } + } + else + { + isLastFrame = false; + TempBuff->data = ENET_HAL_GetBuffDescripData(curBd); + TempBuff->length = enetIfPtr->bdContext.rxBuffSizeAlign; + totalLen += TempBuff->length; + if(TempBuff->next) + { + TempBuff = TempBuff->next; + } + else + { +#if ENET_ENABLE_DETAIL_STATS + enetIfPtr->stats.statsRxMissed++; +#endif + return kStatus_ENET_NoEnoughRxBuffers; + } + } + } + else + { +#if ENET_ENABLE_DETAIL_STATS + enetIfPtr->stats.statsRxMissed++; +#endif + ENET_DRV_UpdateRxBuffDescrip(enetIfPtr, false); + return kStatus_ENET_RxBdFull; + } + } + + return kStatus_ENET_Success; +} +#endif +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_SendData + * Return Value: The execution status. + * Description: ENET frame send function. + * This interface send the frame to ENET device. If the transmit buffer size + * is less than the maximum frame size 1518/1522, please make sure the buffer + * size larger than 256. + *END*********************************************************************/ +enet_status_t ENET_DRV_SendData(enet_dev_if_t * enetIfPtr, uint32_t dataLen, uint32_t bdNumUsed) +{ + volatile enet_bd_struct_t *curBd; + bool isPtpMsg = false; + uint16_t bdIdx = 0; + uint32_t size = 0; + uint8_t *packet; + ENET_Type * base; + + /* Check input parameters*/ + if ((!enetIfPtr ) || (!bdNumUsed)) + { + return kStatus_ENET_InvalidInput; + } + + if(enetIfPtr->bdContext.isTxBdFull) + { +#if ENET_ENABLE_DETAIL_STATS + enetIfPtr->stats.statsTxMissed ++; +#endif + return kStatus_ENET_TxbdFull; + } + + /* Get the current buffer descriptor address*/ + curBd = enetIfPtr->bdContext.txBdCurPtr; +#if FSL_FEATURE_ENET_SUPPORT_PTP + /* Check ptp message only for the first part including ptp head information*/ + packet = ENET_HAL_GetBuffDescripData(curBd); + ENET_DRV_Parse1588Packet(packet, NULL, &isPtpMsg, true); +#endif + base = g_enetBase[enetIfPtr->deviceNumber]; + /* Bd number need for the data transmit*/ + if(bdNumUsed == 1) + { + /* Packet the transmit frame to the buffer descriptor*/ + ENET_HAL_SetTxBdBeforeSend(curBd, dataLen, isPtpMsg, enetIfPtr->isTxCrcEnable, true); + + /* Increase the buffer descriptor address*/ + enetIfPtr->bdContext.txBdCurPtr = + ENET_DRV_IncrTxBuffDescripIndex(enetIfPtr, enetIfPtr->bdContext.txBdCurPtr); + + /* Return if the transmit buffer ring is full*/ + if (enetIfPtr->bdContext.txBdCurPtr == enetIfPtr->bdContext.txBdDirtyPtr) + { + enetIfPtr->bdContext.isTxBdFull = true; + } + else + { + enetIfPtr->bdContext.isTxBdFull = false; + } + /* Active the transmit buffer descriptor*/ + ENET_HAL_SetTxBdActive(base); + + } + else + { + for(bdIdx = 0; bdIdx < bdNumUsed; bdIdx ++) + { + + if(enetIfPtr->bdContext.isTxBdFull) + { +#if ENET_ENABLE_DETAIL_STATS + enetIfPtr->stats.statsTxMissed ++; +#endif + return kStatus_ENET_TxbdFull; + } + + /* Get the current buffer descriptor address*/ + curBd = enetIfPtr->bdContext.txBdCurPtr; + + /* Last Buffer Descriptor */ + if(bdIdx == bdNumUsed - 1) + { + /* Set the transmit flag in the buffer descriptor before the frame + is sent and indicate it is the last one. */ + ENET_HAL_SetTxBdBeforeSend(curBd, dataLen - size, isPtpMsg, enetIfPtr->isTxCrcEnable, true); + } + else + { + /* Set the transmit flag in the buffer descriptor before the frame + is sent and indicate it is not the last one. */ + ENET_HAL_SetTxBdBeforeSend(curBd, enetIfPtr->bdContext.txBuffSizeAlign, isPtpMsg, enetIfPtr->isTxCrcEnable, false); + size += enetIfPtr->bdContext.txBuffSizeAlign; + } + + /* Increase the buffer address*/ + enetIfPtr->bdContext.txBdCurPtr = + ENET_DRV_IncrTxBuffDescripIndex(enetIfPtr, enetIfPtr->bdContext.txBdCurPtr); + + /* Return if the transmit buffer ring is full*/ + if (enetIfPtr->bdContext.txBdCurPtr == enetIfPtr->bdContext.txBdDirtyPtr) + { + enetIfPtr->bdContext.isTxBdFull = true; + } + else + { + enetIfPtr->bdContext.isTxBdFull = false; + } + /* Active the transmit buffer descriptor*/ + ENET_HAL_SetTxBdActive(base); + } + + } + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_RxIRQHandler + * Description: ENET receive isr. + * This interface is the receive interrupt handler. + *END*********************************************************************/ +void ENET_DRV_RxIRQHandler(uint32_t instance) +{ + enet_dev_if_t *enetIfPtr; + ENET_Type * base; + enetIfPtr = enetIfHandle[instance]; +#if !ENET_RECEIVE_ALL_INTERRUPT + event_flags_t flag = 0x1; +#endif + /*Check input parameter*/ + if (!enetIfPtr) + { + return; + } + base = g_enetBase[enetIfPtr->deviceNumber]; + /* Get interrupt status.*/ + while ((ENET_HAL_GetIntStatusFlag(base, kEnetRxFrameInterrupt)) || (ENET_HAL_GetIntStatusFlag(base, kEnetRxByteInterrupt))) + { + /*Clear interrupt*/ + ENET_HAL_ClearIntStatusFlag(base, kEnetRxFrameInterrupt); + ENET_HAL_ClearIntStatusFlag(base, kEnetRxByteInterrupt); +#if !ENET_RECEIVE_ALL_INTERRUPT + /* Release sync signal-----------------*/ + OSA_EventSet(&enetIfPtr->enetReceiveSync, flag); +#else + /* Receive peripheral driver*/ + ENET_DRV_ReceiveData(enetIfPtr); +#endif + } + +} + + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_TxIRQHandler + * Description: ENET transmit isr. + * This interface is the transmit interrupt handler. + *END*********************************************************************/ +void ENET_DRV_TxIRQHandler(uint32_t instance) +{ + enet_dev_if_t *enetIfPtr; + ENET_Type * base; + enetIfPtr = enetIfHandle[instance]; + + /*Check input parameter*/ + if (!enetIfPtr) + { + return; + } + + base = g_enetBase[enetIfPtr->deviceNumber]; + + /* Get interrupt status.*/ + while ((ENET_HAL_GetIntStatusFlag(base, kEnetTxFrameInterrupt)) || + (ENET_HAL_GetIntStatusFlag(base, kEnetTxByteInterrupt))) + { + /*Clear interrupt*/ + ENET_HAL_ClearIntStatusFlag(base, kEnetTxFrameInterrupt); + ENET_HAL_ClearIntStatusFlag(base, kEnetTxByteInterrupt); + + /*Clean up the transmit buffers*/ + ENET_DRV_CleanupTxBuffDescrip(enetIfPtr); + } + + /* Active the transmit buffer descriptor*/ + /* Needed for Kinetis: otherwise last packet in ring buffer may be not sent.*/ + ENET_HAL_SetTxBdActive(base); +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Calc_Crc32 + * Description: Calculate crc-32. + * This function is called by the enet_mac_add_multicast_group and + * enet_mac_leave_multicast_group. + *END*********************************************************************/ +void ENET_DRV_Calc_Crc32(uint8_t *address, uint32_t *crcValue) +{ + uint32_t crc = ENET_ORIGINAL_CRC32, count1,count2; + + if ((!address) || (!crcValue)) + { + return ; + } + + /* Calculate the CRC-32 polynomial on the multicast group address*/ + for (count1 = 0; count1 < kEnetMacAddrLen; count1++) + { + uint8_t c = address[count1]; + for (count2 = 0; count2 < kEnetCrcOffset; count2++) + { + if ((c ^ crc)& 1U) + { + crc >>= 1U; + c >>= 1U; + crc ^= ENET_CRC32_POLYNOMIC; + } + else + { + crc >>= 1U; + c >>= 1U; + } + } + } + + *crcValue = crc; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_AddMulticastGroup + * Return Value: The execution status. + * Description: ADD ENET to the specific multicast group. + * This function is used to add ENET device to specific multicast + * group and it is called by the upper TCP/IP stack. + *END*********************************************************************/ + enet_status_t ENET_DRV_AddMulticastGroup(uint32_t instance, uint8_t *address, uint32_t *hash) +{ + uint32_t crcValue; + ENET_Type * base; + + /* Check input parameters*/ + if (!address) + { + return kStatus_ENET_InvalidInput; + } + base = g_enetBase[instance]; + /* Calculate the CRC-32 polynomial on the multicast group address*/ + ENET_DRV_Calc_Crc32(address, &crcValue); + + /* Set the hash table*/ + ENET_HAL_SetMulticastAddrHash(base, crcValue, kEnetSpecialAddressEnable); + + /* Store the hash value in the right address structure*/ + *hash = (crcValue >>= 26U) & kEnetCrcMask1; + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: ENET_DRV_Leave_MulticastGroup + * Return Value: The execution status. + * Description: ENET Leave specific multicast group. + * This function is used to remove ENET device from specific multicast + * group and it is called by the upper TCP/IP stack. + *END*********************************************************************/ + enet_status_t ENET_DRV_LeaveMulticastGroup(uint32_t instance, uint8_t *address) +{ + uint32_t crcValue; + ENET_Type * base; + /* Check input parameters*/ + if (!address) + { + return kStatus_ENET_InvalidInput; + } + base = g_enetBase[instance]; + /* Calculate the CRC-32 polynomial on the multicast group address*/ + ENET_DRV_Calc_Crc32(address, &crcValue); + + /* Set the hash table*/ + ENET_HAL_SetMulticastAddrHash(base, crcValue, kEnetSpecialAddressDisable); + + return kStatus_ENET_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name: enet_mac_enqueue_buffer + * Return Value: + * Description: ENET mac enqueue buffers. + * This function is used to enqueue buffers to buffer queue. + *END*********************************************************************/ +void enet_mac_enqueue_buffer( void **queue, void *buffer) +{ + *((void **)buffer) = *queue; + *queue = buffer; +} + +/*FUNCTION**************************************************************** + * + * Function Name: enet_mac_dequeue_buffer + * Return Value: The dequeued buffer pointer + * Description: ENET mac dequeue buffers. + * This function is used to dequeue a buffer from buffer queue. + *END*********************************************************************/ +void *enet_mac_dequeue_buffer( void **queue) +{ + void *buffer = *queue; + + if (buffer) + { + *queue = *((void **)buffer); + } + + return buffer; +} + +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/enet/fsl_enet_irq.c b/KSDK_1.2.0/platform/drivers/src/enet/fsl_enet_irq.c new file mode 100755 index 0000000..5286cd5 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/enet/fsl_enet_irq.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_enet_driver.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_ENET_COUNT +/******************************************************************************* + * Variables + ******************************************************************************/ +#define ENET_INSTANCE 0U + + +/******************************************************************************* + * Code + ******************************************************************************/ +void ENET_Transmit_IRQHandler(void) +{ + ENET_DRV_TxIRQHandler(ENET_INSTANCE); +} + +void ENET_Receive_IRQHandler(void) +{ + ENET_DRV_RxIRQHandler(ENET_INSTANCE); +} + +#if FSL_FEATURE_ENET_SUPPORT_PTP +void ENET_1588_Timer_IRQHandler(void) +{ + ENET_DRV_TsIRQHandler(ENET_INSTANCE); +} +#endif +#endif +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/enet/fsl_enet_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/enet/fsl_enet_lpm_callback.c new file mode 100755 index 0000000..467f978 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/enet/fsl_enet_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_ENET_COUNT + +power_manager_error_code_t enet_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t enet_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/ewm/fsl_ewm_common.c b/KSDK_1.2.0/platform/drivers/src/ewm/fsl_ewm_common.c new file mode 100755 index 0000000..b830b0f --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/ewm/fsl_ewm_common.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for EWM instances. */ +EWM_Type * const g_ewmBase[] = EWM_BASE_PTRS; + +/*! @brief Table to save EWM IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_ewmIrqId[] = EWM_IRQS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + + diff --git a/KSDK_1.2.0/platform/drivers/src/ewm/fsl_ewm_driver.c b/KSDK_1.2.0/platform/drivers/src/ewm/fsl_ewm_driver.c new file mode 100755 index 0000000..0d57e15 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/ewm/fsl_ewm_driver.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_ewm_driver.h" +#include "fsl_interrupt_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_EWM_COUNT + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + *******************************************************************************/ + +/*FUNCTION**************************************************************** + * + * Function Name : EWM_DRV_Init + * Description : Initialize EWM + * This function is used to initialize the EWM, after called, the EWM + * will run immediately according to the configure. + * + *END*********************************************************************/ +ewm_status_t EWM_DRV_Init(uint32_t instance, const ewm_config_t* ConfigPtr) +{ + assert(instance < EWM_INSTANCE_COUNT); + EWM_Type * base; + base = g_ewmBase[instance]; + if(!ConfigPtr) + { + return kStatus_EWM_NullArgument; + } + if(ConfigPtr->intEnable) + { + INT_SYS_EnableIRQ(g_ewmIrqId[instance]); /*!< Enable EWM interrupt in NVIC level */ + } + else + { + INT_SYS_DisableIRQ(g_ewmIrqId[instance]); /*!< Disable EWM interrupt in NVIC level */ + } + CLOCK_SYS_EnableEwmClock(instance); /*!< Enable ewm clock */ + EWM_HAL_SetConfig(base, ConfigPtr); + + return kStatus_EWM_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name : EWM_DRV_Deinit + * Description : Shutdown EWM clock + * This function is used to shut down the EWM. + * + *END*********************************************************************/ +void EWM_DRV_Deinit(uint32_t instance) +{ + assert(instance < EWM_INSTANCE_COUNT); + EWM_Type * base = g_ewmBase[instance]; + EWM_HAL_SetIntCmd(base, false); + CLOCK_SYS_DisableEwmClock(instance); +} + +/*FUNCTION**************************************************************** + * + * Function Name : EWM_DRV_IsRunning + * Description : Get EWM running status + * This function is used to get the EWM running status. + * + *END*********************************************************************/ +bool EWM_DRV_IsRunning(uint32_t instance) +{ + assert(instance < EWM_INSTANCE_COUNT); + EWM_Type * base = g_ewmBase[instance]; + return EWM_HAL_IsEnable(base); +} + +/*FUNCTION**************************************************************** + * + * Function Name : EWM_DRV_Refresh + * Description : Refresh EWM counter. + * This function is used to feed the EWM, it will set the EWM timer count to zero and + * should be called before EWM timer is timeout, otherwise a EWM_out output signal will assert. + * + *END*********************************************************************/ +void EWM_DRV_Refresh(uint32_t instance) +{ + assert(instance < EWM_INSTANCE_COUNT); + EWM_Type * base; + base = g_ewmBase[instance]; + INT_SYS_DisableIRQGlobal(); + EWM_HAL_Refresh(base); + INT_SYS_EnableIRQGlobal(); +} + +/*FUNCTION********************************************************************* + * + * Function Name : EWM_DRV_SetIntCmd + * Description : Enables/disables EWM interrupt + *END*************************************************************************/ +void EWM_DRV_SetIntCmd(uint32_t instance, bool enable) +{ + EWM_Type * base; + base = g_ewmBase[instance]; + EWM_HAL_SetIntCmd(base, enable); +} + +#endif +/******************************************************************************* + * EOF + *******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/ewm/fsl_ewm_irq.c b/KSDK_1.2.0/platform/drivers/src/ewm/fsl_ewm_irq.c new file mode 100755 index 0000000..380e358 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/ewm/fsl_ewm_irq.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013 -2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_ewm_driver_test.h" +#if FSL_FEATURE_SOC_EWM_COUNT + + +/****************************************************************************** + * Code + *****************************************************************************/ + +/* EWM and Watchdog have the same IRQ handler---Watchdog_IRQHandler.*/ +/* User can define their own handler in this function */ +void WDOG_EWM_IRQHandler(void) +{ +} +#endif + +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/ewm/fsl_ewm_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/ewm/fsl_ewm_lpm_callback.c new file mode 100755 index 0000000..eade12c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/ewm/fsl_ewm_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_EWM_COUNT + +power_manager_error_code_t ewm_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t ewm_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/FSL_eNVM_FTFx_UM.pdf b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/FSL_eNVM_FTFx_UM.pdf Binary files differnew file mode 100755 index 0000000..fbae5fc --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/FSL_eNVM_FTFx_UM.pdf diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/FTFx_KX_flash_config.h b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/FTFx_KX_flash_config.h new file mode 100755 index 0000000..e4f65ea --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/FTFx_KX_flash_config.h @@ -0,0 +1,207 @@ +/************************************************************************ + (c) Copyright 2012-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +************************************************************************* + + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ + +#ifndef _FTFx_KX_flash_config_H_ +#define _FTFx_KX_flash_config_H_ + +#include "SSD_FTFx_Common.h" +#include "fsl_device_registers.h" + +/*! + * @addtogroup c90tfs_flash_driver + * @{ + */ + +/*! + * @name C90TFS Flash configuration + * @{ + */ + +/* Flash module */ +#if (FSL_FEATURE_FLASH_IS_FTFA == 1) + /*! @brief C90TFS sub-flash module is FTFA_M */ + #define FTFA_M +#endif +#if (FSL_FEATURE_FLASH_IS_FTFE == 1) + /*! @brief C90TFS sub-flash module is FTFE_M */ + #define FTFE_M +#endif + +#if (FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP == 1) + /*! Include Swap control API if the feature is available in the platform */ + #define SWAP_M +#endif + + +#if (FSL_FEATURE_FLASH_HAS_ERASE_FLASH_BLOCK_CMD == 1) + /*! @brief Include Read 1s block and erase block API if the feature is available in the platform */ + #define BLOCK_COMMANDS +#endif +/*@}*/ +/*! + * @name Address convert macros + * @{ + */ +/*! @brief Convert from byte address to word(2 bytes) address + * + * Two address types are only different in DSC devices. In Kinstis devices, they are the same + * +*/ +#define BYTE2WORD(x) (x) +/*! @brief Convert from word(2 bytes) address to byte address + * + * Two address types are only different in DSC devices. In Kinstis devices, they are the same + * + */ +#define WORD2BYTE(x) (x) +/*@}*/ + +/*! + * @name C90TFS Flash configuration + * @{ + */ +/*! @brief Endianness */ +#define ENDIANNESS LITTLE_ENDIAN + +/*! @brief CPU core */ +#define CPU_CORE ARM_CORTEX_M + +/*! @brief P-Flash sector size */ +#define FTFx_PSECTOR_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE +/*! @brief D-Flash sector size */ +#define FTFx_DSECTOR_SIZE FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE +/*! @brief FlexNVM block size */ +#define DEBLOCK_SIZE (FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SIZE * FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT) + +/* EEE Data Set Size Field Description */ +/*! @brief Emulated EEPROM size code 0000 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_0000 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0000 +/*! @brief Emulated EEPROM size code 0001 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_0001 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0001 +/*! @brief Emulated EEPROM size code 0010 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_0010 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0010 +/*! @brief Emulated EEPROM size code 0011 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_0011 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0011 +/*! @brief Emulated EEPROM size code 0100 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_0100 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0100 +/*! @brief Emulated EEPROM size code 0101 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_0101 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0101 +/*! @brief Emulated EEPROM size code 0110 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_0110 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0110 +/*! @brief Emulated EEPROM size code 0111 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_0111 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0111 +/*! @brief Emulated EEPROM size code 1000 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_1000 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1000 +/*! @brief Emulated EEPROM size code 1001 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_1001 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1001 +/*! @brief Emulated EEPROM size code 1010 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_1010 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1010 +/*! @brief Emulated EEPROM size code 1011 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_1011 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1011 +/*! @brief Emulated EEPROM size code 1100 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_1100 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1100 +/*! @brief Emulated EEPROM size code 1101 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_1101 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1101 +/*! @brief Emulated EEPROM size code 1110 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_1110 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110 +/*! @brief Emulated EEPROM size code 1111 mapping to emulated EEPROM size in bytes (0xFFFF = reserved) */ +#define EEESIZE_1111 FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111 + +/* D/E-Flash Partition Code Field Description */ +/*! @brief FlexNVM partition code 0000 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_0000 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 +/*! @brief FlexNVM partition code 0001 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_0001 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 +/*! @brief FlexNVM partition code 0010 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_0010 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 +/*! @brief FlexNVM partition code 0011 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_0011 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 +/*! @brief FlexNVM partition code 0100 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_0100 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 +/*! @brief FlexNVM partition code 0101 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_0101 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 +/*! @brief FlexNVM partition code 0110 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_0110 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 +/*! @brief FlexNVM partition code 0111 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_0111 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 +/*! @brief FlexNVM partition code 1000 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_1000 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 +/*! @brief FlexNVM partition code 1001 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_1001 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 +/*! @brief FlexNVM partition code 1010 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_1010 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 +/*! @brief FlexNVM partition code 1011 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_1011 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 +/*! @brief FlexNVM partition code 1100 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_1100 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 +/*! @brief FlexNVM partition code 1101 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_1101 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 +/*! @brief FlexNVM partition code 1110 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_1110 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 +/*! @brief FlexNVM partition code 1111 mapping to data flash size in bytes (0xFFFFFFFF = reserved) */ +#define DEPART_1111 FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 + + +/*! @brief Data flash IFR map */ +#if (FSL_FEATURE_FLASH_IS_FTFE == 1) + #define DFLASH_IFR_READRESOURCE_ADDRESS 0x8003F8U +#else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA = =1 */ + #define DFLASH_IFR_READRESOURCE_ADDRESS 0x8000FCU +#endif + +/* Size for checking alignment of a section */ +/*! @brief P-Flash Program check command address alignment */ +#define PGMCHK_ALIGN_SIZE FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT +/*! @brief P-Flash write unit size */ +#define PGM_SIZE_BYTE FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE +/*! @brief Resume wait count used in FlashResume function */ +#define RESUME_WAIT_CNT 0x20U + +/*@}*/ + +/*! @}*/ + +#endif /* _FTFx_KX_flash_config_H_ */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/SSD_FTFx.h b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/SSD_FTFx.h new file mode 100755 index 0000000..86d940d --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/SSD_FTFx.h @@ -0,0 +1,925 @@ +/**************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***************************************************************************** + + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS Flash driver + inherited from BM C90TFS Flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +#ifndef _SSD_FTFx_INTERNAL_H_ +#define _SSD_FTFx_INTERNAL_H_ + +#include "SSD_FTFx_Internal.h" + +#define FTFx_SSD_FSTAT_CCIF 0x80U +#define FTFx_SSD_FSTAT_RDCOLERR 0x40U +#define FTFx_SSD_FSTAT_ACCERR 0x20U +#define FTFx_SSD_FSTAT_FPVIOL 0x10U +#define FTFx_SSD_FSTAT_MGSTAT0 0x01U +#define FTFx_SSD_FSTAT_ERROR_BITS (FTFx_SSD_FSTAT_ACCERR \ + |FTFx_SSD_FSTAT_FPVIOL \ + |FTFx_SSD_FSTAT_MGSTAT0) + +#define FTFx_SSD_FCNFG_CCIE 0x80U +#define FTFx_SSD_FCNFG_RDCOLLIE 0x40U +#define FTFx_SSD_FCNFG_ERSAREQ 0x20U +#define FTFx_SSD_FCNFG_ERSSUSP 0x10U +#define FTFx_SSD_FCNFG_RAMRDY 0x02U +#define FTFx_SSD_FCNFG_EEERDY 0x01U + +#define FTFx_SSD_FSEC_KEYEN 0xC0U +#define FTFx_SSD_FSEC_FSLACC 0x0CU +#define FTFx_SSD_FSEC_SEC 0x03U + +/*--------------- FTFx Flash Module Memory Offset Map -----------------*/ +#if(BIG_ENDIAN == ENDIANNESS) /* Big Endian - coldfire CPU */ + /* Flash Status Register (FSTAT)*/ + #define FTFx_SSD_FSTAT_OFFSET 0x00000003U + /* Flash configuration register (FCNFG)*/ + #define FTFx_SSD_FCNFG_OFFSET 0x00000002U + /* Flash security register (FSEC) */ + #define FTFx_SSD_FSEC_OFFSET 0x00000001U + /* Flash Option Register (FOPT) */ + #define FTFx_SSD_FOPT_OFFSET 0x00000000U + /* Flash common command object registers (FCCOB0-B) */ + #define FTFx_SSD_FCCOB0_OFFSET 0x00000004U + #define FTFx_SSD_FCCOB1_OFFSET 0x00000005U + #define FTFx_SSD_FCCOB2_OFFSET 0x00000006U + #define FTFx_SSD_FCCOB3_OFFSET 0x00000007U + #define FTFx_SSD_FCCOB4_OFFSET 0x00000008U + #define FTFx_SSD_FCCOB5_OFFSET 0x00000009U + #define FTFx_SSD_FCCOB6_OFFSET 0x0000000AU + #define FTFx_SSD_FCCOB7_OFFSET 0x0000000BU + #define FTFx_SSD_FCCOB8_OFFSET 0x0000000CU + #define FTFx_SSD_FCCOB9_OFFSET 0x0000000DU + #define FTFx_SSD_FCCOBA_OFFSET 0x0000000EU + #define FTFx_SSD_FCCOBB_OFFSET 0x0000000FU + /* P-Flash protection registers (FPROT0-3) */ + #define FTFx_SSD_FPROT0_OFFSET 0x00000010U + #define FTFx_SSD_FPROT1_OFFSET 0x00000011U + #define FTFx_SSD_FPROT2_OFFSET 0x00000012U + #define FTFx_SSD_FPROT3_OFFSET 0x00000013U + /* D-Flash protection registers (FDPROT) */ + #define FTFx_SSD_FDPROT_OFFSET 0x00000014U + /* EERAM Protection Register (FEPROT) */ + #define FTFx_SSD_FEPROT_OFFSET 0x00000015U + +#else /* Little Endian - kinetis CPU + Nevis2 CPU */ + /* Flash Status Register (FSTAT)*/ + #define FTFx_SSD_FSTAT_OFFSET 0x00000000U + /* Flash configuration register (FCNFG)*/ + #define FTFx_SSD_FCNFG_OFFSET 0x00000001U + /* Flash security register (FSEC) */ + #define FTFx_SSD_FSEC_OFFSET 0x00000002U + /* Flash Option Register (FOPT) */ + #define FTFx_SSD_FOPT_OFFSET 0x00000003U + /* Flash common command object registers (FCCOB0-B) */ + #define FTFx_SSD_FCCOB0_OFFSET 0x00000007U + #define FTFx_SSD_FCCOB1_OFFSET 0x00000006U + #define FTFx_SSD_FCCOB2_OFFSET 0x00000005U + #define FTFx_SSD_FCCOB3_OFFSET 0x00000004U + #define FTFx_SSD_FCCOB4_OFFSET 0x0000000BU + #define FTFx_SSD_FCCOB5_OFFSET 0x0000000AU + #define FTFx_SSD_FCCOB6_OFFSET 0x00000009U + #define FTFx_SSD_FCCOB7_OFFSET 0x00000008U + #define FTFx_SSD_FCCOB8_OFFSET 0x0000000FU + #define FTFx_SSD_FCCOB9_OFFSET 0x0000000EU + #define FTFx_SSD_FCCOBA_OFFSET 0x0000000DU + #define FTFx_SSD_FCCOBB_OFFSET 0x0000000CU + /* P-Flash protection registers (FPROT0-3) */ + #define FTFx_SSD_FPROT0_OFFSET 0x00000013U + #define FTFx_SSD_FPROT1_OFFSET 0x00000012U + #define FTFx_SSD_FPROT2_OFFSET 0x00000011U + #define FTFx_SSD_FPROT3_OFFSET 0x00000010U + /* D-Flash protection registers (FDPROT) */ + #define FTFx_SSD_FDPROT_OFFSET 0x00000017U + /* EERAM Protection Register (FEPROT) */ + #define FTFx_SSD_FEPROT_OFFSET 0x00000016U +#endif + +/* fccob offset address to store resource code */ +#if (PGM_SIZE_BYTE == FTFx_PHRASE_SIZE) + #define RSRC_CODE_OFSSET FTFx_SSD_FCCOB4_OFFSET +#else + #define RSRC_CODE_OFSSET FTFx_SSD_FCCOB8_OFFSET +#endif + +/*------------- Flash hardware algorithm operation commands -------------*/ +#define FTFx_VERIFY_BLOCK 0x00U +#define FTFx_VERIFY_SECTION 0x01U +#define FTFx_PROGRAM_CHECK 0x02U +#define FTFx_READ_RESOURCE 0x03U +#define FTFx_PROGRAM_LONGWORD 0x06U +#define FTFx_PROGRAM_PHRASE 0x07U +#define FTFx_ERASE_BLOCK 0x08U +#define FTFx_ERASE_SECTOR 0x09U +#define FTFx_PROGRAM_SECTION 0x0BU +#define FTFx_VERIFY_ALL_BLOCK 0x40U +#define FTFx_READ_ONCE 0x41U +#define FTFx_PROGRAM_ONCE 0x43U +#define FTFx_ERASE_ALL_BLOCK 0x44U +#define FTFx_SECURITY_BY_PASS 0x45U +#define FTFx_PFLASH_SWAP 0x46U +#define FTFx_PROGRAM_PARTITION 0x80U +#define FTFx_SET_EERAM 0x81U + + + +/* EERAM Function Control Code */ +#define EEE_ENABLE 0x00U +#define EEE_DISABLE 0xFFU + +/*! + * @addtogroup c90tfs_flash_driver + * @{ + */ + +/*! + * @name PFlash swap control codes + * @{ + */ +/*! @brief Initialize Swap System control code */ +#define FTFx_SWAP_SET_INDICATOR_ADDR 0x01U +/*! @brief Set Swap in Update State */ +#define FTFx_SWAP_SET_IN_PREPARE 0x02U +/*! @brief Set Swap in Complete State */ +#define FTFx_SWAP_SET_IN_COMPLETE 0x04U +/*! @brief Report Swap Status */ +#define FTFx_SWAP_REPORT_STATUS 0x08U + +/*@}*/ + +/*! + * @name PFlash swap states + * @{ + */ +/*! @brief Uninitialized swap mode */ +#define FTFx_SWAP_UNINIT 0x00U +/*! @brief Ready swap mode */ +#define FTFx_SWAP_READY 0x01U +/*! @brief Update swap mode */ +#define FTFx_SWAP_UPDATE 0x02U +/*! @brief Update-Erased swap mode */ +#define FTFx_SWAP_UPDATE_ERASED 0x03U +/*! @brief Complete swap mode */ +#define FTFx_SWAP_COMPLETE 0x04U + +/*@}*/ + +/*------------------- Setting Flash interrupt macro --------------------*/ +/*! +* @brief Sets the Flash interrupt enable bits in the FCNFG register. +* +* @param ftfxRegBase: Specifies register base address of the Flash module +* @param value: The bit map value ( 0: disabled, 1 enabled) . +* The numbering is marked from 0 to 7 where bit 0 +* is the least significant bit. Bit 7 is corresponding +* to command complete interrupt. Bit 6 is corresponding +* to read collision error interrupt. +*/ +#define SET_FLASH_INT_BITS(ftfxRegBase, value) REG_WRITE((ftfxRegBase) + FTFx_SSD_FCNFG_OFFSET,\ + ((value)&(FTFx_SSD_FCNFG_CCIE | FTFx_SSD_FCNFG_RDCOLLIE))) +/*! +* @brief Returns the Flash interrupt enable bits in the FCNFG register. +* +* @param ftfxRegBase: Specifies register base address of the Flash module. +*/ +#define GET_FLASH_INT_BITS(ftfxRegBase) REG_READ((ftfxRegBase) + FTFx_SSD_FCNFG_OFFSET) &\ + (FTFx_SSD_FCNFG_CCIE | FTFx_SSD_FCNFG_RDCOLLIE) + +/*! + * @name C90TFS Flash driver APIs + * @{ + */ + +/*---------------- Function Prototypes for Flash SSD --------------------*/ +/*! + * @brief Relocates a function to RAM address. + * + * This function provides a facility to relocate a function in RAM. + * + * @param dest: Destination address where you want to place the function. + * @param size: Size of the function + * @param src: Address of the function will be relocated + * @return Relocated address of the function . + */ +extern uint32_t RelocateFunction(uint32_t dest, uint32_t size, uint32_t src); +/*! + * @brief Initializes Flash. + * + * This API initializes Flash module by clearing status error + * bit and reporting the memory configuration via SSD configuration structure. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @return Successful completion (FTFx_OK) + */ +extern uint32_t FlashInit(PFLASH_SSD_CONFIG pSSDConfig); + +/*! + * @brief Flash command sequence. + * + * This API is used to perform command write sequence on Flash. + * It is internal function, called by driver APIs only. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @return Successful completion (FTFx_OK) + * @return Failed in Flash command execution (FTFx_ERR_ACCERR, FTFx_ERR_PVIOL, + * FTFx_ERR_MGSTAT0) + */ +extern uint32_t FlashCommandSequence(PFLASH_SSD_CONFIG pSSDConfig); +/*! + * @brief P-Flash get protection. + * + * This API retrieves the current P-Flash protection status. Considering + * the time consumption for getting protection is very low and even can + * be ignored. It is not necessary to utilize the Callback function to + * support the time-critical events. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param protectStatus: To return the current value of the P-Flash Protection. + * Each bit is corresponding + * to protection of 1/32 of the total P-Flash. The least + * significant bit is corresponding to the lowest + * address area of P-Flash. The most significant bit + * is corresponding to the highest address area of P- + * Flash and so on. There are two possible cases as below: + * - 0: this area is protected. + * - 1: this area is unprotected. + * @return Successful completion (FTFx_OK) + */ +extern uint32_t PFlashGetProtection(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t* protectStatus); + +/*! + * @brief P-Flash set protection. + * + * This API sets the P-Flash protection to the intended protection status. + * Setting P-Flash protection status is subject to a protection transition + * restriction. If there is a setting violation, it returns + * an error code and the current protection status won’t be changed. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param protectStatus: The expected protect status user wants to set to + * P-Flash protection register. Each bit is corresponding + * to protection of 1/32 of the total P-Flash. The least + * significant bit is corresponding to the lowest + * address area of P-Flash. The most significant bit + * is corresponding to the highest address area of P- + * Flash, and so on. There are two possible cases as shown below: + * - 0: this area is protected. + * - 1: this area is unprotected. + * @return Successful completion (FTFx_OK ) + * @return Error value (FTFx_ERR_CHANGEPROT) + */ +extern uint32_t PFlashSetProtection(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t protectStatus); + +/*! + * @brief Flash get security state. + * + * This API retrieves the current Flash security status, including + * the security enabling state and the back door key enabling state. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param securityState: To return the current security status code. + * FLASH_NOT_SECURE (0x01): Flash currently not in secure state; + * FLASH_SECURE_BACKDOOR_ENABLED (0x02): Flash is secured and + * back door key access enabled; + * FLASH_SECURE_BACKDOOR_DISABLED (0x04): Flash is secured and + * back door key access disabled. + * @return Successful completion (FTFx_OK) + */ +extern uint32_t FlashGetSecurityState(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t* securityState); +/*! + * @brief Flash security bypass. + * + * This API un-secures the device by comparing the user's provided back + * door key with the ones in the Flash Configuration Field. If they are + * matched, the security is released. Otherwise, an + * error code is returned. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param keyBuffer: Point to the user buffer containing the back door key. + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_ACCERR) + */ +extern uint32_t FlashSecurityBypass(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t* keyBuffer, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! + * @brief Flash erase all Blocks. + * + * This API erases all Flash memory, initializes the FlexRAM, verifies + * all memory contents, and then releases the MCU security. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_PVIOL, FTFx_ERR_MGSTAT0, FTFx_ERR_ACCERR) + */ +extern uint32_t FlashEraseAllBlock(PFLASH_SSD_CONFIG pSSDConfig, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! + * @brief Flash verify all Blocks. + * + * This function checks to see if the P-Flash and/or D-Flash, EEPROM + * backup area, and D-Flash IFR have been erased to the specified read + * margin level, if applicable, and releases security if the readout passes. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param marginLevel: Read Margin Choice as follows: + * marginLevel = 0x0: use the Normal read level + * marginLevel = 0x1: use the User read + * marginLevel = 0x2: use the Factory read + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_MGSTAT0, FTFx_ERR_ACCERR) + */ +extern uint32_t FlashVerifyAllBlock(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t marginLevel, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! + * @brief Flash erase sector. + * + * This API erases one or more sectors in P-Flash or D-Flash memory. + * This API always returns FTFx_OK if size provided by the user is + * zero regardless of the input validation. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param dest: Address in the first sector to be erased. + * @param size: Size to be erased in bytes. It is used to determine + * number of sectors to be erased. + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_MGSTAT0, FTFx_ERR_ACCERR, FTFx_ERR_PVIOL,FTFx_ERR_SIZE) + */ +extern uint32_t FlashEraseSector(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! + * @brief Flash verify sector. + * + * This API checks if a section of the P-Flash or the D-Flash memory + * is erased to the specified read margin level. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param dest: Start address for the intended verify operation. + * @param number: Number of alignment unit to be verified. Refer to + * corresponding reference manual to get correct + * information of alignment constrain. + * @param marginLevel: Read Margin Choice as follows: + * marginLevel = 0x0: use Normal read level + * marginLevel = 0x1: use the User read + * marginLevel = 0x2: use the Factory read + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_MGSTAT0, FTFx_ERR_ACCERR) + */ +extern uint32_t FlashVerifySection(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint16_t number, \ + uint8_t marginLevel, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! + * @brief Flash erase suspend. + * + * This API is used to suspend a current operation of Flash erase sector command. + * This function must be located in RAM memory or different Flash blocks which are + * targeted for writing to avoid the RWW error. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @return Successful completion (FTFx_OK) + */ +extern uint32_t FlashEraseSuspend(PFLASH_SSD_CONFIG pSSDConfig); +/*! + * @brief Flash erase resume. + * + * This API is used to resume a previous suspended operation of Flash erase sector command + * This function must be located in RAM memory or different Flash blocks which are targeted + * for writing to avoid RWW error. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @return Successful completion (FTFx_OK) + */ +extern uint32_t FlashEraseResume(PFLASH_SSD_CONFIG pSSDConfig); +/*! + * @brief Flash read once. + * + * This API is used to read out a reserved 64 byte field located in the P-Flash IFR via given number + * of record. See the corresponding reference manual to get the correct value of this number. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param recordIndex: The record index will be read. It can be from 0x0 + * to 0x7 or from 0x0 to 0xF according to specific derivative. + * @param pDataArray: Pointer to the array to return the data read by the read once command. + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_ACCERR) + */ +extern uint32_t FlashReadOnce(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t recordIndex,\ + uint8_t* pDataArray, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! + * @brief Flash program once. + * + * This API is used to program to a reserved 64 byte field located in the + * P-Flash IFR via given number of record. See the corresponding reference manual + * to get correct value of this number. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param recordIndex: The record index will be read. It can be from 0x0 + * to 0x7 or from 0x0 to 0xF according to specific derivative. + * @param pDataArray: Pointer to the array from which data will be + * taken for program once command. + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_ACCERR,FTFx_ERR_MGSTAT0) + */ +extern uint32_t FlashProgramOnce(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t recordIndex,\ + uint8_t* pDataArray, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! + * @brief Flash read resource. + * + * This API is used to read data from special purpose memory in Flash memory module + * including P-Flash IFR, swap IFR, D-Flash IFR space and version ID. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param dest: Start address for the intended read operation. + * @param pDataArray: Pointer to the data returned by the read resource command. + * @param resourceSelectCode: Read resource select code: + * 0 : Flash IFR + * 1: Version ID + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_ACCERR) + */ +extern uint32_t FlashReadResource(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint8_t* pDataArray, \ + uint8_t resourceSelectCode, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! + * @brief Flash program + * + * This API is used to program 4 consecutive bytes (for program long + * word command) and 8 consecutive bytes (for program phrase command) on + * P-Flash or D-Flash block. This API always returns FTFx_OK if size + * provided by user is zero regardless of the input validation + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param dest: Start address for the intended program operation. + * @param size: Size in byte to be programmed + * @param pData: Pointer of source address from which data has to + * be taken for program operation. + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_ACCERR, FTFx_ERR_PVIOL, FTFx_ERR_SIZE, FTFx_ERR_MGSTAT0) + */ +extern uint32_t FlashProgram(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + uint8_t* pData, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! + * @brief Flash program check + * + * This API tests a previously programmed P-Flash or D-Flash long word + * to see if it reads correctly at the specified margin level. This + * API always returns FTFx_OK if size provided by user is zero + * regardless of the input validation + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param dest: Start address for the intended program check operation. + * @param size: Size in byte to check accuracy of program operation + * @param pExpectedData: The pointer to the expected data. + * @param pFailAddr: Returned the first aligned failing address. + * @param marginLevel: Read margin choice as follows: + * marginLevel = 0x1: read at User margin 1/0 level. + * marginLevel = 0x2: read at Factory margin 1/0 level. + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_ACCERR, FTFx_ERR_MGSTAT0) + */ +extern uint32_t FlashProgramCheck(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + uint8_t* pExpectedData, \ + uint32_t* pFailAddr, \ + uint8_t marginLevel, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! + * @brief Calculates check sum. + * + * This API performs 32 bit sum of each byte data over a specified Flash + * memory range without carry which provides rapid method for checking data integrity. + * The callback time period of this API is determined via FLASH_CALLBACK_CS macro in the + * SSD_FTFx_Common.h which is used as a counter value for the CallBack() function calling in + * this API. This value can be changed as per the user requirement. User can change this value to + * obtain the maximum permissible callback time period. + * This API always returns FTFx_OK if size provided by user is zero regardless of the input + * validation. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param dest: Start address of the Flash range to be summed + * @param size: Size in byte of the Flash range to be summed + * @param pSum: To return the sum value + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_RANGE) + */ +extern uint32_t FlashCheckSum(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + uint32_t* pSum); + +#ifndef FTFA_M +/*! + * @brief Flash program section + * + * This API will program the data found in the Section Program Buffer + * to previously erased locations in the Flash memory. Data is preloaded into + * the Section Program Buffer by writing to the acceleration Ram and FlexRam + * while it is set to function as a RAM. The Section Program Buffer is limited + * to the value of FlexRam divides by a ratio. Refer to the associate reference + * manual to get correct value of this ratio. + * For derivatives including swap feature, the swap indicator address is encountered + * during FlashProgramSection, it is bypassed without setting FPVIOL but the content + * are not be programmed. In addition, the content of source data used to program to + * swap indicator will be re-initialized to 0xFF after completion of this command. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param dest: Start address for the intended program operation. + * @param number: Number of alignment unit to be programmed. Refer to associate + * reference manual to get correct value of this alignment constrain. + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_ACCERR, FTFx_ERR_PVIOL, FTFx_ERR_MGSTAT0, FTFx_ERR_RAMRDY) + */ +extern uint32_t FlashProgramSection(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint16_t number, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +#endif + +#if (!(defined(FTFA_M)) || (defined(BLOCK_COMMANDS))) +/*! + * @brief Flash erase block + * + * This API erases all addresses in an individual P-Flash or D-Flash block. + * For the derivatives including multiply logical P-Flash or D-Flash blocks, + * this API erases a single block in a single call. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param dest: Start address for the intended erase operation. + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_ACCERR, FTFx_ERR_PVIOL, FTFx_ERR_MGSTAT0) + */ +extern uint32_t FlashEraseBlock(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! + * @brief Flash verify block + * + * This API checks to see if an entire P-Flash or D-Flash block has been + * erased to the specified margin level + * For the derivatives including multiply logical P-Flash or D-Flash blocks, + * this API erases a single block in a single call. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param dest: Start address for the intended verify operation. + * @param marginLevel: Read Margin Choice as follows: + * marginLevel = 0x0: use Normal read level + * marginLevel = 0x1: use the User read + * marginLevel = 0x2: use the Factory read + * @param pFlashCommandSequence : Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_ACCERR, FTFx_ERR_MGSTAT0) + */ +extern uint32_t FlashVerifyBlock(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint8_t marginLevel, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +#endif + +#if (DEBLOCK_SIZE != 0x0U) +/*! + * @brief EERAM get protection + * + * This API retrieves which EEPROM sections of FlexRAM are protected + * against program and erase operations. Considering the time consumption + * for getting protection is very low and even can be ignored, it is not necessary + * to utilize the Callback function to support the time-critical events + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param protectStatus: To return the current value of the EEPROM + * Protection Register. Each bit is corresponding to + * protection status of 1/8 of the total EEPROM + * use. The least significant bit is corresponding to + * the lowest address area of EEPROM. The most + * significant bit is corresponding to the highest + * address area of EEPROM and so on. There are + * two possible cases as below: + * - 0: this area is protected. + * - 1: this area is unprotected. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_NOEEE) + */ +extern uint32_t EERAMGetProtection(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t* protectStatus); +/*! + * @brief EERAM set protection + * + * This API sets protection to the intended protection status for EEPROM us + * area of FlexRam. This is subject to a protection transition restriction. + * If there is a setting violation, it returns failed information and + * the current protection status won’t be changed. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param protectStatus: The intended protection status value should be + * written to the EEPROM Protection Register. + * Each bit is corresponding to + * protection status of 1/8 of the total EEPROM + * use. The least significant bit is corresponding to + * the lowest address area of EEPROM. The most + * significant bit is corresponding to the highest + * address area of EEPROM and so on. There are + * two possible cases as below: + * - 0: this area is protected. + * - 1: this area is unprotected. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_NOEEE,FTFx_ERR_CHANGEPROT) + */ +extern uint32_t EERAMSetProtection(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t protectStatus); +/*! + * @brief Flash Set EEEEnable + * + * This function is used to change the function of the FlexRAM. When not + * partitioned for EEPROM backup, the FlexRam is typically used as traditional + * RAM. Otherwise, the FlexRam is typically used to store EEPROM data and user + * can use this API to change its functionality according to his application requirement. + * For example, after partitioning to have EEPROM backup, FlexRAM is used for EEPROM + * use accordingly. And this API is used to set FlexRAM is available for + * traditional RAM for FlashProgramSection() use. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param EEEEnable: FlexRam function control code. It can be: + * - 0xFF: make FlexRam available for RAM. + * - 0x00: make FlexRam available for EEPROM. + * @param pFlashCommandSequence: Pointer to the Flash command sequence function. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_ACCERR) + */ +extern uint32_t SetEEEEnable(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t EEEEnable,pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! + * @brief EEPROM Emulator Write + * + * This API is used to write data to FlexRAM section which is partitioned + * as EEPROM use for EEPROM operation. After data has been written to EEPROM + * use section of FlexRAM, the EEPROM file system will create new data record + * in EEPROM back-up area of FlexNVM in round-robin fashion. + * There is no alignment constraint for destination and size parameters + * provided by user. However, according to user’s input provided, this + * API will set priority to write to FlexRAM with following rules: + * 32-bit writing is invoked if destination is 32 bit aligned and size + * is not less than 32 bits. + * 16-bit writing is invoked if destination is 16 bit aligned and size + * is not less than 16 bits. + * 8-bit writing is invoked if destination is 8 bit aligned and size is not less than 8 bits. + * + * @param pSSDConfig: The SSD configuration structure pointer. + * @param dest: Start address for the intended write operation. + * @param size: Size in byte to be written. + * @param pData: Pointer to source address from which data + * has to be taken for writing operation. + * @return Successful completion (FTFx_OK) + * @return Error value (FTFx_ERR_RANGE, FTFx_ERR_NOEEE, FTFx_ERR_PVIOL) + */ +extern uint32_t EEEWrite(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + uint8_t* pData); +/*! + * @brief Flash D/E-Flash Partition. + * + * This API prepares the FlexNVM block for use as D-Flash, EEPROM backup, or a combination + * of both and initializes the FlexRAM. + * + * The single partition choice should be used through entire life time of a given + * application to guarantee the Flash endurance and data retention of Flash module. + * + * @param pSSDConfig The SSD configuration structure pointer + * @param EEEDataSizeCode EEPROM Data Size Code + * @param DEPartitionCode FlexNVM Partition Code + * @param pFlashCommandSequence Pointer to the Flash command sequence function. + * + * @return Successful completion(FTFx_OK) + * @return Error value(FTFx_ERR_ACCERR, FTFx_ERR_MGSTAT0) + */ + +extern uint32_t DEFlashPartition(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t EEEDataSizeCode, \ + uint8_t DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! + * @brief D-Flash get protection. + * + * This API retrieves current P-Flash protection status. Considering the time consumption + * for getting protection is very low and even can be ignored, it is not necessary to utilize + * the Callback function to support the time-critical events. + * + * @param pSSDConfig The SSD configuration structure pointer + * @param protectStatus To return the current value of the D-Flash Protection + * Register. Each bit is corresponding to protection status + * of 1/8 of the total D-Flash. The least significant bit is + * corresponding to the lowest address area of D-Flash. The + * most significant bit is corresponding to the highest address + * area of D-Flash and so on. There are two possible cases as below: + * - 0 : this area is protected. + * - 1 : this area is unprotected. + * + * @return Successful completion(FTFx_OK) + * @return Error value(FTFx_ERR_EFLASHONLY) + */ +extern uint32_t DFlashGetProtection(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t* protectStatus); + +/*! + * @brief D-Flash set protection. + * + * This API sets the D-Flash protection to the intended protection status. Setting D-Flash + * protection status is subject to a protection transition restriction. If there is a setting + * violation, it returns failed information and the current protection status won’t be changed. + * + * @param pSSDConfig The SSD configuration structure pointer + * @param protectStatus The expected protect status user wants to set to D-Flash Protection + * Register. Each bit is corresponding to protection status + * of 1/8 of the total D-Flash. The least significant bit is + * corresponding to the lowest address area of D-Flash. The + * most significant bit is corresponding to the highest address + * area of D-Flash and so on. There are two possible cases as below: + * - 0 : this area is protected. + * - 1 : this area is unprotected. + * + * @return Successful completion(FTFx_OK) + * @return Error value(FTFx_ERR_EFLASHONLY,FTFx_ERR_CHANGEPROT) + */ +extern uint32_t DFlashSetProtection(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t protectStatus); +#endif /* End of DEBLOCK_SIZE */ + +#ifdef SWAP_M +/*! + * @brief Swaps between the two halves of the total logical P-Flash memory blocks in the memory map. + * + * The swap API provides to user with an ability to interfere in a swap progress by letting the + * user code know about the swap state in each phase of the process. This is done via pSwapCallBack() + * parameter. To stop at each intermediate swap state, set the return value of + * this callback function to FALSE. To complete swap process within a single call, + * set the return value of this function to TRUE. + * + * Erase the non-active swap indicator somewhere in the + * application code or in the swap call back function when swap system is in UPDATE state. + * + * In addition, if user does not want to use the swap call back parameter, pass the NULL_SWAP_CALLBACK + * as a null pointer. In this situation, the PFlashSwap() behaves in the same way as setting the return + * value of pSwapCallBack to TRUE and the user does not need to erase the non-active swap + * indicator when the swap system is in UPDATE state. + * + * Below is an example to show how to implement a swap callback: + * @code + * bool PFlashSwapCallback(uint8_t currentSwapMode) + * { + * switch (currentSwapMode) + * { + * case FTFx_SWAP_UNINI: + * // Put your application-specific code here + * break; + * case FTFx_SWAP_READY: + * // Put your application-specific code here + * break; + * case FTFx_SWAP_UPDATE: + * // Put your application-specific code here (example: erase non-active swap indicator here) + * break; + * case FTFx_SWAP_UPDATE_ERASED: + * // Put your application-specific code here (example: erase non-active swap indicator here) + * break; + * case FTFx_SWAP_COMPLETE: + * // Put your application-specific code here + * break; + * default: + * break; + * } + * return TRUE; // Return FALSE to stop at intermediate swap state + *} + * @endcode + * The swap indicator provided by the user must be within the lower half of P-Flash block but not in the + * Flash configuration area. If P-Flash block has two logical blocks, the swap indicator must be + * in P-Flash block 0. If the P-Flash block has four logical blocks, the swap indicator can be in block + * 0 or block 1. It must not be in the Flash configuration field. + * The user must use the same swap indicator for all swap control code except report swap status once + * swap system has been initialized. To refresh swap system to un-initialization state, + * use the FlashEraseAllBlock() to clean up the swap environment. + * + * @param pSSDConfig The SSD configuration structure pointer + * @param addr Address of swap indicator. + * @param pSwapCallback Callback to do specific task while the swapping is being performed + * @param pFlashCommandSequence Pointer to the Flash command sequence function. + * + * @return Successful completion(FTFx_OK) + * @return Error value(FTFx_ERR_ACCERR,FTFx_ERR_MGSTAT0) + */ +extern uint32_t PFlashSwap(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t addr, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! + * @brief Implements swap control command corresponding with the swap control code provided via the swapcmd parameter. + * + * @param pSSDConfig The SSD configuration structure pointer + * @param addr Address of swap indicator. + * @param swapcmd Swap Control Code: + * 0x01 - Initialize Swap System + * 0x02 - Set Swap in Update State + * 0x04 - Set Swap in Complete Stat + * 0x08 - Report Swap Status + * @param pCurrentSwapMode Current Swap Mode: + * 0x00 - Uninitialized + * 0x01 - Ready + * 0x02 - Update + * 0x03 - Update-Erased + * 0x04 - Complete + * @param pCurrentSwapBlockStatus Current Swap Block Status indicates which program Flash block + * is currently located at relative Flash address 0x0_0000 + * 0x00 - Program Flash block 0 + * 0x01 - Program Flash block 1 + * @param pNextSwapBlockStatus Next Swap Block Status indicates which program Flash block + * is located at relative Flash address 0x0_0000 after the next reset. + * 0x00 - Program Flash block 0 + * 0x01 - Program Flash block 1 + * @param pFlashCommandSequence Pointer to the Flash command sequence function. + * + * @return Successful completion(FTFx_OK) + * @return Error value(FTFx_ERR_ACCERR,FTFx_ERR_MGSTAT0) + */ +extern uint32_t PFlashSwapCtl(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t addr, \ + uint8_t swapcmd, \ + uint8_t* pCurrentSwapMode,\ + uint8_t* pCurrentSwapBlockStatus, \ + uint8_t* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +#endif /* End of SWAP_M */ +/*@}*/ + +/*! @}*/ +#endif /* _SSD_FTFx_INTERNAL_H_ */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/SSD_FTFx_Common.h b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/SSD_FTFx_Common.h new file mode 100755 index 0000000..5defe03 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/SSD_FTFx_Common.h @@ -0,0 +1,270 @@ +/**************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +#ifndef _SSD_FTFx_COMMON_H_ +#define _SSD_FTFx_COMMON_H_ + +#include "SSD_Types.h" + +/* Endianness */ +#define BIG_ENDIAN 0 /* Big Endian */ +#define LITTLE_ENDIAN 1 /* Little Endian */ + +/* cpu cores */ +#define COLDFIRE 0 /* ColdFire core */ +#define ARM_CORTEX_M 1 /* ARM Cortex M4 core M0 core*/ +#define DSC_56800EX 2 /* 32 bit DSC core */ + +/* Word size */ +#define FTFx_WORD_SIZE 0x0002U /* 2 bytes */ + +/* Longword size */ +#define FTFx_LONGWORD_SIZE 0x0004U /* 4 bytes */ + +/* Phrase size */ +#define FTFx_PHRASE_SIZE 0x0008U /* 8 bytes */ + +/* Double-phrase size */ +#define FTFx_DPHRASE_SIZE 0x0010U /* 16 bytes */ + +/* Flash security status */ +#define FLASH_SECURITY_STATE_KEYEN 0x80U +#define FLASH_SECURITY_STATE_UNSECURED 0x02U + +/*! + * @addtogroup c90tfs_flash_driver + * @{ + */ + +/*------------ Return Code Definition for FTFx SSD ---------------------*/ +/*! + * @name Return Code Definition for FTFx SSD + * @{ + */ +/*! @brief Function executes successfully */ +#define FTFx_OK 0x0000U +/*!@brief MGSTAT0 bit is set in the FSTAT register +* +* Possible causes: +* +* MGSTAT0 bit in FSTAT register is set. Refer to corresponding command description +* of each API on reference manual to get detail reasons +* +* Solution: +* +* Hardware error +* +*/ +#define FTFx_ERR_MGSTAT0 0x0001U +/*! @brief Protection violation is set in FSTAT register +* +* Possible causes: +* +* FPVIOL bit in FSTAT register is set. Refer to corresponding command description +* of each API on reference manual to get detail reasons +* +* Solution: +* +* The flash location targeted to program/erase operation must be unprotected. Swap +* indicator must not be programmed/erased except in Update or Update-Erase state. +* +*/ +#define FTFx_ERR_PVIOL 0x0010U +/*! @brief Access error is set in the FSTAT register +* +* Possible causes: +* +* ACCERR bit in FSTAT register is set. Refer to corresponding command description +* of each API on reference manual to get detail reasons. +* +* Solution: +* +* Provide valid input parameters for each API according to specific flash module. +* +*/ +#define FTFx_ERR_ACCERR 0x0020U +/*! @brief Cannot change protection status +* +* Possible causes: +* +* Violates protection transition. +* +* Solution: +* +* In NVM normal mode, protection size cannot be decreased. Therefore, the only increasing +* protection size is permitted if the device is operating in this mode. +* +*/ +#define FTFx_ERR_CHANGEPROT 0x0100U +/*! @brief FlexRAM is not set for EEPROM use +* +* Possible causes: +* +* User accesses to EEPROM operation but there is no EEPROM backup enabled. +* +* Solution: +* +* Need to enable EEPROM by partitioning FlexNVM to have EEPROM backup and/or +* enable it by SetEEEnable API. +* +*/ +#define FTFx_ERR_NOEEE 0x0200U +/*! @brief FlexNVM is set for full EEPROM backup +* +* Possible causes: +* +* User accesses to D-Flash operation but there is no D-Flash on FlexNVM. +* +* Solution: +* +* Need to partition FlexNVM to have D-Flash. +* +*/ +#define FTFx_ERR_EFLASHONLY 0x0400U +/*! @brief Programming acceleration RAM is not available +* +* Possible causes: +* +* User invokes flash program section command but FlexRam is being set for EEPROM emulation. +* +* Solution: +* +* Need to set FlexRam as traditional Ram by SetEEEnable API. +* +*/ +#define FTFx_ERR_RAMRDY 0x0800U +/*! @brief Address is out of the valid range +* +* Possible causes: +* +* The size or destination provided by user makes start address or end address +* out of valid range. +* +* Solution: +* +* Make sure the destination and (destination + size) within valid address range. +* +*/ +#define FTFx_ERR_RANGE 0x1000U +/*! @brief Misaligned size +* +* Possible causes: +* +* The size provided by user is misaligned. +* +* Solution: +* +* Size must be an aligned value according to specific constrain of each API. +* +*/ +#define FTFx_ERR_SIZE 0x2000U +/*@}*/ + +/*! + * @name Flash security status + * @{ + */ +/*! @brief Flash currently not in secure state */ +#define FLASH_NOT_SECURE 0x01U +/*! @brief Flash is secured and backdoor key access enabled */ +#define FLASH_SECURE_BACKDOOR_ENABLED 0x02U +/*! @brief Flash is secured and backdoor key access disabled */ +#define FLASH_SECURE_BACKDOOR_DISABLED 0x04U +/*@}*/ + +/*! @}*/ +/*-------------- Read/Write/Set/Clear Operation Macros -----------------*/ +#define REG_BIT_SET(address, mask) (*(vuint8_t*)(address) |= (mask)) +#define REG_BIT_CLEAR(address, mask) (*(vuint8_t*)(address) &= ~(mask)) +#define REG_BIT_GET(address, mask) (*(vuint8_t *)(address) & (uint8_t)(mask)) +#define REG_WRITE(address, value) (*(vuint8_t*)(address) = (value)) +#define REG_READ(address) ((uint8_t)(*(vuint8_t*)(address))) +#define REG_WRITE32(address, value) (*(vuint32_t*)(address) = (value)) +#define REG_READ32(address) ((uint32_t)(*(vuint32_t*)(address))) +#define WRITE8(address, value) (*(vuint8_t*)(address) = (value)) +#define READ8(address) ((uint8_t)(*(vuint8_t*)(address))) +#define SET8(address, value) (*(vuint8_t*)(address) |= (value)) +#define CLEAR8(address, value) (*(vuint8_t*)(address) &= ~(value)) +#define TEST8(address, value) (*(vuint8_t*)(address) & (value)) + +#define WRITE16(address, value) (*(vuint16_t*)(address) = (value)) +#define READ16(address) ((uint16_t)(*(vuint16_t*)(address))) +#define SET16(address, value) (*(vuint16_t*)(address) |= (value)) +#define CLEAR16(address, value) (*(vuint16_t*)(address) &= ~(value)) +#define TEST16(address, value) (*(vuint16_t*)(address) & (value)) + +#define WRITE32(address, value) (*(vuint32_t*)(address) = (value)) +#define READ32(address) ((uint32_t)(*(vuint32_t*)(address))) +#define SET32(address, value) (*(vuint32_t*)(address) |= (value)) +#define CLEAR32(address, value) (*(vuint32_t*)(address) &= ~(value)) +#define TEST32(address, value) (*(vuint32_t*)(address) & (value)) +#define GET_BIT_0_7(value) ((uint8_t)((value) & 0xFFU)) +#define GET_BIT_8_15(value) ((uint8_t)(((value)>>8) & 0xFFU)) +#define GET_BIT_16_23(value) ((uint8_t)(((value)>>16) & 0xFFU)) +#define GET_BIT_24_31(value) ((uint8_t)((value)>>24)) + +/*--------------------- CallBack function period -----------------------*/ +#ifndef FLASH_CALLBACK_CS +#define FLASH_CALLBACK_CS 0x0AU /* Check Sum */ +#endif + +/*! + * @addtogroup c90tfs_flash_driver + * @{ + */ +/*--------------------Null Callback function definition ----------------*/ +/*! + * @name Null Callback function definition + * @{ + */ +/*! @brief Null callback */ +#define NULL_CALLBACK ((PCALLBACK)0xFFFFFFFF) +/*! @brief Null swap callback */ +#define NULL_SWAP_CALLBACK ((PFLASH_SWAP_CALLBACK)0xFFFFFFFF) +/*@}*/ + +/*! @}*/ + +#endif /* _SSD_FTFx_COMMON_H_ */ + diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/SSD_FTFx_Internal.h b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/SSD_FTFx_Internal.h new file mode 100755 index 0000000..cbfb178 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/SSD_FTFx_Internal.h @@ -0,0 +1,99 @@ +/**************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***************************************************************************** + + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +#ifndef _SSD_FTFx_H_ +#define _SSD_FTFx_H_ + +#include "SSD_FTFx_Common.h" + +#include "FTFx_KX_flash_config.h" + + +#ifndef C90TFS_ENABLE_DEBUG + #define C90TFS_ENABLE_DEBUG 0 +#endif + +/* determine offset value for copy FlashLaunchCommand */ +#if ((CPU_CORE == COLDFIRE)||(CPU_CORE == DSC_56800EX)) +#define LAUNCH_COMMAND_OFFSET 0x0U /* coldfile core dont need to shift address */ +#else +#define LAUNCH_COMMAND_OFFSET 0x01U /* other cores need to shift address by 1 before copying */ +#endif + +/* This macros is used for copy command sequence feature*/ +#if (CPU_CORE == DSC_56800EX) + #define PGM2DATA(x) ((x>PROGRAM_RAM_SPACE_BASE)?(x-PROGRAM_RAM_SPACE_BASE + DATA_SPACE_BASE):(x + DATA_SPACE_BASE)) + #define DATA2PGM(x) (x+PROGRAM_RAM_SPACE_BASE) +#else + #define PGM2DATA(x) (x) + #define DATA2PGM(x) (x) +#endif + +/* Enter debug mode macro */ +#if (CPU_CORE == ARM_CORTEX_M) + /* CW10, IAR */ + #if ((defined __ICCARM__) || (defined __GNUC__)) + #define ENTER_DEBUG_MODE asm ("BKPT #0" ) + /* KIEL */ + #elif (defined __ARMCC_VERSION) + #define ENTER_DEBUG_MODE __asm ("BKPT #0" ) + #endif +#endif +#if (CPU_CORE == DSC_56800EX) + #define ENTER_DEBUG_MODE asm ( debughlt) +#endif +#if (CPU_CORE == COLDFIRE) + #define ENTER_DEBUG_MODE asm ( HALT ) +#endif + +#if ((defined __GNUC__) && (CPU_CORE == ARM_CORTEX_M)) + #define SIZE_OPTIMIZATION __attribute__((optimize("O4"))) +#else + #define SIZE_OPTIMIZATION +#endif + +#endif /* _SSD_FTFx_H_ */ + + diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/SSD_Types.h b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/SSD_Types.h new file mode 100755 index 0000000..fd3c8ee --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/include/SSD_Types.h @@ -0,0 +1,277 @@ +/**************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***************************************************************************** + + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ + +#ifndef _SSD_TYPES_H_ +#define _SSD_TYPES_H_ + + +#ifndef FALSE +#define FALSE 0x0U +#endif + +#ifndef TRUE +#define TRUE 0x01U +#endif + +#include <stdint.h> +#include <stdbool.h> + +typedef volatile signed char vint8_t; +typedef volatile unsigned char vuint8_t; +typedef volatile signed short vint16_t; +typedef volatile unsigned short vuint16_t; +typedef volatile signed long vint32_t; +typedef volatile unsigned long vuint32_t; + +#if (defined __MWERKS__) +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed long int32_t; +typedef unsigned long uint32_t; +#endif +/*! + * @addtogroup c90tfs_flash_driver + * @{ + */ + + +/*! + * @name Type definition for flash driver + * @{ + */ +/*-------------------- Callback function prototype ---------------------*/ +/*! @brief Call back function pointer data type */ +typedef void (* PCALLBACK)(void); +/*! @brief Swap call back function pointer data type */ +typedef bool (* PFLASH_SWAP_CALLBACK)(uint8_t function); + + +/*---------------- Flash SSD Configuration Structure -------------------*/ +/*! @brief Flash SSD Configuration Structure +* +* The structure includes the static parameters for C90TFS/FTFx which are +* device-dependent. The user should correctly initialize the fields including +* ftfxRegBase, PFlashBlockBase, PFlashBlockSize, DFlashBlockBase, EERAMBlockBase, +* DebugEnable and CallBack before passing the structure to SSD functions. +* The rest of parameters such as DFlashBlockSize, and EEEBlockSize will be +* initialized in FlashInit() automatically. The pointer to CallBack has to be +* initialized either for null callback or a valid call back function. +* +*/ +typedef struct _ssd_config +{ + uint32_t ftfxRegBase; /*!< The register base address of C90TFS/FTFx */ + uint32_t PFlashBase; /*!< The base address of P-Flash memory */ + uint32_t PFlashSize; /*!< The size in byte of P-Flash memory */ + uint32_t DFlashBase; /*!< For FlexNVM device, this is the base address of D-Flash memory (FlexNVM memory); For non-FlexNVM device, this field is unused */ + uint32_t DFlashSize; /*!< For FlexNVM device, this is the size in byte of area + which is used as D-Flash from FlexNVM + memory; For non-FlexNVM device, this field is unused */ + uint32_t EERAMBase; /*!< The base address of FlexRAM (for FlexNVM + device) or acceleration RAM memory (for non-FlexNVM device) */ + uint32_t EEESize; /*!< For FlexNVM device, this is the size in byte of + EEPROM area which was partitioned from + FlexRAM; For non-FlexNVM device, this field is unused */ + bool DebugEnable; /*!< Background debug mode enable */ + PCALLBACK CallBack; /*!< Call back function to service the time critical events */ +} FLASH_SSD_CONFIG, *PFLASH_SSD_CONFIG; + +/* -------------------- Function Pointer ------------------------------- */ +/*! @brief FlashCommandSequence function pointer */ +typedef uint32_t (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG pSSDConfig); + +/*! @brief FlashInit function pointer */ +typedef uint32_t (*pFLASHINIT) (PFLASH_SSD_CONFIG pSSDConfig); + +/*! @brief PFlashGetProtection function pointer */ +typedef uint32_t (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t* protectStatus); + +/*! @brief PFlashSetProtection function pointer */ +typedef uint32_t (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t protectStatus); + +/*! @brief FlashGetSecurityState function pointer */ +typedef uint32_t (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t* securityState); + +/*! @brief FlashSecurityByPass function pointer */ +typedef uint32_t (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t* keyBuffer, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! @brief FlashEraseAllBlock function pointer */ +typedef uint32_t (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG pSSDConfig, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! @brief FlashEraseBlock function pointer */ +typedef uint32_t (*pFLASHERASEBLOCK) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! @brief FlashEraseSector function pointer */ +typedef uint32_t (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! @brief FlashEraseSuspend function pointer */ +typedef uint32_t (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG pSSDConfig); + +/*! @brief FlashEraseResume function pointer */ +typedef uint32_t (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG pSSDConfig); + +/*! @brief FlashProgramSection function pointer */ +typedef uint32_t (*pFLASHPROGRAMSECTION) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint16_t number, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! @brief FlashChecksum function pointer */ +typedef uint32_t (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + uint32_t* pSum); + +/*! @brief FlashVerifyAllBlock function pointer */ +typedef uint32_t (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t marginLevel, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! Flash verify block */ +typedef uint32_t (*pFLASHVERIFYBLOCK) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint8_t marginLevel, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! @brief FlashVerifySection function pointer */ +typedef uint32_t (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint16_t number, \ + uint8_t marginLevel, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! @brief FlashReadOnce function pointer */ +typedef uint32_t (*pFLASHREADONCE) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t* pDataArray, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! @brief FlashProgramOnce function pointer */ +typedef uint32_t (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t* pDataArray, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! @brief FlashProgramCheck function pointer */ +typedef uint32_t (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + uint8_t* pExpectedData, \ + uint32_t* pFailAddr, \ + uint8_t marginLevel, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! @brief FlashReadResource function pointer */ +typedef uint32_t (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint8_t* pDataArray, \ + uint8_t resourceSelectCode, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! @brief FlashProgram function pointer */ +typedef uint32_t (*pFLASHPROGRAM) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + uint8_t* pData, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! @brief PFlashSwapCtrl function pointer */ +typedef uint32_t (*pPFLASHSWAPCTRL) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t addr, \ + uint8_t swapcmd, \ + uint8_t* pCurrentSwapMode,\ + uint8_t* pCurrentSwapBlockStatus, \ + uint8_t* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! @brief PFlashSwap function pointer */ +typedef uint32_t (*pFLASHSWAP)(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t flashAddress, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); + +/*! @brief DFlashGetProtection function pointer */ +typedef uint32_t (*pDFLASHGETPROTECTION) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t* protectStatus); +/*! @brief DFlashSetProtection function pointer */ +typedef uint32_t (*pDFLASHSETPROTECTION) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t protectStatus); + +/*! @brief EERAMGetProtection function pointer */ +typedef uint32_t (*pEERAMGETPROTECTION) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t* protectStatus); + +/*! @brief EERAMSetProtection function pointer */ +typedef uint32_t (*pEERAMSETPROTECTION) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t protectStatus); +/*! @brief DEFlashParition function pointer */ +typedef uint32_t (*pDEFLASHPARTITION) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t EEEDataSizeCode, \ + uint8_t DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! @brief SetEEEEnable function pointer */ +typedef uint32_t (*pSETEEEENABLE) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t EEEEnable,pFLASHCOMMANDSEQUENCE pFlashCommandSequence); +/*! @brief EEEWrite function pointer */ +typedef uint32_t (*pEEEWRITE) (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + uint8_t* pData); + +/*@}*/ + +/*! @}*/ + +#endif /* _SSD_TYPES_H_ */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/CopyToRam.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/CopyToRam.c new file mode 100755 index 0000000..2f1a3e8 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/CopyToRam.c @@ -0,0 +1,79 @@ +/************************************************************************ + (c) Copyright 2013-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +************************************************************************* + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : RelocateFunction +* Description : Relocate FlashCommandSequence to another address. +* Arguments : uint32_t, uint32_t, pFLASHCOMMANDSEQUENCE +* Return Value : pFLASHCOMMANDSEQUENCE +* +*************************************************************************/ + +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* end of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION RelocateFunction(uint32_t dest, uint32_t size, uint32_t src) +{ + uint32_t temp; + uint16_t value, i, *pSrc, *pDest; + temp = PGM2DATA((uint32_t)src - LAUNCH_COMMAND_OFFSET); + pSrc = (uint16_t *)temp; + pDest = (uint16_t *)dest; + temp = size >>1; + for (i = 0x0U; i < temp; i++) + { + value = READ16(pSrc); + pSrc++; + WRITE16(pDest, value); + pDest++; + } + return ((uint32_t)DATA2PGM((uint32_t)dest + LAUNCH_COMMAND_OFFSET)); +} +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/DEFlashPartition.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/DEFlashPartition.c new file mode 100755 index 0000000..68b2383 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/DEFlashPartition.c @@ -0,0 +1,100 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : DEFlashPartition.c +* Description : This function prepares the D/E-Flash block for use +* as D-Flash, E-Flash or a combination of both and +* initializes the EERAM. +* Arguments : PFLASH_SSD_CONFIG, uint8_t,uint8_t, pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ +#if (DEBLOCK_SIZE != 0x0U) + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION DEFlashPartition(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t EEEDataSizeCode, \ + uint8_t DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + uint32_t ret; /* return code variable */ + uint32_t temp; /* temporary variable */ + + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_PROGRAM_PARTITION); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET; + REG_WRITE(temp, EEEDataSizeCode); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET; + REG_WRITE(temp, DEPartitionCode); + + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + return(ret); +} +#endif /* end of DEBLOCK_SIZE */ +/* end of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/DFlashGetProtection.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/DFlashGetProtection.c new file mode 100755 index 0000000..4809206 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/DFlashGetProtection.c @@ -0,0 +1,90 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************* +* +* Function Name : DFlashGetProtection.c +* Description : This function retrieves current D-Flash protection status. +* Arguments : PFLASH_SSD_CONFIG, uint8_t* +* Return Value : uint32_t +* +*************************************************************************/ +#if (DEBLOCK_SIZE != 0x0U) + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION DFlashGetProtection(PFLASH_SSD_CONFIG pSSDConfig, uint8_t* protectStatus) +{ + uint32_t ret = FTFx_OK; /* return code variable */ + uint32_t temp; /* temporary variable */ + + /* Check if size of DFlash = 0 */ + if(pSSDConfig->DFlashSize == 0x0U) + { + ret = FTFx_ERR_EFLASHONLY; + } + else + { + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FDPROT_OFFSET; + *protectStatus = REG_READ(temp); + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +#endif /* End of DEBLOCK_SIZE */ +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/DFlashSetProtection.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/DFlashSetProtection.c new file mode 100755 index 0000000..c9dbae9 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/DFlashSetProtection.c @@ -0,0 +1,102 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ + +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : DFlashSetProtection.c +* Description : This function sets the D-Flash protection to the +* intended protection status +* Arguments : PFLASH_SSD_CONFIG, uint8_t +* Return Value : uint32_t +* +*************************************************************************/ +#if (DEBLOCK_SIZE != 0x0U) + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION DFlashSetProtection(PFLASH_SSD_CONFIG pSSDConfig, uint8_t protectStatus) +{ + uint32_t ret = FTFx_OK; /* return code variable */ + uint32_t temp; /* temporary variable */ + + /* Check if size of DFlash = 0 */ + if(pSSDConfig->DFlashSize == 0x0U) + { + ret = FTFx_ERR_EFLASHONLY; + } + else + { + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FDPROT_OFFSET; + REG_WRITE(temp, protectStatus); + + if ( protectStatus != REG_READ(temp)) + { + ret = FTFx_ERR_CHANGEPROT; + } + else + { + /* do nothing */ + } + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +#endif /* End of DEBLOCK_SIZE */ +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/EEEWrite.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/EEEWrite.c new file mode 100755 index 0000000..be98e6a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/EEEWrite.c @@ -0,0 +1,175 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : EEEWrite.c +* Description : This function is used to write data to EERAM +* when it is used as EEPROM emulator +* Arguments : PFLASH_SSD_CONFIG, uint32_t, uint32_t, uint8_t, uint32_t +* Return Value : uint32_t +* +************************************************************************/ +#if (DEBLOCK_SIZE != 0x0U) + +/* declare prototype */ +uint32_t WaitEEWriteToFinish(PFLASH_SSD_CONFIG pSSDConfig, uint32_t* dest,\ + uint32_t* size, uint8_t** pData, uint8_t step); + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION WaitEEWriteToFinish(PFLASH_SSD_CONFIG pSSDConfig, uint32_t* dest,\ + uint32_t* size, uint8_t** pData, uint8_t step) +{ + uint32_t ret; /* return code variable */ + uint32_t temp; /* temporary variable */ + + if (0x01U == step) + { + WRITE8(*dest, READ8(*pData)); + } + if (0x02U == step) + { +#if(BIG_ENDIAN == ENDIANNESS) + temp = (uint32_t)READ8(*pData) << 8; + temp |= (uint32_t)(READ8(*pData + 1)); +#else + temp = (uint32_t)READ8(*pData + 1) << 8; + temp |= (uint32_t)(READ8(*pData)); +#endif + WRITE16(BYTE2WORD(*dest), (uint16_t)temp); + } + if (0x04U == step) + { +#if(BIG_ENDIAN == ENDIANNESS) + temp = (uint32_t)READ8(*pData) << 24; + temp |= (uint32_t)(READ8(*pData + 1)) << 16; + temp |= (uint32_t)(READ8(*pData + 2)) << 8; + temp |= (uint32_t)(READ8(*pData + 3)); +#else + temp = (uint32_t)READ8(*pData + 3) << 24; + temp |= (uint32_t)(READ8(*pData + 2)) << 16; + temp |= (uint32_t)(READ8(*pData + 1)) << 8; + temp |= (uint32_t)READ8(*pData); +#endif + WRITE32(BYTE2WORD(*dest), (uint32_t)temp); + } + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET; + while(0x0U == REG_BIT_GET(temp, FTFx_SSD_FCNFG_EEERDY)) + { + /* wait till EEERDY bit is set */ + } + /* Check for protection violation error */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + ret = (uint32_t)REG_READ(temp) & FTFx_SSD_FSTAT_FPVIOL; + + *dest += step; + *size -= step; + *pData += step; + + return ret; +} + +uint32_t SIZE_OPTIMIZATION EEEWrite(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + uint8_t* pData) +{ + uint32_t ret = FTFx_OK; /* Return code variable */ + uint32_t temp; /* variable temp */ + /* convert to byte address */ + dest = WORD2BYTE(dest); + /* Check if EEE is enabled */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET; + if(REG_READ(temp) & FTFx_SSD_FCNFG_EEERDY) + { + /* check range */ + if((dest < WORD2BYTE(pSSDConfig->EERAMBase)) || \ + ((dest + size) > (WORD2BYTE(pSSDConfig->EERAMBase) + pSSDConfig->EEESize))) + { + ret = FTFx_ERR_RANGE; + } + + while ((size > 0x0U) && (ret == FTFx_OK)) + { + + /* dest is 32bit-aligned and size is not less than 4 */ + if ((!(dest & 0x03U)) && (size >= 0x04U)) + { + ret = WaitEEWriteToFinish(pSSDConfig, &dest, &size, &pData, 0x04U); + } + else if ((!(dest & 0x1U)) && (size >= 0x02U)) + { + ret = WaitEEWriteToFinish(pSSDConfig, &dest, &size, &pData, 0x02U); + } + else + { + ret = WaitEEWriteToFinish(pSSDConfig, &dest, &size, &pData, 0x01U); + } + } + } + else + { + ret = FTFx_ERR_NOEEE; + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + return(ret); +} +#endif /* of DEBLOCK_SIZE */ +/* end of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/EERAMGetProtection.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/EERAMGetProtection.c new file mode 100755 index 0000000..e223b6e --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/EERAMGetProtection.c @@ -0,0 +1,91 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : EERAMGetProtection.c +* Description : This function retrieves current EERAM protection status. +* Arguments : PFLASH_SSD_CONFIG, UINT8* +* Return Value : UINT32 +* +*************************************************************************/ +#if (DEBLOCK_SIZE != 0x0U) +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION EERAMGetProtection(PFLASH_SSD_CONFIG pSSDConfig, uint8_t* protectStatus) +{ + uint32_t ret = FTFx_OK; /* return code variable */ + uint32_t temp; /* temporary variable */ + + /* Check if EERAM is set for EEE */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET; + if(0x0U != REG_BIT_GET(temp, FTFx_SSD_FCNFG_EEERDY)) + { + /* EERAM is set for EEE */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FEPROT_OFFSET; + *protectStatus = REG_READ(temp); + } + else + { + ret = FTFx_ERR_NOEEE; + } +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +#endif /* End of DEBLOCK_SIZE */ +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/EERAMSetProtection.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/EERAMSetProtection.c new file mode 100755 index 0000000..9d7b626 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/EERAMSetProtection.c @@ -0,0 +1,103 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : EERAMSetProtection.c +* Description : This function retrieves current EERAM protection status. +* Arguments : PFLASH_SSD_CONFIG, UINT8 +* Return Value : uint32_t +* +*************************************************************************/ +#if (DEBLOCK_SIZE != 0x0U) + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION EERAMSetProtection(PFLASH_SSD_CONFIG pSSDConfig, uint8_t protectStatus) +{ + uint32_t ret = FTFx_OK; /* return code variable */ + uint32_t temp; /* temporary variable */ + + /* Check if EERAM is set for EEE */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET; + if(0x0U == (REG_BIT_GET(temp, FTFx_SSD_FCNFG_EEERDY))) + { + /* EERAM is not set for EEE */ + ret = FTFx_ERR_NOEEE; + } + else + { + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FEPROT_OFFSET; + REG_WRITE(temp, protectStatus); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FEPROT_OFFSET; + if ( protectStatus != REG_READ(temp)) + { + ret = FTFx_ERR_CHANGEPROT; + } + else + { + /* do nothing */ + } + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +#endif /* End of DEBLOCK_SIZE */ +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashCheckSum.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashCheckSum.c new file mode 100755 index 0000000..dd8f421 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashCheckSum.c @@ -0,0 +1,128 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/*********************************************************************** +* +* Function Name : FlashCheckSum.c +* Description : This function is used to calculate checksum value +* for the specified flash range. +* Arguments : PFLASH_SSD_CONFIG,uint32_t ,uint32_t ,uint32_t* +* Return Value : uint32_t +* +************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashCheckSum(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + uint32_t* pSum) +{ + uint32_t counter; /* Counter for callback operation */ + uint32_t data; /* Data read from Flash address */ + uint32_t ret = FTFx_OK; /* Return code variable */ + uint32_t endAddress; /* P Flash end address */ + + counter = 0x0U; + /* convert to byte address */ + dest = WORD2BYTE(dest); + /* calculating Flash end address */ + endAddress = dest + size; + + /* check for valid range of the target addresses */ + if ((dest < WORD2BYTE(pSSDConfig->PFlashBase)) || + (endAddress > (WORD2BYTE(pSSDConfig->PFlashBase) + pSSDConfig->PFlashSize))) + { +#if(DEBLOCK_SIZE) + if ((dest < WORD2BYTE(pSSDConfig->DFlashBase)) || + (endAddress > (WORD2BYTE(pSSDConfig->DFlashBase) + pSSDConfig->DFlashSize))) + { +#endif /* End of if(DEBLOCK_SIZE) */ + /* return an error code FTFx_ERR_RANGE */ + ret = FTFx_ERR_RANGE; + size = 0x0U; +#if(DEBLOCK_SIZE) + } + +#endif /* End of if(DEBLOCK_SIZE) */ + } + *pSum = 0x0U; + /* doing sum operation */ + while(size > 0x0U) + { + data = READ8(dest); + *pSum += (uint32_t)data; + dest += 0x01U; + size -= 0x01U; + + /* Check if need to serve callback function */ + if((++counter) >= FLASH_CALLBACK_CS) + { + /* serve callback function if counter reaches limitation */ + if(NULL_CALLBACK != pSSDConfig->CallBack) + { + (pSSDConfig->CallBack)(); + } + /* Reset counter */ + counter = 0x0U; + } + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + return(ret); +} +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashCommandSequence.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashCommandSequence.c new file mode 100755 index 0000000..1f2ff3a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashCommandSequence.c @@ -0,0 +1,90 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" +/************************************************************************ +* +* Function Name : FlashCommandSequence.c +* Description : Perform command write sequence for flash operation +* Arguments : PFLASH_SSD_CONFIG, UINT8, UINT8* +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashCommandSequence (PFLASH_SSD_CONFIG pSSDConfig ) + +{ + uint32_t ret; /* return code variable */ + uint32_t temp; /* temporary variable */ + + /* clear CCIF to launch command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_BIT_SET(temp, FTFx_SSD_FSTAT_CCIF); + + /* wait for completion of this command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + while(0x0U == (REG_BIT_GET(temp, FTFx_SSD_FSTAT_CCIF))) + { + /* wait till CCIF bit is set */ + /* serve callback function if counter reaches limitation */ + if(NULL_CALLBACK != pSSDConfig->CallBack) + { + (pSSDConfig->CallBack)(); + } + } + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + ret = ((uint32_t)(REG_READ(temp)) & FTFx_SSD_FSTAT_ERROR_BITS); + return(ret); +} + +/* End of file */ + diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseAllBlock.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseAllBlock.c new file mode 100755 index 0000000..fb50deb --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseAllBlock.c @@ -0,0 +1,94 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : FlashEraseAllBlock.c +* Description : The Erase All Blocks operation will erase all Flash + memory, initialize the EERAM, verify all memory + contents, then release MCU security. +* Arguments : PFLASH_SSD_CONFIG, pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashEraseAllBlock (PFLASH_SSD_CONFIG pSSDConfig, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + uint32_t ret; /* return code variable */ + uint32_t temp; /* temporary variable */ + + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_ERASE_ALL_BLOCK); + + /* calling flash command sequence function to execute the command */ + + ret = pFlashCommandSequence(pSSDConfig); + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} + +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseBlock.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseBlock.c new file mode 100755 index 0000000..40380b4 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseBlock.c @@ -0,0 +1,128 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : FlashEraseBlock.c +* Description : The Erase Flash Block operation will erase all addresses in a single P-Flash or D-Flash block. +* Arguments : PFLASH_SSD_CONFIG, uint32_t, pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ +#if (!(defined(FTFA_M)) || (defined(BLOCK_COMMANDS))) + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashEraseBlock (PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + + uint32_t ret = FTFx_OK; /* return code variable */ + uint32_t temp; /* temporary variable */ + + /* convert to byte address */ + dest = WORD2BYTE(dest); + /* check if the destination is aligned or not */ +#if (DEBLOCK_SIZE) + temp = WORD2BYTE(pSSDConfig->DFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize))) + { + dest = dest - temp + 0x800000U; + } + else +#endif + { + temp = WORD2BYTE(pSSDConfig->PFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize))) + { + dest -= temp; + } + else + { + ret = FTFx_ERR_ACCERR; + } + } + + if(FTFx_OK == ret) + { + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_ERASE_BLOCK); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, GET_BIT_16_23(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET; + REG_WRITE(temp, GET_BIT_8_15(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET; + REG_WRITE(temp, GET_BIT_0_7(dest)); + + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + } +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +#endif /* End of FTFE_M and BLOCK_COMMANDS*/ +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseResume.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseResume.c new file mode 100755 index 0000000..0ff2c08 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseResume.c @@ -0,0 +1,98 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : FlashEraseResume.c +* Description : This function is used to resume a previous suspended +* operation of flash erase sector command. +* Arguments : PFLASH_SSD_CONFIG +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashEraseResume(PFLASH_SSD_CONFIG pSSDConfig) + +{ + uint16_t i; /* counter variable */ + uint32_t temp; /* temporary variable */ + i = 0x0U; + + /* check ERSSUSP bit of the flash configuration register */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET; + if(0x0U != REG_BIT_GET(temp, FTFx_SSD_FCNFG_ERSSUSP)) + { + /* clear CCIF to launch command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_BIT_SET(temp, FTFx_SSD_FSTAT_CCIF); + /* wait for completion of this command */ + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + while((0x0U == (REG_BIT_GET(temp, FTFx_SSD_FSTAT_CCIF))) || (i > RESUME_WAIT_CNT)) + { + i++; + } + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(FTFx_OK); +} + +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseSector.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseSector.c new file mode 100755 index 0000000..34de3b5 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseSector.c @@ -0,0 +1,147 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + + +/**************************************************************************** +* +* Function Name : FlashEraseSector +* Description : Perform erase operation on Flash +* Arguments : PFLASH_SSD_CONFIG, uint32_t, uint32_t, pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*****************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashEraseSector(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + + uint32_t ret = FTFx_OK; /* return code variable */ + uint32_t sectorSize; /* size of one sector */ + uint32_t temp; /* temporary variable */ + + + /* convert to byte address */ + dest = WORD2BYTE(dest); + +#if (DEBLOCK_SIZE) + temp = WORD2BYTE(pSSDConfig->DFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize))) + { + dest = dest - temp + 0x800000U; + sectorSize = FTFx_DSECTOR_SIZE; + } + else +#endif + { + temp = WORD2BYTE(pSSDConfig->PFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize))) + { + dest -= temp; + sectorSize = FTFx_PSECTOR_SIZE; + } + else + { + ret = FTFx_ERR_ACCERR; + size = 0x0U; + } + } + + /* check if the size is sector alignment or not */ + if(size & (sectorSize - 0x01U)) + { + /* return an error code FTFx_ERR_SIZE */ + ret = FTFx_ERR_SIZE; + } + + while((size > 0x0U) && (FTFx_OK == ret)) + { + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_ERASE_SECTOR); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, GET_BIT_16_23(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET; + REG_WRITE(temp, GET_BIT_8_15(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET; + REG_WRITE(temp, GET_BIT_0_7(dest)); + + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + + /* update size and destination address */ + size -= sectorSize; + dest += sectorSize; + + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +/* End of file */ + diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseSuspend.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseSuspend.c new file mode 100755 index 0000000..3df71bb --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashEraseSuspend.c @@ -0,0 +1,93 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : FlashEraseSuspend.c +* Description : This function is used to suspend a current operation +* of flash erase sector command. +* Arguments : PFLASH_SSD_CONFIG +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashEraseSuspend(PFLASH_SSD_CONFIG pSSDConfig) +{ + uint32_t temp; /* temporary variable */ + /* check CCIF bit of the flash status register */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + if(0x0U == (REG_BIT_GET(temp, FTFx_SSD_FSTAT_CCIF))) + { + /* If the command write sequence in progressing, */ + /* Set ERSSUSP bit in FCNFG register */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET; + REG_BIT_SET(temp, FTFx_SSD_FCNFG_ERSSUSP); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + while(0x0U == (REG_BIT_GET(temp, FTFx_SSD_FSTAT_CCIF))) + { + /* wait till CCIF bit is set */ + } + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(FTFx_OK); +} +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashGetSecurityState.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashGetSecurityState.c new file mode 100755 index 0000000..4c44794 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashGetSecurityState.c @@ -0,0 +1,106 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" +/************************************************************************ +* +* Function Name : FlashGetSecurityState.c +* Description : This function retrieves the current Flash security +* status, including the security enabling state and +* the backdoor key enabling state. +* Arguments : PFLASH_SSD_CONFIG, uint8_t* +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashGetSecurityState(PFLASH_SSD_CONFIG pSSDConfig, uint8_t* securityState) +{ + /* store data read from flash register */ + uint8_t regValue; + uint32_t temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSEC_OFFSET; + + /*Get flash security register value */ + regValue = REG_READ(temp); + + /* check the status of the flash security bits in the security register */ + if(FLASH_SECURITY_STATE_UNSECURED == (regValue & FTFx_SSD_FSEC_SEC)) + { + /* Flash in unsecured state */ + *securityState = FLASH_NOT_SECURE; + } + else + { + /* Flash in secured state */ + /* check for backdoor key security enable bit */ + if(FLASH_SECURITY_STATE_KEYEN == (regValue & FTFx_SSD_FSEC_KEYEN)) + { + /* Backdoor key security enabled */ + *securityState = FLASH_SECURE_BACKDOOR_ENABLED; + } + else + { + /* Backdoor key security disabled */ + *securityState = FLASH_SECURE_BACKDOOR_DISABLED; + } + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(FTFx_OK); +} + +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashInit.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashInit.c new file mode 100755 index 0000000..81e255f --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashInit.c @@ -0,0 +1,170 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : FlashInit.c +* Description : Initialize the Flash memory +* Arguments : PFLASH_SSD_CONFIG +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashInit (PFLASH_SSD_CONFIG pSSDConfig) +{ +#if (DEBLOCK_SIZE != 0x0U) + uint8_t EEEDataSetSize; /* store EEE Data Set Size */ + uint8_t DEPartitionCode; /* store D/E-Flash Partition Code */ + uint32_t temp; /* temporary variable */ + + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* Write Command Code to FCCOB0 */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_READ_RESOURCE); + + /* Write address to FCCOB1/2/3 */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, GET_BIT_16_23(DFLASH_IFR_READRESOURCE_ADDRESS)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET; + REG_WRITE(temp, GET_BIT_8_15(DFLASH_IFR_READRESOURCE_ADDRESS)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET; + REG_WRITE(temp, GET_BIT_0_7(DFLASH_IFR_READRESOURCE_ADDRESS)); + + /* Write Resource Select Code of 0 to FCCOB8 to select IFR. Without this, */ + /* an access error may occur if the register contains data from a previous command. */ + /* for FTFE module, resource code is FCCOB4. For others, recource code is FCCOB8 */ + temp = pSSDConfig->ftfxRegBase + RSRC_CODE_OFSSET; + REG_WRITE(temp, 0x0U); + + /* clear CCIF bit */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_BIT_SET(temp, FTFx_SSD_FSTAT_CCIF); + + /* check CCIF bit */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + while((REG_BIT_GET(temp, FTFx_SSD_FSTAT_CCIF)) == 0x0U) + { + /* wait till CCIF bit is set */ + } + /* read out EEdata set size and DEpartition code from FCCOBA, FCCOBB for FTFE module, from FCCOB6 and FCCOB7 for others */ + #ifdef FTFE_M + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOBA_OFFSET; + EEEDataSetSize = REG_READ(temp); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOBB_OFFSET; + DEPartitionCode = REG_READ(temp); + #else + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB6_OFFSET; + EEEDataSetSize = REG_READ(temp); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB7_OFFSET; + DEPartitionCode = REG_READ(temp); + #endif + DEPartitionCode = DEPartitionCode & 0x0FU; + EEEDataSetSize = EEEDataSetSize & 0x0FU; + /* Calculate D-Flash size and EEE size */ + if (0x0U == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_0000;} + else if (0x01U == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_0001;} + else if (0x02U == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_0010;} + else if (0x03U == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_0011;} + else if (0x04U == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_0100;} + else if (0x05U == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_0101;} + else if (0x06U == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_0110;} + else if (0x07U == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_0111;} + else if (0x08U == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_1000;} + else if (0x09U == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_1001;} + else if (0x0AU == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_1010;} + else if (0x0BU == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_1011;} + else if (0x0CU == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_1100;} + else if (0x0DU == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_1101;} + else if (0x0EU == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_1110;} + else if (0x0FU == DEPartitionCode) {pSSDConfig->DFlashSize = DEPART_1111;} + + if (0x0U == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_0000;} + else if (0x01U == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_0001;} + else if (0x02U == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_0010;} + else if (0x03U == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_0011;} + else if (0x04U == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_0100;} + else if (0x05U == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_0101;} + else if (0x06U == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_0110;} + else if (0x07U == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_0111;} + else if (0x08U == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_1000;} + else if (0x09U == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_1001;} + else if (0x0AU == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_1010;} + else if (0x0BU == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_1011;} + else if (0x0CU == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_1100;} + else if (0x0DU == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_1101;} + else if (0x0EU == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_1110;} + else if (0x0FU == EEEDataSetSize) {pSSDConfig->EEESize = EEESIZE_1111;} + +#else /* DEBLOCK_SIZE == 0 */ + /* If size of D/E-Flash = 0 */ + pSSDConfig->DFlashSize = 0x0U; + pSSDConfig->EEESize = 0x0U; +#endif /* end of DEBLOCK_SIZE */ +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(FTFx_OK); +} +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashProgram.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashProgram.c new file mode 100755 index 0000000..9671b45 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashProgram.c @@ -0,0 +1,149 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" +/************************************************************************ +* +* Function Name : FlashProgram.c +* Description : Program data into Flash +* Arguments : PFLASH_SSD_CONFIG, uint32_t, uint32_t, uint32_t, +* pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashProgram(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + uint8_t* pData, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + uint32_t ret = FTFx_OK; /* return code variable */ + uint8_t i; + uint32_t temp; + + if (size & (PGM_SIZE_BYTE - 0x01U)) + { + ret = FTFx_ERR_SIZE; + } + else + { + /* convert to byte address */ + dest = WORD2BYTE(dest); +#if (DEBLOCK_SIZE) + temp = WORD2BYTE(pSSDConfig->DFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize))) + { + dest = dest - temp + 0x800000U; + } + else +#endif + { + temp = WORD2BYTE(pSSDConfig->PFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize))) + { + dest -= temp; + } + else + { + ret = FTFx_ERR_ACCERR; + } + } + while((size > 0x0U) && (FTFx_OK == ret)) + { + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + /* passing parameter to the command */ +#if (PGM_SIZE_BYTE == FTFx_PHRASE_SIZE) + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_PROGRAM_PHRASE); +#else + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_PROGRAM_LONGWORD); +#endif + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, GET_BIT_16_23(dest)); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET; + REG_WRITE(temp, GET_BIT_8_15(dest)); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET; + REG_WRITE(temp, GET_BIT_0_7(dest)); + + for (i = 0x0U; i < PGM_SIZE_BYTE; i++) + { + temp = pSSDConfig->ftfxRegBase + i + 0x08U; + REG_WRITE(temp, *(pData + i)); + } + + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + + /* update destination address for next iteration */ + dest += PGM_SIZE_BYTE; + /* update size for next iteration */ + size -= PGM_SIZE_BYTE; + /* increment the source address by 1 */ + pData += PGM_SIZE_BYTE; + } + } +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +/* end of file */ + + diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashProgramCheck.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashProgramCheck.c new file mode 100755 index 0000000..c8f08bd --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashProgramCheck.c @@ -0,0 +1,173 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : FlashProgramCheck.c +* Description : The Program Check command tests a previously +* programmed P-Flash or D-Flash longword to see +* if it reads correctly at the specified margin level. +* Arguments : PFLASH_SSD_CONFIG, uint32_t,uint32_t, uint8_t*, uint32_t*, +* uint8_t*, uint8_t, pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashProgramCheck(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint32_t size, \ + uint8_t* pExpectedData, \ + uint32_t* pFailAddr, \ + uint8_t marginLevel, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + + uint32_t ret; /* return code variable */ + uint32_t offsetAddr ; /* offset address to convert to internal memory address */ + uint32_t temp; /* temporary variable */ + uint8_t i; + /* convert to byte address */ + dest = WORD2BYTE(dest); + if (size & (PGMCHK_ALIGN_SIZE - 0x01U)) + { + ret = FTFx_ERR_SIZE; + + } + else + { + /* check if the destination is aligned or not */ +#if (DEBLOCK_SIZE) + offsetAddr = WORD2BYTE(pSSDConfig->DFlashBase); + if((dest >= offsetAddr) && (dest < (offsetAddr + pSSDConfig->DFlashSize))) + { + dest = dest - offsetAddr + 0x800000U; + } + else +#endif + { + offsetAddr = WORD2BYTE(pSSDConfig->PFlashBase); + if((dest >= offsetAddr) && (dest < offsetAddr + pSSDConfig->PFlashSize)) + { + dest -= offsetAddr; + } + else + { + ret = FTFx_ERR_ACCERR; + size = 0x0U; + } + } + while (size) + { + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_PROGRAM_CHECK); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, GET_BIT_16_23(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET; + REG_WRITE(temp, GET_BIT_8_15(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET; + REG_WRITE(temp, GET_BIT_0_7(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET; + REG_WRITE(temp, marginLevel); + + for (i = 0x0U; i < PGMCHK_ALIGN_SIZE; i++) + { + temp = pSSDConfig->ftfxRegBase + i + 0x0CU; + REG_WRITE(temp, *(pExpectedData + i)); + } + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + + /* checking for the success of command execution */ + if(FTFx_OK != ret) + { +#if (DEBLOCK_SIZE) + if(dest >= 0x800000U) + { + *pFailAddr = BYTE2WORD(dest + offsetAddr - 0x800000U); + size = PGMCHK_ALIGN_SIZE; + } + else +#endif + { + *pFailAddr = BYTE2WORD(dest + offsetAddr); + size = PGMCHK_ALIGN_SIZE; + } + } + size -= PGMCHK_ALIGN_SIZE; + pExpectedData += PGMCHK_ALIGN_SIZE; + dest += PGMCHK_ALIGN_SIZE; + } + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +/* end of file */ + + diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashProgramOnce.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashProgramOnce.c new file mode 100755 index 0000000..dfdd89a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashProgramOnce.c @@ -0,0 +1,107 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" +/************************************************************************ +* +* Function Name : FlashProgramOnce.c +* Description : Program a data record into a dedicated 64 bytes +* (divided into 16 data records) region in +* the P-Flash IFR which stores critical information +* for the user +* Arguments : PFLASH_SSD_CONFIG, uint8_t , uint8_t*, pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashProgramOnce(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t recordIndex,\ + uint8_t* pDataArray, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + + uint8_t i; + uint32_t ret; /* return code variable */ + uint32_t temp; /* temporary variable */ + + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_PROGRAM_ONCE); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, recordIndex); + + for (i = 0x0U; i < PGM_SIZE_BYTE; i ++) + { + temp = pSSDConfig->ftfxRegBase + i + 0x08U; + REG_WRITE(temp, pDataArray[i]); + } + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} + +/* End of file */ + + diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashProgramSection.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashProgramSection.c new file mode 100755 index 0000000..e200874 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashProgramSection.c @@ -0,0 +1,147 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" +/************************************************************************ +* +* Function Name : FlashProgramSection.c +* Description : Program data into Flash +* Arguments : PFLASH_SSD_CONFIG, uint32_t, uint16_t, +* pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ +#ifndef FTFA_M + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashProgramSection(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint16_t number, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + + uint32_t ret = FTFx_OK; /* return code variable */ + uint32_t temp; + + /* check RAMRDY bit of the flash configuration register */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET; + if(0x0U == (REG_BIT_GET(temp, FTFx_SSD_FCNFG_RAMRDY))) + { + /* return an error code FTFx_ERR_RAMRDY */ + ret = FTFx_ERR_RAMRDY; + } + else + { + /* convert to byte address */ + dest = WORD2BYTE(dest); +#if (DEBLOCK_SIZE) + temp = WORD2BYTE(pSSDConfig->DFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize))) + { + dest = dest - temp + 0x800000U; + } + else +#endif + { + temp = WORD2BYTE(pSSDConfig->PFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize))) + { + dest -= temp; + } + else + { + ret = FTFx_ERR_ACCERR; + } + } + + if(ret == FTFx_OK) + { + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_PROGRAM_SECTION); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, GET_BIT_16_23(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET; + REG_WRITE(temp, GET_BIT_8_15(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET; + REG_WRITE(temp, GET_BIT_0_7(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET; + REG_WRITE(temp, GET_BIT_8_15(number)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET; + REG_WRITE(temp, GET_BIT_0_7(number)); + + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + } + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} + +#endif /* End of FTFA */ +/* End of file */ + + diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashReadOnce.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashReadOnce.c new file mode 100755 index 0000000..2cc4192 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashReadOnce.c @@ -0,0 +1,104 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : FlashReadOnce.c +* Description : This function is used to read access to a reserved +* 64 byte field located in the P-Flash IFR. +* Arguments : PFLASH_SSD_CONFIG, uint8_t*, pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashReadOnce(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t recordIndex,\ + uint8_t* pDataArray, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + uint8_t i; + uint32_t ret; /* return code variable */ + uint32_t temp; /* temporary variable */ + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_READ_ONCE); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, recordIndex); + + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + /* checking for the success of command execution */ + if(FTFx_OK == ret) + { + /* Read the data from the FCCOB registers into the pDataArray */ + for (i = 0x0U; i < PGM_SIZE_BYTE; i ++) + { + temp = pSSDConfig->ftfxRegBase + i + 0x08U; + pDataArray[i] = REG_READ(temp); + } + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + return(ret); +} +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashReadResource.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashReadResource.c new file mode 100755 index 0000000..6f5c454 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashReadResource.c @@ -0,0 +1,137 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" +/************************************************************************ +* +* Function Name : FlashReadResource.c +* Description : This function is provided for the user to read data +* from P-Flash IFR and D-Flash IFR space. +* Arguments : PFLASH_SSD_CONFIG, uint32_t, uint8_t*, pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashReadResource(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint8_t* pDataArray, \ + uint8_t resourceSelectCode, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + uint8_t i; + uint32_t ret = FTFx_OK; /* return code variable */ + uint32_t temp; + + /* convert to byte address */ + dest = WORD2BYTE(dest); + /* check if the destination is aligned or not */ +#if (DEBLOCK_SIZE) + temp = WORD2BYTE(pSSDConfig->DFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize))) + { + dest = dest - temp + 0x800000U; + } + else +#endif + { + temp = WORD2BYTE(pSSDConfig->PFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize))) + { + dest -= temp; + } + else + { + ret = FTFx_ERR_ACCERR; + } + } + if(ret == FTFx_OK) + { + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_READ_RESOURCE); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, GET_BIT_16_23(dest)); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET; + REG_WRITE(temp, GET_BIT_8_15(dest)); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET; + REG_WRITE(temp, GET_BIT_0_7(dest)); + + temp = pSSDConfig->ftfxRegBase + RSRC_CODE_OFSSET; + REG_WRITE(temp, resourceSelectCode); + + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + + if (FTFx_OK == ret) + { + /* Read the data from the FCCOB registers into the pDataArray */ + for (i = 0x0U; i < PGM_SIZE_BYTE; i ++) + { + temp = pSSDConfig->ftfxRegBase + i + 0x08U; + pDataArray[i] = REG_READ(temp); + } + } + } +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashSecurityBypass.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashSecurityBypass.c new file mode 100755 index 0000000..1f9fb0a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashSecurityBypass.c @@ -0,0 +1,98 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : FlashSecurityBypass.c +* Description : If the MCU is secured state, this function will +* unsecure the MCU by comparing the provided backdoor +* key with ones in the Flash Configuration Field. +* Arguments : PFLASH_SSD_CONFIG, uint8_t*, pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashSecurityBypass(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t* keyBuffer, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + uint32_t ret; /* return code variable */ + uint32_t temp; /* temporary variable */ + uint8_t i; + + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_SECURITY_BY_PASS); + for (i = 0x0U; i < 0x08U; i++) + { + temp = pSSDConfig->ftfxRegBase + i + 0x08U; + REG_WRITE(temp, keyBuffer[i]); + } + ret = pFlashCommandSequence(pSSDConfig); + + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashVerifyAllBlock.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashVerifyAllBlock.c new file mode 100755 index 0000000..97ba931 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashVerifyAllBlock.c @@ -0,0 +1,96 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : FlashVerifyAllBlock.c +* Description : This function will check to see if the P-Flash +* and D-Flash blocks as well as EERAM, E-Flash records +* and D-Flash IFR have been erased to the specified read +* margin level, if applicable, and will release security +* if the readout passes. +* Arguments : PFLASH_SSD_CONFIG,uint8_t, pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashVerifyAllBlock(PFLASH_SSD_CONFIG pSSDConfig, \ + uint8_t marginLevel, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + uint32_t ret; /* return code variable */ + uint32_t temp; /* temporary variable */ + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_VERIFY_ALL_BLOCK); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, marginLevel); + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +/* end of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashVerifyBlock.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashVerifyBlock.c new file mode 100755 index 0000000..4cea58b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashVerifyBlock.c @@ -0,0 +1,132 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : FlashVerifyBlock.c +* Description : This function will check to see if an entire +* P-Flash or D-Flash block has been erased to the +* specified margin level. +* Arguments : PFLASH_SSD_CONFIG, uint32_t,uint8_t, pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ +#if (!(defined(FTFA_M)) || (defined(BLOCK_COMMANDS))) + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashVerifyBlock(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint8_t marginLevel, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + uint32_t ret = FTFx_OK; /* return code variable */ + uint32_t temp; + + /* convert to byte address */ + dest = WORD2BYTE(dest); + /* check if the destination is aligned or not */ +#if (DEBLOCK_SIZE) + temp = WORD2BYTE(pSSDConfig->DFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize))) + { + dest = dest - temp + 0x800000U; + } + else +#endif + { + temp = WORD2BYTE(pSSDConfig->PFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize))) + { + dest -= temp; + } + else + { + ret = FTFx_ERR_ACCERR; + } + } + if(FTFx_OK == ret) + { + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_VERIFY_BLOCK); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, GET_BIT_16_23(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET; + REG_WRITE(temp, GET_BIT_8_15(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET; + REG_WRITE(temp, GET_BIT_0_7(dest)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET; + REG_WRITE(temp, marginLevel); + + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + } +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +#endif /* End of FTFE_M and BLOCK_COMMANDS*/ +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashVerifySection.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashVerifySection.c new file mode 100755 index 0000000..6548ce4 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/FlashVerifySection.c @@ -0,0 +1,132 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : FlashVerifySection.c +* Description : This function will check to see if a section of +* P-Flash or D-Flash memory is erased to the specified +* read margin level. +* Arguments : PFLASH_SSD_CONFIG,uint32_t,uint16_t,uint8_t, pFLASHCOMMANDSEQUENCE +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION FlashVerifySection(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t dest, \ + uint16_t number, \ + uint8_t marginLevel, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + uint32_t ret = FTFx_OK; /* return code variable */ + uint32_t temp; + + /* convert to byte address */ + dest = WORD2BYTE(dest); + /* check if the destination is aligned or not */ +#if (DEBLOCK_SIZE) + temp = WORD2BYTE(pSSDConfig->DFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize))) + { + dest = dest - temp + 0x800000U; + } + else +#endif + { + temp = WORD2BYTE(pSSDConfig->PFlashBase); + if((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize))) + { + dest -= temp; + } + else + { + ret = FTFx_ERR_ACCERR; + } + } + if(FTFx_OK == ret) + { + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_VERIFY_SECTION); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, GET_BIT_16_23(dest)); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET; + REG_WRITE(temp, GET_BIT_8_15(dest)); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET; + REG_WRITE(temp, GET_BIT_0_7(dest)); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET; + REG_WRITE(temp, GET_BIT_8_15(number)); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET; + REG_WRITE(temp, GET_BIT_0_7(number)); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB6_OFFSET; + REG_WRITE(temp, marginLevel); + + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + } +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} + +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/PFlashGetProtection.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/PFlashGetProtection.c new file mode 100755 index 0000000..88f126c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/PFlashGetProtection.c @@ -0,0 +1,89 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : PFlashGetProtection.c +* Description : This function retrieves current P-Flash protection status. +* Arguments : PFLASH_SSD_CONFIG, uint32_t* +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION PFlashGetProtection(PFLASH_SSD_CONFIG pSSDConfig, uint32_t* protectStatus) +{ + uint32_t reg0, reg1, reg2, reg3; + uint32_t temp; /* temporary variable */ + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FPROT0_OFFSET; + reg0 = REG_READ(temp); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FPROT1_OFFSET; + reg1 = REG_READ(temp); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FPROT2_OFFSET; + reg2 = REG_READ(temp); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FPROT3_OFFSET; + reg3 = REG_READ(temp); + + *protectStatus = (uint32_t)((uint32_t)(reg0 << 24) | (uint32_t)(reg1 << 16) | (uint32_t)(reg2 << 8) | reg3); + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(FTFx_OK); +} +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/PFlashSetProtection.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/PFlashSetProtection.c new file mode 100755 index 0000000..537d076 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/PFlashSetProtection.c @@ -0,0 +1,106 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : PFlashSetProtection.c +* Description : This function sets the P-Flash protection to the +* intended protection status +* Arguments : PFLASH_SSD_CONFIG, uint32_t +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION PFlashSetProtection(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t protectStatus) +{ + uint32_t ret = FTFx_OK; + uint32_t addr; + uint32_t temp0, temp1, temp2, temp3; + uint8_t reg0, reg1, reg2, reg3; + + reg0 = GET_BIT_24_31(protectStatus); + reg1 = GET_BIT_16_23(protectStatus); + reg2 = GET_BIT_8_15(protectStatus); + reg3 = GET_BIT_0_7(protectStatus); + + addr = pSSDConfig->ftfxRegBase + FTFx_SSD_FPROT0_OFFSET; + REG_WRITE(addr, reg0); + temp0 = REG_READ(addr); + addr = pSSDConfig->ftfxRegBase + FTFx_SSD_FPROT1_OFFSET; + REG_WRITE(addr, reg1); + temp1 = REG_READ(addr); + addr = pSSDConfig->ftfxRegBase + FTFx_SSD_FPROT2_OFFSET; + REG_WRITE(addr, reg2); + temp2 = REG_READ(addr); + addr = pSSDConfig->ftfxRegBase + FTFx_SSD_FPROT3_OFFSET; + REG_WRITE(addr, reg3); + temp3 = REG_READ(addr); + + /* Read the value of FPPROT registers */ + if ((temp0 != reg0) || (temp1 != reg1) || (temp2 != reg2) || (temp3 != reg3)) + { + ret = FTFx_ERR_CHANGEPROT; + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/PFlashSwap.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/PFlashSwap.c new file mode 100755 index 0000000..c727b35 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/PFlashSwap.c @@ -0,0 +1,163 @@ +/**HEADER******************************************************************** + Copyright (c) 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Freescale Semiconductor, Inc. nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***************************************************************************** +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +#ifdef SWAP_M +/************************************************************************ +* +* Function Name : PFlashSwap.c +* Description : Perform a swap between P-Flash block 0 and +* P-Flash block 1 +* +* +* Arguments : PFLASH_SSD_CONFIG, uint32_t, pFLASHCOMMANDSEQUENCE, +* PSWAP_CALLBACK +* +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* End of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION PFlashSwap(PFLASH_SSD_CONFIG pSSDConfig, \ + uint32_t addr, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + uint32_t ret = FTFx_OK; /* Return code */ + uint8_t currentSwapMode , currentSwapBlockStatus , nextSwapBlockStatus; + bool swapContinue; + + currentSwapMode = currentSwapBlockStatus = nextSwapBlockStatus = 0xFFU; + swapContinue = FALSE; + + /* Report current swap state */ + ret = PFlashSwapCtl(pSSDConfig,addr,FTFx_SWAP_REPORT_STATUS,¤tSwapMode, \ + ¤tSwapBlockStatus, &nextSwapBlockStatus ,pFlashCommandSequence); + + if (FTFx_OK == ret) + { + if ((FTFx_SWAP_UNINIT == currentSwapMode) || (FTFx_SWAP_READY == currentSwapMode) || \ + (FTFx_SWAP_UPDATE == currentSwapMode)) + { + /* If current swap mode is Uninitialized */ + if (FTFx_SWAP_UNINIT == currentSwapMode) + { + /* Initialize Swap to Initialized/READY state */ + ret = PFlashSwapCtl(pSSDConfig, addr, FTFx_SWAP_SET_INDICATOR_ADDR,¤tSwapMode, \ + ¤tSwapBlockStatus, &nextSwapBlockStatus , pFlashCommandSequence); + } + /* If current swap mode is Initialized/Ready */ + else if (FTFx_SWAP_READY == currentSwapMode) + { + /* Initialize Swap to UPDATE state */ + ret = PFlashSwapCtl(pSSDConfig, addr, FTFx_SWAP_SET_IN_PREPARE,¤tSwapMode, \ + ¤tSwapBlockStatus, &nextSwapBlockStatus , pFlashCommandSequence); + } + else if (FTFx_SWAP_UPDATE == currentSwapMode){} + + /* Check for the success of command execution */ + /* Report the current swap state to user via callback */ + if ((NULL_SWAP_CALLBACK != pSwapCallback) && (FTFx_OK == ret)) + { + swapContinue = pSwapCallback(currentSwapMode); + + if (swapContinue) + { + /* Report current swap state */ + ret = PFlashSwapCtl(pSSDConfig,addr,FTFx_SWAP_REPORT_STATUS,¤tSwapMode, \ + ¤tSwapBlockStatus, &nextSwapBlockStatus , pFlashCommandSequence); + } + } + } + if ((NULL_SWAP_CALLBACK == pSwapCallback)&&(FTFx_SWAP_UPDATE == currentSwapMode)) + { + /* Erase indicator sector in non active block to proceed swap system to update-erased state */ + ret = FlashEraseSector(pSSDConfig, addr + (pSSDConfig->PFlashSize >> 1), FTFx_PSECTOR_SIZE, \ + pFlashCommandSequence); + if (FTFx_OK == ret) + { + /* Now the swap state must be Update-Erased, so report current swap state */ + ret = PFlashSwapCtl(pSSDConfig,addr,FTFx_SWAP_REPORT_STATUS,¤tSwapMode, \ + ¤tSwapBlockStatus, &nextSwapBlockStatus , pFlashCommandSequence); + } + } + /* If current swap mode is Update or Update-Erased */ + if (FTFx_SWAP_UPDATE_ERASED == currentSwapMode) + { + if (NULL_SWAP_CALLBACK == pSwapCallback) + { + swapContinue = TRUE; + } + else + { + swapContinue = pSwapCallback(currentSwapMode); + } + + if (swapContinue) + { + /* Progress Swap to COMPLETE State */ + ret = PFlashSwapCtl(pSSDConfig,addr,FTFx_SWAP_SET_IN_COMPLETE,¤tSwapMode, \ + ¤tSwapBlockStatus, &nextSwapBlockStatus , pFlashCommandSequence); + } + } + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +#endif /* End of SWAP_M */ +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/PFlashSwapCtl.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/PFlashSwapCtl.c new file mode 100755 index 0000000..7b9bc0c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/PFlashSwapCtl.c @@ -0,0 +1,126 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +#ifdef SWAP_M +/************************************************************************ +* +* Function Name : PFlashSwapCtl +* Description : Execute swap command represented by a control code +* +* Arguments : PFLASH_SSD_CONFIG, uint32_t, uint8_t, +* uint8_t* pCurrentSwapMode,uint8_t* pCurrentSwapBlockStatus, +* uint8_t* pNextSwapBlockStatus, +* pFLASHCOMMANDSEQUENCE +* +* Return Value : uint32_t +* +*************************************************************************/ + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* end of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION PFlashSwapCtl(PFLASH_SSD_CONFIG pSSDConfig,uint32_t addr, uint8_t swapcmd,uint8_t* pCurrentSwapMode, \ + uint8_t* pCurrentSwapBlockStatus, \ + uint8_t* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + uint32_t ret; /* Return code variable */ + uint32_t temp; /* temporary variable */ + + addr = WORD2BYTE(addr - pSSDConfig->PFlashBase); + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp, FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_PFLASH_SWAP); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, GET_BIT_16_23(addr)); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET; + REG_WRITE(temp, GET_BIT_8_15(addr)); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET; + REG_WRITE(temp, GET_BIT_0_7(addr)); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET; + REG_WRITE(temp, swapcmd); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET; + REG_WRITE(temp, 0xFFU); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB6_OFFSET; + REG_WRITE(temp, 0xFFU); + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB7_OFFSET; + REG_WRITE(temp, 0xFFU); + + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + + if (FTFx_OK == ret) + { + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET; + *pCurrentSwapMode = REG_READ(temp); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB6_OFFSET; + *pCurrentSwapBlockStatus = REG_READ(temp); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB7_OFFSET; + *pNextSwapBlockStatus = REG_READ(temp); + } + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + return (ret); +} +#endif /* End of SWAP_M */ +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/SetEEEEnable.c b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/SetEEEEnable.c new file mode 100755 index 0000000..7a9de61 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/C90TFS/drvsrc/source/SetEEEEnable.c @@ -0,0 +1,98 @@ +/***************************************************************************** + (c) Copyright 2010-2014 Freescale Semiconductor, Inc. + ALL RIGHTS RESERVED. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** + +***************************************************************************** +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : Sep 25, 2014 * +* * +* AUTHOR : FPT Team * +* E-mail : r56611@freescale.com * +* * +*****************************************************************************/ + +/************************** CHANGES ************************************* +1.1.GA 09.25.2014 FPT Team First version of SDK C90TFS flash driver + inherited from BM C90TFS flash driver v1.02 + (08.04.2014, FPT Team) +*************************************************************************/ +/* include the header files */ +#include "SSD_FTFx.h" + +/************************************************************************ +* +* Function Name : SetEEEEnable.c +* Description : This function is used to change the function of +* the EERAM. When not partitioned for EEE, the EERAM +* is typically used as traditional RAM. When partitioned +* for EEE, the EERAM is typically used to store EEE data. +* Arguments : PFLASH_SSD_CONFIG, uint8_t +* Return Value : uint32_t +* +*************************************************************************/ +#if (DEBLOCK_SIZE != 0x0U) + +/* Enable size optimization */ +#if(ARM_CORTEX_M != CPU_CORE) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif /* end of CPU_CORE */ + +uint32_t SIZE_OPTIMIZATION SetEEEEnable(PFLASH_SSD_CONFIG pSSDConfig, uint8_t EEEEnable, pFLASHCOMMANDSEQUENCE pFlashCommandSequence) +{ + + uint32_t ret; /* return code variable */ + uint32_t temp; /* temporary variable */ + + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear*/ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET; + REG_WRITE(temp,FTFx_SSD_FSTAT_ERROR_BITS); + + /* passing parameter to the command */ + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET; + REG_WRITE(temp, FTFx_SET_EERAM); + + temp = pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET; + REG_WRITE(temp, EEEEnable); + + /* calling flash command sequence function to execute the command */ + ret = pFlashCommandSequence(pSSDConfig); + +#if C90TFS_ENABLE_DEBUG + /* Enter Debug state if enabled */ + if (TRUE == (pSSDConfig->DebugEnable)) + { + ENTER_DEBUG_MODE; + } +#endif + + return(ret); +} +#endif /* End of DEBLOCK_SIZE*/ +/* End of file */ diff --git a/KSDK_1.2.0/platform/drivers/src/flash/fsl_flash_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/flash/fsl_flash_lpm_callback.c new file mode 100755 index 0000000..c34e8d2 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flash/fsl_flash_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t flash_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t flash_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/flexbus/fsl_flexbus_common.c b/KSDK_1.2.0/platform/drivers/src/flexbus/fsl_flexbus_common.c new file mode 100755 index 0000000..abe4d07 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexbus/fsl_flexbus_common.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for FTM instances. */ +FB_Type * const g_fbBase[] = FB_BASE_PTRS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/flexbus/fsl_flexbus_driver.c b/KSDK_1.2.0/platform/drivers/src/flexbus/fsl_flexbus_driver.c new file mode 100755 index 0000000..6dd1e44 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexbus/fsl_flexbus_driver.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexbus_driver.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_FB_COUNT + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Initializes the FlexBus driver. + * + * @param instance The FlexBus peripheral instance number. + * @param fb_config FlexBus input user configuration + */ +flexbus_status_t FLEXBUS_DRV_Init(uint32_t instance, const flexbus_user_config_t *fb_config) +{ + assert(instance < FB_INSTANCE_COUNT); + + FB_Type* fbbase = g_fbBase[instance]; + + if(!fb_config) + { + return kStatus_FLEXBUS_InvalidArgument; + } + + /* clock setting initialization.*/ + CLOCK_SYS_EnableFlexbusClock(instance); + + /* Reset all the register to default state.*/ + FLEXBUS_HAL_Init(fbbase); + /* Configure all the register to a known state */ + FLEXBUS_HAL_Configure(fbbase, fb_config); + + return kStatus_FLEXBUS_Success; +} + +/*! + * @brief Shuts down the FlexBus driver. + * + * @param instance The FlexBus peripheral instance number. + */ +flexbus_status_t FLEXBUS_DRV_Deinit(uint32_t instance) +{ + assert(instance < FB_INSTANCE_COUNT); + + /* disable clock for Flexbus.*/ + CLOCK_SYS_DisableFlexbusClock(instance); + + return kStatus_FLEXBUS_Success; +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/flexbus/fsl_flexbus_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/flexbus/fsl_flexbus_lpm_callback.c new file mode 100755 index 0000000..38ec26e --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexbus/fsl_flexbus_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_FB_COUNT + +power_manager_error_code_t flexbus_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t flexbus_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/flexcan/fsl_flexcan_common.c b/KSDK_1.2.0/platform/drivers/src/flexcan/fsl_flexcan_common.c new file mode 100755 index 0000000..a74c50e --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexcan/fsl_flexcan_common.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for CAN instances. */ +CAN_Type * const g_flexcanBase[] = CAN_BASE_PTRS; + +/* Tables to save CAN IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_flexcanRxWarningIrqId[] = CAN_Rx_Warning_IRQS; +const IRQn_Type g_flexcanTxWarningIrqId[] = CAN_Tx_Warning_IRQS; +const IRQn_Type g_flexcanWakeUpIrqId[] = CAN_Wake_Up_IRQS; +const IRQn_Type g_flexcanErrorIrqId[] = CAN_Error_IRQS; +const IRQn_Type g_flexcanBusOffIrqId[] = CAN_Bus_Off_IRQS; +const IRQn_Type g_flexcanOredMessageBufferIrqId[] = CAN_ORed_Message_buffer_IRQS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/flexcan/fsl_flexcan_driver.c b/KSDK_1.2.0/platform/drivers/src/flexcan/fsl_flexcan_driver.c new file mode 100755 index 0000000..aa4504c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexcan/fsl_flexcan_driver.c @@ -0,0 +1,1027 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexcan_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_FLEXCAN_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to runtime state structure.*/ +flexcan_state_t * g_flexcanStatePtr[CAN_INSTANCE_COUNT] = { NULL }; + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static flexcan_status_t FLEXCAN_DRV_StartSendData( + uint8_t instance, + uint32_t mb_idx, + flexcan_data_info_t *tx_info, + uint32_t msg_id, + uint8_t *mb_data + ); +static flexcan_status_t FLEXCAN_DRV_StartRxMessageBufferData( + uint8_t instance, + uint32_t mb_idx, + flexcan_msgbuff_t *data + ); +static flexcan_status_t FLEXCAN_DRV_StartRxMessageFifoData( + uint8_t instance, + flexcan_msgbuff_t *data + ); +static void FLEXCAN_DRV_CompleteSendData(uint32_t instance); +static void FLEXCAN_DRV_CompleteRxMessageBufferData(uint32_t instance); +static void FLEXCAN_DRV_CompleteRxMessageFifoData(uint32_t instance); + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_SetBitrate + * Description : Set FlexCAN baudrate. + * This function will set up all the time segment values. Those time segment + * values are passed in by the user and are based on the required baudrate. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_SetBitrate(uint8_t instance, flexcan_time_segment_t *bitrate) +{ + assert(instance < CAN_INSTANCE_COUNT); + + /* Set time segments*/ + FLEXCAN_HAL_SetTimeSegments(g_flexcanBase[instance], bitrate); + + return kStatus_FLEXCAN_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_GetBitrate + * Description : Get FlexCAN baudrate. + * This function will be return the current bit rate settings + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_GetBitrate(uint8_t instance, flexcan_time_segment_t *bitrate) +{ + assert(instance < CAN_INSTANCE_COUNT); + + /* Get the time segments*/ + FLEXCAN_HAL_GetTimeSegments(g_flexcanBase[instance], bitrate); + + return kStatus_FLEXCAN_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_SetMasktype + * Description : Set RX masking type. + * This function will set RX masking type as RX global mask or RX individual + * mask. + * + *END**************************************************************************/ +void FLEXCAN_DRV_SetRxMaskType(uint8_t instance, flexcan_rx_mask_type_t type) +{ + assert(instance < CAN_INSTANCE_COUNT); + + FLEXCAN_HAL_SetRxMaskType(g_flexcanBase[instance], type); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_SetRxFifoGlobalMask + * Description : Set Rx FIFO global mask as the 11-bit standard mask or the + * 29-bit extended mask. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_SetRxFifoGlobalMask( + uint8_t instance, + flexcan_msgbuff_id_type_t id_type, + uint32_t mask) +{ + assert(instance < CAN_INSTANCE_COUNT); + + CAN_Type * base = g_flexcanBase[instance]; + + if (id_type == kFlexCanMsgIdStd) + { + /* Set standard global mask for RX FIOF*/ + FLEXCAN_HAL_SetRxFifoGlobalStdMask(base, mask); + } + else if (id_type == kFlexCanMsgIdExt) + { + /* Set extended global mask for RX FIFO*/ + FLEXCAN_HAL_SetRxFifoGlobalExtMask(base, mask); + } + else + { + return kStatus_FLEXCAN_InvalidArgument; + } + + return kStatus_FLEXCAN_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_SetRxMbGlobalMask + * Description : Set Rx Message Buffer global mask as the 11-bit standard mask + * or the 29-bit extended mask. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_SetRxMbGlobalMask( + uint8_t instance, + flexcan_msgbuff_id_type_t id_type, + uint32_t mask) +{ + assert(instance < CAN_INSTANCE_COUNT); + + CAN_Type * base = g_flexcanBase[instance]; + + if (id_type == kFlexCanMsgIdStd) + { + /* Set standard global mask for RX MB*/ + FLEXCAN_HAL_SetRxMsgBuffGlobalStdMask(base, mask); + } + else if (id_type == kFlexCanMsgIdExt) + { + /* Set extended global mask for RX MB*/ + FLEXCAN_HAL_SetRxMsgBuffGlobalExtMask(base, mask); + } + else + { + return kStatus_FLEXCAN_InvalidArgument; + } + + return kStatus_FLEXCAN_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_SetRxIndividualMask + * Description : Set Rx individual mask as the 11-bit standard mask or the + * 29-bit extended mask. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_SetRxIndividualMask( + uint8_t instance, + flexcan_msgbuff_id_type_t id_type, + uint32_t mb_idx, + uint32_t mask) +{ + assert(instance < CAN_INSTANCE_COUNT); + + CAN_Type * base = g_flexcanBase[instance]; + + if (id_type == kFlexCanMsgIdStd) + { + /* Set standard individual mask*/ + return FLEXCAN_HAL_SetRxIndividualStdMask(base, mb_idx, mask); + } + else if (id_type == kFlexCanMsgIdExt) + { + /* Set extended individual mask*/ + return FLEXCAN_HAL_SetRxIndividualExtMask(base, mb_idx, mask); + } + else + { + return kStatus_FLEXCAN_InvalidArgument; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_Init + * Description : Initialize FlexCAN driver. + * This function will select a source clock, reset FlexCAN module, set maximum + * number of message buffers, initialize all message buffers as inactive, enable + * RX FIFO if needed, mask all mask bits, disable all MB interrupts, enable + * FlexCAN normal mode, and enable all the error interrupts if needed. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_Init( + uint32_t instance, + flexcan_state_t *state, + const flexcan_user_config_t *data) +{ + assert(instance < CAN_INSTANCE_COUNT); + assert(state); + + flexcan_status_t result; + CAN_Type * base = g_flexcanBase[instance]; + + /* Enable clock gate to FlexCAN module */ + CLOCK_SYS_EnableFlexcanClock(instance); + + /* Select a source clock for FlexCAN*/ + result = FLEXCAN_HAL_SelectClock(base, kFlexCanClkSourceIpbus); + if (result) + { + return result; + } + + /* Enable the CAN clock */ + FLEXCAN_HAL_Enable(base); + + /* Initialize FLEXCAN device */ + result = FLEXCAN_HAL_Init(base); + if (result) + { + return result; + } + + FLEXCAN_HAL_SetMaxMsgBuffNum(base, data->max_num_mb); + if (data->is_rx_fifo_needed) + { + FLEXCAN_HAL_EnableRxFifo(base, data->num_id_filters); + } + /* Select mode */ + result = FLEXCAN_HAL_SetOperationMode(base, data->flexcanMode); + if (result) + { + return result; + } + + /* Init the interrupt sync object.*/ + OSA_SemaCreate(&state->txIrqSync, 0); + OSA_SemaCreate(&state->rxIrqSync, 0); + /* Enable FlexCAN interrupts.*/ + INT_SYS_EnableIRQ(g_flexcanWakeUpIrqId[instance]); + INT_SYS_EnableIRQ(g_flexcanErrorIrqId[instance]); + INT_SYS_EnableIRQ(g_flexcanBusOffIrqId[instance]); + INT_SYS_EnableIRQ(g_flexcanOredMessageBufferIrqId[instance]); + + state->isTxBusy = false; + state->isRxBusy = false; + state->fifo_message = NULL; + state->rx_mb_idx = 0; + state->tx_mb_idx = 0; + /* Save runtime structure pointers so irq handler can point to the correct state structure */ + g_flexcanStatePtr[instance] = state; + + return (kStatus_FLEXCAN_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_ConfigTxMb + * Description : Configure a Tx message buffer. + * This function will first check if RX FIFO is enabled. If RX FIFO is enabled, + * the function will make sure if the MB requested is not occupied by RX FIFO + * and ID filter table. Then this function will set up the message buffer fields, + * configure the message buffer code for Tx buffer as INACTIVE, and enable the + * Message Buffer interrupt. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_ConfigTxMb( + uint8_t instance, + uint32_t mb_idx, + flexcan_data_info_t *tx_info, + uint32_t msg_id) +{ + assert(instance < CAN_INSTANCE_COUNT); + + flexcan_msgbuff_code_status_t cs; + CAN_Type * base = g_flexcanBase[instance]; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + state->tx_mb_idx = mb_idx; + /* Initialize transmit mb*/ + cs.dataLen = tx_info->data_length; + cs.msgIdType = tx_info->msg_id_type; + cs.code = kFlexCanTXInactive; + return FLEXCAN_HAL_SetTxMsgBuff(base, mb_idx, &cs, msg_id, NULL); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_Send_Blocking + * Description : Set up FlexCAN Message buffer for transmitting data. + * This function will set the MB CODE field as DATA for Tx buffer. Then this + * function will copy user's buffer into the message buffer data area, and wait + * for the Message Buffer interrupt. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_SendBlocking( + uint8_t instance, + uint32_t mb_idx, + flexcan_data_info_t *tx_info, + uint32_t msg_id, + uint8_t *mb_data, + uint32_t timeout_ms) +{ + assert(instance < CAN_INSTANCE_COUNT); + + flexcan_status_t result; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + CAN_Type * base = g_flexcanBase[instance]; + osa_status_t syncStatus; + + state->isTxBlocking = true; + result = FLEXCAN_DRV_StartSendData(instance, mb_idx, tx_info, msg_id, mb_data); + if(result == kStatus_FLEXCAN_Success) + { + /* Enable message buffer interrupt*/ + FLEXCAN_HAL_SetMsgBuffIntCmd(base, mb_idx, true); + /* Enable error interrupts */ + FLEXCAN_HAL_SetErrIntCmd(base,kFlexCanIntErr,true); + do + { + syncStatus = OSA_SemaWait(&state->txIrqSync, timeout_ms); + }while(syncStatus == kStatus_OSA_Idle); + + /* Wait for the interrupt*/ + if (syncStatus != kStatus_OSA_Success) + { + return kStatus_FLEXCAN_TimeOut; + } + } + else + { + return result; + } + + return (kStatus_FLEXCAN_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_Send + * Description : Set up FlexCAN Message buffer for transmitting data. + * This function will set the MB CODE field as DATA for Tx buffer. Then this + * function will copy user's buffer into the message buffer data area. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_Send( + uint8_t instance, + uint32_t mb_idx, + flexcan_data_info_t *tx_info, + uint32_t msg_id, + uint8_t *mb_data) +{ + assert(instance < CAN_INSTANCE_COUNT); + + flexcan_status_t result; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + CAN_Type * base = g_flexcanBase[instance]; + + state->isTxBlocking = false; + + result = FLEXCAN_DRV_StartSendData(instance, mb_idx, tx_info, msg_id, mb_data); + if(result == kStatus_FLEXCAN_Success) + { + /* Enable message buffer interrupt*/ + FLEXCAN_HAL_SetMsgBuffIntCmd(base, mb_idx, true); + /* Enable error interrupts */ + FLEXCAN_HAL_SetErrIntCmd(base,kFlexCanIntErr,true); + } + else + { + return result; + } + + return (kStatus_FLEXCAN_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_ConfigMb + * Description : Configure a Rx message buffer. + * This function will first check if RX FIFO is enabled. If RX FIFO is enabled, + * the function will make sure if the MB requested is not occupied by RX FIFO + * and ID filter table. Then this function will set up the message buffer fields, + * configure the message buffer code for Rx message buffer as NOT_USED, enable + * the Message Buffer interrupt, configure the message buffer code for Rx + * message buffer as INACTIVE, copy user's buffer into the message buffer data + * area, and configure the message buffer code for Rx message buffer as EMPTY. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_ConfigRxMb( + uint8_t instance, + uint32_t mb_idx, + flexcan_data_info_t *rx_info, + uint32_t msg_id) +{ + assert(instance < CAN_INSTANCE_COUNT); + + flexcan_status_t result; + flexcan_msgbuff_code_status_t cs; + CAN_Type * base = g_flexcanBase[instance]; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + state->rx_mb_idx = mb_idx; + cs.dataLen = rx_info->data_length; + cs.msgIdType = rx_info->msg_id_type; + + /* Initialize rx mb*/ + cs.code = kFlexCanRXNotUsed; + result = FLEXCAN_HAL_SetRxMsgBuff(base, mb_idx, &cs, msg_id); + if (result) + { + return result; + } + + /* Initialize receive MB*/ + cs.code = kFlexCanRXInactive; + result = FLEXCAN_HAL_SetRxMsgBuff(base, mb_idx, &cs, msg_id); + if (result) + { + return result; + } + + /* Set up FlexCAN message buffer fields for receiving data*/ + cs.code = kFlexCanRXEmpty; + return FLEXCAN_HAL_SetRxMsgBuff(base, mb_idx, &cs, msg_id); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_ConfigRxFifo + * Description : Confgure RX FIFO ID filter table elements. + * This function will confgure RX FIFO ID filter table elements, and enable RX + * FIFO interrupts. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_ConfigRxFifo( + uint8_t instance, + flexcan_rx_fifo_id_element_format_t id_format, + flexcan_id_table_t *id_filter_table) +{ + assert(instance < CAN_INSTANCE_COUNT); + + flexcan_status_t result; + CAN_Type * base = g_flexcanBase[instance]; + + /* Initialize rx fifo*/ + result = FLEXCAN_HAL_SetRxFifoFilter(base, id_format, id_filter_table); + if(result) + { + return result; + } + + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_RxMessageBufferBlocking + * Description : Start receive data after a Rx MB interrupt occurs. + * This function will lock Rx MB after a Rx MB interrupt occurs. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_RxMessageBufferBlocking( + uint8_t instance, + uint32_t mb_idx, + flexcan_msgbuff_t *data, + uint32_t timeout_ms) +{ + assert(instance < CAN_INSTANCE_COUNT); + assert(data); + + flexcan_status_t result; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + osa_status_t syncStatus; + + state->isRxBlocking = true; + + result = FLEXCAN_DRV_StartRxMessageBufferData(instance, mb_idx, data); + if(result == kStatus_FLEXCAN_Success) + { + do + { + syncStatus = OSA_SemaWait(&state->rxIrqSync, timeout_ms); + }while(syncStatus == kStatus_OSA_Idle); + + /* Wait for the interrupt*/ + if (syncStatus != kStatus_OSA_Success) + { + return kStatus_FLEXCAN_TimeOut; + } + } + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_RxMessageBuffer + * Description : Start receive data after a Rx MB interrupt occurs. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_RxMessageBuffer( + uint8_t instance, + uint32_t mb_idx, + flexcan_msgbuff_t *data) +{ + assert(instance < CAN_INSTANCE_COUNT); + assert(data); + + flexcan_status_t result; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + state->isRxBlocking = false; + + result = FLEXCAN_DRV_StartRxMessageBufferData(instance, mb_idx, data); + + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_RxFifoBlocking + * Description : Start receive data after a Rx FIFO interrupt occurs. + * This function will lock Rx FIFO after a Rx FIFO interrupt occurs + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_RxFifoBlocking( + uint8_t instance, + flexcan_msgbuff_t *data, + uint32_t timeout_ms) +{ + assert(instance < CAN_INSTANCE_COUNT); + assert(data); + + flexcan_status_t result; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + osa_status_t syncStatus; + + state->isRxBlocking = true; + result = FLEXCAN_DRV_StartRxMessageFifoData(instance, data); + if(result == kStatus_FLEXCAN_Success) + { + do + { + syncStatus = OSA_SemaWait(&state->rxIrqSync, timeout_ms); + } while(syncStatus == kStatus_OSA_Idle); + + /* Wait for the interrupt*/ + if (syncStatus != kStatus_OSA_Success) + { + return kStatus_FLEXCAN_TimeOut; + } + } + + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_RxFifoBlocking + * Description : Start receive data after a Rx FIFO interrupt occurs. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_RxFifo( + uint8_t instance, + flexcan_msgbuff_t *data) +{ + assert(instance < CAN_INSTANCE_COUNT); + assert(data); + + flexcan_status_t result; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + state->isRxBlocking = false; + result = FLEXCAN_DRV_StartRxMessageFifoData(instance, data); + + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_Deinit + * Description : Shutdown a FlexCAN module. + * This function will disable all FlexCAN interrupts, and disable the FlexCAN. + * + *END**************************************************************************/ +uint32_t FLEXCAN_DRV_Deinit(uint8_t instance) +{ + assert(instance < CAN_INSTANCE_COUNT); + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + /* Destroy FlexCAN sema. */ + OSA_SemaDestroy(&state->txIrqSync); + OSA_SemaDestroy(&state->rxIrqSync); + /* Disable FlexCAN interrupts.*/ + INT_SYS_DisableIRQ(g_flexcanWakeUpIrqId[instance]); + INT_SYS_DisableIRQ(g_flexcanErrorIrqId[instance]); + INT_SYS_DisableIRQ(g_flexcanBusOffIrqId[instance]); + INT_SYS_DisableIRQ(g_flexcanOredMessageBufferIrqId[instance]); + + /* Disable FlexCAN.*/ + FLEXCAN_HAL_Disable(g_flexcanBase[instance]); + + /* Clear the state pointer */ + g_flexcanStatePtr[instance] = NULL; + + /* Disable clock gate to FlexCAN module */ + CLOCK_SYS_DisableFlexcanClock(instance); + return 0; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_IRQHandler + * Description : Interrupt handler for FLEXCAN. + * This handler read data from MB or FIFO, and then clear the interrupt flags. + * This is not a public API as it is called whenever an interrupt occurs. + * + *END**************************************************************************/ +void FLEXCAN_DRV_IRQHandler(uint8_t instance) +{ + volatile uint32_t flag_reg; + uint32_t temp; + CAN_Type * base = g_flexcanBase[instance]; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + /* Get the interrupts that are enabled and ready */ + flag_reg = ((FLEXCAN_HAL_GetAllMsgBuffIntStatusFlag(base)) & CAN_IMASK1_BUFLM_MASK) & + CAN_RD_IMASK1(base); + + /* Check Tx/Rx interrupt flag and clear the interrupt */ + if(flag_reg) + { + if ((flag_reg & 0x20) && CAN_BRD_MCR_RFEN(base)) + { + if (state->fifo_message != NULL) + { + /* Get RX FIFO field values */ + FLEXCAN_HAL_ReadRxFifo(base, state->fifo_message); + /* Complete receive data */ + FLEXCAN_DRV_CompleteRxMessageFifoData(instance); + FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, flag_reg); + } + } + else + { + /* Check mailbox completed reception*/ + temp = (1 << state->rx_mb_idx); + if (temp & flag_reg) + { + /* Unlock RX message buffer and RX FIFO*/ + FLEXCAN_HAL_LockRxMsgBuff(base, state->rx_mb_idx); + /* Get RX MB field values*/ + FLEXCAN_HAL_GetMsgBuff(base, state->rx_mb_idx, state->mb_message); + /* Unlock RX message buffer and RX FIFO*/ + FLEXCAN_HAL_UnlockRxMsgBuff(base); + + /* Complete receive data */ + FLEXCAN_DRV_CompleteRxMessageBufferData(instance); + FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, temp & flag_reg); + } + /* Check mailbox completed transmission*/ + temp = (1 << state->tx_mb_idx); + if (temp & flag_reg) + { + /* Complete transmit data */ + FLEXCAN_DRV_CompleteSendData(instance); + FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, temp & flag_reg); + } + } + /* Check mailbox completed transmission*/ + temp = (1 << state->tx_mb_idx); + if (flag_reg & temp) + { + /* Complete transmit data */ + FLEXCAN_DRV_CompleteSendData(instance); + FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, temp & flag_reg); + } + } + + /* Clear all other interrupts in ERRSTAT register (Error, Busoff, Wakeup) */ + FLEXCAN_HAL_ClearErrIntStatusFlag(base); + + return; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_GetTransmitStatus + * Description : This function returns whether the previous FLEXCAN receive is + * completed. + * When performing a non-blocking receive, the user can call this function to + * ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_GetTransmitStatus(uint32_t instance) +{ + assert(instance < CAN_INSTANCE_COUNT); + + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + return (state->isTxBusy ? kStatus_FLEXCAN_TxBusy : kStatus_FLEXCAN_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_GetReceiveStatus + * Description : This function returns whether the previous FLEXCAN receive is + * completed. + * When performing a non-blocking receive, the user can call this function to + * ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_GetReceiveStatus(uint32_t instance) +{ + assert(instance < CAN_INSTANCE_COUNT); + + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + return (state->isRxBusy ? kStatus_FLEXCAN_RxBusy : kStatus_FLEXCAN_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_AbortSendingData + * Description : This function ends a non-blocking FLEXCAN transmission early. + * During a non-blocking FLEXCAN transmission, the user has the option to terminate + * the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_AbortSendingData(uint32_t instance) +{ + assert(instance < CAN_INSTANCE_COUNT); + + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!state->isTxBusy) + { + return kStatus_FLEXCAN_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + FLEXCAN_DRV_CompleteSendData(instance); + + return kStatus_FLEXCAN_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_AbortReceivingData + * Description : This function shuts down the FLEXCAN by disabling interrupts and + * the transmitter/receiver. + * This function disables the FLEXCAN interrupts, disables the transmitter and + * receiver. + * + *END**************************************************************************/ +flexcan_status_t FLEXCAN_DRV_AbortReceivingData(uint32_t instance) +{ + assert(instance < CAN_INSTANCE_COUNT); + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!state->isRxBusy) + { + return kStatus_FLEXCAN_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + FLEXCAN_DRV_CompleteRxMessageBufferData(instance); + + return kStatus_FLEXCAN_Success; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_StartSendData + * Description : Initiate (start) a transmit by beginning the process of + * sending data. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static flexcan_status_t FLEXCAN_DRV_StartSendData( + uint8_t instance, + uint32_t mb_idx, + flexcan_data_info_t *tx_info, + uint32_t msg_id, + uint8_t *mb_data + ) +{ + flexcan_status_t result; + flexcan_msgbuff_code_status_t cs; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + CAN_Type * base = g_flexcanBase[instance]; + + if (state->isTxBusy) + { + return kStatus_FLEXCAN_TxBusy; + } + state->isTxBusy = true; + + state->tx_mb_idx = mb_idx; + cs.dataLen = tx_info->data_length; + cs.msgIdType = tx_info->msg_id_type; + + /* Set up FlexCAN message buffer for transmitting data*/ + cs.code = kFlexCanTXData; + result = FLEXCAN_HAL_SetTxMsgBuff(base, mb_idx, &cs, msg_id, mb_data); + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_StartRxMessageBufferData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static flexcan_status_t FLEXCAN_DRV_StartRxMessageBufferData( + uint8_t instance, + uint32_t mb_idx, + flexcan_msgbuff_t *data + ) +{ + flexcan_status_t result; + CAN_Type * base = g_flexcanBase[instance]; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + /* Start receiving mailbox */ + if(state->isRxBusy) + { + return kStatus_FLEXCAN_RxBusy; + } + state->isRxBusy = true; + state->mb_message = data; + + /* Enable MB interrupt*/ + result = FLEXCAN_HAL_SetMsgBuffIntCmd(base, mb_idx, true); + /* Enable error interrupts */ + FLEXCAN_HAL_SetErrIntCmd(base,kFlexCanIntErr,true); + + return result; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_StartRxMessageFifoData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static flexcan_status_t FLEXCAN_DRV_StartRxMessageFifoData( + uint8_t instance, + flexcan_msgbuff_t *data + ) +{ + flexcan_status_t result; + CAN_Type * base = g_flexcanBase[instance]; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + /* Start receiving fifo */ + if(state->isRxBusy) + { + return kStatus_FLEXCAN_RxBusy; + } + state->isRxBusy = true; + + /* This will get filled by the interrupt handler */ + state->fifo_message = data; + + /* Enable RX FIFO interrupts*/ + for (uint8_t i = 5; i <= 7; i++) + { + result = FLEXCAN_HAL_SetMsgBuffIntCmd(base, i, true); + if(result) + { + return result; + } + } + /* Enable error interrupts */ + FLEXCAN_HAL_SetErrIntCmd(base,kFlexCanIntErr,true); + + return kStatus_FLEXCAN_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_CompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXCAN_DRV_CompleteSendData(uint32_t instance) +{ + assert(instance < CAN_INSTANCE_COUNT); + CAN_Type * base = g_flexcanBase[instance]; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + /* Disable the transmitter data register empty interrupt */ + FLEXCAN_HAL_SetMsgBuffIntCmd(base, state->tx_mb_idx, false); + /* Disable error interrupts */ + FLEXCAN_HAL_SetErrIntCmd(base,kFlexCanIntErr,false); + + /* Signal the synchronous completion object. */ + if (state->isTxBlocking) + { + OSA_SemaPost(&state->txIrqSync); + } + + /* Update the information of the module driver state */ + state->isTxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_CompleteRxMessageBufferData + * Description : Finish up a receive by completing the process of receiving + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXCAN_DRV_CompleteRxMessageBufferData(uint32_t instance) +{ + assert(instance < CAN_INSTANCE_COUNT); + + CAN_Type * base = g_flexcanBase[instance]; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + FLEXCAN_HAL_SetMsgBuffIntCmd(base, state->rx_mb_idx, false); + /* Disable error interrupts */ + FLEXCAN_HAL_SetErrIntCmd(base,kFlexCanIntErr,false); + + /* Signal the synchronous completion object. */ + if (state->isRxBlocking) + { + OSA_SemaPost(&state->rxIrqSync); + } + /* Update the information of the module driver state */ + state->isRxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DRV_CompleteRxMessageFifoData + * Description : Finish up a receive by completing the process of receiving + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXCAN_DRV_CompleteRxMessageFifoData(uint32_t instance) +{ + assert(instance < CAN_INSTANCE_COUNT); + uint8_t i; + + CAN_Type * base = g_flexcanBase[instance]; + flexcan_state_t * state = g_flexcanStatePtr[instance]; + + for (i = 5; i <= 7; i++) + { + FLEXCAN_HAL_SetMsgBuffIntCmd(base, i, false); + } + /* Disable error interrupts */ + FLEXCAN_HAL_SetErrIntCmd(base,kFlexCanIntErr,false); + + /* Clear fifo message*/ + state->fifo_message = NULL; + + /* Update status for receive by using fifo*/ + state->isRxBusy = false; + + if(state->isRxBlocking) + { + OSA_SemaPost(&state->rxIrqSync); + } +} +#endif +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/flexcan/fsl_flexcan_irq.c b/KSDK_1.2.0/platform/drivers/src/flexcan/fsl_flexcan_irq.c new file mode 100755 index 0000000..1a1493a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexcan/fsl_flexcan_irq.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexcan_driver.h" +#if FSL_FEATURE_SOC_FLEXCAN_COUNT + +/******************************************************************************* + * Code + ******************************************************************************/ +#if (CAN_INSTANCE_COUNT > 0U) +/* Implementation of CAN0 handler named in startup code. */ +void CAN0_ORed_Message_buffer_IRQHandler(void) +{ + FLEXCAN_DRV_IRQHandler(0); +} + +/* Implementation of CAN0 handler named in startup code. */ +void CAN0_Bus_Off_IRQHandler(void) +{ + FLEXCAN_DRV_IRQHandler(0); +} + +/* Implementation of CAN0 handler named in startup code. */ +void CAN0_Error_IRQHandler(void) +{ + FLEXCAN_DRV_IRQHandler(0); +} + +/* Implementation of CAN0 handler named in startup code. */ +void CAN0_Wake_Up_IRQHandler(void) +{ + FLEXCAN_DRV_IRQHandler(0); +} +#endif + +#if (CAN_INSTANCE_COUNT > 1U) +/* Implementation of CAN1 handler named in startup code. */ +void CAN1_ORed_Message_buffer_IRQHandler(void) +{ + FLEXCAN_DRV_IRQHandler(1); +} + +/* Implementation of CAN1 handler named in startup code. */ +void CAN1_Bus_Off_IRQHandler(void) +{ + FLEXCAN_DRV_IRQHandler(1); +} + +/* Implementation of CAN1 handler named in startup code. */ +void CAN1_Error_IRQHandler(void) +{ + FLEXCAN_DRV_IRQHandler(1); +} + +/* Implementation of CAN1 handler named in startup code. */ +void CAN1_Wake_Up_IRQHandler(void) +{ + FLEXCAN_DRV_IRQHandler(1); +} +#endif +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/flexcan/fsl_flexcan_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/flexcan/fsl_flexcan_lpm_callback.c new file mode 100755 index 0000000..2da753b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexcan/fsl_flexcan_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_FLEXCAN_COUNT + +power_manager_error_code_t flexcan_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t flexcan_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_common.c b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_common.c new file mode 100755 index 0000000..f595d42 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_common.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for FlexIO instances. */ +FLEXIO_Type * const g_flexioBase[] = FLEXIO_BASE_PTRS; + +/* Table to save FlexIO IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_flexioIrqId[FLEXIO_INSTANCE_COUNT] = {UART2_FLEXIO_IRQn}; + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_driver.c b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_driver.c new file mode 100755 index 0000000..42733b1 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_driver.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_driver.h" +#include "fsl_flexio_hal.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_FLEXIO_COUNT +/******************************************************************************* + * Variables + ******************************************************************************/ +flexio_shifter_callback_t shifterIntCallback[FLEXIO_INSTANCE_COUNT][4]; +/*FUNCTION********************************************************************* + * + * Function Name : FLEXIO_DRV_Init + * Description : Initialize the flexio module before using flexio module. + * + *END*************************************************************************/ +flexio_status_t FLEXIO_DRV_Init(uint32_t instance, const flexio_user_config_t *userConfigPtr) +{ + FLEXIO_Type* base = g_flexioBase[instance]; + if (!userConfigPtr) + { + return kStatus_FLEXIO_InvalidArgument; + } + + /* Enable the clock gate for FlexIO. */ + CLOCK_SYS_EnableFlexioClock(instance); + + /* Reset the FlexIO hardware. */ + FLEXIO_HAL_Init(g_flexioBase[instance]); + + /* Disable the FlexIO mode during configure. */ + FLEXIO_DRV_Pause(instance); + + /* Configure the FlexIO's work mode. */ + FLEXIO_HAL_SetDozeModeCmd(base, userConfigPtr->onDozeEnable); + FLEXIO_HAL_SetDebugModeCmd(base, userConfigPtr->onDebugEnable); + FLEXIO_HAL_SetFastAccessCmd(base, userConfigPtr->fastAccessEnable); + + /* Switch on/off the interrupt in NVIC. */ + if (userConfigPtr->useInt) + { + /* Enable the NVIC for FlexIO. */ + INT_SYS_EnableIRQ(g_flexioIrqId[instance]); + } + else + { + /* Disable the NVIC for FlexIO. */ + INT_SYS_DisableIRQ(g_flexioIrqId[instance]); + } + + return kStatus_FLEXIO_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : FLEXIO_DRV_Start + * Description : Enable the flexio's working after configuring the flexio devices. + * + *END*************************************************************************/ +void FLEXIO_DRV_Start(uint32_t instance) +{ + FLEXIO_Type* base = g_flexioBase[instance]; + FLEXIO_HAL_SetFlexioEnableCmd(base, true); +} + +/*FUNCTION********************************************************************* + * + * Function Name : FLEXIO_DRV_Pause + * Description : Disable the flexio's work during configuring the flexio devices. + * + *END*************************************************************************/ +void FLEXIO_DRV_Pause(uint32_t instance) +{ + FLEXIO_Type* base = g_flexioBase[instance]; + FLEXIO_HAL_SetFlexioEnableCmd(base, false); +} + +/*FUNCTION********************************************************************* + * + * Function Name : FLEXIO_DRV_RegisterCallback + * Description : Register the callback function into shifter interrupt. + * + *END*************************************************************************/ +void FLEXIO_DRV_RegisterCallback(uint32_t instance, uint32_t shifterId, + flexio_shifter_int_handler_t shifterIntHandler, + void *param) +{ + shifterIntCallback[instance][shifterId].shifterIntHandler = shifterIntHandler; + shifterIntCallback[instance][shifterId].param = param; +} + +/*FUNCTION********************************************************************* + * + * Function Name : FLEXIO_DRV_Deinit + * Description : Deinitialize the flexio module. + * + *END*************************************************************************/ +flexio_status_t FLEXIO_DRV_Deinit(uint32_t instance) +{ + /* Switch off the interrupt in NVIC. */ + INT_SYS_DisableIRQ(g_flexioIrqId[instance]); + /* Disable the clock gate for FlexIO. */ + CLOCK_SYS_DisableFlexioClock(instance); + + return kStatus_FLEXIO_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_DRV_IRQHandler + * Description : Interrupt handler for FLEXIO. + * This handler polls the shifter status and call the corresponding handler to + * handle the shifter status. + * + *END**************************************************************************/ +void FLEXIO_DRV_IRQHandler(uint32_t instance) +{ + uint32_t shifterMask,shifterNum,shifterStatus,shifterErr,tmp,shifterInt; + shifterNum = FLEXIO_HAL_GetShifterNumber(g_flexioBase[instance]); + shifterStatus = FLEXIO_HAL_GetShifterStatusFlags(g_flexioBase[instance]); + shifterErr = FLEXIO_HAL_GetShifterErrorFlags(g_flexioBase[instance]); + shifterInt = FLEXIO_HAL_GetShifterStatusIntCmd(g_flexioBase[instance]); + if(shifterStatus) + { + for(shifterMask = 0; shifterMask < shifterNum; shifterMask++) + { + tmp = 1<<shifterMask; + if(shifterStatus&tmp) + { + if(shifterInt&tmp) + { + shifterIntCallback[instance][shifterMask].shifterIntHandler(shifterIntCallback[instance][shifterMask].param); + break; + } + } + } + } + if(shifterErr) + { + for(shifterMask = 0; shifterMask < shifterNum; shifterMask++) + { + tmp = 1<<shifterMask; + if(shifterErr&tmp) + { + FLEXIO_HAL_ClearShifterErrorFlags(g_flexioBase[instance],1<<shifterMask); + } + } + } +} + +#endif + +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_i2c_master_driver.c b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_i2c_master_driver.c new file mode 100755 index 0000000..30c5ba9 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_i2c_master_driver.c @@ -0,0 +1,801 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 <string.h> +#include "fsl_flexio_i2c_master_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_FLEXIO_COUNT +/******************************************************************************* + * Prototype + ******************************************************************************/ +static uint32_t isTx = 0; +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static flexio_i2c_status_t FLEXIO_I2C_DRV_MasterStartSendData(flexio_i2c_state_t *i2cState, + uint16_t slaveAddr, + flexio_i2c_memrequest_t *memRequest, + uint8_t * txBuff, + uint32_t txSize); +static flexio_i2c_status_t FLEXIO_I2C_DRV_MasterStartReceiveData(flexio_i2c_state_t *i2cState, + uint16_t slaveAddr, + flexio_i2c_memrequest_t *memRequest, + uint8_t * rxBuff, + uint32_t rxSize); +static void FLEXIO_I2C_DRV_MasterCompleteTransferData(flexio_i2c_state_t *i2cState); +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_Init + * Description : Initialize a I2C device for operation. + * This function will initialize the run-time state structure to keep track of + * the on-going transfers,initialize the module to user defined settings and + * default settings, configures underlying flexio Pin,shifter and timer. + * The following is an example of how to set up the flexio_i2c_state_t and the + * flexio_i2c_userconfig_t parameters and how to call the FLEXIO_I2C_DRV_Init function + * by passing in these parameters: + * flexio_i2c_state_t i2cState; + flexio_i2c_userconif_t i2cMasterConfig; + i2cMasterConfig.baudRate = 100000; + i2cMasterConfig.i2cHwConfig.sdaPinIdx = 0; + i2cMasterConfig.i2cHwConfig.sclkPinIdx = 1; + i2cMasterConfig.i2cHwConfig.shifterIdx = {0,1}; + i2cMasterConfig.i2cHwConfig.timerIdx = {0,1}; + * FLEXIO_I2C_DRV_MasterInit(instance, &i2cState, &i2cMasterConfig); + * + *END**************************************************************************/ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterInit(uint32_t instance, flexio_i2c_state_t *i2cState, + flexio_i2c_userconfig_t *i2cMasterConfig) +{ + if((i2cState == NULL)||(i2cMasterConfig == NULL)) + { + return kStatus_FlexIO_I2C_InvalidParam; + } + FLEXIO_Type* base = g_flexioBase[instance]; + /*Reset the i2cState structure*/ + memset(i2cState,0,sizeof(*i2cState)); + /*Create semaphore for xIrq*/ + OSA_SemaCreate(&i2cState->xIrqSync,0); + /*Init FlexIO I2C resource*/ + i2cState->i2cDev.flexioBase = base; + i2cState->i2cDev.sdaPinIdx = i2cMasterConfig->i2cHwConfig.sdaPinIdx; + i2cState->i2cDev.sckPinIdx = i2cMasterConfig->i2cHwConfig.sclkPinIdx; + i2cState->i2cDev.shifterIdx[0] = i2cMasterConfig->i2cHwConfig.shifterIdx[0]; + i2cState->i2cDev.shifterIdx[1] = i2cMasterConfig->i2cHwConfig.shifterIdx[1]; + i2cState->i2cDev.timerIdx[0] = i2cMasterConfig->i2cHwConfig.timerIdx[0]; + i2cState->i2cDev.timerIdx[1] = i2cMasterConfig->i2cHwConfig.timerIdx[1]; + flexio_i2c_master_config_t masterConfig; + /*Get FlexIO clock frequency for baudrate calculation*/ + masterConfig.flexioBusClk = CLOCK_SYS_GetFlexioFreq(instance); + masterConfig.baudrate = i2cMasterConfig->baudRate; + FLEXIO_I2C_HAL_ConfigMaster(&(i2cState->i2cDev),&masterConfig); + FLEXIO_DRV_RegisterCallback(instance,i2cState->i2cDev.shifterIdx[0], + FLEXIO_I2C_DRV_TX_IRQHandler,(void *)(i2cState)); + FLEXIO_DRV_RegisterCallback(instance,i2cState->i2cDev.shifterIdx[1], + FLEXIO_I2C_DRV_RX_IRQHandler,(void *)(i2cState)); + return kStatus_FlexIO_I2C_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_Deinit + * Description : Shutdown a FlexIO simulated I2C device. + * This function destroy the semaphores + * + *END**************************************************************************/ +void FLEXIO_I2C_DRV_Deinit(flexio_i2c_state_t *i2cState) +{ + /* Destroy transfer sema. */ + OSA_SemaDestroy(&i2cState->xIrqSync); +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_MasterInstallRxCallback + * Description : Install receive data callback function, pass in NULL pointer + * as callback will unistall. + * + *END**************************************************************************/ +flexio_i2c_rx_callback_t FLEXIO_I2C_DRV_MasterInstallRxCallback(flexio_i2c_state_t *i2cState, + flexio_i2c_rx_callback_t function, + void * callbackParam) +{ + flexio_i2c_rx_callback_t currentCallback = i2cState->rxCallback; + i2cState->rxCallback = function; + i2cState->rxCallbackParam = callbackParam; + return currentCallback; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_MasterSendDataBlocking + * Description : This function sends (transmits) data out through the FlexIO + * simulated I2C module using a blocking method. + * A blocking (also known as synchronous) function means that the function does + * not return until the transmit is complete. This blocking function is used to + * send data through the FlexIO simulated I2C port. + * + *END**************************************************************************/ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterSendDataBlocking(flexio_i2c_state_t *i2cState, + uint16_t slaveAddr, + flexio_i2c_memrequest_t *memRequest, + uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + if((i2cState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_I2C_InvalidParam; + } + flexio_i2c_status_t retVal = kStatus_FlexIO_I2C_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking.*/ + i2cState->isXBlocking = true; + + /* Start the transmission process */ + retVal = FLEXIO_I2C_DRV_MasterStartSendData(i2cState, slaveAddr, memRequest, txBuff, txSize); + + if (retVal == kStatus_FlexIO_I2C_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&i2cState->xIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable the transmitter data register empty interrupt */ + FLEXIO_I2C_HAL_SetTxBufferEmptyIntCmd(&(i2cState->i2cDev), false); + /* Update the information of the module driver state */ + i2cState->isXBusy = false; + + retVal = kStatus_FlexIO_I2C_Timeout; + } + } + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_MasterSendData + * Description : This function sends (transmits) data through the FlexIO simulated + * I2C module using a non-blocking method. + * A non-blocking (also known as asynchronous) function means that the function + * returns immediately after initiating the transmit function. The application + * has to get the transmit status to see when the transmit is complete. In + * other words, after calling non-blocking (asynchronous) send function, the + * application must get the transmit status to check if transmit is completed + * or not. + * + *END**************************************************************************/ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterSendData(flexio_i2c_state_t *i2cState, + uint16_t slaveAddr, + flexio_i2c_memrequest_t *memRequest, + uint8_t * txBuff, + uint32_t txSize) +{ + if((i2cState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_I2C_InvalidParam; + } + + flexio_i2c_status_t retVal = kStatus_FlexIO_I2C_Success; + + /* Indicates current transaction is non-blocking */ + i2cState->isXBlocking = false; + + /* Start the transmission process */ + retVal = FLEXIO_I2C_DRV_MasterStartSendData(i2cState, slaveAddr, memRequest, txBuff, txSize); + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_MasterGetTransmitStatus + * Description : This function returns whether the previous transmit has + * finished. + * When performing an non-blocking transmit, the user can call this function to + * ascertain the state of the current transmission: in progress (or busy) or + * complete (success). In addition, if the transmission is still in progress, + * the user can obtain the number of words that have been currently transferred. + * + *END**************************************************************************/ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterGetTransmitStatus(flexio_i2c_state_t *i2cState, uint32_t * bytesRemaining) +{ + if(i2cState == NULL) + { + return kStatus_FlexIO_I2C_InvalidParam; + } + + flexio_i2c_status_t retVal = kStatus_FlexIO_I2C_Success; + uint32_t txSize = i2cState->xSize; + + /* Fill in the bytes transferred. This may return that all bytes were + * transmitted.*/ + if (bytesRemaining) + { + *bytesRemaining = txSize; + } + + if (txSize) + { + retVal = kStatus_FlexIO_I2C_XBusy; + } + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_MasterAbortSendingData + * Description : This function ends a non-blocking I2C transmission early. + * During a non-blocking I2C transmission, the user has the option to terminate + * the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterAbortSendingData(flexio_i2c_state_t *i2cState) +{ + if(i2cState == NULL) + { + return kStatus_FlexIO_I2C_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!i2cState->isXBusy) + { + return kStatus_FlexIO_I2C_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + FLEXIO_I2C_DRV_MasterCompleteTransferData(i2cState); + + return kStatus_FlexIO_I2C_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_MasterReceiveDataBlocking + * Description : This function gets (receives) data from the I2C module using + * a blocking method. A blocking (also known as synchronous) function means that + * the function does not return until the receive is complete. This blocking + * function is used to send data through the I2C port. + * + *END**************************************************************************/ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterReceiveDataBlocking(flexio_i2c_state_t *i2cState, + uint16_t slaveAddr, + flexio_i2c_memrequest_t *memRequest, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout) +{ + if((i2cState == NULL)||(rxBuff == NULL)) + { + return kStatus_FlexIO_I2C_InvalidParam; + } + + flexio_i2c_status_t retVal = kStatus_FlexIO_I2C_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking.*/ + i2cState->isXBlocking = true; + + retVal = FLEXIO_I2C_DRV_MasterStartReceiveData(i2cState, slaveAddr, memRequest, rxBuff, rxSize); + + if (retVal == kStatus_FlexIO_I2C_Success) + { + /* Wait until all the data is received or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&i2cState->xIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable receive data full and rx overrun interrupt */ + FLEXIO_I2C_HAL_SetRxBufferFullIntCmd(&(i2cState->i2cDev), false); + /* Update the information of the module driver state */ + i2cState->isXBusy = false; + + retVal = kStatus_FlexIO_I2C_Timeout; + } + } + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_MasterReceiveData + * Description : This function gets (receives) data from the simluated I2C + * module using a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. In other + * words, after calling non-blocking (asynchronous) get function, the + * application must get the receive status to check if receive is completed or + * not. + * + *END**************************************************************************/ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterReceiveData(flexio_i2c_state_t *i2cState, + uint16_t slaveAddr, + flexio_i2c_memrequest_t *memRequest, + uint8_t * rxBuff, + uint32_t rxSize) +{ + if((i2cState == NULL)||(rxBuff == NULL)) + { + return kStatus_FlexIO_I2C_InvalidParam; + } + + flexio_i2c_status_t retVal = kStatus_FlexIO_I2C_Success; + + /* Indicates current transaction is non-blocking.*/ + i2cState->isXBlocking = false; + + retVal = FLEXIO_I2C_DRV_MasterStartReceiveData(i2cState, slaveAddr, memRequest, rxBuff, rxSize); + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_MasterGetReceiveStatus + * Description : This function returns whether the previous UART receive is + * completed. + * When performing a non-blocking receive, the user can call this function to + * ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, the + * user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterGetReceiveStatus(flexio_i2c_state_t *i2cState, + uint32_t * bytesRemaining) +{ + if(i2cState == NULL) + { + return kStatus_FlexIO_I2C_InvalidParam; + } + flexio_i2c_status_t retVal = kStatus_FlexIO_I2C_Success; + uint32_t rxSize = i2cState->xSize; + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = rxSize; + } + + if (rxSize) + { + retVal = kStatus_FlexIO_I2C_XBusy; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_MasterAbortReceivingData + * Description : This function aborts data receive. + * + *END**************************************************************************/ +flexio_i2c_status_t FLEXIO_I2C_DRV_AbortReceivingData(flexio_i2c_state_t *i2cState) +{ + if(i2cState == NULL) + { + return kStatus_FlexIO_I2C_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!i2cState->isXBusy) + { + return kStatus_FlexIO_I2C_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + FLEXIO_I2C_DRV_MasterCompleteTransferData(i2cState); + + return kStatus_FlexIO_I2C_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_TX_IRQHandler + * Description : Interrupt i2cState for SDO for FlexIO I2C device. + * This i2cState uses the buffers stored in the flexio_i2c_state_t struct to send + * data. This is not a public API as it is called whenever an interrupt occurs. + * + *END**************************************************************************/ +void FLEXIO_I2C_DRV_TX_IRQHandler(void *param) +{ + flexio_i2c_state_t *i2cState = (flexio_i2c_state_t *)param; + if(i2cState == NULL) + { + return; + } + + /* Exit the ISR if no transfer is happening for this instance. */ + if (!i2cState->isXBusy) + { + return; + } + /*Read rx shifter to avoid overrun.*/ + FLEXIO_I2C_HAL_GetData(&(i2cState->i2cDev)); + /* Handle transmit data register empty interrupt */ + --i2cState->xSize; + /* Check to see if there are any more bytes to send */ + if (i2cState->xSize) + { + /* Transmit data and update tx size/buff */ + ++i2cState->xBuff; + FLEXIO_I2C_HAL_PutData(&(i2cState->i2cDev), *(i2cState->xBuff)); + } + else + { + /* Send STOP condition. */ + FLEXIO_I2C_HAL_ConfigXferWordCountOnce(&(i2cState->i2cDev),0); + FLEXIO_I2C_HAL_PutData(&(i2cState->i2cDev), 0x0); + FLEXIO_I2C_DRV_MasterCompleteTransferData(i2cState); + } +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_RX_IRQHandler + * Description : Interrupt i2cState for SDI for FlexIO I2C device. + * This i2cState uses the buffers stored in the flexio_uart_state_t struct to transfer + * data. This is not a public API as it is called whenever an interrupt occurs. + * + *END**************************************************************************/ +void FLEXIO_I2C_DRV_RX_IRQHandler(void *param) +{ + flexio_i2c_state_t *i2cState = (flexio_i2c_state_t *)param; + if(i2cState == NULL) + { + return; + } + + /* Exit the ISR if no transfer is happening for this instance. */ + if (!(i2cState->isXBusy)) + { + return; + } + if(isTx) + { + isTx = 0; + FLEXIO_I2C_HAL_SetRxBufferFullIntCmd(&(i2cState->i2cDev), false); + if(FLEXIO_I2C_HAL_GetRxErrFlag(&(i2cState->i2cDev))) + { + /*Receive NACK from slave, send stop*/ + FLEXIO_I2C_HAL_ClearRxErrFlag(&(i2cState->i2cDev)); + FLEXIO_WR_TIMCFG_TIMDIS(g_flexioBase[0],(i2cState->i2cDev).timerIdx[0],4); + /* Send STOP condition. */ + FLEXIO_I2C_DRV_MasterCompleteTransferData(i2cState); + } + return; + } + /* Handle transmit data register empty interrupt */ + uint32_t tmp = FLEXIO_I2C_HAL_GetData(&(i2cState->i2cDev)); + *(i2cState->xBuff) = tmp>>24; + FLEXIO_I2C_HAL_PutData(&(i2cState->i2cDev), 0xFFFFFFFF); + ++i2cState->xBuff; + --i2cState->xSize; + if(i2cState->xSize == 1) + { + FLEXIO_I2C_HAL_ConfigSendNAck(&(i2cState->i2cDev)); + } + if(i2cState->xSize == 0) + { + /* Send STOP condition. */ + FLEXIO_I2C_HAL_ConfigXferWordCountOnce(&(i2cState->i2cDev),0); + FLEXIO_I2C_HAL_PutData(&(i2cState->i2cDev), 0x0); + FLEXIO_I2C_DRV_MasterCompleteTransferData(i2cState); + if (i2cState->rxCallback != NULL) + { + i2cState->rxCallback(i2cState); + } + } +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_MasterSendAddress + * Description : Initiate (start) a transmit by beginning the process of + * sending slave address. + * + *END**************************************************************************/ +flexio_i2c_status_t FLEXIO_I2C_DRV_MasterSendAddress(flexio_i2c_state_t *i2cState, + uint16_t slaveAddr, + flexio_i2c_direction_t direction, + flexio_i2c_memrequest_t *memRequest) +{ + uint8_t addrByte1, addrByte2, directionBit; + bool is10bitAddr; + /* Make sure the transmit data register is empty and ready for data */ + while(!FLEXIO_I2C_HAL_GetTxBufferEmptyFlag(&(i2cState->i2cDev))) { } + + /*--------------- Prepare Address Buffer ------------------*/ + /* Get r/w bit according to required direction. + * read is 1, write is 0. */ + directionBit = (direction == kFlexIOI2CRead) ? 0x1U : 0x0U; + + /* Check to see if slave address is 10 bits or not. */ + is10bitAddr = ((slaveAddr >> 10U) == 0x1EU) ? true : false; + + /* Get address byte 1 and byte 2 according address bit number. */ + if (is10bitAddr) + { + addrByte1 = (uint8_t)(slaveAddr >> 8U); + addrByte2 = (uint8_t)slaveAddr; + } + else + { + addrByte1 = (uint8_t)slaveAddr; + } + + /* Get the device address with r/w direction. If we have a sub-address, + then that is always done as a write transfer prior to transferring + the actual data.*/ + addrByte1 = addrByte1 << 1U; + + /* First need to write if 10-bit address or has cmd buffer. */ + addrByte1 |= (uint8_t)((is10bitAddr || memRequest) ? 0U : directionBit); + + /* Put the slave address in shifter to start the transmission */ + FLEXIO_I2C_HAL_PutData(&(i2cState->i2cDev), addrByte1); + FLEXIO_I2C_HAL_GetData(&(i2cState->i2cDev)); + FLEXIO_I2C_HAL_GetData(&(i2cState->i2cDev)); + FLEXIO_I2C_HAL_GetData(&(i2cState->i2cDev)); + + if (is10bitAddr) + { + /* Put address byte 2 into shifter. */ + while(!FLEXIO_I2C_HAL_GetRxBufferFullFlag(&(i2cState->i2cDev))){} + FLEXIO_I2C_HAL_PutData(&(i2cState->i2cDev), addrByte2 ); + FLEXIO_I2C_HAL_GetData(&(i2cState->i2cDev)); + } + /*If the operation is a memory operation, send the memory address*/ + if(memRequest) + { + for (uint8_t i = 0U; i < memRequest->memAddrSize; i++) + { + while(!FLEXIO_I2C_HAL_GetRxBufferFullFlag(&(i2cState->i2cDev))){} + FLEXIO_I2C_HAL_PutData(&(i2cState->i2cDev), *(memRequest->memAddress+i)); + FLEXIO_I2C_HAL_GetData(&(i2cState->i2cDev)); + } + } + /* Send slave address again if receiving data from 10-bit address slave, + OR conducting a memory read */ + if((direction == kFlexIOI2CRead)&&(memRequest||is10bitAddr)) + { + /* Prepare for RESTART condition, no stop.*/ + FLEXIO_I2C_HAL_PutData(&(i2cState->i2cDev), 0xFFFFFFFF); + FLEXIO_I2C_HAL_GetData(&(i2cState->i2cDev)); + } + + return kStatus_FlexIO_I2C_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_MasterStartSendData + * Description : Initiate (start) a transmit by beginning the process of + * sending data and enabling the interrupt. + * + *END**************************************************************************/ +static flexio_i2c_status_t FLEXIO_I2C_DRV_MasterStartSendData(flexio_i2c_state_t *i2cState, + uint16_t slaveAddr, + flexio_i2c_memrequest_t *memRequest, + uint8_t * txBuff, + uint32_t txSize) +{ + flexio_i2c_status_t result = kStatus_FlexIO_I2C_Success; + /* Check that we're not busy already transmitting data from a previous + * function call. */ + if (i2cState->isXBusy) + { + return kStatus_FlexIO_I2C_XBusy; + } + + if (txSize == 0U) + { + return kStatus_FlexIO_I2C_NoDataToDeal; + } + /* Initialize the module driver state structure. */ + i2cState->xBuff = txBuff; + i2cState->xSize = txSize; + i2cState->isXBusy = true; + /* Make sure the transmit data register is empty and ready for data */ + while(!FLEXIO_I2C_HAL_GetTxBufferEmptyFlag(&(i2cState->i2cDev))) { } + /*Calculate total bytes in the I2C frame*/ + bool is10bitAddr = ((slaveAddr >> 10U) == 0x1EU) ? true : false; + uint32_t byteCount = txSize + 1; + if(is10bitAddr) + { + byteCount++; + } + else if(memRequest) + { + byteCount += memRequest->memAddrSize; + } + /*Config total bytes in the I2C frame*/ + FLEXIO_I2C_HAL_ConfigXferWordCountOnce(&(i2cState->i2cDev),byteCount); + /*Send slave address and memory address(if a memory request)*/ + result = FLEXIO_I2C_DRV_MasterSendAddress(i2cState, slaveAddr, kFlexIOI2CWrite, memRequest); + if(result != kStatus_FlexIO_I2C_Success) + { + return result; + } + /* Put the first data in shifter to start the transmission */ + FLEXIO_I2C_HAL_PutData(&(i2cState->i2cDev), *(txBuff)); + /* Enable interrupt generation for tx shifter. */ + + FLEXIO_I2C_HAL_SetTxBufferEmptyIntCmd(&(i2cState->i2cDev), true); + isTx = 1; + FLEXIO_I2C_HAL_SetRxBufferFullIntCmd(&(i2cState->i2cDev), true); + return kStatus_FlexIO_I2C_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_StartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static flexio_i2c_status_t FLEXIO_I2C_DRV_MasterStartReceiveData(flexio_i2c_state_t *i2cState, + uint16_t slaveAddr, + flexio_i2c_memrequest_t *memRequest, + uint8_t * rxBuff, + uint32_t rxSize) +{ + flexio_i2c_status_t result = kStatus_FlexIO_I2C_Success; + if(i2cState == NULL) + { + return kStatus_FlexIO_I2C_InvalidParam; + } + + /* Check that we're not busy receiving data from a previous function call. */ + if (i2cState->isXBusy) + { + return kStatus_FlexIO_I2C_XBusy; + } + + if (rxSize == 0U) + { + return kStatus_FlexIO_I2C_NoDataToDeal; + } + + /* Initialize the module driver state structure to indicate transfer in progress + * and with the buffer and byte count data */ + i2cState->xBuff = rxBuff; + i2cState->xSize = rxSize; + i2cState->isXBusy = true; + /*Calculate total bytes in the I2C frame*/ + bool is10bitAddr = ((slaveAddr >> 10U) == 0x1EU) ? true : false; + uint32_t byteCount = 1; + if(is10bitAddr) + { + byteCount++; + } + else + { + if(memRequest) + { + byteCount += memRequest->memAddrSize; + } + else + { + byteCount +=rxSize; + } + } + /*Config total bytes in the I2C frame*/ + FLEXIO_I2C_HAL_ConfigXferWordCountOnce(&(i2cState->i2cDev),byteCount); + /*Send slave address and memory address(if a memory request)*/ + result = FLEXIO_I2C_DRV_MasterSendAddress(i2cState, slaveAddr, kFlexIOI2CRead, memRequest); + while(!FLEXIO_I2C_HAL_GetRxBufferFullFlag(&(i2cState->i2cDev))){} + if(FLEXIO_I2C_HAL_GetRxErrFlag(&(i2cState->i2cDev))) + { + /*Receive NACK from slave, send stop*/ + FLEXIO_I2C_HAL_ClearRxErrFlag(&(i2cState->i2cDev)); + FLEXIO_WR_TIMCFG_TIMDIS(g_flexioBase[0],(i2cState->i2cDev).timerIdx[0],4); + /* Send STOP condition. */ + FLEXIO_I2C_DRV_MasterCompleteTransferData(i2cState); + return result; + } + if(result != kStatus_FlexIO_I2C_Success) + { + return result; + } + /*if 10-bit slave read, needs a second I2C Frame, calculate the total byetes of second frame*/ + if(is10bitAddr || memRequest) + { + byteCount = rxSize + 1 ; + /*Config total bytes in the second I2C frame*/ + FLEXIO_I2C_HAL_ConfigXferWordCountOnce(&(i2cState->i2cDev),byteCount); + /* Send address byte 1 again. */ + if(is10bitAddr) + { + FLEXIO_I2C_HAL_PutData(&(i2cState->i2cDev), (((slaveAddr >> 8)<<1) | 1U)); + + } + else + { + FLEXIO_I2C_HAL_PutData(&(i2cState->i2cDev), ((slaveAddr << 1)| 1U)); + } + FLEXIO_I2C_HAL_GetData(&(i2cState->i2cDev)); + while(!FLEXIO_I2C_HAL_GetRxBufferFullFlag(&(i2cState->i2cDev))){} + } + /*if single byte read, config send NACK*/ + if(rxSize == 1) + { + FLEXIO_I2C_HAL_ConfigSendNAck(&(i2cState->i2cDev)); + } + /*else config send ACK*/ + else + { + FLEXIO_I2C_HAL_ConfigSendAck(&(i2cState->i2cDev)); + } + FLEXIO_I2C_HAL_PutDataPolling(&(i2cState->i2cDev),0xFFFFFFFF); + FLEXIO_I2C_HAL_GetData(&(i2cState->i2cDev)); + /* Enable the receive data full interrupt */ + isTx = 0; + FLEXIO_I2C_HAL_SetRxBufferFullIntCmd(&(i2cState->i2cDev), true); + + return kStatus_FlexIO_I2C_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2C_DRV_CompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXIO_I2C_DRV_MasterCompleteTransferData(flexio_i2c_state_t *i2cState) +{ + if(i2cState == NULL) + { + return; + } + + /* Disable the transmitter data register empty interrupt */ + FLEXIO_I2C_HAL_SetTxBufferEmptyIntCmd(&(i2cState->i2cDev), false); + /* Disable receive data full interrupt */ + FLEXIO_I2C_HAL_SetRxBufferFullIntCmd(&(i2cState->i2cDev), false); + /*Clear Tx/Rx overrun/underrun flag*/ + FLEXIO_I2C_HAL_ClearTxErrFlag(&(i2cState->i2cDev)); + FLEXIO_I2C_HAL_ClearRxErrFlag(&(i2cState->i2cDev)); + + /* Signal the synchronous completion object. */ + if (i2cState->isXBlocking) + { + OSA_SemaPost(&i2cState->xIrqSync); + } + + /* Update the information of the module driver state */ + i2cState->isXBusy = false; +} + +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_i2s_driver.c b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_i2s_driver.c new file mode 100755 index 0000000..fc60de4 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_i2s_driver.c @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + #include "fsl_flexio_i2s_driver.h" + #include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_FLEXIO_COUNT + + +void FLEXIO_I2S_DRV_TxIrq(void *param); +void FLEXIO_I2S_DRV_RxIrq(void *param); + +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL +void FLEXIO_I2S_DRV_EdmaTxCallback(void *param, edma_chn_status_t status); +void FLEXIO_I2S_DRV_EdmaRxCallback(void *param, edma_chn_status_t status); +#else +void FLEXIO_I2S_DRV_DmaTxCallback(void *param, dma_channel_status_t status); +void FLEXIO_I2S_DRV_DmaRxCallback(void *param, dma_channel_status_t status); +#endif + + + /*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_Init + * Description : Initialize flexio I2S state structure. + * This functionconfigure flexio and initialize the state handler. + *END**************************************************************************/ +flexio_i2s_status_t FLEXIO_I2S_DRV_Init(uint32_t instance, flexio_i2s_handler_t *handler, + flexio_i2s_config_t * userConfig) +{ + if ((handler == NULL) || (userConfig == NULL)) + { + return kStatus_FlexioI2S_InvalidParameter; + } + FLEXIO_Type * base = g_flexioBase[instance]; + handler->device.flexioBase = base; + handler->device.txPinIdx = userConfig->txPinIdx; + handler->device.rxPinIdx = userConfig->rxPinIdx; + handler->device.sckPinIdx = userConfig->sckPinIdx; + handler->device.wsPinIdx = userConfig->wsPinIdx; + handler->device.shifterIdx[0] = userConfig->shifterIdx[0]; + handler->device.shifterIdx[1] = userConfig->shifterIdx[1]; + handler->device.timerIdx[0] = userConfig->timerIdx[0]; + handler->device.timerIdx[1] = userConfig->timerIdx[1]; + handler->sample_rate = userConfig->sample_rate; + handler->bit_depth = userConfig->data_depth; + /* Initialize the statement of handler */ + handler->tx_buffer = NULL; + handler->rx_buffer = NULL; + handler->tx_length = 0; + handler->rx_length = 0; + handler->tx_finished_bytes = 0; + handler->rx_finished_bytes = 0; + handler->tx_active = false; + handler->rx_active = false; + OSA_SemaCreate(&handler->tx_sem, 0); + OSA_SemaCreate(&handler->rx_sem, 0); + handler->tx_use_dma = false; + handler->rx_use_dma = false; + /* Configure flexio */ + if (userConfig->master_slave == kFlexioI2SMaster) + { + flexio_i2s_master_config_t master; + master.flexioBusClk = CLOCK_SYS_GetFlexioFreq(instance); + master.bitClk = userConfig->sample_rate * 32 * 2; + master.bitCount = userConfig->data_depth; + FLEXIO_I2S_HAL_Configure_Master(&handler->device, &master); + } + else + { + flexio_i2s_slave_config_t slave; + slave.bitCount = userConfig->data_depth; + FLEXIO_I2S_HAL_Configure_Slave(&handler->device, &slave); + } + FLEXIO_DRV_RegisterCallback(instance,userConfig->shifterIdx[0], + FLEXIO_I2S_DRV_TxIrq, handler); + FLEXIO_DRV_RegisterCallback(instance,userConfig->shifterIdx[1], + FLEXIO_I2S_DRV_RxIrq, handler); + return kStatus_FlexioI2S_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_Deinit + * Description : Deinit flexio I2S. + * This function clear i2s state. + *END**************************************************************************/ +flexio_i2s_status_t FLEXIO_I2S_DRV_Deinit(flexio_i2s_handler_t *handler) +{ + /* Release dma channel */ + if (handler->tx_use_dma) + { +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + EDMA_DRV_ReleaseChannel(&handler->tx_edma_state); +#else + DMA_DRV_FreeChannel(&handler->tx_dma_chn); +#endif + } + if (handler->rx_use_dma) + { +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + EDMA_DRV_ReleaseChannel(&handler->rx_edma_state); +#else + DMA_DRV_FreeChannel(&handler->rx_dma_chn); +#endif + } + memset(&handler, 0, sizeof(flexio_i2s_handler_t)); + return kStatus_FlexioI2S_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_TxStart + * Description : Start transfer data in tx port. + * This function enables tx interrupt request or dma request. + *END**************************************************************************/ +flexio_i2s_status_t FLEXIO_I2S_DRV_TxStart(flexio_i2s_handler_t *handler) +{ + handler->tx_active = true; + FLEXIO_I2S_HAL_SetTxErrIntCmd(&handler->device, true); + if (handler->tx_use_dma) + { + FLEXIO_I2S_HAL_SetTxDmaCmd(&handler->device, true); + } + else + { + FLEXIO_I2S_HAL_SetTxBufferEmptyIntCmd(&handler->device, true); + } + return kStatus_FlexioI2S_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_RxStart + * Description : Start transfer data in rx port. + * This function enables rx interrupt request or dma request. + *END**************************************************************************/ +flexio_i2s_status_t FLEXIO_I2S_DRV_RxStart(flexio_i2s_handler_t *handler) +{ + handler->rx_active = true; + FLEXIO_I2S_HAL_SetRxErrIntCmd(&handler->device, true); + if (handler->rx_use_dma) + { + FLEXIO_I2S_HAL_SetRxDmaCmd(&handler->device, true); + } + else + { + FLEXIO_I2S_HAL_SetRxBufferFullIntCmd(&handler->device, true); + } + return kStatus_FlexioI2S_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_TxStop + * Description : Stop transfer data in tx port. + * This function disables tx interrupt request or dma request. + *END**************************************************************************/ +flexio_i2s_status_t FLEXIO_I2S_DRV_TxStop(flexio_i2s_handler_t *handler) +{ + handler->tx_active = false; + FLEXIO_I2S_HAL_SetTxBufferEmptyIntCmd(&handler->device, false); + FLEXIO_I2S_HAL_SetTxErrIntCmd(&handler->device, false); + if (handler->tx_use_dma) + { + FLEXIO_I2S_HAL_SetTxDmaCmd(&handler->device, false); + } + return kStatus_FlexioI2S_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_RxStop + * Description : Stop transfer data in rx port. + * This function disables rx interrupt request or dma request. + *END**************************************************************************/ +flexio_i2s_status_t FLEXIO_I2S_DRV_RxStop(flexio_i2s_handler_t *handler) +{ + handler->rx_active = false; + FLEXIO_I2S_HAL_SetRxBufferFullIntCmd(&handler->device, false); + FLEXIO_I2S_HAL_SetRxErrIntCmd(&handler->device, false); + if (handler->rx_use_dma) + { + FLEXIO_I2S_HAL_SetRxDmaCmd(&handler->device, false); + } + return kStatus_FlexioI2S_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_SendDataInt + * Description : Send a period of data using interrupt way. + * This function is an async function. + *END**************************************************************************/ +flexio_i2s_status_t FLEXIO_I2S_DRV_SendDataInt(flexio_i2s_handler_t *handler, uint8_t *addr, uint32_t len) +{ + if ((handler == NULL) || (addr == NULL) || (len == 0)) + { + return kStatus_FlexioI2S_InvalidParameter; + } + handler->tx_length = len; + handler->tx_buffer = addr; + handler->tx_finished_bytes = 0; + FLEXIO_I2S_DRV_TxStart(handler); + return kStatus_FlexioI2S_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_ReceiveDataInt + * Description : Receive a period of data using interrupt way. + * This function is an async function. + *END**************************************************************************/ +flexio_i2s_status_t FLEXIO_I2S_DRV_ReceiveDataInt(flexio_i2s_handler_t *handler, uint8_t *addr, uint32_t len) +{ + if ((handler == NULL) || (addr == NULL) || (len == 0)) + { + return kStatus_FlexioI2S_InvalidParameter; + } + handler->rx_length = len; + handler->rx_buffer = addr; + handler->rx_finished_bytes = 0; + FLEXIO_I2S_DRV_RxStart(handler); + return kStatus_FlexioI2S_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_SendDataDma + * Description : Send a period of data using DMA way. + * This function is an async function. + *END**************************************************************************/ +flexio_i2s_status_t FLEXIO_I2S_DRV_SendDataDma(flexio_i2s_handler_t *handler, uint8_t *addr, uint32_t len) +{ + if ((handler == NULL) || (addr == NULL) || (len == 0)) + { + return kStatus_FlexioI2S_InvalidParameter; + } + /* Have not configure DMA. */ + if (!handler->tx_use_dma) + { + uint32_t ret; + /* Request channel for Tx DMA */ + dma_request_source_t baseSource= kDmaRequestMux0FlexIOChannel0; + dma_request_source_t source = (dma_request_source_t)((uint32_t)baseSource + handler->device.shifterIdx[0]); +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + ret = EDMA_DRV_RequestChannel(kDmaAnyChannel, source, &handler->tx_edma_state); + if (ret == kEDMAInvalidChannel) + { + return kStatus_FlexioI2S_Fail; + } + EDMA_DRV_InstallCallback(&handler->tx_edma_state, FLEXIO_I2S_DRV_EdmaTxCallback, handler); +#else + ret = DMA_DRV_RequestChannel(kDmaAnyChannel, source, &handler->tx_dma_chn); + if (ret == kDmaInvalidChannel) + { + return kStatus_FlexioI2S_Fail; + } + DMA_DRV_RegisterCallback(&handler->tx_dma_chn, FLEXIO_I2S_DRV_DmaTxCallback, handler); +#endif + handler->tx_use_dma = true; + } + handler->tx_buffer = addr; + handler->tx_length = len; + /* Configure DMA module */ + uint32_t destAddr = FLEXIO_I2S_HAL_GetTxBufferAddr(&handler->device) + + (4 - handler->bit_depth/8); +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + EDMA_DRV_ConfigLoopTransfer(&handler->tx_edma_state, handler->tx_edma_tcd, + kEDMAMemoryToPeripheral, (uint32_t)addr, destAddr, handler->bit_depth/8, handler->bit_depth/8, + len, 1); + EDMA_DRV_StartChannel(&handler->tx_edma_state); +#else + DMA_DRV_ConfigTransfer(&handler->tx_dma_chn,kDmaMemoryToPeripheral, + handler->bit_depth/8, (uint32_t)addr, destAddr, len); + DMA_DRV_StartChannel(&handler->tx_dma_chn); +#endif + FLEXIO_I2S_DRV_TxStart(handler); + return kStatus_FlexioI2S_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_ReceiveDataDma + * Description : Receive a period of data using interrupt way. + * This function is an async function. + *END**************************************************************************/ +flexio_i2s_status_t FLEXIO_I2S_DRV_ReceiveDataDma(flexio_i2s_handler_t *handler, uint8_t *addr, uint32_t len) +{ + if ((handler == NULL) || (addr == NULL) || (len == 0)) + { + return kStatus_FlexioI2S_InvalidParameter; + } + if (!handler->rx_use_dma) + { + uint32_t ret; + /* Request channel for Rx DMA */ + dma_request_source_t baseSource= kDmaRequestMux0FlexIOChannel0; + dma_request_source_t source = (dma_request_source_t)((uint32_t)baseSource + handler->device.shifterIdx[1]); +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + ret = EDMA_DRV_RequestChannel(kDmaAnyChannel, source, &handler->rx_edma_state); + if (ret == kEDMAInvalidChannel) + { + return kStatus_FlexioI2S_Fail; + } + EDMA_DRV_InstallCallback(&handler->rx_edma_state, FLEXIO_I2S_DRV_EdmaRxCallback, handler); +#else + ret = DMA_DRV_RequestChannel(kDmaAnyChannel, source, &handler->rx_dma_chn); + if (ret == kDmaInvalidChannel) + { + return kStatus_FlexioI2S_Fail; + } + DMA_DRV_RegisterCallback(&handler->rx_dma_chn, FLEXIO_I2S_DRV_DmaRxCallback, handler); +#endif + handler->rx_use_dma = true; + } + handler->rx_buffer = addr; + handler->rx_length = len; + /* Configure DMA module */ + uint32_t srcAddr = FLEXIO_I2S_HAL_GetRxBufferAddr(&handler->device) + + (4 - handler->bit_depth/8); +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + EDMA_DRV_ConfigLoopTransfer(&handler->rx_edma_state, handler->rx_edma_tcd, + kEDMAPeripheralToMemory, srcAddr, (uint32_t)addr, handler->bit_depth/8, handler->bit_depth/8, + len, 1); + EDMA_DRV_StartChannel(&handler->rx_edma_state); +#else + DMA_DRV_ConfigTransfer(&handler->rx_dma_chn,kDmaPeripheralToMemory, + handler->bit_depth/8, srcAddr, (uint32_t)addr, len); + DMA_DRV_StartChannel(&handler->rx_dma_chn); +#endif + FLEXIO_I2S_DRV_RxStart(handler); + return kStatus_FlexioI2S_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_TxIrq + * Description : IRQ handler for tx. + * This function sends data and also handle error flag. + *END**************************************************************************/ +void FLEXIO_I2S_DRV_TxIrq(void * param) +{ + flexio_i2s_handler_t * handler = (flexio_i2s_handler_t *)param; + uint32_t bytes = handler->bit_depth/8; + uint8_t *addr = handler->tx_buffer + handler->tx_finished_bytes; + uint32_t data = 0; + uint32_t i = 0; + /* Clear the error flag. */ + if (FLEXIO_I2S_HAL_GetTxErrFlag(&handler->device)) + { + FLEXIO_I2S_HAL_ClearTxErrFlag(&handler->device); + } + /* If need to transfer data using ISR. */ + if ((FLEXIO_I2S_HAL_GetTxBufferEmptyIntCmd(&handler->device)) && + (FLEXIO_I2S_HAL_GetTxBufferEmptyFlag(&handler->device))) + { + for (i = 0; i < bytes; i ++) + { + data |= (uint32_t)(*addr) << (i * 8U); + addr ++; + handler->tx_finished_bytes ++; + } + data <<= (32 - handler->bit_depth); + FLEXIO_I2S_HAL_PutData(&handler->device, data); + /* If need to callback */ + if (handler->tx_finished_bytes >= handler->tx_length) + { + /* If there is callback */ + if (handler->tx_callback) + { + (handler->tx_callback)(handler->tx_callback_param); + } + else + { + /* If no callback, just close */ + OSA_SemaPost(&handler->tx_sem); + FLEXIO_I2S_DRV_TxStop(handler); + } + } + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_RxIrq + * Description : IRQ handler for rx. + * This function sends data and also handle error flag. + *END**************************************************************************/ +void FLEXIO_I2S_DRV_RxIrq(void * param) +{ + flexio_i2s_handler_t * handler = (flexio_i2s_handler_t *)param; + uint32_t bytes = handler->bit_depth/8; + uint8_t *addr = handler->rx_buffer + handler->rx_finished_bytes; + uint32_t data; + uint32_t i = 0; + /* Clear error flag */ + if (FLEXIO_I2S_HAL_GetRxErrFlag(&handler->device)) + { + FLEXIO_I2S_HAL_ClearRxErrFlag(&handler->device); + } + /* If using ISR to transfer data. */ + if ((FLEXIO_I2S_HAL_GetRxBufferFullIntCmd(&handler->device)) && + (FLEXIO_I2S_HAL_GetRxBufferFullFlag(&handler->device))) + { + data = FLEXIO_I2S_HAL_GetData(&handler->device); + for (i = 0; i < bytes; i ++) + { + *addr = (data >> (8 * i)) & 0xFFU; + addr ++; + handler->rx_finished_bytes ++; + } + /* If finished */ + if (handler->rx_finished_bytes >= handler->rx_length) + { + if (handler->rx_callback) + { + (handler->rx_callback)(handler->rx_callback_param); + } + else + { + OSA_SemaPost(&handler->rx_sem); + FLEXIO_I2S_DRV_RxStop(handler); + } + } + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_TxInstallCallback + * Description : Install callback function for finished sending data. + * This function would be called while finished sending data, both can be used + * in interrupt way and also dma way. + *END**************************************************************************/ +void FLEXIO_I2S_DRV_TxInstallCallback(flexio_i2s_handler_t *handler, i2s_callback callback, + void *param) +{ + handler->tx_callback = callback; + handler->tx_callback_param = param; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_RxInstallCallback + * Description : Install callback function for finished receiving data. + * This function would be called while finished receiving data, both can be used + * in interrupt way and also dma way. + *END**************************************************************************/ +void FLEXIO_I2S_DRV_RxInstallCallback(flexio_i2s_handler_t *handler, i2s_callback callback, + void *param) +{ + handler->rx_callback = callback; + handler->rx_callback_param = param; +} + +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_EdmaTaRxCallback + * Description : Default callback function for edma finished sending data. + * This function would only post semaphore and call callback function installed + * by users if there is. + *END**************************************************************************/ +void FLEXIO_I2S_DRV_EdmaTxCallback(void *param, edma_chn_status_t status) +{ + flexio_i2s_handler_t *handler = (flexio_i2s_handler_t *)param; + OSA_SemaPost(&handler->tx_sem); + if (handler->tx_callback) + { + (handler->tx_callback)(handler->tx_callback_param); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_EdmaRxCallback + * Description : Default callback function for edma finished receiving data. + * This function would only post semaphore and call callback function installed + * by users if there is. + *END**************************************************************************/ +void FLEXIO_I2S_DRV_EdmaRxCallback(void *param, edma_chn_status_t status) +{ + flexio_i2s_handler_t *handler = (flexio_i2s_handler_t *)param; + OSA_SemaPost(&handler->rx_sem); + if (handler->rx_callback) + { + (handler->rx_callback)(handler->rx_callback_param); + } +} +#else +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_DmaTaRxCallback + * Description : Default callback function for dma finished sending data. + * This function would only post semaphore and call callback function installed + * by users if there is. + *END**************************************************************************/ +void FLEXIO_I2S_DRV_DmaTxCallback(void *param, dma_channel_status_t status) +{ + flexio_i2s_handler_t *handler = (flexio_i2s_handler_t *)param; + OSA_SemaPost(&handler->tx_sem); + FLEXIO_I2S_DRV_TxStop(handler); + if (handler->tx_callback) + { + (handler->tx_callback)(handler->tx_callback_param); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_I2S_DRV_DmaRxCallback + * Description : Default callback function for dma finished receiving data. + * This function would only post semaphore and call callback function installed + * by users if there is. + *END**************************************************************************/ +void FLEXIO_I2S_DRV_DmaRxCallback(void *param, dma_channel_status_t status) +{ + flexio_i2s_handler_t *handler = (flexio_i2s_handler_t *)param; + OSA_SemaPost(&handler->rx_sem); + FLEXIO_I2S_DRV_RxStop(handler); + if (handler->tx_callback) + { + (handler->rx_callback)(handler->rx_callback_param); + } +} +#endif +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_irq.c b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_irq.c new file mode 100755 index 0000000..5c0cc6f --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_irq.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_driver.h" + +/******************************************************************************* + * Code + ******************************************************************************/ + +void UART2_FLEXIO_IRQHandler(void) +{ + FLEXIO_DRV_IRQHandler(FLEXIO_IDX); +} + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_lpm_callback.c new file mode 100755 index 0000000..cb90c6b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_FLEXIO_COUNT + +power_manager_error_code_t flexio_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t flexio_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_spi_driver.c b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_spi_driver.c new file mode 100755 index 0000000..7ae0f45 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_spi_driver.c @@ -0,0 +1,2264 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 <string.h> +#include "fsl_flexio_spi_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static flexio_spi_status_t FLEXIO_SPI_DRV_TxConfigDMA(flexio_spi_state_t *spiState); +static flexio_spi_status_t FLEXIO_SPI_DRV_RxConfigDMA(flexio_spi_state_t *spiState); +static flexio_spi_status_t FLEXIO_SPI_DRV_StartSendData(flexio_spi_state_t *spiState, + const uint8_t * txBuff, + uint32_t txSize); +static flexio_spi_status_t FLEXIO_SPI_DRV_StartReceiveData(flexio_spi_state_t *spiState, + uint8_t * rxBuff, + uint32_t rxSize); +static flexio_spi_status_t FLEXIO_SPI_DRV_StartTransferData(flexio_spi_state_t *spiState, + const uint8_t * txBuff, uint8_t * rxBuff, + uint32_t xSize); +static void FLEXIO_SPI_DRV_CompleteSendData(flexio_spi_state_t *spiState); +static void FLEXIO_SPI_DRV_CompleteReceiveData(flexio_spi_state_t *spiState); +static void FLEXIO_SPI_DRV_CompleteTransferData(flexio_spi_state_t *spiState); +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL +static void FLEXIO_SPI_DRV_EdmaTxCallback(void *param, edma_chn_status_t status); +static void FLEXIO_SPI_DRV_EdmaRxCallback(void *param, edma_chn_status_t status); +#else +static void FLEXIO_SPI_DRV_DmaTxCallback(void *param, dma_channel_status_t status); +static void FLEXIO_SPI_DRV_DmaRxCallback(void *param, dma_channel_status_t status); +#endif +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_Init + * Description : Initialize a SPI device for operation. + * This function will initialize the run-time state structure to keep track of + * the on-going transfers,initialize the module to user defined settings and + * default settings, configures underlying flexio Pin,shifter and timer. + * The following is an example of how to set up the flexio_spi_state_t and the + * flexio_spi_userconfig_t parameters and how to call the FLEXIO_SPI_DRV_Init function + * by passing in these parameters: + * flexio_spi_state_t spiState; + flexio_spi_userconif_t spiConfig; + spiConfig.spiMode = kFlexIOSpiMaster; + spiConfig.baudRate = 100000; + spiConfig.clkPhase = kFlexIOSpiClockPhase_FirstEdge; + spiConfig.dataSize = kFlexIOSpi8BitMode; + spiConfig.spiHwConfig.sdoPinIdx = 0; + spiConfig.spiHwConfig.sdiPinIdx = 1; + spiConfig.spiHwConfig.sclkPinIdx = 2; + spiConfig.spiHwConfig.csnPinIdx = 3; + spiConfig.spiHwConfig.shifterIdx = {0,1}; + spiConfig.spiHwConfig.timerIdx = {0,1}; + * FLEXIO_SPI_DRV_Init(instance, &spiState, &spiConfig); + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_Init(uint32_t instance, flexio_spi_state_t *spiState, + flexio_spi_userconfig_t *spiConfig) +{ + if((spiState == NULL)||(spiConfig == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + FLEXIO_Type* base = g_flexioBase[instance]; + /*Reset the spiState structure*/ + memset(spiState,0,sizeof(*spiState)); + /*Create semaphore for txIrq, rxIrq and xIrq*/ + OSA_SemaCreate(&spiState->txIrqSync,0); + OSA_SemaCreate(&spiState->rxIrqSync,0); + OSA_SemaCreate(&spiState->xIrqSync,0); + /*Init FlexIO SPI resource*/ + spiState->spiDev.flexioBase = base; + spiState->spiDev.txPinIdx = spiConfig->spiHwConfig.sdoPinIdx; + spiState->spiDev.rxPinIdx = spiConfig->spiHwConfig.sdiPinIdx; + spiState->spiDev.sclkPinIdx = spiConfig->spiHwConfig.sclkPinIdx; + spiState->spiDev.csnPinIdx = spiConfig->spiHwConfig.csnPinIdx; + spiState->spiDev.shifterIdx[0] = spiConfig->spiHwConfig.shifterIdx[0]; + spiState->spiDev.shifterIdx[1] = spiConfig->spiHwConfig.shifterIdx[1]; + spiState->spiDev.timerIdx[0] = spiConfig->spiHwConfig.timerIdx[0]; + spiState->spiDev.timerIdx[1] = spiConfig->spiHwConfig.timerIdx[1]; + spiState->mode = spiConfig->spiMode; + spiState->dataSize = spiConfig->dataSize; + spiState->bitDirection = spiConfig->bitDirection; + if(spiConfig->spiMode == kFlexIOSpiMaster) + { + flexio_spi_master_config_t masterConfig; + /*Get FlexIO clock frequency for baudrate calculation*/ + masterConfig.flexioBusClk = CLOCK_SYS_GetFlexioFreq(instance); + masterConfig.baudrate = spiConfig->baudRate; + masterConfig.bitCount = spiConfig->dataSize; + if(spiConfig->clkPhase == 0) + { + masterConfig.cphaOneEnable = false; + } + else + { + masterConfig.cphaOneEnable = true; + } + FLEXIO_SPI_HAL_ConfigMaster(&(spiState->spiDev),&masterConfig); + } + else if(spiConfig->spiMode == kFlexIOSpiSlave) + { + flexio_spi_slave_config_t slaveConfig; + slaveConfig.bitCount = spiConfig->dataSize; + if(spiConfig->clkPhase == 0) + { + slaveConfig.cphaOneEnable = false; + } + else + { + slaveConfig.cphaOneEnable = true; + } + FLEXIO_SPI_HAL_ConfigSlave(&(spiState->spiDev),&slaveConfig); + } + FLEXIO_DRV_RegisterCallback(instance,spiState->spiDev.shifterIdx[0], + FLEXIO_SPI_DRV_TX_IRQHandler,(void *)(spiState)); + FLEXIO_DRV_RegisterCallback(instance,spiState->spiDev.shifterIdx[1], + FLEXIO_SPI_DRV_RX_IRQHandler,(void *)(spiState)); + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_Deinit + * Description : Shutdown a FlexIO simulated SPI device. + * This function destroy the semaphores + * + *END**************************************************************************/ +void FLEXIO_SPI_DRV_Deinit(flexio_spi_state_t *spiState) +{ + /* Release dma channel */ + if (spiState->isTxUseDma) + { +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + EDMA_DRV_ReleaseChannel(&spiState->edmaSpiTx); +#else + DMA_DRV_FreeChannel(&spiState->dmaSpiTx); +#endif + } + if (spiState->isRxUseDma) + { +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + EDMA_DRV_ReleaseChannel(&spiState->edmaSpiRx); +#else + DMA_DRV_FreeChannel(&spiState->dmaSpiRx); +#endif + } + /* Destroy TX, RX, Tx&Rx sema. */ + OSA_SemaDestroy(&spiState->txIrqSync); + OSA_SemaDestroy(&spiState->rxIrqSync); + OSA_SemaDestroy(&spiState->xIrqSync); +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_InstallRxCallback + * Description : Install receive data callback function, pass in NULL pointer + * as callback will unistall. + * + *END**************************************************************************/ +flexio_spi_rx_callback_t FLEXIO_SPI_DRV_InstallRxCallback(flexio_spi_state_t *spiState,flexio_spi_rx_callback_t function, + uint8_t * rxBuff,void * callbackParam) +{ + flexio_spi_rx_callback_t currentCallback = spiState->rxCallback; + spiState->rxCallback = function; + spiState->rxCallbackParam = callbackParam; + spiState->rxBuff = rxBuff; + + spiState->isRxBusy = true; + return currentCallback; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_SendDataBlocking + * Description : This function sends (transmits) data out through the FlexIO + * simulated SPI module using a blocking method. + * A blocking (also known as synchronous) function means that the function does + * not return until the transmit is complete. This blocking function is used to + * send data through the FlexIO simulated SPI port. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_SendDataBlocking(flexio_spi_state_t *spiState, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + if((spiState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + flexio_spi_status_t retVal = kStatus_FlexIO_SPI_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking.*/ + spiState->isTxBlocking = true; + + /* Start the transmission process */ + retVal = FLEXIO_SPI_DRV_StartSendData(spiState, txBuff, txSize); + + if (retVal == kStatus_FlexIO_SPI_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&spiState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable the transmitter data register empty interrupt */ + FLEXIO_SPI_HAL_SetTxBufferEmptyIntCmd(&(spiState->spiDev), false); + /* Update the information of the module driver state */ + spiState->isTxBusy = false; + + retVal = kStatus_FlexIO_SPI_Timeout; + } + } + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_SendData + * Description : This function sends (transmits) data through the FlexIO simulated + * SPI module using a non-blocking method. + * A non-blocking (also known as asynchronous) function means that the function + * returns immediately after initiating the transmit function. The application + * has to get the transmit status to see when the transmit is complete. In + * other words, after calling non-blocking (asynchronous) send function, the + * application must get the transmit status to check if transmit is completed + * or not. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_SendData(flexio_spi_state_t *spiState, + const uint8_t * txBuff, + uint32_t txSize) +{ + if((spiState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + flexio_spi_status_t retVal = kStatus_FlexIO_SPI_Success; + + /* Indicates current transaction is non-blocking */ + spiState->isTxBlocking = false; + + /* Start the transmission process */ + retVal = FLEXIO_SPI_DRV_StartSendData(spiState, txBuff, txSize); + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_GetTransmitStatus + * Description : This function returns whether the previous transmit has + * finished. + * When performing an non-blocking transmit, the user can call this function to + * ascertain the state of the current transmission: in progress (or busy) or + * complete (success). In addition, if the transmission is still in progress, + * the user can obtain the number of words that have been currently transferred. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_GetTransmitStatus(flexio_spi_state_t *spiState, uint32_t * bytesRemaining) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + flexio_spi_status_t retVal = kStatus_FlexIO_SPI_Success; + uint32_t txSize = spiState->txSize; + + /* Fill in the bytes transferred. This may return that all bytes were + * transmitted.*/ + if (bytesRemaining) + { + *bytesRemaining = txSize; + } + + if (txSize) + { + retVal = kStatus_FlexIO_SPI_TxBusy; + } + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_AbortSendingData + * Description : This function ends a non-blocking SPI transmission early. + * During a non-blocking SPI transmission, the user has the option to terminate + * the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_AbortSendingData(flexio_spi_state_t *spiState) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!spiState->isTxBusy) + { + return kStatus_FlexIO_SPI_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + FLEXIO_SPI_DRV_CompleteSendData(spiState); + + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_ReceiveDataBlocking + * Description : This function gets (receives) data from the SPI module using + * a blocking method. A blocking (also known as synchronous) function means that + * the function does not return until the receive is complete. This blocking + * function is used to send data through the SPI port. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_ReceiveDataBlocking(flexio_spi_state_t *spiState, uint8_t * rxBuff, + uint32_t rxSize, uint32_t timeout) +{ + if((spiState == NULL)||(rxBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + flexio_spi_status_t retVal = kStatus_FlexIO_SPI_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking.*/ + spiState->isRxBlocking = true; + + retVal = FLEXIO_SPI_DRV_StartReceiveData(spiState, rxBuff, rxSize); + + if (retVal == kStatus_FlexIO_SPI_Success) + { + /* Wait until all the data is received or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&spiState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable receive data full and rx overrun interrupt */ + FLEXIO_SPI_HAL_SetRxBufferFullIntCmd(&(spiState->spiDev), false); + /* Update the information of the module driver state */ + spiState->isRxBusy = false; + + retVal = kStatus_FlexIO_SPI_Timeout; + } + } + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_ReceiveData + * Description : This function gets (receives) data from the simluated SPI + * module using a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. In other + * words, after calling non-blocking (asynchronous) get function, the + * application must get the receive status to check if receive is completed or + * not. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_ReceiveData(flexio_spi_state_t *spiState, + uint8_t * rxBuff, + uint32_t rxSize) +{ + if((spiState == NULL)||(rxBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + flexio_spi_status_t retVal = kStatus_FlexIO_SPI_Success; + + /* Indicates current transaction is non-blocking.*/ + spiState->isRxBlocking = false; + + retVal = FLEXIO_SPI_DRV_StartReceiveData(spiState, rxBuff, rxSize); + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_GetReceiveStatus + * Description : This function returns whether the previous UART receive is + * completed. + * When performing a non-blocking receive, the user can call this function to + * ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, the + * user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_GetReceiveStatus(flexio_spi_state_t *spiState, + uint32_t * bytesRemaining) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + flexio_spi_status_t retVal = kStatus_FlexIO_SPI_Success; + uint32_t rxSize = spiState->rxSize; + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = rxSize; + } + + if (rxSize) + { + retVal = kStatus_FlexIO_SPI_RxBusy; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_AbortReceivingData + * Description : This function aborts data receive. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_AbortReceivingData(flexio_spi_state_t *spiState) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!spiState->isRxBusy) + { + return kStatus_FlexIO_SPI_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + FLEXIO_SPI_DRV_CompleteReceiveData(spiState); + + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_TransferDataBlocking + * Description : This function sends&gets data from the SPI module using + * a blocking method. A blocking (also known as synchronous) function means that + * the function does not return until the transfer is complete. This blocking + * function is used to transfer data through the SPI port. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_TransferDataBlocking(flexio_spi_state_t *spiState, const uint8_t * txBuff, + uint8_t *rxBuff, uint32_t xSize, uint32_t timeout) +{ + if((spiState == NULL)||(txBuff == NULL)||(rxBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + flexio_spi_status_t retVal = kStatus_FlexIO_SPI_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking.*/ + spiState->isXBlocking = true; + + retVal = FLEXIO_SPI_DRV_StartTransferData(spiState, txBuff, rxBuff, xSize); + + if (retVal == kStatus_FlexIO_SPI_Success) + { + /* Wait until all the data is transferred or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&spiState->xIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable receive data full and tx data empty interrupt */ + FLEXIO_SPI_HAL_SetTxBufferEmptyIntCmd(&(spiState->spiDev), false); + FLEXIO_SPI_HAL_SetRxBufferFullIntCmd(&(spiState->spiDev), false); + /* Update the information of the module driver state */ + spiState->isXBusy = false; + + retVal = kStatus_FlexIO_SPI_Timeout; + } + } + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_TransferData + * Description : This function sends&gets data from the simulated SPI + * module using a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the transfer function. The application + * has to get the transfer status to see when the transfer is complete. In other + * words, after calling non-blocking (asynchronous) get function, the + * application must get the transfer status to check if transfer is completed or + * not. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_TransferData(flexio_spi_state_t *spiState, + const uint8_t *txBuff, uint8_t * rxBuff, + uint32_t xSize) +{ + if((spiState == NULL)||(txBuff == NULL)||(rxBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + flexio_spi_status_t retVal = kStatus_FlexIO_SPI_Success; + + /* Indicates current transaction is non-blocking.*/ + spiState->isXBlocking = false; + + retVal = FLEXIO_SPI_DRV_StartTransferData(spiState, txBuff, rxBuff, xSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_AbortTransferData + * Description : This function aborts data transfer. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_AbortTransferData(flexio_spi_state_t *spiState) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!spiState->isXBusy) + { + return kStatus_FlexIO_SPI_NoTransferInProgress; + } + + /* Stop the running transfer. */ + FLEXIO_SPI_DRV_CompleteTransferData(spiState); + + return kStatus_FlexIO_SPI_Success; +} +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_EdmaTxCallback + * Description : This is not a public interface, called when dma tx ends. + * + *END**************************************************************************/ +static void FLEXIO_SPI_DRV_EdmaTxCallback(void *param, dma_channel_status_t status) +{ + flexio_spi_state_t *spiState = (flexio_spi_state_t *)param; + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&spiState->dmaSpiTx); + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), false); + if(spiState->isTxBusy) + { + FLEXIO_SPI_DRV_CompleteSendData(spiState); + } +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_EdmaRxCallback + * Description : This is not a public interface, called when dma rx ends. + * + *END**************************************************************************/ +static void FLEXIO_SPI_DRV_EdmaRxCallback(void *param, dma_channel_status_t status) +{ + flexio_spi_state_t *spiState = (flexio_spi_state_t *)param; + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&spiState->dmaSpiRx); + FLEXIO_SPI_HAL_SetRxDmaCmd(&(spiState->spiDev), false); + if(spiState->isRxBusy) + { + FLEXIO_SPI_DRV_CompleteReceiveData(spiState); + } + else if(spiState->isXBusy) + { + FLEXIO_SPI_DRV_CompleteTransferData(spiState); + } +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_EdmaSendDataBlocking + * Description : Send a period of data using DMA way. + * This function is an async function. + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaSendDataBlocking(flexio_spi_state_t *spiState, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + if((spiState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + /* Check that we're not busy already transmitting data from a previous + * function call. */ + if ((spiState->isTxBusy)||(spiState->isXBusy)) + { + return kStatus_FlexIO_SPI_TxBusy; + } + + if (txSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + /* Have not configure DMA. */ + if (!spiState->isTxUseDma) + { + FLEXIO_SPI_DRV_TxConfigDMA(spiState); + } + /* Configure DMA module */ + uint32_t destAddr; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferMSBAddr(&spiState->spiDev) + + (4 - spiState->dataSize/8); + } + else + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferLSBAddr(&spiState->spiDev); + } + EDMA_DRV_ConfigLoopTransfer(&spiState->edmaSpiTx, &spiState->edmaTxTcd, + kEDMAMemoryToPeripheral, (uint32_t)(txBuff + spiState->dataSize/8), + destAddr, spiState->dataSize/8, spiState->dataSize/8, + (txSize - spiState->dataSize/8), 1); + EDMA_DRV_StartChannel(&spiState->edmaSpiTx); + /* Put the first data in shifter to start the transmission */ + uint32_t tmp; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + tmp = *txBuff; + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<24); + }else + { + tmp = *((const uint16_t *)txBuff); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<16); + } + } + else + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *(spiState->txBuff)); + }else + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *((const uint16_t *)(spiState->txBuff))); + } + } + /* Indicates current transaction is non-blocking */ + spiState->isTxBlocking = true; + spiState->isTxBusy = true; + /*enable dma request interrupt*/ + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), true); + FLEXIO_DRV_Start(0); + /* Wait until the transmit is complete. */ + osa_status_t syncStatus; + do + { + syncStatus = OSA_SemaWait(&spiState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + EDMA_DRV_StopChannel(&spiState->edmaSpiTx); + + /* Update the information of the module driver state */ + spiState->isTxBusy = false; + + return kStatus_FlexIO_SPI_Timeout; + } + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_SendDataDma + * Description : Send a period of data using DMA way. + * This function is an async function. + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaSendData(flexio_spi_state_t *spiState, + const uint8_t * txBuff, uint32_t txSize) +{ + if((spiState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + if ((spiState->isTxBusy)||(spiState->isXBusy)) + { + return kStatus_FlexIO_SPI_TxBusy; + } + + if (txSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + /* Have not configure DMA. */ + if (!spiState->isTxUseDma) + { + FLEXIO_SPI_DRV_TxConfigDMA(spiState); + } + /* Configure DMA module */ + uint32_t destAddr; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferMSBAddr(&spiState->spiDev) + + (4 - spiState->dataSize/8); + } + else + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferLSBAddr(&spiState->spiDev); + } + EDMA_DRV_ConfigLoopTransfer(&spiState->edmaSpiTx, &spiState->edmaTxTcd, + kEDMAMemoryToPeripheral, (uint32_t)(txBuff + spiState->dataSize/8), + destAddr, spiState->dataSize/8, spiState->dataSize/8, + (txSize - spiState->dataSize/8), 1); + EDMA_DRV_StartChannel(&spiState->edmaSpiTx); + /* Put the first data in shifter to start the transmission */ + uint32_t tmp; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + tmp = *txBuff; + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<24); + }else + { + tmp = *((const uint16_t *)txBuff); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<16); + } + } + else + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *(spiState->txBuff)); + }else + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *((const uint16_t *)(spiState->txBuff))); + } + } + /* Indicates current transaction is non-blocking */ + spiState->isTxBlocking = false; + spiState->isTxBusy = true; + /*enable dma request interrupt*/ + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), true); + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_EdmaGetTransmitStatus + * Description : This function returns whether the previous SPI transmit + * has finished. When performing an sync transmit, the user can call this + * function to ascertain the state of the current transmission: in progress + * (or busy) or complete (success). In addition, if the transmission is still + * in progress, the user can obtain the number of words that have been + * currently transferred. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaGetTransmitStatus(flexio_spi_state_t * spiState, + uint32_t * bytesRemaining) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = EDMA_DRV_GetUnfinishedBytes(&spiState->edmaSpiTx); + } + + return (spiState->isTxBusy ? kStatus_FlexIO_SPI_TxBusy : kStatus_FlexIO_SPI_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_EdmaAbortSendingData + * Description : This function Terminates a non-blocking FLEXIO simulated SPI-DMA + * transmission early.During an sync SPI transmission, the user has the option to + * terminate the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaAbortSendingData(flexio_spi_state_t * spiState) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!spiState->isTxBusy) + { + return kStatus_FlexIO_SPI_NoTransmitInProgress; + } + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&spiState->edmaSpiTx); + /* Disable SPI Tx DMA interrupt*/ + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), false); + /* Stop the running transfer. */ + FLEXIO_SPI_DRV_CompleteSendData(spiState); + + return kStatus_FlexIO_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_EdmaReceiveDataBlocking + * Description : Receive a period of data using interrupt way. + * This function is an async function. + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaReceiveDataBlocking(flexio_spi_state_t *spiState, + uint8_t *rxBuff, + uint32_t rxSize, + uint32_t timeout) +{ + if ((spiState == NULL) || (rxBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + if ((spiState->isRxBusy)||(spiState->isXBusy)) + { + return kStatus_FlexIO_SPI_RxBusy; + } + + if (rxSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + /* Have not configure DMA. */ + if (!spiState->isRxUseDma) + { + FLEXIO_SPI_DRV_RxConfigDMA(spiState); + } + /* Configure DMA module */ + uint32_t srcAddr = FLEXIO_SPI_HAL_GetRxBufferMSBAddr(&spiState->spiDev); + EDMA_DRV_ConfigLoopTransfer(&spiState->edmaSpiRx, &spiState->edmaRxTcd, + kEDMAPeripheralToMemory, srcAddr, (uint32_t)rxBuff, spiState->dataSize/8, + spiState->dataSize/8,rxSize, 1); + EDMA_DRV_StartChannel(&spiState->edmaSpiRx); + /* Indicates current transaction is non-blocking */ + spiState->isRxBlocking = true; + spiState->isRxBusy = true; + /*enable dma request interrupt*/ + FLEXIO_SPI_HAL_SetRxDmaCmd(&(spiState->spiDev), true); + FLEXIO_DRV_Start(0); + /* Wait until the transmit is complete. */ + osa_status_t syncStatus; + do + { + syncStatus = OSA_SemaWait(&spiState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + EDMA_DRV_StopChannel(&spiState->edmaSpiRx); + + /* Update the information of the module driver state */ + spiState->isRxBusy = false; + + return kStatus_FlexIO_SPI_Timeout; + } + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_EdmaReceiveData + * Description : Receive a period of data using interrupt way. + * This function is an async function. + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaReceiveData(flexio_spi_state_t *spiState, + uint8_t *rxBuff,uint32_t rxSize) +{ + if ((spiState == NULL) || (rxBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + if ((spiState->isRxBusy)||(spiState->isXBusy)) + { + return kStatus_FlexIO_SPI_RxBusy; + } + + if (rxSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + /* Have not configure DMA. */ + if (!spiState->isRxUseDma) + { + FLEXIO_SPI_DRV_RxConfigDMA(spiState); + } + /* Configure DMA module */ + uint32_t srcAddr = FLEXIO_SPI_HAL_GetRxBufferMSBAddr(&spiState->spiDev); + EDMA_DRV_ConfigLoopTransfer(&spiState->edmaSpiRx, &spiState->edmaRxTcd, + kEDMAPeripheralToMemory, srcAddr, (uint32_t)rxBuff, spiState->dataSize/8, + spiState->dataSize/8, rxSize, 1); + EDMA_DRV_StartChannel(&spiState->edmaSpiRx); + /* Indicates current transaction is non-blocking */ + spiState->isRxBlocking = false; + spiState->isRxBusy = true; + /*enable dma request interrupt*/ + FLEXIO_SPI_HAL_SetRxDmaCmd(&(spiState->spiDev), true); + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_EdmaGetReceiveStatus + * Description : This function returns whether the previous SPI receive is + * complete. When performing an sync receive, the user can call this function + * to ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, + * the user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaGetReceiveStatus(flexio_spi_state_t * spiState, + uint32_t * bytesRemaining) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = EDMA_DRV_GetUnfinishedBytes(&spiState->edmaSpiRx); + } + + return (spiState->isRxBusy ? kStatus_FlexIO_SPI_RxBusy : kStatus_FlexIO_SPI_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_EdmaAbortReceivingData + * Description : This function shuts down the SPI by disabling interrupts and + * the transmitter/receiver. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaAbortReceivingData(flexio_spi_state_t * spiState) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!spiState->isRxBusy) + { + return kStatus_FlexIO_SPI_NoReceiveInProgress; + } + + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&spiState->edmaSpiRx); + /* Disable SPI Rx DMA interrupt*/ + FLEXIO_SPI_HAL_SetRxDmaCmd(&(spiState->spiDev), false); + /* Stop the running transfer. */ + FLEXIO_SPI_DRV_CompleteReceiveData(spiState); + + return kStatus_FlexIO_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_EdmaTransferDataBlocking + * Description : Receive a period of data using interrupt way. + * This function is an async function. + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaTransferDataBlocking(flexio_spi_state_t *spiState, + const uint8_t *txBuff, + uint8_t *rxBuff, + uint32_t xSize, + uint32_t timeout) +{ + if ((spiState == NULL) || (txBuff == NULL) || (rxBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + if ((spiState->isTxBusy)||(spiState->isRxBusy)||(spiState->isXBusy)) + { + return kStatus_FlexIO_SPI_XBusy; + } + + if (xSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + /* Have not configure DMA. */ + if (!spiState->isTxUseDma) + { + FLEXIO_SPI_DRV_TxConfigDMA(spiState); + } + + if (!spiState->isRxUseDma) + { + FLEXIO_SPI_DRV_RxConfigDMA(spiState); + } + /* Configure DMA module */ + uint32_t destAddr; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferMSBAddr(&spiState->spiDev) + + (4 - spiState->dataSize/8); + } + else + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferLSBAddr(&spiState->spiDev); + } + EDMA_DRV_ConfigLoopTransfer(&spiState->edmaSpiTx, &spiState->edmaTxTcd, + kEDMAMemoryToPeripheral, (uint32_t)(txBuff + spiState->dataSize/8), + destAddr, spiState->dataSize/8, spiState->dataSize/8, + (xSize - spiState->dataSize/8), 1); + EDMA_DRV_StartChannel(&spiState->edmaSpiTx); + /* Put the first data in shifter to start the transmission */ + uint32_t tmp; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + tmp = *txBuff; + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<24); + }else + { + tmp = *((const uint16_t *)txBuff); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<16); + } + } + else + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *(spiState->txBuff)); + }else + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *((const uint16_t *)(spiState->txBuff))); + } + } + + uint32_t srcAddr = FLEXIO_SPI_HAL_GetRxBufferMSBAddr(&spiState->spiDev); + EDMA_DRV_ConfigLoopTransfer(&spiState->edmaSpiRx, &spiState->edmaRxTcd, + kEDMAPeripheralToMemory, srcAddr, (uint32_t)rxBuff, + spiState->dataSize/8, spiState->dataSize/8, xSize, 1); + EDMA_DRV_StartChannel(&spiState->edmaSpiRx); + /* Indicates current transaction is non-blocking */ + spiState->isXBlocking = true; + spiState->isXBusy = true; + /*enable dma request interrupt*/ + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), true); + FLEXIO_SPI_HAL_SetRxDmaCmd(&(spiState->spiDev), true); + FLEXIO_DRV_Start(0); + /* Wait until the transmit is complete. */ + osa_status_t syncStatus; + do + { + syncStatus = OSA_SemaWait(&spiState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + EDMA_DRV_StopChannel(&spiState->edmaSpiRx); + + /* Update the information of the module driver state */ + spiState->isRxBusy = false; + + return kStatus_FlexIO_SPI_Timeout; + } + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_EdmaTransferData + * Description : Receive a period of data using interrupt way. + * This function is an async function. + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_EdmaTransferData(flexio_spi_state_t *spiState, + const uint8_t *txBuff, + uint8_t *rxBuff, + uint32_t xSize) +{ + if ((spiState == NULL) || (txBuff == NULL) || (rxBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + if ((spiState->isTxBusy)||(spiState->isRxBusy)||(spiState->isXBusy)) + { + return kStatus_FlexIO_SPI_XBusy; + } + + if (xSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + /* Have not configure DMA. */ + if (!spiState->isTxUseDma) + { + FLEXIO_SPI_DRV_TxConfigDMA(spiState); + } + + if (!spiState->isRxUseDma) + { + FLEXIO_SPI_DRV_RxConfigDMA(spiState); + } + /* Configure DMA module */ + uint32_t destAddr; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferMSBAddr(&spiState->spiDev) + + (4 - spiState->dataSize/8); + } + else + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferLSBAddr(&spiState->spiDev); + } + EDMA_DRV_ConfigLoopTransfer(&spiState->edmaSpiTx, &spiState->edmaTxTcd, + kEDMAMemoryToPeripheral, (uint32_t)(txBuff + spiState->dataSize/8), + destAddr, spiState->dataSize/8, spiState->dataSize/8, + (xSize - spiState->dataSize/8), 1); + EDMA_DRV_StartChannel(&spiState->edmaSpiTx); + /* Put the first data in shifter to start the transmission */ + uint32_t tmp; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + tmp = *txBuff; + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<24); + }else + { + tmp = *((const uint16_t *)txBuff); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<16); + } + } + else + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *(spiState->txBuff)); + }else + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *((const uint16_t *)(spiState->txBuff))); + } + } + + uint32_t srcAddr = FLEXIO_SPI_HAL_GetRxBufferMSBAddr(&spiState->spiDev); + EDMA_DRV_ConfigLoopTransfer(&spiState->edmaSpiRx, &spiState->edmaRxTcd, + kEDMAPeripheralToMemory, srcAddr, (uint32_t)rxBuff, + spiState->dataSize/8, spiState->dataSize/8,xSize, 1); + EDMA_DRV_StartChannel(&spiState->edmaSpiRx); + /* Indicates current transaction is non-blocking */ + spiState->isXBlocking = false; + spiState->isXBusy = true; + /*enable dma request interrupt*/ + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), true); + FLEXIO_SPI_HAL_SetRxDmaCmd(&(spiState->spiDev), true); + return kStatus_FlexIO_SPI_Success; +} +#else +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_DmaGetTransmitStatus + * Description : This function returns whether the previous SPI transmit + * has finished. When performing an async transmit, the user can call this + * function to ascertain the state of the current transmission: in progress + * (or busy) or complete (success). In addition, if the transmission is still + * in progress, the user can obtain the number of words that have been + * currently transferred. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaGetTransmitStatus(flexio_spi_state_t * spiState, + uint32_t * bytesRemaining) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = DMA_DRV_GetUnfinishedBytes(&spiState->dmaSpiTx); + } + + return (spiState->isTxBusy ? kStatus_FlexIO_SPI_TxBusy : kStatus_FlexIO_SPI_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_DmaAbortSendingData + * Description : This function Terminates a non-blocking FLEXIO simulated SPI-DMA + * transmission early.During an sync SPI transmission, the user has the option to + * terminate the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaAbortSendingData(flexio_spi_state_t * spiState) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!spiState->isTxBusy) + { + return kStatus_FlexIO_SPI_NoTransmitInProgress; + } + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&spiState->dmaSpiTx); + /* Disable SPI Tx DMA interrupt*/ + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), false); + /* Stop the running transfer. */ + FLEXIO_SPI_DRV_CompleteSendData(spiState); + + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_DmaTxCallback + * Description : This is not a public interface, called when dma tx ends. + * + *END**************************************************************************/ +static void FLEXIO_SPI_DRV_DmaTxCallback(void *param, dma_channel_status_t status) +{ + flexio_spi_state_t *spiState = (flexio_spi_state_t *)param; + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&spiState->dmaSpiTx); + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), false); + if(spiState->isTxBusy) + { + FLEXIO_SPI_DRV_CompleteSendData(spiState); + } +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_DmaRxCallback + * Description : This is not a public interface, called when dma rx ends. + * + *END**************************************************************************/ +static void FLEXIO_SPI_DRV_DmaRxCallback(void *param, dma_channel_status_t status) +{ + flexio_spi_state_t *spiState = (flexio_spi_state_t *)param; + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&spiState->dmaSpiRx); + FLEXIO_SPI_HAL_SetRxDmaCmd(&(spiState->spiDev), false); + if(spiState->isRxBusy) + { + FLEXIO_SPI_DRV_CompleteReceiveData(spiState); + } + else if(spiState->isXBusy) + { + FLEXIO_SPI_DRV_CompleteTransferData(spiState); + } +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_DmaSendDataBlocking + * Description : Send a period of data using DMA way. + * This function is an async function. + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaSendDataBlocking(flexio_spi_state_t *spiState, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + if((spiState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + /* Check that we're not busy already transmitting data from a previous + * function call. */ + if ((spiState->isTxBusy)||(spiState->isXBusy)) + { + return kStatus_FlexIO_SPI_TxBusy; + } + + if (txSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + /* Have not configure DMA. */ + if (!spiState->isTxUseDma) + { + FLEXIO_SPI_DRV_TxConfigDMA(spiState); + } + /* Configure DMA module */ + uint32_t destAddr; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferMSBAddr(&spiState->spiDev) + + (4 - spiState->dataSize/8); + } + else + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferLSBAddr(&spiState->spiDev); + } + DMA_DRV_ConfigTransfer(&spiState->dmaSpiTx,kDmaMemoryToPeripheral, + spiState->dataSize/8, (uint32_t)(txBuff + spiState->dataSize/8), + destAddr, (txSize - spiState->dataSize/8)); + DMA_DRV_StartChannel(&spiState->dmaSpiTx); + /* Put the first data in shifter to start the transmission */ + uint32_t tmp; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + tmp = *txBuff; + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<24); + }else + { + tmp = *((const uint16_t *)txBuff); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<16); + } + } + else + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *(spiState->txBuff)); + }else + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *((const uint16_t *)(spiState->txBuff))); + } + } + /* Indicates current transaction is non-blocking */ + spiState->isTxBlocking = true; + spiState->isTxBusy = true; + /*enable dma request interrupt*/ + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), true); + FLEXIO_DRV_Start(0); + /* Wait until the transmit is complete. */ + osa_status_t syncStatus; + do + { + syncStatus = OSA_SemaWait(&spiState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&spiState->dmaSpiTx); + + /* Update the information of the module driver state */ + spiState->isTxBusy = false; + + return kStatus_FlexIO_SPI_Timeout; + } + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_DmaSendData + * Description : Send a period of data using DMA way. + * This function is an async function. + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaSendData(flexio_spi_state_t *spiState, + const uint8_t * txBuff, uint32_t txSize) +{ + if ((spiState == NULL) || (txBuff == NULL) ) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + /* Check that we're not busy already transmitting data from a previous + * function call. */ + if ((spiState->isTxBusy)||(spiState->isXBusy)) + { + return kStatus_FlexIO_SPI_TxBusy; + } + + if (txSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + /* Have not configure DMA. */ + if (!spiState->isTxUseDma) + { + FLEXIO_SPI_DRV_TxConfigDMA(spiState); + } + /* Configure DMA module */ + uint32_t destAddr; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferMSBAddr(&spiState->spiDev) + + (4 - spiState->dataSize/8); + } + else + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferLSBAddr(&spiState->spiDev); + } + DMA_DRV_ConfigTransfer(&spiState->dmaSpiTx,kDmaMemoryToPeripheral, + spiState->dataSize/8, (uint32_t)(txBuff + spiState->dataSize/8), + destAddr, (txSize - spiState->dataSize/8)); + DMA_DRV_StartChannel(&spiState->dmaSpiTx); + /* Put the first data in shifter to start the transmission */ + uint32_t tmp; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + tmp = *txBuff; + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<24); + }else + { + tmp = *((const uint16_t *)txBuff); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<16); + } + } + else + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *(spiState->txBuff)); + }else + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *((const uint16_t *)(spiState->txBuff))); + } + } + /* Indicates current transaction is non-blocking */ + spiState->isTxBlocking = false; + spiState->isTxBusy = true; + /*enable dma request interrupt*/ + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), true); + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_DmaReceiveDataBlocking + * Description : Receive a period of data using interrupt way. + * This function is an async function. + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaReceiveDataBlocking(flexio_spi_state_t *spiState, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout) +{ + if ((spiState == NULL) || (rxBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + if ((spiState->isRxBusy)||(spiState->isXBusy)) + { + return kStatus_FlexIO_SPI_RxBusy; + } + + if (rxSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + if (!spiState->isRxUseDma) + { + FLEXIO_SPI_DRV_RxConfigDMA(spiState); + } + /* Configure DMA module */ + uint32_t srcAddr = FLEXIO_SPI_HAL_GetRxBufferMSBAddr(&spiState->spiDev); + DMA_DRV_ConfigTransfer(&spiState->dmaSpiRx,kDmaPeripheralToMemory, + spiState->dataSize/8, srcAddr, (uint32_t)rxBuff, rxSize); + DMA_DRV_StartChannel(&spiState->dmaSpiRx); + /* Indicates current transaction is non-blocking */ + spiState->isRxBlocking = true; + spiState->isRxBusy = true; + /*enable dma request interrupt*/ + FLEXIO_SPI_HAL_SetRxDmaCmd(&(spiState->spiDev), true); + FLEXIO_DRV_Start(0); + /* Wait until the transmit is complete. */ + osa_status_t syncStatus; + do + { + syncStatus = OSA_SemaWait(&spiState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&spiState->dmaSpiRx); + + /* Update the information of the module driver state */ + spiState->isRxBusy = false; + + return kStatus_FlexIO_SPI_Timeout; + } + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_DmaReceiveData + * Description : Receive a period of data using interrupt way. + * This function is an async function. + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaReceiveData(flexio_spi_state_t *spiState, uint8_t *rxBuff, uint32_t rxSize) +{ + if ((spiState == NULL) || (rxBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + if ((spiState->isRxBusy)||(spiState->isXBusy)) + { + return kStatus_FlexIO_SPI_RxBusy; + } + + if (rxSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + if (!spiState->isRxUseDma) + { + FLEXIO_SPI_DRV_RxConfigDMA(spiState); + } + /* Configure DMA module */ + uint32_t srcAddr = FLEXIO_SPI_HAL_GetRxBufferMSBAddr(&spiState->spiDev); + DMA_DRV_ConfigTransfer(&spiState->dmaSpiRx,kDmaPeripheralToMemory, + spiState->dataSize/8, srcAddr, (uint32_t)rxBuff, rxSize); + DMA_DRV_StartChannel(&spiState->dmaSpiRx); + /* Indicates current transaction is non-blocking */ + spiState->isRxBlocking = false; + spiState->isRxBusy = true; + /*enable dma request interrupt*/ + FLEXIO_SPI_HAL_SetRxDmaCmd(&(spiState->spiDev), true); + + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_DmaTransferDataBlocking + * Description : Send&Receive a period of data using interrupt way. + * This function is an async function. + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaTransferDataBlocking(flexio_spi_state_t *spiState, + const uint8_t *txBuff, + uint8_t *rxBuff, + uint32_t xSize, + uint32_t timeout) +{ + if ((spiState == NULL) || (txBuff == NULL) ||(rxBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + if ((spiState->isTxBusy)||(spiState->isRxBusy)||(spiState->isXBusy)) + { + return kStatus_FlexIO_SPI_XBusy; + } + + if (xSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + if (!spiState->isTxUseDma) + { + FLEXIO_SPI_DRV_TxConfigDMA(spiState); + } + if (!spiState->isRxUseDma) + { + FLEXIO_SPI_DRV_RxConfigDMA(spiState); + } + /* Configure DMA module */ + uint32_t destAddr; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferMSBAddr(&spiState->spiDev) + + (4 - spiState->dataSize/8); + } + else + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferLSBAddr(&spiState->spiDev); + } + DMA_DRV_ConfigTransfer(&spiState->dmaSpiTx,kDmaMemoryToPeripheral, + spiState->dataSize/8, (uint32_t)(txBuff + spiState->dataSize/8), + destAddr, (xSize - spiState->dataSize/8)); + DMA_DRV_StartChannel(&spiState->dmaSpiTx); + /* Put the first data in shifter to start the transmission */ + uint32_t tmp; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + tmp = *txBuff; + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<24); + }else + { + tmp = *((const uint16_t *)txBuff); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<16); + } + } + else + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *(spiState->txBuff)); + }else + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *((const uint16_t *)(spiState->txBuff))); + } + } + uint32_t srcAddr = FLEXIO_SPI_HAL_GetRxBufferMSBAddr(&spiState->spiDev); + DMA_DRV_ConfigTransfer(&spiState->dmaSpiRx,kDmaPeripheralToMemory, + spiState->dataSize/8, srcAddr, (uint32_t)rxBuff, xSize); + DMA_DRV_StartChannel(&spiState->dmaSpiRx); + /* Indicates current transaction is non-blocking */ + spiState->isXBlocking = true; + spiState->isXBusy = true; + /*enable dma request interrupt*/ + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), true); + FLEXIO_SPI_HAL_SetRxDmaCmd(&(spiState->spiDev), true); + FLEXIO_DRV_Start(0); + /* Wait until the transfer is complete. */ + osa_status_t syncStatus; + do + { + syncStatus = OSA_SemaWait(&spiState->xIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&spiState->dmaSpiTx); + DMA_DRV_StopChannel(&spiState->dmaSpiRx); + + /* Update the information of the module driver state */ + spiState->isXBusy = false; + + return kStatus_FlexIO_SPI_Timeout; + } + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_DmaTransferData + * Description : Send&Receive a period of data using interrupt way. + * This function is an async function. + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaTransferData(flexio_spi_state_t *spiState, + const uint8_t *txBuff, + uint8_t *rxBuff, + uint32_t xSize) +{ + if ((spiState == NULL) || (txBuff == NULL) ||(rxBuff == NULL)) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + if ((spiState->isTxBusy)||(spiState->isRxBusy)||(spiState->isXBusy)) + { + return kStatus_FlexIO_SPI_XBusy; + } + + if (xSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + if (!spiState->isTxUseDma) + { + FLEXIO_SPI_DRV_TxConfigDMA(spiState); + } + if (!spiState->isRxUseDma) + { + FLEXIO_SPI_DRV_RxConfigDMA(spiState); + } + /* Configure DMA module */ + uint32_t destAddr; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferMSBAddr(&spiState->spiDev) + + (4 - spiState->dataSize/8); + } + else + { + destAddr = FLEXIO_SPI_HAL_GetTxBufferLSBAddr(&spiState->spiDev); + } + DMA_DRV_ConfigTransfer(&spiState->dmaSpiTx,kDmaMemoryToPeripheral, + spiState->dataSize/8, (uint32_t)(txBuff + spiState->dataSize/8), + destAddr, (xSize - spiState->dataSize/8)); + DMA_DRV_StartChannel(&spiState->dmaSpiTx); + /* Put the first data in shifter to start the transmission */ + uint32_t tmp; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + tmp = *txBuff; + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<24); + }else + { + tmp = *((const uint16_t *)txBuff); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<16); + } + } + else + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *(spiState->txBuff)); + }else + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *((const uint16_t *)(spiState->txBuff))); + } + } + uint32_t srcAddr = FLEXIO_SPI_HAL_GetRxBufferMSBAddr(&spiState->spiDev); + DMA_DRV_ConfigTransfer(&spiState->dmaSpiRx,kDmaPeripheralToMemory, + spiState->dataSize/8, srcAddr, (uint32_t)rxBuff, xSize); + DMA_DRV_StartChannel(&spiState->dmaSpiRx); + /* Indicates current transaction is non-blocking */ + spiState->isXBlocking = false; + spiState->isXBusy = true; + /*enable dma request interrupt*/ + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), true); + FLEXIO_SPI_HAL_SetRxDmaCmd(&(spiState->spiDev), true); + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_DmaGetReceiveStatus + * Description : This function returns whether the previous SPI receive is + * complete. When performing an sync receive, the user can call this function + * to ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, + * the user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaGetReceiveStatus(flexio_spi_state_t * spiState, + uint32_t * bytesRemaining) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = DMA_DRV_GetUnfinishedBytes(&spiState->dmaSpiRx); + } + + return (spiState->isRxBusy ? kStatus_FlexIO_SPI_RxBusy : kStatus_FlexIO_SPI_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_DmaAbortReceivingData + * Description : This function shuts down the SPI by disabling interrupts and + * the transmitter/receiver. + * + *END**************************************************************************/ +flexio_spi_status_t FLEXIO_SPI_DRV_DmaAbortReceivingData(flexio_spi_state_t * spiState) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!spiState->isRxBusy) + { + return kStatus_FlexIO_SPI_NoReceiveInProgress; + } + + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&spiState->dmaSpiRx); + /* Disable SPI Rx DMA interrupt*/ + FLEXIO_SPI_HAL_SetTxDmaCmd(&(spiState->spiDev), false); + /* Stop the running transfer. */ + FLEXIO_SPI_DRV_CompleteReceiveData(spiState); + + return kStatus_FlexIO_SPI_Success; +} +#endif +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_TX_IRQHandler + * Description : Interrupt spiState for SDO for FlexIO SPI device. + * This spiState uses the buffers stored in the flexio_spi_state_t struct to send + * data. This is not a public API as it is called whenever an interrupt occurs. + * + *END**************************************************************************/ +void FLEXIO_SPI_DRV_TX_IRQHandler(void *param) +{ + flexio_spi_state_t *spiState = (flexio_spi_state_t *)param; + uint32_t tmp; + if(spiState == NULL) + { + return; + } + + /* Exit the ISR if no transfer is happening for this instance. */ + if ((!spiState->isTxBusy)&& (!spiState->isXBusy)) + { + return; + } + /* Handle transmit data register empty interrupt */ + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + --spiState->txSize; + /* Check to see if there are any more bytes to send */ + if (spiState->txSize) + { + /* Transmit data and update tx size/buff */ + ++spiState->txBuff; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + tmp = *(spiState->txBuff); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<24); + } + else + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *(spiState->txBuff)); + } + } + else + { + if(spiState->isTxBusy) + { + FLEXIO_SPI_DRV_CompleteSendData(spiState); + } + if(spiState->isXBusy) + { + FLEXIO_SPI_HAL_SetTxBufferEmptyIntCmd(&(spiState->spiDev), false); + } + } + } + else + { + spiState->txSize = spiState->txSize - 2; + if(spiState->txSize) + { + spiState->txBuff += 2; + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + tmp = *((const uint16_t *)(spiState->txBuff)); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<16); + } + else + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *((const uint16_t *)(spiState->txBuff))); + } + } + else + { + if(spiState->isTxBusy) + { + FLEXIO_SPI_DRV_CompleteSendData(spiState); + } + if(spiState->isXBusy) + { + FLEXIO_SPI_HAL_SetTxBufferEmptyIntCmd(&(spiState->spiDev), false); + } + } + } +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_RX_IRQHandler + * Description : Interrupt spiState for SDI for FlexIO SPI device. + * This spiState uses the buffers stored in the flexio_uart_state_t struct to transfer + * data. This is not a public API as it is called whenever an interrupt occurs. + * + *END**************************************************************************/ +void FLEXIO_SPI_DRV_RX_IRQHandler(void *param) +{ + flexio_spi_state_t *spiState = (flexio_spi_state_t *)param; + if(spiState == NULL) + { + return; + } + + /* Exit the ISR if no transfer is happening for this instance. */ + if ((!(spiState->isRxBusy))&&(!(spiState->isXBusy))) + { + return; + } + /* Handle transmit data register empty interrupt */ + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + *(spiState->rxBuff) = FLEXIO_SPI_HAL_GetDataMSB(&(spiState->spiDev)); + ++spiState->rxBuff; + --spiState->rxSize; + if(spiState->rxSize == 0) + { + if(spiState->isRxBusy) + { + FLEXIO_SPI_DRV_CompleteReceiveData(spiState); + } + if(spiState->isXBusy) + { + FLEXIO_SPI_DRV_CompleteTransferData(spiState); + } + if (spiState->rxCallback != NULL) + { + spiState->rxCallback(spiState); + } + } + } + else + { + *((uint16_t *)(spiState->rxBuff)) = FLEXIO_SPI_HAL_GetDataMSB(&(spiState->spiDev)); + spiState->rxBuff += 2; + spiState->rxSize -= 2; + if(spiState->rxSize == 0) + { + if(spiState->isRxBusy) + { + FLEXIO_SPI_DRV_CompleteReceiveData(spiState); + } + if(spiState->isXBusy) + { + FLEXIO_SPI_DRV_CompleteTransferData(spiState); + } + if (spiState->rxCallback != NULL) + { + spiState->rxCallback(spiState); + } + } + } +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_TxConfigDMA + * Description : Configure DMA for flexio SPI Tx port. + * This function allocates DMA channel and register dma callback. + *END**************************************************************************/ +static flexio_spi_status_t FLEXIO_SPI_DRV_TxConfigDMA(flexio_spi_state_t *spiState) +{ + uint32_t ret; + /* Request channel for Tx DMA */ + dma_request_source_t baseSource= kDmaRequestMux0FlexIOChannel0; + dma_request_source_t source = (dma_request_source_t)((uint32_t)baseSource + spiState->spiDev.shifterIdx[0]); +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + ret = EDMA_DRV_RequestChannel(kDmaAnyChannel, source, &spiState->edmaSpiTx); + if (ret == kEDMAInvalidChannel) + { + return kStatus_FlexIO_SPI_DmaRequestFail ; + } + EDMA_DRV_InstallCallback(&spiState->edmaSpiTx, FLEXIO_SPI_DRV_EdmaTxCallback, spiState); +#else + ret = DMA_DRV_RequestChannel(kDmaAnyChannel, source, &spiState->dmaSpiTx); + if (ret == kDmaInvalidChannel) + { + return kStatus_FlexIO_SPI_DmaRequestFail ; + } + DMA_DRV_RegisterCallback(&spiState->dmaSpiTx, FLEXIO_SPI_DRV_DmaTxCallback, spiState); +#endif + spiState->isTxUseDma = true; + return kStatus_FlexIO_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_RxConfigDMA + * Description : Configure DMA for flexio SPI Rx port. + * This function allocates DMA channel and register dma callback. + *END**************************************************************************/ +static flexio_spi_status_t FLEXIO_SPI_DRV_RxConfigDMA(flexio_spi_state_t *spiState) +{ + uint32_t ret; + /* Request channel for Tx DMA */ + dma_request_source_t baseSource= kDmaRequestMux0FlexIOChannel0; + dma_request_source_t source = (dma_request_source_t)((uint32_t)baseSource + spiState->spiDev.shifterIdx[1]); +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + ret = EDMA_DRV_RequestChannel(kDmaAnyChannel, source, &spiState->edmaSpiRx); + if (ret == kEDMAInvalidChannel) + { + return kStatus_FlexIO_SPI_DmaRequestFail; + } + EDMA_DRV_InstallCallback(&spiState->edmaSpiRx, FLEXIO_SPI_DRV_EdmaRxCallback, spiState); +#else + ret = DMA_DRV_RequestChannel(kDmaAnyChannel, source, &spiState->dmaSpiRx); + if (ret == kDmaInvalidChannel) + { + return kStatus_FlexIO_SPI_DmaRequestFail; + } + DMA_DRV_RegisterCallback(&spiState->dmaSpiRx, FLEXIO_SPI_DRV_DmaRxCallback, spiState); +#endif + spiState->isRxUseDma = true; + return kStatus_FlexIO_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_StartSendData + * Description : Initiate (start) a transmit by beginning the process of + * sending data and enabling the interrupt. + * + *END**************************************************************************/ +static flexio_spi_status_t FLEXIO_SPI_DRV_StartSendData(flexio_spi_state_t *spiState, + const uint8_t * txBuff, + uint32_t txSize) +{ + uint32_t tmp; + /* Check that we're not busy already transmitting data from a previous + * function call. */ + if (spiState->isTxBusy) + { + return kStatus_FlexIO_SPI_TxBusy; + } + + if (txSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + /* Initialize the module driver state structure. */ + spiState->txBuff = txBuff; + spiState->txSize = txSize; + spiState->isTxBusy = true; + /* Make sure the transmit data register is empty and ready for data */ +// while(!FLEXIO_SPI_HAL_GetTxBufferEmptyFlag(&(spiState->spiDev))) { } + + /* Put the first data in shifter to start the transmission */ + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + tmp = *(spiState->txBuff); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<24); + }else + { + tmp = *((const uint16_t *)(spiState->txBuff)); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<16); + } + } + else + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *(spiState->txBuff)); + }else + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *((const uint16_t *)(spiState->txBuff))); + } + } + /* Enable interrupt generation for tx shifter. */ + FLEXIO_SPI_HAL_SetTxBufferEmptyIntCmd(&(spiState->spiDev), true); + FLEXIO_DRV_Start(0); + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_StartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static flexio_spi_status_t FLEXIO_SPI_DRV_StartReceiveData(flexio_spi_state_t *spiState, + uint8_t * rxBuff, + uint32_t rxSize) +{ + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Check that we're not busy receiving data from a previous function call. */ + if ((spiState->isRxBusy) && (!spiState->rxCallback)) + { + return kStatus_FlexIO_SPI_RxBusy; + } + + if (rxSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + + /* Initialize the module driver state struct to indicate transfer in progress + * and with the buffer and byte count data */ + spiState->rxBuff = rxBuff; + spiState->rxSize = rxSize; + spiState->isRxBusy = true; + + /* Enable the receive data full interrupt */ + FLEXIO_SPI_HAL_SetRxBufferFullIntCmd(&(spiState->spiDev), true); + // FLEXIO_DRV_Start(0); + + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_StartTransferData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static flexio_spi_status_t FLEXIO_SPI_DRV_StartTransferData(flexio_spi_state_t *spiState, + const uint8_t *txBuff,uint8_t * rxBuff, + uint32_t xSize) +{ + uint32_t tmp; + if(spiState == NULL) + { + return kStatus_FlexIO_SPI_InvalidParam; + } + + /* Check that we're not busy transferring data from a previous function call. */ + if ((spiState->isXBusy) && (!spiState->rxCallback)) + { + return kStatus_FlexIO_SPI_XBusy; + } + + if (xSize == 0U) + { + return kStatus_FlexIO_SPI_NoDataToDeal; + } + + /* Initialize the module driver state struct to indicate transfer in progress + * and with the buffer and byte count data */ + spiState->txBuff = txBuff; + spiState->txSize = xSize; + spiState->rxBuff = rxBuff; + spiState->rxSize = xSize; + spiState->isXBusy = true; + + /* Make sure the transmit data register is empty and ready for data */ +// while(!FLEXIO_SPI_HAL_GetTxBufferEmptyFlag(&(spiState->spiDev))) { } + + /* Put the first data in shifter to start the transmission */ + if(spiState->bitDirection == kFlexIOSpiMsbFirst) + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + tmp = *(spiState->txBuff); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<24); + }else + { + tmp = *((const uint16_t *)(spiState->txBuff)); + FLEXIO_SPI_HAL_PutDataMSB(&(spiState->spiDev), tmp<<16); + } + } + else + { + if(spiState->dataSize == kFlexIOSpi8BitMode) + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *(spiState->txBuff)); + }else + { + FLEXIO_SPI_HAL_PutDataLSB(&(spiState->spiDev), *((const uint16_t *)(spiState->txBuff))); + } + } + /* Enable the send data empty and receive data full interrupt */ + FLEXIO_SPI_HAL_SetTxBufferEmptyIntCmd(&(spiState->spiDev), true); + FLEXIO_SPI_HAL_SetRxBufferFullIntCmd(&(spiState->spiDev), true); + if(spiState->mode == kFlexIOSpiMaster) + { + FLEXIO_DRV_Start(0); + } + return kStatus_FlexIO_SPI_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_CompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXIO_SPI_DRV_CompleteSendData(flexio_spi_state_t *spiState) +{ + if(spiState == NULL) + { + return; + } + + /* Disable the transmitter data register empty interrupt */ + FLEXIO_SPI_HAL_SetTxBufferEmptyIntCmd(&(spiState->spiDev), false); + + /* Signal the synchronous completion object. */ + if (spiState->isTxBlocking) + { + OSA_SemaPost(&spiState->txIrqSync); + } + + /* Update the information of the module driver state */ + spiState->isTxBusy = false; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_CompleteReceiveData + * Description : Finish up a receive by completing the process of receiving + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXIO_SPI_DRV_CompleteReceiveData(flexio_spi_state_t *spiState) +{ + if(spiState == NULL) + { + return; + } + + /* Disable receive data full interrupt */ + FLEXIO_SPI_HAL_SetRxBufferFullIntCmd(&(spiState->spiDev), false); + + /* Signal the synchronous completion object. */ + if (spiState->isRxBlocking) + { + OSA_SemaPost(&spiState->rxIrqSync); + } + + /* Update the information of the module driver state */ + spiState->isRxBusy = false; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_SPI_DRV_CompleteTransferData + * Description : Finish up a transfer by completing the process of transferring + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXIO_SPI_DRV_CompleteTransferData(flexio_spi_state_t *spiState) +{ + if(spiState == NULL) + { + return; + } + + /* Disable receive data&send data full interrupt */ + FLEXIO_SPI_HAL_SetRxBufferFullIntCmd(&(spiState->spiDev), false); + FLEXIO_SPI_HAL_SetTxBufferEmptyIntCmd(&(spiState->spiDev), false); + /* Signal the synchronous completion object. */ + if (spiState->isXBlocking) + { + OSA_SemaPost(&spiState->xIrqSync); + } + + /* Update the information of the module driver state */ + spiState->isXBusy = false; +} diff --git a/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_uart_dma_driver.c b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_uart_dma_driver.c new file mode 100755 index 0000000..a990039 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_uart_dma_driver.c @@ -0,0 +1,605 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 <string.h> +#include "fsl_flexio_uart_dma_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#include "fsl_dma_request.h" +#if FSL_FEATURE_SOC_DMA_COUNT + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static void FLEXIO_UART_DRV_DmaCompleteSendData(flexio_uart_dmastate_t * uartDmaState); +static void FLEXIO_UART_DRV_DmaTxCallback(void *param, dma_channel_status_t status); +static flexio_uart_status_t FLEXIO_UART_DRV_DmaStartSendData(flexio_uart_dmastate_t * uartDmaState, + const uint8_t * txBuff, + uint32_t txSize); +static void FLEXIO_UART_DRV_DmaCompleteReceiveData(flexio_uart_dmastate_t * uartDmaState); +static void FLEXIO_UART_DRV_DmaRxCallback(void *param, dma_channel_status_t status); +static flexio_uart_status_t FLEXIO_UART_DRV_DmaStartReceiveData(flexio_uart_dmastate_t * uartDmaState, + uint8_t * rxBuff, + uint32_t rxSize); +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaInit + * Description : Initializes a FLEXIO simulated UART device to work with DMA. + * This function initializes the run-time state structure to keep track of the on-going + * transfers, initializes the module to user-defined settings and default settings, + * configures underlying flexio Pin,shifter and timer resource and enables the FLEXIO + * simulated UART module DMA interrupt. + * The following is an example of how to set up the uart_dma_state_t and the + * uart_user_config_t parameters and how to call the UART_DRV_DmaInit function + * by passing in these parameters: + * uart_user_config_t uartConfig; + flexio_uartdma_userconfig_t uartDmaConfig; + uartDmaConfig.baudRate = 9600; + uartDmaConfig.bitCountPerChar = kUart8BitsPerChar; + uartDmaConfig.uartMode = flexioUART_TxRx; + * FLEXIO_UART_DRV_DmaInit(instance, &uartDmaState, &uartDmaConfig); + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_DmaInit(uint32_t instance, + flexio_uart_dmastate_t * uartDmaState, + const flexio_uartdma_userconfig_t * uartDmaConfig) +{ + if(!(instance < FLEXIO_INSTANCE_COUNT)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + if((uartDmaState == NULL)||(uartDmaConfig == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + FLEXIO_Type* base = g_flexioBase[instance]; + uint32_t flexioSourceClock; + flexio_uart_config_t devConfig; + dma_request_source_t uartTxDmaRequest = kDmaRequestMux0Disable; + dma_request_source_t uartRxDmaRequest = kDmaRequestMux0Disable; + uint32_t dmaRequestBase = kDmaRequestMux0FlexIOChannel0; + + /* Clear the state structure for this instance. */ + memset(uartDmaState, 0, sizeof(flexio_uart_dmastate_t)); + + /* Create Semaphore for txIrq and rxIrq. */ + OSA_SemaCreate(&uartDmaState->txIrqSync, 0); + OSA_SemaCreate(&uartDmaState->rxIrqSync, 0); + + /* Get FlexIO clock frequency for baudrate caculation*/ + flexioSourceClock = CLOCK_SYS_GetFlexioFreq(instance); + uartDmaState->mode = uartDmaConfig->uartMode; + devConfig.flexioBusClk = flexioSourceClock; + devConfig.baudrate = uartDmaConfig->baudRate; + devConfig.bitCount = uartDmaConfig->bitCountPerChar; + + /*Configure buadrate, bit count and hardware resource including pin, shifter and timer for Tx module*/ + if((uartDmaConfig->uartMode == flexioUART_TxOnly)||(uartDmaConfig->uartMode == flexioUART_TxRx)) + { + uartDmaState->txDev.flexioBase = base; + uartDmaState->txDev.txPinIdx = uartDmaConfig->txConfig.pinIdx; + uartDmaState->txDev.shifterIdx = uartDmaConfig->txConfig.shifterIdx; + uartDmaState->txDev.timerIdx = uartDmaConfig->txConfig.timerIdx; + FLEXIO_UART_Tx_HAL_Configure(&(uartDmaState->txDev), &devConfig); + } + /*Configure buadrate, bit count and hardware resource including pin, shifter and timer for Rx module*/ + if((uartDmaConfig->uartMode == flexioUART_RxOnly)||(uartDmaConfig->uartMode == flexioUART_TxRx)) + { + uartDmaState->rxDev.flexioBase = base; + uartDmaState->rxDev.rxPinIdx = uartDmaConfig->rxConfig.pinIdx; + uartDmaState->rxDev.shifterIdx = uartDmaConfig->rxConfig.shifterIdx; + uartDmaState->rxDev.timerIdx = uartDmaConfig->rxConfig.timerIdx; + FLEXIO_UART_Rx_HAL_Configure(&(uartDmaState->rxDev), &devConfig); + } + + FLEXIO_UART_Tx_HAL_SetTxDmaCmd(&(uartDmaState->txDev), true); + FLEXIO_UART_Rx_HAL_SetRxDmaCmd(&(uartDmaState->rxDev), true); + + switch (instance) + { + case 0: + uartRxDmaRequest = (dma_request_source_t)(dmaRequestBase + uartDmaState->rxDev.shifterIdx); + uartTxDmaRequest = (dma_request_source_t)(dmaRequestBase + uartDmaState->txDev.shifterIdx); + break; + default : + break; + } + + /* Request DMA channels for RX FIFO. */ + DMA_DRV_RequestChannel(kDmaAnyChannel, uartRxDmaRequest, + &uartDmaState->dmaUartRx); + DMA_DRV_RegisterCallback(&uartDmaState->dmaUartRx, + FLEXIO_UART_DRV_DmaRxCallback, (void *)uartDmaState); + + /* Request DMA channels for TX FIFO. */ + DMA_DRV_RequestChannel(kDmaAnyChannel, uartTxDmaRequest, + &uartDmaState->dmaUartTx); + DMA_DRV_RegisterCallback(&uartDmaState->dmaUartTx, + FLEXIO_UART_DRV_DmaTxCallback, (void *)uartDmaState); + + return kStatus_FlexIO_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaDeinit + * Description : This function disables the FLEXIO simulated UART-DMA trigger. + * + *END**************************************************************************/ +void FLEXIO_UART_DRV_DmaDeinit(flexio_uart_dmastate_t * uartDmaState) +{ + if(uartDmaState == NULL) + { + return; + } + + FLEXIO_UART_Tx_HAL_SetTxDmaCmd(&(uartDmaState->txDev), false); + FLEXIO_UART_Rx_HAL_SetRxDmaCmd(&(uartDmaState->rxDev), false); + /* Release DMA channel. */ + DMA_DRV_FreeChannel(&uartDmaState->dmaUartRx); + DMA_DRV_FreeChannel(&uartDmaState->dmaUartTx); + + /* Destroy TX and RX sema. */ + OSA_SemaDestroy(&uartDmaState->txIrqSync); + OSA_SemaDestroy(&uartDmaState->rxIrqSync); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaSendDataBlocking + * Description : Sends (transmits) data out through the FLEXIO simulated UART-DMA module + * using a blocking method. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_DmaSendDataBlocking(flexio_uart_dmastate_t * uartDmaState, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + if((uartDmaState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + uartDmaState->isTxBlocking = true; + + /* Start the transmission process */ + retVal = FLEXIO_UART_DRV_DmaStartSendData(uartDmaState, txBuff, txSize); + + if (retVal == kStatus_FlexIO_UART_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&uartDmaState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&uartDmaState->dmaUartTx); + + /* Update the information of the module driver state */ + uartDmaState->isTxBusy = false; + + retVal = kStatus_FlexIO_UART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaSendData + * Description : Sends (transmits) data through the FLEXIO simulated UART-DMA module using a + * non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the transmit function. The application + * has to get the transmit status to see when the transmit is complete. In + * other words, after calling non-blocking (asynchronous) send function, the + * application must get the transmit status to check if transmit is completed + * or not. The asynchronous method of transmitting and receiving allows the UART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_DmaSendData(flexio_uart_dmastate_t * uartDmaState, + const uint8_t * txBuff, + uint32_t txSize) +{ + if((uartDmaState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + + /* Indicates current transaction is non-blocking. */ + uartDmaState->isTxBlocking = false; + + /* Start the transmission process*/ + retVal = FLEXIO_UART_DRV_DmaStartSendData(uartDmaState, txBuff, txSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaGetTransmitStatus + * Description : This function returns whether the previous UART transmit + * has finished. When performing an async transmit, the user can call this + * function to ascertain the state of the current transmission: in progress + * (or busy) or complete (success). In addition, if the transmission is still + * in progress, the user can obtain the number of words that have been + * currently transferred. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_DmaGetTransmitStatus(flexio_uart_dmastate_t * uartDmaState, + uint32_t * bytesRemaining) +{ + if(uartDmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = DMA_DRV_GetUnfinishedBytes(&uartDmaState->dmaUartTx); + } + + return (uartDmaState->isTxBusy ? kStatus_FlexIO_UART_TxBusy : kStatus_FlexIO_UART_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaAbortSendingData + * Description : This function Terminates a non-blocking FLEXIO simulated UART-DMA + * transmission early.During an async UART transmission, the user has the option to + * terminate the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_DmaAbortSendingData(flexio_uart_dmastate_t * uartDmaState) +{ + if(uartDmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!uartDmaState->isTxBusy) + { + return kStatus_FlexIO_UART_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + FLEXIO_UART_DRV_DmaCompleteSendData(uartDmaState); + + return kStatus_FlexIO_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaReceiveDataBlocking + * Description : This function gets (receives) data from the FLEXIO simulated UART-DMA + * module using a blocking method.A blocking (also known as synchronous) function means + * that the function does not return until the receive is complete. This blocking + * function is used to send data through the UART port. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_DmaReceiveDataBlocking(flexio_uart_dmastate_t * uartDmaState, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout) +{ + if((uartDmaState == NULL)||(rxBuff == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + uartDmaState->isRxBlocking = true; + + retVal = FLEXIO_UART_DRV_DmaStartReceiveData(uartDmaState, rxBuff, rxSize); + + if (retVal == kStatus_FlexIO_UART_Success) + { + /* Wait until all the data is received or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&uartDmaState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&uartDmaState->dmaUartRx); + + /* Update the information of the module driver state */ + uartDmaState->isRxBusy = false; + + retVal = kStatus_FlexIO_UART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaReceiveData + * Description : This function gets (receives) data from the FLEXIO simulated + * UART-DMA module using a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. In other + * words, after calling non-blocking (asynchronous) get function, the + * application must get the receive status to check if receive is completed or + * not. The asynchronous method of transmitting and receiving allows the UART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_DmaReceiveData(flexio_uart_dmastate_t * uartDmaState, + uint8_t * rxBuff, + uint32_t rxSize) +{ + if((uartDmaState == NULL)||(rxBuff == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + + /* Indicates current transaction is non-blocking. */ + uartDmaState->isRxBlocking = false; + + retVal = FLEXIO_UART_DRV_DmaStartReceiveData(uartDmaState, rxBuff, rxSize); + + return retVal ; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaGetReceiveStatus + * Description : This function returns whether the previous UART receive is + * complete. When performing an async receive, the user can call this function + * to ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, + * the user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_DmaGetReceiveStatus(flexio_uart_dmastate_t * uartDmaState, + uint32_t * bytesRemaining) +{ + if(uartDmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = DMA_DRV_GetUnfinishedBytes(&uartDmaState->dmaUartRx); + } + + return (uartDmaState->isRxBusy ? kStatus_FlexIO_UART_RxBusy : kStatus_FlexIO_UART_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaAbortReceivingData + * Description : This function shuts down the UART by disabling interrupts and + * the transmitter/receiver. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_DmaAbortReceivingData(flexio_uart_dmastate_t * uartDmaState) +{ + if(uartDmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!uartDmaState->isRxBusy) + { + return kStatus_FlexIO_UART_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + FLEXIO_UART_DRV_DmaCompleteReceiveData(uartDmaState); + + return kStatus_FlexIO_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaCompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXIO_UART_DRV_DmaCompleteSendData(flexio_uart_dmastate_t * uartDmaState) +{ + if(uartDmaState == NULL) + { + return; + } + + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&uartDmaState->dmaUartTx); + + /* Signal the synchronous completion object. */ + if (uartDmaState->isTxBlocking) + { + OSA_SemaPost(&uartDmaState->txIrqSync); + } + + /* Update the information of the module driver state */ + uartDmaState->isTxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaTxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void FLEXIO_UART_DRV_DmaTxCallback(void *param, dma_channel_status_t status) +{ + FLEXIO_UART_DRV_DmaCompleteSendData((flexio_uart_dmastate_t *)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaStartSendData + * Description : This is not a public interface. + * + *END**************************************************************************/ +static flexio_uart_status_t FLEXIO_UART_DRV_DmaStartSendData(flexio_uart_dmastate_t * uartDmaState, + const uint8_t * txBuff, + uint32_t txSize) +{ + if(uartDmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + dma_channel_t *chn = &uartDmaState->dmaUartTx; + + /* Check that we're not busy already transmitting data from a previous function call. */ + if (uartDmaState->isTxBusy) + { + return kStatus_FlexIO_UART_TxBusy; + } + + /* Update UART DMA run-time structure. */ + uartDmaState->isTxBusy = true; + /*Config UART TX DMA transfer*/ + uint32_t destAddr = FLEXIO_UART_Tx_HAL_GetTxBufferAddr((&(uartDmaState->txDev))); + DMA_DRV_ConfigTransfer(chn,kDmaMemoryToPeripheral, + 1, (uint32_t)(txBuff), destAddr, txSize); + + DMA_DRV_StartChannel(chn); + + return kStatus_FlexIO_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaCompleteReceiveData + * Description : Finish up a receive by completing the process of receiving data + * and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXIO_UART_DRV_DmaCompleteReceiveData(flexio_uart_dmastate_t * uartDmaState) +{ + if(uartDmaState == NULL) + { + return; + } + + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&uartDmaState->dmaUartRx); + + /* Signal the synchronous completion object. */ + if (uartDmaState->isRxBlocking) + { + OSA_SemaPost(&uartDmaState->rxIrqSync); + } + + /* Update the information of the module driver state */ + uartDmaState->isRxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaRxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void FLEXIO_UART_DRV_DmaRxCallback(void *param, dma_channel_status_t status) +{ + FLEXIO_UART_DRV_DmaCompleteReceiveData((flexio_uart_dmastate_t *)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_DmaStartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static flexio_uart_status_t FLEXIO_UART_DRV_DmaStartReceiveData(flexio_uart_dmastate_t * uartDmaState, + uint8_t * rxBuff, + uint32_t rxSize) +{ + if(uartDmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + dma_channel_t *chn = &uartDmaState->dmaUartRx; + + /* Check that we're not busy already receiving data from a previous function call. */ + if (uartDmaState->isRxBusy) + { + return kStatus_FlexIO_UART_RxBusy; + } + + /* Update UART DMA run-time structure. */ + uartDmaState->isRxBusy = true; + /*Config UART RX DMA transfer*/ + uint32_t srcAddr = FLEXIO_UART_Rx_HAL_GetRxBufferAddr(&(uartDmaState->rxDev)); + DMA_DRV_ConfigTransfer(chn,kDmaPeripheralToMemory, + 1, srcAddr, (uint32_t)rxBuff, rxSize); + + DMA_DRV_StartChannel(chn); + + return kStatus_FlexIO_UART_Success; +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_uart_driver.c b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_uart_driver.c new file mode 100755 index 0000000..728968d --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_uart_driver.c @@ -0,0 +1,629 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 <string.h> +#include "fsl_flexio_uart_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_FLEXIO_COUNT + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static flexio_uart_status_t FLEXIO_UART_DRV_StartSendData(flexio_uart_state_t *uartState, + const uint8_t * txBuff, + uint32_t txSize); +static flexio_uart_status_t FLEXIO_UART_DRV_StartReceiveData(flexio_uart_state_t *uartState, + uint8_t * rxBuff, + uint32_t rxSize); +static void FLEXIO_UART_DRV_CompleteSendData(flexio_uart_state_t *uartState); +static void FLEXIO_UART_DRV_CompleteReceiveData(flexio_uart_state_t *uartState); +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_Init + * Description : This function initializes a UART instance for operation. + * This function will initialize the run-time state structure to keep track of + * the on-going transfers, ungate the clock to the UART module, initialize the + * module to user defined settings and default settings, configure the IRQ state + * structure and enable the module-level interrupt to the core, and enable the + * UART module transmitter and receiver. + * The following is an example of how to set up the uart_state_t and the + * uart_user_config_t parameters and how to call the UART_DRV_Init function by + * passing in these parameters: + * flexio_uart_user_config_t uartConfig; + * uartConfig.baudRate = 9600; + * uartConfig.bitCountPerChar = kFlexIOUart8BitsPerChar; + * uart_state_t uartState; + * UART_DRV_Init(instance, &uartState, &uartConfig); + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_Init(uint32_t instance, flexio_uart_state_t * uartState, + const flexio_uart_userconfig_t * uartConfig) +{ + if((uartState == NULL)||(uartConfig == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + FLEXIO_Type* base = g_flexioBase[instance]; + uint32_t flexioSourceClock; + flexio_uart_config_t devConfig; + /*Reset the uartState structure*/ + memset(uartState,0,sizeof(*uartState)); + /* Create Semaphore for txIrq and rxIrq. */ + OSA_SemaCreate(&uartState->txIrqSync, 0); + OSA_SemaCreate(&uartState->rxIrqSync, 0); + /* Get FlexIO clock frequency for baudrate caculation*/ + flexioSourceClock = CLOCK_SYS_GetFlexioFreq(instance); + uartState->mode = uartConfig->uartMode; + devConfig.flexioBusClk = flexioSourceClock; + devConfig.baudrate = uartConfig->baudRate; + devConfig.bitCount = uartConfig->bitCounter; + /*Configure buadrate, bit count and hardware resource including pin, shifter and timer for Tx module*/ + if((uartConfig->uartMode == flexioUART_TxOnly)||(uartConfig->uartMode == flexioUART_TxRx)) + { + uartState->txDev.flexioBase = base; + uartState->txDev.txPinIdx = uartConfig->txConfig.pinIdx; + uartState->txDev.shifterIdx = uartConfig->txConfig.shifterIdx; + uartState->txDev.timerIdx = uartConfig->txConfig.timerIdx; + FLEXIO_UART_Tx_HAL_Configure(&(uartState->txDev), &devConfig); + FLEXIO_DRV_RegisterCallback(instance,uartState->txDev.shifterIdx, + FLEXIO_UART_DRV_TX_IRQHandler,(void *)(uartState)); + } + /*Configure buadrate, bit count and hardware resource including pin, shifter and timer for Rx module*/ + if((uartConfig->uartMode == flexioUART_RxOnly)||(uartConfig->uartMode == flexioUART_TxRx)) + { + uartState->rxDev.flexioBase = base; + uartState->rxDev.rxPinIdx = uartConfig->rxConfig.pinIdx; + uartState->rxDev.shifterIdx = uartConfig->rxConfig.shifterIdx; + uartState->rxDev.timerIdx = uartConfig->rxConfig.timerIdx; + FLEXIO_UART_Rx_HAL_Configure(&(uartState->rxDev), &devConfig); + FLEXIO_DRV_RegisterCallback(instance,uartState->rxDev.shifterIdx, + FLEXIO_UART_DRV_RX_IRQHandler,(void *)(uartState)); + } + return kStatus_FlexIO_UART_Success; +} +void FLEXIO_UART_DRV_Deinit(flexio_uart_state_t *uartState) +{ + /* Destroy TX and RX sema. */ + OSA_SemaDestroy(&uartState->txIrqSync); + OSA_SemaDestroy(&uartState->rxIrqSync); +} +flexio_uart_rx_callback_t FLEXIO_UART_DRV_InstallRxCallback(flexio_uart_state_t *uartState,flexio_uart_rx_callback_t function, + uint8_t * rxBuff,void * callbackParam,bool alwaysEnableRxIrq) +{ + flexio_uart_rx_callback_t currentCallback = uartState->rxCallback; + uartState->rxCallback = function; + uartState->rxCallbackParam = callbackParam; + uartState->rxBuff = rxBuff; + + /* Enable/Disable the receive data full interrupt */ + uartState->isRxBusy = true; + return currentCallback; +} +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_SendDataBlocking + * Description : This function sends (transmits) data out through the UART + * module using a blocking method. + * A blocking (also known as synchronous) function means that the function does + * not return until the transmit is complete. This blocking function is used to + * send data through the UART port. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_SendDataBlocking(flexio_uart_state_t *uartState, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + if((uartState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking.*/ + uartState->isTxBlocking = true; + + /* Start the transmission process */ + retVal = FLEXIO_UART_DRV_StartSendData(uartState, txBuff, txSize); + + if (retVal == kStatus_FlexIO_UART_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&uartState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable the transmitter data register empty interrupt */ + FLEXIO_UART_Tx_HAL_SetTxBufferEmptyIntCmd(&(uartState->txDev), false); + /* Update the information of the module driver state */ + uartState->isTxBusy = false; + + retVal = kStatus_FlexIO_UART_Timeout; + } + } + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_SendData + * Description : This function sends (transmits) data through the UART module + * using a non-blocking method. + * A non-blocking (also known as asynchronous) function means that the function + * returns immediately after initiating the transmit function. The application + * has to get the transmit status to see when the transmit is complete. In + * other words, after calling non-blocking (asynchronous) send function, the + * application must get the transmit status to check if transmit is completed + * or not. The asynchronous method of transmitting and receiving allows the UART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_SendData(flexio_uart_state_t *uartState, + const uint8_t * txBuff, + uint32_t txSize) +{ + if((uartState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + + /* Indicates current transaction is non-blocking */ + uartState->isTxBlocking = false; + + /* Start the transmission process */ + retVal = FLEXIO_UART_DRV_StartSendData(uartState, txBuff, txSize); + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_GetTransmitStatus + * Description : This function returns whether the previous UART transmit has + * finished. + * When performing an async transmit, the user can call this function to + * ascertain the state of the current transmission: in progress (or busy) or + * complete (success). In addition, if the transmission is still in progress, + * the user can obtain the number of words that have been currently transferred. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_GetTransmitStatus(flexio_uart_state_t *uartState, uint32_t * bytesRemaining) +{ + if(uartState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + uint32_t txSize = uartState->txSize; + + /* Fill in the bytes transferred. This may return that all bytes were + * transmitted, however, for IPs with FIFO support, there still may be data + * in the TX FIFO still in the process of being transmitted. */ + if (bytesRemaining) + { + *bytesRemaining = txSize; + } + + if (txSize) + { + retVal = kStatus_FlexIO_UART_TxBusy; + } + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_AbortSendingData + * Description : This function ends a non-blocking UART transmission early. + * During a non-blocking UART transmission, the user has the option to terminate + * the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_AbortSendingData(flexio_uart_state_t *uartState) +{ + if(uartState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!uartState->isTxBusy) + { + return kStatus_FlexIO_UART_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + FLEXIO_UART_DRV_CompleteSendData(uartState); + + return kStatus_FlexIO_UART_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_ReceiveDataBlocking + * Description : This function gets (receives) data from the UART module using + * a blocking method. A blocking (also known as synchronous) function means that + * the function does not return until the receive is complete. This blocking + * function is used to send data through the UART port. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_ReceiveDataBlocking(flexio_uart_state_t *uartState, uint8_t * rxBuff, + uint32_t rxSize, uint32_t timeout) +{ + if((uartState == NULL)||(rxBuff == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking.*/ + uartState->isRxBlocking = true; + + retVal = FLEXIO_UART_DRV_StartReceiveData(uartState, rxBuff, rxSize); + + if (retVal == kStatus_FlexIO_UART_Success) + { + /* Wait until all the data is received or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&uartState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable receive data full and rx overrun interrupt */ + FLEXIO_UART_Rx_HAL_SetRxBufferFullIntCmd(&(uartState->rxDev), false); + /* Update the information of the module driver state */ + uartState->isRxBusy = false; + + retVal = kStatus_FlexIO_UART_Timeout; + } + } + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_ReceiveData + * Description : This function gets (receives) data from the UART module using + * a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. In other + * words, after calling non-blocking (asynchronous) get function, the + * application must get the receive status to check if receive is completed or + * not. The asynchronous method of transmitting and receiving allows the UART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_ReceiveData(flexio_uart_state_t *uartState, + uint8_t * rxBuff, + uint32_t rxSize) +{ + if((uartState == NULL)||(rxBuff == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + + /* Indicates current transaction is non-blocking.*/ + uartState->isRxBlocking = false; + + retVal = FLEXIO_UART_DRV_StartReceiveData(uartState, rxBuff, rxSize); + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_GetReceiveStatus + * Description : This function returns whether the previous UART receive is + * completed. + * When performing a non-blocking receive, the user can call this function to + * ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, the + * user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_GetReceiveStatus(flexio_uart_state_t *uartState, + uint32_t * bytesRemaining) +{ + if(uartState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + uint32_t rxSize = uartState->rxSize; + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = rxSize; + } + + if (rxSize) + { + retVal = kStatus_FlexIO_UART_RxBusy; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_AbortReceivingData + * Description : This function shuts down the UART by disabling interrupts and + * the transmitter/receiver. + * This function disables the UART interrupts, disables the transmitter and + * receiver, and flushes the FIFOs (for modules that support FIFOs). + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_AbortReceivingData(flexio_uart_state_t *uartState) +{ + if(uartState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } assert(uartState); + + /* Check if a transfer is running. */ + if (!uartState->isRxBusy) + { + return kStatus_FlexIO_UART_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + FLEXIO_UART_DRV_CompleteReceiveData(uartState); + + return kStatus_FlexIO_UART_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_TX_IRQHandler + * Description : Interrupt handler for TX of FLEXIO UART. + * This handler uses the buffers stored in the flexio_uart_state_t struct to transfer + * data. This is not a public API as it is called whenever an interrupt occurs. + * + *END**************************************************************************/ +void FLEXIO_UART_DRV_TX_IRQHandler(void *param) +{ + flexio_uart_state_t *uartState = (flexio_uart_state_t *)param; + if(uartState == NULL) + { + return; + } + + /* Exit the ISR if no transfer is happening for this instance. */ + if ((!uartState->isTxBusy)) + { + return; + } + /* Handle transmit data register empty interrupt */ + if((FLEXIO_UART_Tx_HAL_GetTxBufferEmptyIntCmd(&(uartState->txDev))) + && (FLEXIO_UART_Tx_HAL_GetTxBufferEmptyFlag(&(uartState->txDev)))) + { + --uartState->txSize; + /* Check to see if there are any more bytes to send */ + if (uartState->txSize) + { + ++uartState->txBuff; + /* Transmit data and update tx size/buff */ + FLEXIO_UART_Tx_HAL_PutData(&(uartState->txDev), *(uartState->txBuff)); + } + else + { + FLEXIO_UART_DRV_CompleteSendData(uartState); + } + } + +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_RX_IRQHandler + * Description : Interrupt handler for RX of FLEXIO UART. + * This handler uses the buffers stored in the flexio_uart_state_t struct to transfer + * data. This is not a public API as it is called whenever an interrupt occurs. + * + *END**************************************************************************/ +void FLEXIO_UART_DRV_RX_IRQHandler(void *param) +{ + flexio_uart_state_t *uartState = (flexio_uart_state_t *)param; + if(uartState == NULL) + { + return; + } + + /* Exit the ISR if no transfer is happening for this instance. */ + if ((!uartState->isRxBusy)) + { + return; + } + /* Handle receive data register full interrupt */ + /* Get data and put into receive buffer */ + *(uartState->rxBuff) = FLEXIO_UART_Rx_HAL_GetData(&(uartState->rxDev)); + + /* Invoke callback if there is one */ + if (uartState->rxCallback != NULL) + { + uartState->rxCallback(uartState); + } + else + { + ++uartState->rxBuff; + --uartState->rxSize; + /* Check and see if this was the last byte received */ + if (uartState->rxSize == 0) + { + FLEXIO_UART_DRV_CompleteReceiveData(uartState); + } + } +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_StartSendData + * Description : Initiate (start) a transmit by beginning the process of + * sending data and enabling the interrupt. + * + *END**************************************************************************/ +static flexio_uart_status_t FLEXIO_UART_DRV_StartSendData(flexio_uart_state_t *uartState, + const uint8_t * txBuff, + uint32_t txSize) +{ + if(uartState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + /* Check that we're not busy already transmitting data from a previous + * function call. */ + if (uartState->isTxBusy) + { + return kStatus_FlexIO_UART_TxBusy; + } + + if (txSize == 0U) + { + return kStatus_FlexIO_UART_NoDataToDeal; + } + /* Initialize the module driver state structure. */ + uartState->txBuff = txBuff; + uartState->txSize = txSize; + uartState->isTxBusy = true; + /* Make sure the transmit data register is empty and ready for data */ + while(!FLEXIO_UART_Tx_HAL_GetTxBufferEmptyFlag(&(uartState->txDev))) { } + + /* Put the first data in shifter to start the transmission */ + FLEXIO_UART_Tx_HAL_PutData(&(uartState->txDev), *(uartState->txBuff)); + /* Enable interrupt generation for tx shifter. */ + FLEXIO_UART_Tx_HAL_SetTxBufferEmptyIntCmd(&(uartState->txDev), true); + + return kStatus_FlexIO_UART_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_StartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static flexio_uart_status_t FLEXIO_UART_DRV_StartReceiveData(flexio_uart_state_t *uartState, + uint8_t * rxBuff, + uint32_t rxSize) +{ + if(uartState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + /* Check that we're not busy receiving data from a previous function call. */ + if ((uartState->isRxBusy) && (!uartState->rxCallback)) + { + return kStatus_FlexIO_UART_RxBusy; + } + + if (rxSize == 0U) + { + return kStatus_FlexIO_UART_NoDataToDeal; + } + + /* Initialize the module driver state struct to indicate transfer in progress + * and with the buffer and byte count data */ + uartState->rxBuff = rxBuff; + uartState->rxSize = rxSize; + uartState->isRxBusy = true; + + /* Enable the receive data full interrupt */ + FLEXIO_UART_Rx_HAL_SetRxBufferFullIntCmd(&(uartState->rxDev), true); + + return kStatus_FlexIO_UART_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_CompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXIO_UART_DRV_CompleteSendData(flexio_uart_state_t *uartState) +{ + if(uartState == NULL) + { + return; + } + + /* Disable the transmitter data register empty interrupt */ + FLEXIO_UART_Tx_HAL_SetTxBufferEmptyIntCmd(&(uartState->txDev), false); + + /* Signal the synchronous completion object. */ + if (uartState->isTxBlocking) + { + OSA_SemaPost(&uartState->txIrqSync); + } + + /* Update the information of the module driver state */ + uartState->isTxBusy = false; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_CompleteReceiveData + * Description : Finish up a receive by completing the process of receiving + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXIO_UART_DRV_CompleteReceiveData(flexio_uart_state_t *uartState) +{ + if(uartState == NULL) + { + return; + } + + /* Disable receive data full interrupt */ + FLEXIO_UART_Rx_HAL_SetRxBufferFullIntCmd(&(uartState->rxDev), false); + + /* Signal the synchronous completion object. */ + if (uartState->isRxBlocking) + { + OSA_SemaPost(&uartState->rxIrqSync); + } + + /* Update the information of the module driver state */ + uartState->isRxBusy = false; +} +#endif diff --git a/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_uart_edma_driver.c b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_uart_edma_driver.c new file mode 100755 index 0000000..16d5e44 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/flexio/fsl_flexio_uart_edma_driver.c @@ -0,0 +1,578 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 <string.h> +#include "fsl_flexio_uart_edma_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#include "fsl_edma_request.h" +#if FSL_FEATURE_SOC_DMA_COUNT + +static void FLEXIO_UART_DRV_EdmaCompleteSendData(flexio_uart_edmastate_t *uartEdmaState); +static void FLEXIO_UART_DRV_EdmaTxCallback(void *param, edma_chn_status_t status); +static flexio_uart_status_t FLEXIO_UART_DRV_EdmaStartSendData(flexio_uart_edmastate_t *uartEdmaState, + const uint8_t * txBuff, + uint32_t txSize); +static void FLEXIO_UART_DRV_EdmaCompleteReceiveData(flexio_uart_edmastate_t *uartEdmaState); +static void FLEXIO_UART_DRV_EdmaRxCallback(void *param, edma_chn_status_t status); +static flexio_uart_status_t FLEXIO_UART_DRV_EdmaStartReceiveData(flexio_uart_edmastate_t *uartEdmaState, + uint8_t * rxBuff, + uint32_t rxSize); +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_Init + * Description : This function initializes a UART instance for operation. + * This function will initialize the run-time state structure to keep track of + * the on-going transfers, ungate the clock to the UART module, initialize the + * module to user defined settings and default settings, configure the IRQ state + * structure and enable the module-level interrupt to the core, and enable the + * UART module transmitter and receiver. + * The following is an example of how to set up the uart_state_t and the + * uart_user_config_t parameters and how to call the UART_DRV_Init function by + * passing in these parameters: + * flexio_uart_user_config_t uartEdmaConfig; + * uartEdmaConfig.baudRate = 9600; + * uartEdmaConfig.bitCountPerChar = kUart8BitsPerChar; + * uart_state_t uartEdmaState; + * UART_DRV_Init(instance, &uartEdmaState, &uartEdmaConfig); + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaInit(instance,flexio_uart_edmastate_t *uartEdmaState, flexio_uartedma_userconfig_t *uartEdmaConfig) +{ + if(!(instance<HW_FlexIO_INSTANCE_COUNT)||(uartEdmaState == NULL)||(uartEdmaConfig == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + FLEXIO_Type* base = g_flexioBase[instance]; + uint32_t flexioSourceClock; + flexio_uart_dev_config_t devConfig; + dma_request_source_t uartTxEdmaRequest = kDmaRequestMux0Disable; + dma_request_source_t uartRxEdmaRequest = kDmaRequestMux0Disable; + + /*Reset the uartEdmaState structure*/ + memset(uartEdmaState,0,sizeof(*uartEdmaState)); + /* Create Semaphore for txIrq and rxIrq. */ + OSA_SemaCreate(&uartEdmaState->txIrqSync, 0); + OSA_SemaCreate(&uartEdmaState->rxIrqSync, 0); + /* Get FlexIO clock frequency for baudrate caculation*/ + flexioSourceClock = CLOCK_SYS_GetFlexioFreq(instance); + uartEdmaState->mode = uartEdmaConfig->uartMode; + devConfig.flexioBusClk = flexioSourceClock; + devConfig.baudrate = uartEdmaConfig->baudRate; + devConfig.bitCount = uartEdmaConfig->bitCounter; + /*Configure buadrate, bit count and hardware resource including pin, shifter and timer for Tx module*/ + if((uartEdmaConfig->uartMode == flexioUART_TxOnly)||(uartEdmaConfig->uartMode == flexioUART_TxRx)) + { + uartEdmaState->txDev.flexioBaseAddr = base; + uartEdmaState->txDev.txPinIdx = uartEdmaConfig->txConfig.pinIdx; + uartEdmaState->txDev.shifterIdx = uartEdmaConfig->txConfig.shifterIdx; + uartEdmaState->txDev.timerIdx = uartEdmaConfig->txConfig.timerIdx; + FLEXIO_UART_Tx_HAL_Configure(&(uartEdmaState->txDev), &devConfig); + } + /*Configure buadrate, bit count and hardware resource including pin, shifter and timer for Rx module*/ + if((uartEdmaConfig->uartMode == flexioUART_RxOnly)||(uartEdmaConfig->uartMode == flexioUART_TxRx)) + { + uartEdmaState->rxDev.flexioBaseAddr = base; + uartEdmaState->rxDev.rxPinIdx = uartEdmaConfig->rxConfig.pinIdx; + uartEdmaState->rxDev.shifterIdx = uartEdmaConfig->rxConfig.shifterIdx; + uartEdmaState->rxDev.timerIdx = uartEdmaConfig->rxConfig.timerIdx; + FLEXIO_UART_Rx_HAL_Configure(&(uartEdmaState->rxDev), &devConfig); + } + switch (instance) + { + case 0: + uartRxEdmaRequest = kDmaRequestMux0FLEXIOShifter0 + rxConfig.shifterIdx; + uartTxEdmaRequest = kDmaRequestMux0FLEXIOShifter0 + txConfig.shifterIdx; + break; + default : + break; + } + /*--------------- Setup RX ------------------*/ + /* Request DMA channels for RX FIFO. */ + EDMA_DRV_RequestChannel(kEDMAAnyChannel, uartRxEdmaRequest, + &uartEdmaState->edmaUartRx); + EDMA_DRV_InstallCallback(&uartEdmaState->edmaUartRx, + FLEXIO_UART_DRV_EdmaRxCallback, (void *)uartEdmaState); + + /*--------------- Setup TX ------------------*/ + /* Request DMA channels for TX FIFO. */ + EDMA_DRV_RequestChannel(kEDMAAnyChannel, uartTxEdmaRequest, + &uartEdmaState->edmaUartTx); + EDMA_DRV_InstallCallback(&uartEdmaState->edmaUartTx, + FLEXIO_UART_DRV_EdmaTxCallback, (void *)uartEdmaState); + /* Finally, enable the UART transmitter and receiver. + * Enable DMA trigger when transmit data register empty, + * and receive data register full. */ + FLEXIO_UART_Rx_HAL_SetTxDmaIntCmd(&(uartEdmaState->txDev), true); + FLEXIO_UART_Rx_HAL_SetRxDmaIntCmd(&(uartEdmaState->rxDev), true); + return kstatus_FlexIO_UART_Success; +} +void FLEXIO_UART_DRV_Deinit(flexio_uart_edmastate_t *uartEdmaState) +{ + if(uartEdmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + FLEXIO_UART_Rx_HAL_SetTxDmaIntCmd(&(uartEdmaState->txDev), false); + FLEXIO_UART_Rx_HAL_SetRxDmaIntCmd(&(uartEdmaState->rxDev), false); + /* Release DMA channel. */ + EDMA_DRV_ReleaseChannel(&uartEdmaState->edmaUartRx); + EDMA_DRV_ReleaseChannel(&uartEdmaState->edmaUartTx); + /* Destroy TX and RX sema. */ + OSA_SemaDestroy(&uartEdmaState->txIrqSync); + OSA_SemaDestroy(&uartEdmaState->rxIrqSync); +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaSendDataBlocking + * Description : Sends (transmits) data out through the UART-DMA module + * using a blocking method. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaSendDataBlocking(flexio_uart_edmastate_t *uartEdmaState, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + if((uartEdmaState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kstatus_FlexIO_UART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + uartEdmaState->isTxBlocking = true; + + /* Start the transmission process */ + retVal = FLEXIO_UART_DRV_EdmaStartSendData(uartEdmaState, txBuff, txSize); + + if (retVal == kStatus_FlexIO_UART_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&uartEdmaState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + + /* Stop DMA channel. */ + EDMA_DRV_StopChannel(&uartEdmaState->edmaUartTx); + + /* Update the information of the module driver state */ + uartEdmaState->isTxBusy = false; + + retVal = kstatus_FlexIO_UART_Timeout; + } + } + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaSendData + * Description : This function sends (transmits) data through the UART module + * using a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the transmit function. The application + * has to get the transmit status to see when the transmit is complete. In + * other words, after calling non-blocking (asynchronous) send function, the + * application must get the transmit status to check if transmit is completed + * or not. The asynchronous method of transmitting and receiving allows the UART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaSendData(flexio_uart_edmastate_t *uartEdmaState, + const uint8_t * txBuff, + uint32_t txSize) +{ + if((uartEdmaState == NULL)||(txBuff == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + + /* Indicates current transaction is non-blocking. */ + uartEdmaState->isTxBlocking = false; + + /* Start the transmission process*/ + retVal = FLEXIO_UART_DRV_EdmaStartSendData(uartEdmaState, txBuff, txSize); + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaGetTransmitStatus + * Description : This function returns whether the previous UART transmit + * has finished. When performing an async transmit, the user can call this + * function to ascertain the state of the current transmission: in progress + * (or busy) or complete (success). In addition, if the transmission is still + * in progress, the user can obtain the number of words that have been + * currently transferred. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaGetTransmitStatus(flexio_uart_edmastate_t *uartEdmaState, + uint32_t * bytesRemaining) +{ + if(uartEdmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + uint32_t txSize = EDMA_DRV_GetUnFinishedBytes(&uartEdmaState->edmaUartTx); + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = txSize; + } + + if (txSize) + { + retVal = kStatus_FlexIO_UART_TxBusy; + } + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaAbortSendingData + * Description : This function terminates an asynchronous UART transmission + * early. During an async UART transmission, the user has the option to + * terminate the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaAbortSendingData(flexio_uart_edmastate_t *uartEdmaState) +{ + if(uartEdmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!uartEdmaState->isTxBusy) + { + return kStatus_FlexIO_UART_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + FLEXIO_UART_DRV_EdmaCompleteSendData(uartEdmaState); + + return kStatus_FlexIO_UART_Success; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaReceiveDataBlocking + * Description : This function gets (receives) data from the UART module using + * a blocking method. A blocking (also known as synchronous) function means that + * the function does not return until the receive is complete. This blocking + * function is used to send data through the UART port. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaReceiveDataBlocking(flexio_uart_edmastate_t *uartEdmaState, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout) +{ + if((uartEdmaState == NULL)||(rxBuff == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + uartEdmaState->isRxBlocking = true; + + retVal = FLEXIO_UART_DRV_EdmaStartReceiveData(uartEdmaState, rxBuff, rxSize); + + if (retVal == kStatus_FlexIO_UART_Success) + { + /* Wait until all the data is received or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&uartEdmaState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + EDMA_DRV_StopChannel(&uartEdmaState->edmaUartRx); + + /* Update the information of the module driver state */ + uartEdmaState->isRxBusy = false; + + retVal = kStatus_FlexIO_UART_Timeout; + } + } + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaReceiveData + * Description : This function gets (receives) data from the UART module using + * a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. In other + * words, after calling non-blocking (asynchronous) get function, the + * application must get the receive status to check if receive is completed or + * not. The asynchronous method of transmitting and receiving allows the UART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaReceiveData(flexio_uart_edmastate_t *uartEdmaState, + uint8_t * rxBuff, + uint32_t rxSize) +{ + if((uartEdmaState == NULL)||(rxBuff == NULL)) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + + /* Indicates current transaction is non-blocking. */ + uartEdmaState->isRxBlocking = false; + + retVal = FLEXIO_UART_DRV_EdmaStartReceiveData(uartEdmaState, rxBuff, rxSize); + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaGetReceiveStatus + * Description : This function returns whether the previous UART receive is + * complete. When performing an async receive, the user can call this function + * to ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, + * the user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaGetReceiveStatus(flexio_uart_edmastate_t *uartEdmaState, + uint32_t * bytesRemaining) +{ + if(uartEdmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + flexio_uart_status_t retVal = kStatus_FlexIO_UART_Success; + uint32_t rxSize = EDMA_DRV_GetUnFinishedBytes(&uartEdmaState->edmaUartRx); + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = rxSize; + } + + if (rxSize) + { + retVal = kStatus_FlexIO_UART_RxBusy; + } + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaAbortReceivingData + * Description : This function shuts down the UART by disabling interrupts and + * the transmitter/receiver. + * + *END**************************************************************************/ +flexio_uart_status_t FLEXIO_UART_DRV_EdmaAbortReceivingData(flexio_uart_edmastate_t *uartEdmaState) +{ + if(uartEdmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + /* Check if a transfer is running. */ + if (!uartEdmaState->isRxBusy) + { + return kStatus_FlexIO_UART_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + FLEXIO_UART_DRV_EdmaCompleteReceiveData(uartEdmaState); + + return kStatus_FlexIO_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaCompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXIO_UART_DRV_EdmaCompleteSendData(flexio_uart_edmastate_t *uartEdmaState) +{ + if(uartEdmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + /* Stop DMA channel. */ + EDMA_DRV_StopChannel(&uartEdmaState->edmaUartTx); + /* Signal the synchronous completion object. */ + if (uartEdmaState->isTxBlocking) + { + OSA_SemaPost(&uartEdmaState->txIrqSync); + } + + /* Update the information of the module driver state */ + uartEdmaState->isTxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaTxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void FLEXIO_UART_DRV_EdmaTxCallback(void *param, edma_chn_status_t status) +{ + FLEXIO_UART_DRV_EdmaCompleteSendData((flexio_uart_edmastate_t *)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaStartSendData + * Description : This is not a public interface. + * + *END**************************************************************************/ +static flexio_uart_status_t FLEXIO_UART_DRV_EdmaStartSendData(flexio_uart_edmastate_t *uartEdmaState, + const uint8_t * txBuff, + uint32_t txSize) +{ + if(uartEdmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + /* Check that we're not busy already transmitting data from a previous function call. */ + if (uartEdmaState->isTxBusy) + { + return kStatus_UART_TxBusy; + } + + /* Update UART DMA run-time structure. */ + uartEdmaState->isTxBusy = true; + + /* Update txBuff and txSize. */ + uint32_t destAddr = FLEXIO_UART_Tx_HAL_GetTxBufferAddr(&(uartEdmaState->txDev)); + EDMA_DRV_ConfigLoopTransfer(&uartEdmaState->edmaUartTx, &uartEdmaState->edmaTxTcd, + kEDMAMemoryToPeripheral, (uint32_t)(txBuff), destAddr, 1, 1, txSize, 1); + /* Start DMA channel */ + EDMA_DRV_StartChannel(&uartEdmaState->edmaUartTx); + + return kStatus_FlexIO_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaCompleteReceiveData + * Description : Finish up a receive by completing the process of receiving data + * and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void FLEXIO_UART_DRV_EdmaCompleteReceiveData(flexio_uart_edmastate_t *uartEdmaState) +{ + if(uartEdmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + /* Stop DMA channel. */ + EDMA_DRV_StopChannel(&uartEdmaState->edmaUartRx); + + /* Signal the synchronous completion object. */ + if (uartEdmaState->isRxBlocking) + { + OSA_SemaPost(&uartEdmaState->rxIrqSync); + } + + /* Update the information of the module driver state */ + uartEdmaState->isRxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaRxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void FLEXIO_UART_DRV_EdmaRxCallback(void *param, edma_chn_status_t status) +{ + FLEXIO_UART_DRV_EdmaCompleteReceiveData((flexio_uart_edmastate_t *)param); +} +/*FUNCTION********************************************************************** + * + * Function Name : FLEXIO_UART_DRV_EdmaStartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static flexio_uart_status_t FLEXIO_UART_DRV_EdmaStartReceiveData(flexio_uart_edmastate_t *uartEdmaState, + uint8_t * rxBuff, + uint32_t rxSize) +{ + if(uartEdmaState == NULL) + { + return kStatus_FlexIO_UART_InvalidParam; + } + + /* Check that we're not busy already receiving data from a previous function call. */ + if (uartEdmaState->isRxBusy) + { + return kStatus_FlexIO_UART_RxBusy; + } + + /* Update UART DMA run-time structure. */ + uartEdmaState->isRxBusy = true; + + /* Update rxBuff and rxSize */ + uint32_t srcAddr = FLEXIO_UART_Rx_HAL_GetRxBufferAddr(&(uartEdmaState->rxDev)); + EDMA_DRV_ConfigLoopTransfer(&uartEdmaState->edmaUartTx, &uartEdmaState->edmaTxTcd, + kEDMAPeripheralToMemory, srcAddr, (uint32_t)rxBuff, 1, 1, rxSize, 1); + EDMA_DRV_StartChannel(&uartEdmaState->edmaUartRx); + + return kStatus_FlexIO_UART_Success; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/ftm/fsl_ftm_common.c b/KSDK_1.2.0/platform/drivers/src/ftm/fsl_ftm_common.c new file mode 100755 index 0000000..193f620 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/ftm/fsl_ftm_common.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_FTM_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for FTM instances. */ +FTM_Type * const g_ftmBase[FTM_INSTANCE_COUNT] = FTM_BASE_PTRS; + +/* Table to save FTM IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_ftmIrqId[FTM_INSTANCE_COUNT] = FTM_IRQS; + +#endif /* FSL_FEATURE_SOC_FTM_COUNT */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/ftm/fsl_ftm_driver.c b/KSDK_1.2.0/platform/drivers/src/ftm/fsl_ftm_driver.c new file mode 100755 index 0000000..5d262eb --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/ftm/fsl_ftm_driver.c @@ -0,0 +1,585 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_ftm_driver.h" +#include "fsl_clock_manager.h" + +#if FSL_FEATURE_SOC_FTM_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of number of channels for each FTM instance */ +const int32_t g_ftmChannelCount[FTM_INSTANCE_COUNT] = FSL_FEATURE_FTM_CHANNEL_COUNTx; +/*! Stores FTM clock source setting */ +static ftm_clock_source_t s_ftmClockSource = kClock_source_FTM_None; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_Init + * Description : Initializes the FTM driver. + * + *END**************************************************************************/ +ftm_status_t FTM_DRV_Init(uint32_t instance, const ftm_user_config_t * info) +{ + assert(instance < FTM_INSTANCE_COUNT); + assert(g_ftmBase[instance] != NULL); + + FTM_Type *ftmBase = g_ftmBase[instance]; + uint8_t chan = g_ftmChannelCount[instance]; + + /* clock setting initialization*/ + CLOCK_SYS_EnableFtmClock(instance); + + FTM_HAL_Reset(ftmBase); + /* Reset the channel registers */ + for(int i = 0; i < chan; i++) + { + FTM_WR_CnSC(ftmBase, i, 0); + FTM_WR_CnV(ftmBase, i, 0); + } + + FTM_HAL_Init(ftmBase); + + FTM_HAL_SetSyncMode(ftmBase, info->syncMethod); + + FTM_HAL_SetTofFreq(ftmBase, info->tofFrequency); + FTM_HAL_SetWriteProtectionCmd(ftmBase, info->isWriteProtection); + FTM_HAL_SetBdmMode(ftmBase,info->BDMMode); + + NVIC_ClearPendingIRQ(g_ftmIrqId[instance]); + INT_SYS_EnableIRQ(g_ftmIrqId[instance]); + + return kStatusFtmSuccess; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_Deinit + * Description : Shuts down the FTM driver. + * + *END**************************************************************************/ +void FTM_DRV_Deinit(uint32_t instance) +{ + assert(instance < FTM_INSTANCE_COUNT); + + /* disable clock for FTM.*/ + CLOCK_SYS_DisableFtmClock(instance); + + INT_SYS_DisableIRQ(g_ftmIrqId[instance]); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_SetFaultIntCmd + * Description : Enables or disables the fault interrupt. + * + *END**************************************************************************/ +void FTM_DRV_SetFaultIntCmd(uint32_t instance, bool faultEnable) +{ + if (faultEnable) + { + FTM_HAL_EnableFaultInt(g_ftmBase[instance]); + } + else + { + FTM_HAL_DisableFaultInt(g_ftmBase[instance]); + } + +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_SetTimeOverflowIntCmd + * Description : Enables or disables the timer overflow interrupt. + * + *END**************************************************************************/ +void FTM_DRV_SetTimeOverflowIntCmd(uint32_t instance, bool overflowEnable) +{ + if (overflowEnable) + { + FTM_HAL_EnableTimerOverflowInt(g_ftmBase[instance]); + } + else + { + FTM_HAL_DisableTimerOverflowInt(g_ftmBase[instance]); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_QuadDecodeStart + * Description : Configures the parameters needed and activates quadrature + * decode mode. + * + *END**************************************************************************/ +void FTM_DRV_QuadDecodeStart(uint32_t instance, ftm_phase_params_t *phaseAParams, + ftm_phase_params_t *phaseBParams, ftm_quad_decode_mode_t quadMode) +{ + assert(instance < FTM_INSTANCE_COUNT); + assert(phaseAParams); + assert(phaseBParams); + + FTM_Type *ftmBase = g_ftmBase[instance]; + + FTM_HAL_SetQuadMode(ftmBase, quadMode); + FTM_HAL_SetQuadPhaseAFilterCmd(ftmBase, phaseAParams->kFtmPhaseInputFilter); + if (phaseAParams->kFtmPhaseInputFilter) + { + /* Set Phase A filter value if phase filter is enabled */ + FTM_HAL_SetChnInputCaptureFilter(ftmBase, CHAN0_IDX, phaseAParams->kFtmPhaseFilterVal); + } + FTM_HAL_SetQuadPhaseBFilterCmd(ftmBase, phaseBParams->kFtmPhaseInputFilter); + if (phaseBParams->kFtmPhaseInputFilter) + { + /* Set Phase B filter value if phase filter is enabled */ + FTM_HAL_SetChnInputCaptureFilter(ftmBase, CHAN1_IDX, phaseBParams->kFtmPhaseFilterVal); + } + FTM_HAL_SetQuadPhaseAPolarity(ftmBase, phaseAParams->kFtmPhasePolarity); + FTM_HAL_SetQuadPhaseBPolarity(ftmBase, phaseBParams->kFtmPhasePolarity); + + FTM_HAL_SetQuadDecoderCmd(ftmBase, true); + + /* Set clock source to start the counter */ + FTM_HAL_SetClockSource(ftmBase, s_ftmClockSource); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_QuadDecodeStop + * Description : De-activates quadrature decode mode. + * This function will initialize the Real Time Clock module. + * + *END**************************************************************************/ +void FTM_DRV_QuadDecodeStop(uint32_t instance) +{ + /* Stop the FTM counter */ + FTM_HAL_SetClockSource(g_ftmBase[instance], kClock_source_FTM_None); + + FTM_HAL_SetQuadDecoderCmd(g_ftmBase[instance], false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_CounterStart + * Description : Starts the FTM counter. This function provides access to the + * FTM counter. The counter can be run in Up-counting and Up-down counting modes. + * To run the counter in Free running mode, choose Up-counting option and provide + * 0x0 for the countStartVal and 0xFFFF for countFinalVal. + * + *END**************************************************************************/ +void FTM_DRV_CounterStart(uint32_t instance, ftm_counting_mode_t countMode, uint32_t countStartVal, + uint32_t countFinalVal, bool enableOverflowInt) +{ + assert(instance < FTM_INSTANCE_COUNT); + + FTM_Type *ftmBase = g_ftmBase[instance]; + uint32_t channel = 0; + + /* Clear the overflow flag */ + FTM_HAL_ClearTimerOverflow(ftmBase); + FTM_HAL_SetCounterInitVal(ftmBase, countStartVal); + FTM_HAL_SetMod(ftmBase, countFinalVal); + FTM_HAL_SetCounter(ftmBase, 0); + + /* Use FTM as counter, disable all the channels */ + for (channel = 0; channel < g_ftmChannelCount[instance]; channel++) + { + FTM_HAL_SetChnEdgeLevel(ftmBase, channel, 0); + } + + if (countMode == kCounting_FTM_UP) + { + FTM_HAL_SetQuadDecoderCmd(ftmBase, false); + FTM_HAL_SetCpwms(ftmBase, 0); + } + else if (countMode == kCounting_FTM_UpDown) + { + FTM_HAL_SetQuadDecoderCmd(ftmBase, false); + FTM_HAL_SetCpwms(ftmBase, 1); + } + + /* Activate interrupts if required */ + FTM_DRV_SetTimeOverflowIntCmd(instance, enableOverflowInt); + + /* Set clock source to start the counter */ + FTM_HAL_SetClockSource(ftmBase, s_ftmClockSource); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_CounterStop + * Description : Stops the FTM counter. + * + *END**************************************************************************/ +void FTM_DRV_CounterStop(uint32_t instance) +{ + /* Stop the FTM counter */ + FTM_HAL_SetClockSource(g_ftmBase[instance], kClock_source_FTM_None); + + FTM_HAL_SetCpwms(g_ftmBase[instance], 0); + + /* Disable the overflow interrupt */ + FTM_DRV_SetTimeOverflowIntCmd(instance, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_CounterRead + * Description : Reads back the current value of the FTM counter. + * + *END**************************************************************************/ +uint32_t FTM_DRV_CounterRead(uint32_t instance) +{ + assert(instance < FTM_INSTANCE_COUNT); + + return FTM_HAL_GetCounter(g_ftmBase[instance]); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_SetClock + * Description : Set FTM clock source. + * This function will save the users clock source selection in the driver and + * uses this to set the clock source whenever the user decides to use features provided + * by this driver like counter, PWM generation etc. It will also set the clock divider. + * + *END**************************************************************************/ +void FTM_DRV_SetClock(uint8_t instance, ftm_clock_source_t clock, ftm_clock_ps_t clockPs) +{ + assert(instance < FTM_INSTANCE_COUNT); + assert(clock != kClock_source_FTM_None); + + /*Clock prescaler*/ + FTM_HAL_SetClockPs(g_ftmBase[instance], clockPs); + s_ftmClockSource = clock; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_GetClock + * Description : Retrieves the frequency of the clock source feeding the FTM counter. + * Function will return a 0 if no clock source is selected and the FTM counter is disabled + * + *END**************************************************************************/ +uint32_t FTM_DRV_GetClock(uint8_t instance) +{ + assert(instance < FTM_INSTANCE_COUNT); + + FTM_Type *ftmBase = g_ftmBase[instance]; + uint8_t clkPs; + uint32_t freq = 0; + + clkPs = (1 << FTM_HAL_GetClockPs(ftmBase)); + + switch(s_ftmClockSource) + { + case kClock_source_FTM_ExternalClk: + freq = CLOCK_SYS_GetFtmExternalFreq(instance) / clkPs; + break; + case kClock_source_FTM_FixedClk: + freq = CLOCK_SYS_GetFtmFixedFreq(instance) / clkPs; + break; + case kClock_source_FTM_SystemClk: + freq = CLOCK_SYS_GetFtmSystemClockFreq(instance) / clkPs; + break; + default: + break; + } + + return freq; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_PwmStop + * Description : Stops channel PWM. + * + *END**************************************************************************/ +void FTM_DRV_PwmStop(uint32_t instance, ftm_pwm_param_t *param, uint8_t channel) +{ + assert((param->mode == kFtmEdgeAlignedPWM) || (param->mode == kFtmCenterAlignedPWM) || + (param->mode == kFtmCombinedPWM)); + assert(instance < FTM_INSTANCE_COUNT); + assert(channel < g_ftmChannelCount[instance]); + + FTM_Type *ftmBase = g_ftmBase[instance]; + + /* Stop the FTM counter */ + FTM_HAL_SetClockSource(ftmBase, kClock_source_FTM_None); + + FTM_HAL_DisablePwmMode(ftmBase, param, channel); + + /* Clear out the registers */ + FTM_HAL_SetMod(ftmBase, 0); + FTM_HAL_SetCounter(ftmBase, 0); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_PwmStart + * Description : Configures duty cycle and frequency and starts outputting + * PWM on specified channel . + * + *END**************************************************************************/ +ftm_status_t FTM_DRV_PwmStart(uint32_t instance, ftm_pwm_param_t *param, uint8_t channel) +{ + uint32_t uFTMhz; + uint16_t uMod, uCnv, uCnvFirstEdge = 0; + + assert(instance < FTM_INSTANCE_COUNT); + assert(param->uDutyCyclePercent <= 100); + assert(channel < g_ftmChannelCount[instance]); + + FTM_Type *ftmBase = g_ftmBase[instance]; + + /* Clear the overflow flag */ + FTM_HAL_ClearTimerOverflow(ftmBase); + + FTM_HAL_EnablePwmMode(ftmBase, param, channel); + + if (s_ftmClockSource == kClock_source_FTM_None) + { + return kStatusFtmError; + } + + uFTMhz = FTM_DRV_GetClock(instance); + + /* Based on Ref manual, in PWM mode CNTIN is to be set 0*/ + FTM_HAL_SetCounterInitVal(ftmBase, 0); + + switch(param->mode) + { + case kFtmEdgeAlignedPWM: + uMod = uFTMhz / (param->uFrequencyHZ) - 1; + uCnv = uMod * param->uDutyCyclePercent / 100; + /* For 100% duty cycle */ + if(uCnv >= uMod) + { + uCnv = uMod + 1; + } + FTM_HAL_SetMod(ftmBase, uMod); + FTM_HAL_SetChnCountVal(ftmBase, channel, uCnv); + break; + case kFtmCenterAlignedPWM: + uMod = uFTMhz / (param->uFrequencyHZ * 2); + uCnv = uMod * param->uDutyCyclePercent / 100; + /* For 100% duty cycle */ + if(uCnv >= uMod) + { + uCnv = uMod + 1; + } + FTM_HAL_SetMod(ftmBase, uMod); + FTM_HAL_SetChnCountVal(ftmBase, channel, uCnv); + break; + case kFtmCombinedPWM: + uMod = uFTMhz / (param->uFrequencyHZ) - 1; + uCnv = uMod * param->uDutyCyclePercent / 100; + uCnvFirstEdge = uMod * param->uFirstEdgeDelayPercent / 100; + /* For 100% duty cycle */ + if(uCnv >= uMod) + { + uCnv = uMod + 1; + } + FTM_HAL_SetMod(ftmBase, uMod); + FTM_HAL_SetChnCountVal(ftmBase, FTM_HAL_GetChnPairIndex(channel) * 2, + uCnvFirstEdge); + FTM_HAL_SetChnCountVal(ftmBase, FTM_HAL_GetChnPairIndex(channel) * 2 + 1, + uCnv + uCnvFirstEdge); + break; + default: + assert(0); + break; + } + + /* Set clock source to start counter */ + FTM_HAL_SetClockSource(ftmBase, s_ftmClockSource); + return kStatusFtmSuccess; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_SetupChnInputCapture + * Description : Enables capture of an input signal on the channel using the + * paramters specified to this function. When the edge specified in the captureMode + * argument occurs on the channel the FTM counter is captured into the CnV register. + * The user will have to read the CnV register separately to get this value. The filter + * function is disabled if the filterVal argument passed in is 0. The filter function + * is available only on channels 0,1,2,3. + * + *END**************************************************************************/ +void FTM_DRV_SetupChnInputCapture(uint32_t instance, ftm_input_capture_edge_mode_t captureMode, + uint8_t channel, uint8_t filterVal) +{ + assert(instance < FTM_INSTANCE_COUNT); + assert(channel < g_ftmChannelCount[instance]); + + FTM_Type *ftmBase = g_ftmBase[instance]; + uint32_t chnlPairnum = FTM_HAL_GetChnPairIndex(channel); + + FTM_HAL_SetClockSource(ftmBase, kClock_source_FTM_None); + + FTM_HAL_SetCounterInitVal(ftmBase, 0); + FTM_HAL_SetMod(ftmBase, 0xFFFF); + FTM_HAL_SetCpwms(ftmBase, 0); + FTM_HAL_SetDualChnCombineCmd(ftmBase, chnlPairnum, false); + FTM_HAL_SetDualEdgeCaptureCmd(ftmBase, chnlPairnum, false); + FTM_HAL_SetChnEdgeLevel(ftmBase, channel, captureMode); + + if (channel < CHAN4_IDX) + { + FTM_HAL_SetChnInputCaptureFilter(ftmBase, channel, filterVal); + } + + FTM_HAL_SetChnMSnBAMode(ftmBase, channel, 0); + + /* Set clock source to start the counter */ + FTM_HAL_SetClockSource(ftmBase, s_ftmClockSource); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_SetupChnOutputCompare + * Description : Configures the FTM to generate timed pulses + * When the FTM counter matches the value of compareVal argument (this is + * written into CnV reg), the channel output is changed based on what is specified + * in the compareMode argument. + * + *END**************************************************************************/ +void FTM_DRV_SetupChnOutputCompare(uint32_t instance, ftm_output_compare_edge_mode_t compareMode, + uint8_t channel, uint32_t compareVal) +{ + assert(instance < FTM_INSTANCE_COUNT); + assert(channel < g_ftmChannelCount[instance]); + + FTM_Type *ftmBase = g_ftmBase[instance]; + uint32_t chnlPairnum = FTM_HAL_GetChnPairIndex(channel); + + FTM_HAL_SetClockSource(ftmBase, kClock_source_FTM_None); + + FTM_HAL_SetCounterInitVal(ftmBase, 0); + FTM_HAL_SetMod(ftmBase, 0xFFFF); + FTM_HAL_SetCpwms(ftmBase, 0); + FTM_HAL_SetDualChnCombineCmd(ftmBase, chnlPairnum, false); + FTM_HAL_SetDualEdgeCaptureCmd(ftmBase, chnlPairnum, false); + FTM_HAL_SetChnEdgeLevel(ftmBase, channel, compareMode); + FTM_HAL_SetChnMSnBAMode(ftmBase, channel, 1); + FTM_HAL_SetChnCountVal(ftmBase, channel, compareVal); + + /* Set clock source to start the counter */ + FTM_HAL_SetClockSource(ftmBase, s_ftmClockSource); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_SetupChnDualEdgeCapture + * Description : Configures the Dual Edge Capture mode of the FTM + * This function sets up the dual edge capture mode on a channel pair. + * The capture edge for the channel pair and the capture mode (one-shot or continuous) + * is specified in the param argument. The filter function is disabled if the + * filterVal argument passed in is 0. The filter function is available only on + * channels 0 and 2. The user will have to read the channel CnV registers separately + * to get the capture values. + * + *END**************************************************************************/ +void FTM_DRV_SetupChnDualEdgeCapture(uint32_t instance, ftm_dual_edge_capture_param_t *param, + uint8_t channel, uint8_t filterVal) +{ + assert(instance < FTM_INSTANCE_COUNT); + assert(channel < g_ftmChannelCount[instance]); + + FTM_Type *ftmBase = g_ftmBase[instance]; + uint32_t chnlPairnum = FTM_HAL_GetChnPairIndex(channel); + + /* Stop the counter */ + FTM_HAL_SetClockSource(ftmBase, kClock_source_FTM_None); + + FTM_HAL_SetCounterInitVal(ftmBase, 0); + FTM_HAL_SetMod(ftmBase, 0xFFFF); + FTM_HAL_SetCpwms(ftmBase, 0); + FTM_HAL_SetDualChnCombineCmd(ftmBase, chnlPairnum, false); + /* Enable the DECAPEN bit */ + FTM_HAL_SetDualEdgeCaptureCmd(ftmBase, chnlPairnum, true); + /* Setup the edge detection from channel n and n + 1 */ + FTM_HAL_SetChnEdgeLevel(ftmBase, chnlPairnum * 2, param->currChanEdgeMode); + FTM_HAL_SetChnEdgeLevel(ftmBase, (chnlPairnum * 2) + 1, param->nextChanEdgeMode); + + FTM_HAL_ClearChnEventFlag(ftmBase, channel); + FTM_HAL_ClearChnEventFlag(ftmBase, channel + 1); + FTM_HAL_SetDualChnDecapCmd(ftmBase, chnlPairnum, true); + FTM_HAL_SetChnMSnBAMode(ftmBase, chnlPairnum * 2, param->mode); + + if (channel < CHAN4_IDX) + { + FTM_HAL_SetChnInputCaptureFilter(ftmBase, channel, filterVal); + } + + /* Set clock source to start the counter */ + FTM_HAL_SetClockSource(ftmBase, s_ftmClockSource); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FTM_DRV_IRQHandler + * Description : Initializes the Real Time Clock module + * This function will initialize the Real Time Clock module. + * + *END**************************************************************************/ +void FTM_DRV_IRQHandler(uint32_t instance) +{ + FTM_Type *ftmBase = g_ftmBase[instance]; + uint16_t channel; + + /* Clear the Status flag if the interrupt is enabled */ + if (FTM_HAL_IsOverflowIntEnabled(ftmBase)) + { + FTM_HAL_ClearTimerOverflow(ftmBase); + } + + for (channel = 0; channel < g_ftmChannelCount[instance]; channel++) + { + if (FTM_HAL_IsChnIntEnabled(ftmBase, channel)) + { + FTM_HAL_ClearChnEventStatus(ftmBase, channel); + } + } +} + +#endif /* FSL_FEATURE_SOC_FTM_COUNT */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/ftm/fsl_ftm_irq.c b/KSDK_1.2.0/platform/drivers/src/ftm/fsl_ftm_irq.c new file mode 100755 index 0000000..495d7da --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/ftm/fsl_ftm_irq.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_ftm_driver.h" + + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if (FTM_INSTANCE_COUNT > 0) +/*! + * @brief Implementation of FTM0 handler named in startup code. + * + * Passes instance to generic FTM IRQ handler. + */ +void FTM0_IRQHandler(void) +{ + FTM_DRV_IRQHandler(0U); +} +#endif + +#if (FTM_INSTANCE_COUNT > 1) +/*! + * @brief Implementation of FTM1 handler named in startup code. + * + * Passes instance to generic FTM IRQ handler. + */ +void FTM1_IRQHandler(void) +{ + FTM_DRV_IRQHandler(1U); +} +#endif + +#if (FTM_INSTANCE_COUNT > 2) +/*! + * @brief Implementation of FTM2 handler named in startup code. + * + * Passes instance to generic FTM IRQ handler. + */ +void FTM2_IRQHandler(void) +{ + FTM_DRV_IRQHandler(2U); +} +#endif + +#if (FTM_INSTANCE_COUNT > 3) +/*! + * @brief Implementation of FTM3 handler named in startup code. + * + * Passes instance to generic FTM IRQ handler. + */ +void FTM3_IRQHandler(void) +{ + FTM_DRV_IRQHandler(3U); +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/ftm/fsl_ftm_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/ftm/fsl_ftm_lpm_callback.c new file mode 100755 index 0000000..e7b400e --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/ftm/fsl_ftm_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t ftm_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t ftm_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/gpio/fsl_gpio_common.c b/KSDK_1.2.0/platform/drivers/src/gpio/fsl_gpio_common.c new file mode 100755 index 0000000..08ff70d --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/gpio/fsl_gpio_common.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_GPIO_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for GPIO instances. */ +GPIO_Type * const g_gpioBase[GPIO_INSTANCE_COUNT] = GPIO_BASE_PTRS; + +#if defined(FGPIO_INSTANCE_COUNT) +/* Table of base addresses for FGPIO instances. */ +FGPIO_Type * const g_fgpioBase[FGPIO_INSTANCE_COUNT ] = FGPIO_BASE_PTRS; +#endif + +/* Table of base addresses for PORT instances. */ +PORT_Type * const g_portBase[PORT_INSTANCE_COUNT] = PORT_BASE_PTRS; + +/* Table to save port IRQ enum numbers defined in CMSIS files. */ +const IRQn_Type g_portIrqId[PORT_INSTANCE_COUNT] = PORT_IRQS; + +#endif /* FSL_FEATURE_SOC_GPIO_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/gpio/fsl_gpio_driver.c b/KSDK_1.2.0/platform/drivers/src/gpio/fsl_gpio_driver.c new file mode 100755 index 0000000..55f471e --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/gpio/fsl_gpio_driver.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_gpio_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_GPIO_COUNT + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_Init + * Description : Initialize all GPIO pins used by board. + * To initialize the GPIO driver, two arrays similar with + * gpio_input_pin_user_config_t inputPin[] and + * gpio_output_pin_user_config_t outputPin[] should be defined in user's file. + * Then simply call GPIO_DRV_Init() and pass into these two arrays. If input + * or output pins is not needed, pass in a NULL. + * + *END**************************************************************************/ +void GPIO_DRV_Init(const gpio_input_pin_user_config_t * inputPins, + const gpio_output_pin_user_config_t * outputPins) +{ + if (inputPins) + { + /* Initialize input pins.*/ + while (inputPins->pinName != GPIO_PINS_OUT_OF_RANGE) + { + GPIO_DRV_InputPinInit(inputPins++); + } + } + + if (outputPins) + { + /* Initialize output pins.*/ + while (outputPins->pinName != GPIO_PINS_OUT_OF_RANGE) + { + GPIO_DRV_OutputPinInit(outputPins++); + } + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_InputPinInit + * Description : Initialize one GPIO input pin used by board. + * + *END**************************************************************************/ +void GPIO_DRV_InputPinInit(const gpio_input_pin_user_config_t *inputPin) +{ + /* Get actual port and pin number.*/ + uint32_t port = GPIO_EXTRACT_PORT(inputPin->pinName); + uint32_t pin = GPIO_EXTRACT_PIN(inputPin->pinName); + GPIO_Type * gpioBase = g_gpioBase[port]; + PORT_Type * portBase = g_portBase[port]; + + /* Un-gate port clock*/ + CLOCK_SYS_EnablePortClock(port); + + /* Set current pin as gpio.*/ + PORT_HAL_SetMuxMode(portBase, pin, kPortMuxAsGpio); + + /* Set current pin as digital input.*/ + GPIO_HAL_SetPinDir(gpioBase, pin, kGpioDigitalInput); + + /* Configure GPIO input features. */ + #if FSL_FEATURE_PORT_HAS_PULL_ENABLE + PORT_HAL_SetPullCmd(portBase, pin, inputPin->config.isPullEnable); + #endif + #if FSL_FEATURE_PORT_HAS_PULL_SELECTION + PORT_HAL_SetPullMode(portBase, pin, inputPin->config.pullSelect); + #endif + #if FSL_FEATURE_PORT_HAS_PASSIVE_FILTER + PORT_HAL_SetPassiveFilterCmd(portBase, pin, + inputPin->config.isPassiveFilterEnabled); + #endif + #if FSL_FEATURE_PORT_HAS_DIGITAL_FILTER + PORT_HAL_SetDigitalFilterCmd(portBase, pin, + inputPin->config.isDigitalFilterEnabled); + #endif + #if FSL_FEATURE_GPIO_HAS_INTERRUPT_VECTOR + PORT_HAL_SetPinIntMode(portBase, pin, inputPin->config.interrupt); + + /* Configure NVIC */ + if ((inputPin->config.interrupt) && (g_portIrqId[port])) + { + /* Enable GPIO interrupt.*/ + INT_SYS_EnableIRQ(g_portIrqId[port]); + } + #endif +} + +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_OutputPinInit + * Description : Initialize one GPIO output pin used by board. + * + *END**************************************************************************/ +void GPIO_DRV_OutputPinInit(const gpio_output_pin_user_config_t *outputPin) +{ + /* Get actual port and pin number.*/ + uint32_t port = GPIO_EXTRACT_PORT(outputPin->pinName); + uint32_t pin = GPIO_EXTRACT_PIN(outputPin->pinName); + GPIO_Type * gpioBase = g_gpioBase[port]; + PORT_Type * portBase = g_portBase[port]; + + /* Un-gate port clock*/ + CLOCK_SYS_EnablePortClock(port); + + /* Set current pin as gpio.*/ + PORT_HAL_SetMuxMode(portBase, pin, kPortMuxAsGpio); + + /* Set current pin as digital output.*/ + GPIO_HAL_SetPinDir(gpioBase, pin, kGpioDigitalOutput); + + /* Configure GPIO output features. */ + GPIO_HAL_WritePinOutput(gpioBase, pin, outputPin->config.outputLogic); + #if FSL_FEATURE_PORT_HAS_SLEW_RATE + PORT_HAL_SetSlewRateMode(portBase, pin, outputPin->config.slewRate); + #endif + #if FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH + PORT_HAL_SetDriveStrengthMode(portBase, pin, outputPin->config.driveStrength); + #endif + #if FSL_FEATURE_PORT_HAS_OPEN_DRAIN + PORT_HAL_SetOpenDrainCmd(portBase, pin, outputPin->config.isOpenDrainEnabled); + #endif +} + +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_GetPinDir + * Description : Get current direction of individual GPIO pin. + * + *END**************************************************************************/ +gpio_pin_direction_t GPIO_DRV_GetPinDir(uint32_t pinName) +{ + GPIO_Type * gpioBase = g_gpioBase[GPIO_EXTRACT_PORT(pinName)]; + uint32_t pin = GPIO_EXTRACT_PIN(pinName); + + return GPIO_HAL_GetPinDir(gpioBase, pin); +} + +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_SetPinDir + * Description : Set current direction of individual GPIO pin. + * + *END**************************************************************************/ +void GPIO_DRV_SetPinDir(uint32_t pinName, gpio_pin_direction_t direction) +{ + GPIO_Type * gpioBase = g_gpioBase[GPIO_EXTRACT_PORT(pinName)]; + uint32_t pin = GPIO_EXTRACT_PIN(pinName); + + GPIO_HAL_SetPinDir(gpioBase, pin, direction); +} + +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_WritePinOutput + * Description : Set output level of individual GPIO pin to logic 1 or 0. + * + *END**************************************************************************/ +void GPIO_DRV_WritePinOutput(uint32_t pinName, uint32_t output) +{ + GPIO_Type * gpioBase = g_gpioBase[GPIO_EXTRACT_PORT(pinName)]; + uint32_t pin = GPIO_EXTRACT_PIN(pinName); + + GPIO_HAL_WritePinOutput(gpioBase, pin, output); +} + +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_SetPinOutput + * Description : Set output level of individual GPIO pin to logic 1. + * + *END**************************************************************************/ +void GPIO_DRV_SetPinOutput(uint32_t pinName) +{ + GPIO_Type * gpioBase = g_gpioBase[GPIO_EXTRACT_PORT(pinName)]; + uint32_t pin = GPIO_EXTRACT_PIN(pinName); + + GPIO_HAL_SetPinOutput(gpioBase, pin); +} + +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_ClearPinOutput + * Description : Set output level of individual GPIO pin to logic 0. + * + *END**************************************************************************/ +void GPIO_DRV_ClearPinOutput(uint32_t pinName) +{ + GPIO_Type * gpioBase = g_gpioBase[GPIO_EXTRACT_PORT(pinName)]; + uint32_t pin = GPIO_EXTRACT_PIN(pinName); + + GPIO_HAL_ClearPinOutput(gpioBase, pin); +} + +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_TogglePinOutput + * Description : Reverse current output logic of individual GPIO pin. + * + *END**************************************************************************/ +void GPIO_DRV_TogglePinOutput(uint32_t pinName) +{ + GPIO_Type * gpioBase = g_gpioBase[GPIO_EXTRACT_PORT(pinName)]; + uint32_t pin = GPIO_EXTRACT_PIN(pinName); + + GPIO_HAL_TogglePinOutput(gpioBase, pin); +} + +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_ReadPinInput + * Description : Read current input value of individual GPIO pin. + * + *END**************************************************************************/ +uint32_t GPIO_DRV_ReadPinInput(uint32_t pinName) +{ + GPIO_Type * gpioBase = g_gpioBase[GPIO_EXTRACT_PORT(pinName)]; + uint32_t pin = GPIO_EXTRACT_PIN(pinName); + + return GPIO_HAL_ReadPinInput(gpioBase, pin); +} + +#if FSL_FEATURE_PORT_HAS_DIGITAL_FILTER +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_SetDigitalFilterCmd + * Description : Enable or disable digital filter in one single port. + * + *END**************************************************************************/ +void GPIO_DRV_SetDigitalFilterCmd(uint32_t pinName, bool isDigitalFilterEnabled) +{ + PORT_Type * portBase = g_portBase[GPIO_EXTRACT_PORT(pinName)]; + uint32_t pin = GPIO_EXTRACT_PIN(pinName); + + PORT_HAL_SetDigitalFilterCmd(portBase, pin, isDigitalFilterEnabled); +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_IsPinIntPending + * Description : Read the individual pin-interrupt status flag. + * + *END**************************************************************************/ +bool GPIO_DRV_IsPinIntPending(uint32_t pinName) +{ + PORT_Type * portBase = g_portBase[GPIO_EXTRACT_PORT(pinName)]; + uint32_t pin = GPIO_EXTRACT_PIN(pinName); + + return PORT_HAL_IsPinIntPending(portBase, pin); +} + +/*FUNCTION********************************************************************** + * + * Function Name : GPIO_DRV_ClearPinIntFlag + * Description : Clear individual GPIO pin interrupt status flag. + * + *END**************************************************************************/ +void GPIO_DRV_ClearPinIntFlag(uint32_t pinName) +{ + PORT_Type * portBase = g_portBase[GPIO_EXTRACT_PORT(pinName)]; + uint32_t pin = GPIO_EXTRACT_PIN(pinName); + + PORT_HAL_ClearPinIntFlag(portBase, pin); +} + +#endif /* FSL_FEATURE_SOC_GPIO_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/gpio/fsl_gpio_irq.c b/KSDK_1.2.0/platform/drivers/src/gpio/fsl_gpio_irq.c new file mode 100755 index 0000000..8c1dea3 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/gpio/fsl_gpio_irq.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include "fsl_gpio_driver.h" + +/******************************************************************************* + * Code + ******************************************************************************/ + +/* gpio IRQ handler with the same name in startup code. */ +void PORTA_IRQHandler(void) +{ + /* Clear interrupt flag.*/ + PORT_HAL_ClearPortIntFlag(PORTA_BASE_PTR); +} + +#if defined (KL16Z4_SERIES) || defined (KL26Z4_SERIES) || defined (KL46Z4_SERIES) || defined (KW01Z4_SERIES) +/* gpio IRQ handler with the same name in startup code. */ +void PORTC_PORTD_IRQHandler(void) +{ + /* Clear interrupt flag.*/ + PORT_HAL_ClearPortIntFlag(PORTC_BASE_PTR); + PORT_HAL_ClearPortIntFlag(PORTD_BASE_PTR); +} +#endif + +#if defined (KL25Z4_SERIES) || defined (K70F12_SERIES) || defined(K60D10_SERIES) || \ + defined (K22F12810_SERIES) || defined (K22F25612_SERIES) || defined (K22F51212_SERIES) || \ + defined (KV31F12810_SERIES) || defined (KV31F25612_SERIES) || defined (KV31F51212_SERIES) || \ + defined (K64F12_SERIES) || defined (K24F12_SERIES) || defined (K63F12_SERIES) || \ + defined (K24F25612_SERIES) || defined (KV30F12810_SERIES) || defined (K02F12810_SERIES) || \ + defined (K26F18_SERIES) || defined (K65F18_SERIES) || defined (K66F18_SERIES) +/* gpio IRQ handler with the same name in startup code. */ +void PORTD_IRQHandler(void) +{ + /* Clear interrupt flag.*/ + PORT_HAL_ClearPortIntFlag(PORTD_BASE_PTR); +} +#endif + +#if defined (K70F12_SERIES) || defined(K60D10_SERIES) || \ + defined (K64F12_SERIES) || defined (K24F12_SERIES) || defined (K63F12_SERIES) || \ + defined (K22F12810_SERIES) || defined (K22F25612_SERIES) || defined (K22F51212_SERIES) || \ + defined (KV31F12810_SERIES) || defined (KV31F25612_SERIES) || defined (KV31F51212_SERIES) || \ + defined (K24F25612_SERIES) || \ + defined (K26F18_SERIES) || defined (K65F18_SERIES) || defined (K66F18_SERIES) +/* gpio IRQ handler with the same name in startup code. */ +void PORTB_IRQHandler(void) +{ + /* Clear interrupt flag.*/ + PORT_HAL_ClearPortIntFlag(PORTB_BASE_PTR); +} + +/* gpio IRQ handler with the same name in startup code. */ +void PORTC_IRQHandler(void) +{ + /* Clear interrupt flag.*/ + PORT_HAL_ClearPortIntFlag(PORTC_BASE_PTR); +} + +/* gpio IRQ handler with the same name in startup code. */ +void PORTE_IRQHandler(void) +{ + /* Clear interrupt flag.*/ + PORT_HAL_ClearPortIntFlag(PORTE_BASE_PTR); +} +#endif + +#if defined (K70F12_SERIES) +/* gpio IRQ handler with the same name in startup code. */ +void PORTF_IRQHandler(void) +{ + /* Clear interrupt flag.*/ + PORT_HAL_ClearPortIntFlag(PORTF_BASE_PTR); +} +#endif + +#if defined (KL03Z4_SERIES) +/* gpio IRQ handler with the same name in startup code. */ +void PORTB_IRQHandler(void) +{ + /* Clear interrupt flag.*/ + PORT_HAL_ClearPortIntFlag(PORTB_BASE_PTR); +} +#endif +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/gpio/fsl_gpio_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/gpio/fsl_gpio_lpm_callback.c new file mode 100755 index 0000000..0961c70 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/gpio/fsl_gpio_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t gpio_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t gpio_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_common.c b/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_common.c new file mode 100755 index 0000000..4a39d87 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_common.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_I2C_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for I2C instances. */ +I2C_Type * const g_i2cBase[I2C_INSTANCE_COUNT] = I2C_BASE_PTRS; + +/* Pointer to runtime state structure.*/ +void * g_i2cStatePtr[I2C_INSTANCE_COUNT] = { NULL }; + +/* Table to save i2c IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_i2cIrqId[I2C_INSTANCE_COUNT] = I2C_IRQS; + +#endif /* FSL_FEATURE_SOC_I2C_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_irq.c b/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_irq.c new file mode 100755 index 0000000..94adae7 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_irq.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_i2c_shared_function.h" +#include "fsl_device_registers.h" + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if (I2C_INSTANCE_COUNT > 0U) +/* Implementation of I2C0 handler named in startup code. */ +void I2C0_IRQHandler(void) +{ + I2C_DRV_IRQHandler(I2C0_IDX); +} +#endif + +#if (I2C_INSTANCE_COUNT > 1U) +/* Implementation of I2C1 handler named in startup code. */ +void I2C1_IRQHandler(void) +{ + I2C_DRV_IRQHandler(I2C1_IDX); +} +#endif + +#if (I2C_INSTANCE_COUNT > 2U) +/* Implementation of I2C2 handler named in startup code. */ +void I2C2_IRQHandler(void) +{ + I2C_DRV_IRQHandler(I2C2_IDX); +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_lpm_callback.c new file mode 100755 index 0000000..77d3f2b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t i2c_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t i2c_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_master_driver.c b/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_master_driver.c new file mode 100755 index 0000000..5d510cd --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_master_driver.c @@ -0,0 +1,806 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_i2c_master_driver.h" +#include "fsl_i2c_shared_function.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_I2C_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Default timeout time(ms) for sending of address and CMD buffer */ +#define I2C_TIMEOUT_MS (30) + +/******************************************************************************* + * Private Functions + ******************************************************************************/ + +static i2c_status_t I2C_DRV_MasterWait(uint32_t instance, uint32_t timeout_ms); +static void I2C_DRV_CompleteTransfer(uint32_t instance); +static i2c_status_t I2C_DRV_SendAddress(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + i2c_direction_t direction, + uint32_t timeout_ms); +static i2c_status_t I2C_DRV_MasterSend(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout_ms, + bool isBlocking); +static i2c_status_t I2C_DRV_MasterReceive(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout_ms, + bool isBlocking); + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterInit + * Description : initializes the I2C master mode driver. + * This function will initialize the I2C master mode driver, enable I2C clock, + * and enable I2C interrupt. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_MasterInit(uint32_t instance, i2c_master_state_t * master) +{ + assert(master); + assert(instance < I2C_INSTANCE_COUNT); + + I2C_Type * base = g_i2cBase[instance]; + + /* Exit if current instance is already initialized */ + if (g_i2cStatePtr[instance]) + { + return kStatus_I2C_Initialized; + } + + /* Initialize driver instance struct */ + memset(master, 0, sizeof(i2c_master_state_t)); + + /* Create sync object for transfer. */ + OSA_SemaCreate(&master->irqSync, 0); + + /* Enable clock for I2C.*/ + CLOCK_SYS_EnableI2cClock(instance); + + /* Initialize peripheral to known state.*/ + I2C_HAL_Init(base); + + /* Save runtime structure pointer */ + g_i2cStatePtr[instance] = master; + + /* Enable I2C interrupt in NVIC level.*/ + INT_SYS_EnableIRQ(g_i2cIrqId[instance]); + + /* Indicate I2C bus is idle. */ + master->i2cIdle = true; + + /* Enable module.*/ + I2C_HAL_Enable(base); + + return kStatus_I2C_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterDeinit + * Description : Deinit the I2C master mode driver. + * This function will deinit the I2C master mode driver, disable I2C clock, + * and disable I2C interrupt. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_MasterDeinit(uint32_t instance) +{ + assert(instance < I2C_INSTANCE_COUNT); + + /* Exit if current instance is already de-initialized or is gated.*/ + if ((!g_i2cStatePtr[instance]) || (!CLOCK_SYS_GetI2cGateCmd(instance))) + { + return kStatus_I2C_Fail; + } + + I2C_Type * base = g_i2cBase[instance]; + i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance]; + + /* Disable module.*/ + I2C_HAL_Disable(base); + + /* Disable clock for I2C.*/ + CLOCK_SYS_DisableI2cClock(instance); + + /* Disable I2C NVIC interrupt*/ + INT_SYS_DisableIRQ(g_i2cIrqId[instance]); + + /* Destroy I2C sema. */ + OSA_SemaDestroy(&master->irqSync); + + /* Cleared state pointer. */ + g_i2cStatePtr[instance] = NULL; + + return kStatus_I2C_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterSetBaudRate + * Description : configures the I2C bus to access a device. + * This function will set baud rate. + * + *END**************************************************************************/ +void I2C_DRV_MasterSetBaudRate(uint32_t instance, const i2c_device_t * device) +{ + assert(device); + assert(instance < I2C_INSTANCE_COUNT); + + I2C_Type * base = g_i2cBase[instance]; + uint32_t i2cClockFreq; + + /* Get current runtime structure. */ + i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance]; + + /* Set baud rate if different.*/ + if (device->baudRate_kbps != master->lastBaudRate_kbps) + { + /* Get the current bus clock.*/ + i2cClockFreq = CLOCK_SYS_GetI2cFreq(instance); + I2C_HAL_SetBaudRate(base, i2cClockFreq, device->baudRate_kbps, NULL); + + /* Record baud rate change */ + master->lastBaudRate_kbps = device->baudRate_kbps; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterSendDataBlocking + * Description : performs a blocking send transaction on the I2C bus. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_MasterSendDataBlocking(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout_ms) +{ + return I2C_DRV_MasterSend(instance, device, cmdBuff, cmdSize, txBuff, txSize, + timeout_ms, true); +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterSendData + * Description : Performs a non-blocking send transaction on the I2C bus. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_MasterSendData(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + const uint8_t * txBuff, + uint32_t txSize) +{ + return I2C_DRV_MasterSend(instance, device, cmdBuff, cmdSize, txBuff, txSize, + 0, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterGetSendStatus + * Description : Gets current status of I2C master transmit. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_MasterGetSendStatus(uint32_t instance, + uint32_t *bytesRemaining) +{ + i2c_status_t retVal = kStatus_I2C_Success; + i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance]; + uint32_t txSize = master->txSize; + + if (bytesRemaining) + { + *bytesRemaining = txSize; + } + + if (txSize) + { + retVal = kStatus_I2C_Busy; + } + + if (master->status != kStatus_I2C_Success) + { + retVal = master->status; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterAbortSendData + * Description : Terminates a non-blocking I2C Master transmission early. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_MasterAbortSendData(uint32_t instance) +{ + i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance]; + + if (master->i2cIdle) + { + return kStatus_I2C_Fail; + } + + I2C_DRV_CompleteTransfer(instance); + + return kStatus_I2C_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterReceiveDataBlocking + * Description : Performs a blocking receive transaction on the I2C bus. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_MasterReceiveDataBlocking(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout_ms) +{ + return I2C_DRV_MasterReceive(instance, device, cmdBuff, cmdSize, rxBuff, + rxSize, timeout_ms, true); +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterReceiveData + * Description : Performs a non-blocking receive transaction on the I2C bus. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_MasterReceiveData(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + uint8_t * rxBuff, + uint32_t rxSize) +{ + return I2C_DRV_MasterReceive(instance, device, cmdBuff, cmdSize, rxBuff, + rxSize, 0, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterGetReceiveStatus + * Description : Gets current status of I2C master receive. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_MasterGetReceiveStatus(uint32_t instance, + uint32_t *bytesRemaining) +{ + i2c_status_t retVal = kStatus_I2C_Success; + i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance]; + uint32_t rxSize = master->rxSize; + + if (bytesRemaining) + { + *bytesRemaining = rxSize; + } + + if (rxSize) + { + retVal = kStatus_I2C_Busy; + } + + if (master->status != kStatus_I2C_Success) + { + retVal = master->status; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C master IRQ handler. + * Description : This handler uses the buffers stored in the + * i2c_master_state_t structs to transfer data. + * This is not a public API as it is called whenever an interrupt occurs. + * + *END**************************************************************************/ +void I2C_DRV_MasterIRQHandler(uint32_t instance) +{ + assert(instance < I2C_INSTANCE_COUNT); + + I2C_Type * base = g_i2cBase[instance]; + + /* Clear the interrupt flag*/ + I2C_HAL_ClearInt(base); + + /* Get current runtime structure */ + i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance]; + + /* Get current master transfer direction */ + i2c_direction_t direction = I2C_HAL_GetDirMode(base); + + /* Exit immediately if there is no transfer in progress OR not in master mode */ + if ((!I2C_HAL_GetStatusFlag(base, kI2CBusBusy)) || + (!I2C_HAL_IsMaster(base))) + { + return; + } + + /* Handle send */ + if (direction == kI2CSend) + { + /* Check whether we got an ACK or NAK from the former byte we sent */ + if (I2C_HAL_GetStatusFlag(base, kI2CReceivedNak)) + { + /* Record that we got a NAK */ + master->status = kStatus_I2C_ReceivedNak; + + /* Got a NAK, so we're done with this transfer */ + I2C_DRV_CompleteTransfer(instance); + } + else + { + /* Continue send if still have data. TxSize/txBuff index need + * increment first because one byte is already sent in order + * to trigger interrupt */ + if (--master->txSize > 0) + { + /* Transmit next byte and update buffer index */ + I2C_HAL_WriteByte(base, *(++master->txBuff)); + } + else + { + /* Finish send data, send STOP, disable interrupt */ + I2C_DRV_CompleteTransfer(instance); + } + } + } + else /* Handle receive */ + { + switch (--master->rxSize) + { + case 0x0U: + /* Finish receive data, send STOP, disable interrupt */ + I2C_DRV_CompleteTransfer(instance); + break; + case 0x1U: + /* For the byte before last, we need to set NAK */ + I2C_HAL_SendNak(base); + break; + default : + I2C_HAL_SendAck(base); + break; + } + + /* Read recently received byte into buffer and update buffer index */ + *(master->rxBuff++) = I2C_HAL_ReadByte(base); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterWait + * Description : Wait transfer to finish. + * This function is a static function which will be called by other data + * transaction APIs. + * + *END**************************************************************************/ +static i2c_status_t I2C_DRV_MasterWait(uint32_t instance, uint32_t timeout_ms) +{ + assert(instance < I2C_INSTANCE_COUNT); + + i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance]; + osa_status_t syncStatus; + + do + { + syncStatus = OSA_SemaWait(&master->irqSync, timeout_ms); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + master->status = kStatus_I2C_Timeout; + } + + return master->status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_CompleteTransfer + * Description : Send STOP and disable interrupt when error happens or finish + * I2C transfers. + * This function is a static function which will be called by other data + * transaction APIs. + * + *END**************************************************************************/ +static void I2C_DRV_CompleteTransfer(uint32_t instance) +{ + assert(instance < I2C_INSTANCE_COUNT); + + I2C_Type * base = g_i2cBase[instance]; + i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance]; + + if ((!master->isRequesting) + || (master->status == kStatus_I2C_ReceivedNak) + || (master->status == kStatus_I2C_Timeout)) + { + /* Disable interrupt. */ + I2C_HAL_SetIntCmd(base, false); + + /* Generate stop signal. */ + I2C_HAL_SendStop(base); + + /* Indicate I2C bus is idle. */ + master->i2cIdle = true; + } + + if (master->isBlocking) + { + OSA_SemaPost(&master->irqSync); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SendAddress + * Description : Prepare and send out address buffer with interrupt. + * This function is a static function which will be called by other data + * transaction APIs. + * + *END**************************************************************************/ +static i2c_status_t I2C_DRV_SendAddress(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + i2c_direction_t direction, + uint32_t timeout_ms) +{ + assert(instance < I2C_INSTANCE_COUNT); + + I2C_Type * base = g_i2cBase[instance]; + /* Get current runtime structure. */ + i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance]; + + uint8_t addrByte1, addrByte2, directionBit; + bool is10bitAddr; + uint8_t addrBuff[2] = {0}; + uint8_t addrSize = 0; + bool isMainXferBlocking = master->isBlocking; + + /* Send of address and CMD must be blocking without STOP */ + master->isRequesting = true; + master->isBlocking = true; + + /*--------------- Prepare Address Buffer ------------------*/ + /* Get r/w bit according to required direction. + * read is 1, write is 0. */ + directionBit = (direction == kI2CReceive) ? 0x1U : 0x0U; + + /* Check to see if slave address is 10 bits or not. */ + is10bitAddr = ((device->address >> 10U) == 0x1EU) ? true : false; + + /* Get address byte 1 and byte 2 according address bit number. */ + if (is10bitAddr) + { + addrByte1 = (uint8_t)(device->address >> 8U); + addrByte2 = (uint8_t)device->address; + } + else + { + addrByte1 = (uint8_t)device->address; + } + + /* Get the device address with r/w direction. If we have a sub-address, + then that is always done as a write transfer prior to transferring + the actual data.*/ + addrByte1 = addrByte1 << 1U; + + /* First need to write if 10-bit address or has cmd buffer. */ + addrByte1 |= (uint8_t)((is10bitAddr || cmdBuff) ? 0U : directionBit); + + /* Put slave address byte 1 into address buffer. */ + addrBuff[addrSize++] = addrByte1; + + if (is10bitAddr) + { + /* Put address byte 2 into address buffer. */ + addrBuff[addrSize++] = addrByte2; + } + + /*--------------- Send Address Buffer ------------------*/ + master->txBuff = addrBuff; + master->txSize = addrSize; + + /* Send first byte in address buffer to trigger interrupt.*/ + I2C_HAL_WriteByte(base, addrBuff[0]); + + /* Wait for the transfer to finish.*/ + I2C_DRV_MasterWait(instance, timeout_ms); + + /*--------------------- Send CMD -----------------------*/ + if ((master->status == kStatus_I2C_Success) && cmdBuff) + { + master->txBuff = cmdBuff; + master->txSize = cmdSize; + + /* Send first byte in address buffer to trigger interrupt.*/ + I2C_HAL_WriteByte(base, *cmdBuff); + + /* Wait for the transfer to finish.*/ + I2C_DRV_MasterWait(instance, timeout_ms); + } + + /*--------------- Send Address Again ------------------*/ + /* Send slave address again if receiving data from 10-bit address slave, + OR conducting a cmd receive */ + if ((master->status == kStatus_I2C_Success) && (direction == kI2CReceive) + && (is10bitAddr || cmdBuff)) + { + /* Need to send slave address again. */ + master->txSize = 1U; + master->txBuff = NULL; + + /* Need to generate a repeat start before changing to receive. */ + I2C_HAL_SendStart(base); + + /* Send address byte 1 again. */ + I2C_HAL_WriteByte(base, (uint8_t)(addrByte1 | 1U)); + + /* Wait for the transfer to finish.*/ + I2C_DRV_MasterWait(instance, timeout_ms); + } + + master->isRequesting = false; + master->isBlocking = isMainXferBlocking ; + + return master->status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterSend + * Description : Private function to handle blocking/non-blocking send. + * This function is a static function which will be called by other data + * transaction APIs. + * + *END**************************************************************************/ +static i2c_status_t I2C_DRV_MasterSend(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout_ms, + bool isBlocking) +{ + assert(instance < I2C_INSTANCE_COUNT); + assert(txBuff); + + I2C_Type * base = g_i2cBase[instance]; + i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance]; + + /* Return if current instance is used */ + if (!master->i2cIdle) + { + return master->status = kStatus_I2C_Busy; + } + + /* Need to assign a pre-defined timeout value for sending address and cmd */ + if (!isBlocking) + { + timeout_ms = I2C_TIMEOUT_MS; + } + + master->txBuff = NULL; + master->txSize = 0; + master->rxBuff = NULL; + master->rxBuff = 0; + master->status = kStatus_I2C_Success; + master->i2cIdle = false; + master->isBlocking = isBlocking; + + I2C_DRV_MasterSetBaudRate(instance, device); + + /* Set direction to send for sending of address and data. */ + I2C_HAL_SetDirMode(base, kI2CSend); + + /* Enable i2c interrupt.*/ + I2C_HAL_ClearInt(base); + I2C_HAL_SetIntCmd(base, true); + + /* Generate start signal. */ + I2C_HAL_SendStart(base); + + /* Send out slave address. */ + I2C_DRV_SendAddress(instance, device, cmdBuff, cmdSize, kI2CSend, timeout_ms); + + /* Send out data in transmit buffer. */ + if (master->status == kStatus_I2C_Success) + { + /* Fill tx buffer and size to run-time structure. */ + master->txBuff = txBuff; + master->txSize = txSize; + + /* Send first byte in transmit buffer to trigger interrupt.*/ + I2C_HAL_WriteByte(base, master->txBuff[0]); + + if (isBlocking) + { + /* Wait for the transfer to finish.*/ + I2C_DRV_MasterWait(instance, timeout_ms); + } + } + else if (master->status == kStatus_I2C_Timeout) + { + /* Disable interrupt. */ + I2C_HAL_SetIntCmd(base, false); + + if (I2C_HAL_GetStatusFlag(base, kI2CBusBusy)) + { + /* Generate stop signal. */ + I2C_HAL_SendStop(base); + } + + /* Indicate I2C bus is idle. */ + master->i2cIdle = true; + } + + return master->status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_MasterReceive + * Description : Private function to handle blocking/non-blocking receive. + * This function is a static function which will be called by other data + * transaction APIs. + * + *END**************************************************************************/ +static i2c_status_t I2C_DRV_MasterReceive(uint32_t instance, + const i2c_device_t * device, + const uint8_t * cmdBuff, + uint32_t cmdSize, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout_ms, + bool isBlocking) +{ + assert(instance < I2C_INSTANCE_COUNT); + assert(rxBuff); + + I2C_Type * base = g_i2cBase[instance]; + i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance]; + + /* Return if current instance is used */ + if (!master->i2cIdle) + { + return master->status = kStatus_I2C_Busy; + } + + /* Need to assign a pre-defined timeout value for sending address and cmd */ + if (!isBlocking) + { + timeout_ms = I2C_TIMEOUT_MS; + } + + master->rxBuff = rxBuff; + master->rxSize = rxSize; + master->txBuff = NULL; + master->txSize = 0; + master->status = kStatus_I2C_Success; + master->i2cIdle = false; + master->isBlocking = isBlocking; + + I2C_DRV_MasterSetBaudRate(instance, device); + + /* Set direction to send for sending of address. */ + I2C_HAL_SetDirMode(base, kI2CSend); + + /* Enable i2c interrupt.*/ + I2C_HAL_ClearInt(base); + I2C_HAL_SetIntCmd(base, true); + + /* Generate start signal. */ + I2C_HAL_SendStart(base); + + /* Send out slave address. */ + I2C_DRV_SendAddress(instance, device, cmdBuff, cmdSize, kI2CReceive, timeout_ms); + + /* Start to receive data. */ + if (master->status == kStatus_I2C_Success) + { + /* Change direction to receive. */ + I2C_HAL_SetDirMode(base, kI2CReceive); + + /* Send NAK if only one byte to read. */ + if (rxSize == 0x1U) + { + I2C_HAL_SendNak(base); + } + else + { + I2C_HAL_SendAck(base); + } + + /* Dummy read to trigger receive of next byte in interrupt. */ + I2C_HAL_ReadByte(base); + + if (isBlocking) + { + /* Wait for the transfer to finish.*/ + I2C_DRV_MasterWait(instance, timeout_ms); + } + } + else if (master->status == kStatus_I2C_Timeout) + { + /* Disable interrupt. */ + I2C_HAL_SetIntCmd(base, false); + + if (I2C_HAL_GetStatusFlag(base, kI2CBusBusy)) + { + /* Generate stop signal. */ + I2C_HAL_SendStop(base); + } + + /* Indicate I2C bus is idle. */ + master->i2cIdle = true; + } + + return master->status; +} + +#endif /* FSL_FEATURE_SOC_I2C_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_shared_function.c b/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_shared_function.c new file mode 100755 index 0000000..74cc14a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_shared_function.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include "fsl_i2c_hal.h" +#include "fsl_i2c_shared_function.h" +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_I2C_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for I2C instances. */ +extern I2C_Type * const g_i2cBase[I2C_INSTANCE_COUNT]; + +/* External for the I2C master driver interrupt handler.*/ +extern void I2C_DRV_MasterIRQHandler(uint32_t instance); + +/* External for the I2C slave driver interrupt handler.*/ +extern void I2C_DRV_SlaveIRQHandler(uint32_t instance); + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Pass IRQ control to either the master or slave driver. + * + * The address of the IRQ handlers are checked to make sure they are non-zero before + * they are called. If the IRQ handler's address is zero, it means that driver was + * not present in the link (because the IRQ handlers are marked as weak). This would + * actually be a program error, because it means the master/slave config for the IRQ + * was set incorrectly. + * + * @param instance Instance number of the I2C module. + */ +void I2C_DRV_IRQHandler(uint32_t instance) +{ + assert(instance < I2C_INSTANCE_COUNT); + I2C_Type * base = g_i2cBase[instance]; + + if (I2C_HAL_IsMaster(base)) + { + /* Master mode.*/ + I2C_DRV_MasterIRQHandler(instance); + } + else + { + /* Slave mode.*/ + I2C_DRV_SlaveIRQHandler(instance); + } +} + +#endif /* FSL_FEATURE_SOC_I2C_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_slave_driver.c b/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_slave_driver.c new file mode 100755 index 0000000..a04f56f --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_slave_driver.c @@ -0,0 +1,818 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_i2c_hal.h" +#include "fsl_i2c_slave_driver.h" +#include "fsl_i2c_shared_function.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_I2C_COUNT + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SlaveInit + * Description : initializes the I2C module. + * This function will save the application callback info, turn on the clock of + * I2C instance, setup according to user configuration. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_SlaveInit(uint32_t instance, + const i2c_slave_user_config_t * userConfigPtr, + i2c_slave_state_t * slave) +{ + assert(slave); + assert(instance < I2C_INSTANCE_COUNT); + + I2C_Type * base = g_i2cBase[instance]; + + /* Exit if current instance is already initialized. */ + if (g_i2cStatePtr[instance]) + { + return kStatus_I2C_Initialized; + } + + /* Init driver instance structure */ + memset(slave, 0, sizeof(i2c_slave_state_t)); + slave->slaveListening = userConfigPtr->slaveListening; + slave->slaveCallback = userConfigPtr->slaveCallback; + slave->callbackParam = userConfigPtr->callbackParam; + + /* Enable clock for I2C.*/ + CLOCK_SYS_EnableI2cClock(instance); + + /* Init instance to known state. */ + I2C_HAL_Init(base); + + /* Set slave address.*/ + I2C_HAL_SetAddress7bit(base, userConfigPtr->address); + + /* Save runtime structure pointer.*/ + g_i2cStatePtr[instance] = slave; + + /* Create Event for irqSync */ + OSA_EventCreate(&slave->irqEvent, kEventAutoClear); + +#if FSL_FEATURE_I2C_HAS_START_STOP_DETECT + /* Enable I2C START&STOP signal detect interrupt in the peripheral.*/ + if(userConfigPtr->startStopDetect) + { + I2C_HAL_SetStartStopIntCmd(base,true); + } +#endif +#if FSL_FEATURE_I2C_HAS_STOP_DETECT + /* Enable STOP signal detect interrupt in the peripheral.*/ + if(userConfigPtr->stopDetect) + { + I2C_HAL_SetStopIntCmd(base,true); + } +#endif + + /* Enable I2C interrupt as default if setup slave listening mode */ + I2C_HAL_SetIntCmd(base, slave->slaveListening); + + /* Enable I2C interrupt from NVIC */ + INT_SYS_EnableIRQ(g_i2cIrqId[instance]); + + /* Enable the peripheral operation.*/ + I2C_HAL_Enable(base); + + return kStatus_I2C_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SlaveDeinit + * Description : Shuts down the I2C slave driver. + * This function will clear the control register and turn off the clock to the + * module. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_SlaveDeinit(uint32_t instance) +{ + assert(instance < I2C_INSTANCE_COUNT); + + /* Exit if current instance is already de-initialized or is gated.*/ + if ((!g_i2cStatePtr[instance]) || (!CLOCK_SYS_GetI2cGateCmd(instance))) + { + return kStatus_I2C_Fail; + } + + I2C_Type * base = g_i2cBase[instance]; + i2c_slave_state_t * i2cSlaveState = (i2c_slave_state_t *)g_i2cStatePtr[instance]; + +#if FSL_FEATURE_I2C_HAS_START_STOP_DETECT + /* Disable I2C START&STOP signal detect interrupt in the peripheral.*/ + I2C_HAL_SetStartStopIntCmd(base,false); +#endif +#if FSL_FEATURE_I2C_HAS_STOP_DETECT + /* Disable STOP signal detect interrupt in the peripheral.*/ + I2C_HAL_SetStopIntCmd(base,false); +#endif + + /* Disable I2C interrupt. */ + I2C_HAL_SetIntCmd(base, false); + + /* Turn off I2C.*/ + I2C_HAL_Disable(base); + + /* Disable clock for I2C.*/ + CLOCK_SYS_DisableI2cClock(instance); + + /* Disable I2C NVIC interrupt */ + INT_SYS_DisableIRQ(g_i2cIrqId[instance]); + + /* Destroy sema. */ + OSA_EventDestroy(&i2cSlaveState->irqEvent); + + /* Clear runtime structure poniter.*/ + g_i2cStatePtr[instance] = NULL; + + return kStatus_I2C_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SlaveGetHandler + * Description : Get run-time handler to I2C slave state structure. + * This function will return the pointer to I2C slave state structure. + * + *END**************************************************************************/ +i2c_slave_state_t * I2C_DRV_SlaveGetHandler(uint32_t instance) +{ + return (i2c_slave_state_t *)g_i2cStatePtr[instance]; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SlaveReceiveDataBlocking + * Description : Receive the data using a blocking method. + * This function set buffer pointer and length to Rx buffer &Rx Size. Then wait + * until the transmission is end (all data are received or STOP signal is + * detected) + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_SlaveReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout_ms) +{ + assert(rxBuff); + assert(instance < I2C_INSTANCE_COUNT); + + i2c_slave_state_t * i2cSlaveState = (i2c_slave_state_t *)g_i2cStatePtr[instance]; + + if(!i2cSlaveState->slaveListening) + { + event_flags_t i2cIrqSetFlags; + osa_status_t syncStatus; + + if (i2cSlaveState->isRxBusy) + { + return kStatus_I2C_Busy; + } + + i2cSlaveState->rxBuff = rxBuff; + i2cSlaveState->rxSize = rxSize; + i2cSlaveState->isRxBusy = true; + i2cSlaveState->isRxBlocking = true; + + /* If IAAS event already comes, read dummy to release the bus.*/ + if(I2C_HAL_GetStatusFlag(g_i2cBase[instance], kI2CAddressAsSlave)) + { + /* Switch to RX mode.*/ + I2C_HAL_SetDirMode(g_i2cBase[instance], kI2CReceive); + I2C_HAL_ReadByte(g_i2cBase[instance]); + } + + I2C_HAL_SetIntCmd(g_i2cBase[instance], true); + + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_EventWait(&i2cSlaveState->irqEvent, + #if (FSL_FEATURE_I2C_HAS_START_STOP_DETECT || FSL_FEATURE_I2C_HAS_STOP_DETECT) + kI2CSlaveStopDetect | + #endif + kI2CSlaveRxFull | kI2CSlaveAbort, + false, + timeout_ms, + &i2cIrqSetFlags); + } while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + I2C_HAL_SetIntCmd(g_i2cBase[instance], false); + i2cSlaveState->status = kStatus_I2C_Timeout; + } + + i2cSlaveState->isRxBlocking = false; + + return i2cSlaveState->status; + } + else /* i2cSlaveState->slaveListening */ + { + return kStatus_I2C_Fail; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SlaveReceiveData + * Description : Receive the data using a non-blocking method. + * This function set buffer pointer and length to Rx buffer & Rx Size + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_SlaveReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(rxBuff); + assert(instance < I2C_INSTANCE_COUNT); + + i2c_slave_state_t * i2cSlaveState = (i2c_slave_state_t *)g_i2cStatePtr[instance]; + + if(!i2cSlaveState->slaveListening) + { + if (i2cSlaveState->isRxBusy) + { + return kStatus_I2C_Busy; + } + + i2cSlaveState->rxBuff = rxBuff; + i2cSlaveState->rxSize = rxSize; + i2cSlaveState->isRxBusy = true; + + /* If IAAS event already comes, read dummy to release the bus.*/ + if(I2C_HAL_GetStatusFlag(g_i2cBase[instance], kI2CAddressAsSlave)) + { + /* Switch to RX mode.*/ + I2C_HAL_SetDirMode(g_i2cBase[instance], kI2CReceive); + I2C_HAL_ReadByte(g_i2cBase[instance]); + } + + I2C_HAL_SetIntCmd(g_i2cBase[instance], true); + + return kStatus_I2C_Success; + } + else /* i2cSlaveState->slaveListening */ + { + return kStatus_I2C_Fail; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SlaveSendDataBlocking + * Description : Send the data using a blocking method. + * This function set buffer pointer and length to Tx buffer & Tx Size. + * Then wait until the transmission is end ( NAK is detected) + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_SlaveSendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout_ms) +{ + assert(txBuff); + assert(instance < I2C_INSTANCE_COUNT); + + i2c_slave_state_t * i2cSlaveState = (i2c_slave_state_t *)g_i2cStatePtr[instance]; + + if(!i2cSlaveState->slaveListening) + { + event_flags_t i2cIrqSetFlags; + osa_status_t syncStatus; + + if (i2cSlaveState->isTxBusy) + { + return kStatus_I2C_Busy; + } + + /* Initialize the module driver state structure. */ + i2cSlaveState->txBuff = txBuff; + i2cSlaveState->txSize = txSize; + i2cSlaveState->isTxBusy = true; + i2cSlaveState->isTxBlocking = true; + + I2C_HAL_SetIntCmd(g_i2cBase[instance], true); + + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_EventWait(&i2cSlaveState->irqEvent, + kI2CSlaveTxNAK | kI2CSlaveAbort, + false, + timeout_ms, + &i2cIrqSetFlags); + } while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + I2C_HAL_SetIntCmd(g_i2cBase[instance], false); + i2cSlaveState->status = kStatus_I2C_Timeout; + } + + i2cSlaveState->isTxBlocking = false; + + return i2cSlaveState->status; + } + else /* i2cSlaveState->slaveListening */ + { + return kStatus_I2C_Fail; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SlaveSendData + * Description : Send the data using a non-blocking method. + * This function set buffer pointer and length to Tx buffer & Tx Size + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_SlaveSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(txBuff); + assert(instance < I2C_INSTANCE_COUNT); + + i2c_slave_state_t * i2cSlaveState = (i2c_slave_state_t *)g_i2cStatePtr[instance]; + + if(!i2cSlaveState->slaveListening) + { + if (i2cSlaveState->isTxBusy) + { + return kStatus_I2C_Busy; + } + + /* Initialize the module driver state structure. */ + i2cSlaveState->txBuff = txBuff; + i2cSlaveState->txSize = txSize; + i2cSlaveState->isTxBusy = true; + + I2C_HAL_SetIntCmd(g_i2cBase[instance], true); + + return kStatus_I2C_Success; + } + else /* i2cSlaveState->slaveListening */ + { + return kStatus_I2C_Fail; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SlaveGetTransmitStatus + * Description : Gets current status of I2C slave driver. This function returns + * whether the previous I2C Slave Transmit has finished + * When performing a non-blocking transmit, the user can call this function to + * ascertain the state of the current transmission: in progress (or busy) or + * complete (finished). The user can obtain the number of bytes that have been + * currently transferred + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_SlaveGetTransmitStatus(uint32_t instance, + uint32_t *bytesRemaining) +{ + assert(instance < I2C_INSTANCE_COUNT); + + /* Get current runtime structure */ + i2c_slave_state_t * i2cSlaveState = (i2c_slave_state_t *)g_i2cStatePtr[instance]; + i2c_status_t retVal = kStatus_I2C_Success; + uint32_t txSize = i2cSlaveState->txSize; + + if (bytesRemaining) + { + *bytesRemaining = txSize; + } + + if (txSize) + { + retVal = kStatus_I2C_Busy; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SlaveGetReceiveStatus + * Description : Gets current status of I2C slave driver. This function returns + * whether the previous I2C Slave Receive has finished + * When performing a non-blocking receiving, the user can call this function to + * ascertain the state of the current receiving: in progress (or busy) or + * complete (finished). The user can obtain the number of bytes that have been + * currently transferred + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_SlaveGetReceiveStatus(uint32_t instance, + uint32_t *bytesRemaining) +{ + assert(instance < I2C_INSTANCE_COUNT); + + /* Get current runtime structure */ + i2c_slave_state_t * i2cSlaveState = (i2c_slave_state_t *)g_i2cStatePtr[instance]; + i2c_status_t retVal = kStatus_I2C_Success; + uint32_t rxSize = i2cSlaveState->rxSize; + + if (bytesRemaining) + { + *bytesRemaining = rxSize; + } + + if (rxSize) + { + retVal = kStatus_I2C_Busy; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SlaveAbortReceiveData + * Description : This function is used to abort receiving of I2C slave + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_SlaveAbortReceiveData(uint32_t instance, uint32_t *rxSize) +{ + assert(instance < I2C_INSTANCE_COUNT); + i2c_slave_state_t * i2cSlaveState = (i2c_slave_state_t *)g_i2cStatePtr[instance]; + + *rxSize = i2cSlaveState->rxSize; + + /* Check if a transfer is running. */ + if (!i2cSlaveState->isRxBusy) + { + return kStatus_I2C_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + i2cSlaveState->isRxBusy = false; + i2cSlaveState->rxBuff = NULL; + i2cSlaveState->rxSize = 0; + + if(!i2cSlaveState->slaveListening) + { + /* Disable I2C interrupt in the peripheral.*/ + I2C_HAL_SetIntCmd(g_i2cBase[instance], false); + + if (i2cSlaveState->isRxBlocking) + { + /* Set kI2CSlaveRxFull event to notify that the receiving is done */ + OSA_EventSet(&i2cSlaveState->irqEvent, kI2CSlaveAbort); + } + } + + return kStatus_I2C_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SlaveAbortSendData + * Description : This function is used to abort sending of I2C slave + * + *END**************************************************************************/ +i2c_status_t I2C_DRV_SlaveAbortSendData(uint32_t instance, uint32_t *txSize) +{ + assert(instance < I2C_INSTANCE_COUNT); + i2c_slave_state_t * i2cSlaveState = (i2c_slave_state_t *)g_i2cStatePtr[instance]; + + *txSize = i2cSlaveState->txSize; + + /* Check if a transfer is running. */ + if (!i2cSlaveState->isTxBusy) + { + return kStatus_I2C_NoSendInProgress; + } + + /* Stop the running transfer. */ + i2cSlaveState->isTxBusy = false; + i2cSlaveState->txBuff = NULL; + i2cSlaveState->txSize = 0; + + if(!i2cSlaveState->slaveListening) + { + /* Disable I2C interrupt in the peripheral.*/ + I2C_HAL_SetIntCmd(g_i2cBase[instance], false); + + if (i2cSlaveState->isTxBlocking) + { + /* Set kI2CSlaveTxEmpty event to notify that the sending is done */ + OSA_EventSet(&i2cSlaveState->irqEvent, kI2CSlaveAbort); + } + } + + return kStatus_I2C_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : I2C_DRV_SlaveIRQHandler + * Description : I2C Slave Generic ISR. + * ISR action be called inside I2C IRQ handler entry. + * + *END**************************************************************************/ +void I2C_DRV_SlaveIRQHandler(uint32_t instance) +{ + assert(instance < I2C_INSTANCE_COUNT); + + I2C_Type * base = g_i2cBase[instance]; + uint8_t i2cData = 0x00; + bool doTransmit = false; + bool wasArbLost = I2C_HAL_GetStatusFlag(base, kI2CArbitrationLost); + bool addressed = I2C_HAL_GetStatusFlag(base, kI2CAddressAsSlave); + bool stopIntEnabled = false; + +#if FSL_FEATURE_I2C_HAS_START_STOP_DETECT + bool startDetected = I2C_HAL_GetStartFlag(base); + bool startIntEnabled = I2C_HAL_GetStartStopIntCmd(base); + bool stopDetected = I2C_HAL_GetStopFlag(base); + stopIntEnabled = startIntEnabled; +#endif + +#if FSL_FEATURE_I2C_HAS_STOP_DETECT + bool stopDetected = I2C_HAL_GetStopFlag(base); + stopIntEnabled = I2C_HAL_GetStopIntCmd(base); +#endif + + /* Get current runtime structure */ + i2c_slave_state_t * i2cSlaveState = (i2c_slave_state_t *)g_i2cStatePtr[instance]; + + /* Get current slave transfer direction */ + i2c_direction_t direction = I2C_HAL_GetDirMode(base); + +#if FSL_FEATURE_I2C_HAS_START_STOP_DETECT + /*--------------- Handle START ------------------*/ + if (startIntEnabled && startDetected) + { + I2C_HAL_ClearStartFlag(base); + I2C_HAL_ClearInt(base); + + if(i2cSlaveState->slaveCallback != NULL) + { + /*Call callback to handle when the driver detect START signal*/ + i2cSlaveState->slaveCallback(instance, + kI2CSlaveStartDetect, + i2cSlaveState->callbackParam); + } + + return; + } +#endif + +#if FSL_FEATURE_I2C_HAS_START_STOP_DETECT || FSL_FEATURE_I2C_HAS_STOP_DETECT + /*--------------- Handle STOP ------------------*/ + if (stopIntEnabled && stopDetected) + { + I2C_HAL_ClearStopFlag(base); + I2C_HAL_ClearInt(base); + + if(!i2cSlaveState->slaveListening) + { + /* Disable I2C interrupt in the peripheral.*/ + I2C_HAL_SetIntCmd(base, false); + } + + if(i2cSlaveState->slaveCallback != NULL) + { + /*Call callback to handle when the driver detect STOP signal*/ + i2cSlaveState->slaveCallback(instance, + kI2CSlaveStopDetect, + i2cSlaveState->callbackParam); + } + + if (i2cSlaveState->isRxBlocking) + { + OSA_EventSet(&i2cSlaveState->irqEvent, kI2CSlaveStopDetect); + } + + i2cSlaveState->status = kStatus_I2C_Idle; + + return; + } +#endif + + /* Clear I2C IRQ.*/ + I2C_HAL_ClearInt(base); + + if (wasArbLost) + { + I2C_HAL_ClearArbitrationLost(base); + if (!addressed) + { + i2cSlaveState->status = kStatus_I2C_AribtrationLost; + if(!i2cSlaveState->slaveListening) + { + /* Disable I2C interrupt in the peripheral.*/ + I2C_HAL_SetIntCmd(base, false); + } + return; + } + } + + /*--------------- Handle Address ------------------*/ + /* Addressed only happens when receiving address. */ + if (addressed) /* Slave is addressed. */ + { + /* Master read from Slave. Slave transmit.*/ + if (I2C_HAL_GetStatusFlag(base, kI2CSlaveTransmit)) + { + /* Switch to TX mode*/ + I2C_HAL_SetDirMode(base, kI2CSend); + + if(i2cSlaveState->slaveCallback != NULL) + { + /*Call callback to handle when the driver get read request*/ + i2cSlaveState->slaveCallback(instance, + kI2CSlaveTxReq, + i2cSlaveState->callbackParam); + } + + doTransmit = true; + } + else /* Master write to Slave. Slave receive.*/ + { + /* Switch to RX mode.*/ + I2C_HAL_SetDirMode(base, kI2CReceive); + + if(i2cSlaveState->slaveCallback != NULL) + { + /*Call callback to handle when the driver get write request*/ + i2cSlaveState->slaveCallback(instance, + kI2CSlaveRxReq, + i2cSlaveState->callbackParam); + } + + /* Read dummy character.*/ + I2C_HAL_ReadByte(base); + } + } + /*--------------- Handle Transfer ------------------*/ + else + { + /* Handle transmit */ + if (direction == kI2CSend) + { + if (I2C_HAL_GetStatusFlag(base, kI2CReceivedNak)) + { + /* Switch to RX mode.*/ + I2C_HAL_SetDirMode(base, kI2CReceive); + /* Read dummy character to release bus */ + I2C_HAL_ReadByte(base); + + if ((!i2cSlaveState->slaveListening) && (!stopIntEnabled)) + { + /* Disable I2C interrupt in the peripheral.*/ + I2C_HAL_SetIntCmd(base, false); + } + + if(i2cSlaveState->slaveCallback != NULL) + { + /* Receive TX NAK, mean transaction is finished, call callback to handle */ + i2cSlaveState->slaveCallback(instance, + kI2CSlaveTxNAK, + i2cSlaveState->callbackParam); + } + + if (i2cSlaveState->isTxBlocking) + { + OSA_EventSet(&i2cSlaveState->irqEvent, kI2CSlaveTxNAK); + } + + i2cSlaveState->txSize = 0; + i2cSlaveState->txBuff = NULL; + i2cSlaveState->isTxBusy = false; + } + else /* ACK from receiver.*/ + { + doTransmit = true; + } + } + /* Handle receive */ + else + { + /* Get byte from data register */ + i2cData = I2C_HAL_ReadByte(base); + + if (i2cSlaveState->rxSize) + { + *(i2cSlaveState->rxBuff) = i2cData; + ++ i2cSlaveState->rxBuff; + -- i2cSlaveState->rxSize; + + if (!i2cSlaveState->rxSize) + { + if (!stopIntEnabled) + { + if(!i2cSlaveState->slaveListening) + { + /* Disable I2C interrupt in the peripheral.*/ + I2C_HAL_SetIntCmd(base, false); + } + + /* All bytes are received, so we're done with this transfer */ + if (i2cSlaveState->isRxBlocking) + { + OSA_EventSet(&i2cSlaveState->irqEvent, kI2CSlaveRxFull); + } + } + + i2cSlaveState->isRxBusy = false; + i2cSlaveState->rxBuff = NULL; + + if(i2cSlaveState->slaveCallback != NULL) + { + /* Rx buffer is full, call callback to handle */ + i2cSlaveState->slaveCallback(instance, + kI2CSlaveRxFull, + i2cSlaveState->callbackParam); + } + } + } + else + { + /* The Rxbuff is full --> Set kStatus_I2C_SlaveRxOverrun*/ + i2cSlaveState->status = kStatus_I2C_SlaveRxOverrun; + } + } + } + + /* DO TRANSMIT*/ + if (doTransmit) + { + /* Send byte to data register */ + if (i2cSlaveState->txSize) + { + i2cData = *(i2cSlaveState->txBuff); + I2C_HAL_WriteByte(base, i2cData); + ++ i2cSlaveState->txBuff; + -- i2cSlaveState->txSize; + if (!i2cSlaveState->txSize) + { + /* All bytes are received, so we're done with this transfer */ + i2cSlaveState->txBuff = NULL; + i2cSlaveState->isTxBusy = false; + + if(i2cSlaveState->slaveCallback != NULL) + { + /* Tx buffer is empty, finish transaction, call callback to handle */ + i2cSlaveState->slaveCallback(instance, + kI2CSlaveTxEmpty, + i2cSlaveState->callbackParam); + } + + } + } + else + { + /* The Txbuff is empty --> set kStatus_I2C_SlaveTxUnderrun*/ + i2cSlaveState->status = kStatus_I2C_SlaveTxUnderrun ; + } + } +} + +#endif /* FSL_FEATURE_SOC_I2C_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/lmem/fsl_lmem_cache_driver.c b/KSDK_1.2.0/platform/drivers/src/lmem/fsl_lmem_cache_driver.c new file mode 100755 index 0000000..d0b6ec6 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lmem/fsl_lmem_cache_driver.c @@ -0,0 +1,792 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_lmem_cache_driver.h" + +#if FSL_FEATURE_SOC_LMEM_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_CodeCacheInvalidateAll + * Description : This function invalidates the entire Processor Code bus cache. + * + * This function invalidates the entire cache meaning that it invalidates both Ways. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + *END**************************************************************************/ +void LMEM_DRV_CodeCacheInvalidateAll(uint32_t instance) +{ + LMEM_Type *base = g_lmemBase[instance]; + + LMEM_HAL_SetCodeCacheInvalidateAllCmd(base, true); + LMEM_HAL_InitiateCodeCacheCommand(base); + + /* Wait until the cache command completes */ + while (LMEM_HAL_IsCodeCacheCommandActive(base)) { } + + /* As a precaution clear the bits to avoid inadvertently re-running this command */ + LMEM_HAL_SetCodeCacheInvalidateAllCmd(base, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_CodeCachePushAll + * Description : This function pushes all modified lines in the entire Processor Code bus cache. + * + * This function pushes all modified lines in both Ways (the entire cache). + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * entry not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + *END**************************************************************************/ +void LMEM_DRV_CodeCachePushAll(uint32_t instance) +{ + LMEM_Type *base = g_lmemBase[instance]; + + LMEM_HAL_SetCodeCachePushAllCmd(base, true); + LMEM_HAL_InitiateCodeCacheCommand(base); + + /* Wait until the cache command completes */ + while (LMEM_HAL_IsCodeCacheCommandActive(base)) { } + + /* As a precaution clear the bits to avoid inadvertently re-running this command */ + LMEM_HAL_SetCodeCachePushAllCmd(base, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_CodeCacheClearAll + * Description : This function clears the entire Processor Code bus cache. + * + * This function clears the entire cache, which is basically a push (flush) and + * invalidate operation. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + *END**************************************************************************/ +void LMEM_DRV_CodeCacheClearAll(uint32_t instance) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* Push and invalidate all */ + LMEM_HAL_SetCodeCachePushAllCmd(base, true); + LMEM_HAL_SetCodeCacheInvalidateAllCmd(base, true); + LMEM_HAL_InitiateCodeCacheCommand(base); + + /* Wait until the cache command completes */ + while (LMEM_HAL_IsCodeCacheCommandActive(base)) { } + + /* As a precaution clear the bits to avoid inadvertently re-running this command */ + LMEM_HAL_SetCodeCachePushAllCmd(base, false); + LMEM_HAL_SetCodeCacheInvalidateAllCmd(base, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_CodeCacheEnable + * Description : This function enables the Processor Code bus cache. + * + * This function enables the cache. The function first invalidates the entire cache, + * then it enables both the cache and write buffer. + * + *END**************************************************************************/ +void LMEM_DRV_CodeCacheEnable(uint32_t instance) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* First, invalidate the entire cache */ + LMEM_DRV_CodeCacheInvalidateAll(instance); + + /* Now enable the cache */ + LMEM_HAL_SetCodeCacheEnableCmd(base, true); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_CodeCacheEnable + * Description : This function disables the Processor Code bus cache. + * + * This function disables the cache and write buffer. + * + *END**************************************************************************/ +void LMEM_DRV_CodeCacheDisable(uint32_t instance) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* First, push any modified contents */ + LMEM_DRV_CodeCachePushAll(instance); + + /* Now disable the cache */ + LMEM_HAL_SetCodeCacheEnableCmd(base, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_CodeCacheInvalidateLine + * Description : This function invalidates a specific line in the Processor Code bus cache. + * + * This function invalidates a specific line in the cache. The function invalidates a + * line in cache based on the physical address passed in by the user. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + *END**************************************************************************/ +void LMEM_DRV_CodeCacheInvalidateLine(uint32_t instance, uint32_t addr) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* Set the invalidate by line command */ + LMEM_HAL_SetCodeCacheLineCommand(base, kCacheLineInvalidate); + + /* Since we're using the physical address, both ways are searched */ + LMEM_HAL_SetCodeCachePhysicalAddr(base, addr); + + LMEM_HAL_InitiateCodeCacheLineCommand(base); + + /* Set the line command to use the physical address */ + LMEM_BWR_PCCLCR_LADSEL(base, 1U); + + /* Wait until the cache command completes */ + while (LMEM_HAL_IsCodeCacheLineCommandActive(base)) { } + + /* No need to clear this command since future line commands will overwrite + * the line command field + */ +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_CodeCacheInvalidateMultiLines + * Description : This function invalidates multiple lines in the Processor Code bus cache. + * + * This function invalidates multiple lines in the cache. The function invalidates the + * lines in cache based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half the total amount of + * cache, then the function shall perform an entire cache invalidate function (which is + * more efficient than invalidating the cache line-by-line). + * The need to check half the total amount of cache is due to the fact that the cache consists of + * two ways and that line commands based on the physical address will search both ways. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + *END**************************************************************************/ +void LMEM_DRV_CodeCacheInvalidateMultiLines(uint32_t instance, uint32_t addr, uint32_t length) +{ + uint32_t endAddr = addr + length; + addr = addr & ~(LMEM_CACHE_LINE_SIZE - 1U); /* Align address to cache line size */ + + /* If the length exceeds 4KB, invalidate all */ + if (length >= 4096U) + { + LMEM_DRV_CodeCacheInvalidateAll(instance); + } + /* Else proceed with multi-line invalidate */ + else + { + while (addr < endAddr) + { + LMEM_DRV_CodeCacheInvalidateLine(instance, addr); + addr = addr + LMEM_CACHE_LINE_SIZE; + } + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_CodeCachePushLine + * Description : This function pushes a specific modified line in the Processor Code bus cache. + * + * This function pushes a specific modified line based on the physical address passed in + * by the user. + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * entry not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + *END**************************************************************************/ +void LMEM_DRV_CodeCachePushLine(uint32_t instance, uint32_t addr) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* Set the push by line command */ + LMEM_HAL_SetCodeCacheLineCommand(base, kCacheLinePush); + + /* Since we're using the physical address, both ways are searched */ + LMEM_HAL_SetCodeCachePhysicalAddr(base, addr); + + LMEM_HAL_InitiateCodeCacheLineCommand(base); + + /* Set the line command to use the physical address */ + LMEM_BWR_PCCLCR_LADSEL(base, 1U); + + /* Wait until the cache command completes */ + while (LMEM_HAL_IsCodeCacheLineCommandActive(base)) { } + + /* No need to clear this command since future line commands will overwrite + * the line command field + */ +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_CodeCachePushMultiLines + * Description : This function pushes multiple modified lines in the Processor Code bus cache. + * + * This function pushes multiple modified lines in the cache. The function pushes the + * lines in cache based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half the total amount of + * cache, then the function shall perform an entire cache push function (which is + * more efficient than pushing the modified lines in the cache line-by-line). + * The need to check half the total amount of cache is due to the fact that the cache consists of + * two ways and that line commands based on the physical address will search both ways. + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * entry not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + *END**************************************************************************/ +void LMEM_DRV_CodeCachePushMultiLines(uint32_t instance, uint32_t addr, uint32_t length) +{ + uint32_t endAddr = addr + length; + addr = addr & ~(LMEM_CACHE_LINE_SIZE - 1U); /* Align address to cache line size */ + + /* If the length exceeds 4KB, push all */ + if (length >= 4096U) + { + LMEM_DRV_CodeCachePushAll(instance); + } + /* Else proceed with multi-line push */ + else + { + while (addr < endAddr) + { + LMEM_DRV_CodeCachePushLine(instance, addr); + addr = addr + LMEM_CACHE_LINE_SIZE; + } + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_CodeCacheClearLine + * Description : This function clears a specific line in the Processor Code bus cache. + * + * This function clears a specific line based on the physical address passed in + * by the user. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + *END**************************************************************************/ +void LMEM_DRV_CodeCacheClearLine(uint32_t instance, uint32_t addr) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* Set the clear by line command */ + LMEM_HAL_SetCodeCacheLineCommand(base, kCacheLineClear); + + /* Since we're using the physical address, both ways are searched */ + LMEM_HAL_SetCodeCachePhysicalAddr(base, addr); + + LMEM_HAL_InitiateCodeCacheLineCommand(base); + + /* Set the line command to use the physical address */ + LMEM_BWR_PCCLCR_LADSEL(base, 1U); + + /* Wait until the cache command completes */ + while (LMEM_HAL_IsCodeCacheLineCommandActive(base)) { } + + /* No need to clear this command since future line commands will overwrite + * the line command field + */ +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_CodeCacheClearMultiLines + * Description : This function clears multiple lines in the Processor Code bus cache. + * + * This function clears multiple lines in the cache. The function clears the + * lines in cache based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half the total amount of + * cache, then the function shall perform an entire cache clear function (which is + * more efficient than clearing the lines in the cache line-by-line). + * The need to check half the total amount of cache is due to the fact that the cache consists of + * two ways and that line commands based on the physical address will search both ways. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + *END**************************************************************************/ +void LMEM_DRV_CodeCacheClearMultiLines(uint32_t instance, uint32_t addr, uint32_t length) +{ + uint32_t endAddr = addr + length; + addr = addr & ~(LMEM_CACHE_LINE_SIZE - 1U); /* Align address to cache line size */ + + /* If the length exceeds 4KB, clear all */ + if (length >= 4096U) + { + LMEM_DRV_CodeCacheClearAll(instance); + } + /* Else proceed with multi-line clear */ + else + { + while (addr < endAddr) + { + LMEM_DRV_CodeCacheClearLine(instance, addr); + addr = addr + LMEM_CACHE_LINE_SIZE; + } + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_CodeCacheDemoteRegion + * Description : This function demotes the cache mode of a region in Processor Code bus cache. + * + * This function allows the user to demote the cache mode of a region within the device's + * memory map. Demoting the cache mode reduces the cache function applied to a memory + * region from write-back to write-through to non-cacheable. The function checks to see + * if the requested cache mode is higher than or equal to the current cache mode, and if + * so, will return an error. After a region is demoted, its cache mode can only be raised + * by a reset, which returns it to its default state. + * To maintain cache coherency, changes to the cache mode should be completed while the + * address space being changed is not being accessed or the cache is disabled. Before a + * cache mode change, this function completes a cache clear all command to push and invalidate any + * cache entries that may have changed. + * + * @param region The desired region to demote of type lmem_cache_region_t + * @param cacheMode The new, demoted cache mode of type lmem_cache_mode_t + * + * @return kStatus_LMEM_CACHE_Success The cache clear operation was successful, or + * kStatus_LMEM_CACHE_Busy The cache is busy performing another operation + * kStatus_LMEM_CACHE_Error The requested cache mode is higher than or equal to the + * current cache mode + * + *END**************************************************************************/ +lmem_cache_status_t LMEM_DRV_CodeCacheDemoteRegion(uint32_t instance, lmem_cache_region_t region, + lmem_cache_mode_t cacheMode) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* If the current cache mode is higher than the requested mode, return error */ + if ((uint32_t)cacheMode >= LMEM_HAL_GetCodeCacheRegionMode(base, region)) + { + return kStatus_LMEM_CACHE_DemoteError; + } + /* Else, proceed to demote the region */ + else + { + LMEM_DRV_CodeCacheClearAll(instance); + LMEM_HAL_SetCodeCacheRegionMode(base, region, cacheMode); + return kStatus_LMEM_CACHE_Success; + } +} + +#if FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_SystemCacheInvalidateAll + * Description : This function invalidates the entire Processor System bus cache. + * + * This function invalidates the entire cache meaning that it invalidates both Ways. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + *END**************************************************************************/ +void LMEM_DRV_SystemCacheInvalidateAll(uint32_t instance) +{ + LMEM_Type *base = g_lmemBase[instance]; + + LMEM_HAL_SetSystemCacheInvalidateAllCmd(base, true); + LMEM_HAL_InitiateSystemCacheCommand(base); + + /* Wait until the cache command completes */ + while (LMEM_HAL_IsSystemCacheCommandActive(base)) { } + + /* As a precaution clear the bits to avoid inadvertently re-running this command */ + LMEM_HAL_SetSystemCacheInvalidateAllCmd(base, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_SystemCachePushAll + * Description : This function pushes all modified lines in the entire Processor System bus + * cache. + * + * This function pushes all modified lines in both Ways (the entire cache). + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * entry not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + *END**************************************************************************/ +void LMEM_DRV_SystemCachePushAll(uint32_t instance) +{ + LMEM_Type *base = g_lmemBase[instance]; + + LMEM_HAL_SetSystemCachePushAllCmd(base, true); + LMEM_HAL_InitiateSystemCacheCommand(base); + + /* Wait until the cache command completes */ + while (LMEM_HAL_IsSystemCacheCommandActive(base)) { } + + /* As a precaution clear the bits to avoid inadvertently re-running this command */ + LMEM_HAL_SetSystemCachePushAllCmd(base, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_SystemCacheClearAll + * Description : This function clears the entire Processor System bus cache. + * + * This function clears the entire cache, which is basically a push (flush) and + * invalidate operation. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + *END**************************************************************************/ +void LMEM_DRV_SystemCacheClearAll(uint32_t instance) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* Push and invalidate all */ + LMEM_HAL_SetSystemCachePushAllCmd(base, true); + LMEM_HAL_SetSystemCacheInvalidateAllCmd(base, true); + LMEM_HAL_InitiateSystemCacheCommand(base); + + /* Wait until the cache command completes */ + while (LMEM_HAL_IsSystemCacheCommandActive(base)) { } + + /* As a precaution clear the bits to avoid inadvertently re-running this command */ + LMEM_HAL_SetSystemCachePushAllCmd(base, false); + LMEM_HAL_SetSystemCacheInvalidateAllCmd(base, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_SystemCacheEnable + * Description : This function enables the Processor System bus cache. + * + * This function enables the cache. The function first invalidates the entire cache, + * then it enables both the cache and write buffer. + * + *END**************************************************************************/ +void LMEM_DRV_SystemCacheEnable(uint32_t instance) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* First, invalidate the entire cache */ + LMEM_DRV_SystemCacheInvalidateAll(instance); + + /* Now enable the cache */ + LMEM_HAL_SetSystemCacheEnableCmd(base, true); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_SystemCacheDisable + * Description : This function disables the Processor System bus cache. + * + * This function disables the cache and write buffer. + * + *END**************************************************************************/ +void LMEM_DRV_SystemCacheDisable(uint32_t instance) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* First, push any modified contents */ + LMEM_DRV_SystemCachePushAll(instance); + + /* Now disable the cache */ + LMEM_HAL_SetSystemCacheEnableCmd(base, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_SystemCacheInvalidateLine + * Description : This function invalidates a specific line in the Processor System bus cache. + * + * This function invalidates a specific line in the cache. The function invalidates a + * line in cache based on the physical address passed in by the user. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + *END**************************************************************************/ +void LMEM_DRV_SystemCacheInvalidateLine(uint32_t instance, uint32_t addr) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* Set the invalidate by line command */ + LMEM_HAL_SetSystemCacheLineCommand(base, kCacheLineInvalidate); + + /* Since we're using the physical address, both ways are searched */ + LMEM_HAL_SetSystemCachePhysicalAddr(base, addr); + + LMEM_HAL_InitiateSystemCacheLineCommand(base); + + /* Set the line command to use the physical address */ + LMEM_BWR_PSCLCR_LADSEL(base, 1U); + + /* Wait until the cache command completes */ + while (LMEM_HAL_IsSystemCacheLineCommandActive(base)) { } + + /* No need to clear this command since future line commands will overwrite + * the line command field + */ +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_SystemCacheInvalidateMultiLines + * Description : This function invalidates multiple lines in the Processor System bus cache. + * + * This function invalidates multiple lines in the cache. The function invalidates the + * lines in cache based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half the total amount of + * cache, then the function shall perform an entire cache invalidate function (which is + * more efficient than invalidating the cache line-by-line). + * The need to check half the total amount of cache is due to the fact that the cache consists of + * two ways and that line commands based on the physical address will search both ways. + * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * + *END**************************************************************************/ +void LMEM_DRV_SystemCacheInvalidateMultiLines(uint32_t instance, uint32_t addr, uint32_t length) +{ + LMEM_Type *base = g_lmemBase[instance]; + uint32_t endAddr = addr + length; + addr = addr & ~(LMEM_CACHE_LINE_SIZE - 1U); /* Align address to cache line size */ + + /* If the length exceeds 4KB, invalidate all */ + if (length >= 4096U) + { + LMEM_DRV_SystemCacheInvalidateAll(instance); + } + /* Else proceed with multi-line invalidate */ + else + { + while (addr < endAddr) + { + LMEM_DRV_SystemCacheInvalidateLine(instance, addr); + addr = addr + LMEM_CACHE_LINE_SIZE; + } + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_SystemCachePushLine + * Description : This function pushes a specific modified line in the Processor System bus + * cache. + * + * This function pushes a specific modified line based on the physical address passed in + * by the user. + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * entry not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + *END**************************************************************************/ +void LMEM_DRV_SystemCachePushLine(uint32_t instance, uint32_t addr) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* Set the push by line command */ + LMEM_HAL_SetSystemCacheLineCommand(base, kCacheLinePush); + + /* Since we're using the physical address, both ways are searched */ + LMEM_HAL_SetSystemCachePhysicalAddr(base, addr); + + LMEM_HAL_InitiateSystemCacheLineCommand(base); + + /* Set the line command to use the physical address */ + LMEM_BWR_PSCLCR_LADSEL(base, 1U); + + /* Wait until the cache command completes */ + while (LMEM_HAL_IsSystemCacheLineCommandActive(base)) { } + + /* No need to clear this command since future line commands will overwrite + * the line command field + */ +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_SystemCachePushMultiLines + * Description : This function pushes multiple modified lines in the Processor System bus cache. + * + * This function pushes multiple modified lines in the cache. The function pushes the + * lines in cache based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half the total amount of + * cache, then the function shall perform an entire cache push function (which is + * more efficient than pushing the modified lines in the cache line-by-line). + * The need to check half the total amount of cache is due to the fact that the cache consists of + * two ways and that line commands based on the physical address will search both ways. + * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If + * entry not valid or not modified, leave as is. This action does not clear the valid + * bit. A cache push is synonymous with a cache flush. + * + *END**************************************************************************/ +void LMEM_DRV_SystemCachePushMultiLines(uint32_t instance, uint32_t addr, uint32_t length) +{ + LMEM_Type *base = g_lmemBase[instance]; + uint32_t endAddr = addr + length; + addr = addr & ~(LMEM_CACHE_LINE_SIZE - 1U); /* Align address to cache line size */ + + /* If the length exceeds 4KB, push all */ + if (length >= 4096U) + { + LMEM_DRV_SystemCachePushAll(instance); + } + /* Else proceed with multi-line push */ + else + { + while (addr < endAddr) + { + LMEM_DRV_SystemCachePushLine(instance, addr); + addr = addr + LMEM_CACHE_LINE_SIZE; + } + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_SystemCacheClearLine + * Description : This function clears a specific line in the Processor System bus cache. + * + * This function clears a specific line based on the physical address passed in + * by the user. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + *END**************************************************************************/ +void LMEM_DRV_SystemCacheClearLine(uint32_t instance, uint32_t addr) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* Set the clear by line command */ + LMEM_HAL_SetSystemCacheLineCommand(base, kCacheLineClear); + + /* Since we're using the physical address, both ways are searched */ + LMEM_HAL_SetSystemCachePhysicalAddr(base, addr); + + LMEM_HAL_InitiateSystemCacheLineCommand(base); + + /* Set the line command to use the physical address */ + LMEM_BWR_PSCLCR_LADSEL(base, 1U); + + /* Wait until the cache command completes */ + while (LMEM_HAL_IsSystemCacheLineCommandActive(base)) { } + + /* No need to clear this command since future line commands will overwrite + * the line command field + */ +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_SystemCacheClearMultiLines + * Description : This function clears multiple lines in the Processor System bus cache. + * + * This function clears multiple lines in the cache. The function clears the + * lines in cache based on the physical address and length in bytes passed in by the + * user. If the function detects that the length meets or exceeds half the total amount of + * cache, then the function shall perform an entire cache clear function (which is + * more efficient than clearing the lines in the cache line-by-line). + * The need to check half the total amount of cache is due to the fact that the cache consists of + * two ways and that line commands based on the physical address will search both ways. + * Clear - Push a cache entry if it is valid and modified, then clear the valid and + * modify bits. If entry not valid or not modified, clear the valid bit. + * + *END**************************************************************************/ +void LMEM_DRV_SystemCacheClearMultiLines(uint32_t instance, uint32_t addr, uint32_t length) +{ + LMEM_Type *base = g_lmemBase[instance]; + uint32_t endAddr = addr + length; + addr = addr & ~(LMEM_CACHE_LINE_SIZE - 1U); /* Align address to cache line size */ + + /* If the length exceeds 4KB, clear all */ + if (length >= 4096U) + { + LMEM_DRV_SystemCacheClearAll(instance); + } + /* Else proceed with multi-line clear */ + else + { + while (addr < endAddr) + { + LMEM_DRV_SystemCacheClearLine(instance, addr); + addr = addr + LMEM_CACHE_LINE_SIZE; + } + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : LMEM_DRV_SystemCacheDemoteRegion + * Description : This function demotes the cache mode of a region in Processor System bus cache. + * + * This function allows the user to demote the cache mode of a region within the device's + * memory map. Demoting the cache mode reduces the cache function applied to a memory + * region from write-back to write-through to non-cacheable. The function checks to see + * if the requested cache mode is higher than or equal to the current cache mode, and if + * so, will return an error. After a region is demoted, its cache mode can only be raised + * by a reset, which returns it to its default state. + * To maintain cache coherency, changes to the cache mode should be completed while the + * address space being changed is not being accessed or the cache is disabled. Before a + * cache mode change, this function completes a cache clear all command to push and invalidate any + * cache entries that may have changed. + * + *END**************************************************************************/ +lmem_cache_status_t LMEM_DRV_SystemCacheDemoteRegion(uint32_t instance, lmem_cache_region_t region, + lmem_cache_mode_t cacheMode) +{ + LMEM_Type *base = g_lmemBase[instance]; + + /* If the current cache mode is higher than the requested mode, return error */ + if ((uint32_t)cacheMode >= LMEM_HAL_GetSystemCacheRegionMode(base, region)) + { + return kStatus_LMEM_CACHE_DemoteError; + } + /* Else, proceed to demote the region */ + else + { + LMEM_DRV_SystemCacheClearAll(instance); + LMEM_HAL_SetSystemCacheRegionMode(base, region, cacheMode); + return kStatus_LMEM_CACHE_Success; + } +} + +#endif /* #if FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE */ + +#endif /* FSL_FEATURE_SOC_LMEM_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/lmem/fsl_lmem_common.c b/KSDK_1.2.0/platform/drivers/src/lmem/fsl_lmem_common.c new file mode 100755 index 0000000..4a2d60c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lmem/fsl_lmem_common.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_LMEM_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for LMEM instances. */ +LMEM_Type * const g_lmemBase[LMEM_INSTANCE_COUNT] = LMEM_BASE_PTRS; + + +#endif /* FSL_FEATURE_SOC_LMEM_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_common.c b/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_common.c new file mode 100755 index 0000000..d6af030 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_common.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_LPSCI_COUNT +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to lpsci runtime state structure.*/ +void * g_lpsciStatePtr[UART0_INSTANCE_COUNT] = { NULL }; + +/* Table of base addresses for lpsci instances. */ +UART0_Type * const g_lpsciBase[UART0_INSTANCE_COUNT] = UART0_BASE_PTRS; + +/* Table to save UART0 IRQ numbers defined in CMSIS files. */ +/* FIX ME: this should be replaced when KL25 header file is ready. */ +IRQn_Type g_lpsciRxTxIrqId[UART0_INSTANCE_COUNT] = { UART0_IRQn }; + +#endif /* FSL_FEATURE_SOC_LPSCI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_dma_driver.c b/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_dma_driver.c new file mode 100755 index 0000000..f678683 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_dma_driver.c @@ -0,0 +1,673 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_lpsci_dma_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#include "fsl_dma_request.h" + +#if FSL_FEATURE_SOC_LPSCI_COUNT +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to lpsci runtime state structure */ +extern void * g_lpsciStatePtr[UART0_INSTANCE_COUNT]; + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static void LPSCI_DRV_DmaCompleteSendData(uint32_t instance); +static void LPSCI_DRV_DmaTxCallback(void *param, dma_channel_status_t status); +static lpsci_status_t LPSCI_DRV_DmaStartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +static void LPSCI_DRV_DmaCompleteReceiveData(uint32_t instance); +static void LPSCI_DRV_DmaRxCallback(void *param, dma_channel_status_t status); +static lpsci_status_t LPSCI_DRV_DmaStartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize); +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaInit + * Description : This function initializes a LPSCI instance for operation. + * This function will initialize the run-time state structure to keep track of + * the on-going transfers, ungate the clock to the LPSCI module, initialize the + * module to user defined settings and default settings, configure LPSCI DMA + * and enable the LPSCI module transmitter and receiver. + * The following is an example of how to set up the lpsci_dma_state_t and the + * lpsci_user_config_t parameters and how to call the LPSCI_DRV_DmaInit function + * by passing in these parameters: + * lpsci_user_config_t lpsciConfig; + * lpsciConfig.baudRate = 9600; + * lpsciConfig.bitCountPerChar = kLpsci8BitsPerChar; + * lpsciConfig.parityMode = kLpsciParityDisabled; + * lpsciConfig.stopBitCount = kLpsciOneStopBit; + * lpsci_dma_state_t lpsciDmaState; + * LPSCI_DRV_DmaInit(instance, &lpsciDmaState, &lpsciConfig); + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_DmaInit(uint32_t instance, + lpsci_dma_state_t * lpsciDmaStatePtr, + const lpsci_dma_user_config_t * lpsciUserConfig) +{ + assert(lpsciDmaStatePtr && lpsciUserConfig); + assert(instance < UART0_INSTANCE_COUNT); + + UART0_Type * base = g_lpsciBase[instance]; + uint32_t lpsciSourceClock = 0; + dma_request_source_t lpsciTxDmaRequest = kDmaRequestMux0Disable; + dma_request_source_t lpsciRxDmaRequest = kDmaRequestMux0Disable; + dma_channel_t *chn; + DMA_Type * dmaBase; + dma_channel_link_config_t config; + + config.channel1 = 0; + config.channel2 = 0; + config.linkType = kDmaChannelLinkDisable; + + /* Exit if current instance is already initialized. */ + if (g_lpsciStatePtr[instance]) + { + return kStatus_LPSCI_Initialized; + } + + /* Clear the state structure for this instance. */ + memset(lpsciDmaStatePtr, 0, sizeof(lpsci_dma_state_t)); + + /* Save runtime structure pointer.*/ + g_lpsciStatePtr[instance] = lpsciDmaStatePtr; + + /* Un-gate LPSCI module clock */ + CLOCK_SYS_EnableLpsciClock(instance); + + /* Set LPSCI clock source */ + CLOCK_SYS_SetLpsciSrc(instance, lpsciUserConfig->clockSource); + + /* Initialize LPSCI to a known state. */ + LPSCI_HAL_Init(base); + + /* Create Semaphore for txIrq and rxIrq. */ + OSA_SemaCreate(&lpsciDmaStatePtr->txIrqSync, 0); + OSA_SemaCreate(&lpsciDmaStatePtr->rxIrqSync, 0); + + /* LPSCI clock source is either system or bus clock depending on instance */ + lpsciSourceClock = CLOCK_SYS_GetLpsciFreq(instance); + + /* Initialize LPSCI baud rate, bit count, parity and stop bit. */ + LPSCI_HAL_SetBaudRate(base, lpsciSourceClock, lpsciUserConfig->baudRate); + LPSCI_HAL_SetBitCountPerChar(base, lpsciUserConfig->bitCountPerChar); + LPSCI_HAL_SetParityMode(base, lpsciUserConfig->parityMode); +#if FSL_FEATURE_LPSCI_HAS_STOP_BIT_CONFIG_SUPPORT + LPSCI_HAL_SetStopBitCount(base, lpsciUserConfig->stopBitCount); +#endif + + /* Enable DMA trigger when transmit data register empty, + * and receive data register full. */ + LPSCI_HAL_SetTxDmaCmd(base, true); + LPSCI_HAL_SetRxDmaCmd(base, true); + + switch (instance) + { + case 0: + lpsciRxDmaRequest = kDmaRequestMux0LPSCI0Rx; + lpsciTxDmaRequest = kDmaRequestMux0LPSCI0Tx; + break; + default : + break; + } + + /* Request DMA channels for RX FIFO. */ + DMA_DRV_RequestChannel(kDmaAnyChannel, lpsciRxDmaRequest, + &lpsciDmaStatePtr->dmaLpsciRx); + DMA_DRV_RegisterCallback(&lpsciDmaStatePtr->dmaLpsciRx, + LPSCI_DRV_DmaRxCallback, (void *)instance); + + chn = &lpsciDmaStatePtr->dmaLpsciRx; + dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + + DMA_HAL_SetAutoAlignCmd(dmaBase, chn->channel, false); + DMA_HAL_SetCycleStealCmd(dmaBase, chn->channel, true); + DMA_HAL_SetAsyncDmaRequestCmd(dmaBase, chn->channel, false); + DMA_HAL_SetDisableRequestAfterDoneCmd(dmaBase, chn->channel, true); + DMA_HAL_SetChanLink(dmaBase, chn->channel, &config); + + DMA_HAL_SetSourceAddr(dmaBase, chn->channel, LPSCI_HAL_GetDataRegAddr(base)); + DMA_HAL_SetSourceModulo(dmaBase, chn->channel, kDmaModuloDisable); + DMA_HAL_SetSourceTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); + DMA_HAL_SetSourceIncrementCmd(dmaBase, chn->channel, false); + + DMA_HAL_SetDestModulo(dmaBase, chn->channel, kDmaModuloDisable); + DMA_HAL_SetDestTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); + DMA_HAL_SetDestIncrementCmd(dmaBase, chn->channel, true); + + DMA_HAL_SetIntCmd(dmaBase, chn->channel, true); + + /* Request DMA channels for TX FIFO. */ + DMA_DRV_RequestChannel(kDmaAnyChannel, lpsciTxDmaRequest, + &lpsciDmaStatePtr->dmaLpsciTx); + DMA_DRV_RegisterCallback(&lpsciDmaStatePtr->dmaLpsciTx, + LPSCI_DRV_DmaTxCallback, (void *)instance); + + chn = &lpsciDmaStatePtr->dmaLpsciTx; + dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + + DMA_HAL_SetAutoAlignCmd(dmaBase, chn->channel, false); + DMA_HAL_SetCycleStealCmd(dmaBase, chn->channel, true); + DMA_HAL_SetAsyncDmaRequestCmd(dmaBase, chn->channel, false); + DMA_HAL_SetDisableRequestAfterDoneCmd(dmaBase, chn->channel, true); + DMA_HAL_SetChanLink(dmaBase, chn->channel, &config); + + DMA_HAL_SetSourceModulo(dmaBase, chn->channel, kDmaModuloDisable); + DMA_HAL_SetSourceTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); + DMA_HAL_SetSourceIncrementCmd(dmaBase, chn->channel, true); + + DMA_HAL_SetDestAddr(dmaBase, chn->channel, LPSCI_HAL_GetDataRegAddr(base)); + DMA_HAL_SetDestModulo(dmaBase, chn->channel, kDmaModuloDisable); + DMA_HAL_SetDestTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); + DMA_HAL_SetDestIncrementCmd(dmaBase, chn->channel, false); + + DMA_HAL_SetIntCmd(dmaBase, chn->channel, true); + + /* Finally, enable the LPSCI transmitter and receiver*/ + LPSCI_HAL_EnableTransmitter(base); + LPSCI_HAL_EnableReceiver(base); + + return kStatus_LPSCI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaDeinit + * Description : This function shuts down the LPSCI by disabling LPSCI DMA and + * the transmitter/receiver. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_DmaDeinit(uint32_t instance) +{ + assert(instance < UART0_INSTANCE_COUNT); + + /* Exit if current instance is already de-initialized or is gated.*/ + if ((!g_lpsciStatePtr[instance]) || (!CLOCK_SYS_GetLpsciGateCmd(instance))) + { + return kStatus_LPSCI_Fail; + } + + UART0_Type * base = g_lpsciBase[instance]; + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + + /* Wait until the data is completely shifted out of shift register */ + while(!(UART0_BRD_S1_TC(base))) { } + + LPSCI_HAL_SetTxDmaCmd(base, false); + LPSCI_HAL_SetRxDmaCmd(base, false); + + /* Release DMA channel. */ + DMA_DRV_FreeChannel(&lpsciDmaState->dmaLpsciRx); + DMA_DRV_FreeChannel(&lpsciDmaState->dmaLpsciTx); + + /* Disable TX and RX */ + LPSCI_HAL_DisableTransmitter(base); + LPSCI_HAL_DisableReceiver(base); + + /* Destroy TX and RX sema. */ + OSA_SemaDestroy(&lpsciDmaState->txIrqSync); + OSA_SemaDestroy(&lpsciDmaState->rxIrqSync); + + /* Cleared state pointer. */ + g_lpsciStatePtr[instance] = NULL; + + /* Gate LPSCI module clock */ + CLOCK_SYS_DisableLpsciClock(instance); + + return kStatus_LPSCI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaSendDataBlocking + * Description : Sends (transmits) data out through the LPSCI-DMA module + * using a blocking method. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_DmaSendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + assert(txBuff); + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + lpsci_status_t retVal = kStatus_LPSCI_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + lpsciDmaState->isTxBlocking = true; + + /* Start the transmission process */ + retVal = LPSCI_DRV_DmaStartSendData(instance, txBuff, txSize); + + if (retVal == kStatus_LPSCI_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&lpsciDmaState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&lpsciDmaState->dmaLpsciTx); + + /* Update the information of the module driver state */ + lpsciDmaState->isTxBusy = false; + + retVal = kStatus_LPSCI_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaSendData + * Description : This function sends (transmits) data through the LPSCI module + * using a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the transmit function. The application + * has to get the transmit status to see when the transmit is complete. In + * other words, after calling non-blocking (asynchronous) send function, the + * application must get the transmit status to check if transmit is completed + * or not. The asynchronous method of transmitting and receiving allows the LPSCI + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_DmaSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(txBuff); + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_status_t retVal = kStatus_LPSCI_Success; + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + + /* Indicates current transaction is non-blocking. */ + lpsciDmaState->isTxBlocking = false; + + /* Start the transmission process*/ + retVal = LPSCI_DRV_DmaStartSendData(instance, txBuff, txSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaGetTransmitStatus + * Description : This function returns whether the previous LPSCI transmit + * has finished. When performing an async transmit, the user can call this + * function to ascertain the state of the current transmission: in progress + * (or busy) or complete (success). In addition, if the transmission is still + * in progress, the user can obtain the number of words that have been + * currently transferred. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_DmaGetTransmitStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = DMA_DRV_GetUnfinishedBytes(&lpsciDmaState->dmaLpsciTx); + } + + return (lpsciDmaState->isTxBusy ? kStatus_LPSCI_TxBusy : kStatus_LPSCI_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaAbortSendingData + * Description : This function terminates an asynchronous LPSCI transmission + * early. During an async LPSCI transmission, the user has the option to + * terminate the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_DmaAbortSendingData(uint32_t instance) +{ + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!lpsciDmaState->isTxBusy) + { + return kStatus_LPSCI_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + LPSCI_DRV_DmaCompleteSendData(instance); + + return kStatus_LPSCI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaReceiveDataBlocking + * Description : This function gets (receives) data from the LPSCI module using + * a blocking method. A blocking (also known as synchronous) function means that + * the function does not return until the receive is complete. This blocking + * function is used to send data through the LPSCI port. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_DmaReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout) +{ + assert(rxBuff); + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + lpsci_status_t retVal = kStatus_LPSCI_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + lpsciDmaState->isRxBlocking = true; + + retVal = LPSCI_DRV_DmaStartReceiveData(instance, rxBuff, rxSize); + + if (retVal == kStatus_LPSCI_Success) + { + /* Wait until all the data is received or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&lpsciDmaState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&lpsciDmaState->dmaLpsciRx); + + /* Update the information of the module driver state */ + lpsciDmaState->isRxBusy = false; + + retVal = kStatus_LPSCI_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaReceiveData + * Description : This function gets (receives) data from the LPSCI module using + * a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. In other + * words, after calling non-blocking (asynchronous) get function, the + * application must get the receive status to check if receive is completed or + * not. The asynchronous method of transmitting and receiving allows the LPSCI + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_DmaReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(rxBuff); + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_status_t retVal = kStatus_LPSCI_Success; + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + + /* Indicates current transaction is non-blocking. */ + lpsciDmaState->isRxBlocking = false; + + retVal = LPSCI_DRV_DmaStartReceiveData(instance, rxBuff, rxSize); + + return retVal ; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaGetReceiveStatus + * Description : This function returns whether the previous LPSCI receive is + * complete. When performing an async receive, the user can call this function + * to ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, + * the user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_DmaGetReceiveStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < UART0_INSTANCE_COUNT); + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = DMA_DRV_GetUnfinishedBytes(&lpsciDmaState->dmaLpsciRx); + } + + return (lpsciDmaState->isRxBusy ? kStatus_LPSCI_RxBusy : kStatus_LPSCI_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaAbortReceivingData + * Description : This function shuts down the LPSCI by disabling interrupts and + * the transmitter/receiver. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_DmaAbortReceivingData(uint32_t instance) +{ + assert(instance < UART0_INSTANCE_COUNT); + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!lpsciDmaState->isRxBusy) + { + return kStatus_LPSCI_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + LPSCI_DRV_DmaCompleteReceiveData(instance); + + return kStatus_LPSCI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaCompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void LPSCI_DRV_DmaCompleteSendData(uint32_t instance) +{ + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&lpsciDmaState->dmaLpsciTx); + + /* Signal the synchronous completion object. */ + if (lpsciDmaState->isTxBlocking) + { + OSA_SemaPost(&lpsciDmaState->txIrqSync); + } + + /* Update the information of the module driver state */ + lpsciDmaState->isTxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaTxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void LPSCI_DRV_DmaTxCallback(void *param, dma_channel_status_t status) +{ + LPSCI_DRV_DmaCompleteSendData((uint32_t)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaStartSendData + * Description : This is not a public interface. + * + *END**************************************************************************/ +static lpsci_status_t LPSCI_DRV_DmaStartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(instance < UART0_INSTANCE_COUNT); + + /* Get current runtime structure. */ + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + dma_channel_t *chn = &lpsciDmaState->dmaLpsciTx; + DMA_Type * dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + + /* Check that we're not busy already transmitting data from a previous function call. */ + if (lpsciDmaState->isTxBusy) + { + return kStatus_LPSCI_TxBusy; + } + + /* Update LPSCI DMA run-time structure. */ + lpsciDmaState->isTxBusy = true; + + DMA_HAL_SetSourceAddr(dmaBase, chn->channel, (uint32_t)txBuff); + DMA_HAL_SetTransferCount(dmaBase, chn->channel, txSize); + + DMA_DRV_StartChannel(chn); + + return kStatus_LPSCI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaCompleteReceiveData + * Description : Finish up a receive by completing the process of receiving data + * and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void LPSCI_DRV_DmaCompleteReceiveData(uint32_t instance) +{ + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&lpsciDmaState->dmaLpsciRx); + + /* Signal the synchronous completion object. */ + if (lpsciDmaState->isRxBlocking) + { + OSA_SemaPost(&lpsciDmaState->rxIrqSync); + } + + /* Update the information of the module driver state */ + lpsciDmaState->isRxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaRxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void LPSCI_DRV_DmaRxCallback(void *param, dma_channel_status_t status) +{ + LPSCI_DRV_DmaCompleteReceiveData((uint32_t)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_DmaStartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static lpsci_status_t LPSCI_DRV_DmaStartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(instance < UART0_INSTANCE_COUNT); + + /* Get current runtime structure. */ + lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; + dma_channel_t *chn = &lpsciDmaState->dmaLpsciRx; + DMA_Type * dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + + /* Check that we're not busy already receiving data from a previous function call. */ + if (lpsciDmaState->isRxBusy) + { + return kStatus_LPSCI_RxBusy; + } + + /* Update LPSCI DMA run-time structure. */ + lpsciDmaState->isRxBusy = true; + + DMA_HAL_SetDestAddr(dmaBase, chn->channel, (uint32_t)rxBuff); + DMA_HAL_SetTransferCount(dmaBase, chn->channel, rxSize); + + DMA_DRV_StartChannel(chn); + + return kStatus_LPSCI_Success; +} + +#endif /* FSL_FEATURE_SOC_LPSCI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_driver.c b/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_driver.c new file mode 100755 index 0000000..e4b9653 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_driver.c @@ -0,0 +1,717 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_lpsci_driver.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_LPSCI_COUNT +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to lpsci runtime state structure */ +extern void * g_lpsciStatePtr[UART0_INSTANCE_COUNT]; + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static void LPSCI_DRV_CompleteSendData(uint32_t instance); +static lpsci_status_t LPSCI_DRV_StartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +static void LPSCI_DRV_CompleteReceiveData(uint32_t instance); +static lpsci_status_t LPSCI_DRV_StartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize); + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_Init + * Description : This function initializes a LPSCI instance for operation. + * This function will initialize the run-time state structure to keep track of + * the on-going transfers, ungate the clock to the LPSCI module, initialize the + * module to user defined settings and default settings, configure the IRQ state + * structure and enable the module-level interrupt to the core, and enable the + * LPSCI module transmitter and receiver. + * The following is an example of how to set up the lpsci_state_t and the + * lpsci_user_config_t parameters and how to call the LPSCI_DRV_Init function + * by passing in these parameters: + * lpsci_user_config_t lpsciConfig; + * lpsciConfig.clockSource = kClockLpsciSrcPllFllSel; + * lpsciConfig.baudRate = 9600; + * lpsciConfig.bitCountPerChar = kLpsci8BitsPerChar; + * lpsciConfig.parityMode = kLpsciParityDisabled; + * lpsciConfig.stopBitCount = kLpsciOneStopBit; + * lpsci_state_t lpsciState; + * LPSCI_DRV_Init(instance, &lpsciState, &lpsciConfig); + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_Init(uint32_t instance, + lpsci_state_t * lpsciStatePtr, + const lpsci_user_config_t * lpsciUserConfig) +{ + assert(lpsciStatePtr && lpsciUserConfig); + assert(instance < UART0_INSTANCE_COUNT); + + UART0_Type * base = g_lpsciBase[instance]; + uint32_t lpsciSourceClock; + + /* Exit if current instance is already initialized. */ + if (g_lpsciStatePtr[instance]) + { + return kStatus_LPSCI_Initialized; + } + + /* Clear the state structure for this instance. */ + memset(lpsciStatePtr, 0, sizeof(lpsci_state_t)); + + /* Save runtime structure pointer.*/ + g_lpsciStatePtr[instance] = lpsciStatePtr; + + /* Un-gate LPSCI module clock */ + CLOCK_SYS_EnableLpsciClock(instance); + + /* Set LPSCI clock source */ + CLOCK_SYS_SetLpsciSrc(instance, lpsciUserConfig->clockSource); + + /* Initialize LPSCI to a known state. */ + LPSCI_HAL_Init(base); + + /* Create Semaphore for txIrq and rxIrq. */ + OSA_SemaCreate(&lpsciStatePtr->txIrqSync, 0); + OSA_SemaCreate(&lpsciStatePtr->rxIrqSync, 0); + + lpsciSourceClock = CLOCK_SYS_GetLpsciFreq(instance); + + /* Initialize LPSCI baud rate, bit count, parity and stop bit. */ + LPSCI_HAL_SetBaudRate(base, lpsciSourceClock, lpsciUserConfig->baudRate); + LPSCI_HAL_SetBitCountPerChar(base, lpsciUserConfig->bitCountPerChar); + LPSCI_HAL_SetParityMode(base, lpsciUserConfig->parityMode); +#if FSL_FEATURE_LPSCI_HAS_STOP_BIT_CONFIG_SUPPORT + LPSCI_HAL_SetStopBitCount(base, lpsciUserConfig->stopBitCount); +#endif + + /* Enable LPSCI interrupt on NVIC level. */ + INT_SYS_EnableIRQ(g_lpsciRxTxIrqId[instance]); + + /* Finally, enable the LPSCI transmitter and receiver*/ + LPSCI_HAL_EnableTransmitter(base); + LPSCI_HAL_EnableReceiver(base); + + return kStatus_LPSCI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_Deinit + * Description : This function shuts down the LPSCI by disabling interrupts + * and the transmitter/receiver. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_Deinit(uint32_t instance) +{ + assert(instance < UART0_INSTANCE_COUNT); + + /* Exit if current instance is already de-initialized or is gated.*/ + if ((!g_lpsciStatePtr[instance]) || (!CLOCK_SYS_GetLpsciGateCmd(instance))) + { + return kStatus_LPSCI_Fail; + } + + UART0_Type * base = g_lpsciBase[instance]; + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + + /* Wait until the data is completely shifted out of shift register */ + while(!(UART0_BRD_S1_TC(base))) { } + + /* Disable the interrupt */ + INT_SYS_DisableIRQ(g_lpsciRxTxIrqId[instance]); + + /* Disable TX and RX */ + LPSCI_HAL_DisableTransmitter(base); + LPSCI_HAL_DisableReceiver(base); + + /* Destroy TX and RX sema. */ + OSA_SemaDestroy(&lpsciState->txIrqSync); + OSA_SemaDestroy(&lpsciState->rxIrqSync); + + /* Cleared state pointer. */ + g_lpsciStatePtr[instance] = NULL; + + /* Gate LPSCI module clock */ + CLOCK_SYS_DisableLpsciClock(instance); + + return kStatus_LPSCI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_InstallRxCallback + * Description : Install receive data callback function. + * + *END**************************************************************************/ +lpsci_rx_callback_t LPSCI_DRV_InstallRxCallback(uint32_t instance, + lpsci_rx_callback_t function, + uint8_t * rxBuff, + void * callbackParam, + bool alwaysEnableRxIrq) +{ + assert(instance < UART0_INSTANCE_COUNT); + UART0_Type * base = g_lpsciBase[instance]; + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + + lpsci_rx_callback_t currentCallback = lpsciState->rxCallback; + lpsciState->rxCallback = function; + lpsciState->rxCallbackParam = callbackParam; + lpsciState->rxBuff = rxBuff; + + /* Enable/Disable the receive data full interrupt */ + lpsciState->isRxBusy = true; + UART0_BWR_C2_RIE(base, alwaysEnableRxIrq); + + return currentCallback; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_InstallTxCallback + * Description : Install transmit data callback function, pass in NULL pointer + * as callback will uninstall. + * + *END**************************************************************************/ +lpsci_tx_callback_t LPSCI_DRV_InstallTxCallback(uint32_t instance, + lpsci_tx_callback_t function, + uint8_t * txBuff, + void * callbackParam) +{ + assert(instance < UART0_INSTANCE_COUNT); + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + + lpsci_tx_callback_t currentCallback = lpsciState->txCallback; + lpsciState->txCallback = function; + lpsciState->txCallbackParam = callbackParam; + lpsciState->txBuff = txBuff; + + return currentCallback; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_SendDataBlocking + * Description : This function sends data out through the LPSCI module using a + * blocking method. It does not return until the transmit is complete. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_SendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + assert(txBuff); + assert(instance < UART0_INSTANCE_COUNT); + + UART0_Type * base = g_lpsciBase[instance]; + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + lpsci_status_t retVal = kStatus_LPSCI_Success; + osa_status_t syncStatus; + + lpsciState->isTxBlocking = true; + + /* Start the transmission process */ + retVal = LPSCI_DRV_StartSendData(instance, txBuff, txSize); + + if (retVal == kStatus_LPSCI_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&lpsciState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable the transmitter data register empty interrupt */ + UART0_BWR_C2_TIE(base, 0U); + + /* Update the information of the module driver state */ + lpsciState->isTxBusy = false; + + retVal = kStatus_LPSCI_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_SendData + * Description : This function sends data through the LPSCI module using a + * non-blocking method. It returns immediately after initiating the transmit + * function. The application has to get the transmit status to see when the + * transmit is complete. In other words, after calling non-blocking send + * function, the application must get the transmit status to check if transmit + * is completed or not. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_SendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(txBuff); + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_status_t retVal = kStatus_LPSCI_Success; + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + + lpsciState->isTxBlocking = false; + + /* Start the transmission process*/ + retVal = LPSCI_DRV_StartSendData(instance, txBuff, txSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_GetTransmitStatus + * Description : This function returns whether the previous LPSCI transmit has + * finished. When performing a non-blocking transmit, the user can call this + * function to ascertain the state of current transmission: in progress (busy) + * or complete (success). In addition, if the transmission is still in progress, + * the user can obtain the number of words that left for transferring. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_GetTransmitStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + lpsci_status_t retVal = kStatus_LPSCI_Success; + uint32_t txSize = lpsciState->txSize; + + if (bytesRemaining) + { + *bytesRemaining = txSize; + } + + if (txSize) + { + retVal = kStatus_LPSCI_TxBusy; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_AbortSendingData + * Description : This function terminates a non-blocking transmission early. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_AbortSendingData(uint32_t instance) +{ + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!lpsciState->isTxBusy) + { + return kStatus_LPSCI_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + LPSCI_DRV_CompleteSendData(instance); + + return kStatus_LPSCI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_ReceiveDataBlocking + * Description : This function receives data from LPSCI using a blocking + * method. It does not return until the receive is complete. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_ReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout) +{ + assert(rxBuff); + assert(instance < UART0_INSTANCE_COUNT); + + UART0_Type * base = g_lpsciBase[instance]; + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + lpsci_status_t retVal = kStatus_LPSCI_Success; + osa_status_t syncStatus; + + lpsciState->isRxBlocking = true; + + retVal = LPSCI_DRV_StartReceiveData(instance, rxBuff, rxSize); + + if (retVal == kStatus_LPSCI_Success) + { + /* Wait until all the data is received or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&lpsciState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable the receive data full and overrun interrupt */ + UART0_BWR_C2_TIE(base, 0U); + LPSCI_HAL_SetIntMode(base, kLpsciIntRxOverrun, false); + + /* Update the information of the module driver state */ + lpsciState->isTxBusy = false; + + retVal = kStatus_LPSCI_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_ReceiveData + * Description : This function receives data from LPSCI using a non-blocking + * method. A non-blocking function means that the function returns immediately + * after initiating the receive function. The application has to get the + * receive status to see when the receive is complete. In other words, after + * calling non-blocking get function, the application must get the receive + * status to check if receive is completed or not. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_ReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(rxBuff); + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_status_t retVal = kStatus_LPSCI_Success; + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + + lpsciState->isRxBlocking = false; + + retVal = LPSCI_DRV_StartReceiveData(instance, rxBuff, rxSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_GetReceiveStatus + * Description : This function returns whether the previous LPSCI receive is + * complete. When performing a non-blocking receive, the user can call this + * function to ascertain the state of current progress: in progress (busy) + * or complete (success). In addition, if the receive is still in progress, + * the user can obtain the number of words that need to be received. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_GetReceiveStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < UART0_INSTANCE_COUNT); + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + lpsci_status_t retVal = kStatus_LPSCI_Success; + uint32_t rxSize = lpsciState->rxSize; + + if (bytesRemaining) + { + *bytesRemaining = rxSize; + } + + if (rxSize) + { + retVal = kStatus_LPSCI_RxBusy; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_AbortReceivingData + * Description : This function terminates a non-blocking receive early. + * + *END**************************************************************************/ +lpsci_status_t LPSCI_DRV_AbortReceivingData(uint32_t instance) +{ + assert(instance < UART0_INSTANCE_COUNT); + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!lpsciState->isRxBusy) + { + return kStatus_LPSCI_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + LPSCI_DRV_CompleteReceiveData(instance); + + return kStatus_LPSCI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_IRQHandler + * Description : Interrupt handler for LPSCI. + * This is not a public API as it is called whenever an interrupt occurs. + * + *END**************************************************************************/ +void LPSCI_DRV_IRQHandler(uint32_t instance) +{ + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + UART0_Type * base = g_lpsciBase[instance]; + + /* Exit the ISR if no transfer is happening for this instance. */ + if ((!lpsciState->isTxBusy) && (!lpsciState->isRxBusy)) + { + return; + } + + /* Handle Rx Data Register Full interrupt */ + if((UART0_BRD_C2_RIE(base)) && (UART0_BRD_S1_RDRF(base))) + { + /* Get data and put in receive buffer */ + LPSCI_HAL_Getchar(base, lpsciState->rxBuff); + + /* Invoke callback if there is one */ + if (lpsciState->rxCallback != NULL) + { + lpsciState->rxCallback(instance, lpsciState); + } + else + { + ++lpsciState->rxBuff; + --lpsciState->rxSize; + + /* Check and see if this was the last byte received */ + if (lpsciState->rxSize == 0) + { + LPSCI_DRV_CompleteReceiveData(instance); + } + } + } + + /* Handle Tx Data Register Empty interrupt */ + if((UART0_BRD_C2_TIE(base)) && (UART0_BRD_S1_TDRE(base))) + { + /* Check to see if there are any more bytes to send */ + if (lpsciState->txSize) + { + /* Transmit data and update tx size/buff. */ + LPSCI_HAL_Putchar(base, *(lpsciState->txBuff)); + + /* Invoke callback if there is one */ + if (lpsciState->txCallback != NULL) + { + /* The callback MUST set the txSize to 0 if the + * transmit is ended.*/ + lpsciState->txCallback(instance, lpsciState); + } + else + { + ++lpsciState->txBuff; + --lpsciState->txSize; + } + + /* Check and see if this was the last byte */ + if (lpsciState->txSize == 0) + { + /* Complete the transfer and disable the interrupt */ + LPSCI_DRV_CompleteSendData(instance); + } + } + } + + /* Handle receive overrun interrupt */ + if (LPSCI_HAL_GetStatusFlag(base, kLpsciRxOverrun)) + { + /* Clear the flag, OR the rxDataRegFull will not be set any more */ + LPSCI_HAL_ClearStatusFlag(base, kLpsciRxOverrun); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_CompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void LPSCI_DRV_CompleteSendData(uint32_t instance) +{ + assert(instance < UART0_INSTANCE_COUNT); + + UART0_Type * base = g_lpsciBase[instance]; + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + + /* Disable the transmitter data register empty interrupt */ + UART0_BWR_C2_TIE(base, 0U); + + /* Signal the synchronous completion object. */ + if (lpsciState->isTxBlocking) + { + OSA_SemaPost(&lpsciState->txIrqSync); + } + + /* Update the information of the module driver state */ + lpsciState->isTxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_StartSendData + * Description : Initiate a transmit by beginning the process of sending data + * and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static lpsci_status_t LPSCI_DRV_StartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(instance < UART0_INSTANCE_COUNT); + + UART0_Type * base = g_lpsciBase[instance]; + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + + /* Check that we're not busy sending data from a previous function call. */ + if (lpsciState->isTxBusy) + { + return kStatus_LPSCI_TxBusy; + } + + if (txSize == 0U) + { + return kStatus_LPSCI_NoDataToDeal; + } + + /* Initialize the module driver state structure. */ + lpsciState->txBuff = txBuff; + lpsciState->txSize = txSize; + lpsciState->isTxBusy = true; + + /* Enable the transmitter data register empty interrupt.*/ + UART0_BWR_C2_TIE(base, 1U); + + return kStatus_LPSCI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_CompleteReceiveData + * Description : Finish up a receive by completing the process of receiving data + * and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void LPSCI_DRV_CompleteReceiveData(uint32_t instance) +{ + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + UART0_Type * base = g_lpsciBase[instance]; + + /* Disable receive data full and overrun interrupt */ + UART0_BWR_C2_RIE(base, 0U); + LPSCI_HAL_SetIntMode(base, kLpsciIntRxOverrun, false); + + /* Signal the synchronous completion object. */ + if (lpsciState->isRxBlocking) + { + OSA_SemaPost(&lpsciState->rxIrqSync); + } + + /* Update the information of the module driver state */ + lpsciState->isRxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPSCI_DRV_StartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static lpsci_status_t LPSCI_DRV_StartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(instance < UART0_INSTANCE_COUNT); + + lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance]; + UART0_Type * base = g_lpsciBase[instance]; + + /* Check that we're not busy receiving data from a previous function call. */ + if ((lpsciState->isRxBusy) && (!lpsciState->rxCallback)) + { + return kStatus_LPSCI_RxBusy; + } + + if (rxSize == 0U) + { + return kStatus_LPSCI_NoDataToDeal; + } + + /* Initialize the module driver state structure. */ + lpsciState->rxBuff = rxBuff; + lpsciState->rxSize = rxSize; + lpsciState->isRxBusy = true; + + /* Enable the receive data overrun interrupt */ + LPSCI_HAL_SetIntMode(base, kLpsciIntRxOverrun, true); + + /* Enable the receive data full interrupt */ + UART0_BWR_C2_RIE(base, 1U); + + return kStatus_LPSCI_Success; +} + +#endif /* FSL_FEATURE_SOC_LPSCI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_irq.c b/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_irq.c new file mode 100755 index 0000000..eafa9f4 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_irq.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdint.h> + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +extern void LPSCI_DRV_IRQHandler(uint32_t instance); +/******************************************************************************* + * Code + ******************************************************************************/ + +/* Implementation of UART0 handler named in startup code. */ +void UART0_IRQHandler(void) +{ + LPSCI_DRV_IRQHandler(0); +} + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_lpm_callback.c new file mode 100755 index 0000000..ed3f376 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lpsci/fsl_lpsci_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t lpsci_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t lpsci_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/lptmr/fsl_lptmr_common.c b/KSDK_1.2.0/platform/drivers/src/lptmr/fsl_lptmr_common.c new file mode 100755 index 0000000..4325ff3 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lptmr/fsl_lptmr_common.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for LPTMR instances. */ +LPTMR_Type * const g_lptmrBase[] = LPTMR_BASE_PTRS; + +/*! @brief Table to save LPTMR IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_lptmrIrqId[] = LPTMR_IRQS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + + diff --git a/KSDK_1.2.0/platform/drivers/src/lptmr/fsl_lptmr_driver.c b/KSDK_1.2.0/platform/drivers/src/lptmr/fsl_lptmr_driver.c new file mode 100755 index 0000000..29892ca --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lptmr/fsl_lptmr_driver.c @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 <assert.h> +#include <string.h> +#include "fsl_lptmr_driver.h" +#include "fsl_interrupt_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_LPTMR_COUNT + +/******************************************************************************* + * Definitions + *******************************************************************************/ +/******************************************************************************* + * Variables + ******************************************************************************/ +static lptmr_state_t *volatile lptmr_state_ptrs[LPTMR_INSTANCE_COUNT]; + +/******************************************************************************* + * Code + *******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : LPTMR_DRV_Init + * Description : initializes the LPTMR driver. + * This function will initialize the LPTMR driver according to user configure + * strcuture. + * + *END**************************************************************************/ +lptmr_status_t LPTMR_DRV_Init(uint32_t instance, lptmr_state_t *userStatePtr, const lptmr_user_config_t* userConfigPtr) +{ + assert(instance < LPTMR_INSTANCE_COUNT); + + LPTMR_Type * base = g_lptmrBase[instance]; + lptmr_prescaler_user_config_t prescalerUserConfig; + lptmr_working_mode_user_config_t workingModeUserConfig; + + if ((!userConfigPtr) || (!userStatePtr)) + { + return kStatus_LPTMR_NullArgument; + } + + /* prescaler value 0 is invalid while working as pulse counter */ + if ((kLptmrTimerModePulseCounter == userConfigPtr->timerMode) && + (true == userConfigPtr->prescalerEnable) && + (kLptmrPrescalerDivide2 == userConfigPtr->prescalerValue)) + { + return kStatus_LPTMR_InvalidPrescalerValue; + } + + /* Enable clock for lptmr */ + CLOCK_SYS_EnableLptmrClock(instance); + + /* Disable lptmr and reset lptmr logic */ + LPTMR_HAL_Disable(base); + + /* LPTMR prescaler configure */ + prescalerUserConfig.prescalerClockSelect = (lptmr_prescaler_clock_select_t)userConfigPtr->prescalerClockSource; + prescalerUserConfig.prescalerBypass = (uint8_t)(userConfigPtr->prescalerEnable == false); + prescalerUserConfig.prescalerValue = userConfigPtr->prescalerValue; + LPTMR_HAL_SetPrescalerMode(base, prescalerUserConfig); + + /* Working Mode configure */ + workingModeUserConfig.timerModeSelect = userConfigPtr->timerMode; + workingModeUserConfig.freeRunningEnable = userConfigPtr->freeRunningEnable; + workingModeUserConfig.pinPolarity = userConfigPtr->pinPolarity; + workingModeUserConfig.pinSelect = userConfigPtr->pinSelect; + LPTMR_HAL_SetTimerWorkingMode(base,workingModeUserConfig); + + /* Internal context */ + lptmr_state_ptrs[instance] = userStatePtr; + + userStatePtr->userCallbackFunc = NULL; + + /* LPTMR interrupt */ + if (userConfigPtr->isInterruptEnabled) + { + LPTMR_HAL_SetIntCmd(base,true); + INT_SYS_EnableIRQ(g_lptmrIrqId[instance]); + } + else + { + LPTMR_HAL_SetIntCmd(base,false); + INT_SYS_DisableIRQ(g_lptmrIrqId[instance]); + } + + /* Caculate prescaler clock frequency */ + if ( kLptmrTimerModeTimeCounter == userConfigPtr->timerMode) + { + userStatePtr->prescalerClockHz = CLOCK_SYS_GetLptmrFreq(instance, + userConfigPtr->prescalerClockSource); + + if (userConfigPtr->prescalerEnable) + { + userStatePtr->prescalerClockHz = (userStatePtr->prescalerClockHz >> ((uint32_t)(userConfigPtr->prescalerValue+1))); + } + } + + return kStatus_LPTMR_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPTMR_DRV_Deinit + * Description : Deinit the LPTMR driver. + * This function will deinit the LPTMR driver, disable LPTMR clock, + * and disable LPTMR interrupt. + * + *END**************************************************************************/ +lptmr_status_t LPTMR_DRV_Deinit(uint32_t instance) +{ + assert(instance < LPTMR_INSTANCE_COUNT); + assert(CLOCK_SYS_GetLptmrGateCmd(instance)); + + LPTMR_Type * base = g_lptmrBase[instance]; + + /* Turn off lptmr hal */ + LPTMR_HAL_Disable(base); + + /* Reset all register to reset value */ + LPTMR_HAL_Init(base); + + /* Disable the interrupt */ + INT_SYS_DisableIRQ(g_lptmrIrqId[instance]); + + /* Disable clock for lptmr */ + CLOCK_SYS_DisableLptmrClock(instance); + + /* Cleared state pointer */ + lptmr_state_ptrs[instance] = NULL; + + return kStatus_LPTMR_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPTMR_DRV_Start + * Description : Start LPTMR counter + * This function will start LPTMR internal counter to count the time or pulse + * + *END**************************************************************************/ +lptmr_status_t LPTMR_DRV_Start(uint32_t instance) +{ + assert(instance < LPTMR_INSTANCE_COUNT); + assert(CLOCK_SYS_GetLptmrGateCmd(instance)); + + LPTMR_Type * base = g_lptmrBase[instance]; + + LPTMR_HAL_Enable(base); + + return kStatus_LPTMR_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPTMR_DRV_Stop + * Description : Stop LPTMR counter + * This function will stop LPTMR internal counter + * + *END**************************************************************************/ +lptmr_status_t LPTMR_DRV_Stop(uint32_t instance) +{ + assert(instance < LPTMR_INSTANCE_COUNT); + assert(CLOCK_SYS_GetLptmrGateCmd(instance)); + + LPTMR_Type * base = g_lptmrBase[instance]; + + LPTMR_HAL_Disable(base); + + return kStatus_LPTMR_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPTMR_DRV_SetTimerPeriodUs + * Description : Set LPTMR timer counter period with unit microsecond + * This function is used to set LPTMR timer counter period with unit microsecond + * + *END**************************************************************************/ +lptmr_status_t LPTMR_DRV_SetTimerPeriodUs(uint32_t instance, uint32_t us) +{ + assert(instance < LPTMR_INSTANCE_COUNT); + assert(us > 0); + assert(CLOCK_SYS_GetLptmrGateCmd(instance)); + + LPTMR_Type * base = g_lptmrBase[instance]; + uint32_t tick_count; + + if (lptmr_state_ptrs[instance]->prescalerClockHz < 1000000U) + { + if (us < (1000000U/lptmr_state_ptrs[instance]->prescalerClockHz)) + { + return kStatus_LPTMR_TimerPeriodUsTooSmall; + } + else + { + tick_count = (us/(1000000U/lptmr_state_ptrs[instance]->prescalerClockHz)); + + /* CMR register is 16 Bits */ + if ( tick_count > 0xFFFFU ) + { + return kStatus_LPTMR_TimerPeriodUsTooLarge; + } + else + { + LPTMR_HAL_SetCompareValue(base,tick_count); + } + } + } + else + { + tick_count = (us*(lptmr_state_ptrs[instance]->prescalerClockHz/1000000U)); + + /* CMR register is 16 Bits */ + if ( tick_count > 0xFFFFU ) + { + return kStatus_LPTMR_TimerPeriodUsTooLarge; + } + else + { + LPTMR_HAL_SetCompareValue(base,tick_count); + } + } + + return kStatus_LPTMR_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPTMR_DRV_GetCurrentTimeUs + * Description : Get LPTMR current time with unit microsecond + * This function is used to get LPTMR current time with unit microsecond + * + *END**************************************************************************/ +uint32_t LPTMR_DRV_GetCurrentTimeUs(uint32_t instance) +{ + assert(instance < LPTMR_INSTANCE_COUNT); + assert(CLOCK_SYS_GetLptmrGateCmd(instance)); + + LPTMR_Type * base = g_lptmrBase[instance]; + + uint32_t us; + + if (lptmr_state_ptrs[instance]->prescalerClockHz < 1000000U) + { + us = LPTMR_HAL_GetCounterValue(base)*(1000000U/lptmr_state_ptrs[instance]->prescalerClockHz); + } + else + { + us = LPTMR_HAL_GetCounterValue(base)/(lptmr_state_ptrs[instance]->prescalerClockHz/1000000U); + } + + return us; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : LPTMR_DRV_SetPulsePeriodCount + * Description : Set the pulse period value while LPTMR working in pulse counter mode + * This function is used to set the pulse period value while LPTMR working in pulse counter mode + * + *END**************************************************************************/ +lptmr_status_t LPTMR_DRV_SetPulsePeriodCount(uint32_t instance, uint32_t pulsePeriodCount) +{ + assert(instance < LPTMR_INSTANCE_COUNT); + assert(pulsePeriodCount > 0); + assert(CLOCK_SYS_GetLptmrGateCmd(instance)); + + LPTMR_Type * base = g_lptmrBase[instance]; + + LPTMR_HAL_SetCompareValue(base, pulsePeriodCount); + + return kStatus_LPTMR_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPTMR_DRV_GetCurrentPulseCount + * Description : Get current pulse count captured in the pulse input pin + * This function is used to get current pulse count captured in the pulse input pin + * + *END**************************************************************************/ +uint32_t LPTMR_DRV_GetCurrentPulseCount(uint32_t instance) +{ + assert(instance < LPTMR_INSTANCE_COUNT); + assert(CLOCK_SYS_GetLptmrGateCmd(instance)); + + LPTMR_Type * base = g_lptmrBase[instance]; + uint32_t count; + + count = LPTMR_HAL_GetCounterValue(base); + + return count; +} + + +/*FUNCTION********************************************************************* + * + * Function Name : LPTMR_DRV_InstallCallback + * Description : Install the user-defined callback in LPTMR module. + * When an LPTMR interrupt request is served, the callback will be executed + * inside the ISR. + * + *END*************************************************************************/ +lptmr_status_t LPTMR_DRV_InstallCallback(uint32_t instance, lptmr_callback_t userCallback) +{ + assert(instance < LPTMR_INSTANCE_COUNT); + + assert (instance < LPTMR_INSTANCE_COUNT); + if (!lptmr_state_ptrs[instance]) + { + return kStatus_LPTMR_NotInitlialized; + } + /* Fill callback function into state structure. */ + lptmr_state_ptrs[instance]->userCallbackFunc = userCallback; + + return kStatus_LPTMR_Success; +} + + +/*FUNCTION********************************************************************* + * + * Function Name : LPTMR_DRV_IRQHandler + * Description : The driver-defined ISR in LPTMR module. + * It includes the process for interrupt mode defined by driver. Currently, it + * will be called inside the system-defined ISR. + * + *END*************************************************************************/ +void LPTMR_DRV_IRQHandler(uint32_t instance) +{ + assert(instance < LPTMR_INSTANCE_COUNT); + assert(CLOCK_SYS_GetLptmrGateCmd(instance)); + + LPTMR_Type * base = g_lptmrBase[instance]; + + /* Clear interrupt flag */ + LPTMR_HAL_ClearIntFlag(base); + + if (lptmr_state_ptrs[instance]) + { + if (lptmr_state_ptrs[instance]->userCallbackFunc) + { + /* Execute user-defined callback function. */ + (*(lptmr_state_ptrs[instance]->userCallbackFunc))(); + } + } +} +#endif +/******************************************************************************* + * EOF + *******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/lptmr/fsl_lptmr_irq.c b/KSDK_1.2.0/platform/drivers/src/lptmr/fsl_lptmr_irq.c new file mode 100755 index 0000000..bdb4ffc --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lptmr/fsl_lptmr_irq.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 -2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_lptmr_driver.h" +#if FSL_FEATURE_SOC_LPTMR_COUNT + +/****************************************************************************** + * Code + *****************************************************************************/ +/* LPTMR IRQ handler that would cover the same name's APIs in startup code */ +void LPTMR0_IRQHandler(void) +{ + LPTMR_DRV_IRQHandler(0U); +} +#endif + +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/lptmr/fsl_lptmr_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/lptmr/fsl_lptmr_lpm_callback.c new file mode 100755 index 0000000..3caec96 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lptmr/fsl_lptmr_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_LPTMR_COUNT + +power_manager_error_code_t lptmr_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t lptmr_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_common.c b/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_common.c new file mode 100755 index 0000000..e0f345c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_common.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_LPUART_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to lpuart runtime state structure.*/ +void * g_lpuartStatePtr[LPUART_INSTANCE_COUNT] = { NULL }; + +/* Table of base addresses for lpuart instances. */ +LPUART_Type * const g_lpuartBase[LPUART_INSTANCE_COUNT] = LPUART_BASE_PTRS; + +/* Table to save LPUART enum numbers defined in CMSIS files. */ +IRQn_Type g_lpuartRxTxIrqId[LPUART_INSTANCE_COUNT] = LPUART_RX_TX_IRQS; + +#endif /* FSL_FEATURE_SOC_LPUART_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_dma_driver.c b/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_dma_driver.c new file mode 100755 index 0000000..e473355 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_dma_driver.c @@ -0,0 +1,674 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_lpuart_dma_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#include "fsl_dma_request.h" + +#if FSL_FEATURE_SOC_LPUART_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to lpuart runtime state structure */ +extern void * g_lpuartStatePtr[LPUART_INSTANCE_COUNT]; + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static void LPUART_DRV_DmaCompleteSendData(uint32_t instance); +static void LPUART_DRV_DmaTxCallback(void *param, dma_channel_status_t status); +static lpuart_status_t LPUART_DRV_DmaStartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +static void LPUART_DRV_DmaCompleteReceiveData(uint32_t instance); +static void LPUART_DRV_DmaRxCallback(void *param, dma_channel_status_t status); +static lpuart_status_t LPUART_DRV_DmaStartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize); +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaInit + * Description : This function initializes a LPUART instance for operation. + * This function will initialize the run-time state structure to keep track of + * the on-going transfers, ungate the clock to the LPUART module, initialize the + * module to user defined settings and default settings, configure LPUART DMA + * and enable the LPUART module transmitter and receiver. + * The following is an example of how to set up the lpuart_dma_state_t and the + * lpuart_user_config_t parameters and how to call the LPUART_DRV_DmaInit function + * by passing in these parameters: + * lpuart_user_config_t lpuartConfig; + * lpuartConfig.baudRate = 9600; + * lpuartConfig.bitCountPerChar = kLpuart8BitsPerChar; + * lpuartConfig.parityMode = kLpuartParityDisabled; + * lpuartConfig.stopBitCount = kLpuartOneStopBit; + * lpuart_dma_state_t lpuartDmaState; + * LPUART_DRV_DmaInit(instance, &lpuartDmaState, &lpuartConfig); + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_DmaInit(uint32_t instance, + lpuart_dma_state_t * lpuartDmaStatePtr, + const lpuart_dma_user_config_t * lpuartUserConfig) +{ + assert(lpuartDmaStatePtr && lpuartUserConfig); + assert(instance < LPUART_INSTANCE_COUNT); + + LPUART_Type * base = g_lpuartBase[instance]; + uint32_t lpuartSourceClock = 0; + dma_request_source_t lpuartTxDmaRequest = kDmaRequestMux0Disable; + dma_request_source_t lpuartRxDmaRequest = kDmaRequestMux0Disable; + dma_channel_t *chn; + DMA_Type * dmaBase; + dma_channel_link_config_t config; + + config.channel1 = 0; + config.channel2 = 0; + config.linkType = kDmaChannelLinkDisable; + + /* Exit if current instance is already initialized. */ + if (g_lpuartStatePtr[instance]) + { + return kStatus_LPUART_Initialized; + } + + /* Clear the state structure for this instance. */ + memset(lpuartDmaStatePtr, 0, sizeof(lpuart_dma_state_t)); + + /* Save runtime structure pointer.*/ + g_lpuartStatePtr[instance] = lpuartDmaStatePtr; + + /* Un-gate LPUART module clock */ + CLOCK_SYS_EnableLpuartClock(instance); + + /* Set LPUART clock source */ + CLOCK_SYS_SetLpuartSrc(instance, lpuartUserConfig->clockSource); + + /* Initialize LPUART to a known state. */ + LPUART_HAL_Init(base); + + /* Create Semaphore for txIrq and rxIrq. */ + OSA_SemaCreate(&lpuartDmaStatePtr->txIrqSync, 0); + OSA_SemaCreate(&lpuartDmaStatePtr->rxIrqSync, 0); + + /* LPUART clock source is either system or bus clock depending on instance */ + lpuartSourceClock = CLOCK_SYS_GetLpuartFreq(instance); + + /* Initialize LPUART baud rate, bit count, parity and stop bit. */ + LPUART_HAL_SetBaudRate(base, lpuartSourceClock, lpuartUserConfig->baudRate); + LPUART_HAL_SetBitCountPerChar(base, lpuartUserConfig->bitCountPerChar); + LPUART_HAL_SetParityMode(base, lpuartUserConfig->parityMode); +#if FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT + LPUART_HAL_SetStopBitCount(base, lpuartUserConfig->stopBitCount); +#endif + + /* Enable DMA trigger when transmit data register empty, + * and receive data register full. */ + LPUART_HAL_SetTxDmaCmd(base, true); + LPUART_HAL_SetRxDmaCmd(base, true); + + switch (instance) + { + case 0: + lpuartRxDmaRequest = kDmaRequestMux0LPUART0Rx; + lpuartTxDmaRequest = kDmaRequestMux0LPUART0Tx; + break; + default : + break; + } + + /* Request DMA channels for RX FIFO. */ + DMA_DRV_RequestChannel(kDmaAnyChannel, lpuartRxDmaRequest, + &lpuartDmaStatePtr->dmaLpuartRx); + DMA_DRV_RegisterCallback(&lpuartDmaStatePtr->dmaLpuartRx, + LPUART_DRV_DmaRxCallback, (void *)instance); + + chn = &lpuartDmaStatePtr->dmaLpuartRx; + dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + + DMA_HAL_SetAutoAlignCmd(dmaBase, chn->channel, false); + DMA_HAL_SetCycleStealCmd(dmaBase, chn->channel, true); + DMA_HAL_SetAsyncDmaRequestCmd(dmaBase, chn->channel, false); + DMA_HAL_SetDisableRequestAfterDoneCmd(dmaBase, chn->channel, true); + DMA_HAL_SetChanLink(dmaBase, chn->channel, &config); + + DMA_HAL_SetSourceAddr(dmaBase, chn->channel, LPUART_HAL_GetDataRegAddr(base)); + DMA_HAL_SetSourceModulo(dmaBase, chn->channel, kDmaModuloDisable); + DMA_HAL_SetSourceTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); + DMA_HAL_SetSourceIncrementCmd(dmaBase, chn->channel, false); + + DMA_HAL_SetDestModulo(dmaBase, chn->channel, kDmaModuloDisable); + DMA_HAL_SetDestTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); + DMA_HAL_SetDestIncrementCmd(dmaBase, chn->channel, true); + + DMA_HAL_SetIntCmd(dmaBase, chn->channel, true); + + /* Request DMA channels for TX FIFO. */ + DMA_DRV_RequestChannel(kDmaAnyChannel, lpuartTxDmaRequest, + &lpuartDmaStatePtr->dmaLpuartTx); + DMA_DRV_RegisterCallback(&lpuartDmaStatePtr->dmaLpuartTx, + LPUART_DRV_DmaTxCallback, (void *)instance); + + chn = &lpuartDmaStatePtr->dmaLpuartTx; + dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + + DMA_HAL_SetAutoAlignCmd(dmaBase, chn->channel, false); + DMA_HAL_SetCycleStealCmd(dmaBase, chn->channel, true); + DMA_HAL_SetAsyncDmaRequestCmd(dmaBase, chn->channel, false); + DMA_HAL_SetDisableRequestAfterDoneCmd(dmaBase, chn->channel, true); + DMA_HAL_SetChanLink(dmaBase, chn->channel, &config); + + DMA_HAL_SetSourceModulo(dmaBase, chn->channel, kDmaModuloDisable); + DMA_HAL_SetSourceTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); + DMA_HAL_SetSourceIncrementCmd(dmaBase, chn->channel, true); + + DMA_HAL_SetDestAddr(dmaBase, chn->channel, LPUART_HAL_GetDataRegAddr(base)); + DMA_HAL_SetDestModulo(dmaBase, chn->channel, kDmaModuloDisable); + DMA_HAL_SetDestTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); + DMA_HAL_SetDestIncrementCmd(dmaBase, chn->channel, false); + + DMA_HAL_SetIntCmd(dmaBase, chn->channel, true); + + /* Finally, enable the LPUART transmitter and receiver*/ + LPUART_HAL_SetTransmitterCmd(base, true); + LPUART_HAL_SetReceiverCmd(base, true); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaDeinit + * Description : This function shuts down the LPUART by disabling LPUART DMA and + * the transmitter/receiver. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_DmaDeinit(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + /* Exit if current instance is already de-initialized or is gated.*/ + if ((!g_lpuartStatePtr[instance]) || (!CLOCK_SYS_GetLpuartGateCmd(instance))) + { + return kStatus_LPUART_Fail; + } + + LPUART_Type * base = g_lpuartBase[instance]; + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + + /* Wait until the data is completely shifted out of shift register */ + while(!(LPUART_BRD_STAT_TC(base))) { } + + LPUART_HAL_SetTxDmaCmd(base, false); + LPUART_HAL_SetRxDmaCmd(base, false); + + /* Release DMA channel. */ + DMA_DRV_FreeChannel(&lpuartDmaState->dmaLpuartRx); + DMA_DRV_FreeChannel(&lpuartDmaState->dmaLpuartTx); + + /* Disable TX and RX */ + LPUART_HAL_SetTransmitterCmd(base, false); + LPUART_HAL_SetReceiverCmd(base, false); + + /* Destroy TX and RX sema. */ + OSA_SemaDestroy(&lpuartDmaState->txIrqSync); + OSA_SemaDestroy(&lpuartDmaState->rxIrqSync); + + /* Cleared state pointer. */ + g_lpuartStatePtr[instance] = NULL; + + /* Gate LPUART module clock */ + CLOCK_SYS_DisableLpuartClock(instance); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaSendDataBlocking + * Description : Sends (transmits) data out through the LPUART-DMA module + * using a blocking method. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_DmaSendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + assert(txBuff); + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + lpuart_status_t retVal = kStatus_LPUART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + lpuartDmaState->isTxBlocking = true; + + /* Start the transmission process */ + retVal = LPUART_DRV_DmaStartSendData(instance, txBuff, txSize); + + if (retVal == kStatus_LPUART_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&lpuartDmaState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&lpuartDmaState->dmaLpuartTx); + + /* Update the information of the module driver state */ + lpuartDmaState->isTxBusy = false; + + retVal = kStatus_LPUART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaSendData + * Description : This function sends (transmits) data through the LPUART module + * using a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the transmit function. The application + * has to get the transmit status to see when the transmit is complete. In + * other words, after calling non-blocking (asynchronous) send function, the + * application must get the transmit status to check if transmit is completed + * or not. The asynchronous method of transmitting and receiving allows the LPUART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_DmaSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(txBuff); + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_status_t retVal = kStatus_LPUART_Success; + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + + /* Indicates current transaction is non-blocking. */ + lpuartDmaState->isTxBlocking = false; + + /* Start the transmission process*/ + retVal = LPUART_DRV_DmaStartSendData(instance, txBuff, txSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaGetTransmitStatus + * Description : This function returns whether the previous LPUART transmit + * has finished. When performing an async transmit, the user can call this + * function to ascertain the state of the current transmission: in progress + * (or busy) or complete (success). In addition, if the transmission is still + * in progress, the user can obtain the number of words that have been + * currently transferred. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_DmaGetTransmitStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = DMA_DRV_GetUnfinishedBytes(&lpuartDmaState->dmaLpuartTx); + } + + return (lpuartDmaState->isTxBusy ? kStatus_LPUART_TxBusy : kStatus_LPUART_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaAbortSendingData + * Description : This function terminates an asynchronous LPUART transmission + * early. During an async LPUART transmission, the user has the option to + * terminate the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_DmaAbortSendingData(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!lpuartDmaState->isTxBusy) + { + return kStatus_LPUART_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + LPUART_DRV_DmaCompleteSendData(instance); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaReceiveDataBlocking + * Description : This function gets (receives) data from the LPUART module using + * a blocking method. A blocking (also known as synchronous) function means that + * the function does not return until the receive is complete. This blocking + * function is used to send data through the LPUART port. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_DmaReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout) +{ + assert(rxBuff); + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + lpuart_status_t retVal = kStatus_LPUART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + lpuartDmaState->isRxBlocking = true; + + retVal = LPUART_DRV_DmaStartReceiveData(instance, rxBuff, rxSize); + + if (retVal == kStatus_LPUART_Success) + { + /* Wait until all the data is received or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&lpuartDmaState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&lpuartDmaState->dmaLpuartRx); + + /* Update the information of the module driver state */ + lpuartDmaState->isRxBusy = false; + + retVal = kStatus_LPUART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaReceiveData + * Description : This function gets (receives) data from the LPUART module using + * a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. In other + * words, after calling non-blocking (asynchronous) get function, the + * application must get the receive status to check if receive is completed or + * not. The asynchronous method of transmitting and receiving allows the LPUART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_DmaReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(rxBuff); + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_status_t retVal = kStatus_LPUART_Success; + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + + /* Indicates current transaction is non-blocking. */ + lpuartDmaState->isRxBlocking = false; + + retVal = LPUART_DRV_DmaStartReceiveData(instance, rxBuff, rxSize); + + return retVal ; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaGetReceiveStatus + * Description : This function returns whether the previous LPUART receive is + * complete. When performing an async receive, the user can call this function + * to ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, + * the user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_DmaGetReceiveStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < LPUART_INSTANCE_COUNT); + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = DMA_DRV_GetUnfinishedBytes(&lpuartDmaState->dmaLpuartRx); + } + + return (lpuartDmaState->isRxBusy ? kStatus_LPUART_RxBusy : kStatus_LPUART_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaAbortReceivingData + * Description : This function shuts down the LPUART by disabling interrupts and + * the transmitter/receiver. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_DmaAbortReceivingData(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!lpuartDmaState->isRxBusy) + { + return kStatus_LPUART_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + LPUART_DRV_DmaCompleteReceiveData(instance); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaCompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void LPUART_DRV_DmaCompleteSendData(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&lpuartDmaState->dmaLpuartTx); + + /* Signal the synchronous completion object. */ + if (lpuartDmaState->isTxBlocking) + { + OSA_SemaPost(&lpuartDmaState->txIrqSync); + } + + /* Update the information of the module driver state */ + lpuartDmaState->isTxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaTxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void LPUART_DRV_DmaTxCallback(void *param, dma_channel_status_t status) +{ + LPUART_DRV_DmaCompleteSendData((uint32_t)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaStartSendData + * Description : This is not a public interface. + * + *END**************************************************************************/ +static lpuart_status_t LPUART_DRV_DmaStartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + /* Get current runtime structure. */ + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + dma_channel_t *chn = &lpuartDmaState->dmaLpuartTx; + DMA_Type * dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + + /* Check that we're not busy already transmitting data from a previous function call. */ + if (lpuartDmaState->isTxBusy) + { + return kStatus_LPUART_TxBusy; + } + + /* Update LPUART DMA run-time structure. */ + lpuartDmaState->isTxBusy = true; + + DMA_HAL_SetSourceAddr(dmaBase, chn->channel, (uint32_t)txBuff); + DMA_HAL_SetTransferCount(dmaBase, chn->channel, txSize); + + DMA_DRV_StartChannel(chn); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaCompleteReceiveData + * Description : Finish up a receive by completing the process of receiving data + * and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void LPUART_DRV_DmaCompleteReceiveData(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&lpuartDmaState->dmaLpuartRx); + + /* Signal the synchronous completion object. */ + if (lpuartDmaState->isRxBlocking) + { + OSA_SemaPost(&lpuartDmaState->rxIrqSync); + } + + /* Update the information of the module driver state */ + lpuartDmaState->isRxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaRxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void LPUART_DRV_DmaRxCallback(void *param, dma_channel_status_t status) +{ + LPUART_DRV_DmaCompleteReceiveData((uint32_t)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_DmaStartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static lpuart_status_t LPUART_DRV_DmaStartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + /* Get current runtime structure. */ + lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; + dma_channel_t *chn = &lpuartDmaState->dmaLpuartRx; + DMA_Type * dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + + /* Check that we're not busy already receiving data from a previous function call. */ + if (lpuartDmaState->isRxBusy) + { + return kStatus_LPUART_RxBusy; + } + + /* Update LPUART DMA run-time structure. */ + lpuartDmaState->isRxBusy = true; + + DMA_HAL_SetDestAddr(dmaBase, chn->channel, (uint32_t)rxBuff); + DMA_HAL_SetTransferCount(dmaBase, chn->channel, rxSize); + + DMA_DRV_StartChannel(chn); + + return kStatus_LPUART_Success; +} + +#endif /* FSL_FEATURE_SOC_LPUART_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_driver.c b/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_driver.c new file mode 100755 index 0000000..6eba446 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_driver.c @@ -0,0 +1,724 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_lpuart_driver.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_LPUART_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to lpuart runtime state structure */ +extern void * g_lpuartStatePtr[LPUART_INSTANCE_COUNT]; + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static lpuart_status_t LPUART_DRV_StartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +static void LPUART_DRV_CompleteSendData(uint32_t instance); +static lpuart_status_t LPUART_DRV_StartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize); +static void LPUART_DRV_CompleteReceiveData(uint32_t instance); +/******************************************************************************* + * Code + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_Init + * Description : This function initializes a LPUART instance for operation. + * This function will initialize the run-time state structure to keep track of + * the on-going transfers, ungate the clock to the LPUART module, initialize the + * module to user defined settings and default settings, configure the IRQ state + * structure and enable the module-level interrupt to the core, and enable the + * LPUART module transmitter and receiver. + * The following is an example of how to set up the lpuart_state_t and the + * lpuart_user_config_t parameters and how to call the LPUART_DRV_Init function + * by passing in these parameters: + * lpuart_user_config_t lpuartConfig; + * lpuartConfig.clockSource = kClockLpuartSrcPllFllSel; + * lpuartConfig.baudRate = 9600; + * lpuartConfig.bitCountPerChar = klpuart8BitsPerChar; + * lpuartConfig.parityMode = klpuartParityDisabled; + * lpuartConfig.stopBitCount = klpuartOneStopBit; + * lpuart_state_t lpuartState; + * LPUART_DRV_Init(instance, &lpuartState, &lpuartConfig); + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_Init(uint32_t instance, lpuart_state_t * lpuartStatePtr, + const lpuart_user_config_t * lpuartUserConfig) +{ + assert(lpuartStatePtr && lpuartUserConfig); + assert(instance < LPUART_INSTANCE_COUNT); + + uint32_t lpuartSourceClock; + LPUART_Type * base = g_lpuartBase[instance]; + + /* Exit if current instance is already initialized. */ + if (g_lpuartStatePtr[instance]) + { + return kStatus_LPUART_Initialized; + } + + /* Clear the state struct for this instance. */ + memset(lpuartStatePtr, 0, sizeof(lpuart_state_t)); + + /* Save runtime structure pointer.*/ + g_lpuartStatePtr[instance] = lpuartStatePtr; + + /* Set LPUART clock source */ + CLOCK_SYS_SetLpuartSrc(instance, lpuartUserConfig->clockSource); + + /* ungate lpuart module clock */ + CLOCK_SYS_EnableLpuartClock(instance); + + /* initialize the LPUART instance */ + LPUART_HAL_Init(base); + + /* Init the interrupt sync object. */ + OSA_SemaCreate(&lpuartStatePtr->txIrqSync, 0); + OSA_SemaCreate(&lpuartStatePtr->rxIrqSync, 0); + + /* LPUART clock source is either system clock or bus clock depending on the instance */ + lpuartSourceClock = CLOCK_SYS_GetLpuartFreq(instance); + + /* initialize the parameters of the LPUART config structure with desired data */ + LPUART_HAL_SetBaudRate(base, lpuartSourceClock, lpuartUserConfig->baudRate); + LPUART_HAL_SetBitCountPerChar(base, lpuartUserConfig->bitCountPerChar); + LPUART_HAL_SetParityMode(base, lpuartUserConfig->parityMode); + LPUART_HAL_SetStopBitCount(base, lpuartUserConfig->stopBitCount); + + /* finally, enable the LPUART transmitter and receiver */ + LPUART_HAL_SetTransmitterCmd(base, true); + LPUART_HAL_SetReceiverCmd(base, true); + + /* Enable LPUART interrupt. */ + INT_SYS_EnableIRQ(g_lpuartRxTxIrqId[instance]); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_Deinit + * Description : This function shuts down the UART by disabling interrupts and + * transmitter/receiver. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_Deinit(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + /* Exit if current instance is already de-initialized or is gated.*/ + if ((!g_lpuartStatePtr[instance]) || (!CLOCK_SYS_GetLpuartGateCmd(instance))) + { + return kStatus_LPUART_Fail; + } + + LPUART_Type * base = g_lpuartBase[instance]; + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + + /* Wait until the data is completely shifted out of shift register */ + while (!LPUART_BRD_STAT_TC(base)) {} + + /* Disable LPUART interrupt. */ + INT_SYS_DisableIRQ(g_lpuartRxTxIrqId[instance]); + + /* disable tx and rx */ + LPUART_HAL_SetTransmitterCmd(base, false); + LPUART_HAL_SetReceiverCmd(base, false); + + /* Destroy TX and RX sema. */ + OSA_SemaDestroy(&lpuartState->txIrqSync); + OSA_SemaDestroy(&lpuartState->rxIrqSync); + + /* Clear our saved pointer to the state structure */ + g_lpuartStatePtr[instance] = NULL; + + /* gate lpuart module clock */ + CLOCK_SYS_DisableLpuartClock(instance); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_InstallRxCallback + * Description : Install receive data callback function. + * + *END**************************************************************************/ +lpuart_rx_callback_t LPUART_DRV_InstallRxCallback(uint32_t instance, + lpuart_rx_callback_t function, + uint8_t * rxBuff, + void * callbackParam, + bool alwaysEnableRxIrq) +{ + assert(instance < LPUART_INSTANCE_COUNT); + LPUART_Type * base = g_lpuartBase[instance]; + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + + lpuart_rx_callback_t currentCallback = lpuartState->rxCallback; + lpuartState->rxCallback = function; + lpuartState->rxCallbackParam = callbackParam; + lpuartState->rxBuff = rxBuff; + + /* Enable/Disable the receive data full interrupt */ + lpuartState->isRxBusy = true; + LPUART_BWR_CTRL_RIE(base, alwaysEnableRxIrq); + + return currentCallback; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_InstallTxCallback + * Description : Install transmit data callback function, pass in NULL pointer + * as callback will uninstall. + * + *END**************************************************************************/ +lpuart_tx_callback_t LPUART_DRV_InstallTxCallback(uint32_t instance, + lpuart_tx_callback_t function, + uint8_t * txBuff, + void * callbackParam) +{ + assert(instance < LPUART_INSTANCE_COUNT); + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + + lpuart_tx_callback_t currentCallback = lpuartState->txCallback; + lpuartState->txCallback = function; + lpuartState->txCallbackParam = callbackParam; + lpuartState->txBuff = txBuff; + + return currentCallback; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_SendDataBlocking + * Description : This function sends data out through the LPUART module using + * blocking method. The function does not return until the transmit is complete. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_SendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + assert(txBuff); + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + LPUART_Type * base = g_lpuartBase[instance]; + lpuart_status_t retVal = kStatus_LPUART_Success; + osa_status_t syncStatus; + + /* Indicates this is a blocking transaction. */ + lpuartState->isTxBlocking = true; + + /* Start the transmission process */ + retVal = LPUART_DRV_StartSendData(instance, txBuff, txSize); + + if (retVal == kStatus_LPUART_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&lpuartState->txIrqSync, timeout); + } while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable transmission complete interrupt */ + LPUART_BWR_CTRL_TIE(base, 0U); + + /* Update the information of the module driver state */ + lpuartState->isTxBusy = false; + + retVal = kStatus_LPUART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_StartSendData + * Description : This function sends data out through the LPUART module using + * non-blocking method. The function will return immediately after calling this + * function. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_SendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(txBuff); + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_status_t retVal = kStatus_LPUART_Success; + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + + /* Indicates this is a non-blocking transaction. */ + lpuartState->isTxBlocking = false; + + /* Start the transmission process */ + retVal = LPUART_DRV_StartSendData(instance, txBuff, txSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_GetTransmitStatus + * Description : This function returns whether the previous LPUART transmit has + * finished. When performing non-blocking transmit, the user can call this + * function to ascertain the state of the current transmission: + * in progress (or busy) or complete (success). In addition, if the transmission + * is still in progress, the user can obtain the number of words that have been + * currently transferred. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_GetTransmitStatus(uint32_t instance, uint32_t * bytesRemaining) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + lpuart_status_t retVal = kStatus_LPUART_Success; + uint32_t txSize = lpuartState->txSize; + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = txSize; + } + + if (txSize) + { + retVal = kStatus_LPUART_TxBusy; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_AbortSendingData + * Description : This function terminates an non-blocking LPUART transmission + * early. During a non-blocking LPUART transmission, the user has the option to + * terminate the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_AbortSendingData(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!lpuartState->isTxBusy) + { + return kStatus_LPUART_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + LPUART_DRV_CompleteSendData(instance); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_ReceiveDataBlocking + * Description : This function receives data from LPUART module using blocking + * method, the function does not return until the receive is complete. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_ReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout) +{ + assert(rxBuff); + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + LPUART_Type * base = g_lpuartBase[instance]; + lpuart_status_t retVal = kStatus_LPUART_Success; + osa_status_t syncStatus; + + /* Indicates this is a blocking transaction. */ + lpuartState->isRxBlocking = true; + + retVal = LPUART_DRV_StartReceiveData(instance, rxBuff, rxSize); + + if (retVal == kStatus_LPUART_Success) + { + /* Wait until the receive is complete. */ + do + { + syncStatus = OSA_SemaWait(&lpuartState->rxIrqSync, timeout); + } while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable receive data full and rx overrun interrupt. */ + LPUART_BWR_CTRL_RIE(base, 0U); + LPUART_HAL_SetIntMode(base, kLpuartIntRxOverrun, false); + + /* Update the information of the module driver state */ + lpuartState->isRxBusy = false; + + retVal = kStatus_LPUART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_ReceiveData + * Description : This function receives data from LPUART module using + * non-blocking method. This function returns immediately after initiating the + * receive function. The application has to get the receive status to see when + * the receive is complete. In other words, after calling non-blocking get + * function, the application must get the receive status to check if receive + * is completed or not. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_ReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(rxBuff); + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_status_t retVal = kStatus_LPUART_Success; + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + + /* Indicates this is a non-blocking transaction. */ + lpuartState->isRxBlocking = false; + + retVal = LPUART_DRV_StartReceiveData(instance, rxBuff, rxSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_GetReceiveStatus + * Description : This function returns whether the previous LPUART receive is + * complete. When performing a non-blocking receive, the user can call this + * function to ascertain the state of the current receive progress: in progress + * or complete. In addition, if the receive is still in progress, the user can + * obtain the number of words that have been currently received. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_GetReceiveStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + lpuart_status_t retVal = kStatus_LPUART_Success; + uint32_t rxSize = lpuartState->rxSize; + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = rxSize; + } + + if (rxSize) + { + retVal = kStatus_LPUART_RxBusy; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_AbortReceivingData + * Description : Terminates a non-blocking receive early. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_AbortReceivingData(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!lpuartState->isRxBusy) + { + return kStatus_LPUART_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + LPUART_DRV_CompleteReceiveData(instance); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_IRQHandler + * Description : Interrupt handler for LPUART. + * This handler uses the buffers stored in the lpuart_state_t structs to transfer + * data. This is not a public API as it is called by IRQ whenever an interrupt + * occurs. + * + *END**************************************************************************/ +void LPUART_DRV_IRQHandler(uint32_t instance) +{ + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + LPUART_Type * base = g_lpuartBase[instance]; + + /* Exit the ISR if no transfer is happening for this instance. */ + if ((!lpuartState->isTxBusy) && (!lpuartState->isRxBusy)) + { + return; + } + + /* Handle receive data full interrupt */ + if((LPUART_BRD_CTRL_RIE(base)) && (LPUART_BRD_STAT_RDRF(base))) + { + /* Get data and put in receive buffer */ + LPUART_HAL_Getchar(base, lpuartState->rxBuff); + + /* Invoke callback if there is one */ + if (lpuartState->rxCallback != NULL) + { + lpuartState->rxCallback(instance, lpuartState); + } + else + { + ++lpuartState->rxBuff; + --lpuartState->rxSize; + + /* Check and see if this was the last byte received */ + if (lpuartState->rxSize == 0) + { + LPUART_DRV_CompleteReceiveData(instance); + } + } + } + + /* Handle transmitter data register empty interrupt */ + if((LPUART_BRD_CTRL_TIE(base)) && (LPUART_BRD_STAT_TDRE(base))) + { + /* check to see if there are any more bytes to send */ + if (lpuartState->txSize) + { + /* Transmit the data */ + LPUART_HAL_Putchar(base, *(lpuartState->txBuff)); + + /* Invoke callback if there is one */ + if (lpuartState->txCallback != NULL) + { + /* The callback MUST set the txSize to 0 if the + * transmit is ended.*/ + lpuartState->txCallback(instance, lpuartState); + } + else + { + ++lpuartState->txBuff; + --lpuartState->txSize; + } + + /* Check and see if this was the last byte */ + if (lpuartState->txSize == 0) + { + /* Complete transfer, will disable tx interrupt */ + LPUART_DRV_CompleteSendData(instance); + } + } + } + + /* Handle receive overrun interrupt */ + if (LPUART_HAL_GetStatusFlag(base, kLpuartRxOverrun)) + { + /* Clear the flag, OR the rxDataRegFull will not be set any more */ + LPUART_HAL_ClearStatusFlag(base, kLpuartRxOverrun); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_StartSendData + * Description : Initiate (start) a transmit by beginning the process of + * sending data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static lpuart_status_t LPUART_DRV_StartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + LPUART_Type * base = g_lpuartBase[instance]; + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + + /* Check it's not busy transmitting data from a previous function call */ + if (lpuartState->isTxBusy) + { + return kStatus_LPUART_TxBusy; + } + + if (txSize == 0U) + { + return kStatus_LPUART_NoDataToDeal; + } + + /* initialize the module driver state structure */ + lpuartState->txBuff = txBuff; + lpuartState->txSize = txSize; + lpuartState->isTxBusy = true; + + /* enable transmission complete interrupt */ + LPUART_BWR_CTRL_TIE(base, 1U); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_CompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void LPUART_DRV_CompleteSendData(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + LPUART_Type * base = g_lpuartBase[instance]; + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + + /* Disable transmission complete interrupt */ + LPUART_BWR_CTRL_TIE(base, 0U); + + /* Signal the synchronous completion object. */ + if (lpuartState->isTxBlocking) + { + OSA_SemaPost(&lpuartState->txIrqSync); + } + + /* Update the information of the module driver state */ + lpuartState->isTxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_StartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static lpuart_status_t LPUART_DRV_StartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + LPUART_Type * base = g_lpuartBase[instance]; + + /* Check it's not busy receiving data from a previous function call */ + if ((lpuartState->isRxBusy) && (!lpuartState->rxCallback)) + { + return kStatus_LPUART_RxBusy; + } + + if (rxSize == 0U) + { + return kStatus_LPUART_NoDataToDeal; + } + + /* Initialize the module driver state struct to indicate transfer in progress + * and with the buffer and byte count data. */ + lpuartState->isRxBusy = true; + lpuartState->rxBuff = rxBuff; + lpuartState->rxSize = rxSize; + + /* Enable the receive data overrun interrupt */ + LPUART_HAL_SetIntMode(base, kLpuartIntRxOverrun, true); + + /* Enable receive data full interrupt */ + LPUART_BWR_CTRL_RIE(base, 1U); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_CompleteReceiveData + * Description : Finish up a receive by completing the process of receiving data + * and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void LPUART_DRV_CompleteReceiveData(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance]; + LPUART_Type * base = g_lpuartBase[instance]; + + /* disable receive data full and rx overrun interrupt. */ + LPUART_BWR_CTRL_RIE(base, 0U); + LPUART_HAL_SetIntMode(base, kLpuartIntRxOverrun, false); + + /* Signal the synchronous completion object. */ + if (lpuartState->isRxBlocking) + { + OSA_SemaPost(&lpuartState->rxIrqSync); + } + + /* Update the information of the module driver state */ + lpuartState->isRxBusy = false; +} + +#endif /* FSL_FEATURE_SOC_LPUART_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_edma_driver.c b/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_edma_driver.c new file mode 100755 index 0000000..ea313a5 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_edma_driver.c @@ -0,0 +1,737 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_lpuart_edma_driver.h" +#include "fsl_interrupt_manager.h" +#include "fsl_edma_request.h" + +#if FSL_FEATURE_SOC_LPUART_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to lpuart runtime state structure */ +extern void * g_lpuartStatePtr[LPUART_INSTANCE_COUNT]; + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static void LPUART_DRV_EdmaCompleteSendData(uint32_t instance); +static void LPUART_DRV_EdmaTxCallback(void *param, edma_chn_status_t status); +static lpuart_status_t LPUART_DRV_EdmaStartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +static void LPUART_DRV_EdmaCompleteReceiveData(uint32_t instance); +static void LPUART_DRV_EdmaRxCallback(void *param, edma_chn_status_t status); +static lpuart_status_t LPUART_DRV_EdmaStartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize); +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaInit + * Description : This function initializes a LPUART instance for operation. + * This function will initialize the run-time state structure to keep track of + * the on-going transfers, ungate the clock to the LPUART module, initialize the + * module to user defined settings and default settings, configure LPUART DMA + * and enable the LPUART module transmitter and receiver. + * The following is an example of how to set up the lpuart_edma_state_t and the + * lpuart_user_config_t parameters and how to call the LPUART_DRV_EdmaInit function + * by passing in these parameters: + * lpuart_user_config_t lpuartConfig; + * lpuartConfig.clockSource = kClockLpuartSrcPllFllSel; + * lpuartConfig.baudRate = 9600; + * lpuartConfig.bitCountPerChar = kLpuart8BitsPerChar; + * lpuartConfig.parityMode = kLpuartParityDisabled; + * lpuartConfig.stopBitCount = kLpuartOneStopBit; + * lpuart_edma_state_t lpuartEdmaState; + * LPUART_DRV_EdmaInit(instance, &lpuartEdmaState, &lpuartConfig); + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_EdmaInit(uint32_t instance, + lpuart_edma_state_t * lpuartEdmaStatePtr, + const lpuart_edma_user_config_t * lpuartUserConfig) +{ + assert(lpuartEdmaStatePtr && lpuartUserConfig); + assert(instance < LPUART_INSTANCE_COUNT); + /* This driver only support UART instances with separate DMA channels for + * both Tx and Rx.*/ + assert(FSL_FEATURE_LPUART_HAS_SEPARATE_DMA_RX_TX_REQn(instance) == 1); + + LPUART_Type * base = g_lpuartBase[instance]; + uint32_t lpuartSourceClock = 0; + dma_request_source_t lpuartTxEdmaRequest = kDmaRequestMux0Disable; + dma_request_source_t lpuartRxEdmaRequest = kDmaRequestMux0Disable; + DMA_Type * dmabase; + uint32_t dmaChannel; + + /* Exit if current instance is already initialized. */ + if (g_lpuartStatePtr[instance]) + { + return kStatus_LPUART_Initialized; + } + + /* Clear the state structure for this instance. */ + memset(lpuartEdmaStatePtr, 0, sizeof(lpuart_edma_state_t)); + + /* Save runtime structure pointer.*/ + g_lpuartStatePtr[instance] = lpuartEdmaStatePtr; + + /* Set LPUART clock source */ + CLOCK_SYS_SetLpuartSrc(instance, lpuartUserConfig->clockSource); + + /* Un-gate LPUART module clock */ + CLOCK_SYS_EnableLpuartClock(instance); + + /* Initialize LPUART to a known state. */ + LPUART_HAL_Init(base); + + /* Create Semaphore for txIrq and rxIrq. */ + OSA_SemaCreate(&lpuartEdmaStatePtr->txIrqSync, 0); + OSA_SemaCreate(&lpuartEdmaStatePtr->rxIrqSync, 0); + + /* LPUART clock source is either system or bus clock depending on instance */ + lpuartSourceClock = CLOCK_SYS_GetLpuartFreq(instance); + + /* Initialize LPUART baud rate, bit count, parity and stop bit. */ + LPUART_HAL_SetBaudRate(base, lpuartSourceClock, lpuartUserConfig->baudRate); + LPUART_HAL_SetBitCountPerChar(base, lpuartUserConfig->bitCountPerChar); + LPUART_HAL_SetParityMode(base, lpuartUserConfig->parityMode); + LPUART_HAL_SetStopBitCount(base, lpuartUserConfig->stopBitCount); + + switch (instance) + { +#if (FSL_FEATURE_LPUART_HAS_SEPARATE_DMA_RX_TX_REQn(0) == 1) + case 0: + lpuartRxEdmaRequest = kDmaRequestMux0LPUART0Rx; + lpuartTxEdmaRequest = kDmaRequestMux0LPUART0Tx; + break; +#endif +#if (FSL_FEATURE_LPUART_HAS_SEPARATE_DMA_RX_TX_REQn(1) == 1) + case 1: + lpuartRxEdmaRequest = kDmaRequestMux0LPUART1Rx; + lpuartTxEdmaRequest = kDmaRequestMux0LPUART1Tx; + break; +#endif +#if (FSL_FEATURE_LPUART_HAS_SEPARATE_DMA_RX_TX_REQn(2) == 1) + case 2: + lpuartRxEdmaRequest = kDmaRequestMux0LPUART2Rx; + lpuartTxEdmaRequest = kDmaRequestMux0LPUART2Tx; + break; +#endif + default : + break; + } + + /*--------------- Setup RX ------------------*/ + /* Request DMA channels for RX FIFO. */ + EDMA_DRV_RequestChannel(kEDMAAnyChannel, lpuartRxEdmaRequest, + &lpuartEdmaStatePtr->edmaLpuartRx); + EDMA_DRV_InstallCallback(&lpuartEdmaStatePtr->edmaLpuartRx, + LPUART_DRV_EdmaRxCallback, (void *)instance); + dmabase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(lpuartEdmaStatePtr->edmaLpuartRx.channel); + dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(lpuartEdmaStatePtr->edmaLpuartRx.channel); + + /* Setup destination */ + EDMA_HAL_HTCDSetDestOffset(dmabase, dmaChannel, 1); + EDMA_HAL_HTCDSetDestLastAdjust(dmabase, dmaChannel, 0); + + /* Setup source */ + EDMA_HAL_HTCDSetSrcAddr(dmabase, dmaChannel, LPUART_HAL_GetDataRegAddr(base)); + EDMA_HAL_HTCDSetSrcOffset(dmabase, dmaChannel, 0); + EDMA_HAL_HTCDSetSrcLastAdjust(dmabase, dmaChannel, 0); + + /* Setup transfer properties */ + EDMA_HAL_HTCDSetNbytes(dmabase, dmaChannel, 1); + EDMA_HAL_HTCDSetChannelMinorLink(dmabase, dmaChannel, 0, false); + EDMA_HAL_HTCDSetAttribute(dmabase, dmaChannel, kEDMAModuloDisable, + kEDMAModuloDisable, kEDMATransferSize_1Bytes, kEDMATransferSize_1Bytes); + EDMA_HAL_HTCDSetScatterGatherCmd(dmabase, dmaChannel, false); + EDMA_HAL_HTCDSetDisableDmaRequestAfterTCDDoneCmd(dmabase, dmaChannel, true); + + /*--------------- Setup TX ------------------*/ + /* Request DMA channels for TX FIFO. */ + EDMA_DRV_RequestChannel(kEDMAAnyChannel, lpuartTxEdmaRequest, + &lpuartEdmaStatePtr->edmaLpuartTx); + EDMA_DRV_InstallCallback(&lpuartEdmaStatePtr->edmaLpuartTx, + LPUART_DRV_EdmaTxCallback, (void *)instance); + + dmabase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(lpuartEdmaStatePtr->edmaLpuartTx.channel); + dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(lpuartEdmaStatePtr->edmaLpuartTx.channel); + + /* Setup destination */ + EDMA_HAL_HTCDSetDestAddr(dmabase, dmaChannel, LPUART_HAL_GetDataRegAddr(base)); + EDMA_HAL_HTCDSetDestOffset(dmabase, dmaChannel, 0); + EDMA_HAL_HTCDSetDestLastAdjust(dmabase, dmaChannel, 0); + + /* Setup source */ + EDMA_HAL_HTCDSetSrcOffset(dmabase, dmaChannel, 1); + EDMA_HAL_HTCDSetSrcLastAdjust(dmabase, dmaChannel, 0); + + /* Setup transfer properties */ + EDMA_HAL_HTCDSetNbytes(dmabase, dmaChannel, 1); + EDMA_HAL_HTCDSetChannelMinorLink(dmabase, dmaChannel, 0, false); + EDMA_HAL_HTCDSetAttribute(dmabase, dmaChannel, kEDMAModuloDisable, + kEDMAModuloDisable, kEDMATransferSize_1Bytes, kEDMATransferSize_1Bytes); + EDMA_HAL_HTCDSetScatterGatherCmd(dmabase, dmaChannel, false); + EDMA_HAL_HTCDSetDisableDmaRequestAfterTCDDoneCmd(dmabase, dmaChannel, true); + + /* Finally, enable the LPUART transmitter and receiver. + * Enable DMA trigger when transmit data register empty, + * and receive data register full. */ + LPUART_HAL_SetTxDmaCmd(base, true); + LPUART_HAL_SetRxDmaCmd(base, true); + LPUART_HAL_SetTransmitterCmd(base, true); + LPUART_HAL_SetReceiverCmd(base, true); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaDeinit + * Description : This function shuts down the LPUART by disabling LPUART DMA and + * the transmitter/receiver. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_EdmaDeinit(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + /* Exit if current instance is already de-initialized or is gated.*/ + if ((!g_lpuartStatePtr[instance]) || (!CLOCK_SYS_GetLpuartGateCmd(instance))) + { + return kStatus_LPUART_Fail; + } + + LPUART_Type * base = g_lpuartBase[instance]; + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + + /* Wait until the data is completely shifted out of shift register */ + while(!(LPUART_BRD_STAT_TC(base))) { } + + LPUART_HAL_SetTxDmaCmd(base, false); + LPUART_HAL_SetRxDmaCmd(base, false); + + /* Release DMA channel. */ + EDMA_DRV_ReleaseChannel(&lpuartEdmaState->edmaLpuartRx); + EDMA_DRV_ReleaseChannel(&lpuartEdmaState->edmaLpuartTx); + + /* Disable TX and RX */ + LPUART_HAL_SetTransmitterCmd(base, false); + LPUART_HAL_SetReceiverCmd(base, false); + + /* Destroy TX and RX sema. */ + OSA_SemaDestroy(&lpuartEdmaState->txIrqSync); + OSA_SemaDestroy(&lpuartEdmaState->rxIrqSync); + + /* Cleared state pointer. */ + g_lpuartStatePtr[instance] = NULL; + + /* Gate LPUART module clock */ + CLOCK_SYS_DisableLpuartClock(instance); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaSendDataBlocking + * Description : Sends (transmits) data out through the LPUART-DMA module + * using a blocking method. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_EdmaSendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + assert(txBuff); + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + DMA_Type *dmabase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(lpuartEdmaState->edmaLpuartTx.channel); + uint32_t dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(lpuartEdmaState->edmaLpuartTx.channel); + lpuart_status_t retVal = kStatus_LPUART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + lpuartEdmaState->isTxBlocking = true; + + /* Start the transmission process */ + retVal = LPUART_DRV_EdmaStartSendData(instance, txBuff, txSize); + + if (retVal == kStatus_LPUART_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&lpuartEdmaState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(dmabase, dmaChannel, false); + + /* Stop DMA channel. */ + EDMA_HAL_SetDmaRequestCmd(dmabase, (edma_channel_indicator_t)dmaChannel, false); + + /* Update the information of the module driver state */ + lpuartEdmaState->isTxBusy = false; + + retVal = kStatus_LPUART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaSendData + * Description : This function sends (transmits) data through the LPUART module + * using a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the transmit function. The application + * has to get the transmit status to see when the transmit is complete. In + * other words, after calling non-blocking (asynchronous) send function, the + * application must get the transmit status to check if transmit is completed + * or not. The asynchronous method of transmitting and receiving allows the LPUART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_EdmaSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(txBuff); + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_status_t retVal = kStatus_LPUART_Success; + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + + /* Indicates current transaction is non-blocking. */ + lpuartEdmaState->isTxBlocking = false; + + /* Start the transmission process*/ + retVal = LPUART_DRV_EdmaStartSendData(instance, txBuff, txSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaGetTransmitStatus + * Description : This function returns whether the previous LPUART transmit + * has finished. When performing an async transmit, the user can call this + * function to ascertain the state of the current transmission: in progress + * (or busy) or complete (success). In addition, if the transmission is still + * in progress, the user can obtain the number of words that have been + * currently transferred. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_EdmaGetTransmitStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + DMA_Type *dmabase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(lpuartEdmaState->edmaLpuartTx.channel); + uint32_t dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(lpuartEdmaState->edmaLpuartTx.channel); + lpuart_status_t retVal = kStatus_LPUART_Success; + uint32_t txSize = 0; + + /* EDMA will reload the major count after finish transfer, need to set + * the count to 0 manually. */ + if (lpuartEdmaState->isTxBusy) + { + txSize = EDMA_HAL_HTCDGetUnfinishedBytes(dmabase, dmaChannel); + retVal = kStatus_LPUART_TxBusy; + } + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = txSize; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaAbortSendingData + * Description : This function terminates an asynchronous LPUART transmission + * early. During an async LPUART transmission, the user has the option to + * terminate the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_EdmaAbortSendingData(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!lpuartEdmaState->isTxBusy) + { + return kStatus_LPUART_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + LPUART_DRV_EdmaCompleteSendData(instance); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaReceiveDataBlocking + * Description : This function gets (receives) data from the LPUART module using + * a blocking method. A blocking (also known as synchronous) function means that + * the function does not return until the receive is complete. This blocking + * function is used to send data through the LPUART port. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_EdmaReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout) +{ + assert(rxBuff); + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + DMA_Type *dmabase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(lpuartEdmaState->edmaLpuartRx.channel); + uint32_t dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(lpuartEdmaState->edmaLpuartRx.channel); + lpuart_status_t retVal = kStatus_LPUART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + lpuartEdmaState->isRxBlocking = true; + + retVal = LPUART_DRV_EdmaStartReceiveData(instance, rxBuff, rxSize); + + if (retVal == kStatus_LPUART_Success) + { + /* Wait until all the data is received or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&lpuartEdmaState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(dmabase, dmaChannel, false); + + /* Stop DMA channel. */ + EDMA_HAL_SetDmaRequestCmd(dmabase, (edma_channel_indicator_t)dmaChannel, false); + + /* Update the information of the module driver state */ + lpuartEdmaState->isRxBusy = false; + + retVal = kStatus_LPUART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaReceiveData + * Description : This function gets (receives) data from the LPUART module + * using a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. In other + * words, after calling non-blocking (asynchronous) get function, the + * application must get the receive status to check if receive is completed or + * not. The asynchronous method of transmitting and receiving allows the LPUART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_EdmaReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(rxBuff); + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_status_t retVal = kStatus_LPUART_Success; + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + + lpuartEdmaState->isRxBlocking = false; + + retVal = LPUART_DRV_EdmaStartReceiveData(instance, rxBuff, rxSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaGetReceiveStatus + * Description : This function returns whether the previous LPUART receive is + * complete. When performing an async receive, the user can call this function + * to ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, + * the user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_EdmaGetReceiveStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < LPUART_INSTANCE_COUNT); + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + DMA_Type *dmabase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(lpuartEdmaState->edmaLpuartRx.channel); + uint32_t dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(lpuartEdmaState->edmaLpuartRx.channel); + lpuart_status_t retVal = kStatus_LPUART_Success; + uint32_t rxSize = 0; + + /* EDMA will reload the major count after finish transfer, need to set + * the count to 0 manually. */ + if (lpuartEdmaState->isRxBusy) + { + rxSize = EDMA_HAL_HTCDGetUnfinishedBytes(dmabase, dmaChannel); + retVal = kStatus_LPUART_RxBusy; + } + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = rxSize; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaAbortReceivingData + * Description : This function shuts down the LPUART by disabling interrupts and + * the transmitter/receiver. + * + *END**************************************************************************/ +lpuart_status_t LPUART_DRV_EdmaAbortReceivingData(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!lpuartEdmaState->isRxBusy) + { + return kStatus_LPUART_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + LPUART_DRV_EdmaCompleteReceiveData(instance); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaCompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void LPUART_DRV_EdmaCompleteSendData(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + DMA_Type *dmabase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(lpuartEdmaState->edmaLpuartTx.channel); + uint32_t dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(lpuartEdmaState->edmaLpuartTx.channel); + + /* Disable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(dmabase, dmaChannel, false); + + /* Stop DMA channel. */ + EDMA_HAL_SetDmaRequestCmd(dmabase, (edma_channel_indicator_t)dmaChannel, false); + + /* Signal the synchronous completion object. */ + if (lpuartEdmaState->isTxBlocking) + { + OSA_SemaPost(&lpuartEdmaState->txIrqSync); + } + + /* Update the information of the module driver state */ + lpuartEdmaState->isTxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaTxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void LPUART_DRV_EdmaTxCallback(void *param, edma_chn_status_t status) +{ + LPUART_DRV_EdmaCompleteSendData((uint32_t)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaStartSendData + * Description : This is not a public interface. + * + *END**************************************************************************/ +static lpuart_status_t LPUART_DRV_EdmaStartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + /* Get current runtime structure. */ + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + DMA_Type *dmabase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(lpuartEdmaState->edmaLpuartTx.channel); + uint32_t dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(lpuartEdmaState->edmaLpuartTx.channel); + + /* Check that we're not busy already transmitting data from a previous function call. */ + if (lpuartEdmaState->isTxBusy) + { + return kStatus_LPUART_TxBusy; + } + + /* Update LPUART DMA run-time structure. */ + lpuartEdmaState->isTxBusy = true; + + /* Update txBuff and txSize */ + EDMA_HAL_HTCDSetSrcAddr(dmabase, dmaChannel, (uint32_t)txBuff); + EDMA_HAL_HTCDSetMajorCount(dmabase, dmaChannel, txSize); + + /* Enable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(dmabase, dmaChannel, true); + + /* Start DMA channel */ + EDMA_HAL_SetDmaRequestCmd(dmabase, (edma_channel_indicator_t)dmaChannel, true); + + return kStatus_LPUART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaCompleteReceiveData + * Description : Finish up a receive by completing the process of receiving data + * and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void LPUART_DRV_EdmaCompleteReceiveData(uint32_t instance) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + DMA_Type *dmabase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(lpuartEdmaState->edmaLpuartRx.channel); + uint32_t dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(lpuartEdmaState->edmaLpuartRx.channel); + + /* Disable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(dmabase, dmaChannel, false); + + /* Stop DMA channel. */ + EDMA_HAL_SetDmaRequestCmd(dmabase, (edma_channel_indicator_t)dmaChannel, false); + + /* Signal the synchronous completion object. */ + if (lpuartEdmaState->isRxBlocking) + { + OSA_SemaPost(&lpuartEdmaState->rxIrqSync); + } + + /* Update the information of the module driver state */ + lpuartEdmaState->isRxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaRxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void LPUART_DRV_EdmaRxCallback(void *param, edma_chn_status_t status) +{ + LPUART_DRV_EdmaCompleteReceiveData((uint32_t)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : LPUART_DRV_EdmaStartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static lpuart_status_t LPUART_DRV_EdmaStartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(instance < LPUART_INSTANCE_COUNT); + + /* Get current runtime structure. */ + lpuart_edma_state_t * lpuartEdmaState = (lpuart_edma_state_t *)g_lpuartStatePtr[instance]; + DMA_Type *dmabase = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(lpuartEdmaState->edmaLpuartRx.channel); + uint32_t dmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(lpuartEdmaState->edmaLpuartRx.channel); + + /* Check that we're not busy already receiving data from a previous function call. */ + if (lpuartEdmaState->isRxBusy) + { + return kStatus_LPUART_RxBusy; + } + + /* Update LPUART DMA run-time structure. */ + lpuartEdmaState->isRxBusy = true; + + /* Update rxBuff and rxSize */ + EDMA_HAL_HTCDSetDestAddr(dmabase, dmaChannel, (uint32_t)rxBuff); + EDMA_HAL_HTCDSetMajorCount(dmabase, dmaChannel, rxSize); + + /* Enable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(dmabase, dmaChannel, true); + + /* Start DMA channel */ + EDMA_HAL_SetDmaRequestCmd(dmabase, (edma_channel_indicator_t)dmaChannel, true); + + return kStatus_LPUART_Success; +} + +#endif /* FSL_FEATURE_SOC_LPUART_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_irq.c b/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_irq.c new file mode 100755 index 0000000..d5271d8 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_irq.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +extern void LPUART_DRV_IRQHandler(uint32_t instance); + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if (LPUART_INSTANCE_COUNT > 0) +/* Implementation of LPUART0 handler named in startup code. */ +void LPUART0_IRQHandler(void) +{ + LPUART_DRV_IRQHandler(0); +} +#endif + +#if (LPUART_INSTANCE_COUNT > 1) +/* Implementation of LPUART0 handler named in startup code. */ +void LPUART1_IRQHandler(void) +{ + LPUART_DRV_IRQHandler(1); +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_lpm_callback.c new file mode 100755 index 0000000..b36c61c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/lpuart/fsl_lpuart_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t lpuart_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t lpuart_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/README.txt b/KSDK_1.2.0/platform/drivers/src/mmcau/README.txt new file mode 100755 index 0000000..6d9031c --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/README.txt @@ -0,0 +1,174 @@ +This is an updated release of the Kinetis MMCAU security function library. + + +This release: + + - new asm-cm0p library created, optimized for ARMv6-M ISA + - minor improvements to asm-cm4 library, optimized for ARMv7-M ISA + + +This release contains the following structure for the mmcau directory: + +README.txt (this file) + +asm-cm0p +|-- cau_api.h +|-- lib_mmcau-cm0p.a +|-- lst +| |-- mmcau_aes_functions.lst +| |-- mmcau_des_functions.lst +| |-- mmcau_md5_functions.lst +| |-- mmcau_sha1_functions.lst +| `-- mmcau_sha256_functions.lst +`-- src + |-- cau2_defines.hdr + |-- mmcau_aes_functions.s + |-- mmcau_des_functions.s + |-- mmcau_md5_functions.s + |-- mmcau_sha1_functions.s + `-- mmcau_sha256_functions.s + +asm-cm4 +|-- cau_api.h +|-- lib_mmcau.a +|-- lst +| |-- mmcau_aes_functions.lst +| |-- mmcau_des_functions.lst +| |-- mmcau_md5_functions.lst +| |-- mmcau_sha1_functions.lst +| `-- mmcau_sha256_functions.lst +`-- src + |-- cau2_defines.hdr + |-- mmcau_aes_functions.s + |-- mmcau_des_functions.s + |-- mmcau_md5_functions.s + |-- mmcau_sha1_functions.s + `-- mmcau_sha256_functions.s + + + +Each mmcau optimized assembly library (cm0p, cm4) is contained in 5 +files (18 functions) and is archived in a lib_mmcau*.a file. + + +Each library was assembled with: +GNU assembler version 4.3.3 (arm-none-linux-gnueabi-as) + + +This mmcau library update is checked-in under Design Sync: +sync://sync-15010:15010/Projects/mcp_armp/mmcau_apb3/tool_data/lib/ +tagged as: mmcau_apb3.01.00.00.11 + + + +asm-cm0p : mmcau assembly library optimized for the ARMv6-M ISA +******** + +Includes the following file versions (with checkin timestamps): + +12/19/2013 10:01 1.1 cau_api.h +11/13/2013 11:30 1.1 lib_mmcau-cm0p.a + (checked in as lib_mmcau-v6m.a) +08/22/2010 22:52 1.1 cau2_defines.hdr +10/31/2013 12:21 1.1 mmcau_aes_functions.s +10/31/2013 12:21 1.1 mmcau_des_functions.s +10/31/2013 12:21 1.1 mmcau_md5_functions.s +10/31/2013 12:21 1.1 mmcau_sha1_functions.s +11/20/2013 09:27 1.2 mmcau_sha256_functions.s + +The following additional asm listing files not under revision control are +also included (with last modified timestamps): + +11/19/2013 11:36 mmcau_aes_functions.lst +11/19/2013 11:36 mmcau_des_functions.lst +11/19/2013 11:36 mmcau_md5_functions.lst +11/19/2013 11:36 mmcau_sha1_functions.lst +11/19/2013 11:36 mmcau_sha256_functions.lst + + +asm-cm4 : mmcau assembly library optimized for the ARMv7-M ISA +******* + +Includes the following file versions (with checkin timestamps): + +12/19/2013 10:01 1.1 cau_api.h +11/21/2013 13:41 1.6 lib_mmcau.a +08/22/2010 22:52 1.1 cau2_defines.hdr +11/21/2013 13:17 1.4 mmcau_aes_functions.s +11/21/2013 13:17 1.4 mmcau_des_functions.s +11/21/2013 13:17 1.6 mmcau_md5_functions.s +11/21/2013 13:17 1.5 mmcau_sha1_functions.s +11/21/2013 13:18 1.6 mmcau_sha256_functions.s + +The following additional asm listing files not under revision control are +also included (with last modified timestamps): + +11/21/2013 13:23 mmcau_aes_functions.lst +11/21/2013 13:23 mmcau_des_functions.lst +11/21/2013 13:23 mmcau_md5_functions.lst +11/21/2013 13:23 mmcau_sha1_functions.lst +11/21/2013 13:23 mmcau_sha256_functions.lst + + + +The calling conventions for the mmcau functions are as follows: +--------------------------------------------------------------- + +mmcau_aes_functions: + void mmcau_aes_set_key (const unsigned char *key, + const int key_size, + unsigned char *key_sch) + void mmcau_aes_encrypt (const unsigned char *in, + const unsigned char *key_sch, + const int nr, + unsigned char *out) + void mmcau_aes_decrypt (const unsigned char *in, + const unsigned char *key_sch, + const int nr, + unsigned char *out) + + +mmcau_des_functions: + int mmcau_des_chk_parity (const unsigned char *key) + void mmcau_des_encrypt (const unsigned char *in, + const unsigned char *key, + unsigned char *out) + void mmcau_des_decrypt (const unsigned char *in, + const unsigned char *key, + unsigned char *out) + + +mmcau_md5_functions: + void mmcau_md5_initialize_output (const unsigned char *md5_state) + void mmcau_md5_hash_n (const unsigned char *msg_data, + const int num_blks, + unsigned char *md5_state) + void mmcau_md5_update (const unsigned char *msg_data, + const int num_blks, + unsigned char *md5_state) + void mcau_md5_hash (const unsigned char *msg_data, + unsigned char *md5_state) + + +mmcau_sha1_functions: + void mmcau_sha1_initialize_output (const unsigned int *sha1_state) + void mmcau_sha1_hash_n (const unsigned char *msg_data, + const int num_blks, + unsigned int *sha1_state) + void mmcau_sha1_update (const unsigned char *msg_data, + const int num_blks, + unsigned int *sha1_state) + void mmcau_sha1_hash (const unsigned char *msg_data, + unsigned int *sha1_state) + + +mmcau_sha256_functions: + int mmcau_sha256_initialize_output (const unsigned int *output) + void mmcau_sha256_hash_n (const unsigned char *input, + const int num_blks, + unsigned int *output) + void mmcau_sha256_update (const unsigned char *input, + const int num_blks, + unsigned int *output) + void mmcau_sha256_hash (const unsigned char *input, + unsigned int *output) diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/cau_api.h b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/cau_api.h new file mode 100755 index 0000000..7d5c72a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/cau_api.h @@ -0,0 +1,389 @@ +/* + * CAU Header File + * Works with library cau_lib.a and lib_mmcau*.a + * Define FREESCALE_CAU if CAU coprocessor is used --Register parameter passing is assumed + * Define FREESCALE_MMCAU if mmCAU coprocessor is used --EABI for Kinetis ARM Cortex-Mx + * 12/19/2013 + */ + +#if FREESCALE_MMCAU +#define cau_aes_set_key mmcau_aes_set_key +#define cau_aes_encrypt mmcau_aes_encrypt +#define cau_aes_decrypt mmcau_aes_decrypt +#define cau_des_chk_parity mmcau_des_chk_parity +#define cau_des_encrypt mmcau_des_encrypt +#define cau_des_decrypt mmcau_des_decrypt +#define cau_md5_initialize_output mmcau_md5_initialize_output +#define cau_md5_hash_n mmcau_md5_hash_n +#define cau_md5_update mmcau_md5_update +#define cau_md5_hash mmcau_md5_hash +#define cau_sha1_initialize_output mmcau_sha1_initialize_output +#define cau_sha1_hash_n mmcau_sha1_hash_n +#define cau_sha1_update mmcau_sha1_update +#define cau_sha1_hash mmcau_sha1_hash +#define cau_sha256_initialize_output mmcau_sha256_initialize_output +#define cau_sha256_hash_n mmcau_sha256_hash_n +#define cau_sha256_update mmcau_sha256_update +#define cau_sha256_hash mmcau_sha256_hash +#endif + +//****************************************************************************** +// +// AES: Performs an AES key expansion +// arguments +// *key pointer to input key (128, 192, 256 bits in length) +// key_size key_size in bits (128, 192, 256) +// *key_sch pointer to key schedule output (44, 52, 60 longwords) +// +// calling convention +// void cau_aes_set_key (const unsigned char *key, +// const int key_size, +// unsigned char *key_sch) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_aes_set_key (const unsigned char *key, const int key_size, + unsigned char *key_sch); + +//****************************************************************************** +//****************************************************************************** +// +// AES: Encrypts a single 16-byte block +// arguments +// *in pointer to 16-byte block of input plaintext +// *key_sch pointer to key schedule (44, 52, 60 longwords) +// nr number of AES rounds (10, 12, 14 = f(key_schedule)) +// *out pointer to 16-byte block of output ciphertext +// +// NOTE Input and output blocks may overlap +// +// calling convention +// void cau_aes_encrypt (const unsigned char *in, +// const unsigned char *key_sch, +// const int nr, +// unsigned char *out) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_aes_encrypt (const unsigned char *in, const unsigned char *key_sch, + const int nr, unsigned char *out); + +//****************************************************************************** +//****************************************************************************** +// +// AES: Decrypts a single 16-byte block +// arguments +// *in pointer to 16-byte block of input chiphertext +// *key_sch pointer to key schedule (44, 52, 60 longwords) +// nr number of AES rounds (10, 12, 14 = f(key_schedule)) +// *out pointer to 16-byte block of output plaintext +// +// NOTE Input and output blocks may overlap +// +// calling convention +// void cau_aes_decrypt (const unsigned char *in, +// const unsigned char *key_sch, +// const int nr, +// unsigned char *out) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_aes_decrypt (const unsigned char *in, const unsigned char *key_sch, + const int nr, unsigned char *out); + +//****************************************************************************** +// +// DES: Checks key parity +// arguments +// *key pointer to 64-bit DES key with parity bits +// +// return +// 0 no error +// -1 parity error +// +// calling convention +// int cau_des_chk_parity (const unsigned char *key) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +int +cau_des_chk_parity (const unsigned char *key); + +//****************************************************************************** +// +// DES: Encrypts a single 8-byte block +// arguments +// *in pointer to 8-byte block of input plaintext +// *key pointer to 64-bit DES key with parity bits +// *out pointer to 8-byte block of output ciphertext +// +// NOTE Input and output blocks may overlap +// +// calling convention +// void cau_des_encrypt (const unsigned char *in, +// const unsigned char *key, +// unsigned char *out) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_des_encrypt (const unsigned char *in, const unsigned char *key, + unsigned char *out); + +//****************************************************************************** +// +// DES: Decrypts a single 8-byte block +// arguments +// *in pointer to 8-byte block of input ciphertext +// *key pointer to 64-bit DES key with parity bits +// *out pointer to 8-byte block of output plaintext +// +// NOTE Input and output blocks may overlap +// +// calling convention +// void cau_des_decrypt (const unsigned char *in, +// const unsigned char *key, +// unsigned char *out) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_des_decrypt (const unsigned char *in, const unsigned char *key, + unsigned char *out); + +//****************************************************************************** +//****************************************************************************** +// +// MD5: Initializes the MD5 state variables +// arguments +// *md_state pointer to 120-bit block of md5 state variables: +// a,b,c,d +// +// calling convention +// void cau_md5_initialize_output (const unsigned char *md_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_md5_initialize_output (const unsigned char *md5_state); + +//****************************************************************************** +//****************************************************************************** +// +// MD5: Updates MD5 state variables for one or more input message blocks +// +// arguments +// *msg_data pointer to start of input message data +// num_blks number of 512-bit blocks to process +// *md_state pointer to 128-bit block of MD5 state variables: +// a,b,c,d +// +// calling convention +// void cau_md5_hash_n (const unsigned char *msg_data, +// const int num_blks, +// unsigned char *md_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_md5_hash_n (const unsigned char *msg_data, const int num_blks, + unsigned char *md5_state); + +//****************************************************************************** +//****************************************************************************** +// +// MD5: Updates MD5 state variables for one or more input message blocks +// arguments +// *msg_data pointer to start of input message data +// num_blks number of 512-bit blocks to process +// *md_state pointer to 128-bit block of MD5 state variables: +// a,b,c,d +// +// calling convention +// void cau_md5_update (const unsigned char *msg_data, +// const int num_blks, +// unsigned char *md_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_md5_update (const unsigned char *msg_data, const int num_blks, + unsigned char *md5_state); + +//****************************************************************************** +//****************************************************************************** +// +// MD5: Performs MD5 hash algorithm for a single input message block +// *msg_data pointer to start of input message data +// *md_state pointer to 128-bit block of MD5 state variables: +// a,b,c,d +// +// calling convention +// void cau_md5_hash (const unsigned char *msg_data, +// unsigned char *md_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_md5_hash (const unsigned char *msg_data, unsigned char *md5_state); + +//****************************************************************************** +//****************************************************************************** +// +// SHA1: Initializes the SHA1 state variables +// arguments +// *sha1_state pointer to 160-bit block of SHA1 state variables: +// a,b,c,d,e +// +// calling convention +// void cau_sha1_initialize_output (const unsigned int *sha1_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha1_initialize_output (const unsigned int *sha1_state); + +//****************************************************************************** +//****************************************************************************** +// +// SHA1: Perform the hash and generate SHA1 state variables for one or more +// input message blocks +// arguments +// *msg_data pointer to start of input message data +// num_blks number of 512-bit blocks to process +// *sha1_state pointer to 160-bit block of SHA1 state variables: +// a,b,c,d,e +// +// NOTE Input message and state variable output blocks must not overlap +// +// calling convention +// void cau_sha1_hash (const unsigned char *msg_data, +// const int num_blks, +// unsigned int *sha1_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha1_hash_n (const unsigned char *msg_data, const int num_blks, + unsigned int *sha1_state); + +//****************************************************************************** +//****************************************************************************** +// +// SHA1: Updates SHA1 state variables for one or more input message blocks +// arguments +// *msg_data pointer to start of input message data +// num_blks number of 512-bit blocks to process +// *sha1_state pointer to 160-bit block of SHA1 state variables: +// a,b,c,d,e +// +// calling convention +// void cau_sha1_update (const unsigned char *msg_data, +// const int num_blks, +// unsigned int *sha1_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha1_update (const unsigned char *msg_data, const int num_blks, + unsigned int *sha1_state); + +//****************************************************************************** +//****************************************************************************** +// +// SHA1: Performs SHA1 hash algorithm on a single input message block +// arguments +// *msg_data pointer to start of input message data +// *sha1_state pointer to 160-bit block of SHA1 state variables: +// a,b,c,d,e +// +// calling convention +// void cau_sha1_update (const unsigned char *msg_data, +// unsigned int *sha1_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha1_hash (const unsigned char *msg_data, + unsigned int *sha1_state); + +//****************************************************************************** +//****************************************************************************** +// +// SHA256: Initializes the hash output and checks the CAU hardware revision +// arguments +// *output pointer to 256-bit message digest output +// +// return +// 0 no error -> CAU2 hardware present +// -1 error -> incorrect CAU hardware revision +// +// calling convention +// int cau_sha256_initialize_output (const unsigned int *output) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +int +cau_sha256_initialize_output (const unsigned int *output); + +//****************************************************************************** +//****************************************************************************** +// +// SHA256: Updates SHA256 digest output for one or more message block arguments +// arguments +// *input pointer to start of input message +// input number of 512-bit blocks to process +// *output pointer to 256-bit message digest output +// +// NOTE Input message and digest output blocks must not overlap +// +// calling convention +// void cau_sha256_hash_n (const unsigned char *input, +// int num_blks, +// const unsigned int *output) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha256_hash_n (const unsigned char *input, const int num_blks, + unsigned int *output); + +//****************************************************************************** +//****************************************************************************** +// +// SHA256: Updates SHA256 state variables for one or more input message blocks +// arguments +// *input pointer to start of input message data +// num_blks number of 512-bit blocks to process +// *output pointer to 256-bit message digest output +// +// calling convention +// void cau_sha256_update (const unsigned char *input, +// const int num_blks, +// unsigned int *output) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha256_update (const unsigned char *input, const int num_blks, + unsigned int *output); + +//****************************************************************************** +//****************************************************************************** +// +// SHA256: Performs SHA256 hash algorithm for a single input message block +// arguments +// *input pointer to start of input message data +// *output pointer to 256-bit message digest output +// +// calling convention +// void cau_sha256_hash (const unsigned char *input, +// unsigned int *output) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha256_hash (const unsigned char *input, unsigned int *output); diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/lib_mmcau-cm0p.a b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/lib_mmcau-cm0p.a Binary files differnew file mode 100755 index 0000000..2a5e2ac --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/lib_mmcau-cm0p.a diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/cau2_defines.hdr b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/cau2_defines.hdr new file mode 100755 index 0000000..320b401 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/cau2_defines.hdr @@ -0,0 +1,62 @@ +#ifndef _MMCAU_H_ +#define _MMCAU_H_ + + .equ TL,0 + .equ TS,0 + .equ CASR,0 + .equ CAA,1 + .equ CA0,2 + .equ CA1,3 + .equ CA2,4 + .equ CA3,5 + .equ CA4,6 + .equ CA5,7 + .equ CA6,8 + .equ CA7,9 + .equ CA8,10 + .equ CNOP,0x000 + .equ LDR,0x010 + .equ STR,0x020 + .equ ADR,0x030 + .equ RADR,0x040 + .equ ADRA,0x050 + .equ XOR,0x060 + .equ ROTL,0x070 + .equ MVRA,0x080 + .equ MVAR,0x090 + .equ AESS,0x0a0 + .equ AESIS,0x0b0 + .equ AESC,0x0c0 + .equ AESIC,0x0d0 + .equ AESR,0x0e0 + .equ AESIR,0x0f0 + .equ DESR,0x100 + .equ DESK,0x110 + .equ HASH,0x120 + .equ SHS,0x130 + .equ MDS,0x140 + .equ SHS2,0x150 + .equ ILL,0x1f0 + .equ IP,8 + .equ FP,4 + .equ DC,1 + .equ CP,2 + .equ KSL1,0 + .equ KSL2,1 + .equ KSR1,2 + .equ KSR2,3 + .equ HFF,0 + .equ HFG,1 + .equ HFH,2 + .equ HFI,3 + .equ HFP,2 + .equ HFC,4 + .equ HFM,5 + .equ HF2C,6 + .equ HF2M,7 + .equ HF2S,8 + .equ HF2T,9 + .equ HF2U,10 + .equ HF2V,11 + +#endif diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_aes_functions.s b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_aes_functions.s new file mode 100755 index 0000000..258fb44 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_aes_functions.s @@ -0,0 +1,1387 @@ +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# Copyright (c) Freescale Semiconductor, Inc 2013. +# +# FILE NAME : mmcau_aes_functions.s +# VERSION : $Id: $ +# TYPE : Source Cortex-M0+ assembly library code +# DEPARTMENT : MCG R&D Core and Platforms +# AUTHOR : Anthony (Teejay) Ciancio +# AUTHOR EMAIL : teejay.ciancio@freescale.com +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# VERSION DATE AUTHOR DESCRIPTION +# ******* **** ****** *********** +# 1.0 2013-11 Ciancio initial release, using the ARMv6-M ISA +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + + .include "cau2_defines.hdr" + .syntax unified + + + .equ MMCAU_PPB_DIRECT, 0xf0005000 + .equ MMCAU_PPB_INDIRECT, 0xf0005800 + .equ MMCAU_1_CMD, 0x80000000 + .equ MMCAU_2_CMDS, 0x80100000 + .equ MMCAU_3_CMDS, 0x80100200 + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_AES_SET_KEY +# Performs an AES key expansion +# +# ARGUMENTS +# *key pointer to input key (128, 192, 256 bits in length) +# key_size key_size in bits (128, 192, 256) +# *key_sch pointer to key schedule output (44, 52, 60 longwords) +# +# CALLING CONVENTION +# void mmcau_aes_set_key (const unsigned char *key, +# const int key_size, +# unsigned char *key_sch) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_aes_set_key) +# -----------+------------------------------------------------------------ +# r0 | *key (arg0) +# r1 | key_size (arg1) +# r2 | *key_sch (arg2) +# | +# > r2 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_aes_set_key + .global mmcau_aes_set_key + .type mmcau_aes_set_key, %function + .align 4 + +_mmcau_aes_set_key: +mmcau_aes_set_key: + +# store regs r4-r12 and r14, we need to restore them at the end of the routine + push {r4-r7, lr} @ store low regs and link reg + mov r3, r8 + mov r4, r9 + mov r5, sl + mov r6, fp + mov r7, ip + push {r3-r7} @ store high regs + + ldr r3, =set_key_reg_data @ prepare for set_key reg load + + +set_key_check_size: + cmp r1, #128 @ if key_size != 128, + bne set_key_check_size_again @ then = 192 or 256, so check again + b set_key_128 @ else = 128, so do set_key_128 + + +set_key_check_size_again: + cmp r1, #192 @ if key_size != 192, + bne set_key_256 @ then = 256, so do set_key_256 + b set_key_192 @ else = 192, so do set_key_192 + .ltorg + + +set_key_256: + +# REGISTER | ALLOCATION (throughout set_key_256) +# -----------+------------------------------------------------------------ +# r0 | scratch +# r1 | scratch +# r2 | *key_sch +# r3 | key_sch[0+8i] / scratch +# r4 | key_sch[1+8i] / scratch +# r5 | key_sch[2+8i] / scratch +# r6 | key_sch[3+8i] / scratch +# r7 | scratch +# r8 | *rcon +# r9 | mmcau_1_cmd(AESS+CAA) +# (sl) r10 | *mmcau_direct_cmd() +# (fp) r11 | mmcau_indirect_cmd(LDR+CAA) +# (ip) r12 | mmcau_indirect_cmd(STR+CAA) +# (sp) r13 | stack pointer +# (lr) r14 | link register + +# load some of the regs in preperation of the AES-256 set key calculations + ldmia r3, {r3-r7} + mov r8, r3 @ r8 = *rcon + mov r9, r4 @ r9 = mmcau_1_cmd(AESS+CAA) + mov sl, r5 @ sl = *mmcau_direct_cmd() + mov fp, r6 @ fp = mmcau_indirect_cmd(LDR+CAA) + mov ip, r7 @ ip = mmcau_indirect_cmd(STR+CAA) + +# calculate key_sch[0-4] + ldmia r0!, {r3-r7} @ load key[0-4]; *key++ + rev r3, r3 @ byterev(key[0]) = key_sch[0] + rev r4, r4 @ byterev(key[1]) = key_sch[1] + rev r5, r5 @ byterev(key[2]) = key_sch[2] + rev r6, r6 @ byterev(key[3]) = key_sch[3] + rev r7, r7 @ byterev(key[4]) = key_sch[4] + stmia r2!, {r3-r7} @ store key_sch[0-4], key_sch++ + +# calculate key_sch[5-7] + ldmia r0, {r0-r1,r7} @ load key[5-7] + rev r0, r0 @ byterev(key[5]) = key_sch[5] + rev r1, r1 @ byterev(key[6]) = key_sch[6] + rev r7, r7 @ byterev(key[7]) = key_sch[7] + stmia r2!, {r0-r1, r7} @ store key_sch[5-7], key_sch++ + +# calculate key_sch[8-11] + mov r0, r8 + ldr r1, [r0] @ load rcon[0] + movs r0, #24 + rors r7, r0 @ ROTL(key_sch[7],8) + mov r0, fp + str r7, [r0] @ ROTL(key_sch[7]) -> acc + mov r7, r9 + mov r0, sl + str r7, [r0] @ AES SubBytes + mov r0, ip + ldr r7, [r0] @ load CAA + eors r1, r7 @ XOR rcon[0] + eors r3, r1 @ XOR key_sch[0] = key_sch[8] + eors r4, r3 @ XOR key_sch[1] = key_sch[9] + eors r5, r4 @ XOR key_sch[2] = key_sch[10] + eors r6, r5 @ XOR key_sch[3] = key_sch[11] + stmia r2!, {r3-r6} @ store key_sch[8-11], *key_sch++ + +# calculate key_sch[12-15] + mov r5, fp + str r6, [r5] @ ROTL(key_sch[11]) -> acc + mov r3, r9 + mov r4, sl + str r3, [r4] @ AES SubBytes + mov r7, ip + ldr r1, [r7] @ load CAA + subs r2, #8<<2 @ set *key_sch[4] + ldmia r2!, {r3-r6} @ load key_sch[4-7], *key_sch++ + eors r3, r1 @ XOR key_sch[4] = key_sch[12] + eors r4, r3 @ XOR key_sch[5] = key_sch[13] + eors r5, r4 @ XOR key_sch[6] = key_sch[14] + eors r6, r5 @ XOR key_sch[7] = key_sch[15] + adds r2, #4<<2 @ set *key_sch[12] + stmia r2!, {r3-r6} @ store key_sch[12-15], *key_sch++ + +# calculate key_sch[16-19] + mov r0, r8 + ldr r7, [r0, #1<<2] @ load rcon[1] + mov r5, fp + movs r0, #24 + mov r3, r9 + rors r6, r0 @ ROTL(key_sch[15],8) + mov r4, sl + str r6, [r5] @ ROTL(key_sch[15]) -> acc + mov r0, ip + str r3, [r4] @ AES SubBytes + ldr r1, [r0] @ load CAA + eors r1, r7 @ XOR rcon[1] + subs r2, #8<<2 @ set *key_sch[8] + ldmia r2!, {r3-r6} @ load key_sch[8-11], *key_sch++ + eors r3, r1 @ XOR key_sch[8] = key_sch[16] + eors r4, r3 @ XOR key_sch[9] = key_sch[17] + eors r5, r4 @ XOR key_sch[10] = key_sch[18] + eors r6, r5 @ XOR key_sch[11] = key_sch[19] + adds r2, #4<<2 @ set *key_sch[16] + stmia r2!, {r3-r6} @ store key_sch[16-19], *key_sch++ + +# calculate key_sch[20-23] + mov r5, fp + str r6, [r5] @ ROTL(key_sch[19]) -> acc + mov r3, r9 + mov r4, sl + str r3, [r4] @ AES SubBytes + mov r7, ip + ldr r1, [r7] @ load CAA + subs r2, #8<<2 @ set *key_sch[12] + ldmia r2!, {r3-r6} @ load key_sch[12-15], *key_sch++ + eors r3, r1 @ XOR key_sch[12] = key_sch[20] + eors r4, r3 @ XOR key_sch[13] = key_sch[21] + eors r5, r4 @ XOR key_sch[14] = key_sch[22] + eors r6, r5 @ XOR key_sch[15] = key_sch[23] + adds r2, #4<<2 @ set *key_sch[20] + stmia r2!, {r3-r6} @ store key_sch[20-23], *key_sch++ + +# calculate key_sch[24-27] + mov r0, r8 + ldr r7, [r0, #2<<2] @ load rcon[2] + mov r5, fp + movs r0, #24 + mov r3, r9 + rors r6, r0 @ ROTL(key_sch[23],8) + mov r4, sl + str r6, [r5] @ ROTL(key_sch[23]) -> acc + mov r0, ip + str r3, [r4] @ AES SubBytes + ldr r1, [r0] @ load CAA + eors r1, r7 @ XOR rcon[2] + subs r2, #8<<2 @ set *key_sch[16] + ldmia r2!, {r3-r6} @ load key_sch[16-19], *key_sch++ + eors r3, r1 @ XOR key_sch[16] = key_sch[24] + eors r4, r3 @ XOR key_sch[17] = key_sch[25] + eors r5, r4 @ XOR key_sch[18] = key_sch[26] + eors r6, r5 @ XOR key_sch[19] = key_sch[27] + adds r2, #4<<2 @ set *key_sch[24] + stmia r2!, {r3-r6} @ store key_sch[24-27], *key_sch++ + +# calculate key_sch[28-31] + mov r5, fp + str r6, [r5] @ ROTL(key_sch[27]) -> acc + mov r3, r9 + mov r4, sl + str r3, [r4] @ AES SubBytes + mov r7, ip + ldr r1, [r7] @ load CAA + subs r2, #8<<2 @ set *key_sch[20] + ldmia r2!, {r3-r6} @ load key_sch[20-23], *key_sch++ + eors r3, r1 @ XOR key_sch[20] = key_sch[28] + eors r4, r3 @ XOR key_sch[21] = key_sch[29] + eors r5, r4 @ XOR key_sch[22] = key_sch[30] + eors r6, r5 @ XOR key_sch[23] = key_sch[31] + adds r2, #4<<2 @ set *key_sch[28] + stmia r2!, {r3-r6} @ store key_sch[28-31], *key_sch++ + +# calculate key_sch[32-35] + mov r0, r8 + ldr r7, [r0, #3<<2] @ load rcon[3] + mov r5, fp + movs r0, #24 + mov r3, r9 + rors r6, r0 @ ROTL(key_sch[31],8) + mov r4, sl + str r6, [r5] @ ROTL(key_sch[31]) -> acc + mov r0, ip + str r3, [r4] @ AES SubBytes + ldr r1, [r0] @ load CAA + eors r1, r7 @ XOR rcon[3] + subs r2, #8<<2 @ set *key_sch[24] + ldmia r2!, {r3-r6} @ load key_sch[24-27], *key_sch++ + eors r3, r1 @ XOR key_sch[24] = key_sch[32] + eors r4, r3 @ XOR key_sch[25] = key_sch[33] + eors r5, r4 @ XOR key_sch[26] = key_sch[34] + eors r6, r5 @ XOR key_sch[27] = key_sch[35] + adds r2, #4<<2 @ set *key_sch[32] + stmia r2!, {r3-r6} @ store key_sch[32-35], *key_sch++ + +# calculate key_sch[36-39] + mov r5, fp + str r6, [r5] @ ROTL(key_sch[35]) -> acc + mov r3, r9 + mov r4, sl + str r3, [r4] @ AES SubBytes + mov r7, ip + ldr r1, [r7] @ load CAA + subs r2, #8<<2 @ set *key_sch[28] + ldmia r2!, {r3-r6} @ load key_sch[28-31], *key_sch++ + eors r3, r1 @ XOR key_sch[28] = key_sch[36] + eors r4, r3 @ XOR key_sch[29] = key_sch[37] + eors r5, r4 @ XOR key_sch[30] = key_sch[38] + eors r6, r5 @ XOR key_sch[31] = key_sch[39] + adds r2, #4<<2 @ set *key_sch[36] + stmia r2!, {r3-r6} @ store key_sch[36-39], *key_sch++ + +# calculate key_sch[40-43] + mov r0, r8 + ldr r7, [r0, #4<<2] @ load rcon[4] + mov r5, fp + movs r0, #24 + mov r3, r9 + rors r6, r0 @ ROTL(key_sch[39],8) + mov r4, sl + str r6, [r5] @ ROTL(key_sch[39]) -> acc + mov r0, ip + str r3, [r4] @ AES SubBytes + ldr r1, [r0] @ load CAA + eors r1, r7 @ XOR rcon[4] + subs r2, #8<<2 @ set *key_sch[32] + ldmia r2!, {r3-r6} @ load key_sch[32-35], *key_sch++ + eors r3, r1 @ XOR key_sch[32] = key_sch[40] + eors r4, r3 @ XOR key_sch[33] = key_sch[41] + eors r5, r4 @ XOR key_sch[34] = key_sch[42] + eors r6, r5 @ XOR key_sch[35] = key_sch[43] + adds r2, #4<<2 @ set *key_sch[40] + stmia r2!, {r3-r6} @ store key_sch[40-43], *key_sch++ + +# calculate key_sch[44-47] + mov r5, fp + str r6, [r5] @ ROTL(key_sch[43]) -> acc + mov r3, r9 + mov r4, sl + str r3, [r4] @ AES SubBytes + mov r7, ip + ldr r1, [r7] @ load CAA + subs r2, #8<<2 @ set *key_sch[36] + ldmia r2!, {r3-r6} @ load key_sch[36-39], *key_sch++ + eors r3, r1 @ XOR key_sch[36] = key_sch[44] + eors r4, r3 @ XOR key_sch[37] = key_sch[45] + eors r5, r4 @ XOR key_sch[38] = key_sch[46] + eors r6, r5 @ XOR key_sch[39] = key_sch[47] + adds r2, #4<<2 @ set *key_sch[44] + stmia r2!, {r3-r6} @ store key_sch[44-47], *key_sch++ + +# calculate key_sch[48-51] + mov r0, r8 + ldr r7, [r0, #5<<2] @ load rcon[5] + mov r5, fp + movs r0, #24 + mov r3, r9 + rors r6, r0 @ ROTL(key_sch[47],8) + mov r4, sl + str r6, [r5] @ ROTL(key_sch[47]) -> acc + mov r0, ip + str r3, [r4] @ AES SubBytes + ldr r1, [r0] @ load CAA + eors r1, r7 @ XOR rcon[5] + subs r2, #8<<2 @ set *key_sch[40] + ldmia r2!, {r3-r6} @ load key_sch[40-43], *key_sch++ + eors r3, r1 @ XOR key_sch[40] = key_sch[48] + eors r4, r3 @ XOR key_sch[41] = key_sch[49] + eors r5, r4 @ XOR key_sch[42] = key_sch[50] + eors r6, r5 @ XOR key_sch[43] = key_sch[51] + adds r2, #4<<2 @ set *key_sch[48] + stmia r2!, {r3-r6} @ store key_sch[48-51], *key_sch++ + +# calculate key_sch[52-55] + mov r5, fp + str r6, [r5] @ ROTL(key_sch[51]) -> acc + mov r3, r9 + mov r4, sl + str r3, [r4] @ AES SubBytes + mov r7, ip + ldr r1, [r7] @ load CAA + subs r2, #8<<2 @ set *key_sch[44] + ldmia r2!, {r3-r6} @ load key_sch[44-47], *key_sch++ + eors r3, r1 @ XOR key_sch[44] = key_sch[52] + eors r4, r3 @ XOR key_sch[45] = key_sch[53] + eors r5, r4 @ XOR key_sch[46] = key_sch[54] + eors r6, r5 @ XOR key_sch[47] = key_sch[55] + adds r2, #4<<2 @ set *key_sch[52] + stmia r2!, {r3-r6} @ store key_sch[52-55], *key_sch++ + +# calculate key_sch[56-59] + mov r0, r8 + ldr r7, [r0, #6<<2] @ load rcon[6] + mov r5, fp + movs r0, #24 + mov r3, r9 + rors r6, r0 @ ROTL(key_sch[55],8) + mov r4, sl + str r6, [r5] @ ROTL(key_sch[55]) -> acc + mov r0, ip + str r3, [r4] @ AES SubBytes + ldr r1, [r0] @ load CAA + eors r1, r7 @ XOR rcon[6] + subs r2, #8<<2 @ set *key_sch[48] + ldmia r2!, {r3-r6} @ load key_sch[48-51], *key_sch++ + eors r3, r1 @ XOR key_sch[48] = key_sch[56] + eors r4, r3 @ XOR key_sch[49] = key_sch[57] + eors r5, r4 @ XOR key_sch[50] = key_sch[58] + eors r6, r5 @ XOR key_sch[51] = key_sch[59] + adds r2, #4<<2 @ set *key_sch[56] + stmia r2!, {r3-r6} @ store key_sch[56-59], *key_sch++ + + b set_key_end @ end routine + + +set_key_192: + +# REGISTER | ALLOCATION (throughout set_key_192) +# -----------+------------------------------------------------------------ +# r0 | key_sch[0+6i] +# r1 | key_sch[1+6i] +# r2 | *key_sch +# r3 | key_sch[2+6i] +# r4 | key_sch[3+6i] +# r5 | key_sch[4+6i] / rcon[i] +# r6 | key_sch[5+6i] / scratch +# r7 | scratch +# r8 | *rcon +# r9 | mmcau_1_cmd(AESS+CAA) +# (sl) r10 | *mmcau_direct_cmd() +# (fp) r11 | mmcau_indirect_cmd(LDR+CAA) +# NOTE | mmcau_indirect_cmd(STR+CAA) = mmcau_indirect_cmd(LDR+CAA)+64 +# (ip) r12 | temporary storage for key_sch[4+6i] +# (sp) r13 | stack pointer +# (lr) r14 | temporary storage for key_sch[5+6i] + +# load some of the regs in preperation of the AES-192 set key calculations + ldmia r3, {r3-r6} + mov r8, r3 @ r8 = *rcon + mov r9, r4 @ r9 = mmcau_1_cmd(AESS+CAA) + mov sl, r5 @ sl = *mmcau_direct_cmd() + mov fp, r6 @ fp = mmcau_indirect_cmd(LDR+CAA) + +# calculate key_sch[0-5] + ldmia r0, {r0-r1, r3-r6} @ load key[0-5] + rev r0, r0 @ byterev(key[0]) = key_sch[0] + rev r1, r1 @ byterev(key[1]) = key_sch[1] + rev r3, r3 @ byterev(key[2]) = key_sch[2] + rev r4, r4 @ byterev(key[3]) = key_sch[3] + rev r5, r5 @ byterev(key[4]) = key_sch[4] + rev r6, r6 @ byterev(key[5]) = key_sch[5] + stmia r2!, {r0-r1, r3-r6} @ store key_sch[0-5] + +# calculate key_sch[6-11] + mov ip, r5 @ temporarily store key_sch[4] + mov lr, r6 @ temporarily store key_sch[5] + mov r7, r8 + ldr r5, [r7, #0<<2] @ load rcon[0] + movs r7, #24 + rors r6, r7 @ ROTL(key_sch[5],8) + mov r7, fp + str r6, [r7] @ ROTL(key_sch[5],8) -> acc + mov r6, r9 + mov r7, sl + str r6, [r7] @ AES SubBytes + mov r6, fp + adds r6, #64 + ldr r7, [r6] @ load CAA + eors r7, r5 @ XOR rcon[0] + mov r5, ip @ restore key_sch[4] + mov r6, lr @ restore key_sch[5] + eors r0, r7 @ XOR key_sch[0] = key_sch[6] + eors r1, r0 @ XOR key_sch[1] = key_sch[7] + eors r3, r1 @ XOR key_sch[2] = key_sch[8] + eors r4, r3 @ XOR key_sch[3] = key_sch[9] + eors r5, r4 @ XOR key_sch[4] = key_sch[10] + eors r6, r5 @ XOR key_sch[5] = key_sch[11] + stmia r2!, {r0-r1, r3-r6} @ store key_sch[6-11], *key_sch++ + +# calculate key_sch[12-17] + mov ip, r5 @ temporarily store key_sch[10] + mov lr, r6 @ temporarily store key_sch[11] + mov r7, r8 + ldr r5, [r7, #1<<2] @ load rcon[1] + movs r7, #24 + rors r6, r7 @ ROTL(key_sch[11],8) + mov r7, fp + str r6, [r7] @ ROTL(key_sch[11],8) -> acc + mov r6, r9 + mov r7, sl + str r6, [r7] @ AES SubBytes + mov r6, fp + adds r6, #64 + ldr r7, [r6] @ load CAA + eors r7, r5 @ XOR rcon[1] + mov r5, ip @ restore key_sch[10] + mov r6, lr @ restore key_sch[11] + eors r0, r7 @ XOR key_sch[6] = key_sch[12] + eors r1, r0 @ XOR key_sch[7] = key_sch[13] + eors r3, r1 @ XOR key_sch[8] = key_sch[14] + eors r4, r3 @ XOR key_sch[9] = key_sch[15] + eors r5, r4 @ XOR key_sch[10] = key_sch[16] + eors r6, r5 @ XOR key_sch[11] = key_sch[17] + stmia r2!, {r0-r1, r3-r6} @ store key_sch[12-17], *key_sch++ + +# calculate key_sch[18-23] + mov ip, r5 @ temporarily store key_sch[16] + mov lr, r6 @ temporarily store key_sch[17] + mov r7, r8 + ldr r5, [r7, #2<<2] @ load rcon[2] + movs r7, #24 + rors r6, r7 @ ROTL(key_sch[17],8) + mov r7, fp + str r6, [r7] @ ROTL(key_sch[17],8) -> acc + mov r6, r9 + mov r7, sl + str r6, [r7] @ AES SubBytes + mov r6, fp + adds r6, #64 + ldr r7, [r6] @ load CAA + eors r7, r5 @ XOR rcon[2] + mov r5, ip @ restore key_sch[16] + mov r6, lr @ restore key_sch[17] + eors r0, r7 @ XOR key_sch[12] = key_sch[18] + eors r1, r0 @ XOR key_sch[13] = key_sch[19] + eors r3, r1 @ XOR key_sch[14] = key_sch[20] + eors r4, r3 @ XOR key_sch[15] = key_sch[21] + eors r5, r4 @ XOR key_sch[16] = key_sch[22] + eors r6, r5 @ XOR key_sch[17] = key_sch[23] + stmia r2!, {r0-r1, r3-r6} @ store key_sch[18-23], *key_sch++ + +# calculate key_sch[24-29] + mov ip, r5 @ temporarily store key_sch[22] + mov lr, r6 @ temporarily store key_sch[23] + mov r7, r8 + ldr r5, [r7, #3<<2] @ load rcon[3] + movs r7, #24 + rors r6, r7 @ ROTL(key_sch[23],8) + mov r7, fp + str r6, [r7] @ ROTL(key_sch[23],8) -> acc + mov r6, r9 + mov r7, sl + str r6, [r7] @ AES SubBytes + mov r6, fp + adds r6, #64 + ldr r7, [r6] @ load CAA + eors r7, r5 @ XOR rcon[3] + mov r5, ip @ restore key_sch[22] + mov r6, lr @ restore key_sch[23] + eors r0, r7 @ XOR key_sch[18] = key_sch[24] + eors r1, r0 @ XOR key_sch[19] = key_sch[25] + eors r3, r1 @ XOR key_sch[20] = key_sch[26] + eors r4, r3 @ XOR key_sch[21] = key_sch[27] + eors r5, r4 @ XOR key_sch[22] = key_sch[28] + eors r6, r5 @ XOR key_sch[23] = key_sch[29] + stmia r2!, {r0-r1, r3-r6} @ store key_sch[24-29], *key_sch++ + +# calculate key_sch[30-35] + mov ip, r5 @ temporarily store key_sch[28] + mov lr, r6 @ temporarily store key_sch[29] + mov r7, r8 + ldr r5, [r7, #4<<2] @ load rcon[4] + movs r7, #24 + rors r6, r7 @ ROTL(key_sch[29],8) + mov r7, fp + str r6, [r7] @ ROTL(key_sch[29],8) -> acc + mov r6, r9 + mov r7, sl + str r6, [r7] @ AES SubBytes + mov r6, fp + adds r6, #64 + ldr r7, [r6] @ load CAA + eors r7, r5 @ XOR rcon[4] + mov r5, ip @ restore key_sch[28] + mov r6, lr @ restore key_sch[29] + eors r0, r7 @ XOR key_sch[24] = key_sch[30] + eors r1, r0 @ XOR key_sch[25] = key_sch[31] + eors r3, r1 @ XOR key_sch[26] = key_sch[32] + eors r4, r3 @ XOR key_sch[27] = key_sch[33] + eors r5, r4 @ XOR key_sch[28] = key_sch[34] + eors r6, r5 @ XOR key_sch[29] = key_sch[35] + stmia r2!, {r0-r1, r3-r6} @ store key_sch[30-35], *key_sch++ + +# calculate key_sch[36-41] + mov ip, r5 @ temporarily store key_sch[34] + mov lr, r6 @ temporarily store key_sch[35] + mov r7, r8 + ldr r5, [r7, #5<<2] @ load rcon[5] + movs r7, #24 + rors r6, r7 @ ROTL(key_sch[35],8) + mov r7, fp + str r6, [r7] @ ROTL(key_sch[35],8) -> acc + mov r6, r9 + mov r7, sl + str r6, [r7] @ AES SubBytes + mov r6, fp + adds r6, #64 + ldr r7, [r6] @ load CAA + eors r7, r5 @ XOR rcon[5] + mov r5, ip @ restore key_sch[34] + mov r6, lr @ restore key_sch[35] + eors r0, r7 @ XOR key_sch[30] = key_sch[36] + eors r1, r0 @ XOR key_sch[31] = key_sch[37] + eors r3, r1 @ XOR key_sch[32] = key_sch[38] + eors r4, r3 @ XOR key_sch[33] = key_sch[39] + eors r5, r4 @ XOR key_sch[34] = key_sch[40] + eors r6, r5 @ XOR key_sch[35] = key_sch[41] + stmia r2!, {r0-r1, r3-r6} @ store key_sch[35-41], *key_sch++ + +# calculate key_sch[42-47] + mov ip, r5 @ temporarily store key_sch[40] + mov lr, r6 @ temporarily store key_sch[41] + mov r7, r8 + ldr r5, [r7, #6<<2] @ load rcon[6] + movs r7, #24 + rors r6, r7 @ ROTL(key_sch[41],8) + mov r7, fp + str r6, [r7] @ ROTL(key_sch[41],8) -> acc + mov r6, r9 + mov r7, sl + str r6, [r7] @ AES SubBytes + mov r6, fp + adds r6, #64 + ldr r7, [r6] @ load CAA + eors r7, r5 @ XOR rcon[6] + mov r5, ip @ restore key_sch[40] + mov r6, lr @ restore key_sch[41] + eors r0, r7 @ XOR key_sch[36] = key_sch[42] + eors r1, r0 @ XOR key_sch[37] = key_sch[43] + eors r3, r1 @ XOR key_sch[38] = key_sch[44] + eors r4, r3 @ XOR key_sch[39] = key_sch[45] + eors r5, r4 @ XOR key_sch[40] = key_sch[46] + eors r6, r5 @ XOR key_sch[41] = key_sch[47] + stmia r2!, {r0-r1, r3-r6} @ store key_sch[42-47], *key_sch++ + +# calculate key_sch[48-51] + mov r7, r8 + ldr r5, [r7, #7<<2] @ load rcon[7] + movs r7, #24 + rors r6, r7 @ ROTL(key_sch[47],8) + mov r7, fp + str r6, [r7] @ ROTL(key_sch[47],8) -> acc + mov r6, r9 + mov r7, sl + str r6, [r7] @ AES SubBytes + mov r6, fp + adds r6, #64 + ldr r7, [r6] @ load CAA + eors r7, r5 @ XOR rcon[7] + eors r0, r7 @ XOR key_sch[42] = key_sch[48] + eors r1, r0 @ XOR key_sch[43] = key_sch[49] + eors r3, r1 @ XOR key_sch[44] = key_sch[50] + eors r4, r3 @ XOR key_sch[45] = key_sch[51] + stmia r2!, {r0-r1, r3-r4} @ store key_sch[48-51], *key_sch++ + + b set_key_end @ end routine + + +set_key_128: + +# REGISTER | ALLOCATION (throughout set_key_128) +# -----------+------------------------------------------------------------ +# r0 | rcon[i] +# r1 | scratch +# r2 | *key_sch +# r3 | key_sch[0+4i] +# r4 | key_sch[1+4i] +# r5 | key_sch[2+4i] +# r6 | key_sch[3+4i] +# r7 | scratch +# r8 | *rcon +# r9 | mmcau_1_cmd(AESS+CAA) +# (sl) r10 | *mmcau_direct_cmd() +# (fp) r11 | mmcau_indirect_cmd(LDR+CAA) +# (ip) r12 | mmcau_indirect_cmd(STR+CAA) +# (sp) r13 | stack pointer +# (lr) r14 | link register + +# load some of the regs in preperation of the AES-128 set key calculations + ldmia r3, {r3-r7} + mov r8, r3 @ r8 = *rcon + mov r9, r4 @ r9 = mmcau_1_cmd(AESS+CAA) + mov sl, r5 @ sl = *mmcau_direct_cmd() + mov fp, r6 @ fp = mmcau_indirect_cmd(LDR+CAA) + mov ip, r7 @ ip = mmcau_indirect_cmd(STR+CAA) + +# calculate key_sch[0-3] + ldmia r0!, {r3-r6} @ load key[0-3] + rev r3, r3 @ byterev(key[0]) = key_sch[0] + rev r4, r4 @ byterev(key[1]) = key_sch[1] + rev r5, r5 @ byterev(key[2]) = key_sch[2] + rev r6, r6 @ byterev(key[3]) = key_sch[3] + stmia r2!, {r3-r6} @ store key_sch[0-3], *key_sch++ + +# calculate key_sch[4-7] + mov r7, r8 + ldr r0, [r7, #0<<2] @ load rcon[0] + movs r7, #24 + mov r1, r6 @ copy key_sch[3] + rors r1, r7 @ ROTL(key_sch[3],8) + mov r7, fp + str r1, [r7] @ ROTL(key_sch[3],8) -> acc + mov r1, r9 + mov r7, sl + str r1, [r7] @ AES SubBytes + mov r1, ip + ldr r7, [r1] @ load CAA + eors r7, r0 @ XOR rcon[0] + eors r3, r7 @ XOR key_sch[0] = key_sch[4] + eors r4, r3 @ XOR key_sch[1] = key_sch[5] + eors r5, r4 @ XOR key_sch[2] = key_sch[6] + eors r6, r5 @ XOR key_sch[3] = key_sch[7] + stmia r2!, {r3-r6} @ store key_sch[4-7], *key_sch++ + +# calculate key_sch[8-11] + mov r7, r8 + ldr r0, [r7, #1<<2] @ load rcon[1] + movs r7, #24 + mov r1, r6 @ copy key_sch[7] + rors r1, r7 @ ROTL(key_sch[7],8) + mov r7, fp + str r1, [r7] @ ROTL(key_sch[7],8) -> acc + mov r1, r9 + mov r7, sl + str r1, [r7] @ AES SubBytes + mov r1, ip + ldr r7, [r1] @ load CAA + eors r7, r0 @ XOR rcon[1] + eors r3, r7 @ XOR key_sch[4] = key_sch[8] + eors r4, r3 @ XOR key_sch[5] = key_sch[9] + eors r5, r4 @ XOR key_sch[6] = key_sch[10] + eors r6, r5 @ XOR key_sch[7] = key_sch[11] + stmia r2!, {r3-r6} @ store key_sch[8-11], *key_sch++ + +# calculate key_sch[12-15] + mov r7, r8 + ldr r0, [r7, #2<<2] @ load rcon[2] + movs r7, #24 + mov r1, r6 @ copy key_sch[11] + rors r1, r7 @ ROTL(key_sch[11],8) + mov r7, fp + str r1, [r7] @ ROTL(key_sch[11],8) -> acc + mov r1, r9 + mov r7, sl + str r1, [r7] @ AES SubBytes + mov r1, ip + ldr r7, [r1] @ load CAA + eors r7, r0 @ XOR rcon[2] + eors r3, r7 @ XOR key_sch[8] = key_sch[12] + eors r4, r3 @ XOR key_sch[9] = key_sch[13] + eors r5, r4 @ XOR key_sch[10] = key_sch[14] + eors r6, r5 @ XOR key_sch[11] = key_sch[15] + stmia r2!, {r3-r6} @ store key_sch[12-15], *key_sch++ + +# calculate key_sch[16-19] + mov r7, r8 + ldr r0, [r7, #3<<2] @ load rcon[3] + movs r7, #24 + mov r1, r6 @ copy key_sch[15] + rors r1, r7 @ ROTL(key_sch[15],8) + mov r7, fp + str r1, [r7] @ ROTL(key_sch[15],8) -> acc + mov r1, r9 + mov r7, sl + str r1, [r7] @ AES SubBytes + mov r1, ip + ldr r7, [r1] @ load CAA + eors r7, r0 @ XOR rcon[3] + eors r3, r7 @ XOR key_sch[12] = key_sch[16] + eors r4, r3 @ XOR key_sch[13] = key_sch[17] + eors r5, r4 @ XOR key_sch[14] = key_sch[18] + eors r6, r5 @ XOR key_sch[15] = key_sch[19] + stmia r2!, {r3-r6} @ store key_sch[16-19], *key_sch++ + +# calculate key_sch[20-23] + mov r7, r8 + ldr r0, [r7, #4<<2] @ load rcon[4] + movs r7, #24 + mov r1, r6 @ copy key_sch[19] + rors r1, r7 @ ROTL(key_sch[19],8) + mov r7, fp + str r1, [r7] @ ROTL(key_sch[19],8) -> acc + mov r1, r9 + mov r7, sl + str r1, [r7] @ AES SubBytes + mov r1, ip + ldr r7, [r1] @ load CAA + eors r7, r0 @ XOR rcon[4] + eors r3, r7 @ XOR key_sch[16] = key_sch[20] + eors r4, r3 @ XOR key_sch[17] = key_sch[21] + eors r5, r4 @ XOR key_sch[18] = key_sch[22] + eors r6, r5 @ XOR key_sch[19] = key_sch[23] + stmia r2!, {r3-r6} @ store key_sch[20-23], *key_sch++ + +# calculate key_sch[24-27] + mov r7, r8 + ldr r0, [r7, #5<<2] @ load rcon[5] + movs r7, #24 + mov r1, r6 @ copy key_sch[23] + rors r1, r7 @ ROTL(key_sch[23],8) + mov r7, fp + str r1, [r7] @ ROTL(key_sch[23],8) -> acc + mov r1, r9 + mov r7, sl + str r1, [r7] @ AES SubBytes + mov r1, ip + ldr r7, [r1] @ load CAA + eors r7, r0 @ XOR rcon[5] + eors r3, r7 @ XOR key_sch[20] = key_sch[24] + eors r4, r3 @ XOR key_sch[21] = key_sch[25] + eors r5, r4 @ XOR key_sch[22] = key_sch[26] + eors r6, r5 @ XOR key_sch[23] = key_sch[27] + stmia r2!, {r3-r6} @ store key_sch[24-27], *key_sch++ + +# calculate key_sch[28-31] + mov r7, r8 + ldr r0, [r7, #6<<2] @ load rcon[6] + movs r7, #24 + mov r1, r6 @ copy key_sch[27] + rors r1, r7 @ ROTL(key_sch[27],8) + mov r7, fp + str r1, [r7] @ ROTL(key_sch[27],8) -> acc + mov r1, r9 + mov r7, sl + str r1, [r7] @ AES SubBytes + mov r1, ip + ldr r7, [r1] @ load CAA + eors r7, r0 @ XOR rcon[6] + eors r3, r7 @ XOR key_sch[24] = key_sch[28] + eors r4, r3 @ XOR key_sch[25] = key_sch[29] + eors r5, r4 @ XOR key_sch[26] = key_sch[30] + eors r6, r5 @ XOR key_sch[27] = key_sch[31] + stmia r2!, {r3-r6} @ store key_sch[28-31], *key_sch++ + +# calculate key_sch[32-35] + mov r7, r8 + ldr r0, [r7, #7<<2] @ load rcon[7] + movs r7, #24 + mov r1, r6 @ copy key_sch[31] + rors r1, r7 @ ROTL(key_sch[31],8) + mov r7, fp + str r1, [r7] @ ROTL(key_sch[31],8) -> acc + mov r1, r9 + mov r7, sl + str r1, [r7] @ AES SubBytes + mov r1, ip + ldr r7, [r1] @ load CAA + eors r7, r0 @ XOR rcon[7] + eors r3, r7 @ XOR key_sch[28] = key_sch[32] + eors r4, r3 @ XOR key_sch[29] = key_sch[33] + eors r5, r4 @ XOR key_sch[30] = key_sch[34] + eors r6, r5 @ XOR key_sch[31] = key_sch[35] + stmia r2!, {r3-r6} @ store key_sch[32-35], *key_sch++ + +# calculate key_sch[36-39] + mov r7, r8 + ldr r0, [r7, #8<<2] @ load rcon[8] + movs r7, #24 + mov r1, r6 @ copy key_sch[35] + rors r1, r7 @ ROTL(key_sch[35],8) + mov r7, fp + str r1, [r7] @ ROTL(key_sch[35],8) -> acc + mov r1, r9 + mov r7, sl + str r1, [r7] @ AES SubBytes + mov r1, ip + ldr r7, [r1] @ load CAA + eors r7, r0 @ XOR rcon[8] + eors r3, r7 @ XOR key_sch[32] = key_sch[36] + eors r4, r3 @ XOR key_sch[33] = key_sch[37] + eors r5, r4 @ XOR key_sch[34] = key_sch[38] + eors r6, r5 @ XOR key_sch[35] = key_sch[39] + stmia r2!, {r3-r6} @ store key_sch[36-39], *key_sch++ + +# calculate key_sch[40-43] + mov r7, r8 + ldr r0, [r7, #9<<2] @ load rcon[9] + movs r7, #24 + mov r1, r6 @ copy key_sch[39] + rors r1, r7 @ ROTL(key_sch[39],8) + mov r7, fp + str r1, [r7] @ ROTL(key_sch[39],8) -> acc + mov r1, r9 + mov r7, sl + str r1, [r7] @ AES SubBytes + mov r1, ip + ldr r7, [r1] @ load CAA + eors r7, r0 @ XOR rcon[9] + eors r3, r7 @ XOR key_sch[36] = key_sch[40] + eors r4, r3 @ XOR key_sch[37] = key_sch[41] + eors r5, r4 @ XOR key_sch[38] = key_sch[42] + eors r6, r5 @ XOR key_sch[39] = key_sch[43] + stmia r2!, {r3-r6} @ store key_sch[40-43], *key_sch++ + + +set_key_end: + + pop {r3-r7} @ restore high regs + mov r8, r3 + mov r9, r4 + mov sl, r5 + mov fp, r6 + mov ip, r7 + pop {r4-r7, pc} @ restore low regs, exit routine + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_AES_ENCRYPT +# Encrypts a single 16-byte block +# +# ARGUMENTS +# *in pointer to 16-byte block of input plaintext +# *key_sch pointer to key schedule (44, 52, 60 longwords) +# nr number of AES rounds (10, 12, 14 = f(key_schedule)) +# *out pointer to 16-byte block of output ciphertext +# +# +# CALLING CONVENTION +# void mmcau_aes_encrypt (const unsigned char *in, +# const unsigned char *key_sch, +# const int nr, +# unsigned char *out) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_aes_encrypt) +# -----------+------------------------------------------------------------ +# r0 | *in (arg0) +# r1 | *key_sch (arg1) +# r2 | nr (arg2) +# r3 | *out (arg3) +# | +# > r3 | irrelevant +# +# +# REGISTER | ALLOCATION (throughout mmcau_aes_encrypt) +# -----------+------------------------------------------------------------ +# r0 | mmcau_3_cmds(AESS+CA0,AESS+CA1,AESS+CA2) +# r1 | *key_sch +# r2 | *mmcau_direct_cmd() +# r3 | scratch +# r4 | key_sch[0+4i] +# r5 | key_sch[1+4i] +# r6 | key_sch[2+4i] +# r7 | key_sch[3+4i] +# r8 | mmcau_indirect_cmd(AESC+CA0) +# r9 | not used +# (sl) r10 | not used +# (fp) r11 | not used +# (ip) r12 | not used +# (sp) r13 | stack pointer +# (lr) r14 | mmcau_2_cmds(AESS+CA3,AESR) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_aes_encrypt + .global mmcau_aes_encrypt + .type mmcau_aes_encrypt, %function + .align 4 + +_mmcau_aes_encrypt: +mmcau_aes_encrypt: + +# store nr and *out, we need them later in the routine +# store regs r4-r8, we need to restore them at the end of the routine + push {r2-r7, lr} @ store nr, *out, low regs, and lr + mov r4, r8 + push {r4} @ store high reg + +# XOR the first 4 keys into the 4 words of plaintext + ldmia r1!, {r4-r7} @ load first 4 keys, *key_sch++ + mov lr, r1 @ temporarily store *key_sch[4] + ldmia r0, {r0-r3} @ load plaintext + rev r0, r0 + rev r1, r1 + rev r2, r2 + rev r3, r3 + eors r4, r0 + eors r5, r1 + eors r6, r2 + eors r7, r3 + ldr r1, =MMCAU_PPB_INDIRECT+(LDR+CA0)<<2 + stmia r1!, {r4-r7} @ store XOR results in CA[0-3] + +# load some of the regs in preperation of the encryption + ldr r0, =encrypt_reg_data + ldmia r0, {r0-r3} + mov r8, r1 @ r8 = mmcau_indirect_cmd(AESC+CA0) + mov r1, lr @ restore r1 = *key_sch[4] + mov lr, r3 @ lr = mmcau_2_cmds(AESS+CA3,AESR) + +# send a series of cau commands to perform the encryption + str r0, [r2] @ SubBytes + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + + ldr r3, [sp, #1<<2] @ load nr + cmp r3, #10 @ check nr + beq encrypt_end @ if aes128, end routine + @ else, continue on + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + + ldr r3, [sp, #1<<2] @ load nr + cmp r3, #12 @ check nr + beq encrypt_end @ if aes192, end routine + @ else, continue on + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ load next 4 keys, *key_sch++ + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + +encrypt_end: + + str r0, [r2] @ SubBytes + mov r3, lr + str r3, [r2] @ SubBytes, ShiftRows + +# XOR the last 4 keys with the 4 words of ciphertext + ldr r0, =MMCAU_PPB_INDIRECT+(STR+CA0)<<2 + ldmia r1!, {r4-r7} @ load last 4 keys + ldmia r0, {r0-r3} @ load ciphertext + eors r4, r0 + eors r5, r1 + eors r6, r2 + eors r7, r3 + rev r4, r4 + rev r5, r5 + rev r6, r6 + rev r7, r7 + ldr r1, [sp, #2<<2] @ get *out + stmia r1!, {r4-r7} @ store XOR results in out[0-3] + + pop {r4} @ restore high reg + mov r8, r4 + add sp, #2<<2 @ set sp = *{r4-r7} + pop {r4-r7, pc} @ restore low regs, exit routine + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_AES_DECRYPT +# Decrypts a single 16-byte block +# +# ARGUMENTS +# *in pointer to 16-byte block of input chiphertext +# *key_sch pointer to key schedule (44, 52, 60 longwords) +# nr number of AES rounds (10, 12, 14 = f(key_schedule)) +# *out pointer to 16-byte block of output plaintext +# +# +# CALLING CONVENTION +# void mmcau_aes_decrypt (const unsigned char *in, +# const unsigned char *key_sch, +# const int nr, +# unsigned char *out) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_aes_decrypt) +# -----------+------------------------------------------------------------ +# r0 | *in (arg0) +# r1 | *key_sch (arg1) +# r2 | nr (arg2) +# r3 | *out (arg3) +# | +# > r3 | irrelevant +# +# +# REGISTER | ALLOCATION (throughout mmcau_aes_decrypt) +# -----------+------------------------------------------------------------ +# r0 | mmcau_3_cmds(AESIR,AESIS+CA3,AESIS+CA) +# r1 | *key_sch +# r2 | *mmcau_direct_cmd() +# r3 | scratch +# r4 | *key_sch[0-4i] +# r5 | *key_sch[1-4i] +# r6 | *key_sch[2-4i] +# r7 | *key_sch[3-4i] +# r8 | mmcau_indirect_cmd(AESIC+CA0) +# r9 | not used +# (sl) r10 | not used +# (fp) r11 | not used +# (ip) r12 | not used +# (sp) r13 | stack pointer +# (lr) r14 | mmcau_2_cmds(AESIS+CA1,AESIS+CA0) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_aes_decrypt + .global mmcau_aes_decrypt + .type mmcau_aes_decrypt, %function + .align 4 + +_mmcau_aes_decrypt: +mmcau_aes_decrypt: + +# store nr and *out, we need them later in the routine +# store regs r4-r8, we need to restore them at the end of the routine + push {r2-r7, lr} @ store nr, *out, low regs, and lr + mov r4, r8 + push {r4} @ store high reg + +# *key_sch is adjusted to define the end of the elements, such that +# the adjustment factor = f(nr) is defined by the expression: +# end of key_sch = 4 * (nr + 1), where nr = {10, 12, 14} + movs r3, #28 + rors r2, r3 + add r1, r2 @ calculate end of key_sch + mov lr, r1 @ temporarily store end of key_sch + +# XOR the last 4 keys into the 4 words of ciphertext + ldmia r1!, {r4-r7} @ load last 4 keys + ldmia r0, {r0-r3} @ load ciphertext + rev r0, r0 + rev r1, r1 + rev r2, r2 + rev r3, r3 + eors r4, r0 + eors r5, r1 + eors r6, r2 + eors r7, r3 + ldr r1, =MMCAU_PPB_INDIRECT+(LDR+CA0)<<2 + stmia r1!, {r4-r7} @ store XOR results in CA[0-3] + +# load some of the regs in preperation of the decryption + ldr r0, =decrypt_reg_data + ldmia r0, {r0-r3} + mov r8, r1 @ r8 = mmcau_indirect_cmd(AESC+CA0) + mov r1, lr @ restore end of key_sch + subs r1, #4<<2 @ *key_sch-- + mov lr, r3 @ lr = mmcau_2_cmds(AESS+CA3,AESR) + +# send a series of cau commands to perform the decryption + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + + ldr r3, [sp, #1<<2] @ restore nr + cmp r3, #10 @ check nr + beq decrypt_end @ if aes128, end routine + @ else, continue on + + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + + ldr r3, [sp, #1<<2] @ restore nr + cmp r3, #12 @ check nr + beq decrypt_end @ if aes192, end routine + @ else, continue on + + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + ldmia r1!, {r4-r7} @ load previous 4 keys + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + subs r1, #8<<2 @ *key_sch-- + str r3, [r2] @ InvSubBytes + mov r3, r8 + stmia r3!, {r4-r7} @ MixColumns + + +decrypt_end: + + str r0, [r2] @ InvShiftRows, InvSubBytes + mov r3, lr + str r3, [r2] @ InvSubBytes + +# XOR the first 4 keys with the 4 words of plaintext + ldr r0, =MMCAU_PPB_INDIRECT+(STR+CA0)<<2 + ldmia r1!, {r4-r7} @ load first 4 keys + ldmia r0, {r0-r3} @ load plaintext + eors r4, r0 + eors r5, r1 + eors r6, r2 + eors r7, r3 + rev r4, r4 + rev r5, r5 + rev r6, r6 + rev r7, r7 + ldr r1, [sp, #2<<2] @ get *out + stmia r1!, {r4-r7} @ store XOR results in out[0-3] + + pop {r4} @ restore high reg + mov r8, r4 + add sp, #2<<2 @ set sp = *{r4-r7} + pop {r4-r7, pc} @ restore low regs, exit routine + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .data + + + .type set_key_reg_data, %object + .align 4 + +set_key_reg_data: + .word rcon @ r8 + .word MMCAU_1_CMD+(AESS+CAA)<<22 @ r9 + .word MMCAU_PPB_DIRECT @ sl + .word MMCAU_PPB_INDIRECT+(LDR+CAA)<<2 @ fp + .word MMCAU_PPB_INDIRECT+(STR+CAA)<<2 @ ip + + + .type encrypt_reg_data, %object + .align 4 + +encrypt_reg_data: + .word MMCAU_3_CMDS+(AESS+CA0)<<22+(AESS+CA1)<<11+AESS+CA2 @ r0 + .word MMCAU_PPB_INDIRECT+(AESC+CA0)<<2 @ r8 + .word MMCAU_PPB_DIRECT @ r2 + .word MMCAU_2_CMDS+(AESS+CA3)<<22+(AESR)<<11 @ lr + + + .type decrypt_reg_data, %object + .align 4 + +decrypt_reg_data: + .word MMCAU_3_CMDS+(AESIR)<<22+(AESIS+CA3)<<11+AESIS+CA2 @ r0 + .word MMCAU_PPB_INDIRECT+(AESIC+CA0)<<2 @ r8 + .word MMCAU_PPB_DIRECT @ r2 + .word MMCAU_2_CMDS+(AESIS+CA1)<<22+(AESIS+CA0)<<11 @ lr + + + .type rcon, %object + .align 4 + +rcon: + .word 0x01000000 + .word 0x02000000 + .word 0x04000000 + .word 0x08000000 + .word 0x10000000 + .word 0x20000000 + .word 0x40000000 + .word 0x80000000 + .word 0x1b000000 + .word 0x36000000 diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_des_functions.s b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_des_functions.s new file mode 100755 index 0000000..817fe41 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_des_functions.s @@ -0,0 +1,271 @@ +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# Copyright (c) Freescale Semiconductor, Inc 2013. +# +# FILE NAME : mmcau_des_functions.s +# VERSION : $Id: $ +# TYPE : Source Cortex-M0+ assembly library code +# DEPARTMENT : MCG R&D Cores and Platforms +# AUTHOR : Anthony (Teejay) Ciancio +# AUTHOR EMAIL : teejay.ciancio@freescale.com +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# VERSION DATE AUTHOR DESCRIPTION +# ******* **** ****** *********** +# 1.0 2013-11 Ciancio initial release, using the ARMv6-M ISA +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + + .include "cau2_defines.hdr" + .syntax unified + + + .equ MMCAU_PPB_DIRECT, 0xf0005000 + .equ MMCAU_PPB_INDIRECT, 0xf0005800 + .equ MMCAU_1_CMD, 0x80000000 + .equ MMCAU_2_CMDS, 0x80100000 + .equ MMCAU_3_CMDS, 0x80100200 + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_DES_CHK_PARITY +# Check key parity +# +# ARGUMENTS +# *key pointer to 64-bit DES key with parity bits +# return 0 no error +# -1 parity error +# +# CALLING CONVENTION +# int mmcau_des_chk_parity (const unsigned char *key) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_des_chk_parity) +# -----------+------------------------------------------------------------ +# r0 | *key (arg0) +# | +# > r0 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_des_chk_parity + .global mmcau_des_chk_parity + .type mmcau_des_chk_parity, %function + .align 4 + +_mmcau_des_chk_parity: +mmcau_des_chk_parity: + +# load the 64-bit key into the CAU's CA0/CA1 regs + ldr r3, =MMCAU_PPB_INDIRECT+((LDR+CA0)<<2) + ldmia r0!, {r1-r2} @ load key + str r1, [r3, #0<<2] @ store lower half in CA0 + str r2, [r3, #1<<2] @ store upper half in CA1 + + ldr r1, =MMCAU_PPB_DIRECT + ldr r2, =MMCAU_1_CMD+((DESK+CP)<<22) + str r2, [r1] @ perform the key schedule + +# CASR[31:28] contain the version number, we left-shift that off +# CASR[27:2] and CASR[0] are always 0 +# CASR[1] is the DPE bit, which equals 1 if parity error or 0 if no error + ldr r0, [r3, #(((STR+CASR)-(LDR+CA0))<<2)] @ load CASR + lsls r0, #4 @ shift off version number + beq mmcau_des_chk_parity_end @ check the DPE bit + +# if parity error, + movs r0, #1 + negs r0, r0 @ return -1 + +# else (no error), +mmcau_des_chk_parity_end: + bx lr @ return 0 + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_DES_ENCRYPT +# Encrypts a single 8-byte block +# +# ARGUMENTS +# *in pointer to 8-byte block of input plaintext +# *key pointer to 64-bit DES key with parity bits +# *out pointer to 8-byte block of output ciphertext +# +# NOTE +# Input and output blocks may overlap +# +# CALLING CONVENTION +# void mmcau_des_encrypt (const unsigned char *in, +# const unsigned char *key, +# unsigned char *out) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_des_encrypt) +# -----------+------------------------------------------------------------ +# r0 | *in (arg0) +# r1 | *key (arg1) +# r2 | *out (arg2) +# | +# > r2 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_des_encrypt + .global mmcau_des_encrypt + .type mmcau_des_encrypt, %function + .align 4 + +_mmcau_des_encrypt: +mmcau_des_encrypt: + +# store regs r4-r7, we need to restore them at the end of the routine + push {r4-r7} @ store regs + +# load the 64-bit key into the CAU's CA0/CA1 regs +# load the 64-bit plaintext input block into the CAU's CA2/CA3 regs + ldr r7, =MMCAU_PPB_INDIRECT+((LDR+CA0)<<2) + ldmia r1!, {r3-r4} @ load key + rev r3, r3 + rev r4, r4 + ldmia r0!, {r5-r6} @ load plaintext + rev r5, r5 + rev r6, r6 + stmia r7!, {r3-r6} @ store in CA[0-3] + +# send a series of 17 direct cau commands to perform the DES round operations +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESK,DESR+IP+KSL1,DESR+KSL2) 1- 3 +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL2) 4- 6 +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL1) 7- 9 +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL2) 10-12 +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL2) 13-15 +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(DESR+KSL1,DESR+FP) 16-17 + ldr r0, =encrypt_reg_data + ldmia r0, {r0-r1, r3-r6} @ load commands + str r3, [r0] @ send commands 1- 3 + str r4, [r0] @ " " 4- 6 + str r5, [r0] @ " " 7- 9 + str r4, [r0] @ " " 10-12 + str r4, [r0] @ " " 13-15 + str r6, [r0] @ " " 16-17 + +# store the 64-bit ciphertext output block into memory + ldmia r1, {r0-r1} @ load ciphertext + rev r0, r0 + rev r1, r1 + stmia r2!, {r0-r1} @ store in out[0-1] + + pop {r4-r7} @ restore regs + bx lr @ exit routine + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_DES_DECRYPT +# Decrypts a single 8-byte block +# +# ARGUMENTS +# *in pointer to 8-byte block of input ciphertext +# *key pointer to 64-bit DES key with parity bits +# *out pointer to 8-byte block of output plaintext +# +# NOTE +# Input and output blocks may overlap +# +# CALLING CONVENTION +# void mmcau_des_decrypt (const unsigned char *in, +# const unsigned char *key, +# unsigned char *out) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_des_decrypt) +# -----------+------------------------------------------------------------ +# r0 | *in (arg0) +# r1 | *key (arg1) +# r2 | *out (arg2) +# | +# > r2 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_des_decrypt + .global mmcau_des_decrypt + .type mmcau_des_decrypt, %function + .align 4 + +_mmcau_des_decrypt: +mmcau_des_decrypt: + +# store regs r4-r7, we need to restore them at the end of the routine + push {r4-r7} @ store regs + +# load the 64-bit key into the CAU's CA0/CA1 regs +# load the 64-bit ciphertext input block into the CAU's CA2/CA3 regs + ldr r7, =MMCAU_PPB_INDIRECT+((LDR+CA0)<<2) + ldmia r1!, {r3-r4} @ load key + rev r3, r3 + rev r4, r4 + ldmia r0!, {r5-r6} @ load ciphertext + rev r5, r5 + rev r6, r6 + stmia r7!, {r3-r6} @ store in CA[0-3] + +# send a series of 17 direct cau commands to perform the DES round operations +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESK+DC,DESR+IP+KSR1,DESR+KSR2) 1- 3 +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR2) 4- 6 +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR1) 7- 9 +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR2) 10-12 +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR2) 13-15 +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(DESR+KSR1,DESR+FP) 16-17 + ldr r0, =decrypt_reg_data + ldmia r0, {r0-r1, r3-r6} @ load commands + str r3, [r0] @ send commands 1- 3 + str r4, [r0] @ " " 4- 6 + str r5, [r0] @ " " 7- 9 + str r4, [r0] @ " " 10-12 + str r4, [r0] @ " " 13-15 + str r6, [r0] @ " " 16-17 + +# store the 64-bit plaintext output block into memory + ldmia r1, {r0-r1} @ load plaintext + rev r0, r0 + rev r1, r1 + stmia r2!, {r0-r1} @ store in out[0-1] + + pop {r4-r7} @ restore regs + bx lr @ exit routine + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .data + + + .type encrypt_reg_data, %object + .align 4 + +encrypt_reg_data: + .word MMCAU_PPB_DIRECT @ r0 + .word MMCAU_PPB_INDIRECT+((STR+CA2)<<2) @ r1 + .word MMCAU_3_CMDS+((DESK)<<22)+((DESR+IP+KSL1)<<11)+DESR+KSL2 @ r3 + .word MMCAU_3_CMDS+((DESR+KSL2)<<22)+((DESR+KSL2)<<11)+DESR+KSL2 @ r4 + .word MMCAU_3_CMDS+((DESR+KSL2)<<22)+((DESR+KSL2)<<11)+DESR+KSL1 @ r5 + .word MMCAU_2_CMDS+((DESR+KSL1)<<22)+((DESR+FP)<<11) @ r6 + + + .type decrypt_reg_data, %object + .align 4 + +decrypt_reg_data: + .word MMCAU_PPB_DIRECT @ r0 + .word MMCAU_PPB_INDIRECT+((STR+CA2)<<2) @ r1 + .word MMCAU_3_CMDS+((DESK+DC)<<22)+((DESR+IP+KSR1)<<11)+DESR+KSR2 @ r3 + .word MMCAU_3_CMDS+((DESR+KSR2)<<22)+((DESR+KSR2)<<11)+DESR+KSR2 @ r4 + .word MMCAU_3_CMDS+((DESR+KSR2)<<22)+((DESR+KSR2)<<11)+DESR+KSR1 @ r5 + .word MMCAU_2_CMDS+((DESR+KSR1)<<22)+((DESR+FP)<<11) @ r6 diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_md5_functions.s b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_md5_functions.s new file mode 100755 index 0000000..c3ef601 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_md5_functions.s @@ -0,0 +1,1168 @@ +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# Copyright (c) Freescale Semiconductor, Inc 2013. +# +# FILE NAME : mmcau_md5_functions.s +# VERSION : $Id: $ +# TYPE : Source Cortex-M0+ assembly library code +# DEPARTMENT : MCG R&D Core and Platforms +# AUTHOR : Anthony (Teejay) Ciancio +# AUTHOR EMAIL : teejay.ciancio@freescale.com +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# VERSION DATE AUTHOR DESCRIPTION +# ******* **** ****** *********** +# 1.0 2013-11 Ciancio initial release, using the ARMv6-M ISA +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + + .include "cau2_defines.hdr" + .syntax unified + + + .equ MMCAU_PPB_DIRECT, 0xf0005000 + .equ MMCAU_PPB_INDIRECT, 0xf0005800 + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_MD5_INITIALIZE_OUTPUT +# Initializes the MD5 state variables +# +# ARGUMENTS +# *md5_state pointer to 120-bit block of md5 state variables: a,b,c,d +# +# CALLING CONVENTION +# void mmcau_md5_initialize_output (const unsigned int *md5_state) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_md5_initialize_output) +# -----------+------------------------------------------------------------ +# r0 | *md5_state (arg0) +# | +# > r0 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_md5_initialize_output + .global mmcau_md5_initialize_output + .type mmcau_md5_initialize_output, %function + .align 4 + +_mmcau_md5_initialize_output: +mmcau_md5_initialize_output: + +# store reg r4, we need to restore it at the end of the routine + push {r4} @ store reg + + ldr r1, =md5_initial_h + ldmia r1, {r1-r4} @ load md5_initial_h[0-3] + stmia r0!, {r1-r4} @ store in md5_state[0-3] + + pop {r4} @ restore reg + bx lr @ exit routine + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_MD5_HASH_N +# Updates MD5 state variables for one or more input message blocks +# +# ARGUMENTS +# *msg_data pointer to start of input message data +# num_blks number of 512-bit blocks to process +# *md5_state pointer to 128-bit block of MD5 state variables: a,b,c,d +# +# CALLING CONVENTION +# void mmucau_md5_hash_n (const unsigned char *msg_data, +# const int num_blks, +# unsigned char *md5_state) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_md5_hash_n) +# -----------+------------------------------------------------------------ +# r0 | *msg_data (arg0) +# r1 | num_blks (arg1) +# r2 | *md5_state (arg2) +# | +# > r2 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_md5_hash_n + .global mmcau_md5_hash_n + .type mmcau_md5_hash_n, %function + .align 4 + +_mmcau_md5_hash_n: +mmcau_md5_hash_n: + +# store num_blks and *md5_state, we need them later in the routine +# store regs r4-r7, we need to restore them at the end of the routine + push {r1-r2, r4-r7} @ store num_blks, *md5_state, regs + +# initialize CAU data regs with current contents of md5_state[0-3] + ldmia r2, {r1-r4} @ load md5_state[0-3] + + ldr r7, =md5_t @ set *md5_t + b next_blk + .ltorg + + + .align 2 +next_blk: + +# REGISTER | ALLOCATION (throughout next_blk) +# -----------+------------------------------------------------------------ +# r0 | *msg_data (arg0) +# r1 | a / num_blks (arg1) +# r2 | b / *md5_state (arg2) +# r3 | c +# r4 | d +# r5 | scratch +# r6 | scratch +# r7 | *md5_t + +# 16 rounds of F(x,y,z) = (x & y) | (~x & z) +# ****************************************** + mov r5, r2 @ b + mvns r6, r2 @ ~b + ands r5, r3 @ b & c + ands r6, r4 @ ~b & d + orrs r5, r6 @ F(b,c,d) + add r1, r5 @ a += F(b,c,d) + ldr r6, [r0, #0<<2] @ load msg_data[0] + add r1, r6 @ a += msg_data[0] + ldmia r7!, {r5} @ load md5_t[0], *md5_t++ + add r1, r5 @ a += md5_t[0] + movs r6, #25 @ amount to rotate + rors r1, r6 @ ROTL(a,7) + add r1, r2 @ a = b + ROTL(a,7) + + mov r5, r1 @ a + mvns r6, r1 @ ~a + ands r5, r2 @ a & b + ands r6, r3 @ ~a & c + orrs r5, r6 @ F(a,b,c) + add r4, r5 @ d += F(a,b,c) + ldr r6, [r0, #1<<2] @ load msg_data[1] + add r4, r6 @ d += msg_data[1] + ldmia r7!, {r5} @ load md5_t[1], *md5_t++ + add r4, r5 @ d += md5_t[1] + movs r6, #20 @ amount to rotate + rors r4, r6 @ ROTL(d,12) + add r4, r1 @ d = a + ROTL(d,12) + + mov r5, r4 @ d + mvns r6, r4 @ ~d + ands r5, r1 @ d & a + ands r6, r2 @ ~d & b + orrs r5, r6 @ F(d,a,b) + add r3, r5 @ c += F(d,a,b) + ldr r6, [r0, #2<<2] @ load msg_data[2] + add r3, r6 @ c += msg_data[2] + ldmia r7!, {r5} @ load md5_t[2], *md5_t++ + add r3, r5 @ c += md5_t[2] + movs r6, #15 @ amount to rotate + rors r3, r6 @ ROTL(c,17) + add r3, r4 @ c = d + ROTL(c,17) + + mov r5, r3 @ c + mvns r6, r3 @ ~c + ands r5, r4 @ c & d + ands r6, r1 @ ~c & a + orrs r5, r6 @ F(c,d,a) + add r2, r5 @ b += F(c,d,a) + ldr r6, [r0, #3<<2] @ load msg_data[3] + add r2, r6 @ b += msg_data[3] + ldmia r7!, {r5} @ load md5_t[3], *md5_t++ + add r2, r5 @ b += md5_t[3] + movs r6, #10 @ amount to rotate + rors r2, r6 @ ROTL(b,22) + add r2, r3 @ b = c + ROTL(b,22) + + mov r5, r2 @ b + mvns r6, r2 @ ~b + ands r5, r3 @ b & c + ands r6, r4 @ ~b & d + orrs r5, r6 @ F(b,c,d) + add r1, r5 @ a += F(b,c,d) + ldr r6, [r0, #4<<2] @ load msg_data[4] + add r1, r6 @ a += msg_data[4] + ldmia r7!, {r5} @ load md5_t[4], *md5_t++ + add r1, r5 @ a += md5_t[4] + movs r6, #25 @ amount to rotate + rors r1, r6 @ ROTL(a,7) + add r1, r2 @ a = b + ROTL(a,7) + + mov r5, r1 @ a + mvns r6, r1 @ ~a + ands r5, r2 @ a & b + ands r6, r3 @ ~a & c + orrs r5, r6 @ F(a,b,c) + add r4, r5 @ d += F(a,b,c) + ldr r6, [r0, #5<<2] @ load msg_data[5] + add r4, r6 @ d += msg_data[5] + ldmia r7!, {r5} @ load md5_t[5], *md5_t++ + add r4, r5 @ d += md5_t[5] + movs r6, #20 @ amount to rotate + rors r4, r6 @ ROTL(d,12) + add r4, r1 @ d = a + ROTL(d,12) + + mov r5, r4 @ d + mvns r6, r4 @ ~d + ands r5, r1 @ d & a + ands r6, r2 @ ~d & b + orrs r5, r6 @ F(d,a,b) + add r3, r5 @ c += F(d,a,b) + ldr r6, [r0, #6<<2] @ load msg_data[6] + add r3, r6 @ c += msg_data[6] + ldmia r7!, {r5} @ load md5_t[6], *md5_t++ + add r3, r5 @ c += md5_t[6] + movs r6, #15 @ amount to rotate + rors r3, r6 @ ROTL(c,17) + add r3, r4 @ c = d + ROTL(c,17) + + mov r5, r3 @ c + mvns r6, r3 @ ~c + ands r5, r4 @ c & d + ands r6, r1 @ ~c & a + orrs r5, r6 @ F(c,d,a) + add r2, r5 @ b += F(c,d,a) + ldr r6, [r0, #7<<2] @ load msg_data[7] + add r2, r6 @ b += msg_data[7] + ldmia r7!, {r5} @ load md5_t[7], *md5_t++ + add r2, r5 @ b += md5_t[7] + movs r6, #10 @ amount to rotate + rors r2, r6 @ ROTL(b,22) + add r2, r3 @ b = c + ROTL(b,22) + + mov r5, r2 @ b + mvns r6, r2 @ ~b + ands r5, r3 @ b & c + ands r6, r4 @ ~b & d + orrs r5, r6 @ F(b,c,d) + add r1, r5 @ a += F(b,c,d) + ldr r6, [r0, #8<<2] @ load msg_data[8] + add r1, r6 @ a += msg_data[8] + ldmia r7!, {r5} @ load md5_t[8], *md5_t++ + add r1, r5 @ a += md5_t[8] + movs r6, #25 @ amount to rotate + rors r1, r6 @ ROTL(a,7) + add r1, r2 @ a = b + ROTL(a,7) + + mov r5, r1 @ a + mvns r6, r1 @ ~a + ands r5, r2 @ a & b + ands r6, r3 @ ~a & c + orrs r5, r6 @ F(a,b,c) + add r4, r5 @ d += F(a,b,c) + ldr r6, [r0, #9<<2] @ load msg_data[9] + add r4, r6 @ d += msg_data[9] + ldmia r7!, {r5} @ load md5_t[9], *md5_t++ + add r4, r5 @ d += md5_t[9] + movs r6, #20 @ amount to rotate + rors r4, r6 @ ROTL(d,12) + add r4, r1 @ d = a + ROTL(d,12) + + mov r5, r4 @ d + mvns r6, r4 @ ~d + ands r5, r1 @ d & a + ands r6, r2 @ ~d & b + orrs r5, r6 @ F(d,a,b) + add r3, r5 @ c += F(d,a,b) + ldr r6, [r0, #10<<2] @ load msg_data[10] + add r3, r6 @ c += msg_data[10] + ldmia r7!, {r5} @ load md5_t[10], *md5_t++ + add r3, r5 @ c += md5_t[10] + movs r6, #15 @ amount to rotate + rors r3, r6 @ ROTL(c,17) + add r3, r4 @ c = d + ROTL(c,17) + + mov r5, r3 @ c + mvns r6, r3 @ ~c + ands r5, r4 @ c & d + ands r6, r1 @ ~c & a + orrs r5, r6 @ F(c,d,a) + add r2, r5 @ b += F(c,d,a) + ldr r6, [r0, #11<<2] @ load msg_data[11] + add r2, r6 @ b += msg_data[11] + ldmia r7!, {r5} @ load md5_t[11], *md5_t++ + add r2, r5 @ b += md5_t[11] + movs r6, #10 @ amount to rotate + rors r2, r6 @ ROTL(b,22) + add r2, r3 @ b = c + ROTL(b,22) + + mov r5, r2 @ b + mvns r6, r2 @ ~b + ands r5, r3 @ b & c + ands r6, r4 @ ~b & d + orrs r5, r6 @ F(b,c,d) + add r1, r5 @ a += F(b,c,d) + ldr r6, [r0, #12<<2] @ load msg_data[12] + add r1, r6 @ a += msg_data[12] + ldmia r7!, {r5} @ load md5_t[12], *md5_t++ + add r1, r5 @ a += md5_t[12] + movs r6, #25 @ amount to rotate + rors r1, r6 @ ROTL(a,7) + add r1, r2 @ a = b + ROTL(a,7) + + mov r5, r1 @ a + mvns r6, r1 @ ~a + ands r5, r2 @ a & b + ands r6, r3 @ ~a & c + orrs r5, r6 @ F(a,b,c) + add r4, r5 @ d += F(a,b,c) + ldr r6, [r0, #13<<2] @ load msg_data[13] + add r4, r6 @ d += msg_data[13] + ldmia r7!, {r5} @ load md5_t[13], *md5_t++ + add r4, r5 @ d += md5_t[13] + movs r6, #20 @ amount to rotate + rors r4, r6 @ ROTL(d,12) + add r4, r1 @ d = a + ROTL(d,12) + + mov r5, r4 @ d + mvns r6, r4 @ ~d + ands r5, r1 @ d & a + ands r6, r2 @ ~d & b + orrs r5, r6 @ F(d,a,b) + add r3, r5 @ c += F(d,a,b) + ldr r6, [r0, #14<<2] @ load msg_data[14] + add r3, r6 @ c += msg_data[14] + ldmia r7!, {r5} @ load md5_t[14], *md5_t++ + add r3, r5 @ c += md5_t[14] + movs r6, #15 @ amount to rotate + rors r3, r6 @ ROTL(c,17) + add r3, r4 @ c = d + ROTL(c,17) + + mov r5, r3 @ c + mvns r6, r3 @ ~c + ands r5, r4 @ c & d + ands r6, r1 @ ~c & a + orrs r5, r6 @ F(c,d,a) + add r2, r5 @ b += F(c,d,a) + ldr r6, [r0, #15<<2] @ load msg_data[15] + add r2, r6 @ b += msg_data[15] + ldmia r7!, {r5} @ load md5_t[15], *md5_t++ + add r2, r5 @ b += md5_t[15] + movs r6, #10 @ amount to rotate + rors r2, r6 @ ROTL(b,22) + add r2, r3 @ b = c + ROTL(b,22) + +# 16 rounds of G(x,y,z) = (x & z) | (y & ~z) +# ****************************************** + mov r5, r4 @ d + mvns r6, r4 @ ~d + ands r5, r2 @ b & d + ands r6, r3 @ c & ~d + orrs r5, r6 @ G(b,c,d) + add r1, r5 @ a += G(b,c,d) + ldr r6, [r0, #1<<2] @ load msg_data[1] + add r1, r6 @ a += msg_data[1] + ldmia r7!, {r5} @ load md5_t[16], *md5_t++ + add r1, r5 @ a += md5_t[16] + movs r6, #27 @ amount to rotate + rors r1, r6 @ ROTL(a,5) + add r1, r2 @ a = b + ROTL(a,5) + + mov r5, r3 @ c + mvns r6, r3 @ ~c + ands r5, r1 @ c & a + ands r6, r2 @ b & ~c + orrs r5, r6 @ G(a,b,c) + add r4, r5 @ d += G(a,b,c) + ldr r6, [r0, #6<<2] @ load msg_data[6] + add r4, r6 @ d += msg_data[6] + ldmia r7!, {r5} @ load md5_t[17], *md5_t++ + add r4, r5 @ d += md5_t[17] + movs r6, #23 @ amount to rotate + rors r4, r6 @ ROTL(d,9) + add r4, r1 @ d = a + ROTL(d,9) + + mov r5, r2 @ b + mvns r6, r2 @ ~b + ands r5, r4 @ b & d + ands r6, r1 @ a & ~b + orrs r5, r6 @ G(d,a,b) + add r3, r5 @ c += G(d,a,b) + ldr r6, [r0, #11<<2] @ load msg_data[11] + add r3, r6 @ c += msg_data[11] + ldmia r7!, {r5} @ load md5_t[18], *md5_t++ + add r3, r5 @ c += md5_t[18] + movs r6, #18 @ amount to rotate + rors r3, r6 @ ROTL(c,14) + add r3, r4 @ c = d + ROTL(c,14) + + mov r5, r1 @ a + mvns r6, r1 @ ~a + ands r5, r3 @ a & c + ands r6, r4 @ d & ~a + orrs r5, r6 @ G(c,d,a) + add r2, r5 @ b += G(c,d,a) + ldr r6, [r0, #0<<2] @ load msg_data[0] + add r2, r6 @ b += msg_data[0] + ldmia r7!, {r5} @ load md5_t[19], *md5_t++ + add r2, r5 @ b += md5_t[19] + movs r6, #12 @ amount to rotate + rors r2, r6 @ ROTL(b,20) + add r2, r3 @ b = c + ROTL(b,20) + + mov r5, r4 @ d + mvns r6, r4 @ ~d + ands r5, r2 @ b & d + ands r6, r3 @ c & ~d + orrs r5, r6 @ G(b,c,d) + add r1, r5 @ a += G(b,c,d) + ldr r6, [r0, #5<<2] @ load msg_data[5] + add r1, r6 @ a += msg_data[5] + ldmia r7!, {r5} @ load md5_t[20], *md5_t++ + add r1, r5 @ a += md5_t[20] + movs r6, #27 @ amount to rotate + rors r1, r6 @ ROTL(a,5) + add r1, r2 @ a = b + ROTL(a,5) + + mov r5, r3 @ c + mvns r6, r3 @ ~c + ands r5, r1 @ c & a + ands r6, r2 @ b & ~c + orrs r5, r6 @ G(a,b,c) + add r4, r5 @ d += G(a,b,c) + ldr r6, [r0, #10<<2] @ load msg_data[10] + add r4, r6 @ d += msg_data[10] + ldmia r7!, {r5} @ load md5_t[21], *md5_t++ + add r4, r5 @ d += md5_t[21] + movs r6, #23 @ amount to rotate + rors r4, r6 @ ROTL(d,9) + add r4, r1 @ d = a + ROTL(d,9) + + mov r5, r2 @ b + mvns r6, r2 @ ~b + ands r5, r4 @ b & d + ands r6, r1 @ a & ~b + orrs r5, r6 @ G(d,a,b) + add r3, r5 @ c += G(d,a,b) + ldr r6, [r0, #15<<2] @ load msg_data[15] + add r3, r6 @ c += msg_data[15] + ldmia r7!, {r5} @ load md5_t[22], *md5_t++ + add r3, r5 @ c += md5_t[22] + movs r6, #18 @ amount to rotate + rors r3, r6 @ ROTL(c,14) + add r3, r4 @ c = d + ROTL(c,14) + + mov r5, r1 @ a + mvns r6, r1 @ ~a + ands r5, r3 @ a & c + ands r6, r4 @ d & ~a + orrs r5, r6 @ G(c,d,a) + add r2, r5 @ b += G(c,d,a) + ldr r6, [r0, #4<<2] @ load msg_data[4] + add r2, r6 @ b += msg_data[4] + ldmia r7!, {r5} @ load md5_t[23], *md5_t++ + add r2, r5 @ b += md5_t[23] + movs r6, #12 @ amount to rotate + rors r2, r6 @ ROTL(b,20) + add r2, r3 @ b = c + ROTL(b,20) + + mov r5, r4 @ d + mvns r6, r4 @ ~d + ands r5, r2 @ b & d + ands r6, r3 @ c & ~d + orrs r5, r6 @ G(b,c,d) + add r1, r5 @ a += G(b,c,d) + ldr r6, [r0, #9<<2] @ load msg_data[9] + add r1, r6 @ a += msg_data[9] + ldmia r7!, {r5} @ load md5_t[24], *md5_t++ + add r1, r5 @ a += md5_t[24] + movs r6, #27 @ amount to rotate + rors r1, r6 @ ROTL(a,5) + add r1, r2 @ a = b + ROTL(a,5) + + mov r5, r3 @ c + mvns r6, r3 @ ~c + ands r5, r1 @ c & a + ands r6, r2 @ b & ~c + orrs r5, r6 @ G(a,b,c) + add r4, r5 @ d += G(a,b,c) + ldr r6, [r0, #14<<2] @ load msg_data[14] + add r4, r6 @ d += msg_data[14] + ldmia r7!, {r5} @ load md5_t[25], *md5_t++ + add r4, r5 @ d += md5_t[25] + movs r6, #23 @ amount to rotate + rors r4, r6 @ ROTL(d,9) + add r4, r1 @ d = a + ROTL(d,9) + + mov r5, r2 @ b + mvns r6, r2 @ ~b + ands r5, r4 @ b & d + ands r6, r1 @ a & ~b + orrs r5, r6 @ G(d,a,b) + add r3, r5 @ c += G(d,a,b) + ldr r6, [r0, #3<<2] @ load msg_data[3] + add r3, r6 @ c += msg_data[3] + ldmia r7!, {r5} @ load md5_t[26], *md5_t++ + add r3, r5 @ c += md5_t[26] + movs r6, #18 @ amount to rotate + rors r3, r6 @ ROTL(c,14) + add r3, r4 @ c = d + ROTL(c,14) + + mov r5, r1 @ a + mvns r6, r1 @ ~a + ands r5, r3 @ a & c + ands r6, r4 @ d & ~a + orrs r5, r6 @ G(c,d,a) + add r2, r5 @ b += G(c,d,a) + ldr r6, [r0, #8<<2] @ load msg_data[8] + add r2, r6 @ b += msg_data[8] + ldmia r7!, {r5} @ load md5_t[27], *md5_t++ + add r2, r5 @ b += md5_t[27] + movs r6, #12 @ amount to rotate + rors r2, r6 @ ROTL(b,20) + add r2, r3 @ b = c + ROTL(b,20) + + mov r5, r4 @ d + mvns r6, r4 @ ~d + ands r5, r2 @ b & d + ands r6, r3 @ c & ~d + orrs r5, r6 @ G(b,c,d) + add r1, r5 @ a += G(b,c,d) + ldr r6, [r0, #13<<2] @ load msg_data[13] + add r1, r6 @ a += msg_data[13] + ldmia r7!, {r5} @ load md5_t[28], *md5_t++ + add r1, r5 @ a += md5_t[28] + movs r6, #27 @ amount to rotate + rors r1, r6 @ ROTL(a,5) + add r1, r2 @ a = b + ROTL(a,5) + + mov r5, r3 @ c + mvns r6, r3 @ ~c + ands r5, r1 @ c & a + ands r6, r2 @ b & ~c + orrs r5, r6 @ G(a,b,c) + add r4, r5 @ d += G(a,b,c) + ldr r6, [r0, #2<<2] @ load msg_data[2] + add r4, r6 @ d += msg_data[2] + ldmia r7!, {r5} @ load md5_t[29], *md5_t++ + add r4, r5 @ d += md5_t[29] + movs r6, #23 @ amount to rotate + rors r4, r6 @ ROTL(d,9) + add r4, r1 @ d = a + ROTL(d,9) + + mov r5, r2 @ b + mvns r6, r2 @ ~b + ands r5, r4 @ b & d + ands r6, r1 @ a & ~b + orrs r5, r6 @ G(d,a,b) + add r3, r5 @ c += G(d,a,b) + ldr r6, [r0, #7<<2] @ load msg_data[7] + add r3, r6 @ c += msg_data[7] + ldmia r7!, {r5} @ load md5_t[30], *md5_t++ + add r3, r5 @ c += md5_t[30] + movs r6, #18 @ amount to rotate + rors r3, r6 @ ROTL(c,14) + add r3, r4 @ c = d + ROTL(c,14) + + mov r5, r1 @ a + mvns r6, r1 @ ~a + ands r5, r3 @ a & c + ands r6, r4 @ d & ~a + orrs r5, r6 @ G(c,d,a) + add r2, r5 @ b += G(c,d,a) + ldr r6, [r0, #12<<2] @ load msg_data[12] + add r2, r6 @ b += msg_data[12] + ldmia r7!, {r5} @ load md5_t[31], *md5_t++ + add r2, r5 @ b += md5_t[31] + movs r6, #12 @ amount to rotate + rors r2, r6 @ ROTL(b,20) + add r2, r3 @ b = c + ROTL(b,20) + +# 16 rounds of H(x,y,z) = x ^ y ^ z +# ********************************* + mov r5, r2 @ b + eors r5, r3 @ b ^ c + eors r5, r4 @ H(b,c,d) + add r1, r5 @ a += H(b,c,d) + ldr r6, [r0, #5<<2] @ load msg_data[5] + add r1, r6 @ a += msg_data[5] + ldmia r7!, {r5} @ load md5_t[32], *md5_t++ + add r1, r5 @ a += md5_t[32] + movs r6, #28 @ amount to rotate + rors r1, r6 @ ROTL(a,4) + add r1, r2 @ a = b + ROTL(a,4) + + mov r5, r1 @ a + eors r5, r2 @ a ^ b + eors r5, r3 @ H(a,b,c) + add r4, r5 @ d += H(a,b,c) + ldr r6, [r0, #8<<2] @ load msg_data[8] + add r4, r6 @ d += msg_data[8] + ldmia r7!, {r5} @ load md5_t[33], *md5_t++ + add r4, r5 @ d += md5_t[33] + movs r6, #21 @ amount to rotate + rors r4, r6 @ ROTL(d,11) + add r4, r1 @ d = a + ROTL(d,11) + + mov r5, r4 @ d + eors r5, r1 @ d ^ a + eors r5, r2 @ H(d,a,b) + add r3, r5 @ c += H(d,a,b) + ldr r6, [r0, #11<<2] @ load msg_data[11] + add r3, r6 @ c += msg_data[11] + ldmia r7!, {r5} @ load md5_t[34], *md5_t++ + add r3, r5 @ c += md5_t[34] + movs r6, #16 @ amount to rotate + rors r3, r6 @ ROTL(c,16) + add r3, r4 @ c = d + ROTL(c,16) + + mov r5, r3 @ c + eors r5, r4 @ c ^ d + eors r5, r1 @ H(c,d,a) + add r2, r5 @ b += H(c,d,a) + ldr r6, [r0, #14<<2] @ load msg_data[14] + add r2, r6 @ b += msg_data[14] + ldmia r7!, {r5} @ load md5_t[35], *md5_t++ + add r2, r5 @ b += md5_t[35] + movs r6, #9 @ amount to rotate + rors r2, r6 @ ROTL(b,23) + add r2, r3 @ b = c + ROTL(b,23) + + mov r5, r2 @ b + eors r5, r3 @ b ^ c + eors r5, r4 @ H(b,c,d) + add r1, r5 @ a += H(b,c,d) + ldr r6, [r0, #1<<2] @ load msg_data[1] + add r1, r6 @ a += msg_data[1] + ldmia r7!, {r5} @ load md5_t[36], *md5_t++ + add r1, r5 @ a += md5_t[36] + movs r6, #28 @ amount to rotate + rors r1, r6 @ ROTL(a,4) + add r1, r2 @ a = b + ROTL(a,4) + + mov r5, r1 @ a + eors r5, r2 @ a ^ b + eors r5, r3 @ H(a,b,c) + add r4, r5 @ d += H(a,b,c) + ldr r6, [r0, #4<<2] @ load msg_data[4] + add r4, r6 @ d += msg_data[4] + ldmia r7!, {r5} @ load md5_t[37], *md5_t++ + add r4, r5 @ d += md5_t[37] + movs r6, #21 @ amount to rotate + rors r4, r6 @ ROTL(d,11) + add r4, r1 @ d = a + ROTL(d,11) + + mov r5, r4 @ d + eors r5, r1 @ d ^ a + eors r5, r2 @ H(d,a,b) + add r3, r5 @ c += H(d,a,b) + ldr r6, [r0, #7<<2] @ load msg_data[7] + add r3, r6 @ c += msg_data[7] + ldmia r7!, {r5} @ load md5_t[38], *md5_t++ + add r3, r5 @ c += md5_t[38] + movs r6, #16 @ amount to rotate + rors r3, r6 @ ROTL(c,16) + add r3, r4 @ c = d + ROTL(c,16) + + mov r5, r3 @ c + eors r5, r4 @ c ^ d + eors r5, r1 @ H(c,d,a) + add r2, r5 @ b += H(c,d,a) + ldr r6, [r0, #10<<2] @ load msg_data[10] + add r2, r6 @ b += msg_data[10] + ldmia r7!, {r5} @ load md5_t[39], *md5_t++ + add r2, r5 @ b += md5_t[39] + movs r6, #9 @ amount to rotate + rors r2, r6 @ ROTL(b,23) + add r2, r3 @ b = c + ROTL(b,23) + + mov r5, r2 @ b + eors r5, r3 @ b ^ c + eors r5, r4 @ H(b,c,d) + add r1, r5 @ a += H(b,c,d) + ldr r6, [r0, #13<<2] @ load msg_data[13] + add r1, r6 @ a += msg_data[13] + ldmia r7!, {r5} @ load md5_t[40], *md5_t++ + add r1, r5 @ a += md5_t[40] + movs r6, #28 @ amount to rotate + rors r1, r6 @ ROTL(a,4) + add r1, r2 @ a = b + ROTL(a,4) + + mov r5, r1 @ a + eors r5, r2 @ a ^ b + eors r5, r3 @ H(a,b,c) + add r4, r5 @ d += H(a,b,c) + ldr r6, [r0, #0<<2] @ load msg_data[0] + add r4, r6 @ d += msg_data[0] + ldmia r7!, {r5} @ load md5_t[41], *md5_t++ + add r4, r5 @ d += md5_t[41] + movs r6, #21 @ amount to rotate + rors r4, r6 @ ROTL(d,11) + add r4, r1 @ d = a + ROTL(d,11) + + mov r5, r4 @ d + eors r5, r1 @ d ^ a + eors r5, r2 @ H(d,a,b) + add r3, r5 @ c += H(d,a,b) + ldr r6, [r0, #3<<2] @ load msg_data[3] + add r3, r6 @ c += msg_data[3] + ldmia r7!, {r5} @ load md5_t[42], *md5_t++ + add r3, r5 @ c += md5_t[42] + movs r6, #16 @ amount to rotate + rors r3, r6 @ ROTL(c,16) + add r3, r4 @ c = d + ROTL(c,16) + + mov r5, r3 @ c + eors r5, r4 @ c ^ d + eors r5, r1 @ H(c,d,a) + add r2, r5 @ b += H(c,d,a) + ldr r6, [r0, #6<<2] @ load msg_data[6] + add r2, r6 @ b += msg_data[6] + ldmia r7!, {r5} @ load md5_t[43], *md5_t++ + add r2, r5 @ b += md5_t[43] + movs r6, #9 @ amount to rotate + rors r2, r6 @ ROTL(b,23) + add r2, r3 @ b = c + ROTL(b,23) + + mov r5, r2 @ b + eors r5, r3 @ b ^ c + eors r5, r4 @ H(b,c,d) + add r1, r5 @ a += H(b,c,d) + ldr r6, [r0, #9<<2] @ load msg_data[9] + add r1, r6 @ a += msg_data[9] + ldmia r7!, {r5} @ load md5_t[44], *md5_t++ + add r1, r5 @ a += md5_t[44] + movs r6, #28 @ amount to rotate + rors r1, r6 @ ROTL(a,4) + add r1, r2 @ a = b + ROTL(a,4) + + mov r5, r1 @ a + eors r5, r2 @ a ^ b + eors r5, r3 @ H(a,b,c) + add r4, r5 @ d += H(a,b,c) + ldr r6, [r0, #12<<2] @ load msg_data[12] + add r4, r6 @ d += msg_data[12] + ldmia r7!, {r5} @ load md5_t[45], *md5_t++ + add r4, r5 @ d += md5_t[45] + movs r6, #21 @ amount to rotate + rors r4, r6 @ ROTL(d,11) + add r4, r1 @ d = a + ROTL(d,11) + + mov r5, r4 @ d + eors r5, r1 @ d ^ a + eors r5, r2 @ H(d,a,b) + add r3, r5 @ c += H(d,a,b) + ldr r6, [r0, #15<<2] @ load msg_data[15] + add r3, r6 @ c += msg_data[15] + ldmia r7!, {r5} @ load md5_t[46], *md5_t++ + add r3, r5 @ c += md5_t[46] + movs r6, #16 @ amount to rotate + rors r3, r6 @ ROTL(c,16) + add r3, r4 @ c = d + ROTL(c,16) + + mov r5, r3 @ c + eors r5, r4 @ c ^ d + eors r5, r1 @ H(c,d,a) + add r2, r5 @ b += H(c,d,a) + ldr r6, [r0, #2<<2] @ load msg_data[2] + add r2, r6 @ b += msg_data[2] + ldmia r7!, {r5} @ load md5_t[47], *md5_t++ + add r2, r5 @ b += md5_t[47] + movs r6, #9 @ amount to rotate + rors r2, r6 @ ROTL(b,23) + add r2, r3 @ b = c + ROTL(b,23) + +# 16 rounds of I(x,y,z) = y ^ (x | ~z) +# ************************************ + mvns r5, r4 @ ~d + orrs r5, r2 @ b | ~d + eors r5, r3 @ I(b,c,d) + add r1, r5 @ a += I(b,c,d) + ldr r6, [r0, #0<<2] @ load msg_data[0] + add r1, r6 @ a += msg_data[0] + ldmia r7!, {r5} @ load md5_t[48], *md5_t++ + add r1, r5 @ a += md5_t[48] + movs r6, #26 @ amount to rotate + rors r1, r6 @ ROTL(a,6) + add r1, r2 @ a = b + ROTL(a,6) + + mvns r5, r3 @ ~c + orrs r5, r1 @ a | ~c + eors r5, r2 @ I(a,b,c) + add r4, r5 @ d += I(a,b,c) + ldr r6, [r0, #7<<2] @ load msg_data[7] + add r4, r6 @ d += msg_data[7] + ldmia r7!, {r5} @ load md5_t[49], *md5_t++ + add r4, r5 @ d += md5_t[49] + movs r6, #22 @ amount to rotate + rors r4, r6 @ ROTL(d,10) + add r4, r1 @ d = a + ROTL(d,10) + + mvns r5, r2 @ ~b + orrs r5, r4 @ d | ~b + eors r5, r1 @ I(d,a,b) + add r3, r5 @ c += I(d,a,b) + ldr r6, [r0, #14<<2] @ load msg_data[14] + add r3, r6 @ c += msg_data[14] + ldmia r7!, {r5} @ load md5_t[50], *md5_t++ + add r3, r5 @ c += md5_t[50] + movs r6, #17 @ amount to rotate + rors r3, r6 @ ROTL(c,15) + add r3, r4 @ c = d + ROTL(c,15) + + mvns r5, r1 @ ~a + orrs r5, r3 @ c | ~a + eors r5, r4 @ I(c,d,a) + add r2, r5 @ b += I(c,d,a) + ldr r6, [r0, #5<<2] @ load msg_data[5] + add r2, r6 @ b += msg_data[5] + ldmia r7!, {r5} @ load md5_t[51], *md5_t++ + add r2, r5 @ b += md5_t[51] + movs r6, #11 @ amount to rotate + rors r2, r6 @ ROTL(b,21) + add r2, r3 @ b = c + ROTL(b,21) + + mvns r5, r4 @ ~d + orrs r5, r2 @ b | ~d + eors r5, r3 @ I(b,c,d) + add r1, r5 @ a += I(b,c,d) + ldr r6, [r0, #12<<2] @ load msg_data[12] + add r1, r6 @ a += msg_data[12] + ldmia r7!, {r5} @ load md5_t[52], *md5_t++ + add r1, r5 @ a += md5_t[52] + movs r6, #26 @ amount to rotate + rors r1, r6 @ ROTL(a,6) + add r1, r2 @ a = b + ROTL(a,6) + + mvns r5, r3 @ ~c + orrs r5, r1 @ a | ~c + eors r5, r2 @ I(a,b,c) + add r4, r5 @ d += I(a,b,c) + ldr r6, [r0, #3<<2] @ load msg_data[3] + add r4, r6 @ d += msg_data[3] + ldmia r7!, {r5} @ load md5_t[53], *md5_t++ + add r4, r5 @ d += md5_t[53] + movs r6, #22 @ amount to rotate + rors r4, r6 @ ROTL(d,10) + add r4, r1 @ d = a + ROTL(d,10) + + mvns r5, r2 @ ~b + orrs r5, r4 @ d | ~b + eors r5, r1 @ I(d,a,b) + add r3, r5 @ c += I(d,a,b) + ldr r6, [r0, #10<<2] @ load msg_data[10] + add r3, r6 @ c += msg_data[10] + ldmia r7!, {r5} @ load md5_t[54], *md5_t++ + add r3, r5 @ c += md5_t[54] + movs r6, #17 @ amount to rotate + rors r3, r6 @ ROTL(c,15) + add r3, r4 @ c = d + ROTL(c,15) + + mvns r5, r1 @ ~a + orrs r5, r3 @ c | ~a + eors r5, r4 @ I(c,d,a) + add r2, r5 @ b += I(c,d,a) + ldr r6, [r0, #1<<2] @ load msg_data[1] + add r2, r6 @ b += msg_data[1] + ldmia r7!, {r5} @ load md5_t[55], *md5_t++ + add r2, r5 @ b += md5_t[55] + movs r6, #11 @ amount to rotate + rors r2, r6 @ ROTL(b,21) + add r2, r3 @ b = c + ROTL(b,21) + + mvns r5, r4 @ ~d + orrs r5, r2 @ b | ~d + eors r5, r3 @ I(b,c,d) + add r1, r5 @ a += I(b,c,d) + ldr r6, [r0, #8<<2] @ load msg_data[8] + add r1, r6 @ a += msg_data[8] + ldmia r7!, {r5} @ load md5_t[56], *md5_t++ + add r1, r5 @ a += md5_t[56] + movs r6, #26 @ amount to rotate + rors r1, r6 @ ROTL(a,6) + add r1, r2 @ a = b + ROTL(a,6) + + mvns r5, r3 @ ~c + orrs r5, r1 @ a | ~c + eors r5, r2 @ I(a,b,c) + add r4, r5 @ d += I(a,b,c) + ldr r6, [r0, #15<<2] @ load msg_data[15] + add r4, r6 @ d += msg_data[15] + ldmia r7!, {r5} @ load md5_t[57], *md5_t++ + add r4, r5 @ d += md5_t[57] + movs r6, #22 @ amount to rotate + rors r4, r6 @ ROTL(d,10) + add r4, r1 @ d = a + ROTL(d,10) + + mvns r5, r2 @ ~b + orrs r5, r4 @ d | ~b + eors r5, r1 @ I(d,a,b) + add r3, r5 @ c += I(d,a,b) + ldr r6, [r0, #6<<2] @ load msg_data[6] + add r3, r6 @ c += msg_data[6] + ldmia r7!, {r5} @ load md5_t[58], *md5_t++ + add r3, r5 @ c += md5_t[58] + movs r6, #17 @ amount to rotate + rors r3, r6 @ ROTL(c,15) + add r3, r4 @ c = d + ROTL(c,15) + + mvns r5, r1 @ ~a + orrs r5, r3 @ c | ~a + eors r5, r4 @ I(c,d,a) + add r2, r5 @ b += I(c,d,a) + ldr r6, [r0, #13<<2] @ load msg_data[13] + add r2, r6 @ b += msg_data[13] + ldmia r7!, {r5} @ load md5_t[59], *md5_t++ + add r2, r5 @ b += md5_t[59] + movs r6, #11 @ amount to rotate + rors r2, r6 @ ROTL(b,21) + add r2, r3 @ b = c + ROTL(b,21) + + mvns r5, r4 @ ~d + orrs r5, r2 @ b | ~d + eors r5, r3 @ I(b,c,d) + add r1, r5 @ a += I(b,c,d) + ldr r6, [r0, #4<<2] @ load msg_data[4] + add r1, r6 @ a += msg_data[4] + ldmia r7!, {r5} @ load md5_t[60], *md5_t++ + add r1, r5 @ a += md5_t[60] + movs r6, #26 @ amount to rotate + rors r1, r6 @ ROTL(a,6) + add r1, r2 @ a = b + ROTL(a,6) + + mvns r5, r3 @ ~c + orrs r5, r1 @ a | ~c + eors r5, r2 @ I(a,b,c) + add r4, r5 @ d += I(a,b,c) + ldr r6, [r0, #11<<2] @ load msg_data[11] + add r4, r6 @ d += msg_data[11] + ldmia r7!, {r5} @ load md5_t[61], *md5_t++ + add r4, r5 @ d += md5_t[61] + movs r6, #22 @ amount to rotate + rors r4, r6 @ ROTL(d,10) + add r4, r1 @ d = a + ROTL(d,10) + + mvns r5, r2 @ ~b + orrs r5, r4 @ d | ~b + eors r5, r1 @ I(d,a,b) + add r3, r5 @ c += I(d,a,b) + ldr r6, [r0, #2<<2] @ load msg_data[2] + add r3, r6 @ c += msg_data[2] + ldmia r7!, {r5} @ load md5_t[62], *md5_t++ + add r3, r5 @ c += md5_t[62] + movs r6, #17 @ amount to rotate + rors r3, r6 @ ROTL(c,15) + add r3, r4 @ c = d + ROTL(c,15) + + mvns r5, r1 @ ~a + orrs r5, r3 @ c | ~a + eors r5, r4 @ I(c,d,a) + add r2, r5 @ b += I(c,d,a) + ldr r6, [r0, #9<<2] @ load msg_data[9] + add r2, r6 @ b += msg_data[9] + ldmia r7!, {r5} @ load md5_t[63], *md5_t++ + add r2, r5 @ b += md5_t[63] + movs r6, #11 @ amount to rotate + rors r2, r6 @ ROTL(b,21) + add r2, r3 @ b = c + ROTL(b,21) + +# after 16 rounds of F, G, H, and I, update md5_state + ldr r6, [sp, #4] @ restore *md5_state + ldr r5, [r6, #0<<2] @ load md5_state[0] + add r1, r5 @ a += md5_state[0] + ldr r5, [r6, #1<<2] @ load md5_state[1] + add r2, r5 @ b += md5_state[1] + ldr r5, [r6, #2<<2] @ load md5_state[2] + add r3, r5 @ c += md5_state[2] + ldr r5, [r6, #3<<2] @ load md5_state[3] + add r4, r5 @ d += md5_state[3] + stmia r6!, {r1-r4} @ store updated md5_state[0-3] + +# check if we need to repeat num_blks + ldr r5, [sp, #0] @ restore num_blks + subs r5, #1 @ decrement num_blks + bne next_blk_repeat @ check num_blks + +# if num_blks = 0, + add sp, #8 @ set sp = *{r4-r7} + pop {r4-r7} @ restore regs + bx lr @ exit routine + +# else (num_blks > 0), +next_blk_repeat: + adds r0, #64 @ *msg_data -> next block of data + str r5, [sp, #0] @ store num_blks + ldr r7, =md5_t @ reset *md5_t + b next_blk @ repeat next_blk + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_MD5_UPDATE +# Updates MD5 state variables for one or more input message blocks +# +# ARGUMENTS +# *msg_data pointer to start of input message data +# num_blks number of 512-bit blocks to process +# *md5_state pointer to 120-bit block of MD5 state variables: a,b,c,d +# +# CALLING CONVENTION +# void mmcau_md5_update (const unsigned char *msg_data, +# const int num_blks, +# unsigned char *md5_state) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_md5_update) +# -----------+------------------------------------------------------------ +# r0 | *msg_data (arg0) +# r1 | num_blks (arg1) +# r2 | *md5_state (arg2) +# | +# > r2 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_md5_update + .global mmcau_md5_update + .type mmcau_md5_update, %function + .align 4 + +_mmcau_md5_update: +mmcau_md5_update: + +# store regs r4-r7 and r14, we need to restore them at the end of the routine + push {r4-r7, lr} @ store regs + + ldr r4, =md5_initial_h + ldmia r4, {r4-r7} @ load md5_initial_h[0-3] + stmia r2!, {r4-r7} @ store in md5_state[0-3] + subs r2, #4<<2 @ reset *md5_state + + bl mmcau_md5_hash_n @ do mmcau_md5_hash_n + + pop {r4-r7, pc} @ restore regs, exit routine + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_MD5_HASH +# Updates MD5 state variables for one input message block +# +# ARGUMENTS +# *msg_data pointer to start of input message data +# *md5_state pointer to 128-bit block of MD5 state variables: a,b,c,d +# +# CALLING CONVENTION +# void mmucau_md5_hash (const unsigned char *msg_data, +# unsigned char *md5_state) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_md5_hash) +# -----------+------------------------------------------------------------ +# r0 | *msg_data (arg0) +# r1 | *md5_state (arg1) +# | +# > r1 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_md5_hash + .global mmcau_md5_hash + .type mmcau_md5_hash, %function + .align 4 + +_mmcau_md5_hash: +mmcau_md5_hash: + + mov r2, r1 @ move arg1 (*md5_state) to arg2 + movs r1, #1 @ set arg1 (num_blks) = 1 + + b mmcau_md5_hash_n @ do mmcau_md5_hash_n + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .data + + + .type md5_initial_h, %object + .align 4 + +md5_initial_h: + .word 0x67452301 @ initial a + .word 0xefcdab89 @ initial b + .word 0x98badcfe @ initial c + .word 0x10325476 @ initial d + + + .type md5_t, %object + .align 4 + +md5_t: + .word 0xd76aa478 + .word 0xe8c7b756 + .word 0x242070db + .word 0xc1bdceee + .word 0xf57c0faf + .word 0x4787c62a + .word 0xa8304613 + .word 0xfd469501 + .word 0x698098d8 + .word 0x8b44f7af + .word 0xffff5bb1 + .word 0x895cd7be + .word 0x6b901122 + .word 0xfd987193 + .word 0xa679438e + .word 0x49b40821 + .word 0xf61e2562 + .word 0xc040b340 + .word 0x265e5a51 + .word 0xe9b6c7aa + .word 0xd62f105d + .word 0x02441453 + .word 0xd8a1e681 + .word 0xe7d3fbc8 + .word 0x21e1cde6 + .word 0xc33707d6 + .word 0xf4d50d87 + .word 0x455a14ed + .word 0xa9e3e905 + .word 0xfcefa3f8 + .word 0x676f02d9 + .word 0x8d2a4c8a + .word 0xfffa3942 + .word 0x8771f681 + .word 0x6d9d6122 + .word 0xfde5380c + .word 0xa4beea44 + .word 0x4bdecfa9 + .word 0xf6bb4b60 + .word 0xbebfbc70 + .word 0x289b7ec6 + .word 0xeaa127fa + .word 0xd4ef3085 + .word 0x04881d05 + .word 0xd9d4d039 + .word 0xe6db99e5 + .word 0x1fa27cf8 + .word 0xc4ac5665 + .word 0xf4292244 + .word 0x432aff97 + .word 0xab9423a7 + .word 0xfc93a039 + .word 0x655b59c3 + .word 0x8f0ccc92 + .word 0xffeff47d + .word 0x85845dd1 + .word 0x6fa87e4f + .word 0xfe2ce6e0 + .word 0xa3014314 + .word 0x4e0811a1 + .word 0xf7537e82 + .word 0xbd3af235 + .word 0x2ad7d2bb + .word 0xeb86d391 diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_sha1_functions.s b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_sha1_functions.s new file mode 100755 index 0000000..723fd12 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_sha1_functions.s @@ -0,0 +1,1468 @@ +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# Copyright (c) Freescale Semiconductor, Inc 2013. +# +# FILE NAME : mmcau_sha1_functions.s +# VERSION : $Id: $ +# TYPE : Source Cortex-M0+ assembly library code +# DEPARTMENT : MCG R&D Core and Platforms +# AUTHOR : Anthony (Teejay) Ciancio +# AUTHOR EMAIL : teejay.ciancio@freescale.com +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# VERSION DATE AUTHOR DESCRIPTION +# ******* **** ****** *********** +# 1.0 2013-11 Ciancio initial release, using the ARMv6-M ISA +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + + .include "cau2_defines.hdr" + .syntax unified + + + .equ MMCAU_PPB_DIRECT, 0xf0005000 + .equ MMCAU_PPB_INDIRECT, 0xf0005800 + .equ MMCAU_1_CMD, 0x80000000 + .equ MMCAU_2_CMDS, 0x80100000 + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_SHA1_INITIALIZE_OUTPUT +# Initializes the SHA1 state variables +# +# ARGUMENTS +# *sha1_state pointer to 160-bit block of SHA1 state variables: a,b,c,d,e +# +# CALLING CONVENTION +# void mmcau_sha1_initialize_output (const unsigned int *sha1_state) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_sha1_initialize_output) +# -----------+------------------------------------------------------------ +# r0 | *sha1_state (arg0) +# | +# > r0 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_sha1_initialize_output + .global mmcau_sha1_initialize_output + .type mmcau_sha1_initialize_output, %function + .align 4 + +_mmcau_sha1_initialize_output: +mmcau_sha1_initialize_output: + +# store regs r4-r5, we need to restore them at the end of the routine + push {r4-r5} @ store regs + +# initialize the hash variables, a-e, both in memory and in the CAU + ldr r1, =sha1_initial_h + ldmia r1, {r1-r5} @ load sha1_initial_h[0-4] + stmia r0!, {r1-r5} @ store in sha1_state[0-4] + + pop {r4-r5} @ restore regs + bx lr @ exit routine + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_SHA1_HASH_N +# Perform the hash and generate SHA1 state variables for one or more input +# message blocks +# +# ARGUMENTS +# *msg_data pointer to start of input message data +# num_blks number of 512-bit blocks to process +# *sha1_state pointer to 160-bit block of SHA1 state variables: a,b,c,d,e +# +# NOTE +# Input message and digest output blocks must not overlap +# +# CALLING CONVENTION +# void mmcau_sha1_hash_n (const unsigned char *msg_data, +# const int num_blks, +# unsigned int *sha1_state) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_sha1_hash_n) +# -----------+------------------------------------------------------------ +# r0 | *msg_data (arg0) +# r1 | num_blks (arg1) +# r2 | *sha1_state (arg2) +# | +# > r2 | irrelevant +# +# +# STACK | ALLOCATION (throughout mmcau_sha1_hash_n) +# -----------+------------------------------------------------------------ +# #356 | *sha1_state +# #352 | num_blks +# #348 | *msg_data +# #344 | *sha1_k +# #24-#340 | w[i] +# #0-#20 | sha1_state[0-4] +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_sha1_hash_n + .global mmcau_sha1_hash_n + .type mmcau_sha1_hash_n, %function + .align 4 + +_mmcau_sha1_hash_n: +mmcau_sha1_hash_n: + +# store *msg_data, num_blks, and *sha1_state, we need them later in the routine +# store regs r4-r7, we need to restore them at the end of the routine + push {r0-r2, r4-r7} @ store *msg_data, num_blks, *sha1_state, regs + +# initialize the hash variables, a-e, in the CAU + ldr r1, =MMCAU_PPB_INDIRECT+((LDR+CA0)<<2) + ldmia r2!, {r3-r7} @ load sha1_state[0-4] + stmia r1!, {r3-r7} @ store in CA[0-4] + + sub sp, #348 @ reserve stack + + + .align 2 +next_blk: + + add r2, sp, #0 @ set *sha1_state (on stack) + stmia r2!, {r3-r7} @ store sha1_state[0-4] + + ldr r4, =MMCAU_PPB_INDIRECT+((LDR+CAA)<<2) + movs r1, #27 + rors r3, r1 @ ROTL(a,5) + str r3, [r4] @ store in CAA + +# prepare regs for loops + ldr r1, =sha1_k + ldr r2, =MMCAU_PPB_DIRECT + adds r4, #128 @ mmcau_indirect_cmd(ADR+CAA) + ldr r5, =MMCAU_1_CMD+((SHS)<<22) + ldr r6, =MMCAU_2_CMDS+((HASH+HFC)<<22)+((ADRA+CA4)<<11) + ldr r7, [r1, #0<<2] @ load k[0] + str r1, [sp, #344] @ store *sha1_k + + +# for (j = 0; j < 16; j++, k++) +# { +# w[i] = byterev(msg_data[k]); // w[i] = m[k] +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(HASH+HFC,ADRA+CA4); // + Ch(), + e +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha1_k[0]; // + k[0] +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = w[i++]; // + w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_1_cmd(SHS); // shift regs +# } +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (throughout the first loop) +# -----------+------------------------------------------------------------ +# r0 | *msg_data +# r1 | scratch +# r2 | *mmcau_direct_cmd() +# r3 | scratch +# r4 | mmcau_indirect_cmd(ADR+CAA) +# r5 | mmcau_1_cmd(SHS) +# r6 | mmcau_2_cmds(HASH+HFC,ADRA+CA4) +# r7 | k[0] + + ldmia r0!, {r1} @ m[0], *msg_data++ + rev r1, r1 @ w[0] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #0<<2+24] @ store w[0] + add r1, r7 @ w[0] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[1], *msg_data++ + rev r1, r1 @ w[1] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #1<<2+24] @ store w[1] + add r1, r7 @ w[1] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[2], *msg_data++ + rev r1, r1 @ w[2] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #2<<2+24] @ store w[2] + add r1, r7 @ w[2] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[3], *msg_data++ + rev r1, r1 @ w[3] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #3<<2+24] @ store w[3] + add r1, r7 @ w[3] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[4], *msg_data++ + rev r1, r1 @ w[4] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #4<<2+24] @ store w[4] + add r1, r7 @ w[4] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[5], *msg_data++ + rev r1, r1 @ w[5] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #5<<2+24] @ store w[5] + add r1, r7 @ w[5] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[6], *msg_data++ + rev r1, r1 @ w[6] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #6<<2+24] @ store w[6] + add r1, r7 @ w[6] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[7], *msg_data++ + rev r1, r1 @ w[7] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #7<<2+24] @ store w[7] + add r1, r7 @ w[7] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[8], *msg_data++ + rev r1, r1 @ w[8] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #8<<2+24] @ store w[8] + add r1, r7 @ w[8] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[9], *msg_data++ + rev r1, r1 @ w[9] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #9<<2+24] @ store w[9] + add r1, r7 @ w[9] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[10], *msg_data++ + rev r1, r1 @ w[10] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #10<<2+24] @ store w[10] + add r1, r7 @ w[10] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[11], *msg_data++ + rev r1, r1 @ w[11] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #11<<2+24] @ store w[11] + add r1, r7 @ w[11] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[12], *msg_data++ + rev r1, r1 @ w[12] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #12<<2+24] @ store w[12] + add r1, r7 @ w[12] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[13], *msg_data++ + rev r1, r1 @ w[13] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #13<<2+24] @ store w[13] + add r1, r7 @ w[13] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[14], *msg_data++ + rev r1, r1 @ w[14] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #14<<2+24] @ store w[14] + add r1, r7 @ w[14] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + ldmia r0!, {r1} @ m[15], *msg_data++ + rev r1, r1 @ w[15] + str r6, [r2] @ + Ch(), + e + str r1, [sp, #15<<2+24] @ store w[15] + add r1, r7 @ w[15] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift registers + + str r0, [sp, #348] @ store *msg_data + movs r3, #31 @ set the amount to rotate + + +# for (j = 0; j < 4; j++) +# { +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(HASH+HFC,ADRA+CA4); // + Ch(), + e +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha1_k[0]; // + k[0] +# *(MMCAU_PPB_INDIRECT + (LDR+CA5)) = w[i-16]; // CA5 = w[i-16] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-14]; // xor w[i-14] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-8]; // xor w[i-8] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-3]; // xor w[i-3] +# *(MMCAU_PPB_INDIRECT + (ROTL+CA5)) = 1; // rotate 1 +# w[i++] = *(MMCAU_PPB_INDIRECT + (STR+CA5)); // store w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(ADRA+CA5,SHS); // + w[i], shift +# } +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (throughout the second loop) +# -----------+------------------------------------------------------------ +# r0 | scratch +# r1 | scratch +# r2 | *mmcau_direct_cmd() +# r3 | amount to rotate = #31 +# r4 | mmcau_indirect_cmd(ADR+CAA) +# r5 | mmcau_1_cmd(SHS) +# r6 | mmcau_2_cmds(HASH+HFC,ADRA+CA4) +# r7 | k[0] + + str r6, [r2] @ + Ch(), + e + ldr r1, [sp, #0<<2+24] @ w[0] + ldr r0, [sp, #2<<2+24] @ w[2] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #8<<2+24] @ w[8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #13<<2+24] @ w[13] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #16<<2+24] @ store w[16] + add r1, r7 @ w[16] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Ch(), + e + ldr r1, [sp, #1<<2+24] @ w[1] + ldr r0, [sp, #3<<2+24] @ w[3] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #9<<2+24] @ w[9] + eors r1, r0 @ XOR w[i-9] + ldr r0, [sp, #14<<2+24] @ w[14] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #17<<2+24] @ store w[17] + add r1, r7 @ w[17] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Ch(), + e + ldr r1, [sp, #2<<2+24] @ w[2] + ldr r0, [sp, #4<<2+24] @ w[4] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #10<<2+24] @ w[10] + eors r1, r0 @ XOR w[i-9] + ldr r0, [sp, #15<<2+24] @ w[15] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #18<<2+24] @ store w[18] + add r1, r7 @ w[18] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Ch(), + e + ldr r1, [sp, #3<<2+24] @ w[3] + ldr r0, [sp, #5<<2+24] @ w[5] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #11<<2+24] @ w[11] + eors r1, r0 @ XOR w[i-9] + ldr r0, [sp, #16<<2+24] @ w[16] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #19<<2+24] @ store w[19] + add r1, r7 @ w[19] + k[0] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + ldr r1, [sp, #344] @ restore *sha1_k + ldr r6, =MMCAU_2_CMDS+((HASH+HFP)<<22)+((ADRA+CA4)<<11) + ldr r7, [r1, #1<<2] @ load k[1] + + +# for (j = 0; j < 20; j++) +# { +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(HASH+HFP,ADRA+CA4); // + Parity(), + e +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha1_k[1]; // + k[1] +# *(MMCAU_PPB_INDIRECT + (LDR+CA5)) = w[i-16]; // CA5 = w[i-16] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-14]; // xor w[i-14] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-8]; // xor w[i-8] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-3]; // xor w[i-3] +# *(MMCAU_PPB_INDIRECT + (ROTL+CA5)) = 1; // rotate 1 +# w[i++] = *(MMCAU_PPB_INDIRECT + (STR+CA5)); // store w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(ADRA+CA5,SHS); // + w[i], shift +# } +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (throughout the third loop) +# -----------+------------------------------------------------------------ +# r0 | scratch +# r1 | scratch +# r2 | *mmcau_direct_cmd() +# r3 | amount to rotate = #31 +# r4 | mmcau_indirect_cmd(ADR+CAA) +# r5 | mmcau_1_cmd(SHS) +# r6 | mmcau_2_cmds(HASH+HFP,ADRA+CA4) +# r7 | k[1] + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #4<<2+24] @ w[i-16] + ldr r0, [sp, #6<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #12<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #17<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #20<<2+24] @ store w[20] + add r1, r7 @ w[20] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #5<<2+24] @ w[i-16] + ldr r0, [sp, #7<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #13<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #18<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #21<<2+24] @ store w[21] + add r1, r7 @ w[21] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #6<<2+24] @ w[i-16] + ldr r0, [sp, #8<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #14<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #19<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #22<<2+24] @ store w[22] + add r1, r7 @ w[22] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #7<<2+24] @ w[i-16] + ldr r0, [sp, #9<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #15<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #20<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #23<<2+24] @ store w[23] + add r1, r7 @ w[23] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #8<<2+24] @ w[i-16] + ldr r0, [sp, #10<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #16<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #21<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #24<<2+24] @ store w[24] + add r1, r7 @ w[24] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #9<<2+24] @ w[i-16] + ldr r0, [sp, #11<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #17<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #22<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #25<<2+24] @ store w[25] + add r1, r7 @ w[25] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #10<<2+24] @ w[i-16] + ldr r0, [sp, #12<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #18<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #23<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #26<<2+24] @ store w[26] + add r1, r7 @ w[26] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #11<<2+24] @ w[i-16] + ldr r0, [sp, #13<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #19<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #24<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #27<<2+24] @ store w[27] + add r1, r7 @ w[27] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #12<<2+24] @ w[i-16] + ldr r0, [sp, #14<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #20<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #25<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #28<<2+24] @ store w[28] + add r1, r7 @ w[28] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #13<<2+24] @ w[i-16] + ldr r0, [sp, #15<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #21<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #26<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #29<<2+24] @ store w[29] + add r1, r7 @ w[29] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #14<<2+24] @ w[i-16] + ldr r0, [sp, #16<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #22<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #27<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #30<<2+24] @ store w[30] + add r1, r7 @ w[30] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #15<<2+24] @ w[i-16] + ldr r0, [sp, #17<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #23<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #28<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #31<<2+24] @ store w[31] + add r1, r7 @ w[31] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #16<<2+24] @ w[i-16] + ldr r0, [sp, #18<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #24<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #29<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #32<<2+24] @ store w[32] + add r1, r7 @ w[32] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #17<<2+24] @ w[i-16] + ldr r0, [sp, #19<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #25<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #30<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #33<<2+24] @ store w[33] + add r1, r7 @ w[33] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #18<<2+24] @ w[i-16] + ldr r0, [sp, #20<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #26<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #31<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #34<<2+24] @ store w[34] + add r1, r7 @ w[34] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #19<<2+24] @ w[i-16] + ldr r0, [sp, #21<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #27<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #32<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #35<<2+24] @ store w[35] + add r1, r7 @ w[35] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #20<<2+24] @ w[i-16] + ldr r0, [sp, #22<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #28<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #33<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #36<<2+24] @ store w[36] + add r1, r7 @ w[36] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #21<<2+24] @ w[i-16] + ldr r0, [sp, #23<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #29<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #34<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #37<<2+24] @ store w[37] + add r1, r7 @ w[37] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #22<<2+24] @ w[i-16] + ldr r0, [sp, #24<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #30<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #35<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #38<<2+24] @ store w[38] + add r1, r7 @ w[38] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #23<<2+24] @ w[i-16] + ldr r0, [sp, #25<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #31<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #36<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #39<<2+24] @ store w[39] + add r1, r7 @ w[39] + k[1] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + ldr r1, [sp, #344] @ restore *sha1_k + ldr r6, =MMCAU_2_CMDS+((HASH+HFM)<<22)+((ADRA+CA4)<<11) + ldr r7, [r1, #2<<2] @ load k[2] + b next_blk_continued + .ltorg + + +next_blk_continued: + +# for (j = 0; j < 20; j++) +# { +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(HASH+HFM,ADRA+CA4); // + Maj(), + e +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha1_k[2]; // + k[2] +# *(MMCAU_PPB_INDIRECT + (LDR+CA5)) = w[i-16]; // CA5 = w[i-16] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-14]; // xor w[i-14] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-8]; // xor w[i-8] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-3]; // xor w[i-3] +# *(MMCAU_PPB_INDIRECT + (ROTL+CA5)) = 1; // rotate 1 +# w[i++] = *(MMCAU_PPB_INDIRECT + (STR+CA5)); // store w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(ADRA+CA5,SHS); // + w[i], shift +# } +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (throughout the fourth loop) +# -----------+------------------------------------------------------------ +# r0 | scratch +# r1 | amount to rotate = #31 +# r2 | *mmcau_direct_cmd() +# r3 | scratch +# r4 | mmcau_indirect_cmd(ADR+CAA) +# r5 | mmcau_1_cmd(SHS) +# r6 | mmcau_2_cmds(HASH+HFP,ADRA+CA4) +# r7 | k[2] + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #24<<2+24] @ w[i-16] + ldr r0, [sp, #26<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #32<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #37<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #40<<2+24] @ store w[40] + add r1, r7 @ w[40] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #25<<2+24] @ w[i-16] + ldr r0, [sp, #27<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #33<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #38<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #41<<2+24] @ store w[41] + add r1, r7 @ w[41] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #26<<2+24] @ w[i-16] + ldr r0, [sp, #28<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #34<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #39<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #42<<2+24] @ store w[42] + add r1, r7 @ w[42] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #27<<2+24] @ w[i-16] + ldr r0, [sp, #29<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #35<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #40<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #43<<2+24] @ store w[43] + add r1, r7 @ w[43] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #28<<2+24] @ w[i-16] + ldr r0, [sp, #30<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #36<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #41<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #44<<2+24] @ store w[44] + add r1, r7 @ w[44] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #29<<2+24] @ w[i-16] + ldr r0, [sp, #31<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #37<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #42<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #45<<2+24] @ store w[45] + add r1, r7 @ w[45] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #30<<2+24] @ w[i-16] + ldr r0, [sp, #32<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #38<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #43<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #46<<2+24] @ store w[46] + add r1, r7 @ w[46] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #31<<2+24] @ w[i-16] + ldr r0, [sp, #33<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #39<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #44<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #47<<2+24] @ store w[47] + add r1, r7 @ w[47] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #32<<2+24] @ w[i-16] + ldr r0, [sp, #34<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #40<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #45<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #48<<2+24] @ store w[48] + add r1, r7 @ w[48] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #33<<2+24] @ w[i-16] + ldr r0, [sp, #35<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #41<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #46<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #49<<2+24] @ store w[49] + add r1, r7 @ w[49] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #34<<2+24] @ w[i-16] + ldr r0, [sp, #36<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #42<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #47<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #50<<2+24] @ store w[50] + add r1, r7 @ w[50] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #35<<2+24] @ w[i-16] + ldr r0, [sp, #37<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #43<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #48<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #51<<2+24] @ store w[51] + add r1, r7 @ w[51] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #36<<2+24] @ w[i-16] + ldr r0, [sp, #38<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #44<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #49<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #52<<2+24] @ store w[52] + add r1, r7 @ w[52] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #37<<2+24] @ w[i-16] + ldr r0, [sp, #39<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #45<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #50<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #53<<2+24] @ store w[53] + add r1, r7 @ w[53] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #38<<2+24] @ w[i-16] + ldr r0, [sp, #40<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #46<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #51<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #54<<2+24] @ store w[54] + add r1, r7 @ w[54] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #39<<2+24] @ w[i-16] + ldr r0, [sp, #41<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #47<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #52<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #55<<2+24] @ store w[55] + add r1, r7 @ w[55] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #40<<2+24] @ w[i-16] + ldr r0, [sp, #42<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #48<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #53<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #56<<2+24] @ store w[56] + add r1, r7 @ w[56] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #41<<2+24] @ w[i-16] + ldr r0, [sp, #43<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #49<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #54<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #57<<2+24] @ store w[57] + add r1, r7 @ w[57] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #42<<2+24] @ w[i-16] + ldr r0, [sp, #44<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #50<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #55<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #58<<2+24] @ store w[58] + add r1, r7 @ w[58] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Maj(), + e + ldr r1, [sp, #43<<2+24] @ w[i-16] + ldr r0, [sp, #45<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #51<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #56<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #59<<2+24] @ store w[59] + add r1, r7 @ w[59] + k[2] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + ldr r1, [sp, #344] @ restore *sha1_k + ldr r6, =MMCAU_2_CMDS+((HASH+HFP)<<22)+((ADRA+CA4)<<11) + ldr r7, [r1, #3<<2] @ load k[3] + + +# for (j = 0; j < 20; j++) +# { +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(HASH+HFP,ADRA+CA4); // + Par(), + e +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha1_k[3]; // + k[3] +# *(MMCAU_PPB_INDIRECT + (LDR+CA5)) = w[i-16]; // CA5 = w[i-16] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-14]; // xor w[i-14] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-8]; // xor w[i-8] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-3]; // xor w[i-3] +# *(MMCAU_PPB_INDIRECT + (ROTL+CA5)) = 1; // rotate 1 +# w[i++] = *(MMCAU_PPB_INDIRECT + (STR+CA5)); // store w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(ADRA+CA5,SHS); // + w[i], shift +# } +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (throughout the fifth/last loop) +# -----------+------------------------------------------------------------ +# r0 | scratch +# r1 | scratch +# r2 | *mmcau_direct_cmd() +# r3 | amount to rotate = #31 +# r4 | mmcau_indirect_cmd(ADR+CAA) +# r5 | mmcau_1_cmd(SHS) +# r6 | mmcau_2_cmds(HASH+HFP,ADRA+CA4) +# r7 | k[3] + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #44<<2+24] @ w[i-16] + ldr r0, [sp, #46<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #52<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #57<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #60<<2+24] @ store w[60] + add r1, r7 @ w[60] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #45<<2+24] @ w[i-16] + ldr r0, [sp, #47<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #53<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #58<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #61<<2+24] @ store w[61] + add r1, r7 @ w[61] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #46<<2+24] @ w[i-16] + ldr r0, [sp, #48<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #54<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #59<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #62<<2+24] @ store w[62] + add r1, r7 @ w[62] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #47<<2+24] @ w[i-16] + ldr r0, [sp, #49<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #55<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #60<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #63<<2+24] @ store w[63] + add r1, r7 @ w[63] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #48<<2+24] @ w[i-16] + ldr r0, [sp, #50<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #56<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #61<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #64<<2+24] @ store w[64] + add r1, r7 @ w[64] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #49<<2+24] @ w[i-16] + ldr r0, [sp, #51<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #57<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #62<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #65<<2+24] @ store w[65] + add r1, r7 @ w[65] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #50<<2+24] @ w[i-16] + ldr r0, [sp, #52<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #58<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #63<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #66<<2+24] @ store w[66] + add r1, r7 @ w[66] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #51<<2+24] @ w[i-16] + ldr r0, [sp, #53<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #59<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #64<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #67<<2+24] @ store w[67] + add r1, r7 @ w[67] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #52<<2+24] @ w[i-16] + ldr r0, [sp, #54<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #60<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #65<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #68<<2+24] @ store w[68] + add r1, r7 @ w[68] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #53<<2+24] @ w[i-16] + ldr r0, [sp, #55<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #61<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #66<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #69<<2+24] @ store w[69] + add r1, r7 @ w[69] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #54<<2+24] @ w[i-16] + ldr r0, [sp, #56<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #62<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #67<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #70<<2+24] @ store w[70] + add r1, r7 @ w[70] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #55<<2+24] @ w[i-16] + ldr r0, [sp, #57<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #63<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #68<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #71<<2+24] @ store w[71] + add r1, r7 @ w[71] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #56<<2+24] @ w[i-16] + ldr r0, [sp, #58<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #64<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #69<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #72<<2+24] @ store w[72] + add r1, r7 @ w[72] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #57<<2+24] @ w[i-16] + ldr r0, [sp, #59<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #65<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #70<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #73<<2+24] @ store w[73] + add r1, r7 @ w[73] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #58<<2+24] @ w[i-16] + ldr r0, [sp, #60<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #66<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #71<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #74<<2+24] @ store w[74] + add r1, r7 @ w[74] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #59<<2+24] @ w[i-16] + ldr r0, [sp, #61<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #67<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #72<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #75<<2+24] @ store w[75] + add r1, r7 @ w[75] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #60<<2+24] @ w[i-16] + ldr r0, [sp, #62<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #68<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #73<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #76<<2+24] @ store w[76] + add r1, r7 @ w[76] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #61<<2+24] @ w[i-16] + ldr r0, [sp, #63<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #69<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #74<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #77<<2+24] @ store w[77] + add r1, r7 @ w[77] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #62<<2+24] @ w[i-16] + ldr r0, [sp, #64<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #70<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #75<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #78<<2+24] @ store w[78] + add r1, r7 @ w[78] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + + str r6, [r2] @ + Par(), + e + ldr r1, [sp, #63<<2+24] @ w[i-16] + ldr r0, [sp, #65<<2+24] @ w[i-14] + eors r1, r0 @ XOR w[i-14] + ldr r0, [sp, #71<<2+24] @ w[i-8] + eors r1, r0 @ XOR w[i-8] + ldr r0, [sp, #76<<2+24] @ w[i-3] + eors r1, r0 @ XOR w[i-3] + rors r1, r3 @ rotate left by 1 + str r1, [sp, #79<<2+24] @ store w[79] + add r1, r7 @ w[79] + k[3] + str r1, [r4] @ add sum to CAA + str r5, [r2] @ shift regs + +# after going through the loops + add r3, sp, #0 @ get *sha1_state (on stack) + ldr r1, =MMCAU_PPB_INDIRECT+((ADR+CA0)<<2) + ldmia r3, {r3-r7} @ load sha1_state[0-4] + stmia r1!, {r3-r7} @ add to CA[0-4] + subs r1, #84 @ mmcau_indirect_cmd(STR+CA0) + ldmia r1!, {r3-r7} @ load sums + +# find out if next_blk should be repeated + ldr r1, [sp, #352] @ restore num_blks + subs r1, #1 @ decrement num_blks + bne next_blk_repeat @ check num_blks + +# if num_blks = 0, + ldr r2, [sp, #356] @ restore *sha1_state + stmia r2!, {r3-r7} @ store CA[0-4] to sha1_state[0-4] + add sp, #360 @ unreserve stack + pop {r4-r7} @ restore regs + bx lr @ exit routine + +# else, +next_blk_repeat: + ldr r0, [sp, #348] @ restore *msg_data + str r1, [sp, #352] @ store num_blks + b next_blk @ repeat next_blk + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_SHA1_UPDATE +# Updates SHA1 state variables for one or more input message blocks +# +# ARGUMENTS +# *msg_data pointer to start of input message data +# num_blks number of 512-bit blocks to process +# *sha1_state pointer to 160-bit block of SHA1 state variables: a,b,c,d,e +# +# CALLING CONVENTION +# void mmcau_sha1_update (const unsigned char *msg_data, +# const int num_blks, +# unsigned int *sha1_state) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_sha1_update) +# -----------+------------------------------------------------------------ +# r0 | *msg_data (arg0) +# r1 | num_blks (arg1) +# r2 | *sha1_state (arg2) +# | +# > r2 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_sha1_update + .global mmcau_sha1_update + .type mmcau_sha1_update, %function + .align 4 + +_mmcau_sha1_update: +mmcau_sha1_update: + +# store regs r4-r7 and r14, we need to restore them at the end of the routine + push {r4-r7, lr} @ store regs + + ldr r3, =sha1_initial_h + ldmia r3, {r3-r7} @ load sha1_initial_h[0-4] + stmia r2!, {r3-r7} @ store in sha1_state[0-4] + subs r2, #5<<2 @ reset *sha1_state + + bl mmcau_sha1_hash_n @ do mmcau_sha1_hash_n + + pop {r4-r7, pc} @ restore regs, exit routine + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_SHA1_HASH +# Perform the hash and generate SHA1 state variables for one input message +# block +# +# ARGUMENTS +# *msg_data pointer to start of input message data +# *sha1_state pointer to 160-bit block of SHA1 state variables: a,b,c,d,e +# +# NOTE +# Input message and digest output blocks must not overlap +# +# CALLING CONVENTION +# void mmcau_sha1_hash (const unsigned char *msg_data, +# unsigned int *sha1_state) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_sha1_hash_n) +# -----------+------------------------------------------------------------ +# r0 | *msg_data (arg0) +# r1 | *sha1_state (arg1) +# | +# > r1 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_sha1_hash + .global mmcau_sha1_hash + .type mmcau_sha1_hash, %function + .align 4 + +_mmcau_sha1_hash: +mmcau_sha1_hash: + + mov r2, r1 @ move arg1 (*sha1_state) to arg2 + movs r1, #1 @ set arg1 (num_blks) = 1 + + ldr r3, =mmcau_sha1_hash_n+1 + bx r3 @ do mmcau_sha1_hash_n + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .data + + + .type sha1_initial_h, %object + .align 4 + +sha1_initial_h: + .word 0x67452301 @ initial a + .word 0xefcdab89 @ initial b + .word 0x98badcfe @ initial c + .word 0x10325476 @ initial d + .word 0xc3d2e1f0 @ initial e + + + .type sha1_k, %object + .align 4 + +sha1_k: + .word 0x5a827999 + .word 0x6ed9eba1 + .word 0x8f1bbcdc + .word 0xca62c1d6 diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_sha256_functions.s b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_sha256_functions.s new file mode 100755 index 0000000..4acbcd4 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm0p/src/mmcau_sha256_functions.s @@ -0,0 +1,694 @@ +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# Copyright (c) Freescale Semiconductor, Inc 2013. +# +# FILE NAME : mmcau_sha256_functions.s +# VERSION : $Id: $ +# TYPE : Source Cortex-M0+ assembly library code +# DEPARTMENT : MCG R&D Core and Platforms +# AUTHOR : Anthony (Teejay) Ciancio +# AUTHOR EMAIL : teejay.ciancio@freescale.com +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# VERSION DATE AUTHOR DESCRIPTION +# ******* **** ****** *********** +# 1.0 2013-11 Ciancio initial release, using the ARMv6-M ISA +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + + .include "cau2_defines.hdr" + .syntax unified + + + .equ MMCAU_PPB_DIRECT, 0xf0005000 + .equ MMCAU_PPB_INDIRECT, 0xf0005800 + .equ MMCAU_1_CMD, 0x80000000 + .equ MMCAU_3_CMDS, 0x80100200 + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_SHA256_INITIALIZE_OUTPUT +# Initializes the hash output and checks the CAU hardware revision +# +# ARGUMENTS +# *output pointer to 256-bit message digest output +# +# CALLING CONVENTION +# int mmcau_sha256_initialize_output (const unsigned int *output) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_sha256_initialize_output) +# -----------+------------------------------------------------------------ +# r0 | *output (arg0) +# | +# > r0 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_sha256_initialize_output + .global mmcau_sha256_initialize_output + .type mmcau_sha256_initialize_output, %function + .align 4 + +_mmcau_sha256_initialize_output: +mmcau_sha256_initialize_output: + +# store regs r4-r7, we need to restore them at the end of the routine + push {r4-r7} @ store regs + + ldr r3, =sha256_initial_h + ldmia r3!, {r4-r7} @ load sha256_initial_h[0-3] + stmia r0!, {r4-r7} @ store in output[0-3] + ldmia r3!, {r4-r7} @ load sha256_initial_h[4-7] + stmia r0!, {r4-r7} @ store in output[4-7] + + movs r0, #0 @ clear the return value + pop {r4-r7} @ restore regs + bx lr @ exit routine + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_SHA256_HASH_N +# Perform the hash for one or more input message blocks and generate the +# message digest output +# +# ARGUMENTS +# *input pointer to start of input message data +# num_blks number of 512-bit blocks to process +# *output pointer to 256-bit message digest +# +# NOTE +# Input message and digest output blocks must not overlap +# +# CALLING CONVENTION +# void mmcau_sha256_hash_n (const unsigned char *input, +# const int num_blks, +# unsigned int *output) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_sha256_hash_n) +# -----------+------------------------------------------------------------ +# r0 | *input (arg0) +# r1 | num_blks (arg1) +# r2 | *output (arg2) +# +# > r2 | irrelevant +# +# +# STACK | ALLOCATION (throughout mmcau_sha256_hash_n) +# -----------+------------------------------------------------------------ +# #268 | *output +# #264 | num_blks +# #260 | *input +# #256 | mmcau_3_cmds(ADRA+CA7,HASH+HF2T,HASH+HF2C) +# #64-#252 | w[i] in loop +# #0-#60 | w[0-15] in next_blk +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_sha256_hash_n + .global mmcau_sha256_hash_n + .type mmcau_sha256_hash_n, %function + .align 4 + +_mmcau_sha256_hash_n: +mmcau_sha256_hash_n: + +# store *input, num_blks, and *output, we need them later in the routine +# store regs r4-r10, we need to restore them at the end of the routine + push {r4-r7, lr} @ store low regs and link reg + mov r3, r8 + mov r4, r9 + mov r5, sl + mov r6, fp + mov r7, ip + push {r0-r2, r3-r7} @ store *input, num_blks, *output, high regs + + sub sp, #260 @ reserve stack + +# initialize the CAU data regs with the current contents of output[0-7] + ldr r1, =MMCAU_PPB_INDIRECT+((LDR+CA0)<<2) + ldmia r2!, {r4-r7} @ load output[0-3] + stmia r1!, {r4-r7} @ store in CA[0-3] + ldmia r2!, {r4-r7} @ load output[4-7] + stmia r1!, {r4-r7} @ store in CA[4-7] + +# prepare for next_blk + ldr r1, =sha256_reg_data+3<<2 @ get *sha256_reg_data[3] + ldmia r1, {r1-r7} @ load sha256_reg_data[3-9] + mov r9, r5 @ store mmcau_indirect_cmd(LDR+CAA) + mov sl, r6 @ store mmcau_indirect_cmd(ADR+CAA) + mov fp, r7 @ store mmcau_indirect_cmd(STR+CAA) + ldr r5, =MMCAU_PPB_DIRECT + + + .align 2 +next_blk: + +# i = 0; +# for (j = 0; j < 16; j++, i++) +# { +# w[i] = byterev(input[i]); // copy m[i] to w[i] +# *(MMCAU_PPB_INDIRECT + (LDR+CAA)) = w[i]; // +w[i]+h+SIGMA1(e) +# // add Ch(e,f,g) +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(ADRA+CA7,HASH+HF2T,HASH+HF2C); +# // +k[i]+t1+SIGMA0(e) +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha256_k[i]; +# // add Maj(a,b,c) +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(MVAR+CA8,HASH+HF2S,HASH+HF2M); +# *(MMCAU_PPB_DIRECT) = mmcau_1_cmd(SHS2); // shift regs +# } +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (throughout next_blk) +# -----------+------------------------------------------------------------ +# r0 | *input +# r1 | mmcau_1_cmd(SHS2) +# r2 | mmcau_3_cmds(MVAR+CA8,HASH+HF2S,HASH+HF2M) +# r3 | mmcau_3_cmds(ADRA+CA7,HASH+HF2T,HASH+HF2C) +# r4 | *sha256_k +# r5 | *mmcau_direct_cmd() +# r6 | scratch +# r7 | scratch +# r8 | not used +# r9 | mmcau_indirect_cmd(LDR+CAA) +# (sl) r10 | mmcau_indirect_cmd(ADR+CAA) +# (fp) r11 | mmcau_indirect_cmd(STR+CAA) +# (ip) r12 | mmcau_1_cmd(SHS2) +# (sp) r13 | stack pointer +# (lr) r14 | mmcau_3_cmds(ADRA+CA7,HASH+HF2T,HASH+HF2M) + + ldmia r0!, {r7} @ m[0], *input++ + rev r7, r7 @ w[0] + str r7, [sp, #0<<2] @ store w[0] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[i] + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + ldmia r4!, {r7} @ k[0], *sha256_k++ + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[0] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[1], *input++ + rev r7, r7 @ w[1] + str r7, [sp, #1<<2] @ store w[1] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[1] + ldmia r4!, {r7} @ k[1], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[1] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[2], *input++ + rev r7, r7 @ w[2] + str r7, [sp, #2<<2] @ store w[2] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[2] + ldmia r4!, {r7} @ k[2], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[2] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[3], *input++ + rev r7, r7 @ w[3] + str r7, [sp, #3<<2] @ store w[3] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[3] + ldmia r4!, {r7} @ k[3], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[3] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[4], *input++ + rev r7, r7 @ w[4] + str r7, [sp, #4<<2] @ store w[4] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[4] + ldmia r4!, {r7} @ k[4], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[4] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[5], *input++ + rev r7, r7 @ w[5] + str r7, [sp, #5<<2] @ store w[5] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[5] + ldmia r4!, {r7} @ k[5], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[5] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[6], *input++ + rev r7, r7 @ w[6] + str r7, [sp, #6<<2] @ store w[6] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[6] + ldmia r4!, {r7} @ k[6], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[6] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[7], *input++ + rev r7, r7 @ w[7] + str r7, [sp, #7<<2] @ store w[7] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[7] + ldmia r4!, {r7} @ k[7], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[7] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[8], *input++ + rev r7, r7 @ w[8] + str r7, [sp, #8<<2] @ store w[8] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[8] + ldmia r4!, {r7} @ k[8], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[8] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[9], *input++ + rev r7, r7 @ w[9] + str r7, [sp, #9<<2] @ store w[9] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[9] + ldmia r4!, {r7} @ k[9], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[9] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[10], *input++ + rev r7, r7 @ w[10] + str r7, [sp, #10<<2] @ store w[10] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[10] + ldmia r4!, {r7} @ k[10], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[10] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[11], *input++ + rev r7, r7 @ w[11] + str r7, [sp, #11<<2] @ store w[11] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[11] + ldmia r4!, {r7} @ k[11], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[11] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[12], *input++ + rev r7, r7 @ w[12] + str r7, [sp, #12<<2] @ store w[12] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[12] + ldmia r4!, {r7} @ k[12], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[12] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[13], *input++ + rev r7, r7 @ w[13] + str r7, [sp, #13<<2] @ store w[13] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[13] + ldmia r4!, {r7} @ k[13], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[13] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[14], *input++ + rev r7, r7 @ w[14] + str r7, [sp, #14<<2] @ store w[14] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[14] + ldmia r4!, {r7} @ k[14], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[14] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + + ldmia r0!, {r7} @ m[15], *input++ + rev r7, r7 @ w[15] + str r7, [sp, #15<<2] @ store w[15] + mov r6, r9 @ mmcau_indirect_cmd(LDR+CAA) + str r7, [r6] @ add w[15] + ldmia r4!, {r7} @ k[15], *sha256_k++ + str r3, [r5] @ +h, +SIGMA1(e), +Ch(e,f,g) + mov r6, sl @ mmcau_indirect_cmd(ADR+CAA) + str r7, [r6] @ add k[15] + str r2, [r5] @ t1, +SIGMA0(e), +Maj(a,b,c) + str r1, [r5] @ shift registers + +# prepare for loop + str r0, [sp, #260] @ store *input + mov ip, r1 @ store SHS2 + mov lr, r2 @ store HF2M + str r3, [sp, #256] @ store HF2C + ldr r0, =sha256_reg_data @ get *sha256_reg_data + ldmia r0, {r0-r2} @ load sha256_reg_data[0-2] + add r3, sp, #0 @ get *w[0] + movs r6, #48 @ set number of loops = 48 + + +loop: + +# for (j = 0; j < 48; j++, i++) +# { +# *(MMCAU_PPB_INDIRECT + (LDR+CAA)) = w[i-16]; // [i-16] +# *(MMCAU_PPB_INDIRECT + (LDR+CA8)) = w[i-15]; // [i-15] +# *(MMCAU_PPB_DIRECT) = mmcau_1_cmd(HASH+HF2U); // + Sigma2(w[i-15]) +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = w[i-7]; // add w[i-7] +# *(MMCAU_PPB_INDIRECT + (LDR+CA8)) = w[i-2]; // load w[i-2] +# *(MMCAU_PPB_DIRECT) = mmcau_1_cmd(HASH+HF2V); // + Sigma1(w[i-2]) +# w[i] = *(MMCAU_PPB_INDIRECT + (STR+CAA)); // store w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(ADRA+CA7,HASH+HF2T,HASH+HF2C); +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha256_k[i]; // add k[i] +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(MVAR+CA8,HASH+HF2S,HASH+HF2M); +# *(MMCAU_PPB_DIRECT) = mmcau_1_cmd(SHS2); // shift registers +# } +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION +# -----------+------------------------------------------------------------ +# r0 | mmcau_1_cmd(HASH+HF2U) +# r1 | mmcau_1_cmd(SHS2) +# r2 | mmcau_indirect_cmd(LDR+CA8) +# r3 | *w[0] +# r4 | *sha256_k +# r5 | *mmcau_direct_cmd() +# r6 | scratch +# r7 | scratch +# r8 | loop count +# r9 | mmcau_indirect_cmd(LDR+CAA) +# (sl) r10 | mmcau_indirect_cmd(ADR+CAA) +# (fp) r11 | mmcau_indirect_cmd(STR+CAA) +# (ip) r12 | mmcau_1_cmd(SHS2) +# (sp) r13 | stack pointer +# (lr) r14 | mmcau_3_cmds(ADRA+CA7,HASH+HF2T,HASH+HF2M) + + mov r8, r6 @ store loop count + ldmia r3!, {r6} @ w[i-16], *w[0]++ + mov r7, r9 @ (LDR+CAA) + str r6, [r7] @ CAA += w[i-16] + ldr r6, [r3, #0<<2] @ w[i-15] + str r6, [r2] @ CA8 += w[i-15] + str r0, [r5] @ (HASH+HF2U) + ldr r6, [r3, #8<<2] @ w[i-7] + mov r7, sl @ (ADR+CAA) + str r6, [r7] @ CAA += w[i-7] + ldr r6, [r3, #13<<2] @ w[i-2] + str r6, [r2] @ CA8 += w[i-2] + str r1, [r5] @ (HASH+HF2V) + mov r7, fp @ (STR+CAA) + ldr r6, [r7] @ w[i] + str r6, [r3, #15<<2] @ store w[i] + ldr r7, [sp, #256] @ (ADRA+CA7,HASH+HF2T,HASH+HF2C) + str r7, [r5] @ +h, SIGMA1(e) & Ch(e,f,g) + ldmia r4!, {r6} @ k[i], *sha256_k++ + mov r7, sl @ (ADR+CAA) + str r6, [r7] @ add k[i] + mov r7, lr @ (MVAR+CA8,HASH+HF2S,HASH+HF2M) + str r7, [r5] @ t1, + SIGMA0(e) + Maj(a,b,c) + mov r7, ip @ (SHS2) + str r7, [r5] @ shift reGs + + +# find out if loop should be repeated + mov r6, r8 @ restore loop count + subs r6, #1 @ decrement loop count + bne loop @ check loop count + +# after going through the loop for the last time + ldr r2, =MMCAU_PPB_INDIRECT+((ADR+CA0)<<2) + ldr r3, [sp, #268] @ restore *output + ldmia r3!, {r4-r7} @ load output[0-3] + stmia r2!, {r4-r7} @ add to CA[0-3] + ldmia r3!, {r4-r7} @ load output[4-7] + stmia r2!, {r4-r7} @ add to CA[4-7] + subs r2, #96 @ mmcau_indirect_cmd(STR+CA0) + subs r3, #8<<2 @ reset *output + ldmia r2!, {r4-r7} @ load new CA[0-3] + stmia r3!, {r4-r7} @ store in output[0-3] + ldmia r2!, {r4-r7} @ load new CA[4-7] + stmia r3!, {r4-r7} @ store in output[4-7] + + +# find out if next_blk should be repeated + ldr r1, [sp, #264] @ restore num_blks + subs r1, #1 @ decrement num_blks + bne repeat_next_blk @ check num_blks + +# if num_blks = 0, + add sp, #272 @ unreserve stack + pop {r3-r7} @ restore high regs + mov r8, r3 + mov r9, r4 + mov sl, r5 + mov fp, r6 + mov ip, r7 + pop {r4-r7, pc} @ restore low regs, exit routine + +# else (num_blks > 0), +repeat_next_blk: + str r1, [sp, #264] @ store num_blks + ldr r0, [sp, #260] @ restore *input + ldr r1, =sha256_reg_data+3<<2 @ get *sha256_reg_data[3] + ldmia r1, {r1-r4} @ load sha256_reg_data[3-6] + ldr r5, =MMCAU_PPB_DIRECT + b next_blk @ repeat next_blk + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_SHA256_UPDATE +# Updates SHA256 state variables for one or more input message blocks +# +# ARGUMENTS +# *input pointer to start of input message data +# num_blks number of 512-bit blocks to process +# *output pointer to 256-bit message digest +# +# CALLING CONVENTION +# void mmcau_sha256_update (const unsigned char *input, +# const int num_blks, +# unsigned int *output) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_sha256_update) +# -----------+------------------------------------------------------------ +# r0 | *input (arg0) +# r1 | num_blks (arg1) +# r2 | *output (arg2) +# | +# > r2 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_sha256_update + .global mmcau_sha256_update + .type mmcau_sha256_update, %function + .align 4 + +_mmcau_sha256_update: +mmcau_sha256_update: + +# store regs r4-r7 and r14, we need to restore them at the end of the routine + push {r4-r7, lr} @ store regs + + ldr r3, =sha256_initial_h + ldmia r3!, {r4-r7} @ load sha256_initial_h[0-3] + stmia r2!, {r4-r7} @ store in output[0-3] + ldmia r3!, {r4-r7} @ load sha256_initial_h[4-7] + stmia r2!, {r4-r7} @ store in output[4-7] + subs r2, #32 @ reset *output + + bl mmcau_sha256_hash_n @ do mmcau_sha256_hash_n + + pop {r4-r7, pc} @ restore regs, exit routine + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# MMCAU_SHA256_HASH +# Perform the hash and generate SHA256 state variables for one input +# Message block. +# +# ARGUMENTS +# *input pointer to start of input message data +# *output pointer to 256-bit message digest +# +# NOTE +# Input message and digest output blocks must not overlap +# +# CALLING CONVENTION +# void mmcau_sha256_hash (const unsigned char *input, +# unsigned int *output) +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# REGISTER | ALLOCATION (at the start of mmcau_sha256_hash) +# -----------+------------------------------------------------------------ +# r0 | *input (arg0) +# r1 | *output (arg1) +# | +# > r1 | irrelevant +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .global _mmcau_sha256_hash + .global mmcau_sha256_hash + .type mmcau_sha256_hash, %function + .align 4 + +_mmcau_sha256_hash: +mmcau_sha256_hash: + + mov r2, r1 @ move arg1 (*output) to arg2 + movs r1, #1 @ set arg1 (num_blks) = 1 + + b mmcau_sha256_hash_n @ do mmcau_sha256_hash_n + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + .data + + + .type sha256_reg_data, %object + .align 4 + +sha256_reg_data: + .word MMCAU_1_CMD+((HASH+HF2U)<<22) @ r0 + .word MMCAU_1_CMD+((HASH+HF2V)<<22) @ r1 + .word MMCAU_PPB_INDIRECT+((LDR+CA8)<<2) @ r2 + .word MMCAU_1_CMD+((SHS2)<<22) @ r1 + .word MMCAU_3_CMDS+((MVAR+CA8)<<22)+((HASH+HF2S)<<11)+HASH+HF2M @ r2 + .word MMCAU_3_CMDS+((ADRA+CA7)<<22)+((HASH+HF2T)<<11)+HASH+HF2C @ r3 + .word sha256_k @ r4 + .word MMCAU_PPB_INDIRECT+((LDR+CAA)<<2) @ r5 + .word MMCAU_PPB_INDIRECT+((ADR+CAA)<<2) @ r6 + .word MMCAU_PPB_INDIRECT+((STR+CAA)<<2) @ r7 + + + .type sha256_initial_h, %object + .align 4 + +sha256_initial_h: + .word 0x6a09e667 + .word 0xbb67ae85 + .word 0x3c6ef372 + .word 0xa54ff53a + .word 0x510e527f + .word 0x9b05688c + .word 0x1f83d9ab + .word 0x5be0cd19 + + + .type sha256_k, %object + .align 4 + +sha256_k: + .word 0x428a2f98 + .word 0x71374491 + .word 0xb5c0fbcf + .word 0xe9b5dba5 + .word 0x3956c25b + .word 0x59f111f1 + .word 0x923f82a4 + .word 0xab1c5ed5 + .word 0xd807aa98 + .word 0x12835b01 + .word 0x243185be + .word 0x550c7dc3 + .word 0x72be5d74 + .word 0x80deb1fe + .word 0x9bdc06a7 + .word 0xc19bf174 + .word 0xe49b69c1 + .word 0xefbe4786 + .word 0x0fc19dc6 + .word 0x240ca1cc + .word 0x2de92c6f + .word 0x4a7484aa + .word 0x5cb0a9dc + .word 0x76f988da + .word 0x983e5152 + .word 0xa831c66d + .word 0xb00327c8 + .word 0xbf597fc7 + .word 0xc6e00bf3 + .word 0xd5a79147 + .word 0x06ca6351 + .word 0x14292967 + .word 0x27b70a85 + .word 0x2e1b2138 + .word 0x4d2c6dfc + .word 0x53380d13 + .word 0x650a7354 + .word 0x766a0abb + .word 0x81c2c92e + .word 0x92722c85 + .word 0xa2bfe8a1 + .word 0xa81a664b + .word 0xc24b8b70 + .word 0xc76c51a3 + .word 0xd192e819 + .word 0xd6990624 + .word 0xf40e3585 + .word 0x106aa070 + .word 0x19a4c116 + .word 0x1e376c08 + .word 0x2748774c + .word 0x34b0bcb5 + .word 0x391c0cb3 + .word 0x4ed8aa4a + .word 0x5b9cca4f + .word 0x682e6ff3 + .word 0x748f82ee + .word 0x78a5636f + .word 0x84c87814 + .word 0x8cc70208 + .word 0x90befffa + .word 0xa4506ceb + .word 0xbef9a3f7 + .word 0xc67178f2 diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/cau_api.h b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/cau_api.h new file mode 100755 index 0000000..7d5c72a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/cau_api.h @@ -0,0 +1,389 @@ +/* + * CAU Header File + * Works with library cau_lib.a and lib_mmcau*.a + * Define FREESCALE_CAU if CAU coprocessor is used --Register parameter passing is assumed + * Define FREESCALE_MMCAU if mmCAU coprocessor is used --EABI for Kinetis ARM Cortex-Mx + * 12/19/2013 + */ + +#if FREESCALE_MMCAU +#define cau_aes_set_key mmcau_aes_set_key +#define cau_aes_encrypt mmcau_aes_encrypt +#define cau_aes_decrypt mmcau_aes_decrypt +#define cau_des_chk_parity mmcau_des_chk_parity +#define cau_des_encrypt mmcau_des_encrypt +#define cau_des_decrypt mmcau_des_decrypt +#define cau_md5_initialize_output mmcau_md5_initialize_output +#define cau_md5_hash_n mmcau_md5_hash_n +#define cau_md5_update mmcau_md5_update +#define cau_md5_hash mmcau_md5_hash +#define cau_sha1_initialize_output mmcau_sha1_initialize_output +#define cau_sha1_hash_n mmcau_sha1_hash_n +#define cau_sha1_update mmcau_sha1_update +#define cau_sha1_hash mmcau_sha1_hash +#define cau_sha256_initialize_output mmcau_sha256_initialize_output +#define cau_sha256_hash_n mmcau_sha256_hash_n +#define cau_sha256_update mmcau_sha256_update +#define cau_sha256_hash mmcau_sha256_hash +#endif + +//****************************************************************************** +// +// AES: Performs an AES key expansion +// arguments +// *key pointer to input key (128, 192, 256 bits in length) +// key_size key_size in bits (128, 192, 256) +// *key_sch pointer to key schedule output (44, 52, 60 longwords) +// +// calling convention +// void cau_aes_set_key (const unsigned char *key, +// const int key_size, +// unsigned char *key_sch) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_aes_set_key (const unsigned char *key, const int key_size, + unsigned char *key_sch); + +//****************************************************************************** +//****************************************************************************** +// +// AES: Encrypts a single 16-byte block +// arguments +// *in pointer to 16-byte block of input plaintext +// *key_sch pointer to key schedule (44, 52, 60 longwords) +// nr number of AES rounds (10, 12, 14 = f(key_schedule)) +// *out pointer to 16-byte block of output ciphertext +// +// NOTE Input and output blocks may overlap +// +// calling convention +// void cau_aes_encrypt (const unsigned char *in, +// const unsigned char *key_sch, +// const int nr, +// unsigned char *out) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_aes_encrypt (const unsigned char *in, const unsigned char *key_sch, + const int nr, unsigned char *out); + +//****************************************************************************** +//****************************************************************************** +// +// AES: Decrypts a single 16-byte block +// arguments +// *in pointer to 16-byte block of input chiphertext +// *key_sch pointer to key schedule (44, 52, 60 longwords) +// nr number of AES rounds (10, 12, 14 = f(key_schedule)) +// *out pointer to 16-byte block of output plaintext +// +// NOTE Input and output blocks may overlap +// +// calling convention +// void cau_aes_decrypt (const unsigned char *in, +// const unsigned char *key_sch, +// const int nr, +// unsigned char *out) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_aes_decrypt (const unsigned char *in, const unsigned char *key_sch, + const int nr, unsigned char *out); + +//****************************************************************************** +// +// DES: Checks key parity +// arguments +// *key pointer to 64-bit DES key with parity bits +// +// return +// 0 no error +// -1 parity error +// +// calling convention +// int cau_des_chk_parity (const unsigned char *key) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +int +cau_des_chk_parity (const unsigned char *key); + +//****************************************************************************** +// +// DES: Encrypts a single 8-byte block +// arguments +// *in pointer to 8-byte block of input plaintext +// *key pointer to 64-bit DES key with parity bits +// *out pointer to 8-byte block of output ciphertext +// +// NOTE Input and output blocks may overlap +// +// calling convention +// void cau_des_encrypt (const unsigned char *in, +// const unsigned char *key, +// unsigned char *out) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_des_encrypt (const unsigned char *in, const unsigned char *key, + unsigned char *out); + +//****************************************************************************** +// +// DES: Decrypts a single 8-byte block +// arguments +// *in pointer to 8-byte block of input ciphertext +// *key pointer to 64-bit DES key with parity bits +// *out pointer to 8-byte block of output plaintext +// +// NOTE Input and output blocks may overlap +// +// calling convention +// void cau_des_decrypt (const unsigned char *in, +// const unsigned char *key, +// unsigned char *out) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_des_decrypt (const unsigned char *in, const unsigned char *key, + unsigned char *out); + +//****************************************************************************** +//****************************************************************************** +// +// MD5: Initializes the MD5 state variables +// arguments +// *md_state pointer to 120-bit block of md5 state variables: +// a,b,c,d +// +// calling convention +// void cau_md5_initialize_output (const unsigned char *md_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_md5_initialize_output (const unsigned char *md5_state); + +//****************************************************************************** +//****************************************************************************** +// +// MD5: Updates MD5 state variables for one or more input message blocks +// +// arguments +// *msg_data pointer to start of input message data +// num_blks number of 512-bit blocks to process +// *md_state pointer to 128-bit block of MD5 state variables: +// a,b,c,d +// +// calling convention +// void cau_md5_hash_n (const unsigned char *msg_data, +// const int num_blks, +// unsigned char *md_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_md5_hash_n (const unsigned char *msg_data, const int num_blks, + unsigned char *md5_state); + +//****************************************************************************** +//****************************************************************************** +// +// MD5: Updates MD5 state variables for one or more input message blocks +// arguments +// *msg_data pointer to start of input message data +// num_blks number of 512-bit blocks to process +// *md_state pointer to 128-bit block of MD5 state variables: +// a,b,c,d +// +// calling convention +// void cau_md5_update (const unsigned char *msg_data, +// const int num_blks, +// unsigned char *md_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_md5_update (const unsigned char *msg_data, const int num_blks, + unsigned char *md5_state); + +//****************************************************************************** +//****************************************************************************** +// +// MD5: Performs MD5 hash algorithm for a single input message block +// *msg_data pointer to start of input message data +// *md_state pointer to 128-bit block of MD5 state variables: +// a,b,c,d +// +// calling convention +// void cau_md5_hash (const unsigned char *msg_data, +// unsigned char *md_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_md5_hash (const unsigned char *msg_data, unsigned char *md5_state); + +//****************************************************************************** +//****************************************************************************** +// +// SHA1: Initializes the SHA1 state variables +// arguments +// *sha1_state pointer to 160-bit block of SHA1 state variables: +// a,b,c,d,e +// +// calling convention +// void cau_sha1_initialize_output (const unsigned int *sha1_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha1_initialize_output (const unsigned int *sha1_state); + +//****************************************************************************** +//****************************************************************************** +// +// SHA1: Perform the hash and generate SHA1 state variables for one or more +// input message blocks +// arguments +// *msg_data pointer to start of input message data +// num_blks number of 512-bit blocks to process +// *sha1_state pointer to 160-bit block of SHA1 state variables: +// a,b,c,d,e +// +// NOTE Input message and state variable output blocks must not overlap +// +// calling convention +// void cau_sha1_hash (const unsigned char *msg_data, +// const int num_blks, +// unsigned int *sha1_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha1_hash_n (const unsigned char *msg_data, const int num_blks, + unsigned int *sha1_state); + +//****************************************************************************** +//****************************************************************************** +// +// SHA1: Updates SHA1 state variables for one or more input message blocks +// arguments +// *msg_data pointer to start of input message data +// num_blks number of 512-bit blocks to process +// *sha1_state pointer to 160-bit block of SHA1 state variables: +// a,b,c,d,e +// +// calling convention +// void cau_sha1_update (const unsigned char *msg_data, +// const int num_blks, +// unsigned int *sha1_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha1_update (const unsigned char *msg_data, const int num_blks, + unsigned int *sha1_state); + +//****************************************************************************** +//****************************************************************************** +// +// SHA1: Performs SHA1 hash algorithm on a single input message block +// arguments +// *msg_data pointer to start of input message data +// *sha1_state pointer to 160-bit block of SHA1 state variables: +// a,b,c,d,e +// +// calling convention +// void cau_sha1_update (const unsigned char *msg_data, +// unsigned int *sha1_state) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha1_hash (const unsigned char *msg_data, + unsigned int *sha1_state); + +//****************************************************************************** +//****************************************************************************** +// +// SHA256: Initializes the hash output and checks the CAU hardware revision +// arguments +// *output pointer to 256-bit message digest output +// +// return +// 0 no error -> CAU2 hardware present +// -1 error -> incorrect CAU hardware revision +// +// calling convention +// int cau_sha256_initialize_output (const unsigned int *output) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +int +cau_sha256_initialize_output (const unsigned int *output); + +//****************************************************************************** +//****************************************************************************** +// +// SHA256: Updates SHA256 digest output for one or more message block arguments +// arguments +// *input pointer to start of input message +// input number of 512-bit blocks to process +// *output pointer to 256-bit message digest output +// +// NOTE Input message and digest output blocks must not overlap +// +// calling convention +// void cau_sha256_hash_n (const unsigned char *input, +// int num_blks, +// const unsigned int *output) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha256_hash_n (const unsigned char *input, const int num_blks, + unsigned int *output); + +//****************************************************************************** +//****************************************************************************** +// +// SHA256: Updates SHA256 state variables for one or more input message blocks +// arguments +// *input pointer to start of input message data +// num_blks number of 512-bit blocks to process +// *output pointer to 256-bit message digest output +// +// calling convention +// void cau_sha256_update (const unsigned char *input, +// const int num_blks, +// unsigned int *output) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha256_update (const unsigned char *input, const int num_blks, + unsigned int *output); + +//****************************************************************************** +//****************************************************************************** +// +// SHA256: Performs SHA256 hash algorithm for a single input message block +// arguments +// *input pointer to start of input message data +// *output pointer to 256-bit message digest output +// +// calling convention +// void cau_sha256_hash (const unsigned char *input, +// unsigned int *output) +#if FREESCALE_CAU +__declspec (standard_abi) +#endif +void +cau_sha256_hash (const unsigned char *input, unsigned int *output); diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/lib_mmcau.a b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/lib_mmcau.a Binary files differnew file mode 100755 index 0000000..e897f36 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/lib_mmcau.a diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/lib_mmcau.lib b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/lib_mmcau.lib Binary files differnew file mode 100755 index 0000000..e897f36 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/lib_mmcau.lib diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/cau2_defines.hdr b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/cau2_defines.hdr new file mode 100755 index 0000000..0968329 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/cau2_defines.hdr @@ -0,0 +1,57 @@ + .equ TL,0 + .equ TS,0 + .equ CASR,0 + .equ CAA,1 + .equ CA0,2 + .equ CA1,3 + .equ CA2,4 + .equ CA3,5 + .equ CA4,6 + .equ CA5,7 + .equ CA6,8 + .equ CA7,9 + .equ CA8,10 + .equ CNOP,0x000 + .equ LDR,0x010 + .equ STR,0x020 + .equ ADR,0x030 + .equ RADR,0x040 + .equ ADRA,0x050 + .equ XOR,0x060 + .equ ROTL,0x070 + .equ MVRA,0x080 + .equ MVAR,0x090 + .equ AESS,0x0a0 + .equ AESIS,0x0b0 + .equ AESC,0x0c0 + .equ AESIC,0x0d0 + .equ AESR,0x0e0 + .equ AESIR,0x0f0 + .equ DESR,0x100 + .equ DESK,0x110 + .equ HASH,0x120 + .equ SHS,0x130 + .equ MDS,0x140 + .equ SHS2,0x150 + .equ ILL,0x1f0 + .equ IP,8 + .equ FP,4 + .equ DC,1 + .equ CP,2 + .equ KSL1,0 + .equ KSL2,1 + .equ KSR1,2 + .equ KSR2,3 + .equ HFF,0 + .equ HFG,1 + .equ HFH,2 + .equ HFI,3 + .equ HFP,2 + .equ HFC,4 + .equ HFM,5 + .equ HF2C,6 + .equ HF2M,7 + .equ HF2S,8 + .equ HF2T,9 + .equ HF2U,10 + .equ HF2V,11 diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_aes_functions.s b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_aes_functions.s new file mode 100755 index 0000000..bd1d3cb --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_aes_functions.s @@ -0,0 +1,929 @@ +#******************************************************************************* +#******************************************************************************* +# +# Copyright (c) Freescale Semiconductor, Inc 2011. +# +# FILE NAME : mmcau_aes_functions.s +# VERSION : $Id: mmcau_aes_functions.s.rca 1.4 Thu Nov 21 14:17:01 2013 b40907 Experimental $ +# TYPE : Source Cortex-Mx assembly library code +# DEPARTMENT : MSG R&D Core and Platforms +# AUTHOR : David Schimke +# AUTHOR'S EMAIL : David.Schimke@freescale.com +# AUTHOR : Anthony (Teejay) Ciancio +# AUTHOR'S EMAIL : teejay.ciancio@freescale.com +# ----------------------------------------------------------------------------- +# Release history +# VERSION Date AUTHOR DESCRIPTION +# 08-2010 David Schimke Initial Release +# 12-2010 David Schimke Remove "global" on data objects +# 01-2011 David Schimke Add byte reverse to correct double word +# read of byte arrays for little endian, +# header added +# 11-2013 Teejay Ciancio Small performance improvements to +# set_key and decrypt; also, some cleanup +# +#******************************************************************************* +#******************************************************************************* + + .include "cau2_defines.hdr" + .equ MMCAU_PPB_DIRECT, 0xe0081000 + .equ MMCAU_PPB_INDIRECT,0xe0081800 + .equ MMCAU_1_CMD, 0x80000000 + .equ MMCAU_2_CMDS, 0x80100000 + .equ MMCAU_3_CMDS, 0x80100200 + + .syntax unified + +#******************************************************************************* +#******************************************************************************* +# +# AES: Performs an AES key expansion +# arguments +# *key pointer to input key (128, 192, 256 bits in length) +# key_size key_size in bits (128, 192, 256) +# *key_sch pointer to key schedule output (44, 52, 60 longwords) +# +# calling convention +# void mmcau_aes_set_key (const unsigned char *key, +# const int key_size, +# unsigned char *key_sch) + +# register allocation +# -------------------- +# r0 = scratch / input *key (arg0) +# r1 = scratch / input size (arg1) +# r2 = scratch / output *key_sch (arg2) +# r3 = scratch +# r4 = scratch +# r5 = scratch +# r6 = scratch +# r7 = scratch +# r8 = scratch +# r9 = scratch +# r10 (sl) = scratch / pointer to rcon +# r11 (fp) = scratch / mmcau_1_cmd(AESS+CAA) +# r12 (ip) = scratch / MMCAU_PPB_DIRECT +# r13 (sp) = stack pointer +# r14 (lr) = scratch / link register + + .global _mmcau_aes_set_key + .global mmcau_aes_set_key + .type mmcau_aes_set_key, %function + .align 4 + +_mmcau_aes_set_key: +mmcau_aes_set_key: + + stmdb sp!, {r4-ip,lr} @ save registers on stack + +# prepare for AES operations register load + movw r8, #:lower16:setkey_reg_data + movt r8, #:upper16:setkey_reg_data + + ldmia r0!, {r4-r7} @ copy key[0-3] + rev r4, r4 @ byte reverse + rev r5, r5 @ byte reverse + rev r6, r6 @ byte reverse + rev r7, r7 @ byte reverse + stmia r2!, {r4-r7} @ to key_sch[0-3] + +# load registers needed for mmcau commands from setkey_reg_data: + ldmia r8, {sl-ip} @ setup AES operations + + cmp r1, #128 @ if key_size = 128 + beq expand_128 @ then go expand_128 + cmp r1, #192 @ else if size = 192 + beq expand_192 @ then go expand_192 + +expand_256: + ldmia r0, {r1,r3,r8-r9} @ copy key[4-7] + rev r1, r1 @ byte reverse + rev r3, r3 @ byte reverse + rev r8, r8 @ byte reverse + rev r9, r9 @ byte reverse + stmia r2!, {r1,r3,r8-r9} @ to key_sch[4-7] + + + ldr r0, [sl], $4 @ get rcon[0]; sl++ + ror lr, r9, $24 @ rotate left by 8 + str lr, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[7])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor lr, r0 @ XOR rcon[0] + +# calculation for key_sch[8-11] + eor r4, lr @ XOR key_sch[0] + eor r5, r4 @ key_sch[1]^key_sch[8] + eor r6, r5 @ key_sch[2]^key_sch[9] + eor r7, r6 @ key_sch[3]^key_sch[10] + stmia r2!, {r4-r7} @ store key_sch[8-11] + + str r7, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[11])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + +# calculation for key_sch[12-15] + eor r1, lr @ XOR key_sch[4] + eor r3, r1 @ key_sch[5]^key_sch[12] + eor r8, r3 @ key_sch[6]^key_sch[13] + eor r9, r8 @ key_sch[7]^key_sch[14] + stmia r2!, {r1,r3,r8-r9} @ store key_sch[12-15] + + ldr r0, [sl], $4 @ get rcon[1]; sl++ + ror lr, r9, $24 @ rotate left by 8 + str lr, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[15])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor lr, r0 @ XOR rcon[1] + +# calculation for key_sch[16-19] + eor r4, lr @ XOR key_sch[8] + eor r5, r4 @ key_sch[9]^key_sch[16] + eor r6, r5 @ key_sch[10]^key_sch[17] + eor r7, r6 @ key_sch[11]^key_sch[18] + stmia r2!, {r4-r7} @ store key_sch[16-19] + + str r7, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[19])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + +# calculation for key_sch[20-23] + eor r1, lr @ XOR key_sch[12] + eor r3, r1 @ key_sch[13]^key_sch[20] + eor r8, r3 @ key_sch[14]^key_sch[21] + eor r9, r8 @ key_sch[15]^key_sch[22] + stmia r2!, {r1,r3,r8-r9} @ store key_sch[20-23] + + ldr r0, [sl], $4 @ get rcon[2]; sl++ + ror lr, r9, $24 @ rotate left by 8 + str lr, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[23])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor lr, r0 @ XOR rcon[2] + +# calculation for key_sch[24-27] + eor r4, lr @ XOR key_sch[16] + eor r5, r4 @ key_sch[17]^key_sch[24] + eor r6, r5 @ key_sch[18]^key_sch[25] + eor r7, r6 @ key_sch[19]^key_sch[26] + stmia r2!, {r4-r7} @ store key_sch[24-27] + + str r7, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[27])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + +# calculation for key_sch[28-31] + eor r1, lr @ XOR key_sch[20] + eor r3, r1 @ key_sch[21]^key_sch[28] + eor r8, r3 @ key_sch[22]^key_sch[29] + eor r9, r8 @ key_sch[23]^key_sch[30] + stmia r2!, {r1,r3,r8-r9} @ store key_sch[28-31] + + ldr r0, [sl], $4 @ get rcon[3]; sl++ + ror lr, r9, $24 @ rotate left by 8 + str lr, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[31])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor lr, r0 @ XOR rcon[3] + +# calculation for key_sch[32-35] + eor r4, lr @ XOR key_sch[24] + eor r5, r4 @ key_sch[25]^key_sch[32] + eor r6, r5 @ key_sch[26]^key_sch[33] + eor r7, r6 @ key_sch[27]^key_sch[34] + stmia r2!, {r4-r7} @ store key_sch[32-35] + + str r7, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[35])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + +# calculation for key_sch[36-39] + eor r1, lr @ XOR key_sch[28] + eor r3, r1 @ key_sch[29]^key_sch[36] + eor r8, r3 @ key_sch[30]^key_sch[37] + eor r9, r8 @ key_sch[31]^key_sch[38] + stmia r2!, {r1,r3,r8-r9} @ store key_sch[36-39] + + ldr r0, [sl], $4 @ get rcon[4]; sl++ + ror lr, r9, $24 @ rotate left by 8 + str lr, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[39])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor lr, r0 @ XOR rcon[4] + +# calculation for key_sch[40-43] + eor r4, lr @ XOR key_sch[32] + eor r5, r4 @ key_sch[33]^key_sch[40] + eor r6, r5 @ key_sch[34]^key_sch[41] + eor r7, r6 @ key_sch[35]^key_sch[42] + stmia r2!, {r4-r7} @ store key_sch[40-43] + + str r7, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[43])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + +# calculation for key_sch[44-47] + eor r1, lr @ XOR key_sch[36] + eor r3, r1 @ key_sch[37]^key_sch[44] + eor r8, r3 @ key_sch[38]^key_sch[45] + eor r9, r8 @ key_sch[39]^key_sch[46] + stmia r2!, {r1,r3,r8-r9} @ store key_sch[44-47] + + ldr r0, [sl], $4 @ get rcon[5]; sl++ + ror lr, r9, $24 @ rotate left by 8 + str lr, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[47])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor lr, r0 @ XOR rcon[5] + +# calculation for key_sch[48-51] + eor r4, lr @ XOR key_sch[40] + eor r5, r4 @ key_sch[41]^key_sch[48] + eor r6, r5 @ key_sch[42]^key_sch[49] + eor r7, r6 @ key_sch[43]^key_sch[50] + stmia r2!, {r4-r7} @ store key_sch[48-51] + + str r7, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[51])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + +# calculation for key_sch[52-55] + eor r1, lr @ XOR key_sch[44] + eor r3, r1 @ key_sch[45]^key_sch[52] + eor r8, r3 @ key_sch[46]^key_sch[53] + eor r9, r8 @ key_sch[47]^key_sch[54] + stmia r2!, {r1,r3,r8-r9} @ store key_sch[52-55] + + ldr r0, [sl], $4 @ get rcon[6]; sl++ + ror lr, r9, $24 @ rotate left by 8 + str lr, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[55])-> acc + str fp, [ip] @ AES SubBytes + ldr lr, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor lr, r0 @ XOR rcon[6] + +# calculation for key_sch[56-59] + eor r4, lr @ XOR key_sch[48] + eor r5, r4 @ key_sch[49]^key_sch[56] + eor r6, r5 @ key_sch[50]^key_sch[57] + eor r7, r6 @ key_sch[51]^key_sch[58] + stmia r2!, {r4-r7} @ store key_sch[56-59] + + ldmia sp!, {r4-ip,pc} @ restore regs and return + +expand_192: + ldmia r0, {r8-r9} @ copy key[4-5] + rev r8, r8 @ byte reverse + rev r9, r9 @ byte reverse + stmia r2!, {r8-r9} @ to key_sch[4-5] + + ldr r0, [sl], $4 @ get rcon[0]; sl++ + ror r3, r9, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[5])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[0] + +# calculation for key_sch[6-11] + eor r4, r3 @ XOR key_sch[0] + eor r5, r4 @ key_sch[1]^key_sch[6] + eor r6, r5 @ key_sch[2]^key_sch[7] + eor r7, r6 @ key_sch[3]^key_sch[8] + eor r8, r7 @ key_sch[4]^key_sch[9] + eor r9, r8 @ key_sch[5]^key_sch[10] + stmia r2!, {r4-r9} @ store key_sch[6-11] + + ldr r0, [sl], $4 @ get rcon[1]; sl++ + ror r3, r9, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[11])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[1] + +# calculation for key_sch[12-17] + eor r4, r3 @ XOR key_sch[6] + eor r5, r4 @ key_sch[7]^key_sch[12] + eor r6, r5 @ key_sch[8]^key_sch[13] + eor r7, r6 @ key_sch[9]^key_sch[14] + eor r8, r7 @ key_sch[10]^key_sch[15] + eor r9, r8 @ key_sch[11]^key_sch[16] + stmia r2!, {r4-r9} @ store key_sch[12-17] + + ldr r0, [sl], $4 @ get rcon[2]; sl++ + ror r3, r9, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[17])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[2] + +# calculation for key_sch[18-23] + eor r4, r3 @ XOR key_sch[12] + eor r5, r4 @ key_sch[13]^key_sch[18] + eor r6, r5 @ key_sch[14]^key_sch[19] + eor r7, r6 @ key_sch[15]^key_sch[20] + eor r8, r7 @ key_sch[16]^key_sch[21] + eor r9, r8 @ key_sch[17]^key_sch[22] + stmia r2!, {r4-r9} @ store key_sch[18-23] + + ldr r0, [sl], $4 @ get rcon[3]; sl++ + ror r3, r9, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[23])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[3] + +# calculation for key_sch[24-29] + eor r4, r3 @ XOR key_sch[18] + eor r5, r4 @ key_sch[19]^key_sch[24] + eor r6, r5 @ key_sch[20]^key_sch[25] + eor r7, r6 @ key_sch[21]^key_sch[26] + eor r8, r7 @ key_sch[22]^key_sch[27] + eor r9, r8 @ key_sch[23]^key_sch[28] + stmia r2!, {r4-r9} @ store key_sch[24-29] + + ldr r0, [sl], $4 @ get rcon[4]; sl++ + ror r3, r9, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[29])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[4] + +# calculation for key_sch[30-35] + eor r4, r3 @ XOR key_sch[24] + eor r5, r4 @ key_sch[25]^key_sch[30] + eor r6, r5 @ key_sch[26]^key_sch[31] + eor r7, r6 @ key_sch[27]^key_sch[32] + eor r8, r7 @ key_sch[28]^key_sch[33] + eor r9, r8 @ key_sch[29]^key_sch[34] + stmia r2!, {r4-r9} @ store key_sch[30-35] + + ldr r0, [sl], $4 @ get rcon[5]; sl++ + ror r3, r9, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[35])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[5] + +# calculation for key_sch[36-41] + eor r4, r3 @ XOR key_sch[30] + eor r5, r4 @ key_sch[31]^key_sch[36] + eor r6, r5 @ key_sch[32]^key_sch[37] + eor r7, r6 @ key_sch[33]^key_sch[38] + eor r8, r7 @ key_sch[34]^key_sch[39] + eor r9, r8 @ key_sch[35]^key_sch[40] + stmia r2!, {r4-r9} @ store key_sch[36-41] + + ldr r0, [sl], $4 @ get rcon[6]; sl++ + ror r3, r9, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[41])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[6] + +# calculation for key_sch[42-47] + eor r4, r3 @ XOR key_sch[36] + eor r5, r4 @ key_sch[37]^key_sch[42] + eor r6, r5 @ key_sch[38]^key_sch[43] + eor r7, r6 @ key_sch[39]^key_sch[44] + eor r8, r7 @ key_sch[40]^key_sch[45] + eor r9, r8 @ key_sch[41]^key_sch[46] + stmia r2!, {r4-r9} @ store key_sch[42-47] + + ldr r0, [sl], $4 @ get rcon[7]; sl++ + ror r3, r9, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[47])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[7] + +# calculation for key_sch[48-51] + eor r4, r3 @ XOR key_sch[42] + eor r5, r4 @ key_sch[43]^key_sch[48] + eor r6, r5 @ key_sch[44]^key_sch[49] + eor r7, r6 @ key_sch[45]^key_sch[50] + stmia r2!, {r4-r7} @ store key_sch[48-51] + + ldmia sp!, {r4-ip,pc} @ restore regs and return + +expand_128: + ldr r0, [sl] @ get rcon[0] + ror r3, r7, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[3])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[0] + +# calculation for key_sch[4-7] + eor r4, r3 @ XOR key_sch[0] + eor r5, r4 @ key_sch[1]^key_sch[4] + eor r6, r5 @ key_sch[2]^key_sch[5] + eor r7, r6 @ key_sch[3]^key_sch[6] + stmia r2!, {r4-r7} @ store key_sch[4-7] + + ldr r0, [sl, $1<<2] @ get rcon[1] + ror r3, r7, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[7])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[1] + +# calculation for key_sch[8-11] + eor r4, r3 @ XOR key_sch[4] + eor r5, r4 @ key_sch[5]^key_sch[8] + eor r6, r5 @ key_sch[6]^key_sch[9] + eor r7, r6 @ key_sch[7]^key_sch[10] + stmia r2!, {r4-r7} @ store key_sch[8-11] + + ldr r0, [sl, $2<<2] @ get rcon[2] + ror r3, r7, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[11])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[2] + +# calculation for key_sch[12-15] + eor r4, r3 @ XOR key_sch[8] + eor r5, r4 @ key_sch[9]^key_sch[12] + eor r6, r5 @ key_sch[10]^key_sch[13] + eor r7, r6 @ key_sch[11]^key_sch[14] + stmia r2!, {r4-r7} @ store key_sch[12-15] + + ldr r0, [sl, $3<<2] @ get rcon[3] + ror r3, r7, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[15])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[3] + +# calculation for key_sch[16-19] + eor r4, r3 @ XOR key_sch[12] + eor r5, r4 @ key_sch[13]^key_sch[16] + eor r6, r5 @ key_sch[14]^key_sch[17] + eor r7, r6 @ key_sch[15]^key_sch[18] + stmia r2!, {r4-r7} @ store key_sch[16-19] + + ldr r0, [sl, $4<<2] @ get rcon[4] + ror r3, r7, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[19])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[4] + +# calculation for key_sch[20-23] + eor r4, r3 @ XOR key_sch[16] + eor r5, r4 @ key_sch[17]^key_sch[20] + eor r6, r5 @ key_sch[18]^key_sch[21] + eor r7, r6 @ key_sch[19]^key_sch[22] + stmia r2!, {r4-r7} @ store key_sch[20-23] + + ldr r0, [sl, $5<<2] @ get rcon[5] + ror r3, r7, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[23])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[5] + +# calculation for key_sch[24-27] + eor r4, r3 @ XOR key_sch[20] + eor r5, r4 @ key_sch[21]^key_sch[24] + eor r6, r5 @ key_sch[22]^key_sch[25] + eor r7, r6 @ key_sch[23]^key_sch[26] + stmia r2!, {r4-r7} @ store key_sch[24-27] + + ldr r0, [sl, $6<<2] @ get rcon[6] + ror r3, r7, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[27])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[6] + +# calculation for key_sch[28-31] + eor r4, r3 @ XOR key_sch[24] + eor r5, r4 @ key_sch[25]^key_sch[28] + eor r6, r5 @ key_sch[26]^key_sch[29] + eor r7, r6 @ key_sch[27]^key_sch[30] + stmia r2!, {r4-r7} @ store key_sch[28-31] + + ldr r0, [sl, $7<<2] @ get rcon[7] + ror r3, r7, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[31])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[7] + +# calculation for key_sch[32-35] + eor r4, r3 @ XOR key_sch[28] + eor r5, r4 @ key_sch[29]^key_sch[32] + eor r6, r5 @ key_sch[30]^key_sch[33] + eor r7, r6 @ key_sch[31]^key_sch[34] + stmia r2!, {r4-r7} @ store key_sch[32-35] + + ldr r0, [sl, $8<<2] @ get rcon[8] + ror r3, r7, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[35])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[8] + +# calculation for key_sch[36-39] + eor r4, r3 @ XOR key_sch[32] + eor r5, r4 @ key_sch[33]^key_sch[36] + eor r6, r5 @ key_sch[34]^key_sch[37] + eor r7, r6 @ key_sch[35]^key_sch[38] + stmia r2!, {r4-r7} @ store key_sch[36-39] + + ldr r0, [sl, $9<<2] @ get rcon[9] + ror r3, r7, $24 @ rotate left by 8 + str r3, [ip, $0x800+(LDR+CAA)<<2] @ ROTL(key_sch[39])-> acc + str fp, [ip] @ AES SubBytes + ldr r3, [ip, $0x800+(STR+CAA)<<2] @ get CAA + eor r3, r0 @ XOR rcon[9] + +# calculation for key_sch[40-43] + eor r4, r3 @ XOR key_sch[36] + eor r5, r4 @ key_sch[37]^key_sch[40] + eor r6, r5 @ key_sch[38]^key_sch[41] + eor r7, r6 @ key_sch[39]^key_sch[42] + stmia r2!, {r4-r7} @ store key_sch[40-43] + + ldmia sp!, {r4-ip,pc} @ restore regs and return + + +#******************************************************************************* +#******************************************************************************* +# +# AES: Encrypts a single 16-byte block +# arguments +# *in pointer to 16-byte block of input plaintext +# *key_sch pointer to key schedule (44, 52, 60 longwords) +# nr number of AES rounds (10, 12, 14 = f(key_schedule)) +# *out pointer to 16-byte block of output ciphertext +# +# +# calling convention +# void mmcau_aes_encrypt (const unsigned char *in, +# const unsigned char *key_sch, +# const int nr, +# unsigned char *out) + + .global _mmcau_aes_encrypt + .global mmcau_aes_encrypt + .type mmcau_aes_encrypt, %function + .align 4 + +_mmcau_aes_encrypt: +mmcau_aes_encrypt: + +# register allocation +# -------------------- +# r0 = scratch / input *in / mmcau_3_cmds(AESS+CA0,AESS+CA1,AESS+CA2) +# r1 = scratch / input *key_sch +# r2 = scratch / input nr +# r3 = scratch / output *out +# r4 = scratch +# r5 = scratch +# r6 = scratch +# r7 = scratch +# r8 = scratch / mmcau_2_cmds(AESS+CA3,AESR) +# r9 = scratch / mmcau_indirect_cmd(AESC+CA0) +# r10 (sl) = scratch / mmcau_indirect_cmd(STR+CA0) +# r11 (fp) = scratch / mmcau_indirect_cmd(LDR+CA0) +# r12 (ip) = scratch / pointer to MMCAU_PPB_DIRECT +# r13 (sp) = stack pointer +# r14 (lr) = link register + + stmdb sp!, {r4-ip} @ save registers on stack + +# load the 16 plain text bytes (4 words) into r4-r7 + ldmia r0, {r4-r7} @ get plaintext[0-3] + rev r4, r4 @ byte reverse + rev r5, r5 @ byte reverse + rev r6, r6 @ byte reverse + rev r7, r7 @ byte reverse + +# prepare for AES operations register load + movw r0, #:lower16:encrypt_reg_data + movt r0, #:upper16:encrypt_reg_data + +# XOR the first 4 keys into the 16 plain text bytes + ldmia r1!, {r8-fp} @ get key_sch[0-3]; r1++ + eor r4, r8 + eor r5, r9 + eor r6, sl + eor r7, fp + +# load registers needed for mmcau commands from encrypt_reg_data: + ldmia r0, {r0,r8-ip} @ setup AES operations + +# load the XOR results into the CAU's CA0 - CA3 registers + stmia fp, {r4-r7} @ load CA0-CA3 + +# send a series of cau commands to perform the encryption + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + + cmp r2, $10 @ if aes128, finish + beq encrypt_end + + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + + cmp r2, $12 @ if aes192, finish + beq encrypt_end + + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + ldmia r1!, {r4-r7} @ get next 4 keys; r1++ + stmia r9, {r4-r7} @ MixColumns + +encrypt_end: + str r0, [ip] @ SubBytes + str r8, [ip] @ SubBytes, ShiftRows + +# XOR the last 4 keys into CAO - CA3 ciphertext output + ldmia sl, {r4-r7} @ get CA0 - CA3 + ldmia r1, {r8-fp} @ get key_sch[j]-[j+3] + eor r4, r8 + eor r5, r9 + eor r6, sl + eor r7, fp + +# store the 16-byte ciphertext output block into memory + rev r4, r4 @ byte reverse + rev r5, r5 @ byte reverse + rev r6, r6 @ byte reverse + rev r7, r7 @ byte reverse + stmia r3, {r4-r7} @ save to output[0-3] + + ldmia sp!, {r4-ip} @ restore regs and return + bx lr + +#******************************************************************************* +#******************************************************************************* +# +# AES: Decrypts a single 16-byte block +# arguments +# *in pointer to 16-byte block of input chiphertext +# *key_sch pointer to key schedule (44, 52, 60 longwords) +# nr number of AES rounds (10, 12, 14 = f(key_schedule)) +# *out pointer to 16-byte block of output plaintext +# +# +# calling convention +# void mmcau_aes_decrypt (const unsigned char *in, +# const unsigned char *key_sch, +# const int nr, +# unsigned char *out) + + .global _mmcau_aes_decrypt + .global mmcau_aes_decrypt + .type mmcau_aes_decrypt, %function + .align 4 + +_mmcau_aes_decrypt: +mmcau_aes_decrypt: + +# register allocation +# -------------------- +# r0 = scratch / input *in / mmcau_3_cmds(AESIR,AESIS+CA3,AESIS+CA2) +# r1 = scratch / input *key_sch +# r2 = scratch / input nr +# r3 = scratch / output *out +# r4 = scratch +# r5 = scratch +# r6 = scratch +# r7 = scratch +# r8 = scratch / mmcau_2_cmds(AESIS+CA1,AESIS+CA0) +# r9 = scratch / mmcau_indirect_cmd(AESIC+CA0) +# r10 (sl) = scratch / mmcau_indirect_cmd(STR+CA0) +# r11 (fp) = scratch / mmcau_indirect_cmd(LDR+CA0) +# r12 (ip) = scratch / pointer to MMCAU_PPB_DIRECT +# r13 (sp) = stack pointer +# r14 (lr) = link register + + stmdb sp!, {r4-ip} @ save registers on stack + +# load the 16 cipher bytes (4 words) into r4-r7 + ldmia r0, {r4-r7} @ get in[0-3] + rev r4, r4 @ byte reverse + rev r5, r5 @ byte reverse + rev r6, r6 @ byte reverse + rev r7, r7 @ byte reverse + +# prepare for AES operations register load + movw r0, #:lower16:decrypt_reg_data + movt r0, #:upper16:decrypt_reg_data + +# the key_sch pointer (r1) is adjusted to define the end of the elements +# the adjustment factor = f(nr) is defined by the expression: +# end of key_sch = 4 x (nr + 1) for nr = {10, 12, 14} + add r1, r1, r2, LSL $4 + +# XOR the last 4 keys into the 4 cipher words + ldmia r1, {r8-fp} @ get last 4 keys + eor r4, r8 + eor r5, r9 + eor r6, sl + eor r7, fp + +# load registers needed for mmcau commands from decrypt_reg_data: + ldmia r0, {r0,r8-ip} @ setup AES operations + +# load the 16 cipher bytes (4 words) into the CAU's CA0 - CA3 registers + stmia fp, {r4-r7} @ load CA0-CA3 + +# send a series of cau commands to perform the decryption + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + + cmp r2, $10 @ if aes128, finish + beq decrypt_end + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + + cmp r2, $12 @ if aes192, finish + beq decrypt_end + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + + ldmdb r1!, {r4-r7} @ key_sch[i] to [i+4]; r1-- + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + stmia r9, {r4-r7} @ MixColumns + +decrypt_end: + str r0, [ip] @ InvShiftRows,InvSubBytes + str r8, [ip] @ InvSubBytes + +# XOR the first 4 keys into CAO - CA3 plaintext output + ldmia sl, {r4-r7} @ get CA0 - CA3 + ldmdb r1!, {r8-fp} @ key_sch[i] to [i+4]; r1-- + eor r4, r8 + eor r5, r9 + eor r6, sl + eor r7, fp + +# store the 16-byte plain text output block into memory + rev r4, r4 @ byte reverse + rev r5, r5 @ byte reverse + rev r6, r6 @ byte reverse + rev r7, r7 @ byte reverse + stmia r3, {r4-r7} @ save to output[0-3] + + ldmia sp!, {r4-ip} @ restore regs and return + bx lr + +#******************************************************************************* + + .data + .type setkey_reg_data, %object + .align 4 + +setkey_reg_data: + .word rcon @ sl + .word MMCAU_1_CMD+(AESS+CAA)<<22 @ fp + .word MMCAU_PPB_DIRECT @ ip + + .type encrypt_reg_data, %object + .align 4 + +encrypt_reg_data: + .word MMCAU_3_CMDS+(AESS+CA0)<<22+(AESS+CA1)<<11+AESS+CA2 @ r0 + .word MMCAU_2_CMDS+(AESS+CA3)<<22+(AESR)<<11 @ r8 + .word MMCAU_PPB_INDIRECT+(AESC+CA0)<<2 @ r9 + .word MMCAU_PPB_INDIRECT+(STR+CA0)<<2 @ sl + .word MMCAU_PPB_INDIRECT+(LDR+CA0)<<2 @ fp + .word MMCAU_PPB_DIRECT @ ip + + .type decrypt_reg_data, %object + .align 4 + +decrypt_reg_data: + .word MMCAU_3_CMDS+(AESIR)<<22+(AESIS+CA3)<<11+AESIS+CA2 @ r0 + .word MMCAU_2_CMDS+(AESIS+CA1)<<22+(AESIS+CA0)<<11 @ r8 + .word MMCAU_PPB_INDIRECT+(AESIC+CA0)<<2 @ r9 + .word MMCAU_PPB_INDIRECT+(STR+CA0)<<2 @ sl + .word MMCAU_PPB_INDIRECT+(LDR+CA0)<<2 @ fp + .word MMCAU_PPB_DIRECT @ ip + + .type rcon, %object + .align 4 + +rcon: + .word 0x01000000 + .word 0x02000000 + .word 0x04000000 + .word 0x08000000 + .word 0x10000000 + .word 0x20000000 + .word 0x40000000 + .word 0x80000000 + .word 0x1b000000 + .word 0x36000000 diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_des_functions.s b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_des_functions.s new file mode 100755 index 0000000..eecfc0d --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_des_functions.s @@ -0,0 +1,257 @@ +#******************************************************************************* +#******************************************************************************* +# +# Copyright (c) Freescale Semiconductor, Inc 2011. +# +# FILE NAME : mmcau_des_functions.s +# VERSION : $Id: mmcau_des_functions.s.rca 1.4 Thu Nov 21 14:17:23 2013 b40907 Experimental $ +# TYPE : Source Cortex-Mx assembly library code +# DEPARTMENT : MSG R&D Core and Platforms +# AUTHOR : David Schimke +# AUTHOR'S EMAIL : David.Schimke@freescale.com +# AUTHOR : Anthony (Teejay) Ciancio +# AUTHOR'S EMAIL : teejay.ciancio@freescale.com +# ----------------------------------------------------------------------------- +# Release history +# VERSION Date AUTHOR DESCRIPTION +# 08-2010 David Schimke Initial Release +# 12-2010 David Schimke Remove "global" on data objects +# 01-2011 David Schimke Add byte reverse to correct double word +# read of byte arrays for little endian, +# header added +# 11-2013 Teejay Ciancio Small performance improvements to +# encrypt and decrypt +# +#******************************************************************************* +#******************************************************************************* + + .include "cau2_defines.hdr" + .equ MMCAU_PPB_DIRECT,0xe0081000 + .equ MMCAU_PPB_INDIRECT,0xe0081800 + .equ MMCAU_1_CMD,0x80000000 + .equ MMCAU_2_CMDS,0x80100000 + .equ MMCAU_3_CMDS,0x80100200 + + .syntax unified + +#******************************************************************************* +#******************************************************************************* +# +# DES: Check key parity +# arguments +# *key pointer to 64-bit DES key with parity bits +# +# return +# 0 no error +# -1 parity error +# +# calling convention +# int mmcau_des_chk_parity (const unsigned char *key) + + .global _mmcau_des_chk_parity + .global mmcau_des_chk_parity + .type mmcau_des_chk_parity, %function + .align 4 + +_mmcau_des_chk_parity: +mmcau_des_chk_parity: + +# load the 64-bit key into the CAU's CA0/CA1 registers + movw r3, #:lower16:(MMCAU_PPB_INDIRECT+(LDR+CA0)<<2) + ldmia r0, {r1-r2} @ get key[0-1] + movt r3, #:upper16:(MMCAU_PPB_INDIRECT+(LDR+CA0)<<2) + stmia r3, {r1-r2} @ to CA0 & CA1 + +# perform the key schedule and check the parity bits + movw r1, #:lower16:MMCAU_PPB_DIRECT @ r1 -> MMCAU_PPB_DIRECT + movw r2, #:lower16:(MMCAU_1_CMD+(DESK+CP)<<22)@ r2 = mmcau_1_cmd(DESK+CP) + movt r1, #:upper16:MMCAU_PPB_DIRECT + movt r2, #:upper16:(MMCAU_1_CMD+(DESK+CP)<<22) + str r2, [r1] @ mmcau_1_cmd(DESK+CP) + +# the CASR[DPE] reflects the DES key parity check + ldr r0, [r3, $((STR+CASR)-(LDR+CA0))<<2] @ get CAU status in r0 + ands r0, $2 @ test the DPE bit + it ne @ if DPE set + movne r0, $-1 @ then return -1 + + bx lr + + +#******************************************************************************* +#******************************************************************************* +# +# DES: Encrypts a single 8-byte block +# arguments +# *in pointer to 8-byte block of input plaintext +# *key pointer to 64-bit DES key with parity bits +# *out pointer to 8-byte block of output ciphertext +# +# NOTE Input and output blocks may overlap +# +# calling convention +# void mmcau_des_encrypt (const unsigned char *in, +# const unsigned char *key, +# unsigned char *out) + + .global _mmcau_des_encrypt + .global mmcau_des_encrypt + .type mmcau_des_encrypt, %function + .align 4 + +_mmcau_des_encrypt: +mmcau_des_encrypt: + +# register allocation +# -------------------- +# r0 = scratch / *in (arg0) / pointer to MMCAU_PPB_DIRECT +# r1 = scratch / *key (arg1) / MMCAU_PPB_INDIRECT+(STR+CA2)<<2 +# r2 = scratch / *out (arg2) +# r3 = scratch / mmcau_3_cmds(DESK,DESR+IP+KSL1,DESR+KSL2) +# r4 = scratch / mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL2) +# r5 = scratch / mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL1) +# r6 = scratch / mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL2) +# r7 = scratch / mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL2) +# r13 (sp) = stack pointer +# r14 (lr) = link register + + stmdb sp!, {r4-r7} @ save registers on stack + +# load the 64-bit key into the CAU's CA0/CA1 registers +# and the 64-bit plaintext input block into CA2/CA3 + movw r7, #:lower16:(MMCAU_PPB_INDIRECT+((LDR+CA0)<<2)) + movt r7, #:upper16:(MMCAU_PPB_INDIRECT+((LDR+CA0)<<2)) + ldmia r1, {r3-r4} @ copy key[0-1] + rev r3, r3 @ byte reverse + rev r4, r4 @ byte reverse + ldmia r0, {r5-r6} @ and plaintext[0-1] + rev r5, r5 @ byte reverse + rev r6, r6 @ byte reverse + stmia r7, {r3-r6} @ into CA0-CA3 + +# load registers for mmcau commands + movw r0, #:lower16:encrypt_reg_data @ get pointer to commands + movt r0, #:upper16:encrypt_reg_data + ldmia r0, {r0-r1,r3-r7} @ load into registers + +# send a series of 17 direct cau commands to perform the DES round operations +# *(MMCAU_PPB_DIRECT + 0) = mmcau_3_cmds(DESK,DESR+IP+KSL1,DESR+KSL2); +# *(MMCAU_PPB_DIRECT + 1) = mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL2); +# *(MMCAU_PPB_DIRECT + 2) = mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL1); +# *(MMCAU_PPB_DIRECT + 3) = mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL2); +# *(MMCAU_PPB_DIRECT + 4) = mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL2); +# *(MMCAU_PPB_DIRECT + 5) = mmcau_2_cmds(DESR+KSL1,DESR+FP); + + stmia r0, {r3-r6} + stmia r0, {r6-r7} + +# get ciphertext[0-1] from CA2/3 and save to output[0-1] + ldmia r1, {r0-r1} @ get ciphertext[0-1] + rev r0, r0 @ byte reverse + rev r1, r1 @ byte reverse + stmia r2, {r0-r1} @ save to output[0-1] + + ldmia sp!, {r4-r7} @ restore regs and return + bx lr + +#******************************************************************************* +#******************************************************************************* +# +# DES: Decrypts a single 8-byte block +# arguments +# *in pointer to 8-byte block of input ciphertext +# *key pointer to 64-bit DES key with parity bits +# *out pointer to 8-byte block of output plaintext +# +# NOTE Input and output blocks may overlap +# +# calling convention +# void mmcau_des_decrypt (const unsigned char *in, +# const unsigned char *key, +# unsigned char *out) + + .global _mmcau_des_decrypt + .global mmcau_des_decrypt + .type mmcau_des_decrypt, %function + .align 4 + +_mmcau_des_decrypt: +mmcau_des_decrypt: + +# register allocation +# -------------------- +# r0 = scratch / *in (arg0) / pointer to MMCAU_PPB_DIRECT +# r1 = scratch / *key (arg1) / MMCAU_PPB_INDIRECT+(STR+CA2)<<2 +# r2 = scratch / *out (arg2) +# r3 = scratch / mmcau_3_cmds(DESK+DC,DESR+IP+KSR1,DESR+KSR2) +# r4 = scratch / mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR2) +# r5 = scratch / mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR1) +# r6 = scratch / mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR2) +# r7 = scratch / mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR2) +# r13 (sp) = stack pointer +# r14 (lr) = link register + + stmdb sp!, {r4-r7} @ save registers on stack + +# load the 64-bit key into the CAU's CA0/CA1 registers +# and the 64-bit ciphertext input block into CA2/CA3 + movw r7, #:lower16:(MMCAU_PPB_INDIRECT+((LDR+CA0)<<2)) + movt r7, #:upper16:(MMCAU_PPB_INDIRECT+((LDR+CA0)<<2)) + ldmia r1, {r3-r4} @ copy key[0-1] + rev r3, r3 @ byte reverse + rev r4, r4 @ byte reverse + ldmia r0, {r5-r6} @ and ciphertext[0-1] + rev r5, r5 @ byte reverse + rev r6, r6 @ byte reverse + stmia r7, {r3-r6} @ into CA0-CA3 + +# load registers for mmcau commands + movw r0, #:lower16:decrypt_reg_data @ get pointer to commands + movt r0, #:upper16:decrypt_reg_data + ldmia r0, {r0-r1,r3-r7} @ load into registers + +# send a series of 17 direct cau commands to perform the DES round operations +# *(MMCAU_PPB_DIRECT + 0) = mmcau_3_cmds(DESK+DC,DESR+IP+KSR1,DESR+KSR2); +# *(MMCAU_PPB_DIRECT + 1) = mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR2); +# *(MMCAU_PPB_DIRECT + 2) = mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR1); +# *(MMCAU_PPB_DIRECT + 3) = mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR2); +# *(MMCAU_PPB_DIRECT + 4) = mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR2); +# *(MMCAU_PPB_DIRECT + 5) = mmcau_2_cmds(DESR+KSR1,DESR+FP); + + stmia r0, {r3-r6} + stmia r0, {r6-r7} + +# get plaintext[0-1] from CA2/3 and store to output[0-1] + ldmia r1, {r0-r1} @ get plaintext[0-1] + rev r0, r0 @ byte reverse + rev r1, r1 @ byte reverse + stmia r2, {r0-r1} @ save to output[0-1] + + ldmia sp!, {r4-r7} @ restore regs and return + bx lr + + + .data + .type encrypt_reg_data, %object + .align 4 + +encrypt_reg_data: + .word MMCAU_PPB_DIRECT @r0 + .word MMCAU_PPB_INDIRECT+((STR+CA2)<<2) @r1 + .word MMCAU_3_CMDS+(DESK)<<22+(DESR+IP+KSL1)<<11+DESR+KSL2 @r3 + .word MMCAU_3_CMDS+(DESR+KSL2)<<22+(DESR+KSL2)<<11+DESR+KSL2 @r4 + .word MMCAU_3_CMDS+(DESR+KSL2)<<22+(DESR+KSL2)<<11+DESR+KSL1 @r5 + .word MMCAU_3_CMDS+(DESR+KSL2)<<22+(DESR+KSL2)<<11+DESR+KSL2 @r6 + .word MMCAU_2_CMDS+(DESR+KSL1)<<22+(DESR+FP)<<11 @r7 + + .type decrypt_reg_data, %object + .align 4 + +decrypt_reg_data: + .word MMCAU_PPB_DIRECT @r0 + .word MMCAU_PPB_INDIRECT+((STR+CA2)<<2) @r1 + .word MMCAU_3_CMDS+(DESK+DC)<<22+(DESR+IP+KSR1)<<11+DESR+KSR2 @r3 + .word MMCAU_3_CMDS+(DESR+KSR2)<<22+(DESR+KSR2)<<11+DESR+KSR2 @r4 + .word MMCAU_3_CMDS+(DESR+KSR2)<<22+(DESR+KSR2)<<11+DESR+KSR1 @r5 + .word MMCAU_3_CMDS+(DESR+KSR2)<<22+(DESR+KSR2)<<11+DESR+KSR2 @r6 + .word MMCAU_2_CMDS+(DESR+KSR1)<<22+(DESR+FP)<<11 @r7 diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_md5_functions.s b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_md5_functions.s new file mode 100755 index 0000000..8500347 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_md5_functions.s @@ -0,0 +1,891 @@ +#******************************************************************************* +#******************************************************************************* +# +# Copyright (c) Freescale Semiconductor, Inc 2011. +# +# FILE NAME : mmcau_md5_functions.s +# VERSION : $Id: mmcau_md5_functions.s.rca 1.6 Thu Nov 21 14:18:27 2013 b40907 Experimental $ +# TYPE : Source Cortex-Mx assembly library code +# DEPARTMENT : MSG R&D Core and Platforms +# AUTHOR : David Schimke +# AUTHOR'S EMAIL : David.Schimke@freescale.com +# ----------------------------------------------------------------------------- +# Release history +# VERSION Date AUTHOR DESCRIPTION +# 08-2010 David Schimke Initial Release +# 12-2010 David Schimke Remove "global" on data objects +# 01-2011 David Schimke Header added +# 11-2013 Teejay Ciancio Cleanup +# +#******************************************************************************* +#******************************************************************************* + + .include "cau2_defines.hdr" + .equ MMCAU_PPB_DIRECT,0xe0081000 + .equ MMCAU_PPB_INDIRECT,0xe0081800 + + .syntax unified + +#******************************************************************************* +#******************************************************************************* +# +# MD5: Initializes the MD5 state variables +# arguments +# *md5_state pointer to 120-bit block of md5 state variables: +# a,b,c,d +# +# calling convention +# void mmcau_md5_initialize_output (const unsigned int *md5_state) + + .global _mmcau_md5_initialize_output + .global mmcau_md5_initialize_output + .type mmcau_md5_initialize_output, %function + .align 4 + +_mmcau_md5_initialize_output: +mmcau_md5_initialize_output: + + stmdb sp!, {r4} @ save registers + + movw r1, #:lower16:md5_initial_h @ r1 -> initial data + movt r1, #:upper16:md5_initial_h + +# copy initial data into hash output buffer + ldmia r1, {r1-r4} @ get md5[0-3] + stmia r0, {r1-r4} @ copy to md5_state[0-3] + + ldmia sp!, {r4} @ restore registers + bx lr + + +#******************************************************************************* +#******************************************************************************* +# +# MD5: Updates MD5 state variables for one or more input message blocks +# +# arguments +# *msg_data pointer to start of input message data +# num_blks number of 512-bit blocks to process +# *md5_state pointer to 128-bit block of MD5 state variables: a,b,c,d +# +# calling convention +# void mmucau_md5_hash_n (const unsigned char *msg_data, +# const int num_blks, +# unsigned char *md5_state) + + .global _mmcau_md5_hash_n + .global mmcau_md5_hash_n + .type mmcau_md5_hash_n, %function + .align 4 + +_mmcau_md5_hash_n: +mmcau_md5_hash_n: + +# register allocation +# -------------------- +# r0 = input pointer (arg0) +# r1 = a / input num_blks (arg1) +# r2 = b / output pointer (arg2) +# r3 = c +# r4 = d +# r5 = scratch +# r6 = scratch +# r7 = pointer to md5_t +# r8 = output pointer +# r9 = input num_blks +# r10 (sl) = not used +# r11 (fp) = not used +# r12 (ip) = not used +# r13 (sp) = stack pointer +# r14 (lr) = link register + + stmdb sp!, {r4-r9} @ save registers on stack + + mov r9, r1 @ r9 = num_blks + mov r8, r2 @ r8 = output pointer + + ldmia r8, {r1-r4} @ get md5_state[0-3] + + movw r7, #:lower16:md5_t @ r7 -> md5_t + movt r7, #:upper16:md5_t + + .align 2 +next_blk: + +# 16 rounds with F(x,y,z) = (x & y) | (~x & z) + + bic.w r5, r4, r2 @ ~b & d + and.w r6, r3, r2 @ b & c + orrs r5, r6 @ F(b,c,d) + add r1, r5 @ a += F(b,c,d) + ldr r6, [r0] @ input[0] + add r1, r6 @ a += input[0] + ldr r6, [r7] @ t[0] + add r1, r6 @ a += t[0] + add.w r1, r2, r1, ror #25 @ a = b + ROTL(a,7) + + bic.w r5, r3, r1 @ ~a & c + and.w r6, r2, r1 @ a & b + orrs r5, r6 @ F(a,b,c) + add r4, r5 @ d += F(a,b,c) + ldr r6, [r0, $1<<2] @ input[1] + add r4, r6 @ d += input[1] + ldr r6, [r7, $1<<2] @ t[1] + add r4, r6 @ d += t[1] + add.w r4, r1, r4, ror #20 @ d = a + ROTL(d,12) + + bic.w r5, r2, r4 @ ~d & b + and.w r6, r1, r4 @ d & a + orrs r5, r6 @ F(d,a,b) + add r3, r5 @ c += F(d,a,b) + ldr r6, [r0, $2<<2] @ input[2] + add r3, r6 @ c += input[2] + ldr r6, [r7, $2<<2] @ t[2] + add r3, r6 @ c += t[2] + add.w r3, r4, r3, ror #15 @ c = d + ROTL(c,17) + + bic.w r5, r1, r3 @ ~c & a + and.w r6, r4, r3 @ c & d + orrs r5, r6 @ F(c,d,a) + add r2, r5 @ b += F(c,d,a) + ldr r6, [r0, $3<<2] @ input[3] + add r2, r6 @ b += input[3] + ldr r6, [r7, $3<<2] @ t[3] + add r2, r6 @ b += t[3] + add.w r2, r3, r2, ror #10 @ b = c + ROTL(b,22) + + bic.w r5, r4, r2 @ ~b & d + and.w r6, r3, r2 @ b & c + orrs r5, r6 @ F(b,c,d) + add r1, r5 @ a += F(b,c,d) + ldr r6, [r0, $4<<2] @ input[4] + add r1, r6 @ a += input[4] + ldr r6, [r7, $4<<2] @ t[4] + add r1, r6 @ a += t[4] + add.w r1, r2, r1, ror #25 @ a = b + ROTL(a,7) + + bic.w r5, r3, r1 @ ~a & c + and.w r6, r2, r1 @ a & b + orrs r5, r6 @ F(a,b,c) + add r4, r5 @ d += F(a,b,c) + ldr r6, [r0, $5<<2] @ input[5] + add r4, r6 @ d += input[5] + ldr r6, [r7, $5<<2] @ t[5] + add r4, r6 @ d += t[5] + add.w r4, r1, r4, ror #20 @ d = a + ROTL(d,12) + + bic.w r5, r2, r4 @ ~d & b + and.w r6, r1, r4 @ d & a + orrs r5, r6 @ F(d,a,b) + add r3, r5 @ c += F(d,a,b) + ldr r6, [r0, $6<<2] @ input[6] + add r3, r6 @ c += input[6] + ldr r6, [r7, $6<<2] @ t[6] + add r3, r6 @ c += t[6] + add.w r3, r4, r3, ror #15 @ c = d + ROTL(c,17) + + bic.w r5, r1, r3 @ ~c & a + and.w r6, r4, r3 @ c & d + orrs r5, r6 @ F(c,d,a) + add r2, r5 @ b += F(c,d,a) + ldr r6, [r0, $7<<2] @ input[7] + add r2, r6 @ b += input[7] + ldr r6, [r7, $7<<2] @ t[7] + add r2, r6 @ b += t[7] + add.w r2, r3, r2, ror #10 @ b = c + ROTL(b,22) + + bic.w r5, r4, r2 @ ~b & d + and.w r6, r3, r2 @ b & c + orrs r5, r6 @ F(b,c,d) + add r1, r5 @ a += F(b,c,d) + ldr r6, [r0, $8<<2] @ input[8] + add r1, r6 @ a += input[8] + ldr r6, [r7, $8<<2] @ t[8] + add r1, r6 @ a += t[8] + add.w r1, r2, r1, ror #25 @ a = b + ROTL(a,7) + + bic.w r5, r3, r1 @ ~a & c + and.w r6, r2, r1 @ a & b + orrs r5, r6 @ F(a,b,c) + add r4, r5 @ d += F(a,b,c) + ldr r6, [r0, $9<<2] @ input[9] + add r4, r6 @ d += input[9] + ldr r6, [r7, $9<<2] @ t[9] + add r4, r6 @ d += t[9] + add.w r4, r1, r4, ror #20 @ d = a + ROTL(d,12) + + bic.w r5, r2, r4 @ ~d & b + and.w r6, r1, r4 @ d & a + orrs r5, r6 @ F(d,a,b) + add r3, r5 @ c += F(d,a,b) + ldr r6, [r0, $10<<2] @ input[10] + add r3, r6 @ c += input[10] + ldr r6, [r7, $10<<2] @ t[10] + add r3, r6 @ c += t[10] + add.w r3, r4, r3, ror #15 @ c = d + ROTL(c,17) + + bic.w r5, r1, r3 @ ~c & a + and.w r6, r4, r3 @ c & d + orrs r5, r6 @ F(c,d,a) + add r2, r5 @ b += F(c,d,a) + ldr r6, [r0, $11<<2] @ input[11] + add r2, r6 @ b += input[11] + ldr r6, [r7, $11<<2] @ t[11] + add r2, r6 @ b += t[11] + add.w r2, r3, r2, ror #10 @ b = c + ROTL(b,22) + + bic.w r5, r4, r2 @ ~b & d + and.w r6, r3, r2 @ b & c + orrs r5, r6 @ F(b,c,d) + add r1, r5 @ a += F(b,c,d) + ldr r6, [r0, $12<<2] @ input[12] + add r1, r6 @ a += input[12] + ldr r6, [r7, $12<<2] @ t[12] + add r1, r6 @ a += t[12] + add.w r1, r2, r1, ror #25 @ a = b + ROTL(a,7) + + bic.w r5, r3, r1 @ ~a & c + and.w r6, r2, r1 @ a & b + orrs r5, r6 @ F(a,b,c) + add r4, r5 @ d += F(a,b,c) + ldr r6, [r0, $13<<2] @ input[13] + add r4, r6 @ d += input[13] + ldr r6, [r7, $13<<2] @ t[13] + add r4, r6 @ d += t[13] + add.w r4, r1, r4, ror #20 @ d = a + ROTL(d,12) + + bic.w r5, r2, r4 @ ~d & b + and.w r6, r1, r4 @ d & a + orrs r5, r6 @ F(d,a,b) + add r3, r5 @ c += F(d,a,b) + ldr r6, [r0, $14<<2] @ input[14] + add r3, r6 @ c += input[14] + ldr r6, [r7, $14<<2] @ t[14] + add r3, r6 @ c += t[14] + add.w r3, r4, r3, ror #15 @ c = d + ROTL(c,17) + + bic.w r5, r1, r3 @ ~c & a + and.w r6, r4, r3 @ c & d + orrs r5, r6 @ F(c,d,a) + add r2, r5 @ b += F(c,d,a) + ldr r6, [r0, $15<<2] @ input[15] + add r2, r6 @ b += input[15] + ldr r6, [r7, $15<<2] @ t[15] + add r2, r6 @ b += t[15] + add.w r2, r3, r2, ror #10 @ b = c + ROTL(b,22) + +# 16 rounds with G(x,y,z) = (x & z) | (y & ~z) + + bic.w r5, r3, r4 @ ~d & c + and.w r6, r2, r4 @ d & b + orrs r5, r6 @ G(b,c,d) + add r1, r5 @ a += G(b,c,d) + ldr r6, [r0, $1<<2] @ input[1] + add r1, r6 @ a += input[1] + ldr r6, [r7, $16<<2] @ t[16] + add r1, r6 @ a += t[16] + add.w r1, r2, r1, ror #27 @ a = b + ROTL(a,5) + + bic.w r5, r2, r3 @ ~c & b + and.w r6, r1, r3 @ c & a + orrs r5, r6 @ G(a,b,c) + add r4, r5 @ d += G(a,b,c) + ldr r6, [r0, $6<<2] @ input[6] + add r4, r6 @ d += input[6] + ldr r6, [r7, $17<<2] @ t[17] + add r4, r6 @ d += t[17] + add.w r4, r1, r4, ror #23 @ d = a + ROTL(d,9) + + bic.w r5, r1, r2 @ ~b & a + and.w r6, r4, r2 @ b & d + orrs r5, r6 @ G(d,a,b) + add r3, r5 @ c += G(d,a,b) + ldr r6, [r0, $11<<2] @ input[11] + add r3, r6 @ c += input[11] + ldr r6, [r7, $18<<2] @ t[18] + add r3, r6 @ c += t[18] + add.w r3, r4, r3, ror #18 @ c = d + ROTL(c,14) + + bic.w r5, r4, r1 @ ~a & d + and.w r6, r3, r1 @ a & c + orrs r5, r6 @ G(d,a,b) + add r2, r5 @ b += G(c,d,a) + ldr r6, [r0] @ input[0] + add r2, r6 @ b += input[0] + ldr r6, [r7, $19<<2] @ t[19] + add r2, r6 @ b += t[19] + add.w r2, r3, r2, ror #12 @ b = c + ROTL(b,20) + + bic.w r5, r3, r4 @ ~d & c + and.w r6, r2, r4 @ d & b + orrs r5, r6 @ G(b,c,d) + add r1, r5 @ a += G(b,c,d) + ldr r6, [r0, $5<<2] @ input[5] + add r1, r6 @ a += input[5] + ldr r6, [r7, $20<<2] @ t[20] + add r1, r6 @ a += t[20] + add.w r1, r2, r1, ror #27 @ a = b + ROTL(a,5) + + bic.w r5, r2, r3 @ ~c & b + and.w r6, r1, r3 @ c & a + orrs r5, r6 @ G(a,b,c) + add r4, r5 @ d += G(a,b,c) + ldr r6, [r0, $10<<2] @ input[10] + add r4, r6 @ d += input[10] + ldr r6, [r7, $21<<2] @ t[21] + add r4, r6 @ d += t[21] + add.w r4, r1, r4, ror #23 @ d = a + ROTL(d,9) + + bic.w r5, r1, r2 @ ~b & a + and.w r6, r4, r2 @ b & d + orrs r5, r6 @ G(d,a,b) + add r3, r5 @ c += G(d,a,b) + ldr r6, [r0, $15<<2] @ input[15] + add r3, r6 @ c += input[15] + ldr r6, [r7, $22<<2] @ t[22] + add r3, r6 @ c += t[22] + add.w r3, r4, r3, ror #18 @ c = d + ROTL(c,14) + + bic.w r5, r4, r1 @ ~a & d + and.w r6, r3, r1 @ a & c + orrs r5, r6 @ G(d,a,b) + add r2, r5 @ b += G(c,d,a) + ldr r6, [r0, $4<<2] @ input[4] + add r2, r6 @ b += input[4] + ldr r6, [r7, $23<<2] @ t[23] + add r2, r6 @ b += t[23] + add.w r2, r3, r2, ror #12 @ b = c + ROTL(b,20) + + bic.w r5, r3, r4 @ ~d & c + and.w r6, r2, r4 @ d & b + orrs r5, r6 @ G(b,c,d) + add r1, r5 @ a += G(b,c,d) + ldr r6, [r0, $9<<2] @ input[9] + add r1, r6 @ a += input[9] + ldr r6, [r7, $24<<2] @ t[24] + add r1, r6 @ a += t[24] + add.w r1, r2, r1, ror #27 @ a = b + ROTL(a,5) + + bic.w r5, r2, r3 @ ~c & b + and.w r6, r1, r3 @ c & a + orrs r5, r6 @ G(a,b,c) + add r4, r5 @ d += G(a,b,c) + ldr r6, [r0, $14<<2] @ input[14] + add r4, r6 @ d += input[14] + ldr r6, [r7, $25<<2] @ t[25] + add r4, r6 @ d += t[25] + add.w r4, r1, r4, ror #23 @ d = a + ROTL(d,9) + + bic.w r5, r1, r2 @ ~b & a + and.w r6, r4, r2 @ b & d + orrs r5, r6 @ G(d,a,b) + add r3, r5 @ c += G(d,a,b) + ldr r6, [r0, $3<<2] @ input[3] + add r3, r6 @ c += input[3] + ldr r6, [r7, $26<<2] @ t[26] + add r3, r6 @ c += t[26] + add.w r3, r4, r3, ror #18 @ c = d + ROTL(c,14) + + bic.w r5, r4, r1 @ ~a & d + and.w r6, r3, r1 @ a & c + orrs r5, r6 @ G(d,a,b) + add r2, r5 @ b += G(c,d,a) + ldr r6, [r0, $8<<2] @ input[8] + add r2, r6 @ b += input[8] + ldr r6, [r7, $27<<2] @ t[27] + add r2, r6 @ b += t[27] + add.w r2, r3, r2, ror #12 @ b = c + ROTL(b,20) + + bic.w r5, r3, r4 @ ~d & c + and.w r6, r2, r4 @ d & b + orrs r5, r6 @ G(b,c,d) + add r1, r5 @ a += G(b,c,d) + ldr r6, [r0, $13<<2] @ input[13] + add r1, r6 @ a += input[13] + ldr r6, [r7, $28<<2] @ t[28] + add r1, r6 @ a += t[28] + add.w r1, r2, r1, ror #27 @ a = b + ROTL(a,5) + + bic.w r5, r2, r3 @ ~c & b + and.w r6, r1, r3 @ c & a + orrs r5, r6 @ G(a,b,c) + add r4, r5 @ d += G(a,b,c) + ldr r6, [r0, $2<<2] @ input[2] + add r4, r6 @ d += input[2] + ldr r6, [r7, $29<<2] @ t[29] + add r4, r6 @ d += t[29] + add.w r4, r1, r4, ror #23 @ d = a + ROTL(d,9) + + bic.w r5, r1, r2 @ ~b & a + and.w r6, r4, r2 @ b & d + orrs r5, r6 @ G(d,a,b) + add r3, r5 @ c += G(d,a,b) + ldr r6, [r0, $7<<2] @ input[7] + add r3, r6 @ c += input[7] + ldr r6, [r7, $30<<2] @ t[30] + add r3, r6 @ c += t[30] + add.w r3, r4, r3, ror #18 @ c = d + ROTL(c,14) + + bic.w r5, r4, r1 @ ~a & d + and.w r6, r3, r1 @ a & c + orrs r5, r6 @ G(d,a,b) + add r2, r5 @ b += G(c,d,a) + ldr r6, [r0, $12<<2] @ input[12] + add r2, r6 @ b += input[12] + ldr r6, [r7, $31<<2] @ t[31] + add r2, r6 @ b += t[31] + add.w r2, r3, r2, ror #12 @ b = c + ROTL(b,20) + +# 16 rounds with H(x,y,z) = x ^ y ^ z + + eor.w r5, r2, r3 @ b ^ c + eors r5, r4 @ H(b,c,d) + add r1, r5 @ a += H(b,c,d) + ldr r6, [r0, $5<<2] @ input[5] + add r1, r6 @ a += input[5] + ldr r6, [r7, $32<<2] @ t[32] + add r1, r6 @ a += t[32] + add.w r1, r2, r1, ror #28 @ a = b + ROTL(a,4) + + eor.w r5, r1, r2 @ a ^ b + eors r5, r3 @ H(a,b,c) + add r4, r5 @ d += H(a,b,c) + ldr r6, [r0, $8<<2] @ input[8] + add r4, r6 @ d += input[8] + ldr r6, [r7, $33<<2] @ t[33] + add r4, r6 @ d += t[33] + add.w r4, r1, r4, ror #21 @ d = a + ROTL(d,11) + + eor.w r5, r4, r1 @ d ^ a + eors r5, r2 @ H(d,a,b) + add r3, r5 @ c += H(d,a,b) + ldr r6, [r0, $11<<2] @ input[11] + add r3, r6 @ c += input[11] + ldr r6, [r7, $34<<2] @ t[34] + add r3, r6 @ c += t[34] + add.w r3, r4, r3, ror #16 @ c = d + ROTL(c,16) + + eor.w r5, r3, r4 @ c ^ d + eors r5, r1 @ H(c,d,a) + add r2, r5 @ b += H(c,d,a) + ldr r6, [r0, $14<<2] @ input[14] + add r2, r6 @ b += input[14] + ldr r6, [r7, $35<<2] @ t[35] + add r2, r6 @ b += t[35] + add.w r2, r3, r2, ror #9 @ b = c + ROTL(d,23) + + eor.w r5, r2, r3 @ b ^ c + eors r5, r4 @ H(b,c,d) + add r1, r5 @ a += H(b,c,d) + ldr r6, [r0, $1<<2] @ input[1] + add r1, r6 @ a += input[1] + ldr r6, [r7, $36<<2] @ t[36] + add r1, r6 @ a += t[36] + add.w r1, r2, r1, ror #28 @ a = b + ROTL(a,4) + + eor.w r5, r1, r2 @ a ^ b + eors r5, r3 @ H(a,b,c) + add r4, r5 @ d += H(a,b,c) + ldr r6, [r0, $4<<2] @ input[4] + add r4, r6 @ d += input[4] + ldr r6, [r7, $37<<2] @ t[37] + add r4, r6 @ d += t[37] + add.w r4, r1, r4, ror #21 @ d = a + ROTL(d,11) + + eor.w r5, r4, r1 @ d ^ a + eors r5, r2 @ H(d,a,b) + add r3, r5 @ c += H(d,a,b) + ldr r6, [r0, $7<<2] @ input[7] + add r3, r6 @ c += input[7] + ldr r6, [r7, $38<<2] @ t[38] + add r3, r6 @ c += t[38] + add.w r3, r4, r3, ror #16 @ c = d + ROTL(c,16) + + eor.w r5, r3, r4 @ c ^ d + eors r5, r1 @ H(c,d,a) + add r2, r5 @ b += H(c,d,a) + ldr r6, [r0, $10<<2] @ input[10] + add r2, r6 @ b += input[10] + ldr r6, [r7, $39<<2] @ t[39] + add r2, r6 @ b += t[39] + add.w r2, r3, r2, ror #9 @ b = c + ROTL(d,23) + + eor.w r5, r2, r3 @ b ^ c + eors r5, r4 @ H(b,c,d) + add r1, r5 @ a += H(b,c,d) + ldr r6, [r0, $13<<2] @ input[13] + add r1, r6 @ a += input[13] + ldr r6, [r7, $40<<2] @ t[40] + add r1, r6 @ a += t[40] + add.w r1, r2, r1, ror #28 @ a = b + ROTL(a,4) + + eor.w r5, r1, r2 @ a ^ b + eors r5, r3 @ H(a,b,c) + add r4, r5 @ d += H(a,b,c) + ldr r6, [r0] @ input[0] + add r4, r6 @ d += input[0] + ldr r6, [r7, $41<<2] @ t[41] + add r4, r6 @ d += t[41] + add.w r4, r1, r4, ror #21 @ d = a + ROTL(d,11) + + eor.w r5, r4, r1 @ d ^ a + eors r5, r2 @ H(d,a,b) + add r3, r5 @ c += H(d,a,b) + ldr r6, [r0, $3<<2] @ input[3] + add r3, r6 @ c += input[3] + ldr r6, [r7, $42<<2] @ t[42] + add r3, r6 @ c += t[42] + add.w r3, r4, r3, ror #16 @ c = d + ROTL(c,16) + + eor.w r5, r3, r4 @ c ^ d + eors r5, r1 @ H(c,d,a) + add r2, r5 @ b += H(c,d,a) + ldr r6, [r0, $6<<2] @ input[6] + add r2, r6 @ b += input[6] + ldr r6, [r7, $43<<2] @ t[43] + add r2, r6 @ b += t[43] + add.w r2, r3, r2, ror #9 @ b = c + ROTL(d,23) + + eor.w r5, r2, r3 @ b ^ c + eors r5, r4 @ H(b,c,d) + add r1, r5 @ a += H(b,c,d) + ldr r6, [r0, $9<<2] @ input[9] + add r1, r6 @ a += input[9] + ldr r6, [r7, $44<<2] @ t[44] + add r1, r6 @ a += t[44] + add.w r1, r2, r1, ror #28 @ a = b + ROTL(a,4) + + eor.w r5, r1, r2 @ a ^ b + eors r5, r3 @ H(a,b,c) + add r4, r5 @ d += H(a,b,c) + ldr r6, [r0, $12<<2] @ input[12] + add r4, r6 @ d += input[12] + ldr r6, [r7, $45<<2] @ t[45] + add r4, r6 @ d += t[45] + add.w r4, r1, r4, ror #21 @ d = a + ROTL(d,11) + + eor.w r5, r4, r1 @ d ^ a + eors r5, r2 @ H(d,a,b) + add r3, r5 @ c += H(d,a,b) + ldr r6, [r0, $15<<2] @ input[15] + add r3, r6 @ c += input[15] + ldr r6, [r7, $46<<2] @ t[46] + add r3, r6 @ c += t[46] + add.w r3, r4, r3, ror #16 @ c = d + ROTL(c,16) + + eor.w r5, r3, r4 @ c ^ d + eors r5, r1 @ H(c,d,a) + add r2, r5 @ b += H(c,d,a) + ldr r6, [r0, $2<<2] @ input[2] + add r2, r6 @ b += input[2] + ldr r6, [r7, $47<<2] @ t[47] + add r2, r6 @ b += t[47] + add.w r2, r3, r2, ror #9 @ b = c + ROTL(d,23) + +# 16 rounds with I(x,y,z) = y ^ (x | ~z) + + orn r5, r2, r4 @ b | ~d + eors r5, r3 @ I(b,c,d) + add r1, r5 @ a += I(b,c,d) + ldr r6, [r0] @ input[0] + add r1, r6 @ a += input[0] + ldr r6, [r7, $48<<2] @ t[48] + add r1, r6 @ a += t[48] + add.w r1, r2, r1, ror #26 @ a = b + ROTL(a,6) + + orn r5, r1, r3 @ a | ~c + eors r5, r2 @ I(a,b,c) + add r4, r5 @ d += I(a,b,c) + ldr r6, [r0, $7<<2] @ input[7] + add r4, r6 @ d += input[7] + ldr r6, [r7, $49<<2] @ t[49] + add r4, r6 @ d += t[49] + add.w r4, r1, r4, ror #22 @ d = a + ROTL(d,10) + + orn r5, r4, r2 @ d | ~b + eors r5, r1 @ I(d,a,b) + add r3, r5 @ c += I(d,a,b) + ldr r6, [r0, $14<<2] @ input[14] + add r3, r6 @ c += input[14] + ldr r6, [r7, $50<<2] @ t[50] + add r3, r6 @ c += t[50] + add.w r3, r4, r3, ror #17 @ c = d + ROTL(c,15) + + orn r5, r3, r1 @ c | ~a + eors r5, r4 @ I(c,d,a) + add r2, r5 @ b += I(c,d,a) + ldr r6, [r0, $5<<2] @ input[5] + add r2, r6 @ b += input[5] + ldr r6, [r7, $51<<2] @ t[51] + add r2, r6 @ b += t[51] + add.w r2, r3, r2, ror #11 @ b = c + ROTL(b,21) + + orn r5, r2, r4 @ b | ~d + eors r5, r3 @ I(b,c,d) + add r1, r5 @ a += I(b,c,d) + ldr r6, [r0, $12<<2] @ input[12] + add r1, r6 @ a += input[12] + ldr r6, [r7, $52<<2] @ t[52] + add r1, r6 @ a += t[52] + add.w r1, r2, r1, ror #26 @ a = b + ROTL(a,6) + + orn r5, r1, r3 @ a | ~c + eors r5, r2 @ I(a,b,c) + add r4, r5 @ d += I(a,b,c) + ldr r6, [r0, $3<<2] @ input[3] + add r4, r6 @ d += input[3] + ldr r6, [r7, $53<<2] @ t[53] + add r4, r6 @ d += t[53] + add.w r4, r1, r4, ror #22 @ d = a + ROTL(d,10) + + orn r5, r4, r2 @ d | ~b + eors r5, r1 @ I(d,a,b) + add r3, r5 @ c += I(d,a,b) + ldr r6, [r0, $10<<2] @ input[10] + add r3, r6 @ c += input[10] + ldr r6, [r7, $54<<2] @ t[54] + add r3, r6 @ c += t[54] + add.w r3, r4, r3, ror #17 @ c = d + ROTL(c,15) + + orn r5, r3, r1 @ c | ~a + eors r5, r4 @ I(c,d,a) + add r2, r5 @ b += I(c,d,a) + ldr r6, [r0, $1<<2] @ input[1] + add r2, r6 @ b += input[1] + ldr r6, [r7, $55<<2] @ t[55] + add r2, r6 @ b += t[55] + add.w r2, r3, r2, ror #11 @ b = c + ROTL(b,21) + + orn r5, r2, r4 @ b | ~d + eors r5, r3 @ I(b,c,d) + add r1, r5 @ a += I(b,c,d) + ldr r6, [r0, $8<<2] @ input[8] + add r1, r6 @ a += input[8] + ldr r6, [r7, $56<<2] @ t[56] + add r1, r6 @ a += t[56] + add.w r1, r2, r1, ror #26 @ a = b + ROTL(a,6) + + orn r5, r1, r3 @ a | ~c + eors r5, r2 @ I(a,b,c) + add r4, r5 @ d += I(a,b,c) + ldr r6, [r0, $15<<2] @ input[15] + add r4, r6 @ d += input[15] + ldr r6, [r7, $57<<2] @ t[57] + add r4, r6 @ d += t[57] + add.w r4, r1, r4, ror #22 @ d = a + ROTL(d,10) + + orn r5, r4, r2 @ d | ~b + eors r5, r1 @ I(d,a,b) + add r3, r5 @ c += I(d,a,b) + ldr r6, [r0, $6<<2] @ input[6] + add r3, r6 @ c += input[6] + ldr r6, [r7, $58<<2] @ t[58] + add r3, r6 @ c += t[58] + add.w r3, r4, r3, ror #17 @ c = d + ROTL(c,15) + + orn r5, r3, r1 @ c | ~a + eors r5, r4 @ I(c,d,a) + add r2, r5 @ b += I(c,d,a) + ldr r6, [r0, $13<<2] @ input[13] + add r2, r6 @ b += input[13] + ldr r6, [r7, $59<<2] @ t[59] + add r2, r6 @ b += t[59] + add.w r2, r3, r2, ror #11 @ b = c + ROTL(b,21) + + orn r5, r2, r4 @ b | ~d + eors r5, r3 @ I(b,c,d) + add r1, r5 @ a += I(b,c,d) + ldr r6, [r0, $4<<2] @ input[4] + add r1, r6 @ a += input[4] + ldr r6, [r7, $60<<2] @ t[60] + add r1, r6 @ a += t[60] + add.w r1, r2, r1, ror #26 @ a = b + ROTL(a,6) + + orn r5, r1, r3 @ a | ~c + eors r5, r2 @ I(a,b,c) + add r4, r5 @ d += I(a,b,c) + ldr r6, [r0, $11<<2] @ input[11] + add r4, r6 @ d += input[11] + ldr r6, [r7, $61<<2] @ t[61] + add r4, r6 @ d += t[61] + add.w r4, r1, r4, ror #22 @ d = a + ROTL(d,10) + + orn r5, r4, r2 @ d | ~b + eors r5, r1 @ I(d,a,b) + add r3, r5 @ c += I(d,a,b) + ldr r6, [r0, $2<<2] @ input[2] + add r3, r6 @ c += input[2] + ldr r6, [r7, $62<<2] @ t[62] + add r3, r6 @ c += t[62] + add.w r3, r4, r3, ror #17 @ c = d + ROTL(c,15) + + orn r5, r3, r1 @ c | ~a + eors r5, r4 @ I(c,d,a) + add r2, r5 @ b += I(c,d,a) + ldr r6, [r0, $9<<2] @ input[9] + add r2, r6 @ b += input[9] + ldr r6, [r7, $63<<2] @ t[63] + add r2, r6 @ b += t[63] + add.w r2, r3, r2, ror #11 @ b = c + ROTL(b,21) + + ldr r5, [r8] @ get original md5_stats[0] + add r1, r5 + ldr r5, [r8, $1<<2] @ get original md5_stats[1] + add r2, r5 + ldr r5, [r8, $2<<2] @ get original md5_stats[2] + add r3, r5 + ldr r5, [r8, $3<<2] @ get original md5_stats[3] + add r4, r5 + + stmia r8, {r1-r4} @ store new md5_state[0-3] + + add r0, $64 @ input ptr -> next block + subs r9, $1 @ decrement num_blks + bne next_blk + + ldmia sp!, {r4-r9} @ restore regs and return + bx lr + + +#******************************************************************************* +#******************************************************************************* +# +# MD5: Updates MD5 state variables for one or more input message blocks +# arguments +# *msg_data pointer to start of input message data +# num_blks number of 512-bit blocks to process +# *md5_state pointer to 120-bit block of MD5 state variables: +# a,b,c,d +# +# calling convention +# void mmcau_md5_update (const unsigned char *msg_data, +# const int num_blks, +# unsigned char *md5_state) + + + .global _mmcau_md5_update + .global mmcau_md5_update + .type mmcau_md5_update, %function + .align 4 + +_mmcau_md5_update: +mmcau_md5_update: + + push {r4-r7,lr} + + movw r4, #:lower16:md5_initial_h @ r4 -> initial data + movt r4, #:upper16:md5_initial_h + +# copy initial data into hash output buffer + ldmia r4, {r4-r7} @ get md5[0-3] + stmia r2, {r4-r7} @ copy to md5_state[0-3] + + bl mmcau_md5_hash_n @ call hash_n routine + + pop {r4-r7,pc} + +#******************************************************************************* +#******************************************************************************* +# +# MD5: Updates MD5 state variables for one input message block +# +# arguments +# *msg_data pointer to start of input message data +# *md5_state pointer to 128-bit block of MD5 state variables: a,b,c,d +# +# calling convention +# void mmucau_md5_hash (const unsigned char *msg_data, +# unsigned char *md5_state) + + .global _mmcau_md5_hash + .global mmcau_md5_hash + .type mmcau_md5_hash, %function + .align 4 + +_mmcau_md5_hash: +mmcau_md5_hash: + + mov r2, r1 @ arg1 (*md5_state) to arg2 + mov r1, $1 @ num_blks = 1 + b mmcau_md5_hash_n @ call hash_n routine + + +#******************************************************************************* + + .data + .type md5_initial_h, %object + .align 4 + +md5_initial_h: + .word 0x67452301 @ initial a + .word 0xefcdab89 @ initial b + .word 0x98badcfe @ initial c + .word 0x10325476 @ initial d + + .type md5_t, %object + .align 4 +md5_t: + .word 0xd76aa478 + .word 0xe8c7b756 + .word 0x242070db + .word 0xc1bdceee + .word 0xf57c0faf + .word 0x4787c62a + .word 0xa8304613 + .word 0xfd469501 + .word 0x698098d8 + .word 0x8b44f7af + .word 0xffff5bb1 + .word 0x895cd7be + .word 0x6b901122 + .word 0xfd987193 + .word 0xa679438e + .word 0x49b40821 + .word 0xf61e2562 + .word 0xc040b340 + .word 0x265e5a51 + .word 0xe9b6c7aa + .word 0xd62f105d + .word 0x02441453 + .word 0xd8a1e681 + .word 0xe7d3fbc8 + .word 0x21e1cde6 + .word 0xc33707d6 + .word 0xf4d50d87 + .word 0x455a14ed + .word 0xa9e3e905 + .word 0xfcefa3f8 + .word 0x676f02d9 + .word 0x8d2a4c8a + .word 0xfffa3942 + .word 0x8771f681 + .word 0x6d9d6122 + .word 0xfde5380c + .word 0xa4beea44 + .word 0x4bdecfa9 + .word 0xf6bb4b60 + .word 0xbebfbc70 + .word 0x289b7ec6 + .word 0xeaa127fa + .word 0xd4ef3085 + .word 0x04881d05 + .word 0xd9d4d039 + .word 0xe6db99e5 + .word 0x1fa27cf8 + .word 0xc4ac5665 + .word 0xf4292244 + .word 0x432aff97 + .word 0xab9423a7 + .word 0xfc93a039 + .word 0x655b59c3 + .word 0x8f0ccc92 + .word 0xffeff47d + .word 0x85845dd1 + .word 0x6fa87e4f + .word 0xfe2ce6e0 + .word 0xa3014314 + .word 0x4e0811a1 + .word 0xf7537e82 + .word 0xbd3af235 + .word 0x2ad7d2bb + .word 0xeb86d391 diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_sha1_functions.s b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_sha1_functions.s new file mode 100755 index 0000000..82d756d --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_sha1_functions.s @@ -0,0 +1,1355 @@ +#******************************************************************************* +#******************************************************************************* +# +# Copyright (c) Freescale Semiconductor, Inc 2011. +# +# FILE NAME : mmcau_sha1_functions.s +# VERSION : $Id: mmcau_sha1_functions.s.rca 1.5 Thu Nov 21 14:17:37 2013 b40907 Experimental $ +# TYPE : Source Cortex-Mx assembly library code +# DEPARTMENT : MSG R&D Core and Platforms +# AUTHOR : David Schimke +# AUTHOR'S EMAIL : David.Schimke@freescale.com +# ----------------------------------------------------------------------------- +# Release history +# VERSION Date AUTHOR DESCRIPTION +# 08-2010 David Schimke Initial Release +# 12-2010 David Schimke Remove "global" on data objects +# 01-2011 David Schimke Header added +# 11-2013 Teejay Ciancio Cleanup +# +#******************************************************************************* +#******************************************************************************* + + .include "cau2_defines.hdr" + .equ MMCAU_PPB_DIRECT,0xe0081000 + .equ MMCAU_PPB_INDIRECT,0xe0081800 + .equ MMCAU_1_CMD, 0x80000000 + .equ MMCAU_2_CMDS, 0x80100000 + + .syntax unified + +#******************************************************************************* +#******************************************************************************* +# +# SHA1: Initializes the SHA1 state variables +# arguments +# *sha1_state pointer to 160-bit block of SHA1 state variables: +# a,b,c,d,e +# +# calling convention +# void mmcau_sha1_initialize_output (const unsigned int *sha1_state) + + .global _mmcau_sha1_initialize_output + .global mmcau_sha1_initialize_output + .type mmcau_sha1_initialize_output, %function + .align 4 + +_mmcau_sha1_initialize_output: +mmcau_sha1_initialize_output: + + stmdb sp!, {r4-r5} @ save registers + + movw r1, #:lower16:sha1_initial_h @ r1 -> initial data + movt r1, #:upper16:sha1_initial_h + +# copy initial data into hash output buffer + ldmia r1, {r1-r5} @ get sha1[0-4] + stmia r0, {r1-r5} @ copy to sha1_state[0-4] + + ldmia sp!, {r4-r5} @ restore registers + bx lr + + +#******************************************************************************* +#******************************************************************************* +# +# SHA1: Perform the hash and generate SHA1 state variables for one or more +# input message blocks +# +# arguments +# *msg_data pointer to start of input message data +# num_blks number of 512-bit blocks to process +# *sha1_state pointer to 160-bit block of SHA1 state variables: +# a,b,c,d,e +# +# NOTE Input message and digest output blocks must not overlap +# +# calling convention +# void mmcau_sha1_hash_n (const unsigned char *msg_data, +# const int num_blks, +# unsigned int *sha1_state) + + .global _mmcau_sha1_hash_n + .global mmcau_sha1_hash_n + .type mmcau_sha1_hash_n, %function + .align 4 + +_mmcau_sha1_hash_n: +mmcau_sha1_hash_n: + +# register allocation +# -------------------- +# r0 = scratch / input pointer (arg0) +# r1 = scratch / input num_blks (arg1) +# r2 = scratch / output pointer (arg2) +# r3 = scratch +# r4 = scratch +# r5 = scratch / mmcau_1_cmd(SHS) +# r6 = scratch / mmcau_2_cmds(HASH+HFC,ADRA+CA4) +# r7 = scratch +# r8 = scratch / mmcau_2_cmds(HASH+HFP,ADRA+CA4) +# r9 = scratch / mmcau_2_cmds(HASH+HFM,ADRA+CA4) +# r10 (sl) = scratch / pointer to sha1_k +# r11 (fp) = pointer to MMCAU_PPB_DIRECT + + stmdb sp!, {r4-fp} @ save registers on stack + + sub sp, $384 @ reserve stack space + + movw fp, #:lower16:MMCAU_PPB_DIRECT @ fp -> MMCAU_PPB_DIRECT + movt fp, #:upper16:MMCAU_PPB_DIRECT + + add r8, fp, $0x800+((LDR+CA0)<<2) @ r8 = INDIRECT (LDR+CA0) + add r9, sp, $28 @ r9 -> sha1_state (stack) + +# initialize the CAU data registers with the current contents of sha1_state[] + ldmia r2, {r3-r7} @ get sha1_state[0-4] + stmia r8, {r3-r7} @ load CA0-CA4 + + .align 2 +next_blk: + stmia r9, {r3-r7} @ copy sha1_state to stack + + ror r5, r3, $27 @ rotate CA0 by 5 + str r5, [fp, $0x800+((LDR+CAA)<<2)] @ load into CAA + + movw r5, #:lower16:MMCAU_1_CMD+(SHS)<<22 + movw r6, #:lower16:MMCAU_2_CMDS+(HASH+HFC)<<22+(ADRA+CA4)<<11 + movw sl, #:lower16:sha1_k + movt r5, #:upper16:MMCAU_1_CMD+(SHS)<<22 + movt r6, #:upper16:MMCAU_2_CMDS+(HASH+HFC)<<22+(ADRA+CA4)<<11 + movt sl, #:upper16:sha1_k + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# for (j = 0; j < 16; j++, k++) +# { +# w[i] = byterev(msg_data[k]); // m[k] -> w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(HASH+HFC,ADRA+CA4); // +Ch(b,c,d),+e +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha1_k[0]; // add k[0] +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = w[i++]; // add w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_1_cmd(SHS); // shift regs +# } +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +# -- (loop unrolled) + + ldr r7, [sl], $4 @ get k[0]; sl++ + + ldr r3, [r0], $4 @ r3 = input[0] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $64] @ w[0] = m[0] + add r4, r7 @ add k[0] to w[0] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[1] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $68] @ w[1] = m[1] + add r4, r7 @ add k[0] to w[1] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[2] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $72] @ w[2] = m[2] + add r4, r7 @ add k[0] to w[2] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[3] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $76] @ w[3] = m[3] + add r4, r7 @ add k[0] to w[3] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[4] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $80] @ w[4] = m[4] + add r4, r7 @ add k[0] to w[4] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[5] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $84] @ w[5] = m[5] + add r4, r7 @ add k[0] to w[5] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[6] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $88] @ w[6] = m[6] + add r4, r7 @ add k[0] to w[6] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[7] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $92] @ w[7] = m[7] + add r4, r7 @ add k[0] to w[7] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[8] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $96] @ w[8] = m[8] + add r4, r7 @ add k[0] to w[8] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[9] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $100] @ w[9] = m[9] + add r4, r7 @ add k[0] to w[9] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[10] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $104] @ w[10] = m[10] + add r4, r7 @ add k[0] to w[10] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[11] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $108] @ w[11] = m[11] + add r4, r7 @ add k[0] to w[11] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[12] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $112] @ w[12] = m[12] + add r4, r7 @ add k[0] to w[12] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[13] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $116] @ w[13] = m[13] + add r4, r7 @ add k[0] to w[13] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[14] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $120] @ w[14] = m[14] + add r4, r7 @ add k[0] to w[14] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + + ldr r3, [r0], $4 @ r3 = input[15] + rev r4, r3 @ byte reverse + str r6, [fp] @ +Ch(b,c,d), +e + str r4, [sp, $124] @ w[15] = m[15] + add r4, r7 @ add k[0] to w[15] + str r4, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift registers + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# for (j = 0; j < 4; j++) +# { +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(HASH+HFC,ADRA+CA4); // +Ch(b,c,d), +e +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha1_k[0]; // +k[0] +# *(MMCAU_PPB_INDIRECT + (LDR+CA5)) = w[i-16]; // ld w[i-16] -> CA5 +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-14]; // xor w[i-14] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-8]; // xor w[i-8] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-3]; // xor w[i-3] +# *(MMCAU_PPB_INDIRECT + (ROTL+CA5)) = 1; // rotate by 1 +# w[i++] = *(MMCAU_PPB_INDIRECT + (STR+CA5)); // store w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(ADRA+CA5,SHS); // +w[i], shift regs +# } +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +# -- (loop unrolled) + + str r6, [fp] @ +Ch(b,c,d), +e + ldr r4, [sp, $64] @ r4 = w[0] + ldr r3, [sp, $72] @ r3 = w[2] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $96] @ r3 = w[8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $116] @ r3 = w[13] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $128] @ store w[16] + add r3, r7 @ add k[0] to w[16] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r6, [fp] @ +Ch(b,c,d), +e + ldr r4, [sp, $68] @ r4 = w[1] + ldr r3, [sp, $76] @ r3 = w[3] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $100] @ r3 = w[9] + eor r4, r3 @ XOR w[i-9] + ldr r3, [sp, $120] @ r3 = w[14] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $132] @ store w[17] + add r3, r7 @ add k[0] to w[17] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r6, [fp] @ +Ch(b,c,d), +e + ldr r4, [sp, $72] @ r4 = w[2] + ldr r3, [sp, $80] @ r3 = w[4] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $104] @ r4 = w[10] + eor r4, r3 @ XOR w[i-9] + ldr r3, [sp, $124] @ r3 = w[15] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $136] @ store w[18] + add r3, r7 @ add k[0] to w[18] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r6, [fp] @ +Ch(b,c,d), +e + ldr r4, [sp, $76] @ r4 = w[3] + ldr r3, [sp, $84] @ r3 = w[5] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $108] @ r4 = w[11] + eor r4, r3 @ XOR w[i-9] + ldr r3, [sp, $128] @ r3 = w[16] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $140] @ store w[19] + add r3, r7 @ add k[0] to w[19] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# for (j = 0; j < 20; j++) +# { +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(HASH+HFP,ADRA+CA4); // +Par(b,c,d), +e +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha1_k[1]; // +k[1] +# *(MMCAU_PPB_INDIRECT + (LDR+CA5)) = w[i-16]; // ld w[i-16] -> CA5 +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-14]; // xor w[i-14] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-8]; // xor w[i-8] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-3]; // xor w[i-3] +# *(MMCAU_PPB_INDIRECT + (ROTL+CA5)) = 1; // rotate by 1 +# w[i++] = *(MMCAU_PPB_INDIRECT + (STR+CA5)); // store w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(ADRA+CA5,SHS); // +w[i], shift regs +# } +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + movw r8, #:lower16:MMCAU_2_CMDS+(HASH+HFP)<<22+(ADRA+CA4)<<11 + movt r8, #:upper16:MMCAU_2_CMDS+(HASH+HFP)<<22+(ADRA+CA4)<<11 + ldr r7, [sl], $4 @ get k[1]; sl++ + +# -- (loop unrolled) + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $80] @ r4 = w[i-16] + ldr r3, [sp, $88] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $112] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $132] @ r4 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $144] @ store w[20] + add r3, r7 @ add k[1] to w[20] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $84] @ r4 = w[i-16] + ldr r3, [sp, $92] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $116] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $136] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $148] @ store w[21] + add r3, r7 @ add k[1] to w[21] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $88] @ r4 = w[i-16] + ldr r3, [sp, $96] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $120] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $140] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $152] @ store w[22] + add r3, r7 @ add k[1] to w[22] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $92] @ r4 = w[i-16] + ldr r3, [sp, $100] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $124] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $144] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $156] @ store w[23] + add r3, r7 @ add k[1] to w[23] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $96] @ r4 = w[i-16] + ldr r3, [sp, $104] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $128] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $148] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $160] @ store w[24] + add r3, r7 @ add k[1] to w[24] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $100] @ r4 = w[i-16] + ldr r3, [sp, $108] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $132] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $152] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $164] @ store w[25] + add r3, r7 @ add k[1] to w[25] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $104] @ r4 = w[i-16] + ldr r3, [sp, $112] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $136] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $156] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $168] @ store w[26] + add r3, r7 @ add k[1] to w[26] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $108] @ r4 = w[i-16] + ldr r3, [sp, $116] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $140] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $160] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $172] @ store w[27] + add r3, r7 @ add k[1] to w[27] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $112] @ r4 = w[i-16] + ldr r3, [sp, $120] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $144] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $164] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $176] @ store w[28] + add r3, r7 @ add k[1] to w[28] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $116] @ r4 = w[i-16] + ldr r3, [sp, $124] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $148] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $168] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $180] @ store w[29] + add r3, r7 @ add k[1] to w[29] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $120] @ r4 = w[i-16] + ldr r3, [sp, $128] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $152] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $172] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $184] @ store w[30] + add r3, r7 @ add k[1] to w[30] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $124] @ r4 = w[i-16] + ldr r3, [sp, $132] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $156] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $176] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $188] @ store w[31] + add r3, r7 @ add k[1] to w[31] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $128] @ r4 = w[i-16] + ldr r3, [sp, $136] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $160] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $180] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $192] @ store w[32] + add r3, r7 @ add k[1] to w[32] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $132] @ r4 = w[i-16] + ldr r3, [sp, $140] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $164] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $184] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $196] @ store w[33] + add r3, r7 @ add k[1] to w[33] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $136] @ r4 = w[i-16] + ldr r3, [sp, $144] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $168] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $188] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $200] @ store w[34] + add r3, r7 @ add k[1] to w[34] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $140] @ r4 = w[i-16] + ldr r3, [sp, $148] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $172] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $192] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $204] @ store w[35] + add r3, r7 @ add k[1] to w[35] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $144] @ r4 = w[i-16] + ldr r3, [sp, $152] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $176] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $196] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $208] @ store w[36] + add r3, r7 @ add k[1] to w[36] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $148] @ r4 = w[i-16] + ldr r3, [sp, $156] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $180] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $200] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $212] @ store w[37] + add r3, r7 @ add k[1] to w[37] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $152] @ r4 = w[i-16] + ldr r3, [sp, $160] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $184] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $204] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $216] @ store w[38] + add r3, r7 @ add k[1] to w[38] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $156] @ r4 = w[i-16] + ldr r3, [sp, $164] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $188] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $208] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $220] @ store w[39] + add r3, r7 @ add k[1] to w[39] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# for (j = 0; j < 20; j++) +# { +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(HASH+HFM,ADRA+CA4); // +Maj(b,c,d), +e +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha1_k[2]; // +k[2] +# *(MMCAU_PPB_INDIRECT + (LDR+CA5)) = w[i-16]; // ld w[i-16] -> CA5 +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-14]; // xor w[i-14] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-8]; // xor w[i-8] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-3]; // xor w[i-3] +# *(MMCAU_PPB_INDIRECT + (ROTL+CA5)) = 1; // rotate by 1 +# w[i++] = *(MMCAU_PPB_INDIRECT + (STR+CA5)); // store w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(ADRA+CA5,SHS); // +w[i], shift regs +# } +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + movw r9, #:lower16:MMCAU_2_CMDS+(HASH+HFM)<<22+(ADRA+CA4)<<11 + movt r9, #:upper16:MMCAU_2_CMDS+(HASH+HFM)<<22+(ADRA+CA4)<<11 + ldr r7, [sl], $4 @ get k[2]; sl++ + +# -- (loop unrolled) + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $160] @ r4 = w[i-16] + ldr r3, [sp, $168] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $192] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $212] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $224] @ store w[40] + add r3, r7 @ add k[2] to w[40] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $164] @ r4 = w[i-16] + ldr r3, [sp, $172] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $196] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $216] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $228] @ store w[41] + add r3, r7 @ add k[2] to w[41] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $168] @ r4 = w[i-16] + ldr r3, [sp, $176] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $200] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $220] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $232] @ store w[42] + add r3, r7 @ add k[2] to w[42] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $172] @ r4 = w[i-16] + ldr r3, [sp, $180] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $204] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $224] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $236] @ store w[43] + add r3, r7 @ add k[2] to w[43] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $176] @ r4 = w[i-16] + ldr r3, [sp, $184] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $208] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $228] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $240] @ store w[44] + add r3, r7 @ add k[2] to w[44] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $180] @ r4 = w[i-16] + ldr r3, [sp, $188] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $212] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $232] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $244] @ store w[45] + add r3, r7 @ add k[2] to w[45] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $184] @ r4 = w[i-16] + ldr r3, [sp, $192] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $216] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $236] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $248] @ store w[46] + add r3, r7 @ add k[2] to w[46] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $188] @ r4 = w[i-16] + ldr r3, [sp, $196] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $220] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $240] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $252] @ store w[47] + add r3, r7 @ add k[2] to w[47] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $192] @ r4 = w[i-16] + ldr r3, [sp, $200] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $224] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $244] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $256] @ store w[48] + add r3, r7 @ add k[2] to w[48] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $196] @ r4 = w[i-16] + ldr r3, [sp, $204] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $228] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $248] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $260] @ store w[49] + add r3, r7 @ add k[2] to w[49] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $200] @ r4 = w[i-16] + ldr r3, [sp, $208] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $232] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $252] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $264] @ store w[50] + add r3, r7 @ add k[2] to w[50] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add w[50] to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $204] @ r4 = w[i-16] + ldr r3, [sp, $212] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $236] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $256] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $268] @ store w[51] + add r3, r7 @ add k[2] to w[51] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $208] @ r4 = w[i-16] + ldr r3, [sp, $216] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $240] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $260] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $272] @ store w[52] + add r3, r7 @ add k[2] to w[52] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $212] @ r4 = w[i-16] + ldr r3, [sp, $220] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $244] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $264] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $276] @ store w[53] + add r3, r7 @ add k[2] to w[53] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $216] @ r4 = w[i-16] + ldr r3, [sp, $224] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $248] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $268] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $280] @ store w[54] + add r3, r7 @ add k[2] to w[54] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $220] @ r4 = w[i-16] + ldr r3, [sp, $228] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $252] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $272] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $284] @ store w[55] + add r3, r7 @ add k[2] to w[55] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $224] @ r4 = w[i-16] + ldr r3, [sp, $232] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $256] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $276] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $288] @ store w[56] + add r3, r7 @ add k[2] to w[56] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $228] @ r4 = w[i-16] + ldr r3, [sp, $236] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $260] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $280] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $292] @ store w[57] + add r3, r7 @ add k[2] to w[57] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $232] @ r4 = w[i-16] + ldr r3, [sp, $240] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $264] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $284] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $296] @ store w[58] + add r3, r7 @ add k[2] to w[58] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r9, [fp] @ +Maj(b,c,d), +e + ldr r4, [sp, $236] @ r4 = w[i-16] + ldr r3, [sp, $244] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $268] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $288] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $300] @ store w[59] + add r3, r7 @ add k[2] to w[59] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# for (j = 0; j < 20; j++) +# { +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(HASH+HFP,ADRA+CA4); // +Par(b,c,d), +e +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha1_k[3]; // +k[3] +# *(MMCAU_PPB_INDIRECT + (LDR+CA5)) = w[i-16]; // ld w[i-16] -> CA5 +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-14]; // xor w[i-14] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-8]; // xor w[i-8] +# *(MMCAU_PPB_INDIRECT + (XOR+CA5)) = w[i-3]; // xor w[i-3] +# *(MMCAU_PPB_INDIRECT + (ROTL+CA5)) = 1; // rotate by 1 +# w[i++] = *(MMCAU_PPB_INDIRECT + (STR+CA5)); // store w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(ADRA+CA5,SHS); // +w[i], shift regs +# } +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + ldr r7, [sl] @ get k[3] + +# -- (loop unrolled) + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $240] @ r4 = w[i-16] + ldr r3, [sp, $248] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $272] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $292] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $304] @ store w[60] + add r3, r7 @ add k[3] to w[60] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $244] @ r4 = w[i-16] + ldr r3, [sp, $252] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $276] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $296] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $308] @ store w[61] + add r3, r7 @ add k[3] to w[61] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $248] @ r4 = w[i-16] + ldr r3, [sp, $256] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $280] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $300] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $312] @ store w[62] + add r3, r7 @ add k[3] to w[62] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $252] @ r4 = w[i-16] + ldr r3, [sp, $260] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $284] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $304] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $316] @ store w[63] + add r3, r7 @ add k[3] to w[63] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $256] @ r4 = w[i-16] + ldr r3, [sp, $264] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $288] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $308] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $320] @ store w[64] + add r3, r7 @ add k[3] to w[64] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $260] @ r4 = w[i-16] + ldr r3, [sp, $268] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $292] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $312] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $324] @ store w[65] + add r3, r7 @ add k[3] to w[65] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $264] @ r4 = w[i-16] + ldr r3, [sp, $272] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $296] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $316] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $328] @ store w[66] + add r3, r7 @ add k[3] to w[66] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $268] @ r4 = w[i-16] + ldr r3, [sp, $276] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $300] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $320] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $332] @ store w[67] + add r3, r7 @ add k[3] to w[67] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $272] @ r4 = w[i-16] + ldr r3, [sp, $280] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $304] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $324] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $336] @ store w[68] + add r3, r7 @ add k[3] to w[68] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $276] @ r4 = w[i-16] + ldr r3, [sp, $284] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $308] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $328] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $340] @ store w[69] + add r3, r7 @ add k[3] to w[69] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $280] @ r4 = w[i-16] + ldr r3, [sp, $288] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $312] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $332] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $344] @ store w[70] + add r3, r7 @ add k[3] to w[70] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $284] @ r4 = w[i-16] + ldr r3, [sp, $292] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $316] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $336] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $348] @ store w[71] + add r3, r7 @ add k[3] to w[71] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $288] @ r4 = w[i-16] + ldr r3, [sp, $296] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $320] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $340] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $352] @ store w[72] + add r3, r7 @ add k[3] to w[72] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $292] @ r4 = w[i-16] + ldr r3, [sp, $300] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $324] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $344] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $356] @ store w[73] + add r3, r7 @ add k[3] to w[73] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $296] @ r4 = w[i-16] + ldr r3, [sp, $304] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $328] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $348] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $360] @ store w[74] + add r3, r7 @ add k[3] to w[74] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $300] @ r4 = w[i-16] + ldr r3, [sp, $308] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $332] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $352] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $364] @ store w[75] + add r3, r7 @ add k[3] to w[75] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $304] @ r4 = w[i-16] + ldr r3, [sp, $312] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $336] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $356] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $368] @ store w[76] + add r3, r7 @ add k[3] to w[76] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $308] @ r4 = w[i-16] + ldr r3, [sp, $316] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $340] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $360] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $372] @ store w[77] + add r3, r7 @ add k[3] to w[77] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $312] @ r4 = w[i-16] + ldr r3, [sp, $320] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $344] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $364] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $376] @ store w[78] + add r3, r7 @ add k[3] to w[78] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + str r8, [fp] @ +Par(b,c,d), +e + ldr r4, [sp, $316] @ r4 = w[i-16] + ldr r3, [sp, $324] @ r3 = w[i-14] + eor r4, r3 @ XOR w[i-14] + ldr r3, [sp, $348] @ r3 = w[i-8] + eor r4, r3 @ XOR w[i-8] + ldr r3, [sp, $368] @ r3 = w[i-3] + eor r4, r3 @ XOR w[i-3] + ror r3, r4, $31 @ rotate left by 1 + str r3, [sp, $380] @ store w[79] + add r3, r7 @ add k[3] to w[79] + str r3, [fp, $0x800+((ADR+CAA)<<2)] @ add sum to CAA + str r5, [fp] @ shift regs + + add r9, sp, $28 @ r9 -> output[0] on stack + add r8, fp, $0x800+((ADR+CA0)<<2) @ r8 = indirect_cmd ADR+CA0 + add sl, fp, $0x800+((STR+CA0)<<2) @ sl = indirect_cmd STR+CA0 + + ldmia r9, {r3-r7} @ get current outputs + stmia r8, {r3-r7} @ add output[i] to CA[4:0] + ldmia sl, {r3-r7} @ get CA[4:0] + + subs r1, $1 @ decrement num_blks + bne next_blk + + add sp, $384 @ unreserve stack space + stmia r2, {r3-r7} @ store CA[i] to output[i] + ldmia sp!, {r4-fp} @ restore regs and return + bx lr + +#******************************************************************************* +#******************************************************************************* +# +# SHA1: Updates SHA1 state variables for one or more input message blocks +# arguments +# *msg_data pointer to start of input message data +# num_blks number of 512-bit blocks to process +# *sha1_state pointer to 160-bit block of SHA1 state variables: +# a,b,c,d,e +# +# calling convention +# void mmcau_sha1_update (const unsigned char *msg_data, +# const int num_blks, +# unsigned int *sha1_state) + + + .global _mmcau_sha1_update + .global mmcau_sha1_update + .type mmcau_sha1_update, %function + .align 4 + +_mmcau_sha1_update: +mmcau_sha1_update: + + stmdb sp!, {r3-r7, lr} @ save registers on stack + + movw r3, #:lower16:sha1_initial_h @ r3 -> initial data + movt r3, #:upper16:sha1_initial_h + +# copy initial data into hash output buffer + ldmia r3, {r3-r7} @ get initial sha1[0-4] + stmia r2, {r3-r7} @ copy to sha1_state[0-4] + + bl mmcau_sha1_hash_n @ call hash_n routine + + ldmia sp!, {r3-r7, pc} @ restore regs and return + +#******************************************************************************* +#******************************************************************************* +# +# SHA1: Perform the hash and generate SHA1 state variables for one input +# message block. +# +# arguments +# *msg_data pointer to start of input message data +# *sha1_state pointer to 160-bit block of SHA1 state variables: +# a,b,c,d,e +# +# NOTE Input message and digest output blocks must not overlap +# +# calling convention +# void mmcau_sha1_hash (const unsigned char *msg_data, +# unsigned int *sha1_state) + + .global _mmcau_sha1_hash + .global mmcau_sha1_hash + .type mmcau_sha1_hash, %function + .align 4 + +_mmcau_sha1_hash: +mmcau_sha1_hash: + + mov r2, r1 @ arg2 = arg1 (*sha1_state) + mov r1, $1 @ arg1 = num_blks = 1 + b mmcau_sha1_hash_n @ branch to hash_n routine + +#******************************************************************************* + + .data + .type sha1_initial_h, %object + .align 4 + +sha1_initial_h: + .word 0x67452301 + .word 0xefcdab89 + .word 0x98badcfe + .word 0x10325476 + .word 0xc3d2e1f0 + + .type sha1_k, %object + .align 4 + +sha1_k: + .word 0x5a827999 + .word 0x6ed9eba1 + .word 0x8f1bbcdc + .word 0xca62c1d6 diff --git a/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_sha256_functions.s b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_sha256_functions.s new file mode 100755 index 0000000..c0a7fe3 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mmcau/asm-cm4/src/mmcau_sha256_functions.s @@ -0,0 +1,535 @@ +#******************************************************************************* +#******************************************************************************* +# +# Copyright (c) Freescale Semiconductor, Inc 2011. +# +# FILE NAME : mmcau_sha256_functions.s +# VERSION : $Id: mmcau_sha256_functions.s.rca 1.6 Thu Nov 21 14:18:00 2013 b40907 Experimental $ +# TYPE : Source Cortex-Mx assembly library code +# DEPARTMENT : MSG R&D Core and Platforms +# AUTHOR : David Schimke +# AUTHOR'S EMAIL : David.Schimke@freescale.com +# ----------------------------------------------------------------------------- +# Release history +# VERSION Date AUTHOR DESCRIPTION +# 08-2010 David Schimke Initial Release +# 12-2010 David Schimke Remove "global" on data objects +# 01-2011 David Schimke Header added +# 11-2013 Teejay Ciancio Cleanup +# +#******************************************************************************* +#******************************************************************************* + + .include "cau2_defines.hdr" + .equ MMCAU_PPB_DIRECT,0xe0081000 + .equ MMCAU_PPB_INDIRECT,0xe0081800 + .equ MMCAU_1_CMD,0x80000000 + .equ MMCAU_3_CMDS,0x80100200 + + .syntax unified + +#******************************************************************************* +#******************************************************************************* +# +# SHA256: Initializes the hash output and checks the CAU hardware revision +# arguments +# *output pointer to 256-bit message digest output +# +# calling convention +# int mmcau_sha256_initialize_output (const unsigned int *output) + + .global _mmcau_sha256_initialize_output + .global mmcau_sha256_initialize_output + .type mmcau_sha256_initialize_output, %function + .align 4 + +_mmcau_sha256_initialize_output: +mmcau_sha256_initialize_output: + + stmdb sp!, {r4-r8} @ save registers + + movw r1, #:lower16:sha256_initial_h @ r1 -> initial data + movt r1, #:upper16:sha256_initial_h + +# copy initial data into message digest output buffer + ldmia r1, {r1-r8} @ get sha256_initial[0-7] + stmia r0, {r1-r8} @ copy to output[0-7] + + ldmia sp!, {r4-r8} @ restore registers + mov r0, $0 @ clear return value in r0 + bx lr + +#******************************************************************************* +#******************************************************************************* +# +# SHA256: Perform the hash for one or more input message blocks and generate the +# message digest output +# +# arguments +# *msg_data pointer to start of input message data +# num_blks number of 512-bit blocks to process +# *sha256_state pointer to 256-bit message digest. +# +# NOTE Input message and digest output blocks must not overlap +# +# calling convention +# void mmcau_sha256_hash_n (const unsigned char *msg_data, +# const int num_blks, +# unsigned int *sha256_state) + .global _mmcau_sha256_hash_n + .global mmcau_sha256_hash_n + .type mmcau_sha256_hash_n, %function + .align 4 + +_mmcau_sha256_hash_n: +mmcau_sha256_hash_n: + +# register allocation +# -------------------- +# r0 = scratch / input pointer (arg0) +# r1 = scratch / input num_blks (arg1) +# r2 = scratch / output pointer (arg2) +# r3 = scratch +# r4 = scratch +# r5 = scratch / mmcau_1_cmd(HASH+HF2U) +# r6 = scratch / mmcau_1_cmd(HASH+HF2V) +# r7 = scratch / mmcau_1_cmd(SHS2) +# r8 = scratch / mmcau_3_cmds(MVAR+CA8,HASH+HF2S,HASH+HF2M) +# r9 = scratch / mmcau_3_cmds(ADRA+CA7,HASH+HF2T,HASH+HF2C) +# r10 (sl) = scratch / pointer to sha256_k +# r11 (fp) = scratch / loop counter +# r12 (ip) = pointer to MMCAU_PPB_DIRECT +# r14 (lr) = link reg / indirect_cmd(ADR+CA0) + + stmdb sp!, {r4-ip} @ save registers on stack + + movw ip, #:lower16:MMCAU_PPB_DIRECT @ ip -> MMCAU_PPB_DIRECT + movt ip, #:upper16:MMCAU_PPB_DIRECT + + sub sp, $320 @ reserve stack space + str r2, [sp, $20] @ save r2 on stack + mov fp, r1 @ fp = num_blks + +# initialize the CAU data registers with the current contents of output[] + ldmia r2, {r1-r8} @ get output[0-7] + + add r9, ip, $0x800+(LDR+CA0)<<2 @ r9 -> mmcau_1_cmd(LDR+CA0) + stmia r9, {r1-r8} @ load CA0-CA7 + +# prepare for SHA256 operations register load + movw sl, #:lower16:sha256_reg_data + movt sl, #:upper16:sha256_reg_data + str sl, [sp, $8] @ save sl on stack + + add r9, sp, $28 @ r9 -> stack copy of output + + .align 2 +next_blk: + + stmia r9, {r1-r8} @ save output on stack + +# load registers needed for mmcau commands from sha256_reg_data: + ldr sl, [sp, $8] @ sl -> sha256_reg_data + ldmia sl, {r5-sl} @ setup sha256 operations + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# i = 0; +# for (j = 0; j < 16; j++, i++) +# { +# w[i] = byterev(input[i]); // copy m[i] to w[i] +# *(MMCAU_PPB_INDIRECT + (LDR+CAA)) = w[i]; // +w[i]+h+SIGMA1(e) +# // add Ch(e,f,g) +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(ADRA+CA7,HASH+HF2T,HASH+HF2C); +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha256_k[i]; // +k[i]+t1+SIGMA0(e) +# // add Maj(a,b,c) +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(MVAR+CA8,HASH+HF2S,HASH+HF2M); +# *(MMCAU_PPB_DIRECT) = mmcau_1_cmd(SHS2); // shift registers +# } +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + +# -- input 0 + + ldr r2, [r0], $4 @ r2 = input[0]; r0++ + rev r1, r2 @ byte reverse + str r1, [sp, $64] @ w[0] (on stack) = m[0] + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[i] + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + ldr r3, [sl], $4 @ get k[1]; sl++ + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[1] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + +# -- repeat for inputs 1 to 15 -- (loop unrolled) + + ldr r2, [r0], $4 @ r2 = input[1]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[1]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[1] + str r1, [sp, $68] @ w[1] (on stack) = m[1] + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[1] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[2]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[2]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[2] + str r1, [sp, $72] @ m[2] -> w[2] (on stack) + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[2] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[3]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[3]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[3] + str r1, [sp, $76] @ m[3] -> w[3] (on stack) + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[3] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[4]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[4]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[4] + str r1, [sp, $80] @ m[4] -> w[4] (on stack) + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[4] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[5]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[5]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[5] + str r1, [sp, $84] @ m[5] -> w[5] (on stack) + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[5] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[6]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[6]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[6] + str r1, [sp, $88] @ m[6] -> w[6] (on stack) + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[6] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[7]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[7]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[7] + str r1, [sp, $92] @ m[7] -> w[7] (on stack) + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[7] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[8]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[8]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[8] + str r1, [sp, $96] @ m[8] -> w[8] (on stack) + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[8] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[9]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[9]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[9] + str r1, [sp, $100] @ m[9] -> w[9] (on stack) + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[9] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[10]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[10]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[10] + str r1, [sp, $104] @ m[10] -> w[10] (on stack + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[10] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[11]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[11]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[11] + str r1, [sp, $108] @ m[11] -> w[11] (on stack + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[11] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[12]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[12]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[12] + str r1, [sp, $112] @ m[12] -> w[12] (on stack + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[12] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[13]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[13]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[13] + str r1, [sp, $116] @ m[13] -> w[13] (on stack) + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[13] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[14]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[14]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[14] + str r1, [sp, $120] @ m[14] -> w[14] (on stack) + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[14] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + ldr r2, [r0], $4 @ r2 = input[15]; r0++ + rev r1, r2 @ byte reverse + ldr r3, [sl], $4 @ get k[15]; sl++ + str r1, [ip, $0x800+(LDR+CAA)<<2] @ add w[15] + str r1, [sp, $124] @ m[15] -> w[15] (on stack) + str r9, [ip] @ +h,+SIGMA1(e),+Ch(e,f,g) + str r3, [ip, $0x800+(ADR+CAA)<<2] @ add k[15] + str r8, [ip] @ t1,+SIGMA0(e),+Maj(a,b,c) + str r7, [ip] @ shift registers + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# for (j = 0; j < 48; j++, i++) +# { +# *(MMCAU_PPB_INDIRECT + (LDR+CAA)) = w[i-16]; // [i-16] +# *(MMCAU_PPB_INDIRECT + (LDR+CA8)) = w[i-15]; // [i-15] +# *(MMCAU_PPB_DIRECT) = mmcau_1_cmd(HASH+HF2U); // + Sigma2(w[i-15]) +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = w[i-7]; // add w[i-7] +# *(MMCAU_PPB_INDIRECT + (LDR+CA8)) = w[i-2]; // load w[i-2] +# *(MMCAU_PPB_DIRECT) = mmcau_1_cmd(HASH+HF2V); // + Sigma1(w[i-2]) +# w[i] = *(MMCAU_PPB_INDIRECT + (STR+CAA)); // store w[i] +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(ADRA+CA7,HASH+HF2T,HASH+HF2C); +# *(MMCAU_PPB_INDIRECT + (ADR+CAA)) = sha256_k[i]; // add k[i] +# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(MVAR+CA8,HASH+HF2S,HASH+HF2M); +# *(MMCAU_PPB_DIRECT) = mmcau_1_cmd(SHS2); // shift registers +# } +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + mov r2, $48 @ loop end + add r3, sp, $128 @ r3 -> w[16] + + .align 2 +loop: + ldr r1, [r3, $(-16<<2)] @ get w[i-16] off stack + str r1, [ip, $0x800+(LDR+CAA)<<2] @ CAA = w[i-16] + ldr r1, [r3, $(-15<<2)] @ get w[i-15] off stack + str r1, [ip, $0x800+(LDR+CA8)<<2] @ CA8 = w[i-15] + str r5, [ip] @ (HASH+HF2U) + ldr r1, [r3, $(-7<<2)] @ get w[i-7] off stack + str r1, [ip, $0x800+(ADR+CAA)<<2] @ CAA += w[i-7] + ldr r1, [r3, $(-2<<2)] @ get w[i-2] off stack + str r1, [ip, $0x800+(LDR+CA8)<<2] @ CA8 = w[i-2] + str r6, [ip] @ (HASH+HF2V) + ldr r1, [ip, $0x800+(STR+CAA)<<2] @ r1 = w[i] [STR+CAA] + str r1, [r3], $4 @ store w[i] on stack; r3++ + str r9, [ip] @ +h, SIGMA1(e) & Ch(e,f,g) + ldr r1, [sl], $4 @ get k[i]; sl++ + str r1, [ip, $0x800+(ADR+CAA)<<2] @ add k[i] + str r8, [ip] @ t1, +SIGMA0(e) +Maj(a,b,c) + str r7, [ip] @ shift registers + subs r2, $1 @ decrement loop count + bne.n loop + + add r9, sp, $28 @ r9 = output[0] on stack + add sl, ip, $0x800+(ADR+CA0)<<2 @ r8 = indirect_cmd(ADR+CA0) + ldmia r9, {r1-r8} @ get current outputs + stmia sl, {r1-r8} @ add output[i] to CA[i] + add sl, ip, $0x800+(STR+CA0)<<2 @ sl = indirect_cmd(STR+CA0) + ldmia sl, {r1-r8} @ get new CA[i]; i = 0-7 + + subs fp, $1 @ decrement num_blks + bne next_blk + + ldr r9, [sp, $20] @ get saved output pointer + add sp, $320 @ restore stack + stmia r9, {r1-r8} @ store CA[i] to output[i] + ldmia sp!, {r4-ip} @ restore regs and return + bx lr + +#******************************************************************************* +#******************************************************************************* +# +# SHA256: Updates SHA256 state variables for one or more input message blocks +# +# arguments: +# *msg_data pointer to start of input message data +# num_blks number of 512-bit blocks to process +# *sha256_state pointer to 256-bit message digest. +# +# calling convention +# void mmcau_sha256_update (const unsigned char *msg_data, +# const int num_blks, +# unsigned int *sha256_state) + + + .global _mmcau_sha256_update + .global mmcau_sha256_update + .type mmcau_sha256_update, %function + .align 4 + +_mmcau_sha256_update: +mmcau_sha256_update: + + stmdb sp!, {r4-fp, lr} @ save registers on stack + + movw r4, #:lower16:sha256_initial_h @ r4 -> initial data + movt r4, #:upper16:sha256_initial_h + +# copy initial data into hash output buffer + ldmia r4, {r4-fp} @ get sha256[0-7] + stmia r2, {r4-fp} @ copy to sha256_state[0-7] + + bl mmcau_sha256_hash_n @ call hash_n routine + + ldmia sp!, {r4-fp,pc} @ restore regs and return + + +#******************************************************************************* +#******************************************************************************* +# +# SHA256: Perform the hash and generate SHA256 state variables for one input +# message block. +# +# arguments +# *msg_data pointer to start of input message data +# *sha256_state pointer to 256-bit message digest. +# +# NOTE Input message and digest output blocks must not overlap +# +# calling convention +# void mmcau_sha256_hash (const unsigned char *msg_data, +# unsigned int *sha256_state) + + .global _mmcau_sha256_hash + .global mmcau_sha256_hash + .type mmcau_sha256_hash, %function + .align 4 + +_mmcau_sha256_hash: +mmcau_sha256_hash: + + mov r2, r1 @ move arg1 to arg2 + mov r1, $1 @ set arg1 = 1 + b mmcau_sha256_hash_n @ use hash_n w/num_blks = 1 + +#******************************************************************************* + + .data + .type sha256_reg_data, %object + .align 4 + +sha256_reg_data: + .word MMCAU_1_CMD+(HASH+HF2U)<<22 @ r5 + .word MMCAU_1_CMD+(HASH+HF2V)<<22 @ r6 + .word MMCAU_1_CMD+(SHS2)<<22 @ r7 + .word MMCAU_3_CMDS+(MVAR+CA8)<<22+(HASH+HF2S)<<11+HASH+HF2M @ r8 + .word MMCAU_3_CMDS+(ADRA+CA7)<<22+(HASH+HF2T)<<11+HASH+HF2C @ r9 + .word sha256_k @ sl + + .type sha256_initial_h, %object + .align 4 + +sha256_initial_h: + .word 0x6a09e667 + .word 0xbb67ae85 + .word 0x3c6ef372 + .word 0xa54ff53a + .word 0x510e527f + .word 0x9b05688c + .word 0x1f83d9ab + .word 0x5be0cd19 + + .type sha256_k, %object + .align 4 + +sha256_k: + .word 0x428a2f98 + .word 0x71374491 + .word 0xb5c0fbcf + .word 0xe9b5dba5 + .word 0x3956c25b + .word 0x59f111f1 + .word 0x923f82a4 + .word 0xab1c5ed5 + .word 0xd807aa98 + .word 0x12835b01 + .word 0x243185be + .word 0x550c7dc3 + .word 0x72be5d74 + .word 0x80deb1fe + .word 0x9bdc06a7 + .word 0xc19bf174 + .word 0xe49b69c1 + .word 0xefbe4786 + .word 0x0fc19dc6 + .word 0x240ca1cc + .word 0x2de92c6f + .word 0x4a7484aa + .word 0x5cb0a9dc + .word 0x76f988da + .word 0x983e5152 + .word 0xa831c66d + .word 0xb00327c8 + .word 0xbf597fc7 + .word 0xc6e00bf3 + .word 0xd5a79147 + .word 0x06ca6351 + .word 0x14292967 + .word 0x27b70a85 + .word 0x2e1b2138 + .word 0x4d2c6dfc + .word 0x53380d13 + .word 0x650a7354 + .word 0x766a0abb + .word 0x81c2c92e + .word 0x92722c85 + .word 0xa2bfe8a1 + .word 0xa81a664b + .word 0xc24b8b70 + .word 0xc76c51a3 + .word 0xd192e819 + .word 0xd6990624 + .word 0xf40e3585 + .word 0x106aa070 + .word 0x19a4c116 + .word 0x1e376c08 + .word 0x2748774c + .word 0x34b0bcb5 + .word 0x391c0cb3 + .word 0x4ed8aa4a + .word 0x5b9cca4f + .word 0x682e6ff3 + .word 0x748f82ee + .word 0x78a5636f + .word 0x84c87814 + .word 0x8cc70208 + .word 0x90befffa + .word 0xa4506ceb + .word 0xbef9a3f7 + .word 0xc67178f2 diff --git a/KSDK_1.2.0/platform/drivers/src/mpu/fsl_mpu_common.c b/KSDK_1.2.0/platform/drivers/src/mpu/fsl_mpu_common.c new file mode 100755 index 0000000..9cb6813 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mpu/fsl_mpu_common.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for MPU instances. */ +MPU_Type * const g_mpuBase[] = MPU_BASE_PTRS; + +/*! @brief Table to save MPU IRQ enum numbers for core access. */ +const IRQn_Type g_mpuIrqId[MPU_INSTANCE_COUNT] = {BusFault_IRQn}; + +/******************************************************************************* + * EOF + ******************************************************************************/ + + diff --git a/KSDK_1.2.0/platform/drivers/src/mpu/fsl_mpu_driver.c b/KSDK_1.2.0/platform/drivers/src/mpu/fsl_mpu_driver.c new file mode 100755 index 0000000..ca63f79 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mpu/fsl_mpu_driver.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 <assert.h> +#include <string.h> +#include "fsl_mpu_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_MPU_COUNT + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + *******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : MPU_DRV_Init + * Description : MPU module init. + * This function is used to initialize MPU regions. + * + *END**************************************************************************/ +mpu_status_t MPU_DRV_Init(uint32_t instance, const mpu_user_config_t *userConfigPtr) +{ + assert(instance < MPU_INSTANCE_COUNT); + MPU_Type * base = g_mpuBase[instance]; + if(!userConfigPtr) + { + return kStatus_MPU_NullArgument; + } + CLOCK_SYS_EnableMpuClock(instance); + MPU_HAL_Init(base); + while(userConfigPtr) + { + MPU_DRV_SetRegionConfig(instance, &(userConfigPtr->regionConfig)); + userConfigPtr = userConfigPtr->next; + } + MPU_HAL_Enable(base); + return kStatus_MPU_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : MPU_DRV_Deinit + * Description : MPU module deinit. + * This function is used to deinit MPU module---disable MPU and disable each region. + * + *END**************************************************************************/ +void MPU_DRV_Deinit(uint32_t instance) +{ + assert(instance < MPU_INSTANCE_COUNT); + MPU_Type * base = g_mpuBase[instance]; + MPU_HAL_Init(base); + CLOCK_SYS_DisableMpuClock(instance); +} + +/*FUNCTION********************************************************************** + * + * Function Name : MPU_DRV_SetRegionConfig + * Description : MPU region init. + * This function is used to initialize a MPU region. + * Note: when writing to a region's word0~word3 will caused the region invalid + * so the region must be set valid by manual. + *END**************************************************************************/ +mpu_status_t MPU_DRV_SetRegionConfig(uint32_t instance, const mpu_region_config_t *regionConfigPtr) +{ + assert(instance < MPU_INSTANCE_COUNT); + MPU_Type * base = g_mpuBase[instance]; + + MPU_HAL_SetRegionConfig(base, regionConfigPtr); + + return kStatus_MPU_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : MPU_DRV_SetLowMasterAccessRights + * Description : Set low master access permission. + * This function is used to set low master access permission. + * + *END**************************************************************************/ +mpu_status_t MPU_DRV_SetLowMasterAccessRights(uint32_t instance, mpu_region_num_t regionNum, mpu_master_t masterNum, const mpu_low_masters_access_rights_t *accessRightsPtr) +{ + assert(instance < MPU_INSTANCE_COUNT); + MPU_Type * base = g_mpuBase[instance]; + if(!accessRightsPtr) + { + return kStatus_MPU_NullArgument; + } + MPU_HAL_SetLowMasterAccessRightsByAlternateReg(base, regionNum, masterNum, accessRightsPtr); + + return kStatus_MPU_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : MPU_DRV_SetHighMasterAccessRights + * Description : Set high master access permission. + * This function is used to set high master access permission. + * + *END**************************************************************************/ +mpu_status_t MPU_DRV_SetHighMasterAccessRights(uint32_t instance, mpu_region_num_t regionNum, mpu_master_t masterNum, const mpu_high_masters_access_rights_t *accessRightsPtr) +{ + assert(instance < MPU_INSTANCE_COUNT); + MPU_Type * base = g_mpuBase[instance]; + if(!accessRightsPtr) + { + return kStatus_MPU_NullArgument; + } + MPU_HAL_SetHighMasterAccessRightsByAlternateReg(base, regionNum, masterNum, accessRightsPtr); + + return kStatus_MPU_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : MPU_DRV_SetRegionAddr + * Description : Set region start address. + * This function is used to set region start address. + * + *END**************************************************************************/ +void MPU_DRV_SetRegionAddr(uint32_t instance, mpu_region_num_t regionNum, uint32_t startAddr, uint32_t endAddr) +{ + assert(instance < MPU_INSTANCE_COUNT); + MPU_Type * base = g_mpuBase[instance]; + MPU_HAL_SetRegionAddr(base, regionNum, startAddr, endAddr); +} + +/*FUNCTION********************************************************************** + * + * Function Name : MPU_DRV_SetRegionValidCmd + * Description : set a region valid or invalid. + * This function is used to set a region valid or invalid. + * + *END**************************************************************************/ +void MPU_DRV_SetRegionValidCmd(uint32_t instance, mpu_region_num_t regionNum, bool enable) +{ + assert(instance < MPU_INSTANCE_COUNT); + MPU_Type * base = g_mpuBase[instance]; + MPU_HAL_SetRegionValidCmd(base, regionNum, enable); +} + +/*FUNCTION********************************************************************** + * + * Function Name : MPU_DRV_GetDetailErrorAccessInfo + * Description : Gets error access detail information. + * Attention: It is possible for two masters access error in same cycle, so a array pointer is needed. + * + *END**************************************************************************/ +mpu_status_t MPU_DRV_GetDetailErrorAccessInfo(uint32_t instance, mpu_access_err_info_t *errInfoArrayPtr) +{ + assert(instance < MPU_INSTANCE_COUNT); + MPU_Type * base = g_mpuBase[instance]; + if(!errInfoArrayPtr) + { + return kStatus_MPU_NullArgument; + } + MPU_HAL_GetDetailErrorAccessInfo(base, errInfoArrayPtr); + + return kStatus_MPU_Success; +} +#endif + +/******************************************************************************* + * EOF + *******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/mpu/fsl_mpu_irq.c b/KSDK_1.2.0/platform/drivers/src/mpu/fsl_mpu_irq.c new file mode 100755 index 0000000..c4a0736 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mpu/fsl_mpu_irq.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 -2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_mpu_driver.h" +#if FSL_FEATURE_SOC_MPU_COUNT + +/****************************************************************************** + * Code + *****************************************************************************/ +/* MPU IRQ handler that would cover the same name's APIs in startup code */ +void BusFault_Handler() +{ +} + +#endif + +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/mpu/fsl_mpu_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/mpu/fsl_mpu_lpm_callback.c new file mode 100755 index 0000000..5a189d1 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/mpu/fsl_mpu_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_MPU_COUNT + +power_manager_error_code_t mpu_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t mpu_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/pdb/fsl_pdb_common.c b/KSDK_1.2.0/platform/drivers/src/pdb/fsl_pdb_common.c new file mode 100755 index 0000000..3ead9e6 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/pdb/fsl_pdb_common.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for PDB instances. */ +PDB_Type * const g_pdbBase[] = PDB_BASE_PTRS; + +/* Table to save PDB IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_pdbIrqId[PDB_INSTANCE_COUNT] = PDB_IRQS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/pdb/fsl_pdb_driver.c b/KSDK_1.2.0/platform/drivers/src/pdb/fsl_pdb_driver.c new file mode 100755 index 0000000..750ea3d --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/pdb/fsl_pdb_driver.c @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include "fsl_pdb_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_PDB_COUNT + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_Init + * Description : Initialize the PDB counter and trigger input for PDB module. + * It resets PDB registers and enables the clock for PDB. So it should be + * called before any operation to PDB module. After initialized, the PDB can + * ack as a triggered timer, which lays the foundation for other features in + * PDB module. + * + *END*************************************************************************/ +pdb_status_t PDB_DRV_Init(uint32_t instance, const pdb_timer_config_t *userConfigPtr) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + if (!userConfigPtr) + { + return kStatus_PDB_InvalidArgument; + } + /* Enable the clock gate from clock manager. */ + CLOCK_SYS_EnablePdbClock(instance); + + /* Reset the registers for PDB module to reset state. */ + PDB_HAL_Init(base); + PDB_HAL_Enable(base); + PDB_HAL_ConfigTimer(base, userConfigPtr); + + /* Configure NVIC. */ + if (userConfigPtr->intEnable) + { + INT_SYS_EnableIRQ(g_pdbIrqId[instance] );/* Enable PDB interrupt in NVIC level.*/ + } + else + { + INT_SYS_DisableIRQ(g_pdbIrqId[instance] );/* Disable PDB interrupt in NVIC level.*/ + } + + return kStatus_PDB_Success; +} + + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_Deinit + * Description : De-initialize the PDB module. + * When the PDB module is not used. Calling this function would shutdown the + * PDB module and reduce the power consumption. + * + *END*************************************************************************/ +pdb_status_t PDB_DRV_Deinit(uint32_t instance) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + INT_SYS_DisableIRQ( g_pdbIrqId[instance] ); + PDB_HAL_Disable(base); + CLOCK_SYS_DisablePdbClock(instance); + + return kStatus_PDB_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_SoftTriggerCmd + * Description : Trigger PDB by software trigger. + * When the PDB is set to use software trigger as input, Calling this function + * would trigger the PDB. + * + *END*************************************************************************/ +void PDB_DRV_SoftTriggerCmd(uint32_t instance) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + PDB_HAL_SetSoftTriggerCmd(base); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_GetTimerValue + * Description : Get the current counter value in PDB module. + * + *END*************************************************************************/ +uint32_t PDB_DRV_GetTimerValue(uint32_t instance) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + return PDB_HAL_GetTimerValue(base); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_GetTimerIntFlag + * Description : Get the interrupt flag for PDB module. It will be + * asserted if the PDB interrupt occurs. + * + *END*************************************************************************/ +bool PDB_DRV_GetTimerIntFlag(uint32_t instance) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + return PDB_HAL_GetTimerIntFlag(base); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_ClearTimerIntFlag + * Description : Clear the interrupt flag for PDB module. + * + *END*************************************************************************/ +void PDB_DRV_ClearTimerIntFlag(uint32_t instance) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + PDB_HAL_ClearTimerIntFlag(base); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_LoadValuesCmd + * Description : Execute the command of loading values. + * + *END*************************************************************************/ +void PDB_DRV_LoadValuesCmd(uint32_t instance) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + PDB_HAL_SetLoadValuesCmd(base); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_SetTimerModulusValue + * Description : Set the value of timer modulus. + * + *END*************************************************************************/ +void PDB_DRV_SetTimerModulusValue(uint32_t instance, uint32_t value) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + PDB_HAL_SetTimerModulusValue(base, value); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_SetValueForTimerInterrupt + * Description : Set the value for the timer interrupt. + * + *END*************************************************************************/ +void PDB_DRV_SetValueForTimerInterrupt(uint32_t instance, uint32_t value) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + PDB_HAL_SetValueForTimerInterrupt(base, value); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_ConfigAdcPreTrigger + * Description : Configure the ADC pre_trigger in the PDB module. + * + *END*************************************************************************/ +pdb_status_t PDB_DRV_ConfigAdcPreTrigger(uint32_t instance, uint32_t chn, const pdb_adc_pretrigger_config_t *configPtr) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + if (!configPtr) + { + return kStatus_PDB_InvalidArgument; + } + + PDB_HAL_SetAdcPreTriggerEnable(base, chn, 1U << (configPtr->adcPreTriggerIdx), configPtr->preTriggerEnable); + PDB_HAL_SetAdcPreTriggerOutputEnable(base, chn, 1U << (configPtr->adcPreTriggerIdx), configPtr->preTriggerOutputEnable); + PDB_HAL_SetAdcPreTriggerBackToBackEnable(base, chn, 1U << (configPtr->adcPreTriggerIdx), configPtr->preTriggerBackToBackEnable); + + return kStatus_PDB_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_GetAdcPreTriggerFlags + * Description : Get the ADC pre_trigger flag in the PDB module. + * + *END*************************************************************************/ +uint32_t PDB_DRV_GetAdcPreTriggerFlags(uint32_t instance, uint32_t chn, uint32_t preChnMask) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + return PDB_HAL_GetAdcPreTriggerFlags(base, chn, preChnMask); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_ClearAdcPreTriggerFlags + * Description : Clear the ADC pre_trigger flag in the PDB module. + * + *END*************************************************************************/ +void PDB_DRV_ClearAdcPreTriggerFlags(uint32_t instance, uint32_t chn, uint32_t preChnMask) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + PDB_HAL_ClearAdcPreTriggerFlags(base, chn, preChnMask); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_GetAdcPreTriggerSeqErrFlags + * Description : Get the ADC pre_trigger flag in the PDB module. + * + *END*************************************************************************/ +uint32_t PDB_DRV_GetAdcPreTriggerSeqErrFlags(uint32_t instance, uint32_t chn, uint32_t preChnMask) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + return PDB_HAL_GetAdcPreTriggerSeqErrFlags(base, chn, preChnMask); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_ClearAdcPreTriggerSeqErrFlags + * Description : Clear the ADC pre_trigger flag in the PDB module. + * + *END*************************************************************************/ +void PDB_DRV_ClearAdcPreTriggerSeqErrFlags(uint32_t instance, uint32_t chn, uint32_t preChnMask) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + PDB_HAL_ClearAdcPreTriggerSeqErrFlags(base, chn, preChnMask); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_SetAdcPreTriggerDelayValue + * Description : Set the ADC pre_trigger delay value in the PDB module. + * + *END*************************************************************************/ +void PDB_DRV_SetAdcPreTriggerDelayValue(uint32_t instance, uint32_t chn, uint32_t preChn, uint32_t value) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + PDB_HAL_SetAdcPreTriggerDelayValue(base, chn, preChn, value); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_ConfigDacInterval + * Description : Configure the DAC interval in the PDB module. + * + *END*************************************************************************/ +pdb_status_t PDB_DRV_ConfigDacInterval(uint32_t instance, uint32_t dacChn, const pdb_dac_interval_config_t *configPtr) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + if (!configPtr) + { + return kStatus_PDB_InvalidArgument; + } + + PDB_HAL_SetDacIntervalTriggerEnable(base, dacChn, configPtr->intervalTriggerEnable); + PDB_HAL_SetDacExtTriggerInputEnable(base, dacChn, configPtr->extTriggerInputEnable); + + return kStatus_PDB_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_SetDacIntervalValue + * Description : Set the DAC interval value in the PDB module. + * + *END*************************************************************************/ +void PDB_DRV_SetDacIntervalValue(uint32_t instance, uint32_t dacChn, uint32_t value) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + PDB_HAL_SetDacIntervalValue(base, dacChn, value); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_SetCmpPulseOutEnable + * Description : Switch on/off the CMP pulse out in the PDB module. + * + *END*************************************************************************/ +void PDB_DRV_SetCmpPulseOutEnable(uint32_t instance, uint32_t pulseChnMask, bool enable) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + PDB_HAL_SetCmpPulseOutEnable(base, pulseChnMask, enable); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_SetCmpPulseOutDelayForHigh + * Description : Set the CMP pulse out delay value for high in the PDB module. + * + *END*************************************************************************/ +void PDB_DRV_SetCmpPulseOutDelayForHigh(uint32_t instance, uint32_t pulseChn, uint32_t value) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + PDB_HAL_SetCmpPulseOutDelayForHigh(base, pulseChn, value); +} + +/*FUNCTION********************************************************************* + * + * Function Name : PDB_DRV_SetCmpPulseOutDelayForLow + * Description : Set the CMP pulse out delay value for low in the PDB module. + * + *END*************************************************************************/ +void PDB_DRV_SetCmpPulseOutDelayForLow(uint32_t instance, uint32_t pulseChn, uint32_t value) +{ + assert(instance < PDB_INSTANCE_COUNT); + PDB_Type * base = g_pdbBase[instance]; + + PDB_HAL_SetCmpPulseOutDelayForLow(base, pulseChn, value); +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/pdb/fsl_pdb_irq.c b/KSDK_1.2.0/platform/drivers/src/pdb/fsl_pdb_irq.c new file mode 100755 index 0000000..571a65a --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/pdb/fsl_pdb_irq.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_pdb_driver.h" +#if FSL_FEATURE_SOC_PDB_COUNT + +/****************************************************************************** + * IRQ Handlers + *****************************************************************************/ +/* PDB IRQ handler that would cover the same name's APIs in startup code. */ +void PDB0_IRQHandler(void) +{ + /* Add user-defined ISR for PDB0. */ + + /* Clear Flags. */ + if ( PDB_DRV_GetPdbCounterIntFlag(0U)) + { + PDB_DRV_ClearPdbCounterIntFlag(0U); + } +} + +#if (PDB_INSTANCE_COUNT > 1) +void PDB1_IRQHandler(void) +{ + /* Add user-defined ISR for PDB1. */ + + /* Clear Flags. */ + if ( PDB_DRV_GetPdbCounterIntFlag(1U)) + { + PDB_DRV_ClearPdbCounterIntFlag(1U); + } +} +#endif +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/pdb/fsl_pdb_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/pdb/fsl_pdb_lpm_callback.c new file mode 100755 index 0000000..bfab56b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/pdb/fsl_pdb_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_PDB_COUNT + +power_manager_error_code_t pdb_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t pdb_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/pit/fsl_pit_common.c b/KSDK_1.2.0/platform/drivers/src/pit/fsl_pit_common.c new file mode 100755 index 0000000..8bbfb48 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/pit/fsl_pit_common.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_PIT_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for pit instances. */ +PIT_Type * const g_pitBase[] = PIT_BASE_PTRS; + +/* Table to save PIT IRQ enum numbers defined in CMSIS files. */ +const IRQn_Type g_pitIrqId[] = PIT_IRQS; + +#endif /* FSL_FEATURE_SOC_PIT_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/pit/fsl_pit_driver.c b/KSDK_1.2.0/platform/drivers/src/pit/fsl_pit_driver.c new file mode 100755 index 0000000..b4fc348 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/pit/fsl_pit_driver.c @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_pit_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_PIT_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* pit source clock variable which will be updated in PIT_DRV_Init */ +uint64_t g_pitSourceClock; + +/* pit instance and channel number used by microseconds functions */ +uint8_t g_pitUsInstance; +uint8_t g_pitUsChannel; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_Init + * Description : Initialize PIT module. + * This function must be called before calling all the other PIT driver functions. + * This function un-gates the PIT clock and enables the PIT module. The + * isRunInDebug passed into function will affect all timer channels. + * + *END**************************************************************************/ +pit_status_t PIT_DRV_Init(uint32_t instance, bool isRunInDebug) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + + /* Un-gate pit clock*/ + CLOCK_SYS_EnablePitClock(instance); + + /* Enable PIT module clock*/ + PIT_HAL_Enable(base); + + /* Set timer run or stop in debug mode*/ + PIT_HAL_SetTimerRunInDebugCmd(base, isRunInDebug); + + /* Finally, update pit source clock frequency.*/ + g_pitSourceClock = CLOCK_SYS_GetPitFreq(instance); + + return kStatus_PIT_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_InitChannel + * Description : Initialize PIT channel. + * This function initialize PIT timers by channel. Pass in timer number and its + * config structure. Timers do not start counting by default after calling this + * function. Function PIT_DRV_StartTimer must be called to start timer counting. + * Call PIT_DRV_SetTimerPeriodByUs to re-set the period. + * + *END**************************************************************************/ +void PIT_DRV_InitChannel(uint32_t instance, + uint32_t channel, + const pit_user_config_t * config) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + + /* Set timer period.*/ + PIT_DRV_SetTimerPeriodByUs(instance, channel, config->periodUs); + + /* Enable or disable interrupt.*/ + PIT_HAL_SetIntCmd(base, channel, config->isInterruptEnabled); + + /* Configure NVIC*/ + if (config->isInterruptEnabled) + { + /* Enable PIT interrupt.*/ + INT_SYS_EnableIRQ(g_pitIrqId[channel]); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_Deinit + * Description : Disable PIT module and gate control + * This function will disable all PIT interrupts and PIT clock. Then gate the + * PIT clock control. pit_init must be called in order to use PIT again. + * + *END**************************************************************************/ +pit_status_t PIT_DRV_Deinit(uint32_t instance) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + uint32_t i; + + /* Exit if current instance is gated.*/ + if (!CLOCK_SYS_GetPitGateCmd(instance)) + { + return kStatus_PIT_Fail; + } + + /* Disable all PIT interrupts. */ + for (i=0; i < FSL_FEATURE_PIT_TIMER_COUNT; i++) + { + PIT_HAL_SetIntCmd(base, i, false); + INT_SYS_DisableIRQ(g_pitIrqId[i]); + } + + /* Disable PIT module clock*/ + PIT_HAL_Disable(base); + + /* Gate PIT clock control*/ + CLOCK_SYS_DisablePitClock(instance); + + return kStatus_PIT_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_StartTimer + * Description : Start 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 will generate a trigger pulse and set the timeout interrupt flag. + * + *END**************************************************************************/ +void PIT_DRV_StartTimer(uint32_t instance, uint32_t channel) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + PIT_HAL_StartTimer(base, channel); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_StopTimer + * Description : Stop timer counting. + * This function will stop every timer counting. Timers will reload their periods + * respectively after calling PIT_DRV_StartTimer next time. + * + *END**************************************************************************/ +void PIT_DRV_StopTimer(uint32_t instance, uint32_t channel) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + PIT_HAL_StopTimer(base, channel); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_SetTimerPeriodByUs + * Description : Set timer period in microseconds unit. + * The period range depends on the frequency of PIT source clock. If required + * period is out the range, try to use lifetime timer if applicable. + * This function is only valid for one single channel. If channels are chained together, + * the period here will make no sense. + * + *END**************************************************************************/ +void PIT_DRV_SetTimerPeriodByUs(uint32_t instance, uint32_t channel, uint32_t us) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + /* Calculate the count value, assign it to timer counter register.*/ + uint32_t count = (uint32_t)(us * g_pitSourceClock / 1000000U - 1U); + PIT_HAL_SetTimerPeriodByCount(base, channel, count); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_GetTimerPeriodByUs + * Description : Gets the timer period in microseconds for one single channel. + * + *END**************************************************************************/ +uint32_t PIT_DRV_GetTimerPeriodByUs(uint32_t instance, uint32_t channel) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + /* Get current timer period by count.*/ + uint64_t currentPeriod = PIT_HAL_GetTimerPeriodByCount(base, channel); + + /* Convert count numbers to microseconds unit.*/ + currentPeriod = (currentPeriod + 1U) * 1000000U / g_pitSourceClock; + return (uint32_t)currentPeriod ; +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_ReadTimerUs + * Description : Read current timer value in microseconds unit. + * This function will return an absolute time stamp in the unit of microseconds. + * One common use of this function is to measure the running time of part of + * code. Just call this function at both the beginning and end of code, the time + * difference between these two time stamp will be the running time (Need to + * make sure the running time will not exceed the timer period). Also, the time + * stamp returned is up-counting. + * + *END**************************************************************************/ +uint32_t PIT_DRV_ReadTimerUs(uint32_t instance, uint32_t channel) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + /* Get current timer count, and reverse it to up-counting.*/ + uint64_t currentTime = (~PIT_HAL_ReadTimerCount(base, channel)); + + /* Convert count numbers to microseconds unit.*/ + currentTime = (currentTime * 1000000U) / g_pitSourceClock; + return (uint32_t)currentTime; +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_SetTimerPeriodByCount + * Description : Sets the timer period in units of count. + * Timers begin counting from the value set by this function. + * The counter period of a running timer can be modified by first stopping + * the timer, setting a new load value, and starting the timer again. If + * timers are not restarted, the new value is loaded after the next trigger + * event. + * + *END**************************************************************************/ +void PIT_DRV_SetTimerPeriodByCount(uint32_t instance, uint32_t channel, uint32_t count) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + + PIT_HAL_SetTimerPeriodByCount(base, channel, count); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_GetTimerPeriodByCount + * Description : Returns the current timer period in units of count. + * + *END**************************************************************************/ +uint32_t PIT_DRV_GetTimerPeriodByCount(uint32_t instance, uint32_t channel) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + + return PIT_HAL_GetTimerPeriodByCount(base, channel); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_ReadTimerCount + * Description : Reads the current timer counting value. + * This function returns the real-time timer counting value, in a range from 0 + * to a timer period. + * + *END**************************************************************************/ +uint32_t PIT_DRV_ReadTimerCount(uint32_t instance, uint32_t channel) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + + return PIT_HAL_ReadTimerCount(base, channel); +} + +#if FSL_FEATURE_PIT_HAS_LIFETIME_TIMER +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_SetLifetimeTimerPeriodByUs + * Description : Set lifetime timer period (Timers must be chained). + * Timer 1 must be chained with timer 0 before using lifetime timer. The period + * range is restricted by "period * g_pitSourceClock < max of an uint64_t integer", + * or it may cause a overflow and is not able to set correct period. + * + *END**************************************************************************/ +void PIT_DRV_SetLifetimeTimerPeriodByUs(uint32_t instance, uint64_t us) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + uint64_t lifeTimeCount; + + /* Calculate the counter value.*/ + lifeTimeCount = us * g_pitSourceClock / 1000000U - 1U; + + /* Assign to timers.*/ + PIT_HAL_SetTimerPeriodByCount(base, 0U, (uint32_t)lifeTimeCount); + PIT_HAL_SetTimerPeriodByCount(base, 1U, (uint32_t)(lifeTimeCount >> 32U)); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_ReadLifetimeTimerUs + * Description : Read current lifetime value in microseconds unit. + * Return an absolute time stamp in the unit of microseconds. The time stamp + * value will not exceed the timer period. Also, the timer is up-counting. + * + *END**************************************************************************/ +uint64_t PIT_DRV_ReadLifetimeTimerUs(uint32_t instance) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + /* Get current lifetime timer count, and reverse it to up-counting.*/ + uint64_t currentTime = (~PIT_HAL_ReadLifetimeTimerCount(base)); + + /* Convert count numbers to microseconds unit.*/ + /* Note: using currentTime * 1000 rather than 1000000 to avoid short time overflow. */ + return currentTime = (currentTime * 1000U) / (g_pitSourceClock / 1000U); +} +#endif /* FSL_FEATURE_PIT_HAS_LIFETIME_TIMER*/ + +#if FSL_FEATURE_PIT_HAS_CHAIN_MODE +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_InitUs + * Description : Initializes two PIT channels to serve as a microseconds unit. + * This function is in parallel with PIT_DRV_InitChannel, they will overwrite + * each other. PIT_DRV_Init must be called before calling this function. + * The microseconds unit will use two chained channels to simulate a lifetime + * timer, the channel number passed in and the "channel -1" channel will be used. + * Note: + * 1. These two channels will be occupied and could not be used with other purposes. + * 2. The channel number passed in must be greater than 0. + + *END**************************************************************************/ +void PIT_DRV_InitUs(uint32_t instance, uint32_t channel) +{ + assert(instance < PIT_INSTANCE_COUNT); + assert(channel > 0U); + + PIT_Type * base = g_pitBase[instance]; + g_pitUsInstance = instance; + g_pitUsChannel = channel; + + PIT_HAL_SetTimerChainCmd(base, channel, true); + PIT_HAL_SetTimerPeriodByCount(base, channel, 0xFFFFFFFFU); + PIT_HAL_SetTimerPeriodByCount(base, channel - 1U, 0xFFFFFFFFU); + + PIT_HAL_StartTimer(base, channel); + PIT_HAL_StartTimer(base, channel - 1U); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_GetUs + * Description : Get an absolute time stamp. + * This function is useful to get elapsed time through calling this function in + * time A, and then call it in time B. The elapsed time could be get by B-A, the + * result may have 3-5 microseconds error depends on system clock frequency. + * + *END**************************************************************************/ +uint32_t PIT_DRV_GetUs(void) +{ + PIT_Type * base = g_pitBase[g_pitUsInstance]; + /* Get current timer count, and reverse it to up-counting.*/ + uint64_t currentTime = ~(((uint64_t)PIT_HAL_ReadTimerCount(base, g_pitUsChannel) << 32U) + + PIT_HAL_ReadTimerCount(base, g_pitUsChannel - 1U)); + + /* Convert count numbers to microseconds unit.*/ + return currentTime = (currentTime * 1000U) / (g_pitSourceClock / 1000U); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_DelayUs + * Description : Delay specific microseconds. + * The delay will have a 3-5 microseconds error depends on system clock frequency. + * + *END**************************************************************************/ +void PIT_DRV_DelayUs(uint32_t us) +{ + PIT_Type * base = g_pitBase[g_pitUsInstance]; + + uint64_t x = us * g_pitSourceClock / 1000000; + uint64_t timeToBe = ((uint64_t)PIT_HAL_ReadTimerCount(base, g_pitUsChannel) << 32U) + + PIT_HAL_ReadTimerCount(base, g_pitUsChannel - 1U) - x; + + while (((uint64_t)PIT_HAL_ReadTimerCount(base, g_pitUsChannel) << 32U) + + PIT_HAL_ReadTimerCount(base, g_pitUsChannel - 1U) + >= timeToBe) + {} +} + +#endif /* FSL_FEATURE_PIT_HAS_CHAIN_MODE */ + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_ClearIntFlag + * Description : Clears the timer interrupt flag. + * + *END**************************************************************************/ +void PIT_DRV_ClearIntFlag(uint32_t instance, uint32_t channel) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + + PIT_HAL_ClearIntFlag(base, channel); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PIT_DRV_IsIntPending + * Description : Reads the current timer timeout flag. + * + *END**************************************************************************/ +bool PIT_DRV_IsIntPending(uint32_t instance, uint32_t channel) +{ + assert(instance < PIT_INSTANCE_COUNT); + + PIT_Type * base = g_pitBase[instance]; + + return PIT_HAL_IsIntPending(base, channel); +} + +#endif /* FSL_FEATURE_SOC_PIT_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/pit/fsl_pit_irq.c b/KSDK_1.2.0/platform/drivers/src/pit/fsl_pit_irq.c new file mode 100755 index 0000000..fb8c874 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/pit/fsl_pit_irq.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <assert.h> +#include "fsl_pit_driver.h" + +/*! + * @addtogroup pit_irq + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/*! + * @brief System default IRQ handler defined in startup code. + * + * Users can either edit this handler or define a callback function. Furthermore, + * interrupt manager could be used to re-map the IRQ handler to another function. + */ +#if FSL_FEATURE_PIT_HAS_SHARED_IRQ_HANDLER +void PIT_IRQHandler(void) +{ + uint32_t i; + for(i=0; i < FSL_FEATURE_PIT_TIMER_COUNT; i++) + { + if (PIT_HAL_IsIntPending(g_pitBase[0], i)) + { + /* Clear interrupt flag.*/ + PIT_HAL_ClearIntFlag(g_pitBase[0], i); + } + } +} +#else + +#if (FSL_FEATURE_PIT_TIMER_COUNT > 0U) +void PIT0_IRQHandler(void) +{ + /* Clear interrupt flag.*/ + PIT_HAL_ClearIntFlag(g_pitBase[0], 0U); +} +#endif + +#if (FSL_FEATURE_PIT_TIMER_COUNT > 1U) +void PIT1_IRQHandler(void) +{ + /* Clear interrupt flag.*/ + PIT_HAL_ClearIntFlag(g_pitBase[0], 1U); +} +#endif + +#if (FSL_FEATURE_PIT_TIMER_COUNT > 2U) +void PIT2_IRQHandler(void) +{ + /* Clear interrupt flag.*/ + PIT_HAL_ClearIntFlag(g_pitBase[0], 2U); +} +#endif + +#if (FSL_FEATURE_PIT_TIMER_COUNT > 3U) +void PIT3_IRQHandler(void) +{ + /* Clear interrupt flag.*/ + PIT_HAL_ClearIntFlag(g_pitBase[0], 3U); +} +#endif + +#endif /* FSL_FEATURE_PIT_HAS_SHARED_IRQ_HANDLER */ + +/*! @} */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/pit/fsl_pit_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/pit/fsl_pit_lpm_callback.c new file mode 100755 index 0000000..ee58434 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/pit/fsl_pit_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t pit_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t pit_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/pwm/fsl_pwm_common.c b/KSDK_1.2.0/platform/drivers/src/pwm/fsl_pwm_common.c new file mode 100755 index 0000000..4437a55 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/pwm/fsl_pwm_common.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_PWM_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for PWM instances. */ +PWM_Type * const g_pwmBase[PWM_INSTANCE_COUNT] = PWM_BASE_PTRS; + +/* Table to save PWM IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_pwmCmpIrqId[FSL_FEATURE_PWM_CMP_INT_HANDLER_COUNT] = PWM_CMP_IRQS; +const IRQn_Type g_pwmReloadIrqId[FSL_FEATURE_PWM_RELOAD_INT_HANDLER_COUNT] = PWM_RELOAD_IRQS; +const IRQn_Type g_pwmCapIrqId[FSL_FEATURE_PWM_CAP_INT_HANDLER_COUNT] = PWM_CAP_IRQS; +const IRQn_Type g_pwmRerrIrqId[FSL_FEATURE_PWM_RERR_INT_HANDLER_COUNT] = PWM_RERR_IRQS; +const IRQn_Type g_pwmFaultIrqId[FSL_FEATURE_PWM_FAULT_INT_HANDLER_COUNT] = PWM_FAULT_IRQS; + +#endif /* FSL_FEATURE_SOC_PWM_COUNT */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/pwm/fsl_pwm_driver.c b/KSDK_1.2.0/platform/drivers/src/pwm/fsl_pwm_driver.c new file mode 100755 index 0000000..691b2c8 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/pwm/fsl_pwm_driver.c @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_pwm_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_PWM_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* External source clock frequency */ +static uint32_t moduleExternalSrcFreq = 0; +/* Module 0 clock frequency */ +static uint32_t pwmModuleFreq[kFlexPwmModule3 + 1] = { 0 }; + +/*! + * @addtogroup pwm_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : PWM_DRV_Init + * Description : Initializes the PWM module. + * Enables the module clocks and interrupts in the interrupt controller. + * + *END**************************************************************************/ +pwm_status_t PWM_DRV_Init(uint32_t instance) +{ + assert(instance < PWM_INSTANCE_COUNT); + PWM_Type *pwmBase = g_pwmBase[instance]; + int i = 0; + + CLOCK_SYS_EnablePwmClock(0U); + CLOCK_SYS_EnablePwmClock(1U); + CLOCK_SYS_EnablePwmClock(2U); + CLOCK_SYS_EnablePwmClock(3U); + + /* Enable eFlexPWM interrupts on NVIC level. */ + for (i = 0; i < FSL_FEATURE_PWM_CMP_INT_HANDLER_COUNT; i++) + { + INT_SYS_EnableIRQ(g_pwmCmpIrqId[i]); + } + for (i = 0; i < FSL_FEATURE_PWM_RELOAD_INT_HANDLER_COUNT; i++) + { + INT_SYS_EnableIRQ(g_pwmReloadIrqId[i]); + } + for (i = 0; i < FSL_FEATURE_PWM_CAP_INT_HANDLER_COUNT; i++) + { + INT_SYS_EnableIRQ(g_pwmCapIrqId[i]); + } + for (i = 0; i < FSL_FEATURE_PWM_RERR_INT_HANDLER_COUNT; i++) + { + INT_SYS_EnableIRQ(g_pwmRerrIrqId[instance]); + } + for (i = 0; i < FSL_FEATURE_PWM_FAULT_INT_HANDLER_COUNT; i++) + { + INT_SYS_EnableIRQ(g_pwmFaultIrqId[instance]); + } + /* Initialize the module */ + PWM_HAL_Init(pwmBase); + + /* Set the initial clock frequency from module 0 */ + pwmModuleFreq[kFlexPwmModule0] = CLOCK_SYS_GetPwmFreq(0); + + return kStatusPwmSuccess; +} + +/*FUNCTION********************************************************************** + * + * Function Name : PWM_DRV_Deinit + * Description : Shuts down the PWM driver. + * This function de-initializes the EflexPWM module and dissables the clock for the submodules. + * Function disables the module-level interrupts. + * + *END**************************************************************************/ +void PWM_DRV_Deinit(uint32_t instance) +{ + assert(instance < PWM_INSTANCE_COUNT); + int i = 0; + + /* Disable Clock to each eFlexPWM submodules. */ + CLOCK_SYS_DisablePwmClock(0U); + CLOCK_SYS_DisablePwmClock(1U); + CLOCK_SYS_DisablePwmClock(2U); + CLOCK_SYS_DisablePwmClock(3U); + + /* Disable eFlexPWM interrupts on NVIC level. */ + for (i = 0; i < FSL_FEATURE_PWM_CMP_INT_HANDLER_COUNT; i++) + { + INT_SYS_DisableIRQ(g_pwmCmpIrqId[i]); + } + for (i = 0; i < FSL_FEATURE_PWM_RELOAD_INT_HANDLER_COUNT; i++) + { + INT_SYS_DisableIRQ(g_pwmReloadIrqId[i]); + } + for (i = 0; i < FSL_FEATURE_PWM_CAP_INT_HANDLER_COUNT; i++) + { + INT_SYS_DisableIRQ(g_pwmCapIrqId[i]); + } + for (i = 0; i < FSL_FEATURE_PWM_RERR_INT_HANDLER_COUNT; i++) + { + INT_SYS_DisableIRQ(g_pwmRerrIrqId[instance]); + } + for (i = 0; i < FSL_FEATURE_PWM_FAULT_INT_HANDLER_COUNT; i++) + { + INT_SYS_DisableIRQ(g_pwmFaultIrqId[instance]); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : PWM_DRV_SetupPwm + * Description : Sets up the PWM signals from the FlewPWM module. + * The function will initialize the submodule per the parameters passed in by the user. The function + * will also setup the value compare registers to match the PWM signal requirements + * NOTE: If the deadtime insertion logic is enabled then the pulse period will be reduced by the + * deadtime period specified by the user. + * + *END**************************************************************************/ +pwm_status_t PWM_DRV_SetupPwm(uint32_t instance, pwm_module_t subModule, pwm_module_setup_t *moduleSetupParams, + pwm_module_signal_setup_t *signalParams) +{ + assert(instance < PWM_INSTANCE_COUNT); + + PWM_Type *pwmBase = g_pwmBase[instance]; + uint32_t freq = 0; + + /* Source clock for submodule 0 cannot be itself */ + if ((moduleSetupParams->clkSrc == kClkSrcPwm0Clk) && (subModule == kFlexPwmModule0)) + { + return kStatusPwmInvalidArgument; + } + /* + * If source clock selection is an external clock, then user should have first provide the + * source frequency by calling PWM_DVR_SetExternalClkFreq() before calling this function + */ + if ((moduleSetupParams->clkSrc == kClkSrcPwmExtClk) && (moduleExternalSrcFreq == 0)) + { + return kStatusPwmInvalidArgument; + } + + /* Setup the PWM submodule */ + PWM_HAL_SetupPwmSubModule(pwmBase, subModule, moduleSetupParams); + + if (moduleSetupParams->clkSrc == kClkSrcPwmIPBusClk) + { + freq = CLOCK_SYS_GetPwmFreq(0); + } + else if (moduleSetupParams->clkSrc == kClkSrcPwm0Clk) + { + freq = pwmModuleFreq[kFlexPwmModule0]; + } + else + { + freq = moduleExternalSrcFreq; + } + freq = freq / (1 << moduleSetupParams->prescale); + + /* Save the module ferquency */ + pwmModuleFreq[subModule] = freq; + + PWM_DRV_UpdatePwmSignal(instance, subModule, signalParams); + + return kStatusPwmSuccess; +} + +/*FUNCTION********************************************************************** + * + * Function Name : PWM_DRV_UpdatePwmSignal + * Description : Update the PWM signal settings. + * The function will update the PWM signal that to the new value that is passed in + * NOTE: If the deadtime insertion logic is enabled then the pulse period will be reduced by the + * deadtime period specified by the user. + * + *END**************************************************************************/ +void PWM_DRV_UpdatePwmSignal(uint32_t instance, pwm_module_t subModule, + pwm_module_signal_setup_t *signalParams) +{ + assert(instance < PWM_INSTANCE_COUNT); + + PWM_Type *pwmBase = g_pwmBase[instance]; + uint16_t pulseCnt, pwmAHighPulse = 0, pwmBHighPulse = 0; + int16_t modulo = 0; + + pulseCnt = ((uint64_t)pwmModuleFreq[subModule] * signalParams->pwmPeriod) / 1000000; + + /* Set signal polarity */ + PWM_HAL_SetOutputPolarityPwmACmd (pwmBase, subModule, signalParams->pwmAPolarity); + PWM_HAL_SetOutputPolarityPwmBCmd (pwmBase, subModule, signalParams->pwmBPolarity); + + /* Pulse width of PWM A */ + if (signalParams->pwmAPulseWidth != FLEXPWM_NO_PWM_OUT_SIGNAL) + { + pwmAHighPulse = ((uint64_t)pwmModuleFreq[subModule] * signalParams->pwmAPulseWidth) / 1000000; + /* Enable output on PWM A */ + PWM_SET_OUTEN(pwmBase, (1U << (PWM_OUTEN_PWMA_EN_SHIFT + subModule))); + } + else + { + /* Disable output on PWM A */ + PWM_CLR_OUTEN(pwmBase, (1U << (PWM_OUTEN_PWMA_EN_SHIFT + subModule))); + } + + /* Pulse width of PWM B */ + if (signalParams->pwmBPulseWidth != FLEXPWM_NO_PWM_OUT_SIGNAL) + { + pwmBHighPulse = ((uint64_t)pwmModuleFreq[subModule] * signalParams->pwmBPulseWidth) / 1000000; + /* Enable output on PWM A */ + PWM_SET_OUTEN(pwmBase, (1U << (PWM_OUTEN_PWMB_EN_SHIFT + subModule))); + + } + else + { + /* Disable output on PWM B */ + PWM_CLR_OUTEN(pwmBase, (1U << (PWM_OUTEN_PWMB_EN_SHIFT + subModule))); + } + + /* Setup the different match registers to generate the PWM signal */ + switch(signalParams->pwmType) + { + case kFlexPwmSignedCenterAligned: + modulo = pulseCnt >> 1; + PWM_WR_INIT(pwmBase, subModule, -modulo); + PWM_WR_VAL0(pwmBase, subModule, 0); + PWM_WR_VAL1(pwmBase, subModule, modulo); + if (pwmAHighPulse != 0) + { + PWM_WR_VAL2(pwmBase, subModule, -(pwmAHighPulse / 2)); + PWM_WR_VAL3(pwmBase, subModule, pwmAHighPulse / 2); + } + if (pwmBHighPulse != 0) + { + PWM_WR_VAL4(pwmBase, subModule, -(pwmBHighPulse / 2)); + PWM_WR_VAL5(pwmBase, subModule, pwmBHighPulse / 2); + } + + break; + case kFlexPwmCenterAligned: + PWM_WR_INIT(pwmBase, subModule, 0); + PWM_WR_VAL0(pwmBase, subModule, pulseCnt / 2); + PWM_WR_VAL1(pwmBase, subModule, pulseCnt); + if (pwmAHighPulse != 0) + { + PWM_WR_VAL2(pwmBase, subModule, (pulseCnt - pwmAHighPulse) / 2); + PWM_WR_VAL3(pwmBase, subModule, (pulseCnt + pwmAHighPulse) / 2); + } + if (pwmBHighPulse != 0) + { + PWM_WR_VAL4(pwmBase, subModule, (pulseCnt - pwmBHighPulse) / 2); + PWM_WR_VAL5(pwmBase, subModule, (pulseCnt - pwmBHighPulse) / 2); + } + + break; + case kFlexPwmSignedEdgeAligned: + modulo = pulseCnt >> 1; + PWM_WR_INIT(pwmBase, subModule, -modulo); + PWM_WR_VAL0(pwmBase, subModule, 0); + PWM_WR_VAL1(pwmBase, subModule, modulo); + if (pwmAHighPulse != 0) + { + PWM_WR_VAL2(pwmBase, subModule, -modulo); + PWM_WR_VAL3(pwmBase, subModule, (-modulo + pwmAHighPulse)); + } + if (pwmBHighPulse != 0) + { + PWM_WR_VAL4(pwmBase, subModule, -modulo); + PWM_WR_VAL5(pwmBase, subModule, (-modulo + pwmBHighPulse)); + } + + break; + case kFlexPwmEdgeAligned: + PWM_WR_INIT(pwmBase, subModule, 0); + PWM_WR_VAL0(pwmBase, subModule, pulseCnt / 2); + PWM_WR_VAL1(pwmBase, subModule, pulseCnt); + if (pwmAHighPulse != 0) + { + PWM_WR_VAL2(pwmBase, subModule, 0); + PWM_WR_VAL3(pwmBase, subModule, pwmAHighPulse); + } + if (pwmBHighPulse != 0) + { + PWM_WR_VAL4(pwmBase, subModule, 0); + PWM_WR_VAL5(pwmBase, subModule, pwmBHighPulse); + } + break; + default: + break; + } + /* Set LDOK bit for this submodule */ + PWM_SET_MCTRL(pwmBase, (1U << subModule)); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PWM_DRV_CounterStart + * Description : Starts the PWM. + * + *END**************************************************************************/ +void PWM_DRV_CounterStart(uint32_t instance, uint8_t value) +{ + assert(instance < PWM_INSTANCE_COUNT); + PWM_Type *pwmBase = g_pwmBase[instance]; + + /* Start multiple PWM sub-modules based on the value passed in */ + PWM_HAL_SetPwmRunCmd(pwmBase, value, true); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PWM_DRV_CounterStop + * Description : Stops the PWM. + * + *END**************************************************************************/ +void PWM_DRV_CounterStop(uint32_t instance, uint8_t value) +{ + assert(instance < PWM_INSTANCE_COUNT); + PWM_Type *pwmBase = g_pwmBase[instance]; + + /* Stop PWM counters */ + PWM_HAL_SetPwmRunCmd(pwmBase, 0x7U, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PWM_DRV_SetTriggerCmd + * Description : Enable or disable the PWM output trigger. + * This function will allow user to enable or disable a PWM triger. PWM has 2 triggers. Trigger 0 is + * activated when the counter matches VAL 0, VAL 2 or VAL 4 register. Trigger 1 is activated when the + * counter matches VAL 1, VAL 3 or VAL 5. + * + *END**************************************************************************/ +void PWM_DRV_SetTriggerCmd(uint32_t instance, pwm_module_t subModule, pwm_val_regs_t trigger, + bool activate) +{ + assert(instance < PWM_INSTANCE_COUNT); + PWM_Type *pwmBase = g_pwmBase[instance]; + + activate ? PWM_SET_TCTRL(pwmBase, subModule, (1U << trigger)) : + PWM_CLR_TCTRL(pwmBase, subModule, (1U << trigger)); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PWM_DRV_SetTriggerVal + * Description : Set the PWM trigger value. + * This function sets the value in the compare register that will be used to generate a trigger. + * NOTE: User must make sure the value register being modified is not currently used to generate a + * PWM signal. + * + *END**************************************************************************/ +void PWM_DRV_SetTriggerVal(uint32_t instance, pwm_module_t subModule, pwm_val_regs_t trigger, + uint16_t triggerVal) +{ + assert(instance < PWM_INSTANCE_COUNT); + PWM_Type *pwmBase = g_pwmBase[instance]; + + PWM_HAL_SetValReg(pwmBase, subModule, trigger, triggerVal); + /* Set LDOK bit for this submodule */ + PWM_SET_MCTRL(pwmBase, (1U << subModule)); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PWM_DRV_SetupFault + * Description : Sets up the PWM fault. + * This function will configure a fault parameters and enable the fault for the appropriate + * sub-module signals + * + *END**************************************************************************/ +void PWM_DRV_SetupFault(uint32_t instance, pwm_module_t subModule, pwm_fault_input_t faultNum, pwm_fault_setup_t *faultParams, + bool pwmA, bool pwmB, bool pwmX) +{ + assert(instance < PWM_INSTANCE_COUNT); + PWM_Type *pwmBase = g_pwmBase[instance]; + + PWM_HAL_SetupFaults(pwmBase, faultNum, faultParams); + + PWM_HAL_SetPwmAFaultInputCmd(pwmBase, subModule, faultNum, pwmA); + PWM_HAL_SetPwmBFaultInputCmd(pwmBase, subModule, faultNum, pwmB); + PWM_HAL_SetPwmXFaultInputCmd(pwmBase, subModule, faultNum, pwmX); +} + +/*FUNCTION********************************************************************** + * + * Function Name : PWM_DRV_SetExternalFreq + * Description : Provide the frequency of the external clock source. + * When using an external signal as clock source, the user should provide the frequency + * of this clock source so that this driver can calculate the register values used to generate + * the requested PWM signal. + * + *END**************************************************************************/ +void PWM_DRV_SetExternalClkFreq(uint32_t instance, uint32_t externalClkFreq) +{ + assert(instance < PWM_INSTANCE_COUNT); + + moduleExternalSrcFreq = externalClkFreq; +} + +#endif /* FSL_FEATURE_SOC_PWM_COUNT */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/pwm/fsl_pwm_irq.c b/KSDK_1.2.0/platform/drivers/src/pwm/fsl_pwm_irq.c new file mode 100755 index 0000000..a7daa7f --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/pwm/fsl_pwm_irq.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" +#include "fsl_pwm_driver.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/* ISR */ +void PWM_Reload0(void); + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Implementation of handler named in startup code. + * + * Passes 0 to generic PWM IRQ handler. + */ +void PWMA_CMP0_IRQHandler(void) +{ + /* Clear interrupt pending capture flags A0,A1,B0,B1,X0,X1. */ + PWM_HAL_ClearCmpFlags(g_pwmBase[0], 0U, 0x3fU); +} + +/*! + * @brief Implementation of handler named in startup code. + * + * Passes 0 to generic PWM IRQ handler. + */ +void PWMA_RELOAD0_IRQHandler(void) +{ + /* Call user function */ + PWM_Reload0(); + + /* Clear interrupt pending flag. */ + PWM_HAL_ClearReloadFlag(g_pwmBase[0], 0U); +} + +/*! + * @brief Implementation of handler named in startup code. + * + * Passes 0 to generic PWM IRQ handler. + */ +void PWMA_CMP1_IRQHandler(void) +{ + /* Clear interrupt pending capture flags A0,A1,B0,B1,X0,X1. */ + PWM_HAL_ClearCmpFlags(g_pwmBase[0], 1U, 0x3fU); +} + +/*! + * @brief Implementation of handler named in startup code. + * + * Passes 0 to generic PWM IRQ handler. + */ +void PWMA_RELOAD1_IRQHandler(void) +{ + /* Clear interrupt pending flag. */ + PWM_HAL_ClearReloadFlag(g_pwmBase[0], 1U); +} + +/*! + * @brief Implementation of handler named in startup code. + * + * Passes 0 to generic PWM IRQ handler. + */ +void PWMA_CMP2_IRQHandler(void) +{ + /* Clear interrupt pending capture flags A0,A1,B0,B1,X0,X1. */ + PWM_HAL_ClearCmpFlags(g_pwmBase[0];, 2U, 0x3fU); +} + +/*! + * @brief Implementation of handler named in startup code. + * + * Passes 0 to generic PWM IRQ handler. + */ +void PWMA_RELOAD2_IRQHandler(void) +{ + /* Clear interrupt pending flag. */ + PWM_HAL_ClearReloadFlag(g_pwmBase[0], 2U); +} + +/*! + * @brief Implementation of handler named in startup code. + * + * Passes 0 to generic PWM IRQ handler. + */ +void PWMA_CMP3_IRQHandler(void) +{ + /* Clear interrupt pending capture flags A0,A1,B0,B1,X0,X1. */ + PWM_HAL_ClearCmpFlags(g_pwmBase[0], 3U, 0x3fU); +} + +/*! + * @brief Implementation of handler named in startup code. + * + * Passes 0 to generic PWM IRQ handler. + */ +void PWMA_RELOAD3_IRQHandler(void) +{ + /* Clear interrupt pending flag. */ + PWM_HAL_ClearReloadFlag(g_pwmBase[0], 3U); +} + +/*! + * @brief Implementation of handler named in startup code. + * + * Passes 0 to generic PWM IRQ handler. + */ +void PWMA_CAP_IRQHandler(void) +{ + PWM_Type *pwmBase = g_pwmBase[0]; + + /* Clear interrupt pending flags from SM0,1,2. */ + PWM_HAL_ClearCapFlagCF(pwmBase, 0U, kCfa1); + PWM_HAL_ClearCapFlagCF(pwmBase, 1U, kCfa1); + PWM_HAL_ClearCapFlagCF(pwmBase, 2U, kCfa1); +} + +/*! + * @brief Implementation of handler named in startup code. + * + * Passes 0 to generic PWM IRQ handler. + */ +void PWMA_RERR_IRQHandler(void) +{ + PWM_Type *pwmBase = g_pwmBase[0]; + + /* Clear interrupt pending flags from SM0,1,2. */ + PWM_HAL_ClearReloadErrFlagREF(pwmBase, 0U); + PWM_HAL_ClearReloadErrFlagREF(pwmBase, 1U); + PWM_HAL_ClearReloadErrFlagREF(pwmBase, 2U); +} + +/*! + * @brief Implementation of handler named in startup code. + * + * Passes 0 to generic PWM IRQ handler. + */ +void PWMA_FAULT_IRQHandler(void) +{ + /* Clear interrupt pending flags from SM0,1,2. */ + PWM_HAL_ClearFaultFlags(g_pwmBase[0], 0x7U); +} + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/pwm/fsl_pwm_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/pwm/fsl_pwm_lpm_callback.c new file mode 100755 index 0000000..7d1de7b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/pwm/fsl_pwm_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t pwm_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t pwm_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/rnga/fsl_rnga_common.c b/KSDK_1.2.0/platform/drivers/src/rnga/fsl_rnga_common.c new file mode 100755 index 0000000..b6c982e --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/rnga/fsl_rnga_common.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for RNGA instances. */ +RNG_Type * const g_rngaBase[] = RNG_BASE_PTRS; + +/*! @brief Table to save RNGA IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_rngaIrqId[] = RNG_IRQS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + + diff --git a/KSDK_1.2.0/platform/drivers/src/rnga/fsl_rnga_driver.c b/KSDK_1.2.0/platform/drivers/src/rnga/fsl_rnga_driver.c new file mode 100755 index 0000000..853bf81 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/rnga/fsl_rnga_driver.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_rnga_driver.h" +#include "fsl_interrupt_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_RNG_COUNT + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************* + * + * Function Name: RNGA_DRV_Init + * Description: This function is used to initialize the RNGA + * + *END*************************************************************************/ +rnga_status_t RNGA_DRV_Init(uint32_t instance, const rnga_user_config_t *config) +{ + assert(instance < RNG_INSTANCE_COUNT); + RNG_Type * base = g_rngaBase[instance]; + bool mEnable; + + if (!config) + { + return kStatus_RNGA_InvalidArgument; + } + /* Enable the clock gate from clock manager. */ + mEnable = CLOCK_SYS_GetRngaGateCmd(instance); + if (!mEnable) + { + CLOCK_SYS_EnableRngaClock(instance); + } + /* Reset the registers for RNGA module to reset state. */ + RNGA_HAL_Init(base); + RNGA_HAL_SetIntMaskCmd(base, config->isIntMasked); + RNGA_HAL_SetHighAssuranceCmd(base, config->highAssuranceEnable); + RNGA_HAL_Enable(base); + + return kStatus_RNGA_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name: RNGA_DRV_Deinit + * Description: This function is used to shut down the RNGA. + * + *END*************************************************************************/ +void RNGA_DRV_Deinit(uint32_t instance) +{ + assert(instance < RNG_INSTANCE_COUNT); + RNG_Type * base = g_rngaBase[instance]; + + RNGA_HAL_Disable(base); + CLOCK_SYS_DisableRngaClock(instance); +} + +/*FUNCTION********************************************************************* + * + * Function Name: RNGA_DRV_IRQHandler + * Description: This function is used to handle error interrupt caused by RNGA underflow. + * + *END*************************************************************************/ +void RNGA_DRV_IRQHandler(uint32_t instance) +{ + assert(instance < RNG_INSTANCE_COUNT); + RNG_Type * base = g_rngaBase[instance]; + RNGA_HAL_ClearIntFlag(base, true); + RNGA_HAL_GetOutputRegUnderflowCmd(base); + RNGA_HAL_GetLastReadStatusCmd(base); +} +#endif + +/******************************************************************************* + * EOF + *******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/rnga/fsl_rnga_irq.c b/KSDK_1.2.0/platform/drivers/src/rnga/fsl_rnga_irq.c new file mode 100755 index 0000000..0a15221 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/rnga/fsl_rnga_irq.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_rnga_driver.h" +#if FSL_FEATURE_SOC_RNG_COUNT + +/****************************************************************************** + * Code + *****************************************************************************/ +/* RNGA_IRQHandler IRQ handler that would cover the same name's APIs in startup code */ +void RNG_IRQHandler(void) +{ + RNGA_DRV_IRQHandler(0); +} +#endif + +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/rnga/fsl_rnga_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/rnga/fsl_rnga_lpm_callback.c new file mode 100755 index 0000000..555bec4 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/rnga/fsl_rnga_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_RNG_COUNT + +power_manager_error_code_t rnga_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t rnga_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/rtc/fsl_rtc_common.c b/KSDK_1.2.0/platform/drivers/src/rtc/fsl_rtc_common.c new file mode 100755 index 0000000..bde85ee --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/rtc/fsl_rtc_common.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_RTC_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for RTC instances. */ +RTC_Type * const g_rtcBase[RTC_INSTANCE_COUNT] = RTC_BASE_PTRS; + +/* Tables to save RTC IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_rtcIrqId[RTC_INSTANCE_COUNT] = RTC_IRQS; +const IRQn_Type g_rtcSecondsIrqId[RTC_INSTANCE_COUNT] = RTC_SECONDS_IRQS; + +#endif /* FSL_FEATURE_SOC_RTC_COUNT */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/rtc/fsl_rtc_driver.c b/KSDK_1.2.0/platform/drivers/src/rtc/fsl_rtc_driver.c new file mode 100755 index 0000000..c1ec0b1 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/rtc/fsl_rtc_driver.c @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <string.h> +#include "fsl_rtc_driver.h" +#include "fsl_clock_manager.h" + +#if FSL_FEATURE_SOC_RTC_COUNT + +/*! + * @addtogroup rtc_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! Stores state of the RTC alarm when repeated periodically */ +static rtc_repeat_alarm_state_t *s_rtcRepeatAlarmState = NULL; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_Init + * Description : Initializes the Real Time Clock module + * This function will initialize the Real Time Clock module. + * + *END**************************************************************************/ + +rtc_status_t RTC_DRV_Init(uint32_t instance) +{ + RTC_Type *rtcBase = g_rtcBase[instance]; + + /* Enable clock gate to RTC module */ + CLOCK_SYS_EnableRtcClock(0U); + + /* Initialize the general configuration for RTC module.*/ + RTC_HAL_Init(rtcBase); + RTC_HAL_Enable(rtcBase); + + NVIC_ClearPendingIRQ(g_rtcIrqId[instance]); + NVIC_ClearPendingIRQ(g_rtcSecondsIrqId[instance]); + INT_SYS_EnableIRQ(g_rtcIrqId[instance]); + INT_SYS_EnableIRQ(g_rtcSecondsIrqId[instance]); + + return kStatusRtcSuccess; +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_Deinit + * Description : Disable RTC module clock gate control + * This function will disable clock gate to RTC module. + * + *END**************************************************************************/ +void RTC_DRV_Deinit(uint32_t instance) +{ + /* Disable RTC interrupts.*/ + INT_SYS_DisableIRQ(g_rtcIrqId[instance]); + INT_SYS_DisableIRQ(g_rtcSecondsIrqId[instance]); + + /* Disable the RTC counter */ + RTC_HAL_Disable(g_rtcBase[instance]); + + /* Disable clock gate to RTC module */ + CLOCK_SYS_DisableRtcClock(0U); + s_rtcRepeatAlarmState = NULL; +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_IsCounterEnabled + * Description : Checks whether the RTC is enabled. + * The function checks the TCE bit in the RTC control register. + * + *END**************************************************************************/ +bool RTC_DRV_IsCounterEnabled(uint32_t instance) +{ + return RTC_HAL_IsCounterEnabled(g_rtcBase[instance]); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_SetDatetime + * Description : Sets the RTC date and time according to the given time struct. + * This function will set the RTC date and time according to the given time + * struct, if start_after_set is true, the RTC oscillator will be enabled and + * the counter will start. + * + *END**************************************************************************/ +bool RTC_DRV_SetDatetime(uint32_t instance, rtc_datetime_t *datetime) +{ + assert(datetime); + RTC_Type *rtcBase = g_rtcBase[instance]; + uint32_t srcClock = 0; + uint32_t seconds = 0; + uint16_t preScaler = 0; + uint64_t tmp = 0; + + /* Return error if the time provided is not valid */ + if (!(RTC_HAL_IsDatetimeCorrectFormat(datetime))) + { + return false; + } + + RTC_HAL_ConvertDatetimeToSecs(datetime, &seconds); + + if ((srcClock = CLOCK_SYS_GetRtcFreq(0U)) != 32768U) + { + /* As the seconds register will not increment every second, we need to adjust the value + * programmed to the seconds register */ + tmp = (uint64_t)seconds * (uint64_t)srcClock; + preScaler = (uint32_t)(tmp & 0x7FFFU); + seconds = (uint32_t)(tmp >> 15U); + } + /* Set time in seconds */ + RTC_HAL_EnableCounter(rtcBase, false); + /* Set seconds counter*/ + RTC_HAL_SetSecsReg(rtcBase, seconds); + /* Set time counter*/ + RTC_HAL_SetPrescaler(rtcBase, preScaler); + /* Enable the counter*/ + RTC_HAL_EnableCounter(rtcBase, true); + return true; +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_GetDatetime + * Description : Gets the actual RTC time and stores it in the given time struct. + * This function will get the actual RTC time and stores it in the given time + * struct. + * + *END**************************************************************************/ +void RTC_DRV_GetDatetime(uint32_t instance, rtc_datetime_t *datetime) +{ + assert(datetime); + + RTC_Type *rtcBase = g_rtcBase[instance]; + uint32_t seconds = 0; + uint32_t srcClock = 0; + uint64_t tmp = 0; + + RTC_HAL_GetDatetimeInSecs(rtcBase, &seconds); + + if ((srcClock = CLOCK_SYS_GetRtcFreq(0U)) != 32768U) + { + /* In case the input clock to the RTC counter is not 32KHz, the seconds register will not + * increment every second, therefore the seconds register value needs to be adjusted. + * to get actual seconds. We then add the prescaler register value to the seconds. + */ + tmp = (uint64_t)seconds << 15U; + tmp |= (uint64_t)(RTC_HAL_GetPrescaler(rtcBase) & 0x7FFFU); + seconds = tmp / srcClock; + } + RTC_HAL_ConvertSecsToDatetime(&seconds, datetime); +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_SetSecsIntCmd + * Description : Enables or disables the RTC seconds interrupt. + * + *END**************************************************************************/ +void RTC_DRV_SetSecsIntCmd(uint32_t instance, bool secondsEnable) +{ + RTC_HAL_SetSecsIntCmd(g_rtcBase[instance], secondsEnable); +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_SetAlarm + * Description : sets the RTC alarm. + * This function will first check if the date time has correct format. If yes, + * convert the date time to seconds, and set the alarm in seconds. + * + *END**************************************************************************/ +bool RTC_DRV_SetAlarm(uint32_t instance, rtc_datetime_t *alarmTime, bool enableAlarmInterrupt) +{ + assert(alarmTime); + + RTC_Type *rtcBase = g_rtcBase[instance]; + uint32_t srcClock = 0; + uint32_t alrmSeconds = 0; + uint32_t currSeconds = 0; + uint64_t tmp = 0; + + /* Return error if the alarm time provided is not valid */ + if (!(RTC_HAL_IsDatetimeCorrectFormat(alarmTime))) + { + return false; + } + + RTC_HAL_ConvertDatetimeToSecs(alarmTime, &alrmSeconds); + + /* Get the current time */ + currSeconds = RTC_HAL_GetSecsReg(rtcBase); + + if ((srcClock = CLOCK_SYS_GetRtcFreq(instance)) != 32768U) + { + /* As the seconds register will not increment every second, we need to adjust the value + * programmed to the alarm register */ + tmp = (uint64_t)alrmSeconds * (uint64_t)srcClock; + alrmSeconds = (uint32_t)(tmp >> 15U); + } + + /* Make sure the alarm is for a future time */ + if (alrmSeconds < currSeconds) + { + return false; + } + + /* set alarm in seconds*/ + RTC_HAL_SetAlarmReg(rtcBase, alrmSeconds); + + /* Activate or deactivate the Alarm interrupt based on user choice */ + RTC_HAL_SetAlarmIntCmd(rtcBase, enableAlarmInterrupt); + + return true; +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_GetAlarm + * Description : returns the RTC alarm time. + * This function will first get alarm time in seconds, then convert the seconds to + * date time. + * + *END**************************************************************************/ +void RTC_DRV_GetAlarm(uint32_t instance, rtc_datetime_t *date) +{ + assert(date); + + uint32_t alrmSeconds = 0; + uint32_t srcClock = 0; + + /* Get alarm in seconds */ + alrmSeconds = RTC_HAL_GetAlarmReg(g_rtcBase[instance]); + + if ((srcClock = CLOCK_SYS_GetRtcFreq(0U)) != 32768U) + { + /* Re-adjust the alarm value to match the method used to program it */ + alrmSeconds = (alrmSeconds * (32768U / srcClock)); + } + + RTC_HAL_ConvertSecsToDatetime(&alrmSeconds, date); +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_InitRepeatAlarm + * Description : Initializes the RTC repeat alarm state structure. + * The RTC driver uses this user-provided structure to store the alarm state + * information. + * + *END**************************************************************************/ +void RTC_DRV_InitRepeatAlarm(uint32_t instance, rtc_repeat_alarm_state_t *repeatAlarmState) +{ + assert(repeatAlarmState); + + /* Init driver repeat alarm struct.*/ + memset(repeatAlarmState, 0, sizeof(*repeatAlarmState)); + s_rtcRepeatAlarmState = repeatAlarmState; +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_SetAlarmRepeat + * Description : Sets an alarm that is periodically repeated. + * + *END**************************************************************************/ +bool RTC_DRV_SetAlarmRepeat(uint32_t instance, rtc_datetime_t *alarmTime, rtc_datetime_t *alarmRepInterval) +{ + assert(s_rtcRepeatAlarmState); + assert(alarmRepInterval); + + if (!(RTC_DRV_SetAlarm(instance, alarmTime, true))) + { + return false; + } + + memcpy(&s_rtcRepeatAlarmState->alarmTime, alarmTime, sizeof(*alarmTime)); + memcpy(&s_rtcRepeatAlarmState->alarmRepTime, alarmRepInterval, sizeof(*alarmRepInterval)); + + return true; +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_DeinitRepeatAlarm + * Description : De-initializes the RTC repeat alarm state structure. + * + *END**************************************************************************/ +void RTC_DRV_DeinitRepeatAlarm(uint32_t instance) +{ + s_rtcRepeatAlarmState = NULL; +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_SetAlarmIntCmd + * Description : Enables or disables the alarm interrupt. + * + *END**************************************************************************/ +void RTC_DRV_SetAlarmIntCmd(uint32_t instance, bool alarmEnable) +{ + RTC_HAL_SetAlarmIntCmd(g_rtcBase[instance], alarmEnable); +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_GetAlarmIntCmd + * Description : Reads the alarm interrupt. + * + *END**************************************************************************/ +bool RTC_DRV_GetAlarmIntCmd(uint32_t instance) +{ + return RTC_HAL_ReadAlarmInt(g_rtcBase[instance]); +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_IsAlarmPending + * Description : Reads the alarm status to see if the alarm has triggered. + * + *END**************************************************************************/ +bool RTC_DRV_IsAlarmPending(uint32_t instance) +{ + /* Return alarm time and status (triggered or not) */ + return RTC_HAL_HasAlarmOccured(g_rtcBase[instance]); +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_SetTimeCompensation + * Description : Writes the compensation value to the RTC compensation register. + * + *END**************************************************************************/ +void RTC_DRV_SetTimeCompensation(uint32_t instance, uint32_t compensationInterval, + uint32_t compensationTime) +{ + RTC_Type *rtcBase = g_rtcBase[instance]; + + RTC_HAL_SetCompensationIntervalRegister(rtcBase, compensationInterval); + RTC_HAL_SetTimeCompensationRegister(rtcBase, compensationTime); +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_GetTimeCompensation + * Description : Reads the compensation value from the RTC compensation register. + * + *END**************************************************************************/ +void RTC_DRV_GetTimeCompensation(uint32_t instance, uint32_t *compensationInterval, + uint32_t *compensationTime) +{ + RTC_Type *rtcBase = g_rtcBase[instance]; + + *compensationInterval = RTC_HAL_GetCompensationIntervalCounter(rtcBase); + *compensationTime = RTC_HAL_GetTimeCompensationValue(rtcBase); +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_AlarmIntAction + * Description : Action to take when an RTC alarm interrupt is triggered. To receive + * alarms periodically, the RTC_TAR register is updated using the repeat interval. + * + *END**************************************************************************/ +void RTC_DRV_AlarmIntAction(uint32_t instance) +{ + RTC_Type *rtcBase = g_rtcBase[instance]; + + if (s_rtcRepeatAlarmState != NULL) + { + s_rtcRepeatAlarmState->alarmTime.year += s_rtcRepeatAlarmState->alarmRepTime.year; + s_rtcRepeatAlarmState->alarmTime.month += s_rtcRepeatAlarmState->alarmRepTime.month; + s_rtcRepeatAlarmState->alarmTime.day += s_rtcRepeatAlarmState->alarmRepTime.day; + s_rtcRepeatAlarmState->alarmTime.hour += s_rtcRepeatAlarmState->alarmRepTime.hour; + s_rtcRepeatAlarmState->alarmTime.minute += s_rtcRepeatAlarmState->alarmRepTime.minute; + RTC_DRV_SetAlarm(instance, &s_rtcRepeatAlarmState->alarmTime, true); + } + else + { + /* Writing to the alarm register clears the TAF flag in the Status register */ + RTC_HAL_SetAlarmReg(rtcBase, 0x0); + RTC_HAL_SetAlarmIntCmd(rtcBase, false); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_SecsIntAction + * Description : Action to take when an RTC seconds interrupt is triggered. + * Disables the time seconds interrupt (TSIE) bit. + * + *END**************************************************************************/ +void RTC_DRV_SecsIntAction(uint32_t instance) +{ + RTC_HAL_SetSecsIntCmd(g_rtcBase[instance], false); +} + +#if FSL_FEATURE_RTC_HAS_MONOTONIC + +/*FUNCTION********************************************************************** + * + * Function Name : RTC_DRV_IncrementMonotonic + * Description : Increments monotonic counter by one. + * This function will increment monotonic counter by one. + * + *END**************************************************************************/ +bool RTC_DRV_IncrementMonotonic(uint32_t instance) +{ + return RTC_HAL_IncrementMonotonicCounter(g_rtcBase[instance]); +} +#endif + +/*! @}*/ + +#endif /* FSL_FEATURE_SOC_RTC_COUNT */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/rtc/fsl_rtc_irq.c b/KSDK_1.2.0/platform/drivers/src/rtc/fsl_rtc_irq.c new file mode 100755 index 0000000..4eb5a50 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/rtc/fsl_rtc_irq.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_rtc_driver.h" + +/*! + * @addtogroup rtc_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/* + * Implementation of RTC IRQ handler with the same name in startup code + */ +void RTC_IRQHandler(void) +{ + RTC_DRV_AlarmIntAction(0); + /* Add user-defined handling for the RTC alarm */ +} + +/* + * Implementation of RTC handler named in startup code. + */ +void RTC_Seconds_IRQHandler(void) +{ + RTC_DRV_SecsIntAction(0); + /* Add user-defined handling for the per second RTC interrupt */ +} + +/*! @}*/ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/rtc/fsl_rtc_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/rtc/fsl_rtc_lpm_callback.c new file mode 100755 index 0000000..51dcde5 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/rtc/fsl_rtc_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t rtc_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t rtc_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/sai/fsl_sai_common.c b/KSDK_1.2.0/platform/drivers/src/sai/fsl_sai_common.c new file mode 100755 index 0000000..ef7dec7 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/sai/fsl_sai_common.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for SAI instances. */ +I2S_Type * const g_saiBase[I2S_INSTANCE_COUNT] = I2S_BASE_PTRS; + +/* Table to save sai IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_saiTxIrqId[I2S_INSTANCE_COUNT] = I2S_TX_IRQS; +const IRQn_Type g_saiRxIrqId[I2S_INSTANCE_COUNT] = I2S_RX_IRQS; + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/sai/fsl_sai_driver.c b/KSDK_1.2.0/platform/drivers/src/sai/fsl_sai_driver.c new file mode 100755 index 0000000..c5b953e --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/sai/fsl_sai_driver.c @@ -0,0 +1,866 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_sai_driver.h" +#include "fsl_interrupt_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_I2S_COUNT + +/******************************************************************************* + *Definition + ******************************************************************************/ +sai_state_t * volatile sai_state_ids[I2S_INSTANCE_COUNT][2]; + +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL +/* EDMA callback function */ +void SAI_DRV_EdmaCallback(void *param, edma_chn_status_t status); +#else +void SAI_DRV_DmaCallback(void *param, dma_channel_status_t status); +#endif + + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_TxInit + * Description : Initialize sai tx module, and initialize sai state. + * + *END**************************************************************************/ +sai_status_t SAI_DRV_TxInit(uint32_t instance, sai_user_config_t * config, sai_state_t *state) +{ + I2S_Type * reg_base = g_saiBase[instance]; + /* Open clock gate for sai instance */ + CLOCK_SYS_EnableSaiClock(instance); + /*Check if the device is busy */ + if(sai_state_ids[instance][0] != NULL) + { + return kStatus_SAI_DeviceBusy; + } + sai_state_ids[instance][0] = state; + SAI_HAL_TxInit(reg_base); + /* Mclk source select */ + if (config->slave_master == kSaiMaster) + { + SAI_HAL_SetMclkSrc(reg_base, config->mclk_source); + SAI_HAL_TxSetBclkSrc(reg_base, config->bclk_source); + } + SAI_HAL_TxSetSyncMode(reg_base, config->sync_mode); + SAI_HAL_TxSetMasterSlave(reg_base, config->slave_master); + SAI_HAL_TxSetProtocol(reg_base, config->protocol); + SAI_HAL_TxSetDataChn(reg_base, config->channel); +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + SAI_HAL_TxSetWatermark(reg_base, config->watermark); +#endif + + /* Fill the state structure */ + sai_state_ids[instance][0]->sync_mode = config->sync_mode; + sai_state_ids[instance][0]->fifo_channel = config->channel; + sai_state_ids[instance][0]->dma_source = config->dma_source; +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + sai_state_ids[instance][0]->watermark = config->watermark; +#endif + sai_state_ids[instance][0]->master_slave = config->slave_master; + OSA_SemaCreate(&state->sem, 0); + INT_SYS_EnableIRQ(g_saiTxIrqId[instance]); + + return kStatus_SAI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_RxInit + * Description : Initialize sai rx module, and initialize sai state. + * + *END**************************************************************************/ +sai_status_t SAI_DRV_RxInit(uint32_t instance, sai_user_config_t * config, sai_state_t *state) +{ + I2S_Type * reg_base = g_saiBase[instance]; + /* Open clock gate for sai instance */ + CLOCK_SYS_EnableSaiClock(instance); + /*Check if the device is busy */ + if(sai_state_ids[instance][1] != NULL) + { + return kStatus_SAI_DeviceBusy; + } + sai_state_ids[instance][1] = state; + SAI_HAL_RxInit(reg_base); + /* Mclk source select */ + if (config->slave_master == kSaiMaster) + { + SAI_HAL_SetMclkSrc(reg_base, config->mclk_source); + SAI_HAL_RxSetBclkSrc(reg_base, config->bclk_source); + } + SAI_HAL_RxSetSyncMode(reg_base, config->sync_mode); + SAI_HAL_RxSetMasterSlave(reg_base, config->slave_master); + SAI_HAL_RxSetProtocol(reg_base, config->protocol); + SAI_HAL_RxSetDataChn(reg_base, config->channel); +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + SAI_HAL_RxSetWatermark(reg_base, config->watermark); +#endif + /* Fill the state structure */ + sai_state_ids[instance][1]->sync_mode = config->sync_mode; + sai_state_ids[instance][1]->fifo_channel = config->channel; + sai_state_ids[instance][1]->dma_source = config->dma_source; +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + sai_state_ids[instance][1]->watermark = config->watermark; +#endif + sai_state_ids[instance][1]->master_slave = config->slave_master; + OSA_SemaCreate(&state->sem, 0); + INT_SYS_EnableIRQ(g_saiRxIrqId[instance]); + + return kStatus_SAI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_TxGetDefaultSetting + * Description : Get default settings for sai tx module. + * + *END**************************************************************************/ +void SAI_DRV_TxGetDefaultSetting(sai_user_config_t * config) +{ + config->bclk_source = kSaiBclkSourceMclkDiv; + config->channel = 0; + config->mclk_source = kSaiMclkSourceSysclk; + config->protocol = kSaiBusI2SType; + config->slave_master = kSaiMaster; +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + config->watermark = 4; +#endif + config->sync_mode = kSaiModeAsync; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_RxGetDefaultSetting + * Description : Get default settings for sai rx module. + * + *END**************************************************************************/ +void SAI_DRV_RxGetDefaultSetting(sai_user_config_t * config) +{ + config->bclk_source = kSaiBclkSourceMclkDiv; + config->channel = 0; + config->mclk_source = kSaiMclkSourceSysclk; + config->protocol = kSaiBusI2SType; + config->slave_master = kSaiMaster; +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + config->watermark = 4; +#endif + config->sync_mode = kSaiModeSync; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_TxDeinit + * Description :Deinit the sai tx module, free the resources. + * + *END**************************************************************************/ +sai_status_t SAI_DRV_TxDeinit(uint32_t instance) +{ + I2S_Type * reg_base = g_saiBase[instance]; + SAI_DRV_TxSetDmaCmd(instance, false); + SAI_DRV_TxSetIntCmd(instance, false); + SAI_HAL_TxDisable(reg_base); + SAI_HAL_TxSetReset(reg_base, kSaiResetTypeSoftware); + SAI_HAL_TxClearStateFlag(reg_base, kSaiStateFlagSoftReset); + /* Release dma channel */ + if (sai_state_ids[instance][0]->use_dma) + { +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + EDMA_DRV_StopChannel(&sai_state_ids[instance][0]->edma_chn); + EDMA_DRV_ReleaseChannel(&sai_state_ids[instance][0]->edma_chn); +#else + DMA_DRV_FreeChannel(&sai_state_ids[instance][0]->chn); +#endif + } + /* Destory sem */ + OSA_SemaDestroy(&sai_state_ids[instance][0]->sem); + sai_state_ids[instance][0] = NULL; + /* Check if need to close the clock gate */ + if ((sai_state_ids[instance][0] == NULL) && (sai_state_ids[instance][1] == NULL)) + { + CLOCK_SYS_DisableSaiClock(instance); + } + return kStatus_SAI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_RxDeinit + * Description :Deinit the sai rx module, free the resources. + * + *END**************************************************************************/ +sai_status_t SAI_DRV_RxDeinit(uint32_t instance) +{ + I2S_Type * reg_base = g_saiBase[instance]; + SAI_DRV_RxSetDmaCmd(instance, false); + SAI_DRV_RxSetIntCmd(instance, false); + SAI_HAL_RxDisable(reg_base); + SAI_HAL_RxSetReset(reg_base, kSaiResetTypeSoftware); + SAI_HAL_RxClearStateFlag(reg_base, kSaiStateFlagSoftReset); + /* Release dma channel */ + if (sai_state_ids[instance][1]->use_dma) + { +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + EDMA_DRV_ReleaseChannel(&sai_state_ids[instance][1]->edma_chn); +#else + DMA_DRV_FreeChannel(&sai_state_ids[instance][1]->chn); +#endif + } + /* Destory sem */ + OSA_SemaDestroy(&sai_state_ids[instance][1]->sem); + + sai_state_ids[instance][1] = NULL; + /* Check if need to close the clock gate */ + if ((sai_state_ids[instance][0] == NULL) && (sai_state_ids[instance][1] == NULL)) + { + CLOCK_SYS_DisableSaiClock(instance); + } + return kStatus_SAI_Success; +} + +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_TxSetWatermark + * Description :Set the watermark value of sai tx. + * + *END**************************************************************************/ +void SAI_DRV_TxSetWatermark(uint32_t instance,uint32_t watermark) +{ + I2S_Type * reg_base = g_saiBase[instance]; + SAI_HAL_TxSetWatermark(reg_base,watermark); + sai_state_ids[instance][0]->watermark = watermark; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_RxSetWatermark + * Description :Set the watermark value of sai rx. + * + *END**************************************************************************/ +void SAI_DRV_RxSetWatermark(uint32_t instance,uint32_t watermark) +{ + I2S_Type * reg_base = g_saiBase[instance]; + SAI_HAL_RxSetWatermark(reg_base,watermark); + sai_state_ids[instance][1]->watermark = watermark; +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_TxConfigDataFormat + * Description :Configure audio format information of tx. + * The audio format information includes the sample rate, data length and so on. + *END**************************************************************************/ +sai_status_t SAI_DRV_TxConfigDataFormat(uint32_t instance, sai_data_format_t *format) +{ + I2S_Type * reg_base = g_saiBase[instance]; + memcpy(&sai_state_ids[instance][0]->format, format, sizeof(sai_data_format_t)); + if(sai_state_ids[instance][0]->master_slave == kSaiMaster) + { + uint32_t bclk = format->sample_rate * format->bits * 2; + uint8_t divider; + if(SAI_HAL_TxGetBclkSrc(reg_base) == 0) + { + divider = (CLOCK_SYS_GetBusClockFreq())/bclk; + } + else + { + divider = format->mclk/bclk; + } +#if FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER + uint32_t frequency = 0; + /* Get the clock source frequency */ + uint32_t mclk_sel = SAI_HAL_GetMclkSrc(reg_base); + frequency = CLOCK_SYS_GetSaiFreq(instance, (clock_sai_src_t)mclk_sel); + /* Configure master clock */ + SAI_HAL_SetMclkDiv(reg_base, format->mclk, frequency); +#endif + /* Master clock and bit clock setting */ + SAI_HAL_TxSetBclkDiv(reg_base, divider); + } + SAI_HAL_TxSetWordWidth(reg_base, sai_state_ids[instance][0]->protocol, format->bits); + /* The channel number configuration */ + SAI_HAL_TxSetMonoStereo(reg_base, format->mono_stereo); + + return kStatus_SAI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_RxConfigDataFormat + * Description :Configure audio format information of rx. + * The audio format information includes the sample rate, data length and so on. + *END**************************************************************************/ +sai_status_t SAI_DRV_RxConfigDataFormat(uint32_t instance, sai_data_format_t *format) +{ + I2S_Type * reg_base = g_saiBase[instance]; + + memcpy(&sai_state_ids[instance][1]->format, format, sizeof(sai_data_format_t)); + if(sai_state_ids[instance][1]->master_slave == kSaiMaster) + { + uint32_t bclk = format->sample_rate * format->bits * 2; + uint8_t divider; + if(SAI_HAL_RxGetBclkSrc(reg_base) == 0) + { + divider = (CLOCK_SYS_GetBusClockFreq())/bclk; + } + else + { + divider = format->mclk/bclk; + } +#if FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER + uint32_t frequency = 0; + /* Get the clock source frequency */ + uint32_t mclk_sel = SAI_HAL_GetMclkSrc(reg_base); + frequency = CLOCK_SYS_GetSaiFreq(instance, (clock_sai_src_t)mclk_sel); + /* Configure master clock */ + SAI_HAL_SetMclkDiv(reg_base, format->mclk, frequency); +#endif + /* Master clock and bit clock setting */ + SAI_HAL_RxSetBclkDiv(reg_base, divider); + } + SAI_HAL_RxSetWordWidth(reg_base, sai_state_ids[instance][1]->protocol, format->bits); + /* The channel number configuration */ + SAI_HAL_RxSetMonoStereo(reg_base, format->mono_stereo); + return kStatus_SAI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_TxStartModule + * Description : Start the writing process. + * + *END**************************************************************************/ +void SAI_DRV_TxStartModule(uint32_t instance) +{ + I2S_Type * reg_base = g_saiBase[instance]; + /* If the sync mode is synchronous, it will need Rx enable bit clock */ + if(sai_state_ids[instance][0]->sync_mode == kSaiModeSync) + { + SAI_HAL_TxEnable(reg_base); + SAI_HAL_RxEnable(reg_base); + } + else + { + SAI_HAL_TxEnable(reg_base); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_RxStartModule + * Description : Start the reading process. + * + *END**************************************************************************/ +void SAI_DRV_RxStartModule(uint32_t instance) +{ + I2S_Type * reg_base = g_saiBase[instance]; + /* If the sync mode is synchronous, it will need Tx enable bit clock */ + if(sai_state_ids[instance][1]->sync_mode == kSaiModeSync) + { + SAI_HAL_RxEnable(reg_base); + SAI_HAL_TxEnable(reg_base); + } + else + { + SAI_HAL_RxEnable(reg_base); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_TxIRQHandler + * Description : The interrupt handle of tx FIFO request or FIFO warning. + * The interrupt handle is used to transfer data from sai buffer to sai fifo. + *END**************************************************************************/ +void SAI_DRV_TxIRQHandler(uint32_t instance) +{ + I2S_Type * reg_base = g_saiBase[instance]; + uint8_t data_size = 0; + uint8_t i = 0; + sai_data_format_t format = sai_state_ids[instance][0]->format; + uint32_t data = 0, temp = 0; + uint32_t len = sai_state_ids[instance][0]->len; + uint32_t count = sai_state_ids[instance][0]->count; + + data_size = format.bits/8; + if((data_size == 3) || (format.bits & 0x7)) + { + data_size = 4; + } + + /* Judge if FIFO error */ + if(SAI_HAL_TxGetStateFlag(reg_base, kSaiStateFlagFIFOError)) + { + SAI_HAL_TxClearStateFlag(reg_base, kSaiStateFlagFIFOError); + } +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + uint8_t j = 0; + /* Interrupt used to transfer data. */ + if((SAI_HAL_TxGetStateFlag(reg_base, kSaiStateFlagFIFORequest)) && + (!sai_state_ids[instance][0]->use_dma)) + { + uint32_t watermark = sai_state_ids[instance][0]->watermark; + uint8_t space = FSL_FEATURE_SAI_FIFO_COUNT - watermark; + /*Judge if the data need to transmit is less than space */ + if(space > (len -count)/data_size) + { + space = (len -count)/data_size; + } + /* If normal, copy the data from sai buffer to FIFO */ + for(i = 0; i < space; i++) + { + for(j = 0; j < data_size; j ++) + { + temp = (uint32_t)(*sai_state_ids[instance][0]->address); + data |= (temp << (8U * j)); + sai_state_ids[instance][0]->address ++; + } + SAI_HAL_SendData(reg_base, sai_state_ids[instance][0]->fifo_channel, (uint32_t )data); + sai_state_ids[instance][0]->count += data_size; + data = 0; + } + /* If a block is finished, just callback */ + count = sai_state_ids[instance][0]->count; + if(count == len) + { + void * callback_param = sai_state_ids[instance][0]->callback_param; + sai_state_ids[instance][0]->count = 0; + sai_state_ids[instance][0]->len = 0; + if (sai_state_ids[instance][0]->callback) + { + (sai_state_ids[instance][0]->callback)(callback_param); + } + else + { + SAI_HAL_TxSetIntCmd(reg_base, kSaiIntrequestFIFORequest, false); + } + } + } +#else + if((SAI_HAL_TxGetStateFlag(reg_base, kSaiStateFlagFIFOWarning)) && + (!sai_state_ids[instance][0]->use_dma)) + { + for(i = 0; i < data_size; i ++) + { + temp = (uint32_t)(*sai_state_ids[instance][0]->address); + data |= (temp << (8U * i)); + sai_state_ids[instance][0]->address ++; + } + SAI_HAL_SendData(reg_base,sai_state_ids[instance][0]->fifo_channel, (uint32_t)data); + sai_state_ids[instance][0]->count += data_size; + count = sai_state_ids[instance][0]->count; + if(count == len) + { + void * callback_param = sai_state_ids[instance][0]->callback_param; + sai_state_ids[instance][0]->count = 0; + sai_state_ids[instance][0]->len = 0; + OSA_SemaPost(&sai_state_ids[instance][0]->sem); + if (sai_state_ids[instance][0]->callback) + { + (sai_state_ids[instance][0]->callback)(callback_param); + } + else + { + SAI_HAL_TxSetIntCmd(reg_base, kSaiIntrequestFIFOWarning, false); + } + } + } +#endif +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_RxIRQHandler + * Description : The interrupt handle of rx FIFO request or FIFO warning. + * The interrupt handle is used to transfer data from sai fifo to sai buffer. + *END**************************************************************************/ +void SAI_DRV_RxIRQHandler(uint32_t instance) +{ + I2S_Type * reg_base = g_saiBase[instance]; + uint8_t i = 0; + uint8_t data_size = 0; + uint32_t data = 0; + sai_data_format_t format = sai_state_ids[instance][1]->format; + uint32_t len = sai_state_ids[instance][1]->len; + uint32_t count = sai_state_ids[instance][1]->count; + + data_size = format.bits/8; + if((data_size == 3) || (format.bits & 0x7)) + { + data_size = 4; + } + + /* Judge if FIFO error */ + if(SAI_HAL_RxGetStateFlag(reg_base, kSaiStateFlagFIFOError)) + { + SAI_HAL_RxClearStateFlag(reg_base, kSaiStateFlagFIFOError); + } +#if (FSL_FEATURE_SAI_FIFO_COUNT > 1) + uint8_t j = 0; + /* Interrupt used to transfer data. */ + if((SAI_HAL_RxGetStateFlag(reg_base, kSaiStateFlagFIFORequest)) && + (!sai_state_ids[instance][1]->use_dma)) + { + uint8_t space = sai_state_ids[instance][1]->watermark; + /*Judge if the data need to transmit is less than space */ + if(space > (len - count)/data_size) + { + space = (len -count)/data_size; + } + /* Read data from FIFO to the buffer */ + for (i = 0; i < space; i ++) + { + data = SAI_HAL_ReceiveData(reg_base, sai_state_ids[instance][1]->fifo_channel); + for(j = 0; j < data_size; j ++) + { + *sai_state_ids[instance][1]->address = (data >> (8U * j)) & 0xFF; + sai_state_ids[instance][1]->address ++; + } + sai_state_ids[instance][1]->count += data_size; + } + /* If need to callback the function */ + count = sai_state_ids[instance][1]->count; + if (count == len) + { + void *callback_param = sai_state_ids[instance][1]->callback_param; + sai_state_ids[instance][1]->count = 0; + sai_state_ids[instance][1]->len = 0; + if (sai_state_ids[instance][1]->callback) + { + (sai_state_ids[instance][1]->callback)(callback_param); + } + else + { + SAI_HAL_RxSetIntCmd(reg_base, kSaiIntrequestFIFORequest,false); + } + } + } +#else + if((SAI_HAL_RxGetStateFlag(reg_base, kSaiStateFlagFIFOWarning)) && + (!sai_state_ids[instance][1]->use_dma)) + { + data = SAI_HAL_ReceiveData(reg_base, sai_state_ids[instance][1]->fifo_channel); + for(i = 0; i < data_size; i ++) + { + *sai_state_ids[instance][1]->address = (data >> (8U * i)) & 0xFF; + sai_state_ids[instance][1]->address ++; + } + sai_state_ids[instance][1]->count += data_size; + count = sai_state_ids[instance][1]->count; + if (count == len) + { + void *callback_param = sai_state_ids[instance][1]->callback_param; + sai_state_ids[instance][1]->count = 0; + sai_state_ids[instance][1]->len = 0; + OSA_SemaPost(&sai_state_ids[instance][1]->sem); + if (sai_state_ids[instance][1]->callback) + { + (sai_state_ids[instance][1]->callback)(callback_param); + } + else + { + SAI_HAL_RxSetIntCmd(reg_base, kSaiIntrequestFIFOWarning, false); + } + } + } + +#endif +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_TxRegisterCallback + * Description : The function would register the callback function to tell sai + * driver what to do after the transfer. + *END**************************************************************************/ +void SAI_DRV_TxRegisterCallback +( +uint32_t instance, +sai_callback_t callback, +void *callback_param +) +{ + sai_state_ids[instance][0]->callback = callback; + sai_state_ids[instance][0]->callback_param = callback_param; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_RxRegisterCallback + * Description : The function would register the callback function to tell sai + * driver what to do after the receive. + *END**************************************************************************/ +void SAI_DRV_RxRegisterCallback +( +uint32_t instance, +sai_callback_t callback, +void *callback_param +) +{ + sai_state_ids[instance][1]->callback = callback; + sai_state_ids[instance][1]->callback_param = callback_param; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_SendDataInt + * Description : The function would tell sai driver to start send a period of + * data to sai tx fifo. + *END**************************************************************************/ +uint32_t SAI_DRV_SendDataInt(uint32_t instance, uint8_t *addr, uint32_t len) +{ + I2S_Type * base = g_saiBase[instance]; + sai_state_ids[instance][0]->len = len; + sai_state_ids[instance][0]->address= addr; +#if FSL_FEATURE_SAI_FIFO_COUNT > 1 + SAI_HAL_TxSetIntCmd(base, kSaiIntrequestFIFOError | kSaiIntrequestFIFORequest, true); +#else + SAI_HAL_TxSetIntCmd(base, kSaiIntrequestFIFOError | kSaiIntrequestFIFOWarning, true); +#endif + SAI_DRV_TxStartModule(instance); + return len; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_ReceiveData + * Description : The function would tell sai driver to start receive a period of + * data from sai rx fifo. + *END**************************************************************************/ +uint32_t SAI_DRV_ReceiveDataInt(uint32_t instance, uint8_t *addr, uint32_t len) +{ + I2S_Type * base = g_saiBase[instance]; + sai_state_ids[instance][1]->len = len; + sai_state_ids[instance][1]->address= addr; +#if FSL_FEATURE_SAI_FIFO_COUNT > 1 + SAI_HAL_RxSetIntCmd(base, kSaiIntrequestFIFOError | kSaiIntrequestFIFORequest, true); +#else + SAI_HAL_RxSetIntCmd(base, kSaiIntrequestFIFOError | kSaiIntrequestFIFOWarning, true); +#endif + SAI_DRV_RxStartModule(instance); + return len; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_SendDatadma + * Description : The function would tell sai driver to start send a period of + * data to sai tx fifo. This function will configure and start dma. + *END**************************************************************************/ +uint32_t SAI_DRV_SendDataDma(uint32_t instance, uint8_t *addr, uint32_t len) +{ + I2S_Type * base = g_saiBase[instance]; + uint32_t bytes = sai_state_ids[instance][0]->format.bits/8; + uint32_t destAddr = SAI_HAL_TxGetFifoAddr(base,sai_state_ids[instance][0]->fifo_channel); +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + edma_chn_state_t *edma_chn = &sai_state_ids[instance][0]->edma_chn; + edma_software_tcd_t *tcd = sai_state_ids[instance][0]->tcd; + uint32_t bytesOnEachRequest = 0; +#if FSL_FEATURE_SAI_FIFO_COUNT > 1 + bytesOnEachRequest = bytes * sai_state_ids[instance][0]->watermark; +#else + bytesOnEachRequest = bytes; +#endif /* FSL_FEATURE_SAI_FIFO_COUNT > 1 */ +#else + dma_channel_t *chn = &sai_state_ids[instance][0]->chn; +#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL */ + if (!sai_state_ids[instance][0]->use_dma) + { + uint32_t ret; +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + ret = EDMA_DRV_RequestChannel(kEDMAAnyChannel, + (dma_request_source_t)sai_state_ids[instance][0]->dma_source, edma_chn); + if (ret == kEDMAInvalidChannel) + { + return kStatus_SAI_Fail; + } + EDMA_DRV_InstallCallback(edma_chn, SAI_DRV_EdmaCallback, + sai_state_ids[instance][0]); +#else + ret = DMA_DRV_RequestChannel(kDmaAnyChannel, + (dma_request_source_t)sai_state_ids[instance][0]->dma_source, chn); + if (ret == kDmaInvalidChannel) + { + return kStatus_SAI_Fail; + } + DMA_DRV_RegisterCallback(chn, SAI_DRV_DmaCallback, + sai_state_ids[instance][0]); +#endif + sai_state_ids[instance][0]->use_dma = true; + } + if (bytes == 3) + { + bytes = 4; + } + sai_state_ids[instance][0]->len = len; + sai_state_ids[instance][0]->address = addr; +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + /* Configure Edma */ + EDMA_DRV_ConfigLoopTransfer(edma_chn, tcd,kEDMAMemoryToPeripheral, + (uint32_t)addr, destAddr, bytes, bytesOnEachRequest, len, 1); + EDMA_DRV_StartChannel(&sai_state_ids[instance][0]->edma_chn); +#else + /* Configure Dma */ + DMA_DRV_ConfigTransfer(chn, kDmaMemoryToPeripheral, + bytes, (uint32_t)addr, destAddr, len); + DMA_DRV_StartChannel(&sai_state_ids[instance][0]->chn); +#endif + /* Enable DMA request */ + SAI_HAL_TxSetIntCmd(base, kSaiIntrequestFIFOError, true); +#if FSL_FEATURE_SAI_FIFO_COUNT > 1 + SAI_HAL_TxSetIntCmd(base, kSaiDmaReqFIFORequest, true); +#else + SAI_HAL_TxSetIntCmd(base, kSaiDmaReqFIFOWarning, true); +#endif + SAI_DRV_TxStartModule(instance); + return len; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_ReceiveDataDma + * Description : The function would tell sai driver to start receive a period of + * data from sai rx fifo. This function would also start dma. + *END**************************************************************************/ +uint32_t SAI_DRV_ReceiveDataDma(uint32_t instance, uint8_t *addr, uint32_t len) +{ + I2S_Type * base = g_saiBase[instance]; + uint32_t bytes = sai_state_ids[instance][1]->format.bits/8; + uint32_t srcAddr = SAI_HAL_RxGetFifoAddr(base,sai_state_ids[instance][1]->fifo_channel); +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + edma_chn_state_t *edma_chn = &sai_state_ids[instance][1]->edma_chn; + edma_software_tcd_t *tcd = sai_state_ids[instance][1]->tcd; + uint32_t bytesOnEachRequest = 0; +#if FSL_FEATURE_SAI_FIFO_COUNT > 1 + bytesOnEachRequest = bytes * sai_state_ids[instance][1]->watermark; +#else + bytesOnEachRequest = bytes; +#endif /* FSL_FEATURE_SAI_FIFO_COUNT > 1 */ +#else + dma_channel_t *chn = &sai_state_ids[instance][1]->chn; +#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL */ + if (!sai_state_ids[instance][1]->use_dma) + { + uint32_t ret; +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + ret = EDMA_DRV_RequestChannel(kEDMAAnyChannel, + (dma_request_source_t)sai_state_ids[instance][1]->dma_source, edma_chn); + if (ret == kEDMAInvalidChannel) + { + return kStatus_SAI_Fail; + } + EDMA_DRV_InstallCallback(edma_chn, SAI_DRV_EdmaCallback, + sai_state_ids[instance][1]); +#else + ret = DMA_DRV_RequestChannel(kDmaAnyChannel, + (dma_request_source_t)sai_state_ids[instance][1]->dma_source, chn); + if (ret == kDmaInvalidChannel) + { + return kStatus_SAI_Fail; + } + DMA_DRV_RegisterCallback(chn, SAI_DRV_DmaCallback, + sai_state_ids[instance][1]); +#endif + sai_state_ids[instance][1]->use_dma = true; + } + if (bytes == 3) + { + bytes = 4; + } + sai_state_ids[instance][1]->len = len; + sai_state_ids[instance][1]->address = addr; +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL + /* Configure Edma */ + EDMA_DRV_ConfigLoopTransfer(edma_chn, tcd, kEDMAPeripheralToMemory, + srcAddr, (uint32_t)addr, bytes, bytesOnEachRequest, len, 1); + EDMA_DRV_StartChannel(&sai_state_ids[instance][1]->edma_chn); +#else + /* Configure Dma */ + DMA_DRV_ConfigTransfer(chn, kDmaPeripheralToMemory, + bytes, srcAddr, (uint32_t)addr, len); + DMA_DRV_StartChannel(&sai_state_ids[instance][1]->chn); +#endif + /* Enable DMA request */ + SAI_HAL_RxSetIntCmd(base, kSaiIntrequestFIFOError, true); +#if FSL_FEATURE_SAI_FIFO_COUNT > 1 + SAI_HAL_RxSetIntCmd(base, kSaiDmaReqFIFORequest, true); +#else + SAI_HAL_RxSetIntCmd(base, kSaiDmaReqFIFOWarning, true); +#endif + SAI_DRV_RxStartModule(instance); + return len; +} + +#if defined FSL_FEATURE_EDMA_MODULE_CHANNEL +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_EdmaCallback + * Description : Callback function registered to edma, it will be called at + * the end of an edma transfer, users can register callback in this function. + *END**************************************************************************/ +void SAI_DRV_EdmaCallback(void *param, edma_chn_status_t status) +{ + sai_state_t *state = (sai_state_t *)param; + OSA_SemaPost(&state->sem); + if (state->callback) + { + (state->callback)(state->callback_param); + } +} +#else +/*FUNCTION********************************************************************** + * + * Function Name : SAI_DRV_DmaCallback + * Description : Callback function registered to edma, it will be called at + * the end of a dma transfer, users can register callback in this function. + *END**************************************************************************/ +void SAI_DRV_DmaCallback(void *param, dma_channel_status_t status) +{ + sai_state_t *state = (sai_state_t *)param; + OSA_SemaPost(&state->sem); + if (state->callback) + { + (state->callback)(state->callback_param); + } +} +#endif + +#endif + +/******************************************************************************* + * EOF + + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/sai/fsl_sai_irq.c b/KSDK_1.2.0/platform/drivers/src/sai/fsl_sai_irq.c new file mode 100755 index 0000000..2aa0286 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/sai/fsl_sai_irq.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_sai_driver.h" +#if FSL_FEATURE_SOC_I2S_COUNT + +extern sai_state_t * volatile sai_state_ids[I2S_INSTANCE_COUNT][2]; + +/************************************************************************* + * Code + ************************************************************************/ +/* I2S IRQ handler with the same name in startup code */ + +#if (FSL_FEATURE_SAI_INT_SOURCE_NUM == 1) + +void I2S0_IRQHandler(void) +{ + if (sai_state_ids[0][1] != NULL) + { + SAI_DRV_RxIRQHandler(0U); + } + if (sai_state_ids[0][0] != NULL) + { + SAI_DRV_TxIRQHandler(0U); + } +} + +#else +void I2S0_Tx_IRQHandler(void) +{ + SAI_DRV_TxIRQHandler(0U); +} + +void I2S0_Rx_IRQHandler(void) +{ + SAI_DRV_RxIRQHandler(0U); +} + +#if defined (K70F12_SERIES) +void I2S1_Tx_IRQHandler(void) +{ + SAI_DRV_TxIRQHandler(1U); +} + +void I2S1_Rx_IRQHandler(void) +{ + SAI_DRV_RxIRQHandler(1U); +} +#endif /*defined K70F12_SERIES */ +#endif /* FSL_FEATURE_SAI_INT_SPURCE_NUM */ +#endif + +/************************************************************************* + * EOF + ************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/sai/fsl_sai_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/sai/fsl_sai_lpm_callback.c new file mode 100755 index 0000000..7b9a460 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/sai/fsl_sai_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_I2S_COUNT + +power_manager_error_code_t sai_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t sai_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/sdhc/fsl_sdhc_common.c b/KSDK_1.2.0/platform/drivers/src/sdhc/fsl_sdhc_common.c new file mode 100755 index 0000000..81627cd --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/sdhc/fsl_sdhc_common.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses. */ +SDHC_Type * const g_sdhcBase[] = SDHC_BASE_PTRS; + +/*! + * @brief Table to save SDHC IRQ enum numbers defined in CMSIS files. + * + */ +const IRQn_Type g_sdhcIrqId[SDHC_INSTANCE_COUNT] = SDHC_IRQS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/sdhc/fsl_sdhc_driver.c b/KSDK_1.2.0/platform/drivers/src/sdhc/fsl_sdhc_driver.c new file mode 100755 index 0000000..9558136 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/sdhc/fsl_sdhc_driver.c @@ -0,0 +1,1626 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "fsl_os_abstraction.h" +#include "fsl_interrupt_manager.h" +#include "fsl_clock_manager.h" +#include "fsl_sdhc_hal.h" +#include "fsl_sdhc_driver.h" +#include "fsl_sdhc.h" +#if FSL_FEATURE_SOC_SDHC_COUNT + +static sdhc_host_t volatile *g_hosts[SDHC_INSTANCE_COUNT] = {0}; +#if ! defined BSP_FSL_SDHC_USING_DYNALLOC +#define BSP_FSL_SDHC_ADMA_TABLE_MAX_ENTRY 16 +static uint32_t g_AdmaTableAddress[SDHC_INSTANCE_COUNT][BSP_FSL_SDHC_ADMA_TABLE_MAX_ENTRY >> 1]; +#endif + +#define SDHC_R1_OUT_OF_RANGE ((uint32_t) 1 << 31) /*!< R1: out of range status bit */ +#define SDHC_R1_ADDRESS_ERROR (1 << 30) /*!< R1: address error status bit */ +#define SDHC_R1_BLOCK_LEN_ERROR (1 << 29) /*!< R1: block length error status bit */ +#define SDHC_R1_ERASE_SEQ_ERROR (1 << 28) /*!< R1: erase sequence error status bit */ +#define SDHC_R1_ERASE_PARAM (1 << 27) /*!< R1: erase parameter error status bit */ +#define SDHC_R1_WP_VIOLATION (1 << 26) /*!< R1: write protection violation status bit */ +#define SDHC_R1_CARD_IS_LOCKED (1 << 25) /*!< R1: card locked status bit */ +#define SDHC_R1_LOCK_UNLOCK_FAILED (1 << 24) /*!< R1: lock/unlock error status bit */ +#define SDHC_R1_COM_CRC_ERROR (1 << 23) /*!< R1: CRC error status bit */ +#define SDHC_R1_ILLEGAL_COMMAND (1 << 22) /*!< R1: illegal command status bit */ +#define SDHC_R1_CARD_ECC_FAILED (1 << 21) /*!< R1: card ecc error status bit */ +#define SDHC_R1_CC_ERROR (1 << 20) /*!< R1: internal card controller status bit */ +#define SDHC_R1_ERROR (1 << 19) /*!< R1: a general or an unknown error status bit */ +#define SDHC_R1_CID_CSD_OVERWRITE (1 << 16) /*!< R1: cid/csd overwrite status bit */ +#define SDHC_R1_WP_ERASE_SKIP (1 << 15) /*!< R1: write protection erase skip status bit */ +#define SDHC_R1_CARD_ECC_DISABLED (1 << 14) /*!< R1: card ecc disabled status bit */ +#define SDHC_R1_ERASE_RESET (1 << 13) /*!< R1: erase reset status bit */ +#define SDHC_R1_STATUS(x) ((uint32_t)(x) & 0xFFFFE000U) /*!< R1: status */ +#define SDHC_R1_READY_FOR_DATA (1 << 8) /*!< R1: ready for data status bit */ +#define SDHC_R1_SWITCH_ERROR (1 << 7) /*!< R1: switch error status bit */ +#define SDHC_R1_APP_CMD (1 << 5) /*!< R1: application command enabled status bit */ +#define SDHC_R1_AKE_SEQ_ERROR (1 << 3) /*!< R1: error in the sequence of the authentication process*/ +#define SDHC_R1_ERROR_BITS(x) (uint32_t)((x) & \ + (SDHC_R1_OUT_OF_RANGE | \ + SDHC_R1_ADDRESS_ERROR | \ + SDHC_R1_BLOCK_LEN_ERROR | \ + SDHC_R1_ERASE_SEQ_ERROR | \ + SDHC_R1_ERASE_PARAM | \ + SDHC_R1_WP_VIOLATION | \ + SDHC_R1_CARD_IS_LOCKED | \ + SDHC_R1_LOCK_UNLOCK_FAILED | \ + SDHC_R1_COM_CRC_ERROR | \ + SDHC_R1_ILLEGAL_COMMAND | \ + SDHC_R1_CARD_ECC_FAILED | \ + SDHC_R1_CC_ERROR | \ + SDHC_R1_ERROR | \ + SDHC_R1_CID_CSD_OVERWRITE | \ + SDHC_R1_AKE_SEQ_ERROR)) /*!< Check error card status */ + +#define SDHC_SD_OCR_VDD_27_28 (1 << 15) /*!< VDD 2.7-2.8 */ +#define SDHC_SD_OCR_VDD_28_29 (1 << 16) /*!< VDD 2.8-2.9 */ +#define SDHC_SD_OCR_VDD_29_30 (1 << 17) /*!< VDD 2.9-3.0 */ +#define SDHC_SD_OCR_VDD_30_31 (1 << 18) /*!< VDD 3.0-3.1 */ +#define SDHC_SD_OCR_VDD_31_32 (1 << 19) /*!< VDD 3.1-3.2 */ +#define SDHC_SD_OCR_VDD_32_33 (1 << 20) /*!< VDD 3.2-3.3 */ +#define SDHC_SD_OCR_VDD_33_34 (1 << 21) /*!< VDD 3.3-3.4 */ +#define SDHC_SD_OCR_VDD_34_35 (1 << 22) /*!< VDD 3.4-3.5 */ +#define SDHC_SD_OCR_VDD_35_36 (1 << 23) /*!< VDD 3.5-3.6 */ + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_SelectClock + * Description: Select clock source for specific host controller + * + *END*********************************************************************/ +static void SDHC_DRV_SelectClock(uint32_t instance) +{ + assert(instance < SDHC_INSTANCE_COUNT); + + g_hosts[instance]->maxClock = CLOCK_SYS_GetSdhcFreq(instance); +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_SetClock + * Description: Enable clock for specific host controller + * + *END*********************************************************************/ +static sdhc_status_t SDHC_DRV_SetClock(uint32_t instance, bool enable) +{ + assert(instance < SDHC_INSTANCE_COUNT); +#if defined BSP_FSL_SDHC_CLKMGMT_ENABLED + CLOCK_SYS_EnableEnetClock(instance); +#endif + return kStatus_SDHC_NoError; +} + +#if defined BSP_FSL_SDHC_ENABLE_ADMA1 +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_FillAdma1Table + * Description: Fill ADMA1 descriptor table, once its finish, the field + * of admaTableAddress is well configured. It will fail, if the incoming + * data does not align. + * + *END*********************************************************************/ +static sdhc_status_t SDHC_DRV_FillAdma1Table(uint32_t instance, uint32_t *buffer, uint32_t length) +{ + uint32_t i = 0, entries; + uint32_t *startAddress; +#if defined BSP_FSL_SDHC_USING_DYNALLOC + sdhc_hal_adma1_descriptor_t *tableAddress = NULL; +#endif + volatile sdhc_host_t *host; + + assert(instance < SDHC_INSTANCE_COUNT); + assert(buffer); + assert(length); + + if (((uint32_t)buffer % SDHC_HAL_ADMA1_ADDR_ALIGN) || + (length % SDHC_HAL_ADMA1_ADDR_ALIGN)) + { + return kStatus_SDHC_DataPrepareError; + } + + host = g_hosts[instance]; + + entries = (length / SDHC_HAL_ADMA1_DESC_MAX_LEN_PER_ENTRY) + 1; + + /* ADMA1 needs two descritors to finish a transfer */ + entries *= 2; +#if defined BSP_FSL_SDHC_USING_DYNALLOC + if (entries > host->admaTableMaxEntries) + { + /* Larger table is needed */ + if (host->admaTableAddress) + { + OSA_MemFree(host->admaTableAddress); + host->admaTableAddress = NULL; + host->admaTableMaxEntries = 0; + } + tableAddress = (sdhc_hal_adma1_descriptor_t *)OSA_MemAllocZero(entries * sizeof(sdhc_hal_adma1_descriptor_t)); + } + + if ((tableAddress == NULL) && (host->admaTableAddress == NULL)) + { + host->admaTableMaxEntries = 0; + /* Failed to alloc memory for ADMA descriptor table */ + return kStatus_SDHC_DmaAddressError; + } + + if (host->admaTableAddress == NULL) + { + /* Update ADMA table address */ + host->admaTableAddress = (uint32_t *)tableAddress; + /* Update ADMA table capacity */ + host->admaTableMaxEntries = entries; + } +#else + if (entries > BSP_FSL_SDHC_ADMA_TABLE_MAX_ENTRY) + { + return kStatus_SDHC_Failed; + } +#endif + + startAddress = buffer; + for (i = 0; i < entries; i += 2) + { + /* Each descriptor for ADMA1 is 64-bit in length */ + if ((length - sizeof(uint32_t) * (startAddress - buffer)) < SDHC_HAL_ADMA1_DESC_MAX_LEN_PER_ENTRY) + { + /* The last piece of data, setting end flag in descriptor */ + host->admaTableAddress[i] = (uint32_t)(length - sizeof(uint32_t) * (startAddress - buffer)) << SDHC_HAL_ADMA1_DESC_LEN_SHIFT; + host->admaTableAddress[i] |= SDHC_HAL_ADMA1_DESC_TYPE_SET; + host->admaTableAddress[i+1] = (uint32_t)(startAddress) << SDHC_HAL_ADMA1_DESC_ADDRESS_SHIFT; + host->admaTableAddress[i+1] |= SDHC_HAL_ADMA1_DESC_TYPE_TRAN | SDHC_HAL_ADMA1_DESC_END_MASK; + } + else + { + host->admaTableAddress[i] = (uint32_t)SDHC_HAL_ADMA1_DESC_MAX_LEN_PER_ENTRY << SDHC_HAL_ADMA1_DESC_LEN_SHIFT; + host->admaTableAddress[i] |= SDHC_HAL_ADMA1_DESC_TYPE_SET; + host->admaTableAddress[i+1] = (uint32_t)(startAddress) << SDHC_HAL_ADMA1_DESC_ADDRESS_SHIFT; + host->admaTableAddress[i+1] |= SDHC_HAL_ADMA1_DESC_TYPE_TRAN; + startAddress += SDHC_HAL_ADMA1_DESC_MAX_LEN_PER_ENTRY/sizeof(uint32_t); + } + } + + return kStatus_SDHC_NoError; +} +#endif + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_SetAdma2Descriptor + * Description: Compose a ADMA2 descriptor, setting address/length and + * corresponding flags to be operated by the internal DMA engine. + * + *END*********************************************************************/ +static void SDHC_DRV_SetAdma2Descriptor(uint32_t *table, + uint32_t *buffer, + uint32_t length, + uint32_t flags) +{ + assert(table); + assert(length <= SDHC_HAL_ADMA2_DESC_MAX_LEN_PER_ENTRY); + + ((sdhc_hal_adma2_descriptor_t *)table)->address = buffer; + ((sdhc_hal_adma2_descriptor_t *)table)->attribute = ((SDHC_HAL_ADMA2_DESC_LEN_MASK & length) << SDHC_HAL_ADMA2_DESC_LEN_SHIFT) | flags; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_FillAdma2Table + * Description: Fill ADMA2 descriptor table, once its finish, the field + * of admaTableAddress is well configured. It will fail, if the incoming + * data does not align. + * + *END*********************************************************************/ +static sdhc_status_t SDHC_DRV_FillAdma2Table(uint32_t instance, uint32_t *buffer, uint32_t length) +{ + uint32_t i = 0, entries; + uint32_t *startAddress; +#if defined BSP_FSL_SDHC_USING_DYNALLOC + sdhc_hal_adma2_descriptor_t *tableAddress = NULL; +#endif + volatile sdhc_host_t *host; + + assert(instance < SDHC_INSTANCE_COUNT); + assert(buffer); + assert(length); + + if ((uint32_t)buffer % SDHC_HAL_ADMA2_ADDR_ALIGN) + { + return kStatus_SDHC_DataPrepareError; + } + + host = g_hosts[instance]; + + entries = ((length / SDHC_HAL_ADMA2_DESC_MAX_LEN_PER_ENTRY) + 1); +#if defined BSP_FSL_SDHC_USING_DYNALLOC + if (entries > host->admaTableMaxEntries) + { + /* Larger table is needed */ + if (host->admaTableAddress) + { + OSA_MemFree(host->admaTableAddress); + host->admaTableAddress = NULL; + host->admaTableMaxEntries = 0; + } + tableAddress = (sdhc_hal_adma2_descriptor_t *)OSA_MemAllocZero(entries * sizeof(sdhc_hal_adma2_descriptor_t)); + } + + if ((tableAddress == NULL) && (host->admaTableAddress == NULL)) + { + host->admaTableMaxEntries = 0; + /* Failed to alloc memory for ADMA descriptor table */ + return kStatus_SDHC_DmaAddressError; + } + + if (host->admaTableAddress == NULL) + { + /* Update ADMA table address */ + host->admaTableAddress = (uint32_t *)tableAddress; + /* Update ADMA table capacity */ + host->admaTableMaxEntries = entries; + } +#else + if (entries > BSP_FSL_SDHC_ADMA_TABLE_MAX_ENTRY) + { + return kStatus_SDHC_Failed; + } +#endif + + startAddress = buffer; + for (i = 0; i < entries * 2; i += 2) + { + /* Each descriptor for ADMA2 is 64-bit in length */ + if ((length - sizeof(uint32_t) * (startAddress - buffer)) <= SDHC_HAL_ADMA2_DESC_MAX_LEN_PER_ENTRY) + { + /* The last piece of data, setting end flag in descriptor */ + SDHC_DRV_SetAdma2Descriptor(&host->admaTableAddress[i], + startAddress, + length - sizeof(uint32_t) * (startAddress - buffer), + SDHC_HAL_ADMA2_DESC_TYPE_TRAN | SDHC_HAL_ADMA2_DESC_END_MASK); + } + else + { + SDHC_DRV_SetAdma2Descriptor(&host->admaTableAddress[i], + startAddress, + SDHC_HAL_ADMA2_DESC_MAX_LEN_PER_ENTRY, + SDHC_HAL_ADMA2_DESC_TYPE_TRAN); + startAddress += SDHC_HAL_ADMA2_DESC_MAX_LEN_PER_ENTRY/sizeof(uint32_t); + } + } + return kStatus_SDHC_NoError; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_PrepareData + * Description: Prepare data for transferring + * + *END*********************************************************************/ +static sdhc_status_t SDHC_DRV_PrepareData(uint32_t instance, + sdhc_request_t *req) +{ + sdhc_status_t ret; + uint32_t totalSize; + volatile sdhc_host_t *host; + + assert(instance < SDHC_INSTANCE_COUNT); + assert(req); + assert(req->data); + assert(req->data->buffer); + assert(req->data->blockCount); + assert(req->data->blockSize); + + host = g_hosts[instance]; + ret = kStatus_SDHC_NoError; + + if ((host->mode != kSdhcTransModeAdma2) +#if defined BSP_FSL_SDHC_ENABLE_ADMA1 + && (host->mode != kSdhcTransModeAdma1) +#endif + ) + { + return ret; + } + + totalSize = (req->data->blockSize * req->data->blockCount); + if (((host->mode == kSdhcTransModeAdma2) && + (totalSize % SDHC_HAL_ADMA2_LEN_ALIGN)) || + ((host->mode == kSdhcTransModeAdma1) && + (totalSize % SDHC_HAL_ADMA1_LEN_ALIGN))) + + { + return kStatus_SDHC_DataPrepareError; + } + + /* Check data length alignment */ + if ((host->mode == kSdhcTransModeAdma2)) + { + /* ADMA2 */ + ret = SDHC_DRV_FillAdma2Table(instance, req->data->buffer, totalSize); + if (ret != kStatus_SDHC_NoError) + { + return ret; + } + } +#if defined BSP_FSL_SDHC_ENABLE_ADMA1 + else + { + /* ADMA1 */ + ret = SDHC_DRV_FillAdma1Table(instance, req->data->buffer, totalSize); + if (ret != kStatus_SDHC_NoError) + { + return ret; + } + } +#endif + + SDHC_HAL_SetAdmaAddress(g_sdhcBase[instance], (uint32_t)host->admaTableAddress); + return ret; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_IsCardPresent + * Description: Check whether card is inserted + * + *END*********************************************************************/ +static bool SDHC_DRV_IsCardPresent(uint32_t instance) +{ + assert(instance < SDHC_INSTANCE_COUNT); + return SDHC_HAL_GetCurState(g_sdhcBase[instance], kSdhcHalIsCardInserted); +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_ConfigClock + * Description: configure clock of host controller, it will set the most + * close clock frequency to the given clock + * + *END*********************************************************************/ +sdhc_status_t SDHC_DRV_ConfigClock(uint32_t instance, uint32_t clock) +{ + sdhc_hal_sdclk_config_t sdClkConf; + volatile sdhc_host_t *host = g_hosts[instance]; + assert(instance < SDHC_INSTANCE_COUNT); + + sdClkConf.enable = true; + sdClkConf.maxHostClk = host->maxClock; + sdClkConf.destClk = clock; + SDHC_HAL_ConfigSdClock(g_sdhcBase[instance], &sdClkConf); + + host->clock = clock; + return kStatus_SDHC_NoError; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_SetBusWidth + * Description: Configure bus width of host controller + * + *END*********************************************************************/ +sdhc_status_t SDHC_DRV_SetBusWidth(uint32_t instance, sdhc_buswidth_t busWidth) +{ + assert(instance < SDHC_INSTANCE_COUNT); + sdhc_hal_dtw_t dtw = kSdhcHalDtw1Bit; + volatile sdhc_host_t *host = g_hosts[instance]; + + switch(busWidth) + { + case kSdhcBusWidth1Bit: + dtw = kSdhcHalDtw1Bit; + break; + case kSdhcBusWidth4Bit: + dtw = kSdhcHalDtw4Bit; + break; + default: + return kStatus_SDHC_InvalidParameter; + } + SDHC_HAL_SetDataTransferWidth(g_sdhcBase[instance], dtw); + host->busWidth = busWidth; + return kStatus_SDHC_NoError; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_Reset + * Description: Reset host controller accord to the given mask + * + *END*********************************************************************/ +static sdhc_status_t SDHC_DRV_Reset(uint32_t instance, uint32_t mask) +{ + uint32_t timeout; + volatile sdhc_host_t *host; + assert(instance < SDHC_INSTANCE_COUNT); + + timeout = 100; + host = g_hosts[instance]; + + if (!(mask & (SDHC_RESET_ALL | SDHC_RESET_DATA | SDHC_RESET_CMD))) + { + return kStatus_SDHC_InvalidParameter; + } + + if (mask & SDHC_RESET_ALL) + { + host->clock = 0; + SDHC_HAL_Reset(g_sdhcBase[instance], SDHC_HAL_RST_TYPE_ALL, timeout); + } + else if (mask == (SDHC_RESET_DATA | SDHC_RESET_CMD)) + { + SDHC_HAL_Reset(g_sdhcBase[instance], (SDHC_HAL_RST_TYPE_DATA + | SDHC_HAL_RST_TYPE_CMD), timeout); + } + else if (mask == SDHC_RESET_CMD) + { + SDHC_HAL_Reset(g_sdhcBase[instance], SDHC_HAL_RST_TYPE_CMD, timeout); + } + else if (mask == SDHC_RESET_DATA) + { + SDHC_HAL_Reset(g_sdhcBase[instance], SDHC_HAL_RST_TYPE_DATA, timeout); + } + return kStatus_SDHC_NoError; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_SendCommand + * Description: Send command to card + * + *END*********************************************************************/ +static sdhc_status_t SDHC_DRV_SendCommand(uint32_t instance, + sdhc_request_t *req) +{ + uint32_t flags = 0; + sdhc_hal_cmd_req_t cmdReq; + sdhc_status_t ret = kStatus_SDHC_NoError; + assert(instance < SDHC_INSTANCE_COUNT); + assert(req); + + if (req->data) + { + flags |= SDHC_HAL_DATA_PRESENT; + + SDHC_HAL_SetIntState(g_sdhcBase[instance], false, + (SDHC_HAL_DMA_ERR_INT | SDHC_HAL_DMA_INT | + SDHC_HAL_BUF_READ_READY_INT | SDHC_HAL_BUF_WRITE_READY_INT)); + SDHC_HAL_SetIntSignal(g_sdhcBase[instance], false, + (SDHC_HAL_DMA_ERR_INT | SDHC_HAL_DMA_INT | + SDHC_HAL_BUF_READ_READY_INT | SDHC_HAL_BUF_WRITE_READY_INT)); + + if (req->flags & FSL_SDHC_REQ_FLAGS_USE_DMA) + { + flags |= SDHC_HAL_ENABLE_DMA; + SDHC_HAL_SetIntState(g_sdhcBase[instance], true, + (SDHC_HAL_DMA_ERR_INT | SDHC_HAL_DMA_INT)); +#if defined BSP_FSL_SDHC_USING_IRQ + SDHC_HAL_SetIntSignal(g_sdhcBase[instance], true, + (SDHC_HAL_DMA_ERR_INT | SDHC_HAL_DMA_INT)); +#endif + } + else + { + SDHC_HAL_SetIntState(g_sdhcBase[instance], true, + (SDHC_HAL_BUF_READ_READY_INT | SDHC_HAL_BUF_WRITE_READY_INT)); +#if defined BSP_FSL_SDHC_USING_IRQ + SDHC_HAL_SetIntSignal(g_sdhcBase[instance], true, + (SDHC_HAL_BUF_READ_READY_INT | SDHC_HAL_BUF_WRITE_READY_INT)); +#endif + } + + if (req->flags & FSL_SDHC_REQ_FLAGS_DATA_READ) + { + flags |= SDHC_HAL_ENABLE_DATA_READ; + } + } + + if (g_req_resp_flags[req->respType] & FSL_SDHC_REQ_RSPTYPE_136BITS) + { + flags |= SDHC_HAL_RESP_LEN_136; + } + else if (g_req_resp_flags[req->respType] & FSL_SDHC_REQ_RSPTYPE_BUSY) + { + flags |= SDHC_HAL_RESP_LEN_48_BC; + } + else if (g_req_resp_flags[req->respType] & FSL_SDHC_REQ_RSPTYPE_PRESENT) + { + flags |= SDHC_HAL_RESP_LEN_48; + } + + if (g_req_resp_flags[req->respType] & FSL_SDHC_REQ_RSPTYPE_CRC) + { + flags |= SDHC_HAL_ENABLE_CRC_CHECK; + } + if (g_req_resp_flags[req->respType] & FSL_SDHC_REQ_RSPTYPE_CHK_IDX) + { + flags |= SDHC_HAL_ENABLE_INDEX_CHECK; + } + + while(SDHC_HAL_GetCurState(g_sdhcBase[instance], kSdhcHalIsCmdInhibit)) {} + + if(req->flags & FSL_SDHC_REQ_FLAGS_STOP_TRANS) + { + flags |= SDHC_HAL_CMD_TYPE_ABORT; + } + else if ((req->data) || + (g_req_resp_flags[req->respType] & FSL_SDHC_REQ_RSPTYPE_BUSY)) + { + while(SDHC_HAL_GetCurState(g_sdhcBase[instance], kSdhcHalIsDataInhibit)) {} + } + + if (req->data) + { + if (req->data->blockCount > 1) + { + flags |= SDHC_HAL_MULTIPLE_BLOCK; + flags |= SDHC_HAL_ENABLE_BLOCK_COUNT; +#ifdef BSP_FSL_SDHC_ENABLE_AUTOCMD12 + /* Enable Auto CMD12 */ + flags |= SDHC_HAL_ENABLE_AUTO_CMD12; +#endif + } + if (req->data->blockCount == ((uint32_t) -1)) + { + cmdReq.dataBlkSize = req->data->blockSize; + cmdReq.dataBlkCount = SDHC_HAL_MAX_BLOCK_COUNT; + flags &= ~SDHC_HAL_ENABLE_BLOCK_COUNT; + } + else + { + cmdReq.dataBlkSize = req->data->blockSize; + cmdReq.dataBlkCount = req->data->blockCount; + } + } + else + { + cmdReq.dataBlkSize = 0; + cmdReq.dataBlkCount = 0; + } + + cmdReq.arg = req->argument; + cmdReq.index = req->cmdIndex; + cmdReq.flags = flags; + SDHC_HAL_SendCmd(g_sdhcBase[instance], &cmdReq); + return ret; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_SetRequestError + * Description: Set error flags for a given request according to irq flags + * + *END*********************************************************************/ +static void SDHC_DRV_SetRequestError(sdhc_request_t *req, uint32_t irqFlags) +{ + assert(req); + if ((!irqFlags) || (!(irqFlags & SDHC_HAL_ALL_ERR_INT))) + { + return; + } + + if (irqFlags & SDHC_HAL_CMD_CRC_ERR_INT) + { + req->error |= FSL_SDHC_REQ_ERR_CMD_CRC; + } + if (irqFlags & SDHC_HAL_CMD_INDEX_ERR_INT) + { + req->error |= FSL_SDHC_REQ_ERR_CMD_INDEX; + } + if (irqFlags & SDHC_HAL_CMD_END_BIT_ERR_INT) + { + req->error |= FSL_SDHC_REQ_ERR_CMD_END_BIT; + } + if (irqFlags & SDHC_HAL_CMD_TIMEOUT_ERR_INT) + { + req->error |= FSL_SDHC_REQ_ERR_CMD_TIMEOUT; + } + if (irqFlags & SDHC_HAL_DATA_TIMEOUT_ERR_INT) + { + req->error |= FSL_SDHC_REQ_ERR_DAT_TIMEOUT; + } + if (irqFlags & SDHC_HAL_DATA_CRC_ERR_INT) + { + req->error |= FSL_SDHC_REQ_ERR_DATA_CRC; + } + if (irqFlags & SDHC_HAL_DATA_END_BIT_ERR_INT) + { + req->error |= FSL_SDHC_REQ_ERR_DATA_END_BIT; + } + if (irqFlags & SDHC_HAL_AUTO_CMD12_ERR_INT) + { + req->error |= FSL_SDHC_REQ_ERR_AUTO_CMD12; + } + if (irqFlags & SDHC_HAL_DMA_ERR_INT) + { + req->error |= FSL_SDHC_REQ_ERR_DMA; + } +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_PioReadBlock + * Description: Read a block using PIO + * + *END*********************************************************************/ +static void SDHC_DRV_PioReadBlock(uint32_t instance, sdhc_request_t *req) +{ + uint32_t blkSz, blkCnt; + blkCnt = req->data->blockCount; + while (SDHC_HAL_GetCurState(g_sdhcBase[instance], kSdhcHalIsBuffReadEnabled)) + { + blkSz = req->data->blockSize; + while (blkSz) + { + req->data->buffer[req->data->bytesTransferred >> 2] = + SDHC_HAL_GetData(g_sdhcBase[instance]); + req->data->bytesTransferred += 4; + blkSz -= 4; + } + blkCnt--; + if (!blkCnt) + { + break; + } + } +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_PioWriteBlock + * Description: Write a block using PIO + * + *END*********************************************************************/ +static void SDHC_DRV_PioWriteBlock(uint32_t instance, sdhc_request_t *req) +{ + uint32_t blkSz, blkCnt; + blkCnt = req->data->blockCount; + while (SDHC_HAL_GetCurState(g_sdhcBase[instance], kSdhcHalIsBuffWriteEnabled)) + { + blkSz = req->data->blockSize; + while (blkSz) + { + SDHC_HAL_SetData(g_sdhcBase[instance], + req->data->buffer[req->data->bytesTransferred >> 2]); + req->data->bytesTransferred += 4; + + blkSz -= 4; + } + blkCnt--; + if (!blkCnt) + { + break; + } + } +} + +#if ! defined BSP_FSL_SDHC_USING_IRQ +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_WaitInt + * Description: Wait for specific interrupts + * + *END*********************************************************************/ +static sdhc_status_t SDHC_DRV_WaitInt(uint32_t instance, + uint32_t mask, + uint32_t *irq, + uint32_t timeoutInMs) +{ + sdhc_status_t status = kStatus_SDHC_NoError; + uint32_t startTime, currentTime, elapsedTime = 0; + assert(timeoutInMs <= FSL_OSA_TIME_RANGE); + + do + { + startTime = OSA_TimeGetMsec(); + *irq = (SDHC_HAL_GetIntFlags(g_sdhcBase[instance]) & mask); + if (*irq) + { + break; + } + currentTime = OSA_TimeGetMsec(); + if (currentTime < startTime) + { + currentTime += FSL_OSA_TIME_RANGE; + } + elapsedTime += currentTime - startTime; + } + while (elapsedTime < timeoutInMs); + + if (!(*irq)) + { + status = kStatus_SDHC_TimeoutError; + } + + return status; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_TransferDataPio + * Description: transfer data using PIO mode + * + *END*********************************************************************/ +static sdhc_status_t SDHC_DRV_TransferDataPio(uint32_t instance, + sdhc_request_t *req, + uint32_t timeoutInMs) +{ + uint32_t opMask, mask, i, j, irqFlags, status; + volatile sdhc_host_t *host; + assert(instance < SDHC_INSTANCE_COUNT); + assert(req); + + host = g_hosts[instance]; + mask = SDHC_HAL_DATA_COMPLETE_INT | SDHC_HAL_DATA_ERR_INT; + if ((req->flags & FSL_SDHC_REQ_FLAGS_DATA_READ)) + { + opMask = SDHC_HAL_BUF_READ_READY_INT; + } + else + { + opMask = SDHC_HAL_BUF_WRITE_READY_INT; + } + for (i = 0; i < req->data->blockCount; i++) + { + status = SDHC_DRV_WaitInt(instance, mask | opMask, + &irqFlags, timeoutInMs); + if (status != kStatus_SDHC_NoError) + { + req->error |= FSL_SDHC_REQ_ERR_TIMEOUT; + host->currentReq = 0; + SDHC_DRV_SetClock(instance, false); + SDHC_DRV_SetRequestError(req, irqFlags); + return kStatus_SDHC_Failed; + } + if (irqFlags & SDHC_HAL_DATA_ERR_INT) + { + SDHC_HAL_ClearIntFlags(g_sdhcBase[instance], mask); + host->currentReq = 0; + SDHC_DRV_SetClock(instance, false); + SDHC_DRV_SetRequestError(req, irqFlags); + return kStatus_SDHC_Failed; + } + if (irqFlags & opMask) + { + if ((req->flags & FSL_SDHC_REQ_FLAGS_DATA_READ)) + { + SDHC_DRV_PioReadBlock(instance, req); + } + else + { + SDHC_DRV_PioWriteBlock(instance, req); + } + SDHC_HAL_ClearIntFlags(g_sdhcBase[instance], opMask); + } + } + + do + { + status = SDHC_DRV_WaitInt(instance, mask, &irqFlags, timeoutInMs); + if (status != kStatus_SDHC_NoError) + { + req->error |= FSL_SDHC_REQ_ERR_TIMEOUT; + host->currentReq = 0; + SDHC_DRV_SetClock(instance, false); + SDHC_DRV_SetRequestError(req, irqFlags); + return kStatus_SDHC_Failed; + } + } while (!(irqFlags & SDHC_HAL_DATA_COMPLETE_INT)); + + SDHC_HAL_ClearIntFlags(g_sdhcBase[instance], mask); + return kStatus_SDHC_NoError; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_TransferDataDma + * Description: transfer data using DMA mode + * + *END*********************************************************************/ +static sdhc_status_t SDHC_DRV_TransferDataDma(uint32_t instance, + sdhc_request_t *req, + uint32_t timeoutInMs) +{ + uint32_t mask, irqFlags; + sdhc_status_t status; + assert(instance < SDHC_INSTANCE_COUNT); + assert(req); + volatile sdhc_host_t *host; + + host = g_hosts[instance]; + if (host->mode == kSdhcTransModeSdma) + { + return kStatus_SDHC_NotSupportYet; + } + + mask = SDHC_HAL_DATA_COMPLETE_INT | SDHC_HAL_DMA_ERR_INT; + do + { + status = SDHC_DRV_WaitInt(instance, mask, &irqFlags, timeoutInMs); + if (status != kStatus_SDHC_NoError) + { + req->error |= FSL_SDHC_REQ_ERR_TIMEOUT; + host->currentReq = 0; + SDHC_DRV_SetClock(instance, false); + SDHC_DRV_SetRequestError(req, irqFlags); + return kStatus_SDHC_Failed; + } + + if (irqFlags & SDHC_HAL_DMA_ERR_INT) + { + req->error |= FSL_SDHC_REQ_ERR_DMA; + host->currentReq = 0; + SDHC_DRV_SetClock(instance, false); + SDHC_DRV_SetRequestError(req, irqFlags); + return kStatus_SDHC_Failed; + } + } while (!(irqFlags & SDHC_HAL_DATA_COMPLETE_INT)); + + SDHC_HAL_ClearIntFlags(g_sdhcBase[instance], mask); + return kStatus_SDHC_NoError; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_TransferData + * Description: transfer data using different mode according to the flags + * of host controller + * + *END*********************************************************************/ +static sdhc_status_t SDHC_DRV_TransferData(uint32_t instance, + sdhc_request_t *req, + uint32_t timeoutInMs) +{ + assert(instance < SDHC_INSTANCE_COUNT); + assert(req); + + if (req->flags & FSL_SDHC_REQ_FLAGS_USE_DMA) + { + return SDHC_DRV_TransferDataDma(instance, req, timeoutInMs); + } + else + { + return SDHC_DRV_TransferDataPio(instance, req, timeoutInMs); + } +} + +#else /* BSP_FSL_SDHC_USING_IRQ */ + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_ClearSetInt + * Description: Clear then set corresponding interrupt mask + * + *END*********************************************************************/ +static void SDHC_DRV_ClearSetInt(uint32_t instance, + uint32_t clear, + uint32_t set) +{ + SDHC_HAL_SetIntState(g_sdhcBase[instance], false, clear); + SDHC_HAL_SetIntSignal(g_sdhcBase[instance], false, clear); + + SDHC_HAL_SetIntState(g_sdhcBase[instance], true, set); + SDHC_HAL_SetIntSignal(g_sdhcBase[instance], true, set); +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_DataIrq + * Description: handle data related irqs + * + *END*********************************************************************/ +static void SDHC_DRV_DataIrq(uint32_t instance, uint32_t irq) +{ + sdhc_request_t *req; + assert(irq & SDHC_HAL_DATA_ALL_INT); + + req = g_hosts[instance]->currentReq; + assert(req); + assert(req->data); + assert(req->data->buffer); + + if (irq & (SDHC_HAL_DATA_ERR_INT | SDHC_HAL_DMA_ERR_INT)) + { + SDHC_DRV_SetRequestError(req, irq); + OSA_SemaPost(req->complete); + return; + } + + if (irq & SDHC_HAL_BUF_READ_READY_INT) + { + SDHC_DRV_PioReadBlock(instance, req); + } + else if (irq & SDHC_HAL_BUF_WRITE_READY_INT) + { + SDHC_DRV_PioWriteBlock(instance, req); + } + else if (irq & SDHC_HAL_DATA_COMPLETE_INT) + { + OSA_SemaPost(req->complete); + } + else if (irq & SDHC_HAL_DMA_INT) + { + if (g_hosts[instance]->mode != kSdhcTransModeSdma) + { + return; + } + } +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_CmdIrq + * Description: handle command related irqs + * + *END*********************************************************************/ +static void SDHC_DRV_CmdIrq(uint32_t instance, uint32_t irq) +{ + sdhc_request_t *req; + uint32_t i; + assert(instance < SDHC_INSTANCE_COUNT); + assert(irq & SDHC_HAL_CMD_ALL_INT); + req = g_hosts[instance]->currentReq; + if (irq & SDHC_HAL_CMD_ERR_INT) + { + SDHC_DRV_SetRequestError(req, irq); + } + else if (irq & SDHC_HAL_CMD_COMPLETE_INT) + { + if (g_req_resp_flags[req->respType] & FSL_SDHC_REQ_RSPTYPE_PRESENT) + { + req->response[0] = SDHC_HAL_GetResponse(g_sdhcBase[instance], 0); + if (!(g_req_resp_flags[req->respType] & + FSL_SDHC_REQ_RSPTYPE_136BITS)) + { + if ((req->respType == kSdhcRespTypeR1) || + (req->respType == kSdhcRespTypeR1b)) + { + req->cardErrStatus = SDHC_R1_ERROR_BITS(req->response[0]); + } + } + else + { + req->response[1] = SDHC_HAL_GetResponse(g_sdhcBase[instance], 1); + req->response[2] = SDHC_HAL_GetResponse(g_sdhcBase[instance], 2); + req->response[3] = SDHC_HAL_GetResponse(g_sdhcBase[instance], 3); + i = 4; + do { + req->response[i - 1] <<= 8; + if (i > 1) + { + req->response[i - 1] |= + ((req->response[i-2] & 0xFF000000U) >> 24); + } + } while(i--); + } + } + } + if ((!req->data) || (req->cardErrStatus)) + { + OSA_SemaPost(req->complete); + } +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_CardDetectIrq + * Description: Card detection interrupt handler + * + *END*********************************************************************/ +static void SDHC_DRV_CardDetectIrq(uint32_t instance, uint32_t irq) +{ + assert(irq & SDHC_HAL_CD_ALL_INT); + assert(g_hosts[instance]->cardDetectCallback); + + if ((irq & SDHC_HAL_CD_ALL_INT) == SDHC_HAL_CARD_INSERTION_INT) + { + if (g_hosts[instance]->cardDetectCallback) + { + g_hosts[instance]->cardDetectCallback(true); + } + SDHC_DRV_ClearSetInt(instance, + SDHC_HAL_CARD_INSERTION_INT, + SDHC_HAL_CARD_REMOVAL_INT); + } + else + { + if (g_hosts[instance]->cardDetectCallback) + { + g_hosts[instance]->cardDetectCallback(false); + } + SDHC_DRV_ClearSetInt(instance, + SDHC_HAL_CARD_REMOVAL_INT, + SDHC_HAL_CARD_INSERTION_INT); + } +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_BlockGapIrq + * Description: Block gap interrupt handler + * + *END*********************************************************************/ +static void SDHC_DRV_BlockGapIrq(uint32_t instance) +{ + assert(g_hosts[instance]->blockGapCallback); + g_hosts[instance]->blockGapCallback(); +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_CardIntIrq + * Description: Card interrupt handler + * + *END*********************************************************************/ +static void SDHC_DRV_CardIntIrq(uint32_t instance) +{ + assert(g_hosts[instance]->cardIntCallback); + g_hosts[instance]->cardIntCallback(); +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_DoIrq + * Description: IRQ handler + * + *END*********************************************************************/ +void SDHC_DRV_DoIrq(uint32_t instance) +{ + volatile uint32_t irq; + volatile uint32_t cardInt = 0; + irq = SDHC_HAL_GetIntFlags(g_sdhcBase[instance]); + + if (!irq) + { + return; + } + + if (irq & SDHC_HAL_CD_ALL_INT) + { + SDHC_DRV_CardDetectIrq(instance, (irq & SDHC_HAL_CD_ALL_INT)); + } + if (irq & SDHC_HAL_CMD_ALL_INT) + { + SDHC_DRV_CmdIrq(instance, (irq & SDHC_HAL_CMD_ALL_INT)); + } + if (irq & SDHC_HAL_DATA_ALL_INT) + { + SDHC_DRV_DataIrq(instance, (irq & SDHC_HAL_DATA_ALL_INT)); + } + if (irq & SDHC_HAL_CARD_INT) + { + cardInt = 1; + } + if (irq & SDHC_HAL_BLOCK_GAP_EVENT_INT) + { + SDHC_DRV_BlockGapIrq(instance); + } + + SDHC_HAL_ClearIntFlags(g_sdhcBase[instance], irq); + + if (cardInt) + { + SDHC_DRV_CardIntIrq(instance); + } + return; +} +#endif + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_GetCaps + * Description: Get the capability of the host. + * + *END*********************************************************************/ +static void SDHC_DRV_GetCaps(uint32_t instance, sdhc_host_t *host) +{ + uint32_t caps = host->caps; + uint32_t capability; + sdhc_hal_basic_info_t basicInfo; + assert(instance < SDHC_INSTANCE_COUNT); + assert(host); + host->ocrSupported = 0; + SDHC_HAL_GetBasicInfo(g_sdhcBase[instance], &basicInfo); + capability = basicInfo.capability; + if (capability & SDHC_HAL_SUPPORT_V330_FLAG) + { + host->ocrSupported |= SDHC_SD_OCR_VDD_32_33 | SDHC_SD_OCR_VDD_33_34; + } + if (capability & SDHC_HAL_SUPPORT_V300_FLAG) + { + host->ocrSupported |= SDHC_SD_OCR_VDD_29_30; + } + if (capability & SDHC_HAL_SUPPORT_HIGHSPEED_FLAG) + { + caps |= FSL_SDHC_HOST_CAPS_SUPPORT_HIGHSPEED; + } + if (capability & SDHC_HAL_SUPPORT_DMA_FLAG) + { + caps |= FSL_SDHC_HOST_CAPS_SUPPORT_DMA; + } + if (capability & SDHC_HAL_SUPPORT_ADMA_FLAG) + { + caps |= FSL_SDHC_HOST_CAPS_SUPPORT_ADMA; + } + if (capability & SDHC_HAL_SUPPORT_SUSPEND_RESUME_FLAG) + { + caps |= FSL_SDHC_HOST_CAPS_SUPPORT_SRS; + } + if (capability & SDHC_HAL_SUPPORT_V180_FLAG) + { + caps |= FSL_SDHC_HOST_CAPS_SUPPORT_V180; + } + if(capability & SDHC_HAL_SUPPORT_EXDMA_FLAG) + { + caps |= FSL_SDHC_HOST_CAPS_SUPPORT_EXDMA; + } + /* eSDHC on all kinetis boards will support 4 bit data bus. */ + caps |= FSL_SDHC_HOST_CAPS_SUPPORT_4BITS; + host->caps = caps; + host->maxBlockSize = basicInfo.maxBlkLen; + host->maxBlockCount = SDHC_HAL_MAX_BLOCK_COUNT; +} + + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_Init + * Description: Initialize host controller by specific instance index. + * + *END*********************************************************************/ +sdhc_status_t SDHC_DRV_Init(uint32_t instance, + sdhc_host_t *host, + const sdhc_user_config_t *config) +{ + uint32_t irqEnabled; + sdhc_hal_config_t sdhcConfig; + sdhc_hal_sdclk_config_t sdClkConfig; + assert(instance < SDHC_INSTANCE_COUNT); + assert(host); + assert(config); + + if (g_hosts[instance]) + { + return kStatus_SDHC_HostIsAlreadyInited; + } + + memset(host, 0, sizeof(sdhc_host_t)); + memset(&sdhcConfig, 0, sizeof(sdhc_hal_config_t)); + g_hosts[instance] = host; + host->instance = instance; + +#if ! defined BSP_FSL_SDHC_USING_IRQ + if (config->cdType == kSdhcCardDetectDat3) + { + return kStatus_SDHC_HostNotSupport; + } +#endif + +#if ! defined BSP_FSL_SDHC_ENABLE_ADMA1 + if (config->transMode == kSdhcTransModeAdma1) + { + return kStatus_SDHC_HostNotSupport; + } +#endif + + host->cdType = config->cdType; + if (((host->cdType == kSdhcCardDetectCdPin) || + (host->cdType == kSdhcCardDetectDat3)) && + (config->cardDetectCallback)) + { + host->cardDetectCallback = config->cardDetectCallback; + } + + CLOCK_SYS_EnableSdhcClock(instance); + SDHC_DRV_SetClock(instance, false); + + CLOCK_SYS_SetSdhcSrc(instance, kClockSdhcSrcPllFllSel); + SDHC_DRV_SelectClock(instance); + + SDHC_DRV_SetClock(instance, true); + + SDHC_HAL_Init(g_sdhcBase[instance]); + SDHC_DRV_Reset(instance, SDHC_RESET_ALL); + + SDHC_DRV_GetCaps(instance, host); + if(!host->maxBlockSize) + { + CLOCK_SYS_DisableSdhcClock(instance); + return kStatus_SDHC_Failed; + } + if(host->caps&FSL_SDHC_HOST_CAPS_SUPPORT_EXDMA) + { + /* Disable external dma */ + sdhcConfig.enFlags &= (~SDHC_HAL_EN_EXT_DMA_REQ_FLAG); + } + host->maxBlockCount = SDHC_HAL_MAX_BLOCK_COUNT; + + if (((config->transMode == kSdhcTransModeSdma) + && (!(host->caps & FSL_SDHC_HOST_CAPS_SUPPORT_DMA))) + || (((config->transMode == kSdhcTransModeAdma1) || + (config->transMode == kSdhcTransModeAdma2)) + && (!(host->caps & FSL_SDHC_HOST_CAPS_SUPPORT_ADMA))) + || (host->swFeature & FSL_SDHC_HOST_SW_FEATURE_NODMA)) + { + CLOCK_SYS_DisableSdhcClock(instance); + return kStatus_SDHC_HostNotSupport; + } + host->mode = config->transMode; + + /* enable irqs */ + SDHC_HAL_SetIntState(g_sdhcBase[instance], false, SDHC_INT_ALL_MASK); + SDHC_HAL_SetIntSignal(g_sdhcBase[instance], false, SDHC_INT_ALL_MASK); + irqEnabled = SDHC_HAL_CMD_INDEX_ERR_INT | SDHC_HAL_CMD_CRC_ERR_INT | + SDHC_HAL_CMD_END_BIT_ERR_INT | SDHC_HAL_CMD_TIMEOUT_ERR_INT | + SDHC_HAL_DATA_TIMEOUT_ERR_INT | SDHC_HAL_DATA_CRC_ERR_INT | + SDHC_HAL_DATA_END_BIT_ERR_INT | SDHC_HAL_CMD_COMPLETE_INT | + SDHC_HAL_DATA_COMPLETE_INT; +#if defined BSP_FSL_SDHC_ENABLE_AUTOCMD12 + irqEnabled |= SDHC_HAL_AUTO_CMD12_ERR_INT; +#endif + if ((host->cdType == kSdhcCardDetectCdPin) || + (host->cdType == kSdhcCardDetectDat3)) + { + irqEnabled |= (SDHC_HAL_CARD_INSERTION_INT | + SDHC_HAL_CARD_REMOVAL_INT); + } + if ((host->cdType == kSdhcCardDetectDat3) || + (host->cdType == kSdhcCardDetectPollDat3)) + { + sdhcConfig.enFlags |= SDHC_HAL_EN_D3CD_FLAG; + if (kStatus_SDHC_NoMedium == SDHC_DRV_DetectCard(instance)) + { + irqEnabled &= ~SDHC_HAL_CARD_REMOVAL_INT; + } + else + { + irqEnabled &= ~SDHC_HAL_CARD_INSERTION_INT; + } + } + + if (host->mode == kSdhcTransModeAdma2) + { + sdhcConfig.dmaMode = kSdhcHalDmaAdma2; +#if ! defined BSP_FSL_SDHC_USING_DYNALLOC + host->admaTableAddress = g_AdmaTableAddress[instance]; +#endif + } +#if defined BSP_FSL_SDHC_ENABLE_ADMA1 + else if (host->mode == kSdhcTransModeAdma1) + { + sdhcConfig.dmaMode = kSdhcHalDmaAdma1; +#if ! defined BSP_FSL_SDHC_USING_DYNALLOC + host->admaTableAddress = g_AdmaTableAddress[instance]; +#endif + } +#endif + else + { + sdhcConfig.dmaMode = kSdhcHalDmaSimple; + } + + SDHC_HAL_SetIntState(g_sdhcBase[instance], true, irqEnabled); + if ((host->cdType == kSdhcCardDetectPollDat3) || + (host->cdType == kSdhcCardDetectPollCd)) + { + irqEnabled &= ~(SDHC_HAL_CARD_REMOVAL_INT | + SDHC_HAL_CARD_INSERTION_INT); + } +#if defined BSP_FSL_SDHC_USING_IRQ + SDHC_HAL_SetIntSignal(g_sdhcBase[instance], true, irqEnabled); +#endif + +#if defined BSP_FSL_SDHC_USING_BIG_ENDIAN + host->endian = kSdhcHalEndianBig; +#else + host->endian = kSdhcHalEndianLittle; +#endif + + sdhcConfig.endianMode = host->endian; + + sdhcConfig.writeWatermarkLevel = 0x80; + sdhcConfig.readWatermarkLevel = 0x80; + SDHC_HAL_Config(g_sdhcBase[instance], &sdhcConfig); + + SDHC_DRV_SetBusWidth(instance, kSdhcBusWidth1Bit); + sdClkConfig.enable = true; + sdClkConfig.maxHostClk = host->maxClock; + sdClkConfig.destClk = config->clock; + SDHC_HAL_ConfigSdClock(g_sdhcBase[instance], &sdClkConfig); +#if defined BSP_FSL_SDHC_USING_IRQ + if (config->cardIntCallback) + { + host->cardIntCallback = config->cardIntCallback; + } + if (config->blockGapCallback) + { + host->blockGapCallback = config->blockGapCallback; + } + INT_SYS_EnableIRQ(g_sdhcIrqId[instance]); +#endif + return kStatus_SDHC_NoError; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_Shutdown + * Description: Deinitialize host controller + * + *END*********************************************************************/ +sdhc_status_t SDHC_DRV_Shutdown(uint32_t instance) +{ + sdhc_hal_sdclk_config_t sdClkConf; + if (g_hosts[instance] == 0) + { + return kStatus_SDHC_Failed; + } + +#if defined BSP_FSL_SDHC_USING_IRQ + INT_SYS_DisableIRQ(g_sdhcIrqId[instance]); +#endif + +#if defined BSP_FSL_SDHC_USING_DYNALLOC + if (g_hosts[instance]->admaTableAddress != NULL) + { + OSA_MemFree(g_hosts[instance]->admaTableAddress); + g_hosts[instance]->admaTableAddress = NULL; + g_hosts[instance]->admaTableMaxEntries = 0; + } +#endif + sdClkConf.enable = false; + SDHC_HAL_ConfigSdClock(g_sdhcBase[instance], &sdClkConf); + SDHC_DRV_SetClock(instance, false); + CLOCK_SYS_DisableSdhcClock(instance); + g_hosts[instance] = 0; + return kStatus_SDHC_NoError; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_DetectCard + * Description: check whether the card is present on specified host + * controller. + * + *END*********************************************************************/ +sdhc_status_t SDHC_DRV_DetectCard(uint32_t instance) +{ + assert(instance < SDHC_INSTANCE_COUNT); + volatile sdhc_host_t *host = g_hosts[instance]; + if (host->cdType == kSdhcCardDetectGpio) + { + return kStatus_SDHC_UnknownStatus; + } + + SDHC_DRV_SetClock(instance, true); + if (!SDHC_DRV_IsCardPresent(instance)) + { + host->flags &= (uint32_t)(~FSL_SDHC_HOST_FLAGS_CARD_PRESENTED); + SDHC_DRV_SetClock(instance, false); + return kStatus_SDHC_NoMedium; + } + host->flags |= FSL_SDHC_HOST_FLAGS_CARD_PRESENTED; + SDHC_HAL_InitCard(g_sdhcBase[instance], 100); + SDHC_DRV_SetClock(instance, false); + return kStatus_SDHC_NoError; +} + +/*FUNCTION**************************************************************** + * + * Function Name: SDHC_DRV_IssueRequestBlocking + * Description: Isuue request on specific host controller and return + * on completion. + * + *END*********************************************************************/ +sdhc_status_t SDHC_DRV_IssueRequestBlocking(uint32_t instance, + sdhc_request_t *req, + uint32_t timeoutInMs) +{ + sdhc_status_t ret; + volatile sdhc_host_t *host; + + assert(instance < SDHC_INSTANCE_COUNT); + assert(req); + + /* Wait until last time sdhc send operation complete */ + while(!SDHC_HAL_GetCurState(g_sdhcBase[instance], kSdhcHalGetDataLine0Level)){} + + host = g_hosts[instance]; + ret = kStatus_SDHC_NoError; + req->error = 0; + + if ((req->data) && (req->data->blockSize % 4)) + { + return kStatus_SDHC_BlockSizeNotSupportError; + } + + if ((req->data) && (host->mode != kSdhcTransModePio)) + { + if (kStatus_SDHC_NoError == SDHC_DRV_PrepareData(instance, req)) + { + req->flags |= FSL_SDHC_REQ_FLAGS_USE_DMA; + } + } + +#if defined BSP_FSL_SDHC_USING_IRQ + osa_status_t status; +#if defined BSP_FSL_SDHC_USING_DYNALLOC + semaphore_t *complete = + (semaphore_t *)OSA_MemAllocZero(sizeof(semaphore_t)); + if (kStatus_OSA_Success != OSA_SemaCreate(complete, 0)) + { + return kStatus_SDHC_Failed; + } + assert(!req->complete); /* it should not be asigned outside of this routine */ + req->complete = complete; +#else + semaphore_t complete = {0}; + if (kStatus_OSA_Success != OSA_SemaCreate(&complete, 0)) + { + return kStatus_SDHC_Failed; + } + req->complete = &complete; +#endif +#endif + + SDHC_DRV_SetClock(instance, true); + + if (host->currentReq) + { + req->error |= FSL_SDHC_REQ_ERR_HOST_BUSY; + SDHC_DRV_SetClock(instance, false); +#if defined BSP_FSL_SDHC_USING_IRQ + OSA_SemaDestroy(req->complete); +#if defined BSP_FSL_SDHC_USING_DYNALLOC + OSA_MemFree(req->complete); +#endif + req->complete = NULL; +#endif + return kStatus_SDHC_HostIsBusyError; + } + + host->currentReq = req; + + if (kStatus_SDHC_NoError != SDHC_DRV_SendCommand(instance, req)) + { + host->currentReq = 0; + SDHC_DRV_SetClock(instance, false); + req->error |= FSL_SDHC_REQ_ERR_SEND_CMD; +#if defined BSP_FSL_SDHC_USING_IRQ + OSA_SemaDestroy(req->complete); +#if defined BSP_FSL_SDHC_USING_DYNALLOC + OSA_MemFree(req->complete); +#endif + req->complete = NULL; +#endif + return kStatus_SDHC_Failed; + } + +#if defined BSP_FSL_SDHC_USING_IRQ + do + { + if (!timeoutInMs) + { + status = OSA_SemaWait(req->complete, OSA_WAIT_FOREVER); + } + else + { + status = OSA_SemaWait(req->complete, timeoutInMs); + } + } while (status == kStatus_OSA_Idle); + + if (status != kStatus_OSA_Success) + { + req->error |= FSL_SDHC_REQ_ERR_TIMEOUT; + } + + OSA_SemaDestroy(req->complete); +#if defined BSP_FSL_SDHC_USING_DYNALLOC + OSA_MemFree(req->complete); +#endif + req->complete = NULL; +#else /* BSP_FSL_SDHC_USING_IRQ */ + uint32_t mask = 0, irqFlags = 0, i; + mask = SDHC_HAL_CMD_COMPLETE_INT | SDHC_HAL_CMD_ERR_INT; + if (kStatus_SDHC_NoError != SDHC_DRV_WaitInt(instance, mask, &irqFlags, timeoutInMs)) + { + host->currentReq = 0; + SDHC_DRV_SetClock(instance, false); + SDHC_DRV_SetRequestError(req, irqFlags); + return kStatus_SDHC_Failed; + } + + if (irqFlags != SDHC_HAL_CMD_COMPLETE_INT) + { + SDHC_HAL_ClearIntFlags(g_sdhcBase[instance], mask); + host->currentReq = 0; + SDHC_DRV_SetClock(instance, false); + SDHC_DRV_SetRequestError(req, irqFlags); + return kStatus_SDHC_Failed; + } + + SDHC_HAL_ClearIntFlags(g_sdhcBase[instance], SDHC_HAL_CMD_COMPLETE_INT); + if (g_req_resp_flags[req->respType] & FSL_SDHC_REQ_RSPTYPE_PRESENT) + { + req->response[0] = SDHC_HAL_GetResponse(g_sdhcBase[instance], 0); + if (!(g_req_resp_flags[req->respType] & FSL_SDHC_REQ_RSPTYPE_136BITS)) + { + if ((req->respType == kSdhcRespTypeR1) || + (req->respType == kSdhcRespTypeR1b)) + { + req->cardErrStatus = SDHC_R1_ERROR_BITS(req->response[0]); + } + } + else + { + req->response[1] = SDHC_HAL_GetResponse(g_sdhcBase[instance], 1); + req->response[2] = SDHC_HAL_GetResponse(g_sdhcBase[instance], 2); + req->response[3] = SDHC_HAL_GetResponse(g_sdhcBase[instance], 3); + i = 4; + do { + req->response[i - 1] <<= 8; + if (i > 1) + { + req->response[i - 1] |= + ((req->response[i-2] & 0xFF000000U) >> 24); + } + } while(i--); + } + } + + if ((!req->cardErrStatus) && (req->data)) + { + ret = SDHC_DRV_TransferData(instance, req, timeoutInMs); + } +#endif /* ! BSP_FSL_SDHC_USING_IRQ */ + + if (req->cardErrStatus) + { + ret = kStatus_SDHC_RequestCardStatusError; + } + + if (req->error) + { + ret = kStatus_SDHC_RequestFailed; + } + + host->currentReq = 0; + SDHC_DRV_SetClock(instance, false); + return ret; +} +#endif + +/************************************************************************************************* + * EOF + ************************************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/sdhc/fsl_sdhc_irq.c b/KSDK_1.2.0/platform/drivers/src/sdhc/fsl_sdhc_irq.c new file mode 100755 index 0000000..515a26b --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/sdhc/fsl_sdhc_irq.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_sdhc_driver.h" +#if FSL_FEATURE_SOC_SDHC_COUNT + +#if (FSL_RTOS_MQX) +void MQX_SDHC_IRQHandler(void) +{ +#if defined BSP_FSL_SDHC_USING_IRQ + SDHC_DRV_DoIrq(0); +#endif +} +#else +void SDHC_IRQHandler(void) +{ +#if defined BSP_FSL_SDHC_USING_IRQ + SDHC_DRV_DoIrq(0); +#endif +} +#endif +#endif diff --git a/KSDK_1.2.0/platform/drivers/src/sdhc/fsl_sdhc_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/sdhc/fsl_sdhc_lpm_callback.c new file mode 100755 index 0000000..d9c9608 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/sdhc/fsl_sdhc_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_SDHC_COUNT + +power_manager_error_code_t sdhc_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t sdhc_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_common.c b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_common.c new file mode 100755 index 0000000..2ab3275 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_common.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_SPI_COUNT +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Pointer to runtime state structure.*/ +void * g_spiStatePtr[SPI_INSTANCE_COUNT] = { NULL }; + +/*! @brief Table of base pointers for SPI instances. */ +SPI_Type * const g_spiBase[SPI_INSTANCE_COUNT] = SPI_BASE_PTRS; + +/*! @brief Table of SPI FIFO sizes per instance. */ +const uint32_t g_spiFifoSize[SPI_INSTANCE_COUNT] = FSL_FEATURE_SPI_FIFO_SIZEx; + +/*! + * @brief Table to save SPI IRQ enum numbers defined in CMSIS files. + * + * This is used by SPI master and slave init functions to enable or disable SPI interrupts. + * This table is indexed by the module instance number and returns SPI IRQ numbers. + */ +const IRQn_Type g_spiIrqId[SPI_INSTANCE_COUNT] = SPI_IRQS; + +#endif /* FSL_FEATURE_SOC_SPI_COUNT */ +/******************************************************************************* +* EOF +******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_dma_irq.c b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_dma_irq.c new file mode 100755 index 0000000..caec192 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_dma_irq.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <stdbool.h> +#include "fsl_spi_shared_function.h" +#include "fsl_device_registers.h" + +/*! + * @addtogroup spi_irq + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if (SPI_INSTANCE_COUNT == 1) +/*! + * @brief This function is the implementation of SPI0 handler named in startup code. + * + * It passes the instance to the shared SPI DMA IRQ handler. + */ +void SPI0_IRQHandler(void) +{ + SPI_DRV_DmaIRQHandler(SPI0_IDX); +} + +#else +/*! + * @brief This function is the implementation of SPI0 handler named in startup code. + * + * It passes the instance to the shared SPI DMA IRQ handler. + */ +void SPI0_IRQHandler(void) +{ + SPI_DRV_DmaIRQHandler(SPI0_IDX); +} + +/*! + * @brief This function is the implementation of SPI1 handler named in startup code. + * + * It passes the instance to the shared SPI DMA IRQ handler. + */ +void SPI1_IRQHandler(void) +{ + SPI_DRV_DmaIRQHandler(SPI1_IDX); +} +#endif + +/*! @} */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_dma_master_driver.c b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_dma_master_driver.c new file mode 100755 index 0000000..af8de81 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_dma_master_driver.c @@ -0,0 +1,885 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string.h> +#include "fsl_spi_dma_master_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_SPI_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ +uint32_t g_interruptCnt = 0; +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Pointer to runtime state structure.*/ +extern void * g_spiStatePtr[SPI_INSTANCE_COUNT]; + +static uint8_t s_byteToSend; /* Word to send, if no send buffer, this variable is used + as the word to send, which should be initialized to 0. Needs + to be static and stored in data section as this variable + address is the DMA source address if no source buffer. */ + +static uint8_t s_rxBuffIfNull; /* If no receive buffer provided, direct rx DMA channel to this + destination */ + +/* Table of SPI FIFO sizes per instance. */ +extern const uint32_t g_spiFifoSize[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +spi_status_t SPI_DRV_DmaMasterStartTransfer(uint32_t instance, + const spi_dma_master_user_config_t * device); + +static void SPI_DRV_DmaMasterCompleteTransfer(uint32_t instance); + +void SPI_DRV_DmaMasterCallback(void *param, dma_channel_status_t chanStatus); + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaMasterCallback + * Description : This function is called when the DMA generates an interrupt. + * The DMA generates an interrupt when the channel is "done", meaning that the + * expected number of bytes have been transferred. When the interrupt occurs, + * the DMA will jump to this callback as it was registered in the DMA register + * callback service function. The user will defined their own callback function + * to take whatever action they deem necessary for handling the end of a transfer. + * For example, the user may simply want their callback function to set a global + * flag to indicate that the transfer is complete. The user defined callback + * is passed in through the "param" parameter. + * The parameter chanStatus is currently not used. + * + *END**************************************************************************/ +void SPI_DRV_DmaMasterCallback(void *param, dma_channel_status_t chanStatus) +{ + uint32_t instance = (uint32_t)(param); + + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_dma_master_state_t * spiDmaState = (spi_dma_master_state_t *)g_spiStatePtr[instance]; + + SPI_Type *base = g_spiBase[instance]; + + /* If the extraByte flag was set, need to enable the TX empty interrupt to get the last byte */ + if (spiDmaState->extraByte) + { + SPI_HAL_SetTxDmaCmd(base, false); + + /* If the TX buffer is already empty then it may not generate an interrupt so soon + * after the TX DMA is disabled, therefore read the RX data and put into RX buffer. + */ + if (SPI_HAL_GetIntStatusFlag(base, kSpiTxBufferEmptyFlag)) + { +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + /* If the SPI module contains a FIFO (and if it is enabled), check the FIFO empty flag */ + if ((g_spiFifoSize[instance] != 0) && (SPI_HAL_GetFifoCmd(base))) + { + /* Wait till the rx buffer has data */ + while (SPI_HAL_GetFifoStatusFlag(base, kSpiRxFifoEmpty) == 1) {} + + } + else /* Check the read pending flag */ + { + /* Wait till the rx buffer has data */ + while (SPI_HAL_IsReadBuffFullPending(base) == 0) {} + } + + /* If there is a receive buffer, copy the final byte from the SPI data register + * to the receive buffer + */ + if (spiDmaState->receiveBuffer) + { + spiDmaState->receiveBuffer[spiDmaState->transferByteCnt-2] = + SPI_HAL_ReadDataLow(base); + } + /* Else, read out the data register and throw away the bytes read */ + else + { + /* Read and throw away the lower data buffer to clear it out */ + s_rxBuffIfNull = SPI_HAL_ReadDataLow(base); + } + /* Read and throw away the upper data buffer to clear it out */ + s_rxBuffIfNull = SPI_HAL_ReadDataHigh(base); + SPI_DRV_DmaMasterCompleteTransfer(instance); +#endif + } + else + { + /* Else, if the TX buffer is not empty, enable the interrupt and handle the + * receive in the ISR + */ + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, true); + } + } + else /* If no extra byte is needing to be receive, complete the transfer */ + { + SPI_DRV_DmaMasterCompleteTransfer(instance); + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaMasterInit + * Description : Initializes a SPI instance for master mode operation to work with DMA. + * This function uses a dma driven method for transferring data. + * this function initializes the run-time state structure to track the ongoing + * transfers, ungates the clock to the SPI module, resets the SPI module, initializes the module + * to user defined settings and default settings, configures the IRQ state structure, enables + * the module-level interrupt to the core, and enables the SPI module. + * + * This initialization function also configures the DMA module by requesting channels for DMA + * operation. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_DmaMasterInit(uint32_t instance, spi_dma_master_state_t * spiDmaState) +{ + SPI_Type *base = g_spiBase[instance]; + + /* Clear the state for this instance.*/ + memset(spiDmaState, 0, sizeof(* spiDmaState)); + + /* Enable clock for SPI*/ + CLOCK_SYS_EnableSpiClock(instance); + + /* configure the run-time state struct with the source clock value */ + spiDmaState->spiSourceClock = CLOCK_SYS_GetSpiFreq(instance); + + /* Reset the SPI module to it's default state, which includes SPI disabled */ + SPI_HAL_Init(base); + + /* Init the interrupt sync object.*/ + OSA_SemaCreate(&spiDmaState->irqSync, 0); + + /* Set SPI to master mode */ + SPI_HAL_SetMasterSlave(base, kSpiMaster); + + /* Set slave select to automatic output mode */ + SPI_HAL_SetSlaveSelectOutputMode(base, kSpiSlaveSelect_AutomaticOutput); + + /* Set the SPI pin mode to normal mode */ + SPI_HAL_SetPinMode(base, kSpiPinMode_Normal); + +#if FSL_FEATURE_SPI_FIFO_SIZE + if (g_spiFifoSize[instance] != 0) + { + /* If SPI module contains a FIFO, enable it and set watermarks to half full/empty */ + SPI_HAL_SetFifoMode(base, true, kSpiTxFifoOneHalfEmpty, kSpiRxFifoOneHalfFull); + + /* Set the interrupt clearing mechansim select for later use in driver to clear + * status flags + */ + SPI_HAL_SetIntClearCmd(base, true); + } +#endif + /* Save runtime structure pointers to irq handler can point to the correct state structure*/ + g_spiStatePtr[instance] = spiDmaState; + + /***************************************** + * Request DMA channel for RX and TX FIFO + *****************************************/ + /* This channel transfers data from RX FIFO to receiveBuffer */ + if (instance == 0) + { + /* Request DMA channel for RX FIFO */ + DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI0Rx, &spiDmaState->dmaReceive); + /* Request DMA channel for TX FIFO */ + DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI0Tx, &spiDmaState->dmaTransmit); + } +#if (SPI_INSTANCE_COUNT > 1) + else + { + /* Request DMA channel for RX FIFO */ + DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI1Rx, &spiDmaState->dmaReceive); + /* Request DMA channel for TX FIFO */ + DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI1Tx, &spiDmaState->dmaTransmit); + } +#endif + + /* Enable SPI interrupt.*/ + INT_SYS_EnableIRQ(g_spiIrqId[instance]); + + /* SPI system Enable */ + SPI_HAL_Enable(base); + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaMasterDeinit + * Description : Shuts down a SPI instance with DMA support. + * + * This function resets the SPI peripheral, gates its clock, disables any used interrupts to + * the core, and releases any used DMA channels. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_DmaMasterDeinit(uint32_t instance) +{ + /* instantiate local variable of type spi_dma_master_state_t and point to global state */ + spi_dma_master_state_t * spiDmaState = (spi_dma_master_state_t *)g_spiStatePtr[instance]; + SPI_Type *base = g_spiBase[instance]; + + /* Restore the module to defaults which includes disabling the SPI then power it down.*/ + SPI_HAL_Init(base); + + /* destroy the interrupt sync object.*/ + OSA_SemaDestroy(&spiDmaState->irqSync); + + /* Disable SPI interrupt.*/ + INT_SYS_DisableIRQ(g_spiIrqId[instance]); + + /* Gate the clock for SPI.*/ + CLOCK_SYS_DisableSpiClock(instance); + + /* Free DMA channels */ + DMA_DRV_FreeChannel(&spiDmaState->dmaReceive); + DMA_DRV_FreeChannel(&spiDmaState->dmaTransmit); + + /* Clear state pointer. */ + g_spiStatePtr[instance] = NULL; + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaMasterConfigureBus + * Description : Configures the SPI port to access a device on the bus with DMA support. + * + * The term "device" is used to indicate the SPI device for which the SPI master is communicating. + * The user has two options to configure the device parameters: either pass in the + * pointer to the device configuration structure to the desired transfer function or pass it in to + * the SPI_DRV_DmaMasterConfigureBus function. The user can pass in a device structure to the + * transfer function which contains the parameters for the bus (the transfer function then calls + * this function). However, the user has the option to call this function directly especially + * to get the calculated baud rate, at which point they may pass in NULL for the device + * structure in the transfer function (assuming they have called this configure bus function + * first). + * + *END**************************************************************************/ +void SPI_DRV_DmaMasterConfigureBus(uint32_t instance, + const spi_dma_master_user_config_t * device, + uint32_t * calculatedBaudRate) +{ + assert(device); + + /* instantiate local variable of type spi_dma_master_state_t and point to global state */ + spi_dma_master_state_t * spiDmaState = (spi_dma_master_state_t *)g_spiStatePtr[instance]; + + SPI_Type *base = g_spiBase[instance]; + + /* Configure the bus to access the provided device.*/ + *calculatedBaudRate = SPI_HAL_SetBaud(base, device->bitsPerSec, + spiDmaState->spiSourceClock); + SPI_HAL_SetDataFormat(base, device->polarity, device->phase, device->direction); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + SPI_HAL_Set8or16BitMode(base, device->bitCount); +#endif + +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaMasterTransferBlocking + * Description : Performs a blocking SPI master mode transfer with DMA support. + * + * This function simultaneously sends and receives data on the SPI bus, as SPI is naturally + * a full-duplex bus. The function does return until the transfer is complete. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_DmaMasterTransferBlocking(uint32_t instance, + const spi_dma_master_user_config_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount, + uint32_t timeout) +{ + /* instantiate local variable of type spi_dma_master_state_t and point to global state */ + spi_dma_master_state_t * spiDmaState = (spi_dma_master_state_t *)g_spiStatePtr[instance]; + spi_status_t errorStatus = kStatus_SPI_Success; + SPI_Type *base = g_spiBase[instance]; + + /* fill in members of the run-time state struct*/ + spiDmaState->isTransferBlocking = true; /* Indicates this is a blocking transfer */ + spiDmaState->sendBuffer = (const uint8_t *)sendBuffer; + spiDmaState->receiveBuffer = (uint8_t *)receiveBuffer; + spiDmaState->remainingSendByteCount = transferByteCount; + spiDmaState->remainingReceiveByteCount = transferByteCount; + + /* start the transfer process*/ + errorStatus = SPI_DRV_DmaMasterStartTransfer(instance, device); + if (errorStatus != kStatus_SPI_Success) + { + return errorStatus; + } + + /* As this is a synchronous transfer, wait until the transfer is complete.*/ + osa_status_t syncStatus; + + do + { + syncStatus = OSA_SemaWait(&spiDmaState->irqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + /* If a timeout occurs, stop the transfer by setting the isTransferInProgress to false and + * disabling DMA requests and interrupts, then return the timeout error status. + */ + if (syncStatus != kStatus_OSA_Success) + { + /* The transfer is complete.*/ + spiDmaState->isTransferInProgress = false; + + /* Disable DMA requests and interrupts. */ + SPI_HAL_SetRxDmaCmd(base, false); + SPI_HAL_SetTxDmaCmd(base, false); + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, false); + + errorStatus = kStatus_SPI_Timeout; + } + + return errorStatus; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaMasterTransfer + * Description : Performs a non-blocking SPI master mode transfer with DMA support. + * + * This function returns immediately. It is the user's responsibility to check back to + * ascertain if the transfer is complete (using the SPI_DRV_DmaMasterGetTransferStatus function). + * This function simultaneously sends and receives data on the SPI bus, as SPI is naturally + * a full-duplex bus. The function does return until the transfer is complete. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_DmaMasterTransfer(uint32_t instance, + const spi_dma_master_user_config_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount) +{ + /* instantiate local variable of type spi_dma_master_state_t and point to global state */ + spi_dma_master_state_t * spiDmaState = (spi_dma_master_state_t *)g_spiStatePtr[instance]; + spi_status_t errorStatus = kStatus_SPI_Success; + + /* fill in members of the run-time state struct*/ + spiDmaState->isTransferBlocking = false; /* Indicates this is a non-blocking transfer */ + spiDmaState->sendBuffer = sendBuffer; + spiDmaState->receiveBuffer = (uint8_t *)receiveBuffer; + spiDmaState->remainingSendByteCount = transferByteCount; + spiDmaState->remainingReceiveByteCount = transferByteCount; + + errorStatus = SPI_DRV_DmaMasterStartTransfer(instance, device); + if (errorStatus != kStatus_SPI_Success) + { + return errorStatus; + } + + /* Else, return immediately as this is an async transfer */ + return kStatus_SPI_Success; +} + +/*! + * @brief Initiate (start) a transfer using DMA. This is not a public API as it is called from + * other driver functions + */ +spi_status_t SPI_DRV_DmaMasterStartTransfer(uint32_t instance, + const spi_dma_master_user_config_t * device) +{ + /* instantiate local variable of type spi_dma_master_state_t and point to global state */ + spi_dma_master_state_t * spiDmaState = (spi_dma_master_state_t *)g_spiStatePtr[instance]; + + /* For temporarily storing DMA register channel */ + uint8_t txChannel, rxChannel; + void * param; + uint32_t calculatedBaudRate; + SPI_Type *base = g_spiBase[instance]; + uint32_t transferSizeInBytes; /* DMA transfer size in bytes */ + + /* Initialize s_byteToSend */ + s_byteToSend = 0; + + /* If the transfer count is zero, then return immediately.*/ + if (spiDmaState->remainingSendByteCount == 0) + { + /* Signal the synchronous completion object if the transfer wasn't async. + * Otherwise, when we return the the sync function we'll get stuck in the sync wait loop. + */ + if (spiDmaState->isTransferBlocking) + { + OSA_SemaPost(&spiDmaState->irqSync); + } + + return kStatus_SPI_Success; + } + + /* Configure bus for this device. If NULL is passed, we assume the caller has + * preconfigured the bus using SPI_DRV_DmaMasterConfigureBus(). + * Do nothing for calculatedBaudRate. If the user wants to know the calculatedBaudRate + * then they can call this function separately. + */ + if (device) + { + SPI_DRV_DmaMasterConfigureBus(instance, device, &calculatedBaudRate); + } + + /* In order to flush any remaining data in the shift register, disable then enable the SPI */ + SPI_HAL_Disable(base); + SPI_HAL_Enable(base); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + /* Check the transfer byte count. If bits/frame > 8, meaning 2 bytes, and if + * the transfer byte count is an odd count we'll have to round down the RX transfer byte count + * to the next lowest even number by one and assert a flag to indicate in the interrupt handler + * that we take care of sending and receiving this last byte. We'll round up TX byte count. + */ + if (SPI_HAL_Get8or16BitMode(base) == kSpi16BitMode) /* Applies to 16-bit transfers */ + { + /* Odd byte count for 16-bit transfers, set the extraByte flag */ + if (spiDmaState->remainingSendByteCount & 1UL) /* If odd byte count */ + { + transferSizeInBytes = 2; /* Set transfer size to two bytes for the DMA operation */ + spiDmaState->extraByte = true; /* Set the extraByte flag */ + + /* Round up TX byte count so when DMA completes, all data would've been sent */ + spiDmaState->remainingSendByteCount += 1U; +// spiDmaState->remainingSendByteCount &= ~1U; + + /* Round down RX byte count which means at the end of the RX DMA transfer, we'll need + * to set up an interrupt to get the last byte. + */ + spiDmaState->remainingReceiveByteCount &= ~1U; + + /* Store the transfer byte count to the run-time state struct + * for later use in the interrupt handler. + */ + spiDmaState->transferByteCnt = spiDmaState->remainingSendByteCount; + } + /* Even byte count for 16-bit transfers, clear the extraByte flag */ + else + { + transferSizeInBytes = 2; /* Set transfer size to two bytes for the DMA operation */ + spiDmaState->extraByte = false; /* Clear the extraByte flag */ + } + } + else /* For 8-bit transfers */ + { + transferSizeInBytes = 1; + spiDmaState->extraByte = false; + } +#else + transferSizeInBytes = 1; +#endif + + param = (void *)(instance); /* For DMA callback, set "param" as the SPI instance number */ + rxChannel = spiDmaState->dmaReceive.channel; + txChannel = spiDmaState->dmaTransmit.channel; + /* Only need to set the DMA reg base addr once since it should be the same for all code */ + DMA_Type *dmabase = g_dmaBase[rxChannel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + DMAMUX_Type *dmamuxbase = g_dmamuxBase[txChannel/FSL_FEATURE_DMAMUX_MODULE_CHANNEL]; + + /* Check that we're not busy.*/ + if (spiDmaState->isTransferInProgress) + { + return kStatus_SPI_Busy; + } + + /* Save information about the transfer for use by the ISR.*/ + spiDmaState->isTransferInProgress = true; + + /* The DONE needs to be cleared before programming the channel's TCDs for the next + * transfer. + */ + DMA_HAL_ClearStatus(dmabase, rxChannel); + DMA_HAL_ClearStatus(dmabase, txChannel); + + /* Disable and enable the TX and RX DMA channel at the DMA mux. Doing so will prevent an + * inadvertent DMA transfer when the TX and RX DMA channel ERQ bit is set after having been + * cleared from a previous DMA transfer (clearing of the ERQ bit is automatically performed + * at the end of a transfer when D_REQ is set). + */ + DMAMUX_HAL_SetChannelCmd(dmamuxbase, txChannel, false); + DMAMUX_HAL_SetChannelCmd(dmamuxbase, txChannel, true); + DMAMUX_HAL_SetChannelCmd(dmamuxbase, rxChannel, false); + DMAMUX_HAL_SetChannelCmd(dmamuxbase, rxChannel, true); + + /************************************************************************************ + * Set up the RX DMA channel Transfer Control Descriptor (TCD) + * Note, if there is no receive byte count, then bypass RX DMA set up. + ***********************************************************************************/ + if (spiDmaState->remainingReceiveByteCount) + { + /* If no receive buffer then disable incrementing the destination and set the destination + * to a temporary location + */ + if (!spiDmaState->receiveBuffer) + { + /* Set up this channel's control which includes enabling the DMA interrupt */ + DMA_DRV_ConfigTransfer(&spiDmaState->dmaReceive, + kDmaPeripheralToMemory, + transferSizeInBytes, + SPI_HAL_GetDataRegAddr(base), /* src is data register */ + (uint32_t)(&s_rxBuffIfNull), /* dest is temporary location */ + (uint32_t)(spiDmaState->remainingReceiveByteCount)); + + /* Do not increment the destination address */ + DMA_HAL_SetDestIncrementCmd(dmabase, rxChannel, false); + } + else + { + /* Set up this channel's control which includes enabling the DMA interrupt */ + DMA_DRV_ConfigTransfer(&spiDmaState->dmaReceive, + kDmaPeripheralToMemory, + transferSizeInBytes, + SPI_HAL_GetDataRegAddr(base), /* src is data register */ + (uint32_t)(spiDmaState->receiveBuffer),/* dest is rx buffer */ + (uint32_t)(spiDmaState->remainingReceiveByteCount)); + } + + /* For SPI16 modules, if the bits/frame is 16, then we need to adjust the destination + * size to still be 8-bits since the DMA_DRV_ConfigTransfer sets this to 16-bits, but + * we always provide a 8-bit buffer. + */ + if (transferSizeInBytes == 2) + { + DMA_HAL_SetDestTransferSize(dmabase, rxChannel, kDmaTransfersize8bits); + } + + /* Enable the cycle steal mode which forces a single read/write transfer per request */ + DMA_HAL_SetCycleStealCmd(dmabase, rxChannel, true); + + /* Enable the DMA peripheral request */ + DMA_DRV_StartChannel(&spiDmaState->dmaReceive); + + /* Register callback for DMA interrupt */ + DMA_DRV_RegisterCallback(&spiDmaState->dmaReceive, SPI_DRV_DmaMasterCallback, param); + + /* Enable the SPI RX DMA Request after the TX DMA request is enabled. This is done to + * make sure that the RX DMA channel does not end prematurely before we've completely set + * up the TX DMA channel since part of the TX DMA set up involves placing 1 or 2 bytes of + * data into the send data register which causes an immediate transfer. + */ + } + + /************************************************************************************ + * Set up the TX DMA channel Transfer Control Descriptor (TCD) + * Note, if there is no source buffer (if user passes in NULL), then send zeros + ***********************************************************************************/ + /* Per the reference manual, before enabling the SPI transmit DMA request, we first need + * to read the status register and then write to the SPI data register. Afterwards, we need + * to decrement the sendByteCount and perform other driver maintenance functions. + */ + + /* Read the SPI Status register */ + SPI_HAL_IsTxBuffEmptyPending(base); + + /* Start the transfer by writing the first byte/word to the SPI data register. + * If a send buffer was provided, the byte/word comes from there. Otherwise we just send zeros. + * This will cause an immeidate transfer which in some cases may cause the RX DMA channel to + * complete before having the chance to completely set up the TX DMA channel. As such, we'll + * enable the RX DMA channel last. + */ +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if (transferSizeInBytes == 2) /* 16-bit transfers for SPI16 module */ + { + if (spiDmaState->sendBuffer) + { + s_byteToSend = *(spiDmaState->sendBuffer); + SPI_HAL_WriteDataLow(base, s_byteToSend); + ++spiDmaState->sendBuffer; + + s_byteToSend = *(spiDmaState->sendBuffer); + SPI_HAL_WriteDataHigh(base, s_byteToSend); + ++spiDmaState->sendBuffer; + } + else /* Else, if no send buffer, write zeros */ + { + SPI_HAL_WriteDataLow(base, s_byteToSend); + SPI_HAL_WriteDataHigh(base, s_byteToSend); + } + spiDmaState->remainingSendByteCount -= 2; /* Decrement the send byte count by 2 */ + } + else /* 8-bit transfers for SPI16 module */ + { + if (spiDmaState->sendBuffer) + { + s_byteToSend = *(spiDmaState->sendBuffer); + ++spiDmaState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, s_byteToSend); /* If no send buffer, s_byteToSend=0 */ + --spiDmaState->remainingSendByteCount; /* Decrement the send byte count */ + } +#else + /* For SPI modules that do not support 16-bit transfers */ + if (spiDmaState->sendBuffer) + { + s_byteToSend = *(spiDmaState->sendBuffer); + ++spiDmaState->sendBuffer; + } + SPI_HAL_WriteData(base, s_byteToSend); /* If no send buffer, s_byteToSend=0 */ + --spiDmaState->remainingSendByteCount; /* Decrement the send byte count */ +#endif + + /* If there are no more bytes to send then return without setting up the TX DMA channel + * and let the receive DMA channel complete the transfer if the RX DMA channel was setup. + * If the RX DMA channel was not set up (due to odd byte count of 1 in 16-bit mode), enable + * the interrupt to get the received byte. + */ + if (!spiDmaState->remainingSendByteCount) /* No more bytes to send */ + { + if (spiDmaState->remainingReceiveByteCount) + { + /* Enable the RX DMA channel request now */ + SPI_HAL_SetRxDmaCmd(base, true); + return kStatus_SPI_Success; + } + else /* If RX DMA chan not setup then enable the interrupt to get the received byte */ + { + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, true); + return kStatus_SPI_Success; + } + } + /* Else, since there are more bytes to send, go ahead and set up the TX DMA channel */ + else + { + /* If there is a send buffer, data comes from there, else send 0 */ + if (spiDmaState->sendBuffer) + { + /* Set up this channel's control which includes enabling the DMA interrupt */ + DMA_DRV_ConfigTransfer(&spiDmaState->dmaTransmit, kDmaMemoryToPeripheral, + transferSizeInBytes, + (uint32_t)(spiDmaState->sendBuffer), + SPI_HAL_GetDataRegAddr(base), + (uint32_t)(spiDmaState->remainingSendByteCount)); + } + else /* Configure TX DMA channel to send zeros */ + { + /* Set up this channel's control which includes enabling the DMA interrupt */ + DMA_DRV_ConfigTransfer(&spiDmaState->dmaTransmit, kDmaMemoryToPeripheral, + transferSizeInBytes, + (uint32_t)(&s_byteToSend), + SPI_HAL_GetDataRegAddr(base), + (uint32_t)(spiDmaState->remainingSendByteCount)); + + /* Now clear SINC since we are only sending zeroes, don't increment source */ + DMA_HAL_SetSourceIncrementCmd(dmabase, txChannel, false); + } + + /* For SPI16 modules, if the bits/frame is 16, then we need to adjust the source + * size to still be 8-bits since the DMA_DRV_ConfigTransfer sets this to 16-bits, but + * we always provide a 8-bit buffer. + */ + if (transferSizeInBytes == 2) + { + DMA_HAL_SetSourceTransferSize(dmabase, txChannel, kDmaTransfersize8bits); + } + + /* Enable the cycle steal mode which forces a single read/write transfer per request */ + DMA_HAL_SetCycleStealCmd(dmabase, txChannel, true); + + /* Now, disable the TX chan interrupt since we'll use the RX chan interrupt */ + DMA_HAL_SetIntCmd(dmabase, txChannel, false); + + /* Enable the DMA peripheral request */ + DMA_DRV_StartChannel(&spiDmaState->dmaTransmit); + + /* Enable the SPI TX DMA Request */ + SPI_HAL_SetTxDmaCmd(base, true); + + /* Enable the SPI RX DMA Request after the TX DMA request is enabled. This is done to + * make sure that the RX DMA channel does not end prematurely before we've completely set + * up the TX DMA channel since part of the TX DMA set up involves placing 1 or 2 bytes of + * data into the send data register which causes an immediate transfer. + */ + SPI_HAL_SetRxDmaCmd(base, true); + } + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaMasterGetTransferStatus + * Description : Returns whether the previous transfer finished with DMA support. + * + * When performing an a-sync transfer, the user can call this function to ascertain the state of the + * current transfer: in progress (or busy) or complete (success). In addition, if the transfer + * is still in progress, the user can get the number of words that have been + * transferred up to now. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_DmaMasterGetTransferStatus(uint32_t instance, + uint32_t * bytesTransferred) +{ + /* instantiate local variable of type spi_dma_master_state_t and point to global state */ + spi_dma_master_state_t * spiDmaState = (spi_dma_master_state_t *)g_spiStatePtr[instance]; + + /* Fill in the bytes transferred.*/ + if (bytesTransferred) + { + *bytesTransferred = spiDmaState->remainingSendByteCount - + DMA_DRV_GetUnfinishedBytes(&spiDmaState->dmaTransmit); + } + + return (spiDmaState->isTransferInProgress ? kStatus_SPI_Busy : kStatus_SPI_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaMasterAbortTransfer + * Description : Terminates an asynchronous transfer early with DMA support. + * + * During an async transfer, the user has the option to terminate the transfer early if the transfer + * is still in progress. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_DmaMasterAbortTransfer(uint32_t instance) +{ + /* instantiate local variable of type spi_dma_master_state_t and point to global state */ + spi_dma_master_state_t * spiDmaState = (spi_dma_master_state_t *)g_spiStatePtr[instance]; + + /* Check if a transfer is running.*/ + if (!spiDmaState->isTransferInProgress) + { + return kStatus_SPI_NoTransferInProgress; + } + + /* Stop the running transfer.*/ + SPI_DRV_DmaMasterCompleteTransfer(instance); + + return kStatus_SPI_Success; +} + +/*! + * @brief Finish up a transfer. + * Cleans up after a transfer is complete. Interrupts are disabled, and the SPI module + * is disabled. This is not a public API as it is called from other driver functions. + */ +static void SPI_DRV_DmaMasterCompleteTransfer(uint32_t instance) +{ + /* instantiate local variable of type spi_dma_master_state_t and point to global state */ + spi_dma_master_state_t * spiDmaState = (spi_dma_master_state_t *)g_spiStatePtr[instance]; + + SPI_Type *base = g_spiBase[instance]; + + /* Disable DMA requests and interrupts. */ + SPI_HAL_SetRxDmaCmd(base, false); + SPI_HAL_SetTxDmaCmd(base, false); + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, false); + + /* The transfer is complete.*/ + spiDmaState->isTransferInProgress = false; + + if (spiDmaState->isTransferBlocking) + { + /* Signal the synchronous completion object */ + OSA_SemaPost(&spiDmaState->irqSync); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaMasterIRQHandler + * Description : Interrupt handler for SPI master mode. + * This handler is used when the extraByte flag is set to retrieve the received last byte. + * + *END**************************************************************************/ +void SPI_DRV_DmaMasterIRQHandler(uint32_t instance) +{ +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_dma_master_state_t * spiDmaState = (spi_dma_master_state_t *)g_spiStatePtr[instance]; + + SPI_Type *base = g_spiBase[instance]; + + /* If the SPI module contains a FIFO (and if it is enabled), check the FIFO empty flag */ + if ((g_spiFifoSize[instance] != 0) && (SPI_HAL_GetFifoCmd(base))) + { + if (SPI_HAL_GetFifoStatusFlag(base, kSpiRxFifoEmpty) == 0) + { + /* If there is a receive buffer, copy the final byte from the SPI data register + * to the receive buffer + */ + if (spiDmaState->receiveBuffer) + { + spiDmaState->receiveBuffer[spiDmaState->transferByteCnt-2] = + SPI_HAL_ReadDataLow(base); + } + /* Else, read out the data register and throw away the bytes read */ + else + { + /* Read and throw away the lower data buffer to clear it out */ + s_rxBuffIfNull = SPI_HAL_ReadDataLow(base); + } + /* Read and throw away the upper data buffer to clear it out */ + s_rxBuffIfNull = SPI_HAL_ReadDataHigh(base); + + SPI_DRV_DmaMasterCompleteTransfer(instance); + } + } + else /* Check the read pending flag */ + { + if (SPI_HAL_IsReadBuffFullPending(base) == 1) + { + /* If there is a receive buffer, copy the final byte from the SPI data register + * to the receive buffer + */ + if (spiDmaState->receiveBuffer) + { + spiDmaState->receiveBuffer[spiDmaState->transferByteCnt-2] = + SPI_HAL_ReadDataLow(base); + } + /* Else, read out the data register and throw away the bytes read */ + else + { + /* Read and throw away the lower data buffer to clear it out */ + s_rxBuffIfNull = SPI_HAL_ReadDataLow(base); + } + /* Read and throw away the upper data buffer to clear it out */ + s_rxBuffIfNull = SPI_HAL_ReadDataHigh(base); + SPI_DRV_DmaMasterCompleteTransfer(instance); + } + } +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ +} + +#endif /* FSL_FEATURE_SOC_SPI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_dma_shared_function.c b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_dma_shared_function.c new file mode 100755 index 0000000..925d8ef --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_dma_shared_function.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include "fsl_spi_dma_shared_function.h" + +#if FSL_FEATURE_SOC_SPI_COUNT +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Extern for the DSPI DMA master driver's interrupt handler.*/ +extern void SPI_DRV_DmaMasterIRQHandler(uint32_t instance); + +/* Extern for the DSPI DMA slave driver's interrupt handler.*/ +extern void SPI_DRV_DmaSlaveIRQHandler(uint32_t instance); + +/*! @brief Table of base pointers for SPI instances. */ +extern SPI_Type * const g_spiBase[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief The function SPI_DRV_DmaIRQHandler passes IRQ control to either the master or + * slave driver. + * + * The address of the IRQ handlers are checked to make sure they are non-zero before + * they are called. If the IRQ handler's address is zero, it means that driver was + * not present in the link (because the IRQ handlers are marked as weak). This would + * actually be a program error, because it means the master/slave config for the IRQ + * was set incorrectly. + */ +void SPI_DRV_DmaIRQHandler(uint32_t instance) +{ + assert(instance < SPI_INSTANCE_COUNT); + SPI_Type *base = g_spiBase[instance]; + + if (SPI_HAL_IsMaster(base)) + { + /* Master mode.*/ + SPI_DRV_DmaMasterIRQHandler(instance); + } + else + { + /* Slave mode.*/ + SPI_DRV_DmaSlaveIRQHandler(instance); + } +} + +#endif /* FSL_FEATURE_SOC_SPI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_dma_slave_driver.c b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_dma_slave_driver.c new file mode 100755 index 0000000..0685cd1 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_dma_slave_driver.c @@ -0,0 +1,878 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string.h> +#include "fsl_spi_dma_slave_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_SPI_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @brief Flags of SPI slave event. + * + * SPI event used to notify user that it finishes the task. + */ +typedef enum _spi_dma_event_flags { + kSpiDmaTransferDone = 0x01, /*!< Transferring done flag */ +} spi_dma_event_flag_t; +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Pointer to runtime state structure.*/ +extern void * g_spiStatePtr[SPI_INSTANCE_COUNT]; + +static uint8_t s_byteToSend; /* Word to send, if no send buffer, this variable is used + as the word to send, which should be initialized to 0. Needs + to be static and stored in data section as this variable + address is the DMA source address if no source buffer. */ + +static uint8_t s_rxBuffIfNull; /* If no receive buffer provided, direct rx DMA channel to this + destination */ + +/* Table of SPI FIFO sizes per instance. */ +extern const uint32_t g_spiFifoSize[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Code + ******************************************************************************/ +/*! + * @brief Configure SPI slave module and start the transfer using DMA + * + * This function updates SPI slave state structure, configures SPI slave module + * using DMA driven and then start the transfer. + * + * @param instance The instance number of the SPI peripheral. + */ +static spi_status_t SPI_DRV_DmaSlaveStartTransfer(uint32_t instance); + +/*! + * @brief Stop the SPI slave transfer using DMA + * + * This function makes SPI slave transferring stop. + * + * @param instance The instance number of the SPI peripheral. + */ +static void SPI_DRV_DmaSlaveCompleteTransfer(uint32_t instance); + +/*! + * @brief The callback function for DMA complete interrupt. + * + * @param param Instance number of the SPI module. + * @param chanStatus Current status of DMA channel. + */ +void SPI_DRV_DmaSlaveCallback(void *param, dma_channel_status_t chanStatus); + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaSlaveCallback + * Description : This function is called when the DMA generates an interrupt. + * The DMA generates an interrupt when the channel is "done", meaning that the + * expected number of bytes have been transferred. When the interrupt occurs, + * the DMA will jump to this callback as it was registered in the DMA register + * callback service function. The user will defined their own callback function + * to take whatever action they deem necessary for handling the end of a transfer. + * For example, the user may simply want their callback function to set a global + * flag to indicate that the transfer is complete. The user defined callback + * is passed in through the "param" parameter. + * The parameter chanStatus is currently not used. + * + *END**************************************************************************/ +void SPI_DRV_DmaSlaveCallback(void *param, dma_channel_status_t chanStatus) +{ + uint32_t instance = (uint32_t)(param); + + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_dma_slave_state_t * spiDmaState = (spi_dma_slave_state_t *)g_spiStatePtr[instance]; + + SPI_Type *base = g_spiBase[instance]; + + /* If hasExtraByte flag was set, need to enable the TX empty interrupt to get the last byte */ + if ((spiDmaState->hasExtraByte) && (spiDmaState->remainingReceiveByteCount)) + { + SPI_HAL_SetTxDmaCmd(base, false); + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, true); + } + else + { + /* Transfer completed, finish the transfer */ + SPI_DRV_DmaSlaveCompleteTransfer(instance); + } + +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaSlaveInit + * Description : Initializes the SPI module for slave mode. + * Saves the application callback info, turns on the clock to the module, + * enables the device, and enables interrupts. Sets the SPI to a slave mode. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_DmaSlaveInit(uint32_t instance, spi_dma_slave_state_t * spiState, + const spi_dma_slave_user_config_t * slaveConfig) +{ + SPI_Type *base = g_spiBase[instance]; + assert(slaveConfig); + assert(instance < SPI_INSTANCE_COUNT); + assert(spiState); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if (slaveConfig->bitCount > kSpi16BitMode) + { + /* bits/frame larger than hardware support */ + return kStatus_SPI_InvalidParameter; + } +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + + /* Check if the slave already initialized */ + if (g_spiStatePtr[instance]) + { + return kStatus_SPI_AlreadyInitialized; + } + + /* Clear the state for this instance. */ + memset(spiState, 0, sizeof(* spiState)); + + spiState->hasExtraByte = false; + + /* Update dummy pattern value */ + spiState->dummyPattern = slaveConfig->dummyPattern; + + /* Enable clock for SPI */ + CLOCK_SYS_EnableSpiClock(instance); + + /* Reset the SPI module to its default settings including disabling SPI */ + SPI_HAL_Init(base); + + /* Initialize the event structure */ + OSA_EventCreate(&spiState->event, kEventAutoClear); + + /* Set SPI to slave mode */ + SPI_HAL_SetMasterSlave(base, kSpiSlave); + + /* Configure the slave clock polarity, phase and data direction */ + SPI_HAL_SetDataFormat(base, slaveConfig->polarity, slaveConfig->phase, + slaveConfig->direction); + + /* Set the SPI pin mode to normal mode */ + SPI_HAL_SetPinMode(base, kSpiPinMode_Normal); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + SPI_HAL_Set8or16BitMode(base, slaveConfig->bitCount); +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + +#if FSL_FEATURE_SPI_FIFO_SIZE + if (g_spiFifoSize[instance] != 0) + { + /* If SPI module contains a FIFO, enable it and set watermarks to half full/empty */ + SPI_HAL_SetFifoMode(base, true, kSpiTxFifoOneHalfEmpty, kSpiRxFifoOneHalfFull); + + /* Set the interrupt clearing mechansim select for later use in driver to clear + * status flags + */ + SPI_HAL_SetIntClearCmd(base, true); + } +#endif /* FSL_FEATURE_SPI_FIFO_SIZE */ + + /***************************************** + * Request DMA channel for RX and TX FIFO + *****************************************/ + /* This channel transfers data from RX FIFO to receiveBuffer */ + if (instance == 0) + { + /* Request DMA channel for RX FIFO */ + if (kDmaInvalidChannel == DMA_DRV_RequestChannel(kDmaAnyChannel, + kDmaRequestMux0SPI0Rx, + &spiState->dmaReceive)) + { + return kStatus_SPI_DMAChannelInvalid; + } + /* Request DMA channel for TX FIFO */ + if (kDmaInvalidChannel == DMA_DRV_RequestChannel(kDmaAnyChannel, + kDmaRequestMux0SPI0Tx, + &spiState->dmaTransmit)) + { + return kStatus_SPI_DMAChannelInvalid; + } + } +#if (SPI_INSTANCE_COUNT > 1) + else if (instance == 1) + { + /* Request DMA channel for RX FIFO */ + if (kDmaInvalidChannel == DMA_DRV_RequestChannel(kDmaAnyChannel, + kDmaRequestMux0SPI1Rx, + &spiState->dmaReceive)) + { + return kStatus_SPI_DMAChannelInvalid; + } + /* Request DMA channel for TX FIFO */ + if (kDmaInvalidChannel == DMA_DRV_RequestChannel(kDmaAnyChannel, + kDmaRequestMux0SPI1Tx, + &spiState->dmaTransmit)) + { + return kStatus_SPI_DMAChannelInvalid; + } + } + else + { + return kStatus_SPI_OutOfRange; + } +#endif + + /* Save runtime structure pointers to irq handler can point to the correct state structure */ + g_spiStatePtr[instance] = spiState; + + /* Enable SPI interrupt. The transmit interrupt should immediately cause an interrupt + * which will fill in the transmit buffer and will be ready to send once the slave initiates + * transmission. + */ + INT_SYS_EnableIRQ(g_spiIrqId[instance]); + + /* SPI module enable */ + SPI_HAL_Enable(base); + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaSlaveDeinit + * Description : De-initializes the device. + * Clears the control register and turns off the clock to the module. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_DmaSlaveDeinit(uint32_t instance) +{ + spi_dma_slave_state_t * spiState = (spi_dma_slave_state_t *)g_spiStatePtr[instance]; + SPI_Type *base = g_spiBase[instance]; + + assert(instance < SPI_INSTANCE_COUNT); + + /* Disable SPI interrupt */ + INT_SYS_DisableIRQ(g_spiIrqId[instance]); + + /* Reset the SPI module to its default settings including disabling SPI and its interrupts */ + SPI_HAL_Init(base); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if (g_spiFifoSize[instance] != 0) + { + SPI_HAL_SetFifoIntCmd(base, kSpiRxFifoNearFullInt, false); + } + + /* disable transmit interrupt */ + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, false); +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + + /* Free DMA channels */ + DMA_DRV_FreeChannel(&spiState->dmaReceive); + DMA_DRV_FreeChannel(&spiState->dmaTransmit); + + /* Disable clock for SPI */ + CLOCK_SYS_DisableSpiClock(instance); + + /* Destroy the event */ + OSA_EventDestroy(&spiState->event); + + /* Clear state pointer */ + g_spiStatePtr[instance] = NULL; + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaSlaveTransfer + * Description : Transfer data with the master using DMA driven. Starts the + * transfer with transmit buffer, receive buffer and transfer byte count passed. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_DmaSlaveTransfer(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount) +{ + spi_dma_slave_state_t * spiState = (spi_dma_slave_state_t *)g_spiStatePtr[instance]; + spi_status_t errorStatus = kStatus_SPI_Success; + + /* Validate the parameter */ + assert(instance < SPI_INSTANCE_COUNT); + + if ((!sendBuffer) && (!receiveBuffer)) + { + /* sendBuffer and receiveBuffer are not available, this is invalid */ + return kStatus_SPI_InvalidParameter; + } + + if (!transferByteCount) + { + /* number of transfer bytes is 0 */ + return kStatus_SPI_InvalidParameter; + } + + if (spiState->isTransferInProgress) + { + /* The another transfer is in progress */ + return kStatus_SPI_Busy; + } + + /* fill in members of the run-time state struct */ + spiState->isSync = false; + spiState->sendBuffer = sendBuffer; + spiState->receiveBuffer = (uint8_t *)receiveBuffer; + spiState->remainingSendByteCount = transferByteCount; + spiState->remainingReceiveByteCount = transferByteCount; + + /* Setup hardware to start the transfer */ + errorStatus = SPI_DRV_DmaSlaveStartTransfer(instance); + if (errorStatus != kStatus_SPI_Success) + { + return errorStatus; + } + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaSlaveTransferBlocking + * Description : Transfer data with the master, using blocking call and DMA + * driven. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_DmaSlaveTransferBlocking(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount, + uint32_t timeout) +{ + spi_dma_slave_state_t * spiState = (spi_dma_slave_state_t *)g_spiStatePtr[instance]; + spi_status_t errorStatus = kStatus_SPI_Success; + event_flags_t setFlags = 0; + + /* fill in members of the run-time state struct */ + spiState->isSync = true; + spiState->sendBuffer = (const uint8_t *)sendBuffer; + spiState->receiveBuffer = (uint8_t *)receiveBuffer; + spiState->remainingSendByteCount = transferByteCount; + spiState->remainingReceiveByteCount = transferByteCount; + + /* Clear the event flags */ + OSA_EventClear(&spiState->event, kSpiDmaTransferDone); + + errorStatus = SPI_DRV_DmaSlaveStartTransfer(instance); + if (errorStatus != kStatus_SPI_Success) + { + return errorStatus; + } + + /* As this is a synchronous transfer, wait until the transfer is complete. */ + osa_status_t syncStatus; + + do + { + syncStatus = OSA_EventWait(&spiState->event, kSpiDmaTransferDone, true, timeout, &setFlags); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Abort the transfer so it doesn't continue unexpectedly. */ + SPI_DRV_DmaSlaveAbortTransfer(instance); + + errorStatus = kStatus_SPI_Timeout; + } + + return errorStatus; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaSlaveStartTransfer + * Description : Starts the transfer with information passed. + * + *END**************************************************************************/ +static spi_status_t SPI_DRV_DmaSlaveStartTransfer(uint32_t instance) +{ + spi_dma_slave_state_t * spiState = (spi_dma_slave_state_t *)g_spiStatePtr[instance]; + + /* For temporarily storing DMA register channel */ + uint8_t txChannel, rxChannel; + void * param; + SPI_Type *base = g_spiBase[instance]; + uint32_t transferSizeInBytes; /* DMA transfer size in bytes */ + + /* Initialize s_byteToSend */ + s_byteToSend = spiState->dummyPattern; + + /* If the transfer count is zero, then return immediately. */ + if (spiState->remainingSendByteCount == 0) + { + /* Signal the synchronous completion object if the transfer wasn't async. + * Otherwise, when we return the the sync function we'll get stuck in the sync wait loop. + */ + if (spiState->isSync) + { + /* Signal the synchronous completion object */ + OSA_EventSet(&spiState->event, kSpiDmaTransferDone); + } + return kStatus_SPI_Success; + } + + /* In order to flush any remaining data in the shift register, disable then enable the SPI */ + SPI_HAL_Disable(base); + SPI_HAL_Enable(base); + + /* First, set the DMA transfer size in bytes */ +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if (SPI_HAL_Get8or16BitMode(base) == kSpi16BitMode) + { + transferSizeInBytes = 2; + /* If bits/frame > 8, meaning 2 bytes, then the transfer byte count must not be an odd + * count. If so, drop the last odd byte. This odd byte will be transferred in when dma + * completed + */ + if (spiState->remainingSendByteCount % 2 != 0) + { + spiState->remainingSendByteCount ++; + spiState->remainingReceiveByteCount --; + spiState->hasExtraByte = true; + } + else + { + spiState->hasExtraByte = false; + } + } + else + { + transferSizeInBytes = 1; + } +#else + transferSizeInBytes = 1; +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + + param = (void *)(instance); /* For DMA callback, set "param" as the SPI instance number */ + rxChannel = spiState->dmaReceive.channel; + txChannel = spiState->dmaTransmit.channel; + /* Only need to set the DMA reg base addr once since it should be the same for all code */ + DMA_Type *dmabase = g_dmaBase[rxChannel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + DMAMUX_Type *dmamuxbase = g_dmamuxBase[txChannel/FSL_FEATURE_DMAMUX_MODULE_CHANNEL]; + + /* Save information about the transfer for use by the ISR. */ + spiState->isTransferInProgress = true; + + /* The DONE needs to be cleared before programming the channel's TCDs for the next transfer. */ + DMA_HAL_ClearStatus(dmabase, rxChannel); + DMA_HAL_ClearStatus(dmabase, txChannel); + + /* Disable and enable the TX DMA channel at the DMA mux. Doing so will prevent an + * inadvertent DMA transfer when the TX DMA channel ERQ bit is set after having been + * cleared from a previous DMA transfer (clearing of the ERQ bit is automatically performed + * at the end of a transfer when D_REQ is set). + */ + DMAMUX_HAL_SetChannelCmd(dmamuxbase, txChannel, false); + DMAMUX_HAL_SetChannelCmd(dmamuxbase, txChannel, true); + DMAMUX_HAL_SetChannelCmd(dmamuxbase, rxChannel, false); + DMAMUX_HAL_SetChannelCmd(dmamuxbase, rxChannel, true); + + /************************************************************************************ + * Set up the RX DMA channel Transfer Control Descriptor (TCD) + * Note, if there is no receive buffer (if user passes in NULL), then bypass RX DMA + * set up. + ************************************************************************************/ + /* If no receive buffer then disable incrementing the destination and set the destination + * to a temporary location + */ + if ((spiState->remainingReceiveByteCount > 0) || (spiState->hasExtraByte)) + { + uint32_t receiveSize = spiState->remainingReceiveByteCount; + if ((!spiState->receiveBuffer) || (!spiState->remainingReceiveByteCount)) + { + if (!spiState->remainingReceiveByteCount) + { + /* If receive count is 0, always receive 1 frame (2 bytes) */ + receiveSize = 2; + } + /* Set up this channel's control which includes enabling the DMA interrupt */ + DMA_DRV_ConfigTransfer(&spiState->dmaReceive, + kDmaPeripheralToMemory, + transferSizeInBytes, + SPI_HAL_GetDataRegAddr(base), /* src is data register */ + (uint32_t)(&s_rxBuffIfNull), /* dest is temporary location */ + (uint32_t)(receiveSize)); + + /* Do not increment the destination address */ + DMA_HAL_SetDestIncrementCmd(dmabase, rxChannel, false); + } + else + { + /* Set up this channel's control which includes enabling the DMA interrupt */ + DMA_DRV_ConfigTransfer(&spiState->dmaReceive, + kDmaPeripheralToMemory, + transferSizeInBytes, + SPI_HAL_GetDataRegAddr(base), /* src is data register */ + (uint32_t)(spiState->receiveBuffer), /* dest is rx buffer */ + (uint32_t)(receiveSize)); + } + + /* For SPI16 modules, if the bits/frame is 16, then we need to adjust the destination + * size to still be 8-bits since the DMA_DRV_ConfigTransfer sets this to 16-bits, but + * we always provide a 8-bit buffer. + */ + if (transferSizeInBytes == 2) + { + DMA_HAL_SetDestTransferSize(dmabase, rxChannel, kDmaTransfersize8bits); + } + + /* Enable the cycle steal mode which forces a single read/write transfer per request */ + DMA_HAL_SetCycleStealCmd(dmabase, rxChannel, true); + + /* Enable the DMA peripheral request */ + DMA_DRV_StartChannel(&spiState->dmaReceive); + + /* Register callback for DMA interrupt */ + DMA_DRV_RegisterCallback(&spiState->dmaReceive, SPI_DRV_DmaSlaveCallback, param); + } + + /************************************************************************************ + * Set up the TX DMA channel Transfer Control Descriptor (TCD) + * Note, if there is no source buffer (if user passes in NULL), then send zeros + ************************************************************************************/ + /* Per the reference manual, before enabling the SPI transmit DMA request, we first need + * to read the status register and then write to the SPI data register. Afterwards, we need + * to decrement the sendByteCount and perform other driver maintenance functions. + */ + /* Read the SPI Status register */ + SPI_HAL_IsTxBuffEmptyPending(base); + + /* Start the transfer by writing the first byte/word to the SPI data register. + * If a send buffer was provided, the byte/word comes from there. Otherwise we just send zeros. + */ +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if (transferSizeInBytes == 2) /* 16-bit transfers for SPI16 module */ + { + if (spiState->sendBuffer) + { + s_byteToSend = *(spiState->sendBuffer); + SPI_HAL_WriteDataLow(base, s_byteToSend); + ++spiState->sendBuffer; + + s_byteToSend = *(spiState->sendBuffer); + SPI_HAL_WriteDataHigh(base, s_byteToSend); + ++spiState->sendBuffer; + } + else /* Else, if no send buffer, write zeros */ + { + SPI_HAL_WriteDataLow(base, s_byteToSend); + SPI_HAL_WriteDataHigh(base, s_byteToSend); + } + spiState->remainingSendByteCount -= 2; /* Decrement the send byte count by 2 */ + } + else /* 8-bit transfers for SPI16 module */ + { + if (spiState->sendBuffer) + { + s_byteToSend = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, s_byteToSend); /* If no send buffer, s_byteToSend=0 */ + --spiState->remainingSendByteCount; /* Decrement the send byte count for use in DMA setup */ + } +#else + /* For SPI modules that do not support 16-bit transfers */ + if (spiState->sendBuffer) + { + s_byteToSend = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteData(base, s_byteToSend); /* If no send buffer, s_byteToSend=0 */ + --spiState->remainingSendByteCount; /* Decrement the send byte count for use in DMA setup */ +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + + /* If there are no more bytes to send then return without setting up the TX DMA channel. + * Else, set up the TX DMA channel and enable the TX DMA request. + */ + if (!spiState->remainingSendByteCount) /* No more bytes to send */ + { + if ((spiState->remainingReceiveByteCount) || (spiState->hasExtraByte)) + { + /* Enable the RX DMA channel request now */ + SPI_HAL_SetRxDmaCmd(base, true); + return kStatus_SPI_Success; + } + else /* If RX DMA chan not setup then enable the interrupt to get the received byte */ + { + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, true); + return kStatus_SPI_Success; + } + } + else /* Since there are more bytes to send, set up the TX DMA channel */ + { + /* If there is a send buffer, data comes from there, else send 0 */ + if (spiState->sendBuffer) + { + /* Set up this channel's control which includes enabling the DMA interrupt */ + DMA_DRV_ConfigTransfer(&spiState->dmaTransmit, kDmaMemoryToPeripheral, + transferSizeInBytes, + (uint32_t)(spiState->sendBuffer), + SPI_HAL_GetDataRegAddr(base), + (uint32_t)(spiState->remainingSendByteCount)); + } + else /* Configure TX DMA channel to send zeros */ + { + /* Set up this channel's control which includes enabling the DMA interrupt */ + DMA_DRV_ConfigTransfer(&spiState->dmaTransmit, kDmaMemoryToPeripheral, + transferSizeInBytes, + (uint32_t)(&s_byteToSend), + SPI_HAL_GetDataRegAddr(base), + (uint32_t)(spiState->remainingSendByteCount)); + + /* Now clear SINC since we are only sending zeroes, don't increment source */ + DMA_HAL_SetSourceIncrementCmd(dmabase, txChannel, false); + } + + /* For SPI16 modules, if the bits/frame is 16, then we need to adjust the source + * size to still be 8-bits since the DMA_DRV_ConfigTransfer sets this to 16-bits, but + * we always provide a 8-bit buffer. + */ + if (transferSizeInBytes == 2) + { + DMA_HAL_SetSourceTransferSize(dmabase, txChannel, kDmaTransfersize8bits); + } + + /* Enable the cycle steal mode which forces a single read/write transfer per request */ + DMA_HAL_SetCycleStealCmd(dmabase, txChannel, true); + + /* Now, disable the TX chan interrupt since we'll use the RX chan interrupt */ + DMA_HAL_SetIntCmd(dmabase, txChannel, false); + + /* Enable the DMA peripheral request */ + DMA_DRV_StartChannel(&spiState->dmaTransmit); + + /* Enable the SPI TX DMA Request */ + SPI_HAL_SetTxDmaCmd(base, true); + + /* Enable the SPI RX DMA request also. */ + SPI_HAL_SetRxDmaCmd(base, true); + } + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaSlaveCompleteTransfer + * Description : Finish up a transfer. + * Cleans up after a transfer is complete. Interrupts are disabled, and the SPI module + * is disabled. This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void SPI_DRV_DmaSlaveCompleteTransfer(uint32_t instance) +{ + spi_dma_slave_state_t * spiState = (spi_dma_slave_state_t *)g_spiStatePtr[instance]; + + SPI_Type *base = g_spiBase[instance]; + + /* Disable DMA requests and interrupts. */ + SPI_HAL_SetRxDmaCmd(base, false); + SPI_HAL_SetTxDmaCmd(base, false); + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, false); + + /* Stop DMA channels */ + DMA_DRV_StopChannel(&spiState->dmaTransmit); + DMA_DRV_StopChannel(&spiState->dmaReceive); + + /* Disable interrupts */ + SPI_HAL_SetIntMode(base, kSpiRxFullAndModfInt, false); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if (g_spiFifoSize[instance] != 0) + { + /* Now disable the SPI FIFO interrupts */ + SPI_HAL_SetFifoIntCmd(base, kSpiTxFifoNearEmptyInt, false); + SPI_HAL_SetFifoIntCmd(base, kSpiRxFifoNearFullInt, false); + } + + /* Receive extra byte if remaining receive byte is 0 */ + if ((spiState->hasExtraByte) && (!spiState->remainingReceiveByteCount) && + (spiState->receiveBuffer)) + { + spiState->receiveBuffer[spiState->remainingReceiveByteCount] = + SPI_HAL_ReadDataLow(base); + } +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + + if (spiState->isSync) + { + /* Signal the synchronous completion object */ + OSA_EventSet(&spiState->event, kSpiDmaTransferDone); + } + + /* The transfer is complete, update the state structure */ + spiState->isTransferInProgress = false; + spiState->status = kStatus_SPI_Success; + spiState->errorCount = 0; + spiState->sendBuffer = NULL; + spiState->receiveBuffer = NULL; + spiState->remainingSendByteCount = 0; + spiState->remainingReceiveByteCount = 0; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaSlaveAbortTransfer + * Description : Stop the transfer if it is in progress + * + *END**************************************************************************/ +spi_status_t SPI_DRV_DmaSlaveAbortTransfer(uint32_t instance) +{ + spi_dma_slave_state_t * spiState = (spi_dma_slave_state_t *)g_spiStatePtr[instance]; + + /* Check instance is valid or not */ + assert(instance < SPI_INSTANCE_COUNT); + + /* Check driver is initialized */ + if (!spiState) + { + return kStatus_SPI_NonInit; + } + + /* Check transfer is in progress */ + if (!spiState->isTransferInProgress) + { + return kStatus_SPI_NoTransferInProgress; + } + + /* Stop transfer */ + SPI_DRV_DmaSlaveCompleteTransfer(instance); + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaSlaveGetTransferStatus + * Description : Returns whether the previous transfer finished. + * When performing an a-sync transfer, the user can call this function to ascertain the state of the + * current transfer: in progress (or busy) or complete (success). In addition, if the transfer + * is still in progress, the user can get the number of words that have been + * transferred up to now. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_DmaSlaveGetTransferStatus(uint32_t instance, + uint32_t * framesTransferred) +{ + spi_dma_slave_state_t * spiState = (spi_dma_slave_state_t *)g_spiStatePtr[instance]; + + /* Fill in the bytes transferred. */ + if (framesTransferred) + { + *framesTransferred = spiState->remainingSendByteCount - + DMA_DRV_GetUnfinishedBytes(&spiState->dmaTransmit); + } + + return (spiState->isTransferInProgress ? kStatus_SPI_Busy : kStatus_SPI_Success); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_DmaSlaveIRQHandler + * Description : Interrupt handler for SPI master mode. + * This handler is used when the hasExtraByte flag is set to retrieve the received last byte. + * + *END**************************************************************************/ +void SPI_DRV_DmaSlaveIRQHandler(uint32_t instance) +{ +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_dma_slave_state_t * spiDmaState = (spi_dma_slave_state_t *)g_spiStatePtr[instance]; + + SPI_Type *base = g_spiBase[instance]; + + /* If the SPI module contains a FIFO (and if it is enabled), check the FIFO empty flag */ + if ((g_spiFifoSize[instance] != 0) && (SPI_HAL_GetFifoCmd(base))) + { + if (SPI_HAL_GetFifoStatusFlag(base, kSpiRxFifoEmpty) == 0) + { + /* If there is a receive buffer, copy the final byte from the SPI data register + * to the receive buffer + */ + if (spiDmaState->receiveBuffer) + { + spiDmaState->receiveBuffer[spiDmaState->remainingReceiveByteCount] = + SPI_HAL_ReadDataLow(base); + } + /* Else, read out the data register and throw away the bytes read */ + else + { + /* Read and throw away the lower data buffer to clear it out */ + s_rxBuffIfNull = SPI_HAL_ReadDataLow(base); + } + /* Read and throw away the upper data buffer to clear it out */ + s_rxBuffIfNull = SPI_HAL_ReadDataHigh(base); + + SPI_DRV_DmaSlaveCompleteTransfer(instance); + } + } + else /* Check the read pending flag */ + { + if (SPI_HAL_IsReadBuffFullPending(base) == 1) + { + /* If there is a receive buffer, copy the final byte from the SPI data register + * to the receive buffer + */ + if (spiDmaState->receiveBuffer) + { + spiDmaState->receiveBuffer[spiDmaState->remainingReceiveByteCount] = + SPI_HAL_ReadDataLow(base); + } + /* Else, read out the data register and throw away the bytes read */ + else + { + /* Read and throw away the lower data buffer to clear it out */ + s_rxBuffIfNull = SPI_HAL_ReadDataLow(base); + } + /* Read and throw away the upper data buffer to clear it out */ + s_rxBuffIfNull = SPI_HAL_ReadDataHigh(base); + SPI_DRV_DmaSlaveCompleteTransfer(instance); + } + } +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ +} + +#endif /* FSL_FEATURE_SOC_SPI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_irq.c b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_irq.c new file mode 100755 index 0000000..c35fa67 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_irq.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <stdbool.h> +#include "fsl_spi_shared_function.h" +#include "fsl_device_registers.h" + +/*! + * @addtogroup spi_irq + * @{ + */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if (SPI_INSTANCE_COUNT == 1) +/*! + * @brief This function is the implementation of SPI0 handler named in startup code. + * + * It passes the instance to the shared SPI IRQ handler. + */ +void SPI0_IRQHandler(void) +{ + SPI_DRV_IRQHandler(SPI0_IDX); +} + +#else +/*! + * @brief This function is the implementation of SPI0 handler named in startup code. + * + * It passes the instance to the shared SPI IRQ handler. + */ +void SPI0_IRQHandler(void) +{ + SPI_DRV_IRQHandler(SPI0_IDX); +} + +/*! + * @brief This function is the implementation of SPI1 handler named in startup code. + * + * It passes the instance to the shared SPI IRQ handler. + */ +void SPI1_IRQHandler(void) +{ + SPI_DRV_IRQHandler(SPI1_IDX); +} +#endif + +/*! @} */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_lpm_callback.c new file mode 100755 index 0000000..68ad841 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t spi_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t spi_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_master_driver.c b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_master_driver.c new file mode 100755 index 0000000..b7cdbae --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_master_driver.c @@ -0,0 +1,956 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <string.h> +#include "fsl_spi_master_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_SPI_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Pointer to runtime state structure.*/ +extern void * g_spiStatePtr[SPI_INSTANCE_COUNT]; + +/* Table of SPI FIFO sizes per instance. */ +extern const uint32_t g_spiFifoSize[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static spi_status_t SPI_DRV_MasterStartTransfer(uint32_t instance, + const spi_master_user_config_t * device); +static void SPI_DRV_MasterCompleteTransfer(uint32_t instance); +#if FSL_FEATURE_SPI_FIFO_SIZE +static void SPI_DRV_MasterFillupTxFifo(uint32_t instance); +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_MasterInit + * Description : Initialize a SPI instance for master mode operation. + * This function uses a CPU interrupt driven method for transferring data. + * This function initializes the run-time state structure to track the ongoing + * transfers, ungates the clock to the SPI module, resets and initializes the module + * to default settings, configures the IRQ state structure, enables + * the module-level interrupt to the core, and enables the SPI module. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_MasterInit(uint32_t instance, spi_master_state_t * spiState) +{ + SPI_Type *base = g_spiBase[instance]; + + /* Clear the state for this instance.*/ + memset(spiState, 0, sizeof(* spiState)); + + /* Enable clock for SPI*/ + CLOCK_SYS_EnableSpiClock(instance); + + /* configure the run-time state struct with the source clock value */ + spiState->spiSourceClock = CLOCK_SYS_GetSpiFreq(instance); + + /* Reset the SPI module to it's default state, which includes SPI disabled */ + SPI_HAL_Init(base); + + /* Init the interrupt sync object.*/ + OSA_SemaCreate(&spiState->irqSync, 0); + + /* Set SPI to master mode */ + SPI_HAL_SetMasterSlave(base, kSpiMaster); + + /* Set slave select to automatic output mode */ + SPI_HAL_SetSlaveSelectOutputMode(base, kSpiSlaveSelect_AutomaticOutput); + + /* Set the SPI pin mode to normal mode */ + SPI_HAL_SetPinMode(base, kSpiPinMode_Normal); + +#if FSL_FEATURE_SPI_FIFO_SIZE + if (g_spiFifoSize[instance] != 0) + { + /* If SPI module contains a FIFO, enable it and set watermarks to half full/empty */ + SPI_HAL_SetFifoMode(base, true, kSpiTxFifoOneHalfEmpty, kSpiRxFifoOneHalfFull); + } +#endif + /* Save runtime structure pointers to irq handler can point to the correct state structure*/ + g_spiStatePtr[instance] = spiState; + + /* Enable SPI interrupt.*/ + INT_SYS_EnableIRQ(g_spiIrqId[instance]); + + /* SPI system Enable*/ + SPI_HAL_Enable(base); + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_MasterDeinit + * Description : Shutdown a SPI instance. + * This function resets the SPI peripheral, gates its clock, and disables the interrupt to + * the core. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_MasterDeinit(uint32_t instance) +{ + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_master_state_t * spiState = (spi_master_state_t *)g_spiStatePtr[instance]; + SPI_Type *base = g_spiBase[instance]; + + /* Restore the module to defaults which includes disabling the SPI then power it down.*/ + SPI_HAL_Init(base); + + /* destroy the interrupt sync object.*/ + OSA_SemaDestroy(&spiState->irqSync); + + /* Disable SPI interrupt.*/ + INT_SYS_DisableIRQ(g_spiIrqId[instance]); + + /* Gate the clock for SPI.*/ + CLOCK_SYS_DisableSpiClock(instance); + + /* Clear state pointer. */ + g_spiStatePtr[instance] = NULL; + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_MasterConfigureBus + * Description : Configures the SPI port to access a device on the bus. + * The term "device" is used to indicate the SPI device for which the SPI master is communicating. + * The user has two options to configure the device parameters: either pass in the + * pointer to the device configuration structure to the desired transfer function (see + * SPI_DRV_MasterTransferDataBlocking or SPI_DRV_MasterTransferData) or pass it in to the + * SPI_DRV_MasterConfigureBus function. The user can pass in a device structure to the transfer + * function which contains the parameters for the bus (the transfer function will then call + * this function). However, the user has the option to call this function directly especially + * to get the calculated baud rate, at which point they may pass in NULL for the device + * struct in the transfer function (assuming they have called this configure bus function + * first). + * + *END**************************************************************************/ +void SPI_DRV_MasterConfigureBus(uint32_t instance, + const spi_master_user_config_t * device, + uint32_t * calculatedBaudRate) +{ + assert(device); + + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_master_state_t * spiState = (spi_master_state_t *)g_spiStatePtr[instance]; + + SPI_Type *base = g_spiBase[instance]; + + /* Configure the bus to access the provided device.*/ + *calculatedBaudRate = SPI_HAL_SetBaud(base, device->bitsPerSec, spiState->spiSourceClock); + SPI_HAL_SetDataFormat(base, device->polarity, device->phase, device->direction); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + SPI_HAL_Set8or16BitMode(base, device->bitCount); +#endif + +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_MasterTransferBlocking + * Description : Performs a blocking SPI master mode transfer. + * This function simultaneously sends and receives data on the SPI bus, as SPI is naturally + * a full-duplex bus. The function will not return until the transfer is complete. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_MasterTransferBlocking(uint32_t instance, + const spi_master_user_config_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount, + uint32_t timeout) +{ + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_master_state_t * spiState = (spi_master_state_t *)g_spiStatePtr[instance]; + spi_status_t errorStatus = kStatus_SPI_Success; + SPI_Type *base = g_spiBase[instance]; + + /* fill in members of the run-time state struct*/ + spiState->isTransferBlocking = true; /* Indicates this is a blocking transfer */ + spiState->sendBuffer = (const uint8_t *)sendBuffer; + spiState->receiveBuffer = (uint8_t *)receiveBuffer; + spiState->remainingSendByteCount = transferByteCount; + spiState->remainingReceiveByteCount = transferByteCount; + + /* start the transfer process*/ + errorStatus = SPI_DRV_MasterStartTransfer(instance, device); + if (errorStatus != kStatus_SPI_Success) + { + return errorStatus; + } + + /* As this is a synchronous transfer, wait until the transfer is complete.*/ + osa_status_t syncStatus; + + do + { + syncStatus = OSA_SemaWait(&spiState->irqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + /* If a timeout occurs, stop the transfer by setting the isTransferInProgress to false and + * disabling interrupts, then return the timeout error status. + */ + if (syncStatus != kStatus_OSA_Success) + { + /* The transfer is complete.*/ + spiState->isTransferInProgress = false; + + /* Disable interrupts */ + SPI_HAL_SetIntMode(base, kSpiRxFullAndModfInt, false); + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, false); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if (g_spiFifoSize[instance] != 0) + { + /* Now disable the SPI FIFO interrupts */ + SPI_HAL_SetFifoIntCmd(base, kSpiTxFifoNearEmptyInt, false); + SPI_HAL_SetFifoIntCmd(base, kSpiRxFifoNearFullInt, false); + } +#endif + errorStatus = kStatus_SPI_Timeout; + } + + return errorStatus; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_MasterTransfer + * Description : Perform a non-blocking SPI master mode transfer. + * This function will return immediately. It is the user's responsiblity to check back to + * ascertain if the transfer is complete (using the SPI_DRV_MasterGetTransferStatus function). + * This function simultaneously sends and receives data on the SPI bus, as SPI is naturally + * a full-duplex bus. The function will not return until the transfer is complete. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_MasterTransfer(uint32_t instance, + const spi_master_user_config_t * device, + const uint8_t * sendBuffer, + uint8_t * receiveBuffer, + size_t transferByteCount) +{ + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_master_state_t * spiState = (spi_master_state_t *)g_spiStatePtr[instance]; + spi_status_t errorStatus = kStatus_SPI_Success; + + /* fill in members of the run-time state struct*/ + spiState->isTransferBlocking = false; /* Indicates this is a non-blocking transfer */ + spiState->sendBuffer = sendBuffer; + spiState->receiveBuffer = (uint8_t *)receiveBuffer; + spiState->remainingSendByteCount = transferByteCount; + spiState->remainingReceiveByteCount = transferByteCount; + + /* start the transfer process*/ + errorStatus = SPI_DRV_MasterStartTransfer(instance, device); + if (errorStatus != kStatus_SPI_Success) + { + return errorStatus; + } + + /* Else, return immediately as this is an async transfer */ + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_MasterGetTransferStatus + * Description : Returns whether the previous transfer finished. + * When performing an a-sync transfer, the user can call this function to ascertain the state of the + * current transfer: in progress (or busy) or complete (success). In addition, if the transfer + * is still in progress, the user can get the number of words that have been + * transferred up to now. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_MasterGetTransferStatus(uint32_t instance, + uint32_t * bytesTransferred) +{ + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_master_state_t * spiState = (spi_master_state_t *)g_spiStatePtr[instance]; + + /* Fill in the bytes transferred.*/ + if (bytesTransferred) + { + *bytesTransferred = spiState->transferredByteCount; + } + + return (spiState->isTransferInProgress ? kStatus_SPI_Busy : kStatus_SPI_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_MasterAbortTransfer + * Description : Terminates an asynchronous transfer early. + * During an async transfer, the user has the option to terminate the transfer early if the transfer + * is still in progress. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_MasterAbortTransfer(uint32_t instance) +{ + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_master_state_t * spiState = (spi_master_state_t *)g_spiStatePtr[instance]; + + /* Check if a transfer is running.*/ + if (!spiState->isTransferInProgress) + { + return kStatus_SPI_NoTransferInProgress; + } + + /* Stop the running transfer.*/ + SPI_DRV_MasterCompleteTransfer(instance); + + return kStatus_SPI_Success; +} + +/*! + * @brief Initiate (start) a transfer. This is not a public API as it is called from other + * driver functions + */ +static spi_status_t SPI_DRV_MasterStartTransfer(uint32_t instance, + const spi_master_user_config_t * device) +{ + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_master_state_t * spiState = (spi_master_state_t *)g_spiStatePtr[instance]; + + uint32_t calculatedBaudRate; + SPI_Type *base = g_spiBase[instance]; + + /* Check that we're not busy.*/ + if (spiState->isTransferInProgress) + { + return kStatus_SPI_Busy; + } + + /* Configure bus for this device. If NULL is passed, we assume the caller has + * preconfigured the bus using SPI_DRV_MasterConfigureBus(). + * Do nothing for calculatedBaudRate. If the user wants to know the calculatedBaudRate + * then they can call this function separately. + */ + if (device) + { + SPI_DRV_MasterConfigureBus(instance, device, &calculatedBaudRate); + } + + /* In order to flush any remaining data in the shift register, disable then enable the SPI */ + SPI_HAL_Disable(base); + SPI_HAL_Enable(base); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + spi_data_bitcount_mode_t bitCount; + + bitCount = SPI_HAL_Get8or16BitMode(base); + + /* Check the transfer byte count. If bits/frame > 8, meaning 2 bytes if bits/frame > 8, and if + * the transfer byte count is an odd count we'll have to increase the transfer byte count + * by one and assert a flag to indicate to the receive function that it will need to handle + * an extra byte so that it does not inadverently over-write an another byte to the receive + * buffer. For sending the extra byte, we don't care if we read past the send buffer since we + * are only reading from it and the absolute last byte (that completes the final 16-bit word) + * is a don't care byte anyway. + */ + if ((bitCount == kSpi16BitMode) && (spiState->remainingSendByteCount & 1UL)) + { + spiState->remainingSendByteCount += 1; + spiState->remainingReceiveByteCount += 1; + spiState->extraByte = true; + } + else + { + spiState->extraByte = false; + } + +#endif + + /* If the byte count is zero, then return immediately.*/ + if (spiState->remainingSendByteCount == 0) + { + SPI_DRV_MasterCompleteTransfer(instance); + return kStatus_SPI_Success; + } + + /* Save information about the transfer for use by the ISR.*/ + spiState->isTransferInProgress = true; + spiState->transferredByteCount = 0; + + /* Make sure TX data register (or FIFO) is empty. If not, return appropriate + * error status. This also causes a read of the status + * register which is required before writing to the data register below. + */ + if (SPI_HAL_IsTxBuffEmptyPending(base) != 1) + { + return kStatus_SPI_TxBufferNotEmpty; + } + + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + /* If the module/instance contains a FIFO (and if enabled), proceed with FIFO usage for either + * 8- or 16-bit transfers, else bypass to non-FIFO usage. + */ + if ((g_spiFifoSize[instance] != 0) && (SPI_HAL_GetFifoCmd(base))) + { + /* First fill the FIFO with data */ + SPI_DRV_MasterFillupTxFifo(instance); + + /* If the remaining RX byte count is less than the RX FIFO watermark, enable + * the TX FIFO empty interrupt. Once the TX FIFO is empty, we are ensured + * that the transmission is complete and can then drain the RX FIFO. + * Else, enable the RX FIFO interrupt based on the watermark. In the IRQ + * handler, another check will be made to see if the remaining RX byte count + * is less than the RX FIFO watermark. + */ + if (spiState->remainingReceiveByteCount < g_spiFifoSize[instance]) + { + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, true); /* TX FIFO empty interrupt */ + } + else + { + SPI_HAL_SetFifoIntCmd(base, kSpiRxFifoNearFullInt, true); + } + } + /* Modules that support 16-bit transfers but without FIFO support */ + else + { + uint8_t byteToSend = 0; + + /* SPI configured for 16-bit transfers, no FIFO */ + if (bitCount == kSpi16BitMode) + { + uint8_t byteToSendLow = 0; + uint8_t byteToSendHigh = 0; + + if (spiState->sendBuffer) + { + byteToSendLow = *(spiState->sendBuffer); + ++spiState->sendBuffer; + + /* If the extraByte flag is set and these are the last 2 bytes, then skip this */ + if (!((spiState->extraByte) && (spiState->remainingSendByteCount == 2))) + { + byteToSendHigh = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + } + SPI_HAL_WriteDataLow(base, byteToSendLow); + SPI_HAL_WriteDataHigh(base, byteToSendHigh); + + spiState->remainingSendByteCount -= 2; /* decrement by 2 */ + spiState->transferredByteCount += 2; /* increment by 2 */ + } + /* SPI configured for 8-bit transfers, no FIFO */ + else + { + if (spiState->sendBuffer) + { + byteToSend = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, byteToSend); + + --spiState->remainingSendByteCount; + ++spiState->transferredByteCount; + } + + /* Only enable the receive interrupt. This should be ok since SPI is a synchronous + * protocol, so every RX interrupt we get, we should be ready to send. However, since + * the SPI has a shift register and data buffer (for transmit and receive), things may not + * be cycle-to-cycle synchronous. To compensate for this, enabling the RX interrupt only + * ensures that we do indeed receive data before sending out the next data word. In the + * ISR we make sure to first check for the RX data buffer full before checking the TX + * data register empty flag. + */ + SPI_HAL_SetIntMode(base, kSpiRxFullAndModfInt, true); + } + +#else /* For SPI modules that do not support 16-bit transfers */ + + /* Start the transfer by writing the first byte. If a send buffer was provided, the byte + * comes from there. Otherwise we just send a zero byte. Note that before writing to the + * data register, the status register must first be read, which was already performed above. + */ + uint8_t byteToSend = 0; + if (spiState->sendBuffer) + { + byteToSend = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteData(base, byteToSend); + + --spiState->remainingSendByteCount; + ++spiState->transferredByteCount; + + /* Only enable the receive interrupt. This should be ok since SPI is a synchronous + * protocol, so every RX interrupt we get, we should be ready to send. However, since + * the SPI has a shift register and data buffer (for transmit and receive), things may not + * be cycle-to-cycle synchronous. To compensate for this, enabling the RX interrupt only + * ensures that we do indeed receive data before sending out the next data word. In the + * ISR we make sure to first check for the RX data buffer full before checking the TX + * data register empty flag. + */ + SPI_HAL_SetIntMode(base, kSpiRxFullAndModfInt, true); +#endif + + return kStatus_SPI_Success; +} + +#if FSL_FEATURE_SPI_FIFO_SIZE +/*! + * @brief Fill up the TX FIFO with data. + * This function fills up the TX FIFO. + * This is not a public API as it is called from other driver functions. + */ +static void SPI_DRV_MasterFillupTxFifo(uint32_t instance) +{ + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_master_state_t * spiState = (spi_master_state_t *)g_spiStatePtr[instance]; + SPI_Type *base = g_spiBase[instance]; + uint8_t byteToSendLow = 0; + uint8_t byteToSendHigh = 0; + + /* Declare variables for storing volatile data later in the code */ + uint32_t remainRxByteCnt, remainTxByteCnt; + + spi_data_bitcount_mode_t bitCount = SPI_HAL_Get8or16BitMode(base); + + /* Store the SPI state struct volatile member variables into temporary + * non-volatile variables to allow for MISRA compliant calculations + */ + remainTxByteCnt = spiState->remainingSendByteCount; + remainRxByteCnt = spiState->remainingReceiveByteCount; + + /* Architectural note: When developing the TX FIFO fill functionality, it was found that to + * achieve more efficient run-time performance, it was better to first check the bits/frame + * setting and then proceed with the FIFO fill management process, rather than to clutter the + * FIFO fill process with continual checks of the bits/frame setting. + */ + + /* If bits/frame is greater than one byte */ + if (bitCount == kSpi16BitMode) + { + /* Fill the fifo until it is full or until the send word count is 0 or until the difference + * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth. + * The reason for checking the difference is to ensure we only send as much as the + * RX FIFO can receive. Note, the FIFO depth assumes maximum data length of 16-bits, + * but since we are using 8-bit buffers, the FIFO depth is twice the reported depth. + */ + while((SPI_HAL_GetFifoStatusFlag(base, kSpiTxFifoFull)== 0) && + ((remainRxByteCnt - remainTxByteCnt) < (g_spiFifoSize[instance]*2))) + { + if (spiState->sendBuffer) + { + byteToSendLow = *(spiState->sendBuffer); + ++spiState->sendBuffer; + + byteToSendHigh = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, byteToSendLow); + SPI_HAL_WriteDataHigh(base, byteToSendHigh); + + spiState->remainingSendByteCount -= 2; /* decrement by 2 */ + spiState->transferredByteCount += 2; /* increment by 2 */ + + /* Update the SPI state struct volatile member variables into temporary + * non-volatile variables to allow for MISRA compliant calculations + */ + remainTxByteCnt = spiState->remainingSendByteCount; + remainRxByteCnt = spiState->remainingReceiveByteCount; + + /* exit loop if send count is zero */ + if (spiState->remainingSendByteCount == 0) + { + break; + } + } + } + /* Optimized for bit count = 8 */ + else + { + /* Fill the fifo until it is full or until the send word count is 0 or until the difference + * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth. + * The reason for checking the difference is to ensure we only send as much as the + * RX FIFO can receive. Note, the FIFO depth assumes maximum data length of 16-bits, + * but since we are using 8-bit buffers, the FIFO depth is twice the reported depth. + */ + while((SPI_HAL_GetFifoStatusFlag(base, kSpiTxFifoFull)== 0) && + ((remainRxByteCnt - remainTxByteCnt) < (g_spiFifoSize[instance]*2))) + { + if (spiState->sendBuffer) + { + byteToSendLow = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, byteToSendLow); + + --spiState->remainingSendByteCount; + ++spiState->transferredByteCount; + + /* Update the SPI state struct volatile member variables into temporary + * non-volatile variables to allow for MISRA compliant calculations + */ + remainTxByteCnt = spiState->remainingSendByteCount; + remainRxByteCnt = spiState->remainingReceiveByteCount; + + /* exit loop if send count is zero */ + if (spiState->remainingSendByteCount == 0) + { + break; + } + } + } +} +#endif /* FSL_FEATURE_SPI_FIFO_SIZE */ + +/*! + * @brief Finish up a transfer. + * Cleans up after a transfer is complete. Interrupts are disabled, and the SPI module + * is disabled. This is not a public API as it is called from other driver functions. + */ +static void SPI_DRV_MasterCompleteTransfer(uint32_t instance) +{ + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_master_state_t * spiState = (spi_master_state_t *)g_spiStatePtr[instance]; + + SPI_Type *base = g_spiBase[instance]; + + /* The transfer is complete.*/ + spiState->isTransferInProgress = false; + + /* Disable interrupts */ + SPI_HAL_SetIntMode(base, kSpiRxFullAndModfInt, false); + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, false); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if (g_spiFifoSize[instance] != 0) + { + /* Now disable the SPI FIFO interrupts */ + SPI_HAL_SetFifoIntCmd(base, kSpiTxFifoNearEmptyInt, false); + SPI_HAL_SetFifoIntCmd(base, kSpiRxFifoNearFullInt, false); + } +#endif + + if (spiState->isTransferBlocking) + { + /* Signal the synchronous completion object */ + OSA_SemaPost(&spiState->irqSync); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_MasterIRQHandler + * Description : Interrupt handler for SPI master mode. + * This handler uses the buffers stored in the spi_master_state_t structs to transfer data. + * + *END**************************************************************************/ +void SPI_DRV_MasterIRQHandler(uint32_t instance) +{ + /* instantiate local variable of type spi_master_state_t and point to global state */ + spi_master_state_t * spiState = (spi_master_state_t *)g_spiStatePtr[instance]; + + SPI_Type *base = g_spiBase[instance]; + + /* Exit the ISR if no transfer is happening for this instance.*/ + if (!spiState->isTransferInProgress) + { + return; + } + + /* RECEIVE IRQ handler: Check read buffer only if there are remaining bytes to read. */ + if (spiState->remainingReceiveByteCount) + { +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + uint8_t byteReceivedLow, byteReceivedHigh; + + spi_data_bitcount_mode_t bitCntRx = SPI_HAL_Get8or16BitMode(base); + + /* If the SPI module contains a FIFO (and if it's enabled), drain the FIFO until it is empty + * or until the remainingSendByteCount reaches 0. + */ + if ((g_spiFifoSize[instance] != 0) && (SPI_HAL_GetFifoCmd(base))) + { + /* Clear the RX near full interrupt */ + SPI_HAL_ClearFifoIntUsingBitWrite(base, kSpiRxNearFullClearInt); + + /* Architectural note: When developing the RX FIFO drain code, it was found that to + * achieve more efficient run-time performance, it was better to first check the + * bits/frame setting and then proceed with the FIFO fill management process, rather + * than to clutter the drain process with continual checks of the bits/frame setting. + */ + + /* Optimized for bit count = 16 with FIFO support */ + if (bitCntRx == kSpi16BitMode) + { + /* Do this while the RX FIFO is not empty */ + while (SPI_HAL_GetFifoStatusFlag(base, kSpiRxFifoEmpty) == 0) + { + /* Read the bytes from the RX FIFO */ + byteReceivedLow = SPI_HAL_ReadDataLow(base); + byteReceivedHigh = SPI_HAL_ReadDataHigh(base); + + /* Store read bytes into rx buffer only if a buffer pointer was provided */ + if (spiState->receiveBuffer) + { + *spiState->receiveBuffer = byteReceivedLow; + ++spiState->receiveBuffer; + + /* If the extraByte flag is set and these are the last 2 bytes, then skip. + * This will avoid over-writing the rx buffer with another un-needed byte. + */ + if (!((spiState->extraByte) && (spiState->remainingReceiveByteCount == 2))) + { + *spiState->receiveBuffer = byteReceivedHigh; + ++spiState->receiveBuffer; + } + } + + spiState->remainingReceiveByteCount -= 2; /* decrement the rx byte count by 2 */ + + /* If there is no more data to receive, break */ + if (spiState->remainingReceiveByteCount == 0) + { + break; + } + } + } + + /* Optimized for bit count = 8 with FIFO support */ + else + { + while (SPI_HAL_GetFifoStatusFlag(base, kSpiRxFifoEmpty) == 0) + { + /* Read the bytes from the RX FIFO */ + byteReceivedLow = SPI_HAL_ReadDataLow(base); + + /* Store read bytes into rx buffer only if a buffer pointer was provided */ + if (spiState->receiveBuffer) + { + *spiState->receiveBuffer = byteReceivedLow; + ++spiState->receiveBuffer; + } + + --spiState->remainingReceiveByteCount; /* decrement the rx byte count by 1 */ + + /* If there is no more data to receive, break */ + if (spiState->remainingReceiveByteCount == 0) + { + break; + } + } + } + + /* If the remaining RX byte count is less than the RX FIFO watermark, enable + * the TX FIFO empty interrupt. Once the TX FIFO is empty, we are ensured + * that the transmission is complete and can then drain the RX FIFO. + */ + if (spiState->remainingReceiveByteCount < g_spiFifoSize[instance]) + { + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, true); /* TX FIFO empty interrupt */ + } + } + + /* For SPI modules that do not have a FIFO (or if disabled), but have 16-bit transfer + * capability */ + else + { + if (SPI_HAL_IsReadBuffFullPending(base)) + { + + /* For 16-bit transfers w/o FIFO support */ + if (bitCntRx == kSpi16BitMode) + { + /* Read the bytes from the RX FIFO */ + byteReceivedLow = SPI_HAL_ReadDataLow(base); + byteReceivedHigh = SPI_HAL_ReadDataHigh(base); + + /* Store read bytes into rx buffer only if a buffer pointer was provided */ + if (spiState->receiveBuffer) + { + *spiState->receiveBuffer = byteReceivedLow; + ++spiState->receiveBuffer; + + /* If the extraByte flag is set and these are the last 2 bytes, then skip. + * This will avoid over-writing the rx buffer with another un-needed byte. + */ + if (!((spiState->extraByte) && (spiState->remainingReceiveByteCount == 2))) + { + *spiState->receiveBuffer = byteReceivedHigh; + ++spiState->receiveBuffer; + } + } + + spiState->remainingReceiveByteCount -= 2; /* decrement the rx byte count by 2 */ + + } + + /* For 8-bit transfers w/o FIFO support */ + else + { + /* Read the bytes from the RX FIFO */ + byteReceivedLow = SPI_HAL_ReadDataLow(base); + + /* Store read bytes into rx buffer only if a buffer pointer was provided */ + if (spiState->receiveBuffer) + { + *spiState->receiveBuffer = byteReceivedLow; + ++spiState->receiveBuffer; + } + + --spiState->remainingReceiveByteCount; /* decrement the rx byte count by 1 */ + } + } + } + +#else /* For SPI modules that do not support 16-bit transfers and don't have FIFO */ + + uint8_t byteReceived; + /* For SPI modules without 16-bit transfer capability or FIFO support */ + if (SPI_HAL_IsReadBuffFullPending(base)) + { + /* Read the bytes from the RX FIFO */ + byteReceived = SPI_HAL_ReadData(base); + + /* Store read bytes into rx buffer only if a buffer pointer was provided */ + if (spiState->receiveBuffer) + { + *spiState->receiveBuffer = byteReceived; + ++spiState->receiveBuffer; + } + + --spiState->remainingReceiveByteCount; /* decrement the rx byte count by 1 */ + } +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + } + + /* TRANSMIT IRQ handler + * Check write buffer. We always have to send a byte in order to keep the transfer + * moving. So if the caller didn't provide a send buffer, we just send a zero byte. + */ + uint8_t byteToSend = 0; + if (spiState->remainingSendByteCount) + { +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + uint8_t byteToSendLow = 0; + uint8_t byteToSendHigh = 0; + + spi_data_bitcount_mode_t bitCntTx = SPI_HAL_Get8or16BitMode(base); + + /* If SPI module has a FIFO and if it is enabled */ + if ((g_spiFifoSize[instance] != 0) && (SPI_HAL_GetFifoCmd(base))) + { + if (SPI_HAL_GetFifoStatusFlag(base, kSpiTxNearEmpty)) + { + /* Fill of the TX FIFO with ongoing data */ + SPI_DRV_MasterFillupTxFifo(instance); + } + } + else + { + if (SPI_HAL_IsTxBuffEmptyPending(base)) + { + if (bitCntTx == kSpi16BitMode) + { + if (spiState->sendBuffer) + { + byteToSendLow = *(spiState->sendBuffer); + ++spiState->sendBuffer; + + byteToSendHigh = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, byteToSendLow); + SPI_HAL_WriteDataHigh(base, byteToSendHigh); + + spiState->remainingSendByteCount -= 2; /* decrement by 2 */ + spiState->transferredByteCount += 2; /* increment by 2 */ + } + else /* SPI configured for 8-bit transfers */ + { + if (spiState->sendBuffer) + { + byteToSend = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, byteToSend); + + --spiState->remainingSendByteCount; + ++spiState->transferredByteCount; + } + } + } +#else /* For SPI modules that do not support 16-bit transfers */ + if (SPI_HAL_IsTxBuffEmptyPending(base)) + { + if (spiState->sendBuffer) + { + byteToSend = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteData(base, byteToSend); + + --spiState->remainingSendByteCount; + ++spiState->transferredByteCount; + } +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + } + + /* Check if we're done with this transfer. The transfer is complete when all of the + * expected data is received. + */ + if ((spiState->remainingSendByteCount == 0) && (spiState->remainingReceiveByteCount == 0)) + { + /* Complete the transfer. This disables the interrupts, so we don't wind up in + * the ISR again. + */ + SPI_DRV_MasterCompleteTransfer(instance); + } +} + +#endif /* FSL_FEATURE_SOC_SPI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_shared_function.c b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_shared_function.c new file mode 100755 index 0000000..8a2543e --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_shared_function.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include "fsl_spi_shared_function.h" + +#if FSL_FEATURE_SOC_SPI_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Extern for the DSPI master driver's interrupt handler.*/ +extern void SPI_DRV_MasterIRQHandler(uint32_t instance); + +/* Extern for the SPI slave driver's interrupt handler.*/ +extern void SPI_DRV_SlaveIRQHandler(uint32_t instance); + +/*! @brief Table of base pointers for SPI instances. */ +extern SPI_Type * const g_spiBase[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Pass IRQ control to either the master or slave driver. + * + * The address of the IRQ handlers are checked to make sure they are non-zero before + * they are called. If the IRQ handler's address is zero, it means that driver was + * not present in the link (because the IRQ handlers are marked as weak). This would + * actually be a program error, because it means the master/slave config for the IRQ + * was set incorrectly. + */ +void SPI_DRV_IRQHandler(uint32_t instance) +{ + assert(instance < SPI_INSTANCE_COUNT); + SPI_Type *base = g_spiBase[instance]; + + if (SPI_HAL_IsMaster(base)) + { + /* Master mode.*/ + SPI_DRV_MasterIRQHandler(instance); + } + else + { + /* Slave mode.*/ + SPI_DRV_SlaveIRQHandler(instance); + } +} + +#endif /* FSL_FEATURE_SOC_SPI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_slave_driver.c b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_slave_driver.c new file mode 100755 index 0000000..045cf30 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/spi/fsl_spi_slave_driver.c @@ -0,0 +1,959 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_spi_slave_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_SPI_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @brief Flags of SPI slave event. + * + * SPI event used to notify user that it finishes the task. + */ +typedef enum _spi_event_flags { + kSpiTransferDone = 0x01, /*!< Transferring done flag */ +} spi_event_flag_t; + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Pointer to runtime state structure.*/ +extern void * g_spiStatePtr[SPI_INSTANCE_COUNT]; + +/* Table of SPI FIFO sizes per instance. */ +extern const uint32_t g_spiFifoSize[SPI_INSTANCE_COUNT]; + +/******************************************************************************* + * Code + ******************************************************************************/ +/*! + * @brief Configure SPI slave module and start the transfer + * + * This function updates SPI slave state structure, configures SPI slave module + * using interrupt driven and then start the transfer. + * + * @param instance The instance number of the SPI peripheral. + */ +static spi_status_t SPI_DRV_SlaveStartTransfer(uint32_t instance); + +/*! + * @brief Stop the SPI slave transfer + * + * This function makes SPI slave transferring stop. + * + * @param instance The instance number of the SPI peripheral. + */ +static void SPI_DRV_SlaveCompleteTransfer(uint32_t instance); + +#if FSL_FEATURE_SPI_FIFO_SIZE +/*! + * @brief Fill up the TX FIFO by data from transmit buffer. + * + * This function fill up the available TX FIFO register by transmit data from the buffer. + * + * @param instance The instance number of the SPI peripheral. + */ +static void SPI_DRV_SlaveFillupTxFifo(uint32_t instance); +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_SlaveIRQHandler + * Description : SPI Slave Generic IRQ handler. + * + *END**************************************************************************/ +void SPI_DRV_SlaveIRQHandler(uint32_t instance) +{ + spi_slave_state_t * spiState = (spi_slave_state_t *)g_spiStatePtr[instance]; + + SPI_Type *base = g_spiBase[instance]; + int32_t minRemainingSend = 0; +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + spi_data_bitcount_mode_t bitCount = SPI_HAL_Get8or16BitMode(base); +#endif + + /* Exit the ISR if no transfer is happening for this instance.*/ + if (!spiState->isTransferInProgress) + { + return; + } + /* Calculate the minimum remaining send count value, if remainingSendByteCount less + * than this value, disable the transmit interrupt + */ +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if (bitCount == kSpi16BitMode) + { + minRemainingSend = -1; + } + else + { + minRemainingSend = 0; + } +#else + minRemainingSend = 0; +#endif + + /* TRANSMIT IRQ handler - note, handle TX first for slave mode + * Check write buffer. We always have to send a byte in order to keep the transfer + * moving. So if the caller didn't provide a send buffer, we just send a zero byte. + */ + if (spiState->remainingSendByteCount >= minRemainingSend) + { +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + /* Initialize bytes to send with zero so that if tere is no send buffer, we'll always + * send zeros as the default. + */ + uint8_t byteToSendLow = 0; + uint8_t byteToSendHigh = 0; + + /* Set the default sending value to dummy pattern value */ + byteToSendLow = spiState->dummyPattern & 0xFF; + byteToSendHigh = (spiState->dummyPattern & 0xFF00) >> 8; + + /* If module instance has a FIFO (and is enabled), fill up any empty slots in the FIFO */ + if ((g_spiFifoSize[instance] != 0) && (SPI_HAL_GetFifoCmd(base))) + { + /* Fill of the TX FIFO with ongoing data */ + SPI_DRV_SlaveFillupTxFifo(instance); + } + /* For instances without a FIFO or if disabled */ + else + { + if (SPI_HAL_IsTxBuffEmptyPending(base)) + { + if (bitCount == kSpi16BitMode) + { + if ((spiState->sendBuffer) && (spiState->remainingSendByteCount > 0)) + { + byteToSendLow = *(spiState->sendBuffer); + ++spiState->sendBuffer; + byteToSendHigh = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, byteToSendLow); + SPI_HAL_WriteDataHigh(base, byteToSendHigh); + + spiState->remainingSendByteCount -= 2; /* decrement by 2 */ + spiState->transferredByteCount += 2; /* increment by 2 */ + } + else /* SPI configured for 8-bit transfers */ + { + if ((spiState->sendBuffer) && (spiState->remainingSendByteCount > 0)) + { + byteToSendLow = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, byteToSendLow); + + --spiState->remainingSendByteCount; + ++spiState->transferredByteCount; + } + } + } +#else /* For SPI modules that do not support 16-bit transfers */ + if (SPI_HAL_IsTxBuffEmptyPending(base)) + { + uint8_t byteToSend = spiState->dummyPattern; + if ((spiState->sendBuffer) && (spiState->remainingSendByteCount > 0)) + { + byteToSend = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteData(base, byteToSend); + + --spiState->remainingSendByteCount; + ++spiState->transferredByteCount; + } +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + } + +#if 1 + if (spiState->remainingSendByteCount < minRemainingSend) + { + /* After all send data was pushed into TX FIFO or buffer, the TX near empty interrupt + * and SPI transmit interrupt must be disabled. + */ +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if ((g_spiFifoSize[instance] != 0) && (SPI_HAL_GetFifoCmd(base))) + { + /* Clear the TX near empty interrupt */ + SPI_HAL_ClearFifoIntUsingBitWrite(base, kSpiTxFifoEmptyClearInt); + /* Disable TX near empty interrupt */ + SPI_HAL_SetFifoIntCmd(base, kSpiTxFifoNearEmptyInt, false); + } + else +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + { + /* Disable Tx buffer empty interrupt */ + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, false); + } + } +#endif + + /* RECEIVE IRQ handler + * Check read buffer only if there are remaining bytes to read. If user did not supply a + * receive buffer, then simply read the data register and discard the data. + */ + if (spiState->remainingReceiveByteCount > 0) + { +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + uint8_t byteReceivedLow, byteReceivedHigh; + + /* If the SPI module contains a FIFO (and if enabled), drain the FIFO until it is empty + * or until the remainingSendByteCount reaches 0. + */ + if ((g_spiFifoSize[instance] != 0) && (SPI_HAL_GetFifoCmd(base))) + { + /* Clear the RX near full interrupt */ + SPI_HAL_ClearFifoIntUsingBitWrite(base, kSpiRxNearFullClearInt); + + /* Architectural note: When developing the RX FIFO drain code, it was found that to + * achieve more efficient run-time performance, it was better to first check the + * bits/frame setting and then proceed with the FIFO fill management process, rather + * than to clutter the drain process with continual checks of the bits/frame setting. + */ + if (bitCount == kSpi16BitMode) + { + /* Do this while the RX FIFO is not empty */ + while (SPI_HAL_GetFifoStatusFlag(base, kSpiRxFifoEmpty) == 0) + { + /* Read the bytes from the RX FIFO */ + byteReceivedLow = SPI_HAL_ReadDataLow(base); + byteReceivedHigh = SPI_HAL_ReadDataHigh(base); + + /* Store read bytes into rx buffer, only if rx buffer was provided */ + if (spiState->receiveBuffer) + { + *spiState->receiveBuffer = byteReceivedLow; + ++spiState->receiveBuffer; + + if (--spiState->remainingReceiveByteCount > 0) + { + *spiState->receiveBuffer = byteReceivedHigh; + ++spiState->receiveBuffer; + } + --spiState->remainingReceiveByteCount; + } + else + { + spiState->remainingReceiveByteCount -= 2; + } + + /* If there is no more data to receive, break */ + if (spiState->remainingReceiveByteCount == 0) + { + break; + } + } + } + /* Optimized for bit count = 8 */ + else + { + while (SPI_HAL_GetFifoStatusFlag(base, kSpiRxFifoEmpty) == 0) + { + /* Read the bytes from the RX FIFO */ + byteReceivedLow = SPI_HAL_ReadDataLow(base); + + /* Store read bytes into rx buffer, only if rx buffer was provided */ + if (spiState->receiveBuffer) + { + *spiState->receiveBuffer = byteReceivedLow; + ++spiState->receiveBuffer; + } + + --spiState->remainingReceiveByteCount; + + /* If there is no more data to receive, break */ + if (spiState->remainingReceiveByteCount == 0) + { + break; + } + } + } + + /* If the remaining RX byte count is less than the RX FIFO watermark, enable + * the TX FIFO empty interrupt. Once the TX FIFO is empty, we are ensured + * that the transmission is complete and can then drain the RX FIFO. + */ + if (spiState->remainingReceiveByteCount < g_spiFifoSize[instance]) + { + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, true); /* TX FIFO empty interrupt */ + } + } + /* For SPI modules that do not have a FIFO, but have 16-bit transfer capability */ + else + { + if (SPI_HAL_IsReadBuffFullPending(base)) + { + if (bitCount == kSpi16BitMode) + { + /* Read the bytes from the RX FIFO */ + byteReceivedLow = SPI_HAL_ReadDataLow(base); + byteReceivedHigh = SPI_HAL_ReadDataHigh(base); + + /* Store read bytes into rx buffer, only if rx buffer was provided */ + if (spiState->receiveBuffer) + { + + *spiState->receiveBuffer = byteReceivedLow; + ++spiState->receiveBuffer; + if (--spiState->remainingReceiveByteCount > 0) + { + + *spiState->receiveBuffer = byteReceivedHigh; + ++spiState->receiveBuffer; + } + --spiState->remainingReceiveByteCount; + } + else + { + spiState->remainingReceiveByteCount -= 2; + } + } + else /* For 8-bit transfers */ + { + /* Read the bytes from the RX FIFO */ + byteReceivedLow = SPI_HAL_ReadDataLow(base); + + /* Store read bytes into rx buffer, only if rx buffer was provided */ + if (spiState->receiveBuffer) + { + *spiState->receiveBuffer = byteReceivedLow; + ++spiState->receiveBuffer; + } + --spiState->remainingReceiveByteCount; + } + } + } +#else + uint8_t byteReceived; + /* For SPI modules without 16-bit transfer capability or FIFO support */ + if (SPI_HAL_IsReadBuffFullPending(base)) + { + /* Read the bytes from the RX FIFO */ + byteReceived = SPI_HAL_ReadData(base); + + /* Store read bytes into rx buffer, only if rx buffer was provided */ + if (spiState->receiveBuffer) + { + *spiState->receiveBuffer = byteReceived; + ++spiState->receiveBuffer; + } + + --spiState->remainingReceiveByteCount; + } +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + } + + /* Check if we're done with this transfer.*/ + if ((spiState->remainingSendByteCount <= 0) && (spiState->remainingReceiveByteCount <= 0)) + { + /* Complete the transfer. This disables the interrupts, so we don't wind up in + * the ISR again. + */ + SPI_DRV_SlaveCompleteTransfer(instance); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_SlaveInit + * Description : Initializes the SPI module for slave mode. + * Saves the application callback info, turns on the clock to the module, + * enables the device, and enables interrupts. Sets the SPI to a slave mode. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_SlaveInit(uint32_t instance, spi_slave_state_t * spiState, + const spi_slave_user_config_t * slaveConfig) +{ + SPI_Type *base = g_spiBase[instance]; + + assert(slaveConfig); + assert(instance < SPI_INSTANCE_COUNT); + assert(spiState); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if (slaveConfig->bitCount > kSpi16BitMode) + { + /* bits/frame larger than hardware support */ + return kStatus_SPI_InvalidParameter; + } +#endif + + /* Check if the slave already initialized */ + if (g_spiStatePtr[instance]) + { + return kStatus_SPI_AlreadyInitialized; + } + + /* Clear the state for this instance. */ + memset(spiState, 0, sizeof(* spiState)); + + /* Update dummy pattern value */ + spiState->dummyPattern = slaveConfig->dummyPattern; + + /* Enable clock for SPI */ + CLOCK_SYS_EnableSpiClock(instance); + + /* Reset the SPI module to its default settings including disabling SPI */ + SPI_HAL_Init(base); + + /* Initialize the event structure */ + OSA_EventCreate(&spiState->event, kEventAutoClear); + + /* Set SPI to slave mode */ + SPI_HAL_SetMasterSlave(base, kSpiSlave); + + /* Configure the slave clock polarity, phase and data direction */ + SPI_HAL_SetDataFormat(base, slaveConfig->polarity, slaveConfig->phase, + slaveConfig->direction); + + /* Set the SPI pin mode to normal mode */ + SPI_HAL_SetPinMode(base, kSpiPinMode_Normal); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + /* Set the bit/frame mode */ + SPI_HAL_Set8or16BitMode(base, slaveConfig->bitCount); +#endif + +#if FSL_FEATURE_SPI_FIFO_SIZE + if (g_spiFifoSize[instance] != 0) + { + /* If SPI module contains a FIFO, enable it and set watermarks to half full/empty */ + SPI_HAL_SetFifoMode(base, true, kSpiTxFifoOneHalfEmpty, kSpiRxFifoOneHalfFull); + } +#endif + + /* Save runtime structure pointers to irq handler can point to the correct state structure */ + g_spiStatePtr[instance] = spiState; + + /* Enable SPI interrupt. */ + INT_SYS_EnableIRQ(g_spiIrqId[instance]); + + /* SPI system enable now */ + SPI_HAL_Enable(base); + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_SlaveDeinit + * Description : De-initializes the device. + * Clears the control register and turns off the clock to the module. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_SlaveDeinit(uint32_t instance) +{ + spi_slave_state_t * spiState = (spi_slave_state_t *)g_spiStatePtr[instance]; + SPI_Type *base = g_spiBase[instance]; + + assert(instance < SPI_INSTANCE_COUNT); + + if (spiState == NULL) + { + return kStatus_SPI_NonInit; + } + + /* Disable SPI interrupt */ + INT_SYS_DisableIRQ(g_spiIrqId[instance]); + + /* Reset the SPI module to its default settings including disabling SPI and its interrupts */ + SPI_HAL_Init(base); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if (g_spiFifoSize[instance] != 0) + { + /* Disable the FIFO feature */ + SPI_HAL_SetFifoIntCmd(base, kSpiRxFifoNearFullInt, false); + } + + /* Disable transmit interrupt */ + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, false); +#endif + + /* SPI system disable */ + SPI_HAL_Disable(base); + + /* Disable clock for SPI */ + CLOCK_SYS_DisableSpiClock(instance); + + /* Destroy the event */ + OSA_EventDestroy(&spiState->event); + + /* Clear state pointer. */ + g_spiStatePtr[instance] = NULL; + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_SlaveTransfer + * Description : Transfer data with the master. Starts the transfer with + * transmit buffer, receive buffer and transfer byte count passed. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_SlaveTransfer(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount) +{ + spi_slave_state_t * spiState = (spi_slave_state_t *)g_spiStatePtr[instance]; + spi_status_t errorStatus = kStatus_SPI_Success; + + /* Validate the parameter */ + assert(instance < SPI_INSTANCE_COUNT); + + if ((!sendBuffer) && (!receiveBuffer)) + { + /* sendBuffer and receiveBuffer are not available, this is invalid */ + return kStatus_SPI_InvalidParameter; + } + + if (!transferByteCount) + { + /* number of transfer bytes is 0 */ + return kStatus_SPI_InvalidParameter; + } + + if (spiState->isTransferInProgress) + { + /* The another transfer is in progress */ + return kStatus_SPI_Busy; + } + + /* fill in members of the run-time state struct */ + spiState->isSync = false; + spiState->sendBuffer = sendBuffer; + spiState->receiveBuffer = receiveBuffer; + spiState->remainingSendByteCount = transferByteCount; + spiState->remainingReceiveByteCount = transferByteCount; + + /* Start the transfer */ + errorStatus = SPI_DRV_SlaveStartTransfer(instance); + if (errorStatus != kStatus_SPI_Success) + { + return errorStatus; + } + + return kStatus_SPI_Success; +} + + +#if FSL_FEATURE_SPI_FIFO_SIZE +/*! + * @brief Fill up the TX FIFO with data. + * This function fills up the TX FIFO. + * This is not a public API as it is called from other driver functions. + */ +static void SPI_DRV_SlaveFillupTxFifo(uint32_t instance) +{ + spi_slave_state_t * spiState = (spi_slave_state_t *)g_spiStatePtr[instance]; + SPI_Type *base = g_spiBase[instance]; + uint8_t byteToSendLow = 0; + uint8_t byteToSendHigh = 0; + spi_data_bitcount_mode_t bitCount = SPI_HAL_Get8or16BitMode(base); /* the bit/frame */ + + /* Set the default sending value to dummy pattern value */ + byteToSendLow = spiState->dummyPattern & 0xFF; + byteToSendHigh = (spiState->dummyPattern & 0xFF00) >> 8; + + /* Architectural note: When developing the TX FIFO fill functionality, it was found that to + * achieve more efficient run-time performance, it was better to first check the bits/frame + * setting and then proceed with the FIFO fill management process, rather than to clutter the + * FIFO fill process with continual checks of the bits/frame setting. + */ + + /* If bits/frame is greater than one byte */ + if (bitCount == kSpi16BitMode) + { + /* Fill the fifo until it is full or until the send word count is 0 */ + while(SPI_HAL_GetFifoStatusFlag(base, kSpiTxFifoFull)== 0) + { + if ((spiState->sendBuffer) && (spiState->remainingSendByteCount > 0)) + { + byteToSendLow = *(spiState->sendBuffer); + ++spiState->sendBuffer; + byteToSendHigh = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, byteToSendLow); + SPI_HAL_WriteDataHigh(base, byteToSendHigh); + + spiState->remainingSendByteCount -= 2; /* decrement by 2 */ + spiState->transferredByteCount += 2; /* increment by 2 */ + + /* exit loop if send count is zero */ + if (spiState->remainingSendByteCount < 0) + { + break; + } + } + } + /* Optimized for bit count = 8 */ + else + { + /* Fill the fifo until it is full or until the send word count is 0 */ + while(SPI_HAL_GetFifoStatusFlag(base, kSpiTxFifoFull)== 0) + { + if ((spiState->sendBuffer) && (spiState->remainingSendByteCount > 0)) + { + byteToSendLow = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, byteToSendLow); + + --spiState->remainingSendByteCount; + ++spiState->transferredByteCount; + + /* exit loop if send count is zero */ + if (spiState->remainingSendByteCount < 0) + { + break; + } + } + } +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_SlaveStartTransfer + * Description : Starts the transfer with information passed. + * + *END**************************************************************************/ +static spi_status_t SPI_DRV_SlaveStartTransfer(uint32_t instance) +{ + spi_slave_state_t * spiState = (spi_slave_state_t *)g_spiStatePtr[instance]; + SPI_Type *base = g_spiBase[instance]; + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + spi_data_bitcount_mode_t bitCount; + + bitCount = SPI_HAL_Get8or16BitMode(base); +#endif + + /* Save information about the transfer for use by the ISR. */ + spiState->isTransferInProgress = true; + spiState->transferredByteCount = 0; + + /* SPI system disable */ + SPI_HAL_Disable(base); + /* SPI system enable now */ + SPI_HAL_Enable(base); + + /* Make sure TX data register (or FIFO) is empty. If not, return appropriate + * error status. This also causes a read of the status + * register which is required before writing to the data register below. + */ + if (SPI_HAL_IsTxBuffEmptyPending(base) != 1) + { + return kStatus_SPI_TxBufferNotEmpty; + } + + /* If SPI module/instance contains a FIFO (and enabled), proceed with FIFO usage, else bypass */ +#if FSL_FEATURE_SPI_16BIT_TRANSFERS +#if FSL_FEATURE_SPI_FIFO_SIZE + if ((g_spiFifoSize[instance] != 0) && (SPI_HAL_GetFifoCmd(base))) + { + /* First fill the FIFO with data */ + SPI_DRV_SlaveFillupTxFifo(instance); + + /* If the remaining RX byte count is less than the RX FIFO watermark, enable + * the TX FIFO empty interrupt. Once the TX FIFO is empty, we are ensured + * that the transmission is complete and can then drain the RX FIFO. + * Else, enable the RX FIFO interrupt based on the watermark. In the IRQ + * handler, another check will be made to see if the remaining RX byte count + * is less than the RX FIFO watermark. + */ + if (spiState->remainingReceiveByteCount < g_spiFifoSize[instance]) + { + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, true); /* TX FIFO empty interrupt */ + } + else + { + /* Enable both receive and transmit interrupts to make the slave can keep up with the + * master. + */ + SPI_HAL_SetFifoIntCmd(base, kSpiRxFifoNearFullInt, true); + SPI_HAL_SetFifoIntCmd(base, kSpiTxFifoNearEmptyInt, true); + } + } + else +#endif /* FSL_FEATURE_SPI_FIFO_SIZE */ + /* For instances without a FIFO but with the capability to transfer up to 16-bits */ + { + uint8_t byteToSend = 0; + if (bitCount == kSpi16BitMode) + { + uint8_t byteToSendLow = 0; + uint8_t byteToSendHigh = 0; + + if (spiState->sendBuffer) + { + byteToSendLow = *(spiState->sendBuffer); + ++spiState->sendBuffer; + + byteToSendHigh = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, byteToSendLow); + SPI_HAL_WriteDataHigh(base, byteToSendHigh); + + spiState->remainingSendByteCount -= 2; /* decrement by 2 */ + spiState->transferredByteCount += 2; /* increment by 2 */ + } + else /* SPI configured for 8-bit transfers */ + { + if (spiState->sendBuffer) + { + byteToSend = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteDataLow(base, byteToSend); + + --spiState->remainingSendByteCount; + ++spiState->transferredByteCount; + } + + /* Enable both receive and transmit interrupts to make the slave can keep up with the + * master. + */ + SPI_HAL_SetIntMode(base, kSpiRxFullAndModfInt, true); + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, true); + } +#else + /* For modules that do not support 16-bit transfers or FIFO + * Start the transfer by writing the first byte. If a send buffer was provided, the byte + * comes from there. Otherwise we just send a zero byte. Note that before writing to the + * data register, the status register must first be read, which was already performed above. + */ + uint8_t byteToSend = 0; + if (spiState->sendBuffer) + { + byteToSend = *(spiState->sendBuffer); + ++spiState->sendBuffer; + } + SPI_HAL_WriteData(base, byteToSend); + + --spiState->remainingSendByteCount; + ++spiState->transferredByteCount; + + /* Enable both receive and transmit interrupts to make the slave can keep up with the + * master. + */ + SPI_HAL_SetIntMode(base, kSpiRxFullAndModfInt, true); + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, true); + +#endif + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_SlaveCompleteTransfer + * Description : The transfer has ben completed, stop it. + * + *END**************************************************************************/ +static void SPI_DRV_SlaveCompleteTransfer(uint32_t instance) +{ + spi_slave_state_t * spiState = (spi_slave_state_t *)g_spiStatePtr[instance]; + SPI_Type *base = g_spiBase[instance]; + + /* The transfer is complete, update state */ + spiState->isTransferInProgress = false; + spiState->status = kStatus_SPI_Success; + spiState->errorCount = 0; + spiState->sendBuffer = NULL; + spiState->receiveBuffer = NULL; + spiState->remainingSendByteCount = 0; + spiState->remainingReceiveByteCount = 0; + + /* Disable interrupts */ + SPI_HAL_SetIntMode(base, kSpiRxFullAndModfInt, false); + SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, false); + +#if FSL_FEATURE_SPI_16BIT_TRANSFERS + if (g_spiFifoSize[instance] != 0) + { + /* Now disable the SPI FIFO interrupts */ + SPI_HAL_SetFifoIntCmd(base, kSpiTxFifoNearEmptyInt, false); + SPI_HAL_SetFifoIntCmd(base, kSpiRxFifoNearFullInt, false); + } +#endif + + /* Set the event flag if function is sync */ + if(spiState->isSync) + { + OSA_EventSet(&spiState->event, kSpiTransferDone); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_SlaveAbortTransfer + * Description : Stop the transfer if it is in progress + * + *END**************************************************************************/ +spi_status_t SPI_DRV_SlaveAbortTransfer(uint32_t instance) +{ + spi_slave_state_t * spiState = (spi_slave_state_t *)g_spiStatePtr[instance]; + + /* Check instance is valid or not */ + assert(instance < SPI_INSTANCE_COUNT); + + /* Check driver is initialized */ + if (!spiState) + { + return kStatus_SPI_NonInit; + } + + /* Check transfer is in progress */ + if (!spiState->isTransferInProgress) + { + return kStatus_SPI_NoTransferInProgress; + } + + /* Stop transfer */ + SPI_DRV_SlaveCompleteTransfer(instance); + + return kStatus_SPI_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_SlaveGetTransferStatus + * Description : Returns whether the previous transfer finished. + * When performing an a-sync transfer, the user can call this function to ascertain the state of the + * current transfer: in progress (or busy) or complete (success). In addition, if the transfer + * is still in progress, the user can get the number of words that have been + * transferred up to now. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_SlaveGetTransferStatus(uint32_t instance, + uint32_t * framesTransferred) +{ + spi_slave_state_t * spiState = (spi_slave_state_t *)g_spiStatePtr[instance]; + + /* Fill in the bytes transferred. */ + if (framesTransferred) + { + *framesTransferred = spiState->transferredByteCount; + } + + return (spiState->isTransferInProgress ? kStatus_SPI_Busy : kStatus_SPI_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : SPI_DRV_SlaveTransferBlocking + * Description : Transfer data with the master, using blocking call. + * + *END**************************************************************************/ +spi_status_t SPI_DRV_SlaveTransferBlocking(uint32_t instance, + const uint8_t *sendBuffer, + uint8_t *receiveBuffer, + uint32_t transferByteCount, + uint32_t timeout) +{ + spi_slave_state_t * spiState = (spi_slave_state_t *)g_spiStatePtr[instance]; + spi_status_t errorStatus = kStatus_SPI_Success; + event_flags_t setFlags = 0; + + /* Validate the parameter */ + assert(instance < SPI_INSTANCE_COUNT); + + if ((!sendBuffer) && (!receiveBuffer)) + { + /* sendBuffer and receiveBuffer are not available, this is invalid */ + return kStatus_SPI_InvalidParameter; + } + + if (!transferByteCount) + { + /* number of transfer bytes is 0 */ + return kStatus_SPI_InvalidParameter; + } + + if (spiState->isTransferInProgress) + { + /* The another transfer is in progress */ + return kStatus_SPI_Busy; + } + + /* fill in members of the run-time state struct */ + spiState->isSync = true; + spiState->sendBuffer = (const uint8_t *)sendBuffer; + spiState->receiveBuffer = (uint8_t *)receiveBuffer; + spiState->remainingSendByteCount = transferByteCount; + spiState->remainingReceiveByteCount = transferByteCount; + + /* Clear the event flags */ + OSA_EventClear(&spiState->event, kSpiTransferDone); + + errorStatus = SPI_DRV_SlaveStartTransfer(instance); + if (errorStatus != kStatus_SPI_Success) + { + return errorStatus; + } + + /* As this is a synchronous transfer, wait until the transfer is complete. */ + osa_status_t syncStatus; + + do + { + syncStatus = OSA_EventWait(&spiState->event, kSpiTransferDone, true, timeout, &setFlags); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Abort the transfer so it doesn't continue unexpectedly. */ + SPI_DRV_SlaveAbortTransfer(instance); + + errorStatus = kStatus_SPI_Timeout; + } + + return errorStatus; +} + +#endif /* FSL_FEATURE_SOC_SPI_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/tpm/fsl_tpm_common.c b/KSDK_1.2.0/platform/drivers/src/tpm/fsl_tpm_common.c new file mode 100755 index 0000000..677717d --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/tpm/fsl_tpm_common.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_TPM_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for TPM instances. */ +TPM_Type * const g_tpmBase[TPM_INSTANCE_COUNT] = TPM_BASE_PTRS; + +/* Tables to save TPM IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_tpmIrqId[TPM_INSTANCE_COUNT] = TPM_IRQS; + +#endif /* FSL_FEATURE_SOC_TPM_COUNT */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/tpm/fsl_tpm_driver.c b/KSDK_1.2.0/platform/drivers/src/tpm/fsl_tpm_driver.c new file mode 100755 index 0000000..40a0321 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/tpm/fsl_tpm_driver.c @@ -0,0 +1,505 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_tpm_driver.h" +#include "fsl_clock_manager.h" + +#if FSL_FEATURE_SOC_TPM_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! Stores TPM clock source setting */ +static tpm_clock_mode_t s_tpmClockSource = kTpmClockSourceNoneClk; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_Init + * Description : Initializes the TPM driver. + * This function will initialize the TPM module. + * + *END**************************************************************************/ +tpm_status_t TPM_DRV_Init(uint32_t instance, const tpm_general_config_t * info) +{ + assert(instance < TPM_INSTANCE_COUNT); + + TPM_Type *tpmBase = g_tpmBase[instance]; + + /*Enable TPM clock*/ + CLOCK_SYS_EnableTpmClock(instance); + + TPM_HAL_Reset(tpmBase, instance); + + /*trigger mode*/ + TPM_HAL_SetTriggerMode(tpmBase, info->isTriggerMode); + TPM_HAL_SetStopOnOverflowMode(tpmBase, info->isStopCountOnOveflow); + TPM_HAL_SetReloadOnTriggerMode(tpmBase, info->isCountReloadOnTrig); + + /*trigger source*/ + TPM_HAL_SetTriggerSrc(tpmBase, info->triggerSource); + + /*global time base*/ + TPM_HAL_EnableGlobalTimeBase(tpmBase, info->isGlobalTimeBase); + + /*Debug mode*/ + TPM_HAL_SetDbgMode(tpmBase, info->isDBGMode); + + NVIC_ClearPendingIRQ(g_tpmIrqId[instance]); + INT_SYS_EnableIRQ(g_tpmIrqId[instance]); + + return kStatusTpmSuccess; +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_SetClock + * Description : Set TPM clock source. + * This function will set the TPM clock source defined in the tpm_clock_source_t structure. + * It will also set the clock divider. + * + *END**************************************************************************/ +void TPM_DRV_SetClock(uint32_t instance, tpm_clock_source_t clock, tpm_clock_ps_t clockPs) +{ + assert(instance < TPM_INSTANCE_COUNT); + + TPM_Type *tpmBase = g_tpmBase[instance]; + + /*Clock prescaler*/ + TPM_HAL_SetClockDiv(tpmBase, clockPs); + + if (clock == kTpmClockSourcNone) + { + s_tpmClockSource = kTpmClockSourceNoneClk; + } + else if ((clock == kTpmClockSourceModuleOSCERCLK) || (clock == kTpmClockSourceModuleHighFreq) || + (clock == kTpmClockSourceModuleMCGIRCLK)) + { + CLOCK_SYS_SetTpmSrc(instance, (clock_tpm_src_t)clock); + s_tpmClockSource = kTpmClockSourceModuleClk; + } + else if ((clock == kTpmClockSourceExternalCLKIN0) || (clock == kTpmClockSourceExternalCLKIN1)) + + { + CLOCK_SYS_SetTpmExternalSrc(instance, (sim_tpm_clk_sel_t)(clock - 4)); + s_tpmClockSource = kTpmClockSourceExternalClk; + } + else + { + s_tpmClockSource = kTpmClockSourceReservedClk; + } + +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_GetClock + * Description : Get the TPM clock frequency. + * The function returns the frequency of the TPM clock. + * + *END**************************************************************************/ +uint32_t TPM_DRV_GetClock(uint32_t instance) +{ + assert(instance < TPM_INSTANCE_COUNT); + + TPM_Type *tpmBase = g_tpmBase[instance]; + uint32_t freq = 0; + uint32_t clockPs; + + /* Clock prescaler */ + clockPs = (1 << TPM_HAL_GetClockDiv(tpmBase)); + + switch (s_tpmClockSource) + { + case kTpmClockSourceModuleClk: + freq = CLOCK_SYS_GetTpmFreq(0) / clockPs; + break; + case kTpmClockSourceExternalClk: + freq = CLOCK_SYS_GetTpmExternalFreq(instance) / clockPs; + break; + default: + break; + } + + return freq; +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_SetTimeOverflowIntCmd + * Description : Enable or disable the timer overflow interrupt + * This function will enable or disable the TPM timer overflow (TOF) interrupt. + * + *END**************************************************************************/ +void TPM_DRV_SetTimeOverflowIntCmd(uint32_t instance, bool overflowEnable) +{ + if (overflowEnable) + { + TPM_HAL_EnableTimerOverflowInt(g_tpmBase[instance]); + } + else + { + TPM_HAL_DisableTimerOverflowInt(g_tpmBase[instance]); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_SetChnIntCmd + * Description : Enable or disable the channel interrupt + * This function will enable or disable the channel interrupt. + * + *END**************************************************************************/ +void TPM_DRV_SetChnIntCmd(uint32_t instance, uint8_t channelNum, bool enable) +{ + if (enable) + { + TPM_HAL_EnableChnInt(g_tpmBase[instance], channelNum); + } + else + { + TPM_HAL_DisableChnInt(g_tpmBase[instance], channelNum); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_Deinit + * Description : Shuts down the TPM driver. + * This function will deactivate the TPM driver. + * + *END**************************************************************************/ +void TPM_DRV_Deinit(uint32_t instance) +{ + TPM_HAL_Reset(g_tpmBase[instance], instance); + + INT_SYS_DisableIRQ(g_tpmIrqId[instance]); + + /* disable clock for TPM.*/ + CLOCK_SYS_DisableTpmClock(instance); +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_PwmStop + * Description : Stops channel PWM. + * This function will stop outputting the PWM signal on the channel. + * + *END**************************************************************************/ +void TPM_DRV_PwmStop(uint32_t instance, tpm_pwm_param_t *param, uint8_t channel) +{ + assert((param->mode == kTpmEdgeAlignedPWM) || (param->mode == kTpmCenterAlignedPWM)); + assert(instance < TPM_INSTANCE_COUNT); + assert(channel < g_tpmChannelCount[instance]); + + TPM_Type *tpmBase = g_tpmBase[instance]; + + /* Set clock source to none to disable counter */ + TPM_HAL_SetClockMode(tpmBase, kTpmClockSourceNoneClk); + + TPM_HAL_DisableChn(tpmBase, channel); +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_PwmStart + * Description : Configures duty cycle, frequency and starts outputting PWM on specified channel. + * This function will configure the channel for edge or center PWM mode and start outputting a + * PWM signal. + * + *END**************************************************************************/ +tpm_status_t TPM_DRV_PwmStart(uint32_t instance, tpm_pwm_param_t *param, uint8_t channel) +{ + uint32_t freq; + uint16_t uMod, uCnv; + + assert(instance < TPM_INSTANCE_COUNT); + assert(param->uDutyCyclePercent <= 100); + assert(channel < g_tpmChannelCount[instance]); + + TPM_Type *tpmBase = g_tpmBase[instance]; + + if (s_tpmClockSource == kTpmClockSourceNoneClk) + { + return kStatusTpmFail; + } + + freq = TPM_DRV_GetClock(instance); + + /* When switching mode, disable channel first */ + TPM_HAL_DisableChn(tpmBase, channel); + + switch(param->mode) + { + case kTpmEdgeAlignedPWM: + uMod = freq / param->uFrequencyHZ - 1; + uCnv = uMod * param->uDutyCyclePercent / 100; + /* For 100% duty cycle */ + if(uCnv >= uMod) + { + uCnv = uMod + 1; + } + TPM_HAL_SetMod(tpmBase, uMod); + TPM_HAL_SetChnCountVal(tpmBase, channel, uCnv); + break; + case kTpmCenterAlignedPWM: + uMod = freq / (param->uFrequencyHZ * 2); + uCnv = uMod * param->uDutyCyclePercent / 100; + /* For 100% duty cycle */ + if(uCnv >= uMod) + { + uCnv = uMod + 1; + } + TPM_HAL_SetMod(tpmBase, uMod); + TPM_HAL_SetChnCountVal(tpmBase, channel, uCnv); + break; + default: + assert(0); + break; + } + + /* Set the requested PWM mode */ + TPM_HAL_EnablePwmMode(tpmBase, param, channel); + + /* Set the TPM clock */ + TPM_HAL_SetClockMode(tpmBase, s_tpmClockSource); + + return kStatusTpmSuccess; +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_CounterStart + * Description : Starts the TPM counter. + * This function provides access to the TPM counter. The counter can be run in + * Up-counting and Up-down counting modes. + * + *END**************************************************************************/ +void TPM_DRV_CounterStart(uint32_t instance, tpm_counting_mode_t countMode, uint32_t countFinalVal, + bool enableOverflowInt) +{ + assert(instance < TPM_INSTANCE_COUNT); + + TPM_Type *tpmBase = g_tpmBase[instance]; + uint32_t channel = 0; + + /* Set clock source to none to disable counter */ + TPM_HAL_SetClockMode(tpmBase, kTpmClockSourceNoneClk); + + /* Clear the overflow flag */ + TPM_HAL_ClearTimerOverflowFlag(tpmBase); + TPM_HAL_SetMod(tpmBase, countFinalVal); + + /* Use TPM as counter, turn off all the channels */ + for (channel = 0; channel < g_tpmChannelCount[instance]; channel++) + { + TPM_HAL_DisableChn(tpmBase, channel); + } + + if (countMode == kTpmCountingUp) + { + TPM_HAL_SetCpwms(tpmBase, 0); + } + else if (countMode == kTpmCountingUpDown) + { + TPM_HAL_SetCpwms(tpmBase, 1); + } + + /* Activate interrupts if required */ + TPM_DRV_SetTimeOverflowIntCmd(instance, enableOverflowInt); + + /* Set the TPM clock */ + TPM_HAL_SetClockMode(tpmBase, s_tpmClockSource); +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_CounterStop + * Description : Stops the TPM counter. + * + *END**************************************************************************/ +void TPM_DRV_CounterStop(uint32_t instance) +{ + /* Set clock source to none to disable counter */ + TPM_HAL_SetClockMode(g_tpmBase[instance], kTpmClockSourceNoneClk); + /* Clear CPWMS bit after disable counter */ + TPM_HAL_SetCpwms(g_tpmBase[instance], 0); + + /* Disable the overflow interrupt */ + TPM_DRV_SetTimeOverflowIntCmd(instance, false); +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_CounterRead + * Description : Reads back the current value of the TPM counter. + * + *END**************************************************************************/ +uint32_t TPM_DRV_CounterRead(uint32_t instance) +{ + assert(instance < TPM_INSTANCE_COUNT); + + return TPM_HAL_GetCounterVal(g_tpmBase[instance]); +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_InputCaptureEnable + * Description : Setup the channel for TPM input capture mode. + * This function will setup the capture mode for a channel depending on what is provided in the mode + * argument. Channel interrupts can be enabled or disabled by using the intEnable argument. + * + *END**************************************************************************/ +void TPM_DRV_InputCaptureEnable(uint32_t instance, uint8_t channel, tpm_input_capture_mode_t mode, + uint32_t countFinalVal, bool intEnable) +{ + assert(instance < TPM_INSTANCE_COUNT); + + TPM_Type *tpmBase = g_tpmBase[instance]; + + /* Set clock source to none to disable counter */ + TPM_HAL_SetClockMode(tpmBase, kTpmClockSourceNoneClk); + + TPM_HAL_DisableChn(tpmBase, channel); + TPM_HAL_ClearChnInt(tpmBase, channel); + TPM_HAL_ClearCounter(tpmBase); + TPM_HAL_SetCpwms(tpmBase, 0); + TPM_HAL_SetMod(tpmBase, countFinalVal); + TPM_HAL_SetChnMsnbaElsnbaVal(tpmBase, channel, (mode << TPM_CnSC_ELSA_SHIFT)); + + TPM_DRV_SetChnIntCmd(instance, channel, intEnable); + + /* Set the TPM clock */ + TPM_HAL_SetClockMode(tpmBase, s_tpmClockSource); +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_GetChnVal + * Description : Reads back the current value of the TPM channel value register. + * + *END**************************************************************************/ +uint32_t TPM_DRV_GetChnVal(uint32_t instance, uint8_t channel) +{ + assert(instance < TPM_INSTANCE_COUNT); + + return TPM_HAL_GetChnCountVal(g_tpmBase[instance], channel); +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_OutputCompareEnable + * Description : TPM output compare mode setup. + * This function will setup the compare mode for a channel depending on what is provided in the mode + * argument. Channel interrupts can be enabled or disabled by using the intEnable argument. The compare + * value is provided in the matchVal argument. + * + *END**************************************************************************/ +void TPM_DRV_OutputCompareEnable(uint32_t instance, uint8_t channel, tpm_output_compare_mode_t mode, + uint32_t countFinalVal, uint32_t matchVal, bool intEnable) +{ + assert(instance < TPM_INSTANCE_COUNT); + + TPM_Type *tpmBase = g_tpmBase[instance]; + uint32_t cmpMode = 0; + + /* Set clock source to none to disable counter */ + TPM_HAL_SetClockMode(tpmBase, kTpmClockSourceNoneClk); + + TPM_HAL_DisableChn(tpmBase, channel); + TPM_HAL_ClearChnInt(tpmBase, channel); + TPM_HAL_ClearCounter(tpmBase); + TPM_HAL_SetCpwms(tpmBase, 0); + TPM_HAL_SetMod(tpmBase, countFinalVal); + + if ((mode == kTpmHighPulseOutput) || (mode == kTpmLowPulseOutput)) + { + cmpMode = ((uint32_t)mode - 3) << TPM_CnSC_ELSA_SHIFT; + TPM_HAL_SetChnMsnbaElsnbaVal(tpmBase, channel, + ((0x3 << TPM_CnSC_MSA_SHIFT) | cmpMode)); + } + else + { + cmpMode = mode << TPM_CnSC_ELSA_SHIFT; + TPM_HAL_SetChnMsnbaElsnbaVal(tpmBase, channel, + ((0x1 << TPM_CnSC_MSA_SHIFT) | cmpMode)); + } + TPM_HAL_SetChnCountVal(tpmBase, channel, matchVal); + + TPM_DRV_SetChnIntCmd(instance, channel, intEnable); + + /* Set the TPM clock */ + TPM_HAL_SetClockMode(tpmBase, s_tpmClockSource); +} + +/*FUNCTION********************************************************************** + * + * Function Name : TPM_DRV_IRQHandler + * Description : The handler function is called from the TPM interrupt handler + * This function will clear the bits in the status register for the interrupt sources that are + * enabled. + * + *END**************************************************************************/ +void TPM_DRV_IRQHandler(uint32_t instance) +{ + uint16_t status = 0; + uint16_t channel; + TPM_Type *tpmBase = g_tpmBase[instance]; + + /* Clear the status flags for the interrupts enabled */ + if (TPM_HAL_IsOverflowIntEnabled(tpmBase)) + { + status = (1 << TPM_STATUS_TOF_SHIFT); + } + + for (channel = 0; channel < g_tpmChannelCount[instance]; channel++) + { + if (TPM_HAL_IsChnIntEnabled(tpmBase, channel)) + { + status |= (1u << channel); + } + } + + TPM_HAL_ClearStatusReg(tpmBase, status); +} + +#endif /* FSL_FEATURE_SOC_TPM_COUNT */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/tpm/fsl_tpm_irq.c b/KSDK_1.2.0/platform/drivers/src/tpm/fsl_tpm_irq.c new file mode 100755 index 0000000..b0b4000 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/tpm/fsl_tpm_irq.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_tpm_driver.h" + + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if (TPM_INSTANCE_COUNT > 0) +/*! + * @brief Implementation of handler named in startup code. + * + * Passes instance to generic TPM IRQ handler. + */ +void TPM0_IRQHandler(void) +{ + TPM_DRV_IRQHandler(0U); +} +#endif + +#if (TPM_INSTANCE_COUNT > 1) +/*! + * @brief Implementation of TPM1 handler named in startup code. + * + * Passes instance to generic TPM IRQ handler. + */ +void TPM1_IRQHandler(void) +{ + TPM_DRV_IRQHandler(1U); +} +#endif + +#if (TPM_INSTANCE_COUNT > 2) +/*! + * @brief Implementation of TPM2 handler named in startup code. + * + * Passes instance to generic TPM IRQ handler. + */ +void TPM2_IRQHandler(void) +{ + TPM_DRV_IRQHandler(2U); +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/tpm/fsl_tpm_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/tpm/fsl_tpm_lpm_callback.c new file mode 100755 index 0000000..5357099 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/tpm/fsl_tpm_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t tpm_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t tpm_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_common.c b/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_common.c new file mode 100755 index 0000000..7b3132f --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_common.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" +#include "fsl_tsi_driver.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Table of base addresses for tsi instances. */ +TSI_Type * const g_tsiBase[] = TSI_BASE_PTRS; + +/* Table to save TSI IRQ numbers defined in CMSIS files. */ +const IRQn_Type g_tsiIrqId[TSI_INSTANCE_COUNT] = { TSI0_IRQn }; + +/* Pointer to tsi runtime state structure.*/ +tsi_state_t * g_tsiStatePtr[TSI_INSTANCE_COUNT] = { NULL }; + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_driver.c b/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_driver.c new file mode 100755 index 0000000..01a8517 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_driver.c @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <string.h> +#include "fsl_tsi_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_TSI_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ +extern IRQn_Type tsi_irq_ids[TSI_INSTANCE_COUNT]; +extern void TSI_DRV_IRQHandler0(void); +extern const tsi_parameter_limits_t * g_tsiParamLimits[tsi_OpModeCnt]; + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_Init +* Description : Initialize whole the TSI peripheral to be ready to read capacitance changes +* To initialize the TSI driver, the configuration structure should be handled. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_Init(uint32_t instance, tsi_state_t * tsiState, const tsi_user_config_t * tsiUserConfig) +{ + assert(instance < TSI_INSTANCE_COUNT); + + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiSt = g_tsiStatePtr[instance]; + + /* Critical section. */ + OSA_EnterCritical(kCriticalDisableInt); + + /* Exit if current instance is already initialized. */ + if(tsiSt) + { + /* End of critical section. */ + OSA_ExitCritical(kCriticalDisableInt); + return kStatus_TSI_Initialized; + } + /* Save runtime structure pointer.*/ + tsiSt = g_tsiStatePtr[instance] = tsiState; + + /* Clear the state structure for this instance. */ + memset(tsiSt, 0, sizeof(tsi_state_t)); + + /* Create the mutex used by whole driver. */ + OSA_MutexCreate(&tsiSt->lock); + /* Create the mutex used by change mode function. */ + OSA_MutexCreate(&tsiSt->lockChangeMode); + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiSt->lock, OSA_WAIT_FOREVER)) + { + /* End of critical section. */ + OSA_ExitCritical(kCriticalDisableInt); + return kStatus_TSI_Error; + } + + /* End of critical section. */ + OSA_ExitCritical(kCriticalDisableInt); + + tsiSt->opMode = tsi_OpModeNormal; + + tsiSt->opModesData[tsiSt->opMode].config = *tsiUserConfig->config; /* Store the hardware configuration. */ + + tsiSt->pCallBackFunc = tsiUserConfig->pCallBackFunc; + tsiSt->usrData = tsiUserConfig->usrData; + tsiSt->isBlockingMeasure = false; + /* Un-gate TSI module clock */ + CLOCK_SYS_EnableTsiClock(instance); + + /* Initialize the interrupt sync object. */ + OSA_SemaCreate(&tsiSt->irqSync, 0); + + TSI_HAL_Init(base); + TSI_HAL_SetConfiguration(base, &tsiSt->opModesData[tsiSt->opMode].config); + TSI_HAL_EnableInterrupt(base); + TSI_HAL_EnableEndOfScanInterrupt(base); + TSI_HAL_EnableSoftwareTriggerScan(base); + + /* Disable all electrodes */ + tsiState->opModesData[tsiState->opMode].enabledElectrodes = 0; + + /* Enable TSI interrupt on NVIC level. */ + INT_SYS_EnableIRQ(g_tsiIrqId[instance]); + + tsiSt->status = kStatus_TSI_Initialized; + + /* End of critical section. */ + OSA_MutexUnlock(&tsiSt->lock); + + return kStatus_TSI_Success; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_DeInit +* Description : De initialize whole the TSI peripheral and driver to be ready +* for any future use and don't load the system. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_DeInit(uint32_t instance) +{ + assert(instance < TSI_INSTANCE_COUNT); + + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + if (tsiState == NULL) + { + return kStatus_TSI_Error; + } + + TSI_HAL_DisableInterrupt(base); + tsiState->opModesData[tsiState->opMode].enabledElectrodes = 0; + TSI_HAL_ClearOutOfRangeFlag(base); + TSI_HAL_ClearEndOfScanFlag(base); + TSI_HAL_DisableModule(base); + + /* Disable the interrupt */ + INT_SYS_DisableIRQ(g_tsiIrqId[instance]); + + /* Destroy the interrupt synch object*/ + OSA_SemaDestroy(&tsiState->irqSync); + + /* Clear runtime structure pointer.*/ + tsiState = NULL; + + /* Gate TSI module clock */ + CLOCK_SYS_DisableTsiClock(instance); + + return kStatus_TSI_Success; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_SetCallBackFunc +* Description : Set the TSI call back function pointer for non blocking measurement +* +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_SetCallBackFunc(uint32_t instance, const tsi_callback_t pFuncCallBack, void * usrData) +{ + assert(instance < TSI_INSTANCE_COUNT); + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + if (g_tsiStatePtr[instance]->status != kStatus_TSI_Initialized) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return g_tsiStatePtr[instance]->status; + } + + g_tsiStatePtr[instance]->pCallBackFunc = pFuncCallBack; + g_tsiStatePtr[instance]->usrData = usrData; + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_Success; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_GetEnabledElectrodes +* Description : Get Enables electrodes for measuring. +* +*END**************************************************************************/ +uint32_t TSI_DRV_GetEnabledElectrodes(uint32_t instance) +{ + assert(instance < TSI_INSTANCE_COUNT); + + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + return tsiState->opModesData[tsiState->opMode].enabledElectrodes; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_MeasureBlocking +* Description : This function gets (measure) capacitance of enabled electrodes +* from the TSI module using a blocking method. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_MeasureBlocking(uint32_t instance) +{ + assert(instance < TSI_INSTANCE_COUNT); + osa_status_t syncStatus; + tsi_status_t status; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + /* Start the measurement process */ + if ((status = TSI_DRV_Measure(instance)) != kStatus_TSI_Success) + { + return status; + } + + tsiState->isBlockingMeasure = true; + + do + { + syncStatus = OSA_SemaWait(&tsiState->irqSync, 1000); /* 1 second timeout. */ + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Abort the measurement so it doesn't continue unexpectedly.*/ + TSI_DRV_AbortMeasure(instance); + return kStatus_TSI_Error; + } + + return kStatus_TSI_Success; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_AbortMeasure +* Description : This function aborts possible measure cycle. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_AbortMeasure(uint32_t instance) +{ + assert(instance < TSI_INSTANCE_COUNT); + + TSI_Type * base = g_tsiBase[instance]; + tsi_status_t status = kStatus_TSI_Success; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + if(tsiState->status == kStatus_TSI_Recalibration) + { + status = kStatus_TSI_Recalibration; + } + else if(tsiState->status != kStatus_TSI_Initialized) + { + TSI_HAL_ClearOutOfRangeFlag(base); + TSI_HAL_ClearEndOfScanFlag(base); + TSI_HAL_DisableModule(base); + + if(tsiState->isBlockingMeasure) + { + /* Signal the synchronous completion object. */ + OSA_SemaPost(&tsiState->irqSync); + tsiState->isBlockingMeasure = false; + } + + /* Return status of the driver to initialized state */ + tsiState->status = kStatus_TSI_Initialized; + } + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return status; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_IsBusy +* Description : Function returns the busy state of the driver +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_GetStatus(uint32_t instance) +{ + assert(instance < TSI_INSTANCE_COUNT); + + return g_tsiStatePtr[instance]->status; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_Recalibrate +* Description : The function force the recalibration process of TSI parameters. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_Recalibrate(uint32_t instance, uint32_t * lowestSignal) +{ + assert(instance < TSI_INSTANCE_COUNT); + + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + if (tsiState->status != kStatus_TSI_Initialized) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + return tsiState->status; + } + + tsiState->status = kStatus_TSI_Recalibration; + + *lowestSignal = TSI_HAL_Recalibrate(base, &(tsiState->opModesData[tsiState->opMode].config), + tsiState->opModesData[tsiState->opMode].enabledElectrodes, + g_tsiParamLimits[tsiState->opMode]); + + tsiState->status = kStatus_TSI_Initialized; + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + if(*lowestSignal == 0) + { + return kStatus_TSI_Error; + } + else + { + return kStatus_TSI_Success; + } +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_DisableLowPower +* Description : Enables/Disables the low power module. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_DisableLowPower(uint32_t instance, const tsi_modes_t mode) +{ + assert(instance < TSI_INSTANCE_COUNT); + + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + tsi_status_t status; + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + if (tsiState->status != kStatus_TSI_LowPower) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return tsiState->status; + } + + TSI_HAL_DisableLowPower(base); + TSI_HAL_EnableInterrupt(base); + TSI_HAL_EnableEndOfScanInterrupt(base); + TSI_HAL_EnableSoftwareTriggerScan(base); + + tsiState->status = kStatus_TSI_Initialized; + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + status = TSI_DRV_ChangeMode(instance, mode); + + return status; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_GetMode +* Description : Function returns the current mode of the driver +* +*END**************************************************************************/ +tsi_modes_t TSI_DRV_GetMode(uint32_t instance) +{ + assert(instance < TSI_INSTANCE_COUNT); + + return g_tsiStatePtr[instance]->opMode; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_SaveConfiguration +* Description : The function save the configuration for one mode of operation. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_SaveConfiguration(uint32_t instance, const tsi_modes_t mode, tsi_operation_mode_t * operationMode) +{ + assert(instance < TSI_INSTANCE_COUNT); + assert(operationMode); + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + if(mode >= tsi_OpModeCnt) + { + return kStatus_TSI_InvalidMode; + } + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + *operationMode = tsiState->opModesData[mode]; + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_Success; +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_irq.c b/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_irq.c new file mode 100755 index 0000000..a8f09da --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_irq.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_tsi_driver.h" +#if FSL_FEATURE_SOC_TSI_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +extern void TSI_DRV_IRQHandler(uint32_t instance); +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Implementation of TSI0 handler named in startup code. + * + * Passes instance to generic TSI IRQ handler. + */ +void TSI0_IRQHandler(void) +{ + TSI_DRV_IRQHandler(0); +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_lpm_callback.c new file mode 100755 index 0000000..51452ed --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_TSI_COUNT + +power_manager_error_code_t tsi_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t tsi_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_v2_driver_specific.c b/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_v2_driver_specific.c new file mode 100755 index 0000000..b72b13f --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_v2_driver_specific.c @@ -0,0 +1,505 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <string.h> +#include "fsl_tsi_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_TSI_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ +extern IRQn_Type tsi_irq_ids[TSI_INSTANCE_COUNT]; +extern void TSI_DRV_IRQHandler0(void); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +const tsi_parameter_limits_t g_tsiParamLimits[tsi_OpModeCnt] = +{ + /* Normal operation mode. */ + { + /* consNumberOfScan */ + { + /* upper */ + kTsiConsecutiveScansNumber_32time, + /* lower */ + kTsiConsecutiveScansNumber_1time + }, + /* refOscChargeCurrent */ + { + /* upper */ + kTsiRefOscChargeCurrent_32uA, + /* lower */ + kTsiRefOscChargeCurrent_2uA + }, + /* extOscChargeCurrent */ + { + /* upper */ + kTsiExtOscChargeCurrent_32uA, + /* lower */ + kTsiExtOscChargeCurrent_2uA + }, + /* activeModePrescaler */ + { + /* upper */ + kTsiActiveModePrescaler_1div, + /* lower */ + kTsiActiveModePrescaler_128div + } + }, + /* Proximity operation mode. */ + { + /* consNumberOfScan */ + { + /* upper */ + kTsiConsecutiveScansNumber_32time, + /* lower */ + kTsiConsecutiveScansNumber_1time + }, + /* refOscChargeCurrent */ + { + /* upper */ + kTsiRefOscChargeCurrent_32uA, + /* lower */ + kTsiRefOscChargeCurrent_2uA + }, + /* extOscChargeCurrent */ + { + /* upper */ + kTsiExtOscChargeCurrent_32uA, + /* lower */ + kTsiExtOscChargeCurrent_2uA + }, + /* activeModePrescaler */ + { + /* upper */ + kTsiActiveModePrescaler_1div, + /* lower */ + kTsiActiveModePrescaler_128div + } + }, + /* Low Power operation mode. */ + { + /* consNumberOfScan */ + { + /* upper */ + kTsiConsecutiveScansNumber_32time, + /* lower */ + kTsiConsecutiveScansNumber_1time + }, + /* refOscChargeCurrent */ + { + /* upper */ + kTsiRefOscChargeCurrent_32uA, + /* lower */ + kTsiRefOscChargeCurrent_2uA + }, + /*extOscChargeCurrent */ + { + /* upper */ + kTsiExtOscChargeCurrent_32uA, + /* lower */ + kTsiExtOscChargeCurrent_2uA + }, + /* activeModePrescaler */ + { + /* upper */ + kTsiActiveModePrescaler_1div, + /* lower */ + kTsiActiveModePrescaler_128div + } + } +}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_EnableElectrode +* Description : Enables/Disables the electrode for measuring. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_EnableElectrode(uint32_t instance, const uint32_t channel, const bool enable) +{ + assert(instance < TSI_INSTANCE_COUNT); + assert(channel < FSL_FEATURE_TSI_CHANNEL_COUNT); + + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + if (tsiState->status != kStatus_TSI_Initialized) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return tsiState->status; + } + + /* Check the condition for low power mode. */ + if((tsiState->opMode == tsi_OpModeLowPower) || (tsiState->opMode == tsi_OpModeProximity)) + { + if(tsiState->opModesData[tsi_OpModeLowPower].enabledElectrodes != 0) + { + /* Only one elctrode can be enabled in low power mode and proximity. */ + + /* Disable al previous enabled. */ + TSI_HAL_DisableChannels(base, 0xffffffff); + } + } + + if(enable) + { + tsiState->opModesData[tsiState->opMode].enabledElectrodes |= (1U << channel); + TSI_HAL_EnableChannel(base, channel); + } + else + { + tsiState->opModesData[tsiState->opMode].enabledElectrodes &= ~(1U << channel); + TSI_HAL_DisableChannel(base, channel); + } + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_Success; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_GetCounter +* Description : Function returns the counter value of selected channel +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_GetCounter(uint32_t instance, const uint32_t channel, uint16_t * counter) +{ + assert(instance < TSI_INSTANCE_COUNT); + assert(channel < FSL_FEATURE_TSI_CHANNEL_COUNT); + assert(counter); + + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + if(!TSI_HAL_GetEnabledChannel(base, channel)) + { + return kStatus_TSI_InvalidChannel; + } + + *counter = tsiState->counters[channel]; + + return kStatus_TSI_Success; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_Measure +* Description : This function gets (measure) capacitance of enabled electrodes +* from the TSI module using a non-blocking method. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_Measure(uint32_t instance) +{ + assert(instance < TSI_INSTANCE_COUNT); + + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + if (tsiState->status != kStatus_TSI_Initialized) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return tsiState->status; + } + + tsiState->status = kStatus_TSI_Busy; + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + TSI_HAL_DisableModule(base); + TSI_HAL_EnableSoftwareTriggerScan(base); + TSI_HAL_EnableModule(base); + TSI_HAL_StartSoftwareTrigger(base); + + return kStatus_TSI_Success; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_EnableLowPower +* Description : Enables/Disables the low power module. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_EnableLowPower(uint32_t instance) +{ + assert(instance < TSI_INSTANCE_COUNT); + + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + tsi_status_t status; + uint32_t i; + int32_t channel = -1; + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + if((tsiState->opModesData[tsiState->opMode].config.thresl == 0) || (tsiState->opModesData[tsiState->opMode].config.thresh == 0)) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_Error; + } + + if ((status = TSI_DRV_ChangeMode(instance, tsi_OpModeLowPower)) != kStatus_TSI_Success) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return status; + } + + if(tsiState->opModesData[tsiState->opMode].enabledElectrodes == 0) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_InvalidChannel; + } + + for(i = 0; i < FSL_FEATURE_TSI_CHANNEL_COUNT; i++) + { + if((uint32_t)(1 << i) & tsiState->opModesData[tsiState->opMode].enabledElectrodes) + { + channel = i; + break; + } + } + + if(channel == -1) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_InvalidChannel; + } + + tsiState->status = kStatus_TSI_LowPower; + + /* Configurate the peripheral for next use */ + TSI_HAL_EnableOutOfRangeInterrupt(base); + TSI_HAL_EnablePeriodicalScan(base); + TSI_HAL_SetLowPowerChannel(base, channel); + TSI_HAL_EnableLowPower(base); + TSI_HAL_EnableInterrupt(base); + TSI_HAL_EnableModule(base); + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_Success; +} + + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_ChangeMode +* Description : The function change the current mode. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_ChangeMode(uint32_t instance, const tsi_modes_t mode) +{ + assert(instance < TSI_INSTANCE_COUNT); + + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + if((mode == tsiState->opMode) || (mode == tsi_OpModeNoChange)) + { + return kStatus_TSI_Success; + } + + if(mode >= tsi_OpModeNoise) /* Neither the noise mode is not supported in TSIv1&2 revision. */ + { + return kStatus_TSI_InvalidMode; + } + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lockChangeMode, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + if (tsiState->status != kStatus_TSI_Initialized) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lockChangeMode); + return tsiState->status; + } + + tsiState->opMode = mode; + + TSI_HAL_SetConfiguration(base, &tsiState->opModesData[mode].config); + + /* Disable all electrodes */ + TSI_HAL_DisableChannels(base, 0xffff); + + /* Enable the set electrodes for current operation mode */ + TSI_HAL_EnableChannels(base, tsiState->opModesData[mode].enabledElectrodes); + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lockChangeMode); + + return kStatus_TSI_Success; +} + + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_LoadConfiguration +* Description : The function load the configuration for one mode of operation. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_LoadConfiguration(uint32_t instance, const tsi_modes_t mode, const tsi_operation_mode_t * operationMode) +{ + assert(instance < TSI_INSTANCE_COUNT); + assert(operationMode); + TSI_Type * base; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + if(mode >= tsi_OpModeCnt) + { + return kStatus_TSI_InvalidMode; + } + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + tsiState->opModesData[mode] = *operationMode; + + /* In case that the loaded configuration is active one, update the HW also. */ + if(mode == tsiState->opMode) + { + base = g_tsiBase[instance]; + + TSI_HAL_SetConfiguration(base, &tsiState->opModesData[mode].config); + + /* Disable all electrodes */ + TSI_HAL_DisableChannels(base, 0xffff); + + /* Enable the set electrodes for current operation mode */ + TSI_HAL_EnableChannels(base, tsiState->opModesData[mode].enabledElectrodes); + + TSI_HAL_EnableInterrupt(base); + TSI_HAL_EnableEndOfScanInterrupt(base); + } + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_Success; +} + +/*! + * @brief Interrupt handler for TSI. + * This handler uses the tsi State structure to handle the instance depend data. + * This is not a public API as it is called whenever an interrupt occurs. + */ +void TSI_DRV_IRQHandler(uint32_t instance) +{ + TSI_Type * base = g_tsiBase[instance]; + uint32_t channels = TSI_HAL_GetEnabledChannels(base); + uint32_t i; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + /* Check if a measure is running and wanted. */ + + if(tsiState->status != kStatus_TSI_Busy) + { + return; + } + + TSI_HAL_ClearOutOfRangeFlag(base); + TSI_HAL_ClearEndOfScanFlag(base); + + for(i = 0; i < FSL_FEATURE_TSI_CHANNEL_COUNT; i++) + { + if((uint32_t)(1 << i) & channels) + { + tsiState->counters[i] = TSI_HAL_GetCounter(base, i); + } + } + + + if(tsiState->isBlockingMeasure) + { + /* Signal the synchronous completion object. */ + OSA_SemaPost(&tsiState->irqSync); + tsiState->isBlockingMeasure = false; + } + else if(tsiState->pCallBackFunc) + { + tsiState->pCallBackFunc(instance, tsiState->usrData); + } + + if(tsiState->status != kStatus_TSI_LowPower) + { + /* Return status of the driver to initialized state */ + tsiState->status = kStatus_TSI_Initialized; + } +} + +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_v4_driver_specific.c b/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_v4_driver_specific.c new file mode 100755 index 0000000..4111716 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/tsi/fsl_tsi_v4_driver_specific.c @@ -0,0 +1,522 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <string.h> +#include "fsl_tsi_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#if FSL_FEATURE_SOC_TSI_COUNT + +/******************************************************************************* + * Definitions + ******************************************************************************/ +extern IRQn_Type tsi_irq_ids[TSI_INSTANCE_COUNT]; +extern void TSI_DRV_IRQHandler0(void); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Normal operation mode parameter limits. */ +const tsi_parameter_limits_t g_tsiParamLimits_normal = +{ + /* consNumberOfScan */ + { + /* upper */ + kTsiConsecutiveScansNumber_32time, + /* lower */ + kTsiConsecutiveScansNumber_1time + }, + /* refOscChargeCurrent */ + { + /* upper */ + kTsiRefOscChargeCurrent_32uA, + /* lower */ + kTsiRefOscChargeCurrent_1uA + }, + /*extOscChargeCurrent */ + { + /* upper */ + kTsiExtOscChargeCurrent_32uA, + /* lower */ + kTsiExtOscChargeCurrent_1uA + } +}; +/* Proximity operation mode parameter limits. */ +const tsi_parameter_limits_t g_tsiParamLimits_proximity = +{ + /* consNumberOfScan */ + { + /* upper */ + kTsiConsecutiveScansNumber_32time, + /* lower */ + kTsiConsecutiveScansNumber_1time + }, + /* refOscChargeCurrent */ + { + /* upper */ + kTsiRefOscChargeCurrent_32uA, + /* lower */ + kTsiRefOscChargeCurrent_1uA + }, + /*extOscChargeCurrent */ + { + /* upper */ + kTsiExtOscChargeCurrent_32uA, + /* lower */ + kTsiExtOscChargeCurrent_1uA + } +}; + +/* Low Power operation mode parameter limits. */ +const tsi_parameter_limits_t g_tsiParamLimits_low_power = +{ + /* consNumberOfScan */ + { + /* upper */ + kTsiConsecutiveScansNumber_32time, + /* lower */ + kTsiConsecutiveScansNumber_1time + }, + /* refOscChargeCurrent */ + { + /* upper */ + kTsiRefOscChargeCurrent_32uA, + /* lower */ + kTsiRefOscChargeCurrent_1uA + }, + /*extOscChargeCurrent */ + { + /* upper */ + kTsiExtOscChargeCurrent_32uA, + /* lower */ + kTsiExtOscChargeCurrent_1uA + } +}; + +const tsi_parameter_limits_t * g_tsiParamLimits[tsi_OpModeCnt] = +{ + &g_tsiParamLimits_normal, + &g_tsiParamLimits_proximity, + &g_tsiParamLimits_low_power, + NULL /* The NULL pointer force the HAL function to calibrate NOISE mode. */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_EnableElectrode +* Description : Enables/Disables the electrode for measuring. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_EnableElectrode(uint32_t instance, const uint32_t channel, const bool enable) +{ + assert(instance < TSI_INSTANCE_COUNT); + assert(channel < FSL_FEATURE_TSI_CHANNEL_COUNT); + + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + if (tsiState->status != kStatus_TSI_Initialized) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return tsiState->status; + } + + /* Check the condition for low power mode. */ + if((tsiState->opMode == tsi_OpModeLowPower) || (tsiState->opMode == tsi_OpModeProximity)) + { + tsiState->opModesData[tsiState->opMode].enabledElectrodes = 0; + } + + if(enable) + { + tsiState->opModesData[tsiState->opMode].enabledElectrodes |= (1U << channel); + } + else + { + tsiState->opModesData[tsiState->opMode].enabledElectrodes &= ~(1U << channel); + } + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_Success; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_GetCounter +* Description : Function returns the counter value of selected channel +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_GetCounter(uint32_t instance, const uint32_t channel, uint16_t * counter) +{ + assert(instance < TSI_INSTANCE_COUNT); + assert(channel < FSL_FEATURE_TSI_CHANNEL_COUNT); + assert(counter); + + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + if(!((1U << channel) & (tsiState->opModesData[tsiState->opMode].enabledElectrodes))) /* Check the channel number. */ + { + return kStatus_TSI_InvalidChannel; + } + + *counter = tsiState->counters[channel]; + + return kStatus_TSI_Success; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_Measure +* Description : This function gets (measure) capacitance of enabled electrodes +* from the TSI module using a non-blocking method. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_Measure(uint32_t instance) +{ + assert(instance < TSI_INSTANCE_COUNT); + + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + uint32_t first_pen, pen; + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + if (tsiState->status != kStatus_TSI_Initialized) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return tsiState->status; + } + + if(!tsiState->opModesData[tsiState->opMode].enabledElectrodes) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_InvalidChannel; + } + + tsiState->status = kStatus_TSI_Busy; + + first_pen = 0U; + pen = tsiState->opModesData[tsiState->opMode].enabledElectrodes; + while (((pen >> first_pen) & 0x1U) == 0U) { + first_pen++; + } + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + TSI_HAL_DisableModule(base); + TSI_HAL_SetMeasuredChannelNumber(base, first_pen); + TSI_HAL_EnableSoftwareTriggerScan(base); + TSI_HAL_EnableModule(base); + TSI_HAL_StartSoftwareTrigger(base); + + return kStatus_TSI_Success; +} + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_EnableLowPower +* Description : Enables/Disables the low power module. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_EnableLowPower(uint32_t instance) +{ + assert(instance < TSI_INSTANCE_COUNT); + + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + tsi_status_t status; + uint32_t i; + int32_t channel = -1; + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + if((tsiState->opModesData[tsiState->opMode].config.thresl == 0) || (tsiState->opModesData[tsiState->opMode].config.thresh == 0)) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_Error; + } + + if ((status = TSI_DRV_ChangeMode(instance, tsi_OpModeLowPower)) != kStatus_TSI_Success) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return status; + } + + if(tsiState->opModesData[tsiState->opMode].enabledElectrodes == 0) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_InvalidChannel; + } + + /* Configurate the peripheral for next use */ + TSI_HAL_EnableOutOfRangeInterrupt(base); + TSI_HAL_EnableHardwareTriggerScan(base); + + for(i = 0; i < FSL_FEATURE_TSI_CHANNEL_COUNT; i++) + { + if((uint32_t)(1 << i) & tsiState->opModesData[tsiState->opMode].enabledElectrodes) + { + channel = i; + break; + } + } + + if(channel == -1) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_InvalidChannel; + } + + tsiState->status = kStatus_TSI_LowPower; + + TSI_HAL_EnableLowPower(base); + TSI_HAL_SetMeasuredChannelNumber(base, channel); + TSI_HAL_EnableInterrupt(base); + TSI_HAL_EnableModule(base); + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_Success; +} + + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_ChangeMode +* Description : The function change the current mode. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_ChangeMode(uint32_t instance, const tsi_modes_t mode) +{ + assert(instance < TSI_INSTANCE_COUNT); + + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + if((mode == tsiState->opMode) || (mode == tsi_OpModeNoChange)) + { + return kStatus_TSI_Success; + } + + if(mode >= tsi_OpModeCnt) + { + return kStatus_TSI_InvalidMode; + } + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lockChangeMode, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + if (tsiState->status != kStatus_TSI_Initialized) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lockChangeMode); + + return tsiState->status; + } + + if(mode == tsi_OpModeNoise) + { + if(!tsiState->opModesData[mode].config.mode) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lockChangeMode); + + return kStatus_TSI_InvalidMode; + } + }else + { + if(tsiState->opModesData[mode].config.mode) + { + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lockChangeMode); + + return kStatus_TSI_InvalidMode; + } + } + + tsiState->opMode = mode; + + TSI_HAL_SetConfiguration(base, &tsiState->opModesData[mode].config); + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lockChangeMode); + + return kStatus_TSI_Success; +} + + +/*FUNCTION********************************************************************** +* +* Function Name : TSI_DRV_LoadConfiguration +* Description : The function load the configuration for one mode of operation. +* +*END**************************************************************************/ +tsi_status_t TSI_DRV_LoadConfiguration(uint32_t instance, const tsi_modes_t mode, const tsi_operation_mode_t * operationMode) +{ + assert(instance < TSI_INSTANCE_COUNT); + assert(operationMode); + TSI_Type * base; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + + if(mode >= tsi_OpModeCnt) + { + return kStatus_TSI_InvalidMode; + } + + /* Critical section. Access to global variable */ + if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) + { + return kStatus_TSI_Error; + } + + tsiState->opModesData[mode] = *operationMode; + + /* In case that the loaded configuration is active one, update the HW also. */ + if(mode == tsiState->opMode) + { + base = g_tsiBase[instance]; + + TSI_HAL_SetConfiguration(base, &tsiState->opModesData[mode].config); + TSI_HAL_EnableInterrupt(base); + TSI_HAL_EnableEndOfScanInterrupt(base); + } + + /* End of critical section. */ + OSA_MutexUnlock(&tsiState->lock); + + return kStatus_TSI_Success; +} + +/*! + * @brief Interrupt handler for TSI. + * This handler uses the tsi State structure to handle the instance depend data. + * This is not a public API as it is called whenever an interrupt occurs. + */ +void TSI_DRV_IRQHandler(uint32_t instance) +{ + TSI_Type * base = g_tsiBase[instance]; + tsi_state_t * tsiState = g_tsiStatePtr[instance]; + uint32_t channels = tsiState->opModesData[tsiState->opMode].enabledElectrodes; + uint32_t curr_channel = TSI_HAL_GetMeasuredChannelNumber(base); + uint32_t next_pen, pen; + /* Check if a measure is running and wanted. */ + + TSI_HAL_ClearOutOfRangeFlag(base); + TSI_HAL_ClearEndOfScanFlag(base); + + if((uint32_t)(1 << curr_channel) & channels) + { + /* Am I in noise mode? */ + if(tsiState->opMode == tsi_OpModeNoise) + { + tsiState->counters[curr_channel] = TSI_HAL_GetMode(base); + } + else + { + tsiState->counters[curr_channel] = TSI_HAL_GetCounter(base); + } + } + + next_pen = curr_channel + 1; + pen = channels; + while (((((pen >> next_pen) & 0x1U)) == 0U) && (next_pen < 16)) + { + next_pen++; + } + + if(next_pen < 16) + { + /* Measurement must continue on next channel. */ + TSI_HAL_SetMeasuredChannelNumber(base, next_pen); + TSI_HAL_StartSoftwareTrigger(base); + return; + } + + if(tsiState->isBlockingMeasure) + { + /* Signal the synchronous completion object. */ + OSA_SemaPost(&tsiState->irqSync); + tsiState->isBlockingMeasure = false; + } + else if(tsiState->pCallBackFunc) + { + tsiState->pCallBackFunc(instance, tsiState->usrData); + } + + if(tsiState->status != kStatus_TSI_LowPower) + { + /* Return status of the driver to initialized state */ + tsiState->status = kStatus_TSI_Initialized; + } +} + +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_common.c b/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_common.c new file mode 100755 index 0000000..87fd1c3 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_common.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +#if FSL_FEATURE_SOC_UART_COUNT +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to uart runtime state structure.*/ +void * g_uartStatePtr[UART_INSTANCE_COUNT] = { NULL }; + +/* Table of base addresses for uart instances. */ +UART_Type * const g_uartBase[UART_INSTANCE_COUNT] = UART_BASE_PTRS; + +/* Table to save UART IRQ numbers defined in CMSIS files. */ +IRQn_Type g_uartRxTxIrqId[UART_INSTANCE_COUNT] = UART_RX_TX_IRQS; + +#endif /* FSL_FEATURE_SOC_UART_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_dma_driver.c b/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_dma_driver.c new file mode 100755 index 0000000..d3453a2 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_dma_driver.c @@ -0,0 +1,691 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_uart_dma_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#include "fsl_dma_request.h" + +#if FSL_FEATURE_SOC_DMA_COUNT && FSL_FEATURE_SOC_UART_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to uart runtime state structure */ +extern void * g_uartStatePtr[UART_INSTANCE_COUNT]; + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static void UART_DRV_DmaCompleteSendData(uint32_t instance); +static void UART_DRV_DmaTxCallback(void *param, dma_channel_status_t status); +static uart_status_t UART_DRV_DmaStartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +static void UART_DRV_DmaCompleteReceiveData(uint32_t instance); +static void UART_DRV_DmaRxCallback(void *param, dma_channel_status_t status); +static uart_status_t UART_DRV_DmaStartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize); +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaInit + * Description : This function initializes a UART instance for operation. + * This function will initialize the run-time state structure to keep track of + * the on-going transfers, ungate the clock to the UART module, initialize the + * module to user defined settings and default settings, configure UART DMA + * and enable the UART module transmitter and receiver. + * The following is an example of how to set up the uart_dma_state_t and the + * uart_user_config_t parameters and how to call the UART_DRV_DmaInit function + * by passing in these parameters: + * uart_user_config_t uartConfig; + * uartConfig.baudRate = 9600; + * uartConfig.bitCountPerChar = kUart8BitsPerChar; + * uartConfig.parityMode = kUartParityDisabled; + * uartConfig.stopBitCount = kUartOneStopBit; + * uart_dma_state_t uartDmaState; + * UART_DRV_DmaInit(instance, &uartDmaState, &uartConfig); + * + *END**************************************************************************/ +uart_status_t UART_DRV_DmaInit(uint32_t instance, + uart_dma_state_t * uartDmaStatePtr, + const uart_dma_user_config_t * uartUserConfig) +{ + assert(uartDmaStatePtr && uartUserConfig); + assert(g_uartBase[instance]); + assert(instance < UART_INSTANCE_COUNT); + /* This driver only support UART instances with separate DMA channels for + * both Tx and Rx.*/ + assert(FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(instance) == 1); + + UART_Type * base = g_uartBase[instance]; + uint32_t uartSourceClock = 0; + dma_request_source_t uartTxDmaRequest = kDmaRequestMux0Disable; + dma_request_source_t uartRxDmaRequest = kDmaRequestMux0Disable; + dma_channel_t *chn; + DMA_Type * dmaBase; + dma_channel_link_config_t config; + + config.channel1 = 0; + config.channel2 = 0; + config.linkType = kDmaChannelLinkDisable; + + /* Exit if current instance is already initialized. */ + if (g_uartStatePtr[instance]) + { + return kStatus_UART_Initialized; + } + + /* Clear the state structure for this instance. */ + memset(uartDmaStatePtr, 0, sizeof(uart_dma_state_t)); + + /* Save runtime structure pointer.*/ + g_uartStatePtr[instance] = uartDmaStatePtr; + + /* Un-gate UART module clock */ + CLOCK_SYS_EnableUartClock(instance); + + /* Initialize UART to a known state. */ + UART_HAL_Init(base); + + /* Create Semaphore for txIrq and rxIrq. */ + OSA_SemaCreate(&uartDmaStatePtr->txIrqSync, 0); + OSA_SemaCreate(&uartDmaStatePtr->rxIrqSync, 0); + + /* UART clock source is either system or bus clock depending on instance */ + uartSourceClock = CLOCK_SYS_GetUartFreq(instance); + + /* Initialize UART baud rate, bit count, parity and stop bit. */ + UART_HAL_SetBaudRate(base, uartSourceClock, uartUserConfig->baudRate); + UART_HAL_SetBitCountPerChar(base, uartUserConfig->bitCountPerChar); + UART_HAL_SetParityMode(base, uartUserConfig->parityMode); +#if FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT + UART_HAL_SetStopBitCount(base, uartUserConfig->stopBitCount); +#endif + + /* Enable DMA trigger when transmit data register empty, + * and receive data register full. */ + UART_HAL_SetTxDmaCmd(base, true); + UART_HAL_SetRxDmaCmd(base, true); + + switch (instance) + { +#if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(0) == 1) + case 0: + uartRxDmaRequest = kDmaRequestMux0UART0Rx; + uartTxDmaRequest = kDmaRequestMux0UART0Tx; + break; +#endif +#if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(1) == 1) + case 1: + uartRxDmaRequest = kDmaRequestMux0UART1Rx; + uartTxDmaRequest = kDmaRequestMux0UART1Tx; + break; +#endif +#if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(2) == 1) + case 2: + uartRxDmaRequest = kDmaRequestMux0UART2Rx; + uartTxDmaRequest = kDmaRequestMux0UART2Tx; + break; +#endif + default : + break; + } + + /* Request DMA channels for RX FIFO. */ + DMA_DRV_RequestChannel(kDmaAnyChannel, uartRxDmaRequest, + &uartDmaStatePtr->dmaUartRx); + DMA_DRV_RegisterCallback(&uartDmaStatePtr->dmaUartRx, + UART_DRV_DmaRxCallback, (void *)instance); + + chn = &uartDmaStatePtr->dmaUartRx; + dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + + DMA_HAL_SetAutoAlignCmd(dmaBase, chn->channel, false); + DMA_HAL_SetCycleStealCmd(dmaBase, chn->channel, true); + DMA_HAL_SetAsyncDmaRequestCmd(dmaBase, chn->channel, false); + DMA_HAL_SetDisableRequestAfterDoneCmd(dmaBase, chn->channel, true); + DMA_HAL_SetChanLink(dmaBase, chn->channel, &config); + + DMA_HAL_SetSourceAddr(dmaBase, chn->channel, UART_HAL_GetDataRegAddr(base)); + DMA_HAL_SetSourceModulo(dmaBase, chn->channel, kDmaModuloDisable); + DMA_HAL_SetSourceTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); + DMA_HAL_SetSourceIncrementCmd(dmaBase, chn->channel, false); + + DMA_HAL_SetDestModulo(dmaBase, chn->channel, kDmaModuloDisable); + DMA_HAL_SetDestTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); + DMA_HAL_SetDestIncrementCmd(dmaBase, chn->channel, true); + + DMA_HAL_SetIntCmd(dmaBase, chn->channel, true); + + /* Request DMA channels for TX FIFO. */ + DMA_DRV_RequestChannel(kDmaAnyChannel, uartTxDmaRequest, + &uartDmaStatePtr->dmaUartTx); + DMA_DRV_RegisterCallback(&uartDmaStatePtr->dmaUartTx, + UART_DRV_DmaTxCallback, (void *)instance); + + chn = &uartDmaStatePtr->dmaUartTx; + dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + + DMA_HAL_SetAutoAlignCmd(dmaBase, chn->channel, false); + DMA_HAL_SetCycleStealCmd(dmaBase, chn->channel, true); + DMA_HAL_SetAsyncDmaRequestCmd(dmaBase, chn->channel, false); + DMA_HAL_SetDisableRequestAfterDoneCmd(dmaBase, chn->channel, true); + DMA_HAL_SetChanLink(dmaBase, chn->channel, &config); + + DMA_HAL_SetSourceModulo(dmaBase, chn->channel, kDmaModuloDisable); + DMA_HAL_SetSourceTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); + DMA_HAL_SetSourceIncrementCmd(dmaBase, chn->channel, true); + + DMA_HAL_SetDestAddr(dmaBase, chn->channel, UART_HAL_GetDataRegAddr(base)); + DMA_HAL_SetDestModulo(dmaBase, chn->channel, kDmaModuloDisable); + DMA_HAL_SetDestTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); + DMA_HAL_SetDestIncrementCmd(dmaBase, chn->channel, false); + + DMA_HAL_SetIntCmd(dmaBase, chn->channel, true); + + /* Finally, enable the UART transmitter and receiver*/ + UART_HAL_EnableTransmitter(base); + UART_HAL_EnableReceiver(base); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaDeinit + * Description : This function shuts down the UART by disabling UART DMA and + * the transmitter/receiver. + * + *END**************************************************************************/ +uart_status_t UART_DRV_DmaDeinit(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + assert(g_uartBase[instance]); + + /* Exit if current instance is already de-initialized or is gated.*/ + if ((!g_uartStatePtr[instance]) || (!CLOCK_SYS_GetUartGateCmd(instance))) + { + return kStatus_UART_Fail; + } + + UART_Type * base = g_uartBase[instance]; + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + + /* Wait until the data is completely shifted out of shift register */ + while(!(UART_BRD_S1_TC(base))) { } + + UART_HAL_SetTxDmaCmd(base, false); + UART_HAL_SetRxDmaCmd(base, false); + + /* Release DMA channel. */ + DMA_DRV_FreeChannel(&uartDmaState->dmaUartRx); + DMA_DRV_FreeChannel(&uartDmaState->dmaUartTx); + + /* Disable TX and RX */ + UART_HAL_DisableTransmitter(base); + UART_HAL_DisableReceiver(base); + + /* Destroy TX and RX sema. */ + OSA_SemaDestroy(&uartDmaState->txIrqSync); + OSA_SemaDestroy(&uartDmaState->rxIrqSync); + + /* Cleared state pointer. */ + g_uartStatePtr[instance] = NULL; + + /* Gate UART module clock */ + CLOCK_SYS_DisableUartClock(instance); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaSendDataBlocking + * Description : Sends (transmits) data out through the UART-DMA module + * using a blocking method. + * + *END**************************************************************************/ +uart_status_t UART_DRV_DmaSendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + assert(txBuff); + assert(instance < UART_INSTANCE_COUNT); + + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + uart_status_t retVal = kStatus_UART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + uartDmaState->isTxBlocking = true; + + /* Start the transmission process */ + retVal = UART_DRV_DmaStartSendData(instance, txBuff, txSize); + + if (retVal == kStatus_UART_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&uartDmaState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&uartDmaState->dmaUartTx); + + /* Update the information of the module driver state */ + uartDmaState->isTxBusy = false; + + retVal = kStatus_UART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaSendData + * Description : This function sends (transmits) data through the UART module + * using a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the transmit function. The application + * has to get the transmit status to see when the transmit is complete. In + * other words, after calling non-blocking (asynchronous) send function, the + * application must get the transmit status to check if transmit is completed + * or not. The asynchronous method of transmitting and receiving allows the UART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +uart_status_t UART_DRV_DmaSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(txBuff); + assert(instance < UART_INSTANCE_COUNT); + + uart_status_t retVal = kStatus_UART_Success; + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + + /* Indicates current transaction is non-blocking. */ + uartDmaState->isTxBlocking = false; + + /* Start the transmission process*/ + retVal = UART_DRV_DmaStartSendData(instance, txBuff, txSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaGetTransmitStatus + * Description : This function returns whether the previous UART transmit + * has finished. When performing an async transmit, the user can call this + * function to ascertain the state of the current transmission: in progress + * (or busy) or complete (success). In addition, if the transmission is still + * in progress, the user can obtain the number of words that have been + * currently transferred. + * + *END**************************************************************************/ +uart_status_t UART_DRV_DmaGetTransmitStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < UART_INSTANCE_COUNT); + + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = DMA_DRV_GetUnfinishedBytes(&uartDmaState->dmaUartTx); + } + + return (uartDmaState->isTxBusy ? kStatus_UART_TxBusy : kStatus_UART_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaAbortSendingData + * Description : This function terminates an asynchronous UART transmission + * early. During an async UART transmission, the user has the option to + * terminate the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +uart_status_t UART_DRV_DmaAbortSendingData(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!uartDmaState->isTxBusy) + { + return kStatus_UART_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + UART_DRV_DmaCompleteSendData(instance); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaReceiveDataBlocking + * Description : This function gets (receives) data from the UART module using + * a blocking method. A blocking (also known as synchronous) function means that + * the function does not return until the receive is complete. This blocking + * function is used to send data through the UART port. + * + *END**************************************************************************/ +uart_status_t UART_DRV_DmaReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout) +{ + assert(rxBuff); + assert(instance < UART_INSTANCE_COUNT); + + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + uart_status_t retVal = kStatus_UART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + uartDmaState->isRxBlocking = true; + + retVal = UART_DRV_DmaStartReceiveData(instance, rxBuff, rxSize); + + if (retVal == kStatus_UART_Success) + { + /* Wait until all the data is received or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&uartDmaState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&uartDmaState->dmaUartRx); + + /* Update the information of the module driver state */ + uartDmaState->isRxBusy = false; + + retVal = kStatus_UART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaReceiveData + * Description : This function gets (receives) data from the UART module using + * a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. In other + * words, after calling non-blocking (asynchronous) get function, the + * application must get the receive status to check if receive is completed or + * not. The asynchronous method of transmitting and receiving allows the UART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +uart_status_t UART_DRV_DmaReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(rxBuff); + assert(instance < UART_INSTANCE_COUNT); + + uart_status_t retVal = kStatus_UART_Success; + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + + /* Indicates current transaction is non-blocking. */ + uartDmaState->isRxBlocking = false; + + retVal = UART_DRV_DmaStartReceiveData(instance, rxBuff, rxSize); + + return retVal ; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaGetReceiveStatus + * Description : This function returns whether the previous UART receive is + * complete. When performing an async receive, the user can call this function + * to ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, + * the user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +uart_status_t UART_DRV_DmaGetReceiveStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < UART_INSTANCE_COUNT); + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = DMA_DRV_GetUnfinishedBytes(&uartDmaState->dmaUartRx); + } + + return (uartDmaState->isRxBusy ? kStatus_UART_RxBusy : kStatus_UART_Success); +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaAbortReceivingData + * Description : This function shuts down the UART by disabling interrupts and + * the transmitter/receiver. + * + *END**************************************************************************/ +uart_status_t UART_DRV_DmaAbortReceivingData(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!uartDmaState->isRxBusy) + { + return kStatus_UART_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + UART_DRV_DmaCompleteReceiveData(instance); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaCompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void UART_DRV_DmaCompleteSendData(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&uartDmaState->dmaUartTx); + + /* Signal the synchronous completion object. */ + if (uartDmaState->isTxBlocking) + { + OSA_SemaPost(&uartDmaState->txIrqSync); + } + + /* Update the information of the module driver state */ + uartDmaState->isTxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaTxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void UART_DRV_DmaTxCallback(void *param, dma_channel_status_t status) +{ + UART_DRV_DmaCompleteSendData((uint32_t)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaStartSendData + * Description : This is not a public interface. + * + *END**************************************************************************/ +static uart_status_t UART_DRV_DmaStartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(instance < UART_INSTANCE_COUNT); + + /* Get current runtime structure. */ + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + dma_channel_t *chn = &uartDmaState->dmaUartTx; + DMA_Type * dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + + /* Check that we're not busy already transmitting data from a previous function call. */ + if (uartDmaState->isTxBusy) + { + return kStatus_UART_TxBusy; + } + + /* Update UART DMA run-time structure. */ + uartDmaState->isTxBusy = true; + + DMA_HAL_SetSourceAddr(dmaBase, chn->channel, (uint32_t)txBuff); + DMA_HAL_SetTransferCount(dmaBase, chn->channel, txSize); + + DMA_DRV_StartChannel(chn); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaCompleteReceiveData + * Description : Finish up a receive by completing the process of receiving data + * and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void UART_DRV_DmaCompleteReceiveData(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + + /* Stop DMA channel. */ + DMA_DRV_StopChannel(&uartDmaState->dmaUartRx); + + /* Signal the synchronous completion object. */ + if (uartDmaState->isRxBlocking) + { + OSA_SemaPost(&uartDmaState->rxIrqSync); + } + + /* Update the information of the module driver state */ + uartDmaState->isRxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaRxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void UART_DRV_DmaRxCallback(void *param, dma_channel_status_t status) +{ + UART_DRV_DmaCompleteReceiveData((uint32_t)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_DmaStartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static uart_status_t UART_DRV_DmaStartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(instance < UART_INSTANCE_COUNT); + + /* Get current runtime structure. */ + uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; + dma_channel_t *chn = &uartDmaState->dmaUartRx; + DMA_Type * dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; + + /* Check that we're not busy already receiving data from a previous function call. */ + if (uartDmaState->isRxBusy) + { + return kStatus_UART_RxBusy; + } + + /* Update UART DMA run-time structure. */ + uartDmaState->isRxBusy = true; + + DMA_HAL_SetDestAddr(dmaBase, chn->channel, (uint32_t)rxBuff); + DMA_HAL_SetTransferCount(dmaBase, chn->channel, rxSize); + + DMA_DRV_StartChannel(chn); + + return kStatus_UART_Success; +} + +#endif /* FSL_FEATURE_SOC_DMA_COUNT && FSL_FEATURE_SOC_UART_COUNT */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_driver.c b/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_driver.c new file mode 100755 index 0000000..78f74de --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_driver.c @@ -0,0 +1,844 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_uart_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" + +#if FSL_FEATURE_SOC_UART_COUNT +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to uart runtime state structure */ +extern void * g_uartStatePtr[UART_INSTANCE_COUNT]; + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static void UART_DRV_CompleteSendData(uint32_t instance); +static uart_status_t UART_DRV_StartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +static void UART_DRV_CompleteReceiveData(uint32_t instance); +static uart_status_t UART_DRV_StartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize); +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_Init + * Description : This function initializes a UART instance for operation. + * This function will initialize the run-time state structure to keep track of + * the on-going transfers, ungate the clock to the UART module, initialize the + * module to user defined settings and default settings, configure the IRQ state + * structure and enable the module-level interrupt to the core, and enable the + * UART module transmitter and receiver. + * The following is an example of how to set up the uart_state_t and the + * uart_user_config_t parameters and how to call the UART_DRV_Init function by + * passing in these parameters: + * uart_user_config_t uartConfig; + * uartConfig.baudRate = 9600; + * uartConfig.bitCountPerChar = kUart8BitsPerChar; + * uartConfig.parityMode = kUartParityDisabled; + * uartConfig.stopBitCount = kUartOneStopBit; + * uart_state_t uartState; + * UART_DRV_Init(instance, &uartState, &uartConfig); + * + *END**************************************************************************/ +uart_status_t UART_DRV_Init(uint32_t instance, uart_state_t * uartStatePtr, + const uart_user_config_t * uartUserConfig) +{ + assert(uartStatePtr && uartUserConfig); + assert(g_uartBase[instance]); + assert(instance < UART_INSTANCE_COUNT); + + UART_Type * base = g_uartBase[instance]; + uint32_t uartSourceClock; + + /* Exit if current instance is already initialized. */ + if (g_uartStatePtr[instance]) + { + return kStatus_UART_Initialized; + } + + /* Clear the state structure for this instance. */ + memset(uartStatePtr, 0, sizeof(uart_state_t)); + + /* Save runtime structure pointer.*/ + g_uartStatePtr[instance] = uartStatePtr; + + /* Un-gate UART module clock */ + CLOCK_SYS_EnableUartClock(instance); + + /* Initialize UART to a known state. */ + UART_HAL_Init(base); + + /* Create Semaphore for txIrq and rxIrq. */ + OSA_SemaCreate(&uartStatePtr->txIrqSync, 0); + OSA_SemaCreate(&uartStatePtr->rxIrqSync, 0); + + /* UART clock source is either system or bus clock depending on instance */ + uartSourceClock = CLOCK_SYS_GetUartFreq(instance); + + /* Initialize UART baud rate, bit count, parity and stop bit. */ + UART_HAL_SetBaudRate(base, uartSourceClock, uartUserConfig->baudRate); + UART_HAL_SetBitCountPerChar(base, uartUserConfig->bitCountPerChar); + UART_HAL_SetParityMode(base, uartUserConfig->parityMode); +#if FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT + UART_HAL_SetStopBitCount(base, uartUserConfig->stopBitCount); +#endif + +#if FSL_FEATURE_UART_HAS_FIFO + uint8_t fifoSize; + /* Obtain raw TX FIFO size bit setting */ + fifoSize = UART_HAL_GetTxFifoSize(base); + /* Now calculate the number of data words per given FIFO size */ + uartStatePtr->txFifoEntryCount = (fifoSize == 0 ? 1 : 0x1 << (fifoSize + 1)); + + /* Configure the TX FIFO watermark to be 1/2 of the total entry or 0 if + * entry count = 1 A watermark setting of 0 for TX FIFO entry count of 1 + * means that TDRE will only interrupt when the TX buffer (the one entry in + * the TX FIFO) is empty. Otherwise, if we set the watermark to 1, the TDRE + * will always be set regardless if the TX buffer was empty or not as the + * spec says TDRE will set when the FIFO is at or below the configured + * watermark. */ + if (uartStatePtr->txFifoEntryCount > 1) + { + UART_HAL_SetTxFifoWatermark(base, (uartStatePtr->txFifoEntryCount >> 1U)); + } + else + { + UART_HAL_SetTxFifoWatermark(base, 0); + } + + /* Configure the RX FIFO watermark to be 1. + * Note about RX FIFO support: There is only one RX data full interrupt that + * is associated with the RX FIFO Watermark. The watermark cannot be + * dynamically changed. This means if the rxSize is less than the programmed + * watermark the interrupt will never occur. If we try to change the + * watermark, this will involve shutting down the receiver first - which is + * not a desirable operation when the UART is actively receiving data. + * Hence, the best solution is to set the RX FIFO watermark to 1. */ + UART_HAL_SetRxFifoWatermark(base, 1); + + /* Enable and flush the FIFO prior to enabling the TX/RX */ + UART_HAL_SetTxFifoCmd(base, true); + UART_HAL_SetRxFifoCmd(base, true); + UART_HAL_FlushTxFifo(base); + UART_HAL_FlushRxFifo(base); +#else + /* For modules that do not support a FIFO, they have a data buffer that + * essentially acts likes a one-entry FIFO, thus to make the code cleaner, + * we'll equate txFifoEntryCount to 1. Also note that TDRE flag will set + * only when the tx buffer is empty. */ + uartStatePtr->txFifoEntryCount = 1; +#endif + + /* Enable UART interrupt on NVIC level. */ + INT_SYS_EnableIRQ(g_uartRxTxIrqId[instance]); + + /* Finally, enable the UART transmitter and receiver*/ + UART_HAL_EnableTransmitter(base); + UART_HAL_EnableReceiver(base); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_Deinit + * Description : This function shuts down the UART by disabling interrupts and + * the transmitter/receiver. + * This function disables the UART interrupts, disables the transmitter and + * receiver, and flushes the FIFOs (for modules that support FIFOs). + * + *END**************************************************************************/ +uart_status_t UART_DRV_Deinit(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + assert(g_uartBase[instance]); + + /* Exit if current instance is already de-initialized or is gated.*/ + if ((!g_uartStatePtr[instance]) || (!CLOCK_SYS_GetUartGateCmd(instance))) + { + return kStatus_UART_Fail; + } + + UART_Type * base = g_uartBase[instance]; + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + + /* In case there is still data in the TX FIFO or shift register that is + * being transmitted wait till transmit is complete. */ +#if FSL_FEATURE_UART_HAS_FIFO + /* Wait until there all of the data has been drained from the TX FIFO */ + while(UART_HAL_GetTxDatawordCountInFifo(base) != 0) { } +#endif + /* Wait until the data is completely shifted out of shift register */ + while(!(UART_BRD_S1_TC(base))) { } + + /* Disable the interrupt */ + INT_SYS_DisableIRQ(g_uartRxTxIrqId[instance]); + + /* Disable TX and RX */ + UART_HAL_DisableTransmitter(base); + UART_HAL_DisableReceiver(base); + + /* Destroy TX and RX sema. */ + OSA_SemaDestroy(&uartState->txIrqSync); + OSA_SemaDestroy(&uartState->rxIrqSync); + +#if FSL_FEATURE_UART_HAS_FIFO + /* Disable the FIFOs; should be done after disabling the TX/RX */ + UART_HAL_SetTxFifoCmd(base, false); + UART_HAL_SetRxFifoCmd(base, false); + UART_HAL_FlushTxFifo(base); + UART_HAL_FlushRxFifo(base); +#endif + + /* Cleared state pointer. */ + g_uartStatePtr[instance] = NULL; + + /* Gate UART module clock */ + CLOCK_SYS_DisableUartClock(instance); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_InstallRxCallback + * Description : Install receive data callback function, pass in NULL pointer + * as callback will unistall. + * + *END**************************************************************************/ +uart_rx_callback_t UART_DRV_InstallRxCallback(uint32_t instance, + uart_rx_callback_t function, + uint8_t * rxBuff, + void * callbackParam, + bool alwaysEnableRxIrq) +{ + assert(instance < UART_INSTANCE_COUNT); + UART_Type * base = g_uartBase[instance]; + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + + uart_rx_callback_t currentCallback = uartState->rxCallback; + uartState->rxCallback = function; + uartState->rxCallbackParam = callbackParam; + uartState->rxBuff = rxBuff; + + /* Enable/Disable the receive data full interrupt */ + uartState->isRxBusy = true; + UART_BWR_C2_RIE(base, alwaysEnableRxIrq); + + return currentCallback; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_InstallTxCallback + * Description : Install transmit data callback function, pass in NULL pointer + * as callback will uninstall. + * + *END**************************************************************************/ +uart_tx_callback_t UART_DRV_InstallTxCallback(uint32_t instance, + uart_tx_callback_t function, + uint8_t * txBuff, + void * callbackParam) +{ + assert(instance < UART_INSTANCE_COUNT); + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + + uart_tx_callback_t currentCallback = uartState->txCallback; + uartState->txCallback = function; + uartState->txCallbackParam = callbackParam; + uartState->txBuff = txBuff; + + return currentCallback; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_SendDataBlocking + * Description : This function sends (transmits) data out through the UART + * module using a blocking method. + * A blocking (also known as synchronous) function means that the function does + * not return until the transmit is complete. This blocking function is used to + * send data through the UART port. + * + *END**************************************************************************/ +uart_status_t UART_DRV_SendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + assert(txBuff); + assert(instance < UART_INSTANCE_COUNT); + + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + UART_Type * base = g_uartBase[instance]; + uart_status_t retVal = kStatus_UART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking.*/ + uartState->isTxBlocking = true; + + /* Start the transmission process */ + retVal = UART_DRV_StartSendData(instance, txBuff, txSize); + + if (retVal == kStatus_UART_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&uartState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable the transmitter data register empty interrupt */ + UART_BWR_C2_TIE(base, 0U); + + /* Update the information of the module driver state */ + uartState->isTxBusy = false; + + retVal = kStatus_UART_Timeout; + } + +#if FSL_FEATURE_UART_HAS_FIFO + /* Wait till the TX FIFO is empty before returning. */ + while(UART_HAL_GetTxDatawordCountInFifo(base) != 0) { } +#endif + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_SendData + * Description : This function sends (transmits) data through the UART module + * using a non-blocking method. + * A non-blocking (also known as asynchronous) function means that the function + * returns immediately after initiating the transmit function. The application + * has to get the transmit status to see when the transmit is complete. In + * other words, after calling non-blocking (asynchronous) send function, the + * application must get the transmit status to check if transmit is completed + * or not. The asynchronous method of transmitting and receiving allows the UART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +uart_status_t UART_DRV_SendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(txBuff); + assert(instance < UART_INSTANCE_COUNT); + + uart_status_t retVal = kStatus_UART_Success; + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + + /* Indicates current transaction is non-blocking */ + uartState->isTxBlocking = false; + + /* Start the transmission process */ + retVal = UART_DRV_StartSendData(instance, txBuff, txSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_GetTransmitStatus + * Description : This function returns whether the previous UART transmit has + * finished. + * When performing an async transmit, the user can call this function to + * ascertain the state of the current transmission: in progress (or busy) or + * complete (success). In addition, if the transmission is still in progress, + * the user can obtain the number of words that have been currently transferred. + * + *END**************************************************************************/ +uart_status_t UART_DRV_GetTransmitStatus(uint32_t instance, uint32_t * bytesRemaining) +{ + assert(instance < UART_INSTANCE_COUNT); + + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + uart_status_t retVal = kStatus_UART_Success; + uint32_t txSize = uartState->txSize; + + /* Fill in the bytes transferred. This may return that all bytes were + * transmitted, however, for IPs with FIFO support, there still may be data + * in the TX FIFO still in the process of being transmitted. */ + if (bytesRemaining) + { + *bytesRemaining = txSize; + } + + if (txSize) + { + retVal = kStatus_UART_TxBusy; + } + +#if FSL_FEATURE_UART_HAS_FIFO + UART_Type * base = g_uartBase[instance]; + + if (UART_HAL_GetTxDatawordCountInFifo(base)) + { + retVal = kStatus_UART_TxBusy; + } +#endif + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_AbortSendingData + * Description : This function ends a non-blocking UART transmission early. + * During a non-blocking UART transmission, the user has the option to terminate + * the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +uart_status_t UART_DRV_AbortSendingData(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!uartState->isTxBusy) + { + return kStatus_UART_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + UART_DRV_CompleteSendData(instance); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_ReceiveDataBlocking + * Description : This function gets (receives) data from the UART module using + * a blocking method. A blocking (also known as synchronous) function means that + * the function does not return until the receive is complete. This blocking + * function is used to send data through the UART port. + * + *END**************************************************************************/ +uart_status_t UART_DRV_ReceiveDataBlocking(uint32_t instance, uint8_t * rxBuff, + uint32_t rxSize, uint32_t timeout) +{ + assert(rxBuff); + assert(instance < UART_INSTANCE_COUNT); + + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + UART_Type * base = g_uartBase[instance]; + uart_status_t retVal = kStatus_UART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking.*/ + uartState->isRxBlocking = true; + + retVal = UART_DRV_StartReceiveData(instance, rxBuff, rxSize); + + if (retVal == kStatus_UART_Success) + { + /* Wait until all the data is received or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&uartState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable receive data full and rx overrun interrupt */ + UART_BWR_C2_RIE(base, 0); + UART_HAL_SetIntMode(base, kUartIntRxOverrun, false); + + /* Update the information of the module driver state */ + uartState->isRxBusy = false; + + retVal = kStatus_UART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_ReceiveData + * Description : This function gets (receives) data from the UART module using + * a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. In other + * words, after calling non-blocking (asynchronous) get function, the + * application must get the receive status to check if receive is completed or + * not. The asynchronous method of transmitting and receiving allows the UART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +uart_status_t UART_DRV_ReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(rxBuff); + assert(instance < UART_INSTANCE_COUNT); + + uart_status_t retVal = kStatus_UART_Success; + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + + /* Indicates current transaction is non-blocking.*/ + uartState->isRxBlocking = false; + + retVal = UART_DRV_StartReceiveData(instance, rxBuff, rxSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_GetReceiveStatus + * Description : This function returns whether the previous UART receive is + * completed. + * When performing a non-blocking receive, the user can call this function to + * ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, the + * user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +uart_status_t UART_DRV_GetReceiveStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < UART_INSTANCE_COUNT); + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + uart_status_t retVal = kStatus_UART_Success; + uint32_t rxSize = uartState->rxSize; + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = rxSize; + } + + if (rxSize) + { + retVal = kStatus_UART_RxBusy; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_AbortReceivingData + * Description : This function shuts down the UART by disabling interrupts and + * the transmitter/receiver. + * This function disables the UART interrupts, disables the transmitter and + * receiver, and flushes the FIFOs (for modules that support FIFOs). + * + *END**************************************************************************/ +uart_status_t UART_DRV_AbortReceivingData(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!uartState->isRxBusy) + { + return kStatus_UART_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + UART_DRV_CompleteReceiveData(instance); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_IRQHandler + * Description : Interrupt handler for UART. + * This handler uses the buffers stored in the uart_state_t structs to transfer + * data. This is not a public API as it is called whenever an interrupt occurs. + * + *END**************************************************************************/ +void UART_DRV_IRQHandler(uint32_t instance) +{ + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + UART_Type * base = g_uartBase[instance]; + + /* Exit the ISR if no transfer is happening for this instance. */ + if ((!uartState->isTxBusy) && (!uartState->isRxBusy)) + { + return; + } + + /* Handle receive data register full interrupt, if rx data register full + * interrupt is enabled AND there is data available. */ + if((UART_BRD_C2_RIE(base)) && (UART_BRD_S1_RDRF(base))) + { +#if FSL_FEATURE_UART_HAS_FIFO + /* Read out all data from RX FIFO */ + while(UART_HAL_GetRxDatawordCountInFifo(base)) + { +#endif + /* Get data and put into receive buffer */ + UART_HAL_Getchar(base, uartState->rxBuff); + + /* Invoke callback if there is one */ + if (uartState->rxCallback != NULL) + { + uartState->rxCallback(instance, uartState); + } + else + { + ++uartState->rxBuff; + --uartState->rxSize; + + /* Check and see if this was the last byte */ + if (uartState->rxSize == 0U) + { + UART_DRV_CompleteReceiveData(instance); + #if FSL_FEATURE_UART_HAS_FIFO + break; + #endif + } + } +#if FSL_FEATURE_UART_HAS_FIFO + } +#endif + } + + /* Handle transmit data register empty interrupt, if tx data register empty + * interrupt is enabled AND tx data register is currently empty. */ + if((UART_BRD_C2_TIE(base)) && (UART_BRD_S1_TDRE(base))) + { + /* Check to see if there are any more bytes to send */ + if (uartState->txSize) + { + uint8_t emptyEntryCountInFifo; +#if FSL_FEATURE_UART_HAS_FIFO + emptyEntryCountInFifo = uartState->txFifoEntryCount - + UART_HAL_GetTxDatawordCountInFifo(base); +#else + emptyEntryCountInFifo = uartState->txFifoEntryCount; +#endif + while(emptyEntryCountInFifo--) + { + /* Transmit data and update tx size/buff */ + UART_HAL_Putchar(base, *(uartState->txBuff)); + + /* Invoke callback if there is one */ + if (uartState->txCallback != NULL) + { + /* The callback MUST set the txSize to 0 if the + * transmit is ended.*/ + uartState->txCallback(instance, uartState); + } + else + { + ++uartState->txBuff; + --uartState->txSize; + } + + /* Check and see if this was the last byte */ + if (uartState->txSize == 0U) + { + UART_DRV_CompleteSendData(instance); + break; + } + } + } + } + + /* Handle receive overrun interrupt */ + if (UART_HAL_GetStatusFlag(base, kUartRxOverrun)) + { + /* Clear the flag, OR the rxDataRegFull will not be set any more */ + UART_HAL_ClearStatusFlag(base, kUartRxOverrun); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_CompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void UART_DRV_CompleteSendData(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + + UART_Type * base = g_uartBase[instance]; + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + + /* Disable the transmitter data register empty interrupt */ + UART_BWR_C2_TIE(base, 0U); + + /* Signal the synchronous completion object. */ + if (uartState->isTxBlocking) + { + OSA_SemaPost(&uartState->txIrqSync); + } + + /* Update the information of the module driver state */ + uartState->isTxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_StartSendData + * Description : Initiate (start) a transmit by beginning the process of + * sending data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static uart_status_t UART_DRV_StartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(instance < UART_INSTANCE_COUNT); + + UART_Type * base = g_uartBase[instance]; + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + + /* Check that we're not busy already transmitting data from a previous + * function call. */ + if (uartState->isTxBusy) + { + return kStatus_UART_TxBusy; + } + + if (txSize == 0U) + { + return kStatus_UART_NoDataToDeal; + } + + /* Initialize the module driver state structure. */ + uartState->txBuff = txBuff; + uartState->txSize = txSize; + uartState->isTxBusy = true; + + /* Enable the transmitter data register empty interrupt. The TDRE flag will + * set whenever the TX buffer is emptied into the TX shift register (for + * non-FIFO IPs) or when the data in the TX FIFO is at or below the + * programmed watermark (for FIFO-supported IPs). */ + UART_BWR_C2_TIE(base, 1U); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_CompleteReceiveData + * Description : Finish up a receive by completing the process of receiving + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void UART_DRV_CompleteReceiveData(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + UART_Type * base = g_uartBase[instance]; + + /* Disable receive data full and rx overrun interrupt */ + UART_BWR_C2_RIE(base, 0U); + UART_HAL_SetIntMode(base, kUartIntRxOverrun, false); + + /* Signal the synchronous completion object. */ + if (uartState->isRxBlocking) + { + OSA_SemaPost(&uartState->rxIrqSync); + } + + /* Update the information of the module driver state */ + uartState->isRxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_StartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static uart_status_t UART_DRV_StartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(instance < UART_INSTANCE_COUNT); + + uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance]; + UART_Type * base = g_uartBase[instance]; + + /* Check that we're not busy receiving data from a previous function call. */ + if ((uartState->isRxBusy) && (!uartState->rxCallback)) + { + return kStatus_UART_RxBusy; + } + + if (rxSize == 0U) + { + return kStatus_UART_NoDataToDeal; + } + + /* Initialize the module driver state struct to indicate transfer in progress + * and with the buffer and byte count data */ + uartState->rxBuff = rxBuff; + uartState->rxSize = rxSize; + uartState->isRxBusy = true; + + /* Enable the receive data overrun interrupt */ + UART_HAL_SetIntMode(base, kUartIntRxOverrun, true); + + /* Enable the receive data full interrupt */ + UART_BWR_C2_RIE(base, 1U); + + return kStatus_UART_Success; +} + +#endif /* FSL_FEATURE_SOC_UART_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_edma_driver.c b/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_edma_driver.c new file mode 100755 index 0000000..7d99aac --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_edma_driver.c @@ -0,0 +1,757 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_uart_edma_driver.h" +#include "fsl_clock_manager.h" +#include "fsl_interrupt_manager.h" +#include "fsl_edma_request.h" +#if FSL_FEATURE_SOC_EDMA_COUNT && FSL_FEATURE_SOC_UART_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Pointer to uart runtime state structure */ +extern void * g_uartStatePtr[UART_INSTANCE_COUNT]; + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static void UART_DRV_EdmaCompleteSendData(uint32_t instance); +static void UART_DRV_EdmaTxCallback(void *param, edma_chn_status_t status); +static uart_status_t UART_DRV_EdmaStartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize); +static void UART_DRV_EdmaCompleteReceiveData(uint32_t instance); +static void UART_DRV_EdmaRxCallback(void *param, edma_chn_status_t status); +static uart_status_t UART_DRV_EdmaStartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize); +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaInit + * Description : This function initializes a UART instance for operation. + * This function will initialize the run-time state structure to keep track of + * the on-going transfers, ungate the clock to the UART module, initialize the + * module to user defined settings and default settings, configure UART DMA + * and enable the UART module transmitter and receiver. + * The following is an example of how to set up the uart_edma_state_t and the + * uart_user_config_t parameters and how to call the UART_DRV_EdmaInit function + * by passing in these parameters: + * uart_user_config_t uartConfig; + * uartConfig.baudRate = 9600; + * uartConfig.bitCountPerChar = kUart8BitsPerChar; + * uartConfig.parityMode = kUartParityDisabled; + * uartConfig.stopBitCount = kUartOneStopBit; + * uart_edma_state_t uartEdmaState; + * UART_DRV_EdmaInit(instance, &uartEdmaState, &uartConfig); + * + *END**************************************************************************/ +uart_status_t UART_DRV_EdmaInit(uint32_t instance, + uart_edma_state_t * uartEdmaStatePtr, + const uart_edma_user_config_t * uartUserConfig) +{ + assert(uartEdmaStatePtr && uartUserConfig); + assert(g_uartBase[instance]); + assert(instance < UART_INSTANCE_COUNT); + /* This driver only support UART instances with separate DMA channels for + * both Tx and Rx.*/ + assert(FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(instance) == 1); + + UART_Type * base = g_uartBase[instance]; + uint32_t uartSourceClock = 0; + dma_request_source_t uartTxEdmaRequest = kDmaRequestMux0Disable; + dma_request_source_t uartRxEdmaRequest = kDmaRequestMux0Disable; + DMA_Type * edmaBaseAddr; + uint32_t edmaChannel; + + /* Exit if current instance is already initialized. */ + if (g_uartStatePtr[instance]) + { + return kStatus_UART_Initialized; + } + + /* Clear the state structure for this instance. */ + memset(uartEdmaStatePtr, 0, sizeof(uart_edma_state_t)); + + /* Save runtime structure pointer.*/ + g_uartStatePtr[instance] = uartEdmaStatePtr; + + /* Un-gate UART module clock */ + CLOCK_SYS_EnableUartClock(instance); + + /* Initialize UART to a known state. */ + UART_HAL_Init(base); + + /* Create Semaphore for txIrq and rxIrq. */ + OSA_SemaCreate(&uartEdmaStatePtr->txIrqSync, 0); + OSA_SemaCreate(&uartEdmaStatePtr->rxIrqSync, 0); + + /* UART clock source is either system or bus clock depending on instance */ + uartSourceClock = CLOCK_SYS_GetUartFreq(instance); + + /* Initialize UART baud rate, bit count, parity and stop bit. */ + UART_HAL_SetBaudRate(base, uartSourceClock, uartUserConfig->baudRate); + UART_HAL_SetBitCountPerChar(base, uartUserConfig->bitCountPerChar); + UART_HAL_SetParityMode(base, uartUserConfig->parityMode); +#if FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT + UART_HAL_SetStopBitCount(base, uartUserConfig->stopBitCount); +#endif + + switch (instance) + { +#if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(0) == 1) + case 0: + uartRxEdmaRequest = kDmaRequestMux0UART0Rx; + uartTxEdmaRequest = kDmaRequestMux0UART0Tx; + break; +#endif +#if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(1) == 1) + case 1: + uartRxEdmaRequest = kDmaRequestMux0UART1Rx; + uartTxEdmaRequest = kDmaRequestMux0UART1Tx; + break; +#endif +#if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(2) == 1) + case 2: + uartRxEdmaRequest = kDmaRequestMux0UART2Rx; + uartTxEdmaRequest = kDmaRequestMux0UART2Tx; + break; +#endif +#if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(3) == 1) + case 3: + uartRxEdmaRequest = kDmaRequestMux0UART3Rx; + uartTxEdmaRequest = kDmaRequestMux0UART3Tx; + break; +#endif +#if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(4) == 1) + case 4: + uartRxEdmaRequest = kDmaRequestMux0UART4Rx; + uartTxEdmaRequest = kDmaRequestMux0UART4Tx; + break; +#endif +#if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(5) == 1) + case 5: + uartRxEdmaRequest = kDmaRequestMux0UART5Rx; + uartTxEdmaRequest = kDmaRequestMux0UART5Tx; + break; +#endif + default : + break; + } + + /*--------------- Setup RX ------------------*/ + /* Request DMA channels for RX FIFO. */ + EDMA_DRV_RequestChannel(kEDMAAnyChannel, uartRxEdmaRequest, + &uartEdmaStatePtr->edmaUartRx); + EDMA_DRV_InstallCallback(&uartEdmaStatePtr->edmaUartRx, + UART_DRV_EdmaRxCallback, (void *)instance); + + edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(uartEdmaStatePtr->edmaUartRx.channel); + edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(uartEdmaStatePtr->edmaUartRx.channel); + + /* Setup destination */ + EDMA_HAL_HTCDSetDestOffset(edmaBaseAddr, edmaChannel, 1); + EDMA_HAL_HTCDSetDestLastAdjust(edmaBaseAddr, edmaChannel, 0); + + /* Setup source */ + EDMA_HAL_HTCDSetSrcAddr(edmaBaseAddr, edmaChannel, UART_HAL_GetDataRegAddr(base)); + EDMA_HAL_HTCDSetSrcOffset(edmaBaseAddr, edmaChannel, 0); + EDMA_HAL_HTCDSetSrcLastAdjust(edmaBaseAddr, edmaChannel, 0); + + /* Setup transfer properties */ + EDMA_HAL_HTCDSetNbytes(edmaBaseAddr, edmaChannel, 1); + EDMA_HAL_HTCDSetChannelMinorLink(edmaBaseAddr, edmaChannel, 0, false); + EDMA_HAL_HTCDSetAttribute(edmaBaseAddr, edmaChannel, kEDMAModuloDisable, + kEDMAModuloDisable, kEDMATransferSize_1Bytes, kEDMATransferSize_1Bytes); + EDMA_HAL_HTCDSetScatterGatherCmd(edmaBaseAddr, edmaChannel, false); + EDMA_HAL_HTCDSetDisableDmaRequestAfterTCDDoneCmd(edmaBaseAddr, edmaChannel, true); + + /*--------------- Setup TX ------------------*/ + /* Request DMA channels for TX FIFO. */ + EDMA_DRV_RequestChannel(kEDMAAnyChannel, uartTxEdmaRequest, + &uartEdmaStatePtr->edmaUartTx); + EDMA_DRV_InstallCallback(&uartEdmaStatePtr->edmaUartTx, + UART_DRV_EdmaTxCallback, (void *)instance); + + edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(uartEdmaStatePtr->edmaUartTx.channel); + edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(uartEdmaStatePtr->edmaUartTx.channel); + + /* Setup destination */ + EDMA_HAL_HTCDSetDestAddr(edmaBaseAddr, edmaChannel, UART_HAL_GetDataRegAddr(base)); + EDMA_HAL_HTCDSetDestOffset(edmaBaseAddr, edmaChannel, 0); + EDMA_HAL_HTCDSetDestLastAdjust(edmaBaseAddr, edmaChannel, 0); + + /* Setup source */ + EDMA_HAL_HTCDSetSrcOffset(edmaBaseAddr, edmaChannel, 1); + EDMA_HAL_HTCDSetSrcLastAdjust(edmaBaseAddr, edmaChannel, 0); + + /* Setup transfer properties */ + EDMA_HAL_HTCDSetNbytes(edmaBaseAddr, edmaChannel, 1); + EDMA_HAL_HTCDSetChannelMinorLink(edmaBaseAddr, edmaChannel, 0, false); + EDMA_HAL_HTCDSetAttribute(edmaBaseAddr, edmaChannel, kEDMAModuloDisable, + kEDMAModuloDisable, kEDMATransferSize_1Bytes, kEDMATransferSize_1Bytes); + EDMA_HAL_HTCDSetScatterGatherCmd(edmaBaseAddr, edmaChannel, false); + EDMA_HAL_HTCDSetDisableDmaRequestAfterTCDDoneCmd(edmaBaseAddr, edmaChannel, true); + + /* Finally, enable the UART transmitter and receiver. + * Enable DMA trigger when transmit data register empty, + * and receive data register full. */ + UART_HAL_SetTxDmaCmd(base, true); + UART_HAL_SetRxDmaCmd(base, true); + UART_HAL_EnableTransmitter(base); + UART_HAL_EnableReceiver(base); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaDeinit + * Description : This function shuts down the UART by disabling UART DMA and + * the transmitter/receiver. + * + *END**************************************************************************/ +uart_status_t UART_DRV_EdmaDeinit(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + assert(g_uartBase[instance]); + + /* Exit if current instance is already de-initialized or is gated.*/ + if ((!g_uartStatePtr[instance]) || (!CLOCK_SYS_GetUartGateCmd(instance))) + { + return kStatus_UART_Fail; + } + + UART_Type * base = g_uartBase[instance]; + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + + /* Wait until the data is completely shifted out of shift register */ + while(!(UART_BRD_S1_TC(base))) { } + + UART_HAL_SetTxDmaCmd(base, false); + UART_HAL_SetRxDmaCmd(base, false); + + /* Release DMA channel. */ + EDMA_DRV_ReleaseChannel(&uartEdmaState->edmaUartRx); + EDMA_DRV_ReleaseChannel(&uartEdmaState->edmaUartTx); + + /* Disable TX and RX */ + UART_HAL_DisableTransmitter(base); + UART_HAL_DisableReceiver(base); + + /* Destroy TX and RX sema. */ + OSA_SemaDestroy(&uartEdmaState->txIrqSync); + OSA_SemaDestroy(&uartEdmaState->rxIrqSync); + + /* Cleared state pointer. */ + g_uartStatePtr[instance] = NULL; + + /* Gate UART module clock */ + CLOCK_SYS_DisableUartClock(instance); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaSendDataBlocking + * Description : Sends (transmits) data out through the UART-DMA module + * using a blocking method. + * + *END**************************************************************************/ +uart_status_t UART_DRV_EdmaSendDataBlocking(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize, + uint32_t timeout) +{ + assert(txBuff); + assert(instance < UART_INSTANCE_COUNT); + + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + DMA_Type * edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(uartEdmaState->edmaUartTx.channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(uartEdmaState->edmaUartTx.channel); + uart_status_t retVal = kStatus_UART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + uartEdmaState->isTxBlocking = true; + + /* Start the transmission process */ + retVal = UART_DRV_EdmaStartSendData(instance, txBuff, txSize); + + if (retVal == kStatus_UART_Success) + { + /* Wait until the transmit is complete. */ + do + { + syncStatus = OSA_SemaWait(&uartEdmaState->txIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(edmaBaseAddr, edmaChannel, false); + + /* Stop DMA channel. */ + EDMA_HAL_SetDmaRequestCmd(edmaBaseAddr, (edma_channel_indicator_t)edmaChannel, false); + + /* Update the information of the module driver state */ + uartEdmaState->isTxBusy = false; + + retVal = kStatus_UART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaSendData + * Description : This function sends (transmits) data through the UART module + * using a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the transmit function. The application + * has to get the transmit status to see when the transmit is complete. In + * other words, after calling non-blocking (asynchronous) send function, the + * application must get the transmit status to check if transmit is completed + * or not. The asynchronous method of transmitting and receiving allows the UART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +uart_status_t UART_DRV_EdmaSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(txBuff); + assert(instance < UART_INSTANCE_COUNT); + + uart_status_t retVal = kStatus_UART_Success; + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + + /* Indicates current transaction is non-blocking. */ + uartEdmaState->isTxBlocking = false; + + /* Start the transmission process*/ + retVal = UART_DRV_EdmaStartSendData(instance, txBuff, txSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaGetTransmitStatus + * Description : This function returns whether the previous UART transmit + * has finished. When performing an async transmit, the user can call this + * function to ascertain the state of the current transmission: in progress + * (or busy) or complete (success). In addition, if the transmission is still + * in progress, the user can obtain the number of words that have been + * currently transferred. + * + *END**************************************************************************/ +uart_status_t UART_DRV_EdmaGetTransmitStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < UART_INSTANCE_COUNT); + + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + DMA_Type * edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(uartEdmaState->edmaUartTx.channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(uartEdmaState->edmaUartTx.channel); + uart_status_t retVal = kStatus_UART_Success; + uint32_t txSize = 0; + + /* EDMA will reload the major count after finish transfer, need to set + * the count to 0 manually. */ + if (uartEdmaState->isTxBusy) + { + txSize = EDMA_HAL_HTCDGetUnfinishedBytes(edmaBaseAddr, edmaChannel); + retVal = kStatus_UART_TxBusy; + } + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = txSize; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaAbortSendingData + * Description : This function terminates an asynchronous UART transmission + * early. During an async UART transmission, the user has the option to + * terminate the transmission early if the transmission is still in progress. + * + *END**************************************************************************/ +uart_status_t UART_DRV_EdmaAbortSendingData(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!uartEdmaState->isTxBusy) + { + return kStatus_UART_NoTransmitInProgress; + } + + /* Stop the running transfer. */ + UART_DRV_EdmaCompleteSendData(instance); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaReceiveDataBlocking + * Description : This function gets (receives) data from the UART module using + * a blocking method. A blocking (also known as synchronous) function means that + * the function does not return until the receive is complete. This blocking + * function is used to send data through the UART port. + * + *END**************************************************************************/ +uart_status_t UART_DRV_EdmaReceiveDataBlocking(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize, + uint32_t timeout) +{ + assert(rxBuff); + assert(instance < UART_INSTANCE_COUNT); + + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + DMA_Type * edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(uartEdmaState->edmaUartRx.channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(uartEdmaState->edmaUartRx.channel); + uart_status_t retVal = kStatus_UART_Success; + osa_status_t syncStatus; + + /* Indicates current transaction is blocking. */ + uartEdmaState->isRxBlocking = true; + + retVal = UART_DRV_EdmaStartReceiveData(instance, rxBuff, rxSize); + + if (retVal == kStatus_UART_Success) + { + /* Wait until all the data is received or for timeout.*/ + do + { + syncStatus = OSA_SemaWait(&uartEdmaState->rxIrqSync, timeout); + }while(syncStatus == kStatus_OSA_Idle); + + if (syncStatus != kStatus_OSA_Success) + { + /* Disable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(edmaBaseAddr, edmaChannel, false); + + /* Stop DMA channel. */ + EDMA_HAL_SetDmaRequestCmd(edmaBaseAddr, (edma_channel_indicator_t)edmaChannel, false); + + /* Update the information of the module driver state */ + uartEdmaState->isRxBusy = false; + + retVal = kStatus_UART_Timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaReceiveData + * Description : This function gets (receives) data from the UART module using + * a non-blocking method. + * A non-blocking (also known as synchronous) function means that the function + * returns immediately after initiating the receive function. The application + * has to get the receive status to see when the receive is complete. In other + * words, after calling non-blocking (asynchronous) get function, the + * application must get the receive status to check if receive is completed or + * not. The asynchronous method of transmitting and receiving allows the UART + * to perform a full duplex operation (simultaneously transmit and receive). + * + *END**************************************************************************/ +uart_status_t UART_DRV_EdmaReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(rxBuff); + assert(instance < UART_INSTANCE_COUNT); + + uart_status_t retVal = kStatus_UART_Success; + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + + /* Indicates current transaction is non-blocking. */ + uartEdmaState->isRxBlocking = false; + + retVal = UART_DRV_EdmaStartReceiveData(instance, rxBuff, rxSize); + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaGetReceiveStatus + * Description : This function returns whether the previous UART receive is + * complete. When performing an async receive, the user can call this function + * to ascertain the state of the current receive progress: in progress (or busy) + * or complete (success). In addition, if the receive is still in progress, + * the user can obtain the number of words that have been currently received. + * + *END**************************************************************************/ +uart_status_t UART_DRV_EdmaGetReceiveStatus(uint32_t instance, + uint32_t * bytesRemaining) +{ + assert(instance < UART_INSTANCE_COUNT); + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + DMA_Type * edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(uartEdmaState->edmaUartRx.channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(uartEdmaState->edmaUartRx.channel); + uart_status_t retVal = kStatus_UART_Success; + uint32_t rxSize = 0; + + /* EDMA will reload the major count after finish transfer, need to set + * the count to 0 manually. */ + if (uartEdmaState->isRxBusy) + { + rxSize = EDMA_HAL_HTCDGetUnfinishedBytes(edmaBaseAddr, edmaChannel); + retVal = kStatus_UART_RxBusy; + } + + /* Fill in the bytes transferred. */ + if (bytesRemaining) + { + *bytesRemaining = rxSize; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaAbortReceivingData + * Description : This function shuts down the UART by disabling interrupts and + * the transmitter/receiver. + * + *END**************************************************************************/ +uart_status_t UART_DRV_EdmaAbortReceivingData(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + + /* Check if a transfer is running. */ + if (!uartEdmaState->isRxBusy) + { + return kStatus_UART_NoReceiveInProgress; + } + + /* Stop the running transfer. */ + UART_DRV_EdmaCompleteReceiveData(instance); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaCompleteSendData + * Description : Finish up a transmit by completing the process of sending + * data and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void UART_DRV_EdmaCompleteSendData(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + DMA_Type * edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(uartEdmaState->edmaUartTx.channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(uartEdmaState->edmaUartTx.channel); + + /* Disable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(edmaBaseAddr, edmaChannel, false); + + /* Stop DMA channel. */ + EDMA_HAL_SetDmaRequestCmd(edmaBaseAddr, (edma_channel_indicator_t)edmaChannel, false); + + /* Signal the synchronous completion object. */ + if (uartEdmaState->isTxBlocking) + { + OSA_SemaPost(&uartEdmaState->txIrqSync); + } + + /* Update the information of the module driver state */ + uartEdmaState->isTxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaTxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void UART_DRV_EdmaTxCallback(void *param, edma_chn_status_t status) +{ + UART_DRV_EdmaCompleteSendData((uint32_t)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaStartSendData + * Description : This is not a public interface. + * + *END**************************************************************************/ +static uart_status_t UART_DRV_EdmaStartSendData(uint32_t instance, + const uint8_t * txBuff, + uint32_t txSize) +{ + assert(instance < UART_INSTANCE_COUNT); + + /* Get current runtime structure. */ + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + DMA_Type * edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(uartEdmaState->edmaUartTx.channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(uartEdmaState->edmaUartTx.channel); + + /* Check that we're not busy already transmitting data from a previous function call. */ + if (uartEdmaState->isTxBusy) + { + return kStatus_UART_TxBusy; + } + + /* Update UART DMA run-time structure. */ + uartEdmaState->isTxBusy = true; + + /* Update txBuff and txSize. */ + EDMA_HAL_HTCDSetSrcAddr(edmaBaseAddr, edmaChannel, (uint32_t)txBuff); + EDMA_HAL_HTCDSetMajorCount(edmaBaseAddr, edmaChannel, txSize); + + /* Enable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(edmaBaseAddr, edmaChannel, true); + + /* Start DMA channel */ + EDMA_HAL_SetDmaRequestCmd(edmaBaseAddr, (edma_channel_indicator_t)edmaChannel, true); + + return kStatus_UART_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaCompleteReceiveData + * Description : Finish up a receive by completing the process of receiving data + * and disabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static void UART_DRV_EdmaCompleteReceiveData(uint32_t instance) +{ + assert(instance < UART_INSTANCE_COUNT); + + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + DMA_Type * edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(uartEdmaState->edmaUartRx.channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(uartEdmaState->edmaUartRx.channel); + + /* Disable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(edmaBaseAddr, edmaChannel, false); + + /* Stop DMA channel. */ + EDMA_HAL_SetDmaRequestCmd(edmaBaseAddr, (edma_channel_indicator_t)edmaChannel, false); + + /* Signal the synchronous completion object. */ + if (uartEdmaState->isRxBlocking) + { + OSA_SemaPost(&uartEdmaState->rxIrqSync); + } + + /* Update the information of the module driver state */ + uartEdmaState->isRxBusy = false; +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaRxCallback + * Description : This is not a public interface. + * + *END**************************************************************************/ +static void UART_DRV_EdmaRxCallback(void *param, edma_chn_status_t status) +{ + UART_DRV_EdmaCompleteReceiveData((uint32_t)param); +} + +/*FUNCTION********************************************************************** + * + * Function Name : UART_DRV_EdmaStartReceiveData + * Description : Initiate (start) a receive by beginning the process of + * receiving data and enabling the interrupt. + * This is not a public API as it is called from other driver functions. + * + *END**************************************************************************/ +static uart_status_t UART_DRV_EdmaStartReceiveData(uint32_t instance, + uint8_t * rxBuff, + uint32_t rxSize) +{ + assert(instance < UART_INSTANCE_COUNT); + + /* Get current runtime structure. */ + uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance]; + DMA_Type * edmaBaseAddr = VIRTUAL_CHN_TO_EDMA_MODULE_REGBASE(uartEdmaState->edmaUartRx.channel); + uint32_t edmaChannel = VIRTUAL_CHN_TO_EDMA_CHN(uartEdmaState->edmaUartRx.channel); + + /* Check that we're not busy already receiving data from a previous function call. */ + if (uartEdmaState->isRxBusy) + { + return kStatus_UART_RxBusy; + } + + /* Update UART DMA run-time structure. */ + uartEdmaState->isRxBusy = true; + + /* Update rxBuff and rxSize */ + EDMA_HAL_HTCDSetDestAddr(edmaBaseAddr, edmaChannel, (uint32_t)rxBuff); + EDMA_HAL_HTCDSetMajorCount(edmaBaseAddr, edmaChannel, rxSize); + + /* Enable DMA major loop interrupt */ + EDMA_HAL_HTCDSetIntCmd(edmaBaseAddr, edmaChannel, true); + + /* Start DMA channel */ + EDMA_HAL_SetDmaRequestCmd(edmaBaseAddr, (edma_channel_indicator_t)edmaChannel, true); + + return kStatus_UART_Success; +} + +#endif /* FSL_FEATURE_SOC_DMA_COUNT && FSL_FEATURE_SOC_UART_COUNT */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_irq.c b/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_irq.c new file mode 100755 index 0000000..05d23e6 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_irq.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_uart_driver.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +extern void UART_DRV_IRQHandler(uint32_t instance); +/******************************************************************************* + * Code + ******************************************************************************/ + +#if defined (KL16Z4_SERIES) || defined (KL25Z4_SERIES) || defined (KL26Z4_SERIES) || \ + defined (KL46Z4_SERIES) || defined (KV10Z7_SERIES) || defined (KW01Z4_SERIES) +/* NOTE: If a sub-family has UART0 separated as another IP, it will be handled by + * LPSCI driver. + */ +#if !defined (UART0_INSTANCE_COUNT) && (UART_INSTANCE_COUNT > 0) +/* Implementation of UART0 handler named in startup code. */ +void UART0_IRQHandler(void) +{ + UART_DRV_IRQHandler(0); +} +#endif + +#if (UART_INSTANCE_COUNT > 1) +/* Implementation of UART1 handler named in startup code. */ +void UART1_IRQHandler(void) +{ + UART_DRV_IRQHandler(1); +} +#endif + +#if (UART_INSTANCE_COUNT > 2) +/* Implementation of UART2 handler named in startup code. */ +void UART2_IRQHandler(void) +{ + UART_DRV_IRQHandler(2); +} +#endif + +#elif defined (K64F12_SERIES) || defined (K24F12_SERIES) || defined (K63F12_SERIES) || \ + defined (K22F51212_SERIES) || defined (K22F25612_SERIES) || defined (K22F12810_SERIES) || \ + defined (KV31F51212_SERIES) || defined (KV31F25612_SERIES) || defined (KV31F12810_SERIES) || \ + defined (K70F12_SERIES) || defined(K60D10_SERIES) || defined(K24F25612_SERIES) || \ + defined (KV30F12810_SERIES) || defined (K02F12810_SERIES) || \ + defined (K65F18_SERIES) || defined (K66F18_SERIES) || defined (K26F18_SERIES) + +#if (UART_INSTANCE_COUNT > 0) +/* Implementation of UART0 handler named in startup code. */ +void UART0_RX_TX_IRQHandler(void) +{ + UART_DRV_IRQHandler(0); +} +#endif + +#if (UART_INSTANCE_COUNT > 1) +/* Implementation of UART1 handler named in startup code. */ +void UART1_RX_TX_IRQHandler(void) +{ + UART_DRV_IRQHandler(1); +} +#endif + +#if (UART_INSTANCE_COUNT > 2) +/* Implementation of UART2 handler named in startup code. */ +void UART2_RX_TX_IRQHandler(void) +{ + UART_DRV_IRQHandler(2); +} +#endif + +#if (UART_INSTANCE_COUNT > 3) +/* Implementation of UART3 handler named in startup code. */ +void UART3_RX_TX_IRQHandler(void) +{ + UART_DRV_IRQHandler(3); +} +#endif + +#if (UART_INSTANCE_COUNT > 4) +/* Implementation of UART4 handler named in startup code. */ +void UART4_RX_TX_IRQHandler(void) +{ + UART_DRV_IRQHandler(4); +} +#endif + +#if (UART_INSTANCE_COUNT > 5) +/* Implementation of UART5 handler named in startup code. */ +void UART5_RX_TX_IRQHandler(void) +{ + UART_DRV_IRQHandler(5); +} +#endif + +#elif defined (KL27Z644_SERIES) || defined (KL17Z644_SERIES) || defined (KL43Z4_SERIES) + +#if (UART_INSTANCE_COUNT > 0) +/* Implementation of UART1 handler named in startup code. */ +void UART2_FLEXIO_IRQHandler(void) +{ + UART_DRV_IRQHandler(2); +} +#endif + +#else + #error "No valid CPU defined!" +#endif +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_lpm_callback.c new file mode 100755 index 0000000..f52a363 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/uart/fsl_uart_lpm_callback.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" + +power_manager_error_code_t uart_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t uart_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} + diff --git a/KSDK_1.2.0/platform/drivers/src/vref/fsl_vref_common.c b/KSDK_1.2.0/platform/drivers/src/vref/fsl_vref_common.c new file mode 100755 index 0000000..f6ce8c0 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/vref/fsl_vref_common.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for VREF instances. */ +VREF_Type * const g_vrefBase[] = VREF_BASE_PTRS; + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/platform/drivers/src/vref/fsl_vref_driver.c b/KSDK_1.2.0/platform/drivers/src/vref/fsl_vref_driver.c new file mode 100755 index 0000000..a745305 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/vref/fsl_vref_driver.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include "fsl_vref_driver.h" +#include "fsl_vref_hal.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_VREF_COUNT + +/*FUNCTION********************************************************************* + * + * Function Name : VREF_DRV_Init + * Description : Initialize the comparator in VREF module. + * + *END*************************************************************************/ +vref_status_t VREF_DRV_Init(uint32_t instance, const vref_user_config_t *userConfigPtr) +{ + assert(instance < VREF_INSTANCE_COUNT); + VREF_Type * base = (VREF_Type *)g_vrefBase[instance]; + + if (!userConfigPtr) + { + return kStatus_VREF_InvalidArgument; + } + + /* Enable clock for VREF. */ + CLOCK_SYS_EnableVrefClock(instance); + + /* Reset all the register to default state. */ + VREF_HAL_Init(base); + /* Configure VREF to a known state*/ + VREF_HAL_Configure(base, userConfigPtr); + + VREF_HAL_WaitVoltageStable(base); + + return kStatus_VREF_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : VREF_DRV_Deinit + * Description : De-initialize the comparator in VREF module. It will gate + * the clock to VREF module. When VREF is no long used in application, calling + * this API will shut down the device to reduce power consumption. + * + *END*************************************************************************/ +vref_status_t VREF_DRV_Deinit(uint32_t instance) +{ + assert(instance < VREF_INSTANCE_COUNT); + VREF_Type * base = (VREF_Type *)g_vrefBase[instance]; + + VREF_HAL_Disable(base); + + /* Disable clock for ADC. */ + CLOCK_SYS_DisableVrefClock(instance); + + return kStatus_VREF_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : VREF_DRV_SetTrimValue + * Description : Set TRIM bits value + * + *END*************************************************************************/ +vref_status_t VREF_DRV_SetTrimValue(uint32_t instance, uint8_t trimValue) +{ + assert(instance < VREF_INSTANCE_COUNT); + VREF_Type * base = (VREF_Type *)g_vrefBase[instance]; + + VREF_HAL_SetTrimVal(base, trimValue); + + VREF_HAL_WaitVoltageStable(base); + + return kStatus_VREF_Success; +} + +#if FSL_FEATURE_VREF_HAS_LOW_REFERENCE +/*FUNCTION********************************************************************* + * + * Function Name : VREF_DRV_SetTrimValue + * Description : Set TRIM bits value + * + *END*************************************************************************/ +vref_status_t VREF_DRV_SetLowReferenceTrimVal(uint32_t instance, uint8_t trimValue) +{ + assert(instance < VREF_INSTANCE_COUNT); + VREF_Type * base = (VREF_Type *)g_vrefBase[instance]; + + VREF_HAL_SetLowReferenceTrimVal(base, trimValue); + + VREF_HAL_WaitVoltageStable(base); + + return kStatus_VREF_Success; +} +#endif +#endif + +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/vref/fsl_vref_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/vref/fsl_vref_lpm_callback.c new file mode 100755 index 0000000..4286ea8 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/vref/fsl_vref_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_VREF_COUNT + +power_manager_error_code_t vref_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t vref_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/wdog/fsl_wdog_common.c b/KSDK_1.2.0/platform/drivers/src/wdog/fsl_wdog_common.c new file mode 100755 index 0000000..5e18998 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/wdog/fsl_wdog_common.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Table of base addresses for WDOG instances. */ +WDOG_Type * const g_wdogBase[] = WDOG_BASE_PTRS; + +/*! @brief Table to save WDOG IRQ enum numbers defined in CMSIS header file. */ +const IRQn_Type g_wdogIrqId[] = WDOG_IRQS; + +/******************************************************************************* + * EOF + ******************************************************************************/ + + diff --git a/KSDK_1.2.0/platform/drivers/src/wdog/fsl_wdog_driver.c b/KSDK_1.2.0/platform/drivers/src/wdog/fsl_wdog_driver.c new file mode 100755 index 0000000..79c9dc8 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/wdog/fsl_wdog_driver.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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_wdog_driver.h" +#include "fsl_interrupt_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_WDOG_COUNT + +/******************************************************************************* + * Variables + *******************************************************************************/ + +static uint32_t wdogWctInstructionCount; + +/******************************************************************************* + * Code + *******************************************************************************/ + +/*FUNCTION**************************************************************** + * + * Function Name : WDOG_DRV_Unlock + * Description : Unlock watchdog register written + * This function is used to unlock the WDOG register written because WDOG register + * will lock automatically after 256 bus clock. Written while the register is + * locked has no affect. + * + *END*********************************************************************/ +static void WDOG_DRV_Unlock(void) +{ + WDOG_Type *base = g_wdogBase[0]; + INT_SYS_DisableIRQGlobal(); + WDOG_HAL_Unlock(base); + INT_SYS_EnableIRQGlobal(); +} + +/*FUNCTION**************************************************************** + * + * Function Name : WDOG_DRV_WaitWctClose + * Description : Wait until the WCT is closed + * This function is used wait until the WCT window is closed, WCT time is 256 bus cycles, here + * use nop to wait timeout, one nop running time is one core cycle. + * + *END*********************************************************************/ +static void WDOG_DRV_WaitWctClose(void) +{ + uint32_t count; + /* here using nop instruction, otherwise empty code will be optimized in release target */ + for ( count = 0 ; count < wdogWctInstructionCount; count++ ) + { + __NOP(); + } +} + + +/*FUNCTION**************************************************************** + * + * Function Name : WDOG_DRV_Init + * Description : Initialize watchdog + * This function is used to initialize the WDOG, after called, the WDOG + * will run immediately according to the configure. + * + *END*********************************************************************/ +wdog_status_t WDOG_DRV_Init(const wdog_config_t* userConfigPtr) +{ + uint32_t coreClockHz, busClockHz; + if(!userConfigPtr) + { + return kStatus_WDOG_NullArgument; + } + WDOG_Type *base = g_wdogBase[0]; + coreClockHz = CLOCK_SYS_GetCoreClockFreq(); + busClockHz = CLOCK_SYS_GetBusClockFreq(); + wdogWctInstructionCount = ((coreClockHz/busClockHz) << 8); /* WCT is 256 bus clock */ + WDOG_DRV_Unlock(); + WDOG_HAL_SetConfig(base, userConfigPtr); + WDOG_DRV_WaitWctClose(); + return kStatus_WDOG_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name : WDOG_DRV_Deinit + * Description : Shutdown watchdog + * This function is used to shutdown the WDOG. + * + *END*********************************************************************/ +wdog_status_t WDOG_DRV_Deinit(void) +{ + WDOG_Type *base = g_wdogBase[0]; + WDOG_DRV_Unlock(); + WDOG_HAL_Disable(base); + WDOG_DRV_WaitWctClose(); + return kStatus_WDOG_Success; +} + +/*FUNCTION**************************************************************** + * + * Function Name : WDOG_DRV_IsRunning + * Description : Get watchdog running status + * This function is used to get the WDOG running status. + * + *END*********************************************************************/ +bool WDOG_DRV_IsRunning(void) +{ + WDOG_Type *base = g_wdogBase[0]; + return WDOG_HAL_IsEnable(base); +} + +/*FUNCTION**************************************************************** + * + * Function Name : WDOG_DRV_Refresh + * Description : Refresh watchdog. + * This function is used to feed the WDOG, it will set the WDOG timer count to zero and + * should be called before watchdog timer is timeout, otherwise a RESET will assert. + * + *END*********************************************************************/ +void WDOG_DRV_Refresh(void) +{ + WDOG_Type *base = g_wdogBase[0]; + INT_SYS_DisableIRQGlobal(); + WDOG_HAL_Refresh(base); + INT_SYS_EnableIRQGlobal(); +} + +/*FUNCTION**************************************************************** + * + * Function Name : WDOG_DRV_ResetSystem + * Description : Reset chip by watchdog + * This function is used to reset chip using WDOG. + * + *END*********************************************************************/ +void WDOG_DRV_ResetSystem(void) +{ + WDOG_Type *base = g_wdogBase[0]; + WDOG_HAL_ResetSystem(base); +} +#endif + +/******************************************************************************* + * EOF + *******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/wdog/fsl_wdog_irq.c b/KSDK_1.2.0/platform/drivers/src/wdog/fsl_wdog_irq.c new file mode 100755 index 0000000..f6aa5fb --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/wdog/fsl_wdog_irq.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 -2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdint.h> +#include <stdbool.h> +#include "fsl_wdog_driver.h" +#if FSL_FEATURE_SOC_WDOG_COUNT + +/****************************************************************************** + * Code + *****************************************************************************/ +/* Watchdog_IRQHandler IRQ handler that would cover the same name's APIs in startup code */ +void WDOG_EWM_IRQHandler(void) +{ +} + +#endif + +/****************************************************************************** + * EOF + *****************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/wdog/fsl_wdog_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/wdog/fsl_wdog_lpm_callback.c new file mode 100755 index 0000000..aec3d08 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/wdog/fsl_wdog_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_WDOG_COUNT + +power_manager_error_code_t wdog_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t wdog_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + diff --git a/KSDK_1.2.0/platform/drivers/src/xbar/fsl_xbar_common.c b/KSDK_1.2.0/platform/drivers/src/xbar/fsl_xbar_common.c new file mode 100755 index 0000000..49b5c89 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/xbar/fsl_xbar_common.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ +#if defined(FSL_FEATURE_XBAR_HAS_SINGLE_MODULE) +#define XBARA_Type XBAR_Type +/* Table of base addresses for XBAR instances. */ +XBARA_Type * const g_xbaraBase[] = XBAR_BASE_PTRS; + +/* Table to save XBAR IRQ numbers defined in CMSIS files. */ +const IRQn_Type g_xbarIrqId[] = {XBAR_IRQn}; + +#else +/* Table of base addresses for XBAR instances. */ +XBARA_Type * const g_xbaraBase[] = XBARA_BASE_PTRS; +XBARB_Type * const g_xbarbBase[] = XBARB_BASE_PTRS; + +/* Table to save port IRQ enum numbers defined in CMSIS files. */ +const IRQn_Type g_xbarIrqId[] = {XBARA_IRQn}; +#endif /* FSL_FEATURE_XBAR_HAS_SINGLE_MODULE */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/xbar/fsl_xbar_driver.c b/KSDK_1.2.0/platform/drivers/src/xbar/fsl_xbar_driver.c new file mode 100755 index 0000000..8190581 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/xbar/fsl_xbar_driver.c @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <string.h> +#include "fsl_xbar_driver.h" +#include "fsl_interrupt_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_XBAR_COUNT + +/*! @brief Pointers to internal state structure for XBAR module. */ +static xbar_state_t * volatile g_xbarState; + +/*FUNCTION********************************************************************* + * + * Function Name : XBAR_DRV_Init + * Description : Initialize the XBAR module to the reset state. This API + * should be called before any operation of the XBAR module. + * + *END*************************************************************************/ +xbar_status_t XBAR_DRV_Init(xbar_state_t * xbarStatePtr) +{ + XBARA_Type * xbara_base = g_xbaraBase[0]; + + g_xbarState = xbarStatePtr; + + /* Clear the state structure. */ + memset(xbarStatePtr, 0, sizeof(xbar_state_t)); + + CLOCK_SYS_EnableXbarClock(XBARA_MODULE); + + XBARA_HAL_Init(xbara_base); + +#if !defined(FSL_FEATURE_XBAR_HAS_SINGLE_MODULE) + XBARB_Type * xbarb_base = g_xbarbBase[0]; + CLOCK_SYS_EnableXbarClock(XBARB_MODULE); + + XBARB_HAL_Init(xbarb_base); +#endif /* FSL_FEATURE_XBAR_HAS_SINGLE_MODULE */ + + /* Enable XBAR interrupt on NVIC level. */ + INT_SYS_EnableIRQ(g_xbarIrqId[XBARA_MODULE]); + + return kStatus_XBAR_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : XBAR_DRV_Control_Config + * Description : This function configures the XBAR module control register + * of selected XBAR_OUT output. Control fields provide the ability to perform + * edge detection on the corresponding XBAR_OUT output. Edge detection in turn + * can optionally be used to trigger an interrupt or DMA request. The intention + * is that, by detecting specified edges on signals propagating through the + * Crossbar, interrupts or DMA requests can be triggered to perform data + * transfers to or from other system components. DENn and IENn should not be set + * to 1 at the same time for the same output XBAR_OUT[n]. + * + *END*************************************************************************/ +xbar_status_t XBAR_DRV_ConfigOutControl(uint32_t outIndex, const xbar_control_config_t * controlConfigPtr) +{ + XBARA_Type * xbara_base = g_xbaraBase[0]; + + /* Set active edge for edge detection. */ + XBARA_HAL_SetOutActiveEdge(xbara_base, outIndex, controlConfigPtr->activeEdge); + + /* Set interrupt or DMA function. */ + if(controlConfigPtr->intDmaReq == kXbarReqIen) + { + XBARA_HAL_SetDMAOutCmd(xbara_base, outIndex, false); + XBARA_HAL_SetIntOutCmd(xbara_base, outIndex, true); + } + else if(controlConfigPtr->intDmaReq == kXbarReqDen) + { + XBARA_HAL_SetIntOutCmd(xbara_base, outIndex, false); + XBARA_HAL_SetDMAOutCmd(xbara_base, outIndex, true); + } + else + { + XBARA_HAL_SetIntOutCmd(xbara_base, outIndex, false); + XBARA_HAL_SetDMAOutCmd(xbara_base, outIndex, false); + } + + return kStatus_XBAR_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : XBAR_DRV_Deinit + * Description : De-initialize the XBAR module. It shuts down XBAR module + * clock to reduce the power consumption and resets XBAR's registers to a known + * state. + * + *END*************************************************************************/ +void XBAR_DRV_Deinit(void) +{ + XBARA_Type * xbara_base = g_xbaraBase[0]; + + /* Cleared state pointer. */ + g_xbarState = NULL; + + /* Disable XBAR interrupt on NVIC level. */ + INT_SYS_DisableIRQ(g_xbarIrqId[0]); + + /*Initialize module to reset state - clears all configurations*/ + XBARA_HAL_Init(xbara_base); + + /* Disable XBARB module clock */ + CLOCK_SYS_DisableXbarClock(XBARA_MODULE); + +#if !defined(FSL_FEATURE_XBAR_HAS_SINGLE_MODULE) + + XBARB_Type * xbarb_base = g_xbarbBase[0]; + + /*Initialize module to reset state - clears all configurations*/ + XBARB_HAL_Init(xbarb_base); + + /* Disable XBARB module clock */ + CLOCK_SYS_DisableXbarClock(XBARB_MODULE); +#endif /* FSL_FEATURE_XBAR_HAS_SINGLE_MODULE */ +} + +/*FUNCTION********************************************************************* + * + * Function Name : XBAR_DRV_ConfigSignalConnection + * Description : This function configures connections between XBAR_IN[*] + * and XBAR_OUT[*] signals. + * + *END*************************************************************************/ +xbar_status_t XBAR_DRV_ConfigSignalConnection(xbar_input_signal_t input, xbar_output_signal_t output) +{ + + if(((uint32_t)input & (1U<<8U)) && ((uint32_t)output & (1U<<8U))) + { + XBARA_Type * xbara_base = g_xbaraBase[0]; + uint32_t outputA = ((uint32_t)output & ~(1U<<8U)); + uint32_t inputA = ((uint32_t)input & ~(1U<<8U)); + XBARA_HAL_SetOutSel(xbara_base, outputA, inputA); + return kStatus_XBAR_Success; + } + +#if !defined(FSL_FEATURE_XBAR_HAS_SINGLE_MODULE) + else if(((uint32_t)input & (1U<<9U)) && ((uint32_t)output & (1U<<9U))) + { + XBARB_Type * xbarb_base = g_xbarbBase[0]; + uint32_t outputB = ((uint32_t)output & ~(1U<<9U)); + uint32_t inputB = ((uint32_t)input & ~(1U<<9U)); + XBARB_HAL_SetOutSel(xbarb_base, outputB, inputB); + return kStatus_XBAR_Success; + } +#endif /* FSL_FEATURE_XBAR_HAS_SINGLE_MODULE */ + else + { + return kStatus_XBAR_InvalidArgument; + } +} + +/*FUNCTION********************************************************************* + * + * Function Name : XBAR_DRV_GetEdgeDetectionStatus + * Description : Get the active edge detection status of selected output. + * If the active edge occurs, the return value will be asserted. When interrupt + * or DMA functionality is enabled for XBAR_OUTx, this field is 1 when the + * interrupt or DMA request is asserted and 0 when the interrupt or DMA request + * has been cleared. + * + *END*************************************************************************/ +bool XBAR_DRV_GetEdgeDetectionStatus(uint32_t outIndex) +{ + XBARA_Type * xbara_base = g_xbaraBase[0]; + + return XBARA_HAL_GetEdgeDetectionStatus(xbara_base, outIndex); + +} + +/*FUNCTION********************************************************************* + * + * Function Name : XBAR_DRV_ClearEdgeDetectionStatus + * Description : Clear the edge detection status of selected output. + * This field is cleared by this function or by DMA_ACKx reception when DENx + * is set. + * + *END*************************************************************************/ +xbar_status_t XBAR_DRV_ClearEdgeDetectionStatus(uint32_t outIndex) +{ + XBARA_Type * xbara_base = g_xbaraBase[0]; + + XBARA_HAL_ClearEdgeDetectionStatus(xbara_base, outIndex); + + return kStatus_XBAR_Success; +} + +/*FUNCTION********************************************************************* + * + * Function Name : XBAR_DRV_InstallCallback + * Description : Install the user-defined callback in XBAR module. + * When an XBAR interrupt request is served, the callback will be executed + * inside the ISR. + * + *END*************************************************************************/ +xbar_status_t XBAR_DRV_InstallCallback(uint32_t outIndex, xbar_callback_t userCallback, void * callbackParam) +{ + if(outIndex >= FSL_FEATURE_XBARA_INTERRUPT_COUNT) + { + return kStatus_XBAR_InvalidArgument; + } + + xbar_state_t * xbarState = (xbar_state_t *)g_xbarState; + xbarState->userCallbackFunct[outIndex] = userCallback; + xbarState->xbarCallbackParam[outIndex] = callbackParam; + + return kStatus_XBAR_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : XBAR_DRV_IRQHandler + * Description : Driver-defined ISR in XBAR module. + * This is not a public API as it is called whenever an interrupt occurs. + * + *END**************************************************************************/ +void XBAR_DRV_IRQHandler(void) +{ + XBARA_Type * xbara_base = g_xbaraBase[0]; + xbar_state_t* stateOutput = g_xbarState; + + uint32_t outIndex; + + for(outIndex = 0; outIndex < FSL_FEATURE_XBARA_INTERRUPT_COUNT; outIndex++) + { + if(XBARA_HAL_GetIntOutCmd(xbara_base, outIndex)) + { + if(XBARA_HAL_GetEdgeDetectionStatus(xbara_base, outIndex)) + { + /* Execute the user-defined callback function. */ + if (stateOutput->userCallbackFunct[outIndex]) + { + (*(stateOutput->userCallbackFunct[outIndex]))(stateOutput->xbarCallbackParam[outIndex]); + } + + /* Make sure the flags are cleared. */ + XBARA_HAL_ClearEdgeDetectionStatus(xbara_base, outIndex); + } + } + } +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/KSDK_1.2.0/platform/drivers/src/xbar/fsl_xbar_irq.c b/KSDK_1.2.0/platform/drivers/src/xbar/fsl_xbar_irq.c new file mode 100755 index 0000000..80fb8be --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/xbar/fsl_xbar_irq.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_xbar_driver.h" +#if FSL_FEATURE_SOC_XBAR_COUNT + +/******************************************************************************* + * Code + ******************************************************************************/ +/* XBAR IRQ handler that would cover the same name's APIs in startup code */ +#if !defined(FSL_FEATURE_XBAR_HAS_SINGLE_MODULE) +void XBARA_IRQHandler(void) +#else +void XBAR_IRQHandler(void) +#endif +{ + XBAR_DRV_IRQHandler(); +} +#endif + +/****************************************************************************** + * EOF + *****************************************************************************/
\ No newline at end of file diff --git a/KSDK_1.2.0/platform/drivers/src/xbar/fsl_xbar_lpm_callback.c b/KSDK_1.2.0/platform/drivers/src/xbar/fsl_xbar_lpm_callback.c new file mode 100755 index 0000000..19f3f29 --- /dev/null +++ b/KSDK_1.2.0/platform/drivers/src/xbar/fsl_xbar_lpm_callback.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Includes +/////////////////////////////////////////////////////////////////////////////// + +// Standard C Included Files +#include <stdio.h> +#include <stdint.h> + +// SDK Included Files +#include "fsl_power_manager.h" +#include "fsl_clock_manager.h" +#if FSL_FEATURE_SOC_XBAR_COUNT + +power_manager_error_code_t xbar_pm_callback(power_manager_notify_struct_t * notify, + power_manager_callback_data_t * dataPtr) +{ + power_manager_error_code_t result = kPowerManagerSuccess; + + switch (notify->notifyType) + { + case kPowerManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kPowerManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kPowerManagerError; + break; + } + + return result; +} + +clock_manager_error_code_t xbar_cm_callback(clock_notify_struct_t *notify, + void* dataPtr) +{ + clock_manager_error_code_t result = kClockManagerSuccess; + + switch (notify->notifyType) + { + case kClockManagerNotifyBefore: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyRecover: + /* TODO */ + /* Add code here. */ + break; + + case kClockManagerNotifyAfter: + /* TODO */ + /* Add code here. */ + break; + + default: + result = kClockManagerError; + break; + } + return result; +} +#endif + |