mirror of https://github.com/ARMmbed/mbed-os.git
Lots of K64F SPI fixes (#315)
* Update DSPI driver to latest version from NXP * Other updates to SDK files * Fix double DMA transactions, improve dummy byte support * Simplify dummy byte setting * Also fix SPI driver bug * Fix infinite hang with interrupt SPI * Better fix for SPI hang * Remove earlier fixpull/15530/head
parent
de0c404983
commit
5354079bfb
|
@ -480,7 +480,7 @@ public:
|
|||
typename std::enable_if<std::is_integral<WordT>::value, int>::type
|
||||
transfer(const WordT *tx_buffer, int tx_length, CacheAlignedBuffer<WordT> &rx_buffer, int rx_length, const event_callback_t &callback, int event = SPI_EVENT_COMPLETE)
|
||||
{
|
||||
MBED_ASSERT(rx_length <= static_cast<int>(rx_buffer.capacity()));
|
||||
MBED_ASSERT(rx_length <= static_cast<int>(rx_buffer.capacity() * sizeof(WordT)));
|
||||
return transfer_internal(tx_buffer, tx_length, rx_buffer.data(), rx_length, callback, event);
|
||||
}
|
||||
|
||||
|
@ -489,7 +489,7 @@ public:
|
|||
typename std::enable_if<std::is_integral<WordT>::value, int>::type
|
||||
transfer(const std::nullptr_t tx_buffer, int tx_length, CacheAlignedBuffer<WordT> &rx_buffer, int rx_length, const event_callback_t &callback, int event = SPI_EVENT_COMPLETE)
|
||||
{
|
||||
MBED_ASSERT(rx_length <= static_cast<int>(rx_buffer.capacity()));
|
||||
MBED_ASSERT(rx_length <= static_cast<int>(rx_buffer.capacity() * sizeof(WordT)));
|
||||
return transfer_internal(tx_buffer, tx_length, rx_buffer.data(), rx_length, callback, event);
|
||||
}
|
||||
template<typename WordT>
|
||||
|
@ -528,7 +528,7 @@ public:
|
|||
typename std::enable_if<std::is_integral<WordT>::value, int>::type
|
||||
transfer_and_wait(const WordT *tx_buffer, int tx_length, CacheAlignedBuffer<WordT> &rx_buffer, int rx_length, rtos::Kernel::Clock::duration_u32 timeout = rtos::Kernel::wait_for_u32_forever)
|
||||
{
|
||||
MBED_ASSERT(rx_length <= static_cast<int>(rx_buffer.capacity()));
|
||||
MBED_ASSERT(rx_length <= static_cast<int>(rx_buffer.capacity() * sizeof(WordT)));
|
||||
return transfer_and_wait_internal(tx_buffer, tx_length, rx_buffer.data(), rx_length, timeout);
|
||||
}
|
||||
|
||||
|
@ -537,7 +537,7 @@ public:
|
|||
typename std::enable_if<std::is_integral<WordT>::value, int>::type
|
||||
transfer_and_wait(const std::nullptr_t tx_buffer, int tx_length, CacheAlignedBuffer<WordT> &rx_buffer, int rx_length, rtos::Kernel::Clock::duration_u32 timeout = rtos::Kernel::wait_for_u32_forever)
|
||||
{
|
||||
MBED_ASSERT(rx_length <= static_cast<int>(rx_buffer.capacity()));
|
||||
MBED_ASSERT(rx_length <= static_cast<int>(rx_buffer.capacity() * sizeof(WordT)));
|
||||
return transfer_and_wait_internal(tx_buffer, tx_length, rx_buffer.data(), rx_length, timeout);
|
||||
}
|
||||
template<typename WordT>
|
||||
|
@ -549,6 +549,8 @@ public:
|
|||
|
||||
/**
|
||||
* @brief Abort the on-going SPI transfer, if any, and continue with transfers in the queue, if any.
|
||||
*
|
||||
* @note If a transfer is aborted, its callback will not be called at all.
|
||||
*/
|
||||
void abort_transfer();
|
||||
|
||||
|
|
|
@ -235,6 +235,9 @@ void spi_free(spi_t *obj);
|
|||
*
|
||||
* Set the number of bits per frame, configure clock polarity and phase, shift order and master/slave mode.
|
||||
* The default bit order is MSB.
|
||||
*
|
||||
* This function shall NOT modify the SPI frequency if the SPI frequency has previously been set.
|
||||
*
|
||||
* @param[in,out] obj The SPI object to configure
|
||||
* @param[in] bits The number of bits per frame
|
||||
* @param[in] mode The SPI mode (clock polarity, phase, and shift direction)
|
||||
|
|
|
@ -38,6 +38,7 @@ target_sources(mbed-mcu-k64f
|
|||
drivers/fsl_cmp.c
|
||||
drivers/fsl_cmt.c
|
||||
drivers/fsl_crc.c
|
||||
drivers/fsl_common_arm.c
|
||||
drivers/fsl_dac.c
|
||||
drivers/fsl_dmamux.c
|
||||
drivers/fsl_dspi.c
|
||||
|
|
|
@ -1,31 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2021 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_COMMON_H_
|
||||
|
@ -34,8 +12,13 @@
|
|||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(__ICCARM__) || (defined(__CC_ARM) || defined(__ARMCC_VERSION)) || defined(__GNUC__)
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#include "fsl_device_registers.h"
|
||||
|
||||
/*!
|
||||
|
@ -43,115 +26,210 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Configurations
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Macro to use the default weak IRQ handler in drivers. */
|
||||
#ifndef FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ
|
||||
#define FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ 1
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Construct a status code value from a group and code number. */
|
||||
#define MAKE_STATUS(group, code) ((((group)*100) + (code)))
|
||||
#define MAKE_STATUS(group, code) ((((group)*100L) + (code)))
|
||||
|
||||
/*! @brief Construct the version number for drivers. */
|
||||
#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
|
||||
/*! @brief Construct the version number for drivers.
|
||||
*
|
||||
* The driver version is a 32-bit number, for both 32-bit platforms(such as Cortex M)
|
||||
* and 16-bit platforms(such as DSC).
|
||||
*
|
||||
* @verbatim
|
||||
|
||||
| Unused || Major Version || Minor Version || Bug Fix |
|
||||
31 25 24 17 16 9 8 0
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
#define MAKE_VERSION(major, minor, bugfix) (((major) * 65536L) + ((minor) * 256L) + (bugfix))
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief common driver version. */
|
||||
#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 3, 1))
|
||||
/*@}*/
|
||||
|
||||
/* Debug console type definition. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console base on UART. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console base on LPUART. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console base on LPSCI. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console base on USBCDC. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console base on USBCDC. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console based on UART. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console based on LPUART. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console based on LPSCI. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console based on USBCDC. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console based on FLEXCOMM. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_IUART 6U /*!< Debug console based on i.MX UART. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_VUSART 7U /*!< Debug console based on LPC_VUSART. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_MINI_USART 8U /*!< Debug console based on LPC_USART. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_SWO 9U /*!< Debug console based on SWO. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_QSCI 10U /*!< Debug console based on QSCI. */
|
||||
|
||||
/*! @brief Status group numbers. */
|
||||
enum _status_groups
|
||||
{
|
||||
kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */
|
||||
kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */
|
||||
kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */
|
||||
kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */
|
||||
kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */
|
||||
kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */
|
||||
kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */
|
||||
kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */
|
||||
kStatusGroup_UART = 10, /*!< Group number for UART status codes. */
|
||||
kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */
|
||||
kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */
|
||||
kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */
|
||||
kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/
|
||||
kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/
|
||||
kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/
|
||||
kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */
|
||||
kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */
|
||||
kStatusGroup_SAI = 19, /*!< Group number for SAI status code */
|
||||
kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */
|
||||
kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */
|
||||
kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */
|
||||
kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */
|
||||
kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */
|
||||
kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */
|
||||
kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */
|
||||
kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */
|
||||
kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */
|
||||
kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */
|
||||
kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */
|
||||
kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */
|
||||
kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */
|
||||
kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */
|
||||
kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */
|
||||
kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */
|
||||
kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */
|
||||
kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */
|
||||
kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */
|
||||
kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */
|
||||
kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */
|
||||
kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */
|
||||
kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */
|
||||
kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */
|
||||
kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */
|
||||
kStatusGroup_ApplicationRangeStart = 100, /*!< Starting number for application groups. */
|
||||
kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */
|
||||
kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */
|
||||
kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */
|
||||
kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */
|
||||
kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */
|
||||
kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */
|
||||
kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */
|
||||
kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */
|
||||
kStatusGroup_UART = 10, /*!< Group number for UART status codes. */
|
||||
kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */
|
||||
kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */
|
||||
kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */
|
||||
kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/
|
||||
kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/
|
||||
kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/
|
||||
kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */
|
||||
kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */
|
||||
kStatusGroup_SAI = 19, /*!< Group number for SAI status code */
|
||||
kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */
|
||||
kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */
|
||||
kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */
|
||||
kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */
|
||||
kStatusGroup_FLEXIO_MCULCD = 24, /*!< Group number for FLEXIO LCD status codes */
|
||||
kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */
|
||||
kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */
|
||||
kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */
|
||||
kStatusGroup_IUART = 28, /*!< Group number for IUART status codes */
|
||||
kStatusGroup_CSI = 29, /*!< Group number for CSI status codes */
|
||||
kStatusGroup_MIPI_DSI = 30, /*!< Group number for MIPI DSI status codes */
|
||||
kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */
|
||||
kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */
|
||||
kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */
|
||||
kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */
|
||||
kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */
|
||||
kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */
|
||||
kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */
|
||||
kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */
|
||||
kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */
|
||||
kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */
|
||||
kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */
|
||||
kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */
|
||||
kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */
|
||||
kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */
|
||||
kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */
|
||||
kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */
|
||||
kStatusGroup_DMIC = 58, /*!< Group number for DMIC status codes. */
|
||||
kStatusGroup_SDIF = 59, /*!< Group number for SDIF status codes.*/
|
||||
kStatusGroup_SPIFI = 60, /*!< Group number for SPIFI status codes. */
|
||||
kStatusGroup_OTP = 61, /*!< Group number for OTP status codes. */
|
||||
kStatusGroup_MCAN = 62, /*!< Group number for MCAN status codes. */
|
||||
kStatusGroup_CAAM = 63, /*!< Group number for CAAM status codes. */
|
||||
kStatusGroup_ECSPI = 64, /*!< Group number for ECSPI status codes. */
|
||||
kStatusGroup_USDHC = 65, /*!< Group number for USDHC status codes.*/
|
||||
kStatusGroup_LPC_I2C = 66, /*!< Group number for LPC_I2C status codes.*/
|
||||
kStatusGroup_DCP = 67, /*!< Group number for DCP status codes.*/
|
||||
kStatusGroup_MSCAN = 68, /*!< Group number for MSCAN status codes.*/
|
||||
kStatusGroup_ESAI = 69, /*!< Group number for ESAI status codes. */
|
||||
kStatusGroup_FLEXSPI = 70, /*!< Group number for FLEXSPI status codes. */
|
||||
kStatusGroup_MMDC = 71, /*!< Group number for MMDC status codes. */
|
||||
kStatusGroup_PDM = 72, /*!< Group number for MIC status codes. */
|
||||
kStatusGroup_SDMA = 73, /*!< Group number for SDMA status codes. */
|
||||
kStatusGroup_ICS = 74, /*!< Group number for ICS status codes. */
|
||||
kStatusGroup_SPDIF = 75, /*!< Group number for SPDIF status codes. */
|
||||
kStatusGroup_LPC_MINISPI = 76, /*!< Group number for LPC_MINISPI status codes. */
|
||||
kStatusGroup_HASHCRYPT = 77, /*!< Group number for Hashcrypt status codes */
|
||||
kStatusGroup_LPC_SPI_SSP = 78, /*!< Group number for LPC_SPI_SSP status codes. */
|
||||
kStatusGroup_I3C = 79, /*!< Group number for I3C status codes */
|
||||
kStatusGroup_LPC_I2C_1 = 97, /*!< Group number for LPC_I2C_1 status codes. */
|
||||
kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */
|
||||
kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */
|
||||
kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */
|
||||
kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */
|
||||
kStatusGroup_IAP = 102, /*!< Group number for IAP status codes */
|
||||
kStatusGroup_SFA = 103, /*!< Group number for SFA status codes*/
|
||||
kStatusGroup_SPC = 104, /*!< Group number for SPC status codes. */
|
||||
kStatusGroup_PUF = 105, /*!< Group number for PUF status codes. */
|
||||
kStatusGroup_TOUCH_PANEL = 106, /*!< Group number for touch panel status codes */
|
||||
|
||||
kStatusGroup_HAL_GPIO = 121, /*!< Group number for HAL GPIO status codes. */
|
||||
kStatusGroup_HAL_UART = 122, /*!< Group number for HAL UART status codes. */
|
||||
kStatusGroup_HAL_TIMER = 123, /*!< Group number for HAL TIMER status codes. */
|
||||
kStatusGroup_HAL_SPI = 124, /*!< Group number for HAL SPI status codes. */
|
||||
kStatusGroup_HAL_I2C = 125, /*!< Group number for HAL I2C status codes. */
|
||||
kStatusGroup_HAL_FLASH = 126, /*!< Group number for HAL FLASH status codes. */
|
||||
kStatusGroup_HAL_PWM = 127, /*!< Group number for HAL PWM status codes. */
|
||||
kStatusGroup_HAL_RNG = 128, /*!< Group number for HAL RNG status codes. */
|
||||
kStatusGroup_HAL_I2S = 129, /*!< Group number for HAL I2S status codes. */
|
||||
kStatusGroup_TIMERMANAGER = 135, /*!< Group number for TiMER MANAGER status codes. */
|
||||
kStatusGroup_SERIALMANAGER = 136, /*!< Group number for SERIAL MANAGER status codes. */
|
||||
kStatusGroup_LED = 137, /*!< Group number for LED status codes. */
|
||||
kStatusGroup_BUTTON = 138, /*!< Group number for BUTTON status codes. */
|
||||
kStatusGroup_EXTERN_EEPROM = 139, /*!< Group number for EXTERN EEPROM status codes. */
|
||||
kStatusGroup_SHELL = 140, /*!< Group number for SHELL status codes. */
|
||||
kStatusGroup_MEM_MANAGER = 141, /*!< Group number for MEM MANAGER status codes. */
|
||||
kStatusGroup_LIST = 142, /*!< Group number for List status codes. */
|
||||
kStatusGroup_OSA = 143, /*!< Group number for OSA status codes. */
|
||||
kStatusGroup_COMMON_TASK = 144, /*!< Group number for Common task status codes. */
|
||||
kStatusGroup_MSG = 145, /*!< Group number for messaging status codes. */
|
||||
kStatusGroup_SDK_OCOTP = 146, /*!< Group number for OCOTP status codes. */
|
||||
kStatusGroup_SDK_FLEXSPINOR = 147, /*!< Group number for FLEXSPINOR status codes.*/
|
||||
kStatusGroup_CODEC = 148, /*!< Group number for codec status codes. */
|
||||
kStatusGroup_ASRC = 149, /*!< Group number for codec status ASRC. */
|
||||
kStatusGroup_OTFAD = 150, /*!< Group number for codec status codes. */
|
||||
kStatusGroup_SDIOSLV = 151, /*!< Group number for SDIOSLV status codes. */
|
||||
kStatusGroup_MECC = 152, /*!< Group number for MECC status codes. */
|
||||
kStatusGroup_ENET_QOS = 153, /*!< Group number for ENET_QOS status codes. */
|
||||
kStatusGroup_LOG = 154, /*!< Group number for LOG status codes. */
|
||||
kStatusGroup_I3CBUS = 155, /*!< Group number for I3CBUS status codes. */
|
||||
kStatusGroup_QSCI = 156, /*!< Group number for QSCI status codes. */
|
||||
kStatusGroup_SNT = 157, /*!< Group number for SNT status codes. */
|
||||
kStatusGroup_QUEUEDSPI = 158, /*!< Group number for QSPI status codes. */
|
||||
kStatusGroup_POWER_MANAGER = 159, /*!< Group number for POWER_MANAGER status codes. */
|
||||
};
|
||||
|
||||
/*! @brief Generic status return codes. */
|
||||
enum _generic_status
|
||||
/*! \public
|
||||
* @brief Generic status return codes.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0),
|
||||
kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1),
|
||||
kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2),
|
||||
kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3),
|
||||
kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4),
|
||||
kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5),
|
||||
kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6),
|
||||
kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< Generic status for Success. */
|
||||
kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< Generic status for Fail. */
|
||||
kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2), /*!< Generic status for read only failure. */
|
||||
kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3), /*!< Generic status for out of range access. */
|
||||
kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< Generic status for invalid argument check. */
|
||||
kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5), /*!< Generic status for timeout. */
|
||||
kStatus_NoTransferInProgress =
|
||||
MAKE_STATUS(kStatusGroup_Generic, 6), /*!< Generic status for no transfer in progress. */
|
||||
kStatus_Busy = MAKE_STATUS(kStatusGroup_Generic, 7), /*!< Generic status for module is busy. */
|
||||
kStatus_NoData =
|
||||
MAKE_STATUS(kStatusGroup_Generic, 8), /*!< Generic status for no data is found for the operation. */
|
||||
};
|
||||
|
||||
/*! @brief Type used for all status and error return values. */
|
||||
typedef int32_t status_t;
|
||||
|
||||
/*
|
||||
* The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
|
||||
* defined in previous of this file.
|
||||
/*!
|
||||
* @name Min/max macros
|
||||
* @{
|
||||
*/
|
||||
#include "fsl_clock.h"
|
||||
|
||||
/*
|
||||
* Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral
|
||||
*/
|
||||
#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
|
||||
(defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
|
||||
#include "fsl_reset.h"
|
||||
#endif
|
||||
|
||||
/*! @name Min/max macros */
|
||||
/* @{ */
|
||||
#if !defined(MIN)
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#if !defined(MAX)
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
/* @} */
|
||||
|
||||
/*! @brief Computes the number of elements in an array. */
|
||||
#if !defined(ARRAY_SIZE)
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
/*! @name UINT16_MAX/UINT32_MAX value */
|
||||
/* @{ */
|
||||
|
@ -164,17 +242,18 @@ typedef int32_t status_t;
|
|||
#endif
|
||||
/* @} */
|
||||
|
||||
/*! @name Timer utilities */
|
||||
/*! @name Suppress fallthrough warning macro */
|
||||
/* For switch case code block, if case section ends without "break;" statement, there wil be
|
||||
fallthrough warning with compiler flag -Wextra or -Wimplicit-fallthrough=n when using armgcc.
|
||||
To suppress this warning, "SUPPRESS_FALL_THROUGH_WARNING();" need to be added at the end of each
|
||||
case section which misses "break;"statement.
|
||||
*/
|
||||
/* @{ */
|
||||
/*! Macro to convert a microsecond period to raw count value */
|
||||
#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)((uint64_t)us * clockFreqInHz / 1000000U)
|
||||
/*! Macro to convert a raw count value to microsecond */
|
||||
#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000000U / clockFreqInHz)
|
||||
|
||||
/*! Macro to convert a millisecond period to raw count value */
|
||||
#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)ms * clockFreqInHz / 1000U)
|
||||
/*! Macro to convert a raw count value to millisecond */
|
||||
#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000U / clockFreqInHz)
|
||||
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
|
||||
#define SUPPRESS_FALL_THROUGH_WARNING() __attribute__((fallthrough))
|
||||
#else
|
||||
#define SUPPRESS_FALL_THROUGH_WARNING()
|
||||
#endif
|
||||
/* @} */
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -186,120 +265,32 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Enable specific interrupt.
|
||||
* @brief Allocate memory with given alignment and aligned size.
|
||||
*
|
||||
* Enable the interrupt not routed from intmux.
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
* This is provided to support the dynamically allocated memory
|
||||
* used in cache-able region.
|
||||
* @param size The length required to malloc.
|
||||
* @param alignbytes The alignment size.
|
||||
* @retval The allocated memory.
|
||||
*/
|
||||
static inline void EnableIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
if (NotAvail_IRQn == interrupt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0)
|
||||
if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX)
|
||||
#endif
|
||||
{
|
||||
NVIC_EnableIRQ(interrupt);
|
||||
}
|
||||
}
|
||||
void *SDK_Malloc(size_t size, size_t alignbytes);
|
||||
|
||||
/*!
|
||||
* @brief Disable specific interrupt.
|
||||
* @brief Free memory.
|
||||
*
|
||||
* Disable the interrupt not routed from intmux.
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
* @param ptr The memory to be release.
|
||||
*/
|
||||
static inline void DisableIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
if (NotAvail_IRQn == interrupt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0)
|
||||
if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX)
|
||||
#endif
|
||||
{
|
||||
NVIC_DisableIRQ(interrupt);
|
||||
}
|
||||
}
|
||||
void SDK_Free(void *ptr);
|
||||
|
||||
/*!
|
||||
* @brief Disable the global IRQ
|
||||
* @brief Delay at least for some time.
|
||||
* Please note that, this API uses while loop for delay, different run-time environments make the time not precise,
|
||||
* if precise delay count was needed, please implement a new delay function with hardware timer.
|
||||
*
|
||||
* Disable the global interrupt and return the current primask register. User is required to provided the primask
|
||||
* register for the EnableGlobalIRQ().
|
||||
*
|
||||
* @return Current primask value.
|
||||
* @param delayTime_us Delay time in unit of microsecond.
|
||||
* @param coreClock_Hz Core clock frequency with Hz.
|
||||
*/
|
||||
static inline uint32_t DisableGlobalIRQ(void)
|
||||
{
|
||||
uint32_t regPrimask = __get_PRIMASK();
|
||||
|
||||
__disable_irq();
|
||||
|
||||
return regPrimask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enaable the global IRQ
|
||||
*
|
||||
* Set the primask register with the provided primask value but not just enable the primask. The idea is for the
|
||||
* convinience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to
|
||||
* use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair.
|
||||
*
|
||||
* @param primask value of primask register to be restored. The primask value is supposed to be provided by the
|
||||
* DisableGlobalIRQ().
|
||||
*/
|
||||
static inline void EnableGlobalIRQ(uint32_t primask)
|
||||
{
|
||||
__set_PRIMASK(primask);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief install IRQ handler
|
||||
*
|
||||
* @param irq IRQ number
|
||||
* @param irqHandler IRQ handler address
|
||||
*/
|
||||
void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
|
||||
|
||||
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
|
||||
/*!
|
||||
* @brief Enable specific interrupt for wake-up from deep-sleep mode.
|
||||
*
|
||||
* Enable the interrupt for wake-up from deep sleep mode.
|
||||
* Some interrupts are typically used in sleep mode only and will not occur during
|
||||
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
|
||||
* those clocks (significantly increasing power consumption in the reduced power mode),
|
||||
* making these wake-ups possible.
|
||||
*
|
||||
* @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internally).
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
*/
|
||||
void EnableDeepSleepIRQ(IRQn_Type interrupt);
|
||||
|
||||
/*!
|
||||
* @brief Disable specific interrupt for wake-up from deep-sleep mode.
|
||||
*
|
||||
* Disable the interrupt for wake-up from deep sleep mode.
|
||||
* Some interrupts are typically used in sleep mode only and will not occur during
|
||||
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
|
||||
* those clocks (significantly increasing power consumption in the reduced power mode),
|
||||
* making these wake-ups possible.
|
||||
*
|
||||
* @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internally).
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
*/
|
||||
void DisableDeepSleepIRQ(IRQn_Type interrupt);
|
||||
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
|
||||
void SDK_DelayAtLeastUs(uint32_t delayTime_us, uint32_t coreClock_Hz);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
@ -307,4 +298,12 @@ void DisableDeepSleepIRQ(IRQn_Type interrupt);
|
|||
|
||||
/*! @} */
|
||||
|
||||
#if (defined(__DSC__) && defined(__CW__))
|
||||
#include "fsl_common_dsc.h"
|
||||
#elif defined(__XCC__)
|
||||
#include "fsl_common_dsp.h"
|
||||
#else
|
||||
#include "fsl_common_arm.h"
|
||||
#endif
|
||||
|
||||
#endif /* _FSL_COMMON_H_ */
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2021 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/* Component ID definition, used by tools. */
|
||||
#ifndef FSL_COMPONENT_ID
|
||||
#define FSL_COMPONENT_ID "platform.drivers.common_arm"
|
||||
#endif
|
||||
|
||||
#ifndef __GIC_PRIO_BITS
|
||||
#if defined(ENABLE_RAM_VECTOR_TABLE)
|
||||
uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler)
|
||||
{
|
||||
#ifdef __VECTOR_TABLE
|
||||
#undef __VECTOR_TABLE
|
||||
#endif
|
||||
|
||||
/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */
|
||||
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
|
||||
extern uint32_t Image$$VECTOR_ROM$$Base[];
|
||||
extern uint32_t Image$$VECTOR_RAM$$Base[];
|
||||
extern uint32_t Image$$RW_m_data$$Base[];
|
||||
|
||||
#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base
|
||||
#define __VECTOR_RAM Image$$VECTOR_RAM$$Base
|
||||
#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base))
|
||||
#elif defined(__ICCARM__)
|
||||
extern uint32_t __RAM_VECTOR_TABLE_SIZE[];
|
||||
extern uint32_t __VECTOR_TABLE[];
|
||||
extern uint32_t __VECTOR_RAM[];
|
||||
#elif defined(__GNUC__)
|
||||
extern uint32_t __VECTOR_TABLE[];
|
||||
extern uint32_t __VECTOR_RAM[];
|
||||
extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[];
|
||||
uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES);
|
||||
#endif /* defined(__CC_ARM) || defined(__ARMCC_VERSION) */
|
||||
uint32_t n;
|
||||
uint32_t ret;
|
||||
uint32_t irqMaskValue;
|
||||
|
||||
irqMaskValue = DisableGlobalIRQ();
|
||||
if (SCB->VTOR != (uint32_t)__VECTOR_RAM)
|
||||
{
|
||||
/* Copy the vector table from ROM to RAM */
|
||||
for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++)
|
||||
{
|
||||
__VECTOR_RAM[n] = __VECTOR_TABLE[n];
|
||||
}
|
||||
/* Point the VTOR to the position of vector table */
|
||||
SCB->VTOR = (uint32_t)__VECTOR_RAM;
|
||||
}
|
||||
|
||||
ret = __VECTOR_RAM[(int32_t)irq + 16];
|
||||
/* make sure the __VECTOR_RAM is noncachable */
|
||||
__VECTOR_RAM[(int32_t)irq + 16] = irqHandler;
|
||||
|
||||
EnableGlobalIRQ(irqMaskValue);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* ENABLE_RAM_VECTOR_TABLE. */
|
||||
#endif /* __GIC_PRIO_BITS. */
|
||||
|
||||
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
|
||||
|
||||
/*
|
||||
* When FSL_FEATURE_POWERLIB_EXTEND is defined to non-zero value,
|
||||
* powerlib should be used instead of these functions.
|
||||
*/
|
||||
#if !(defined(FSL_FEATURE_POWERLIB_EXTEND) && (FSL_FEATURE_POWERLIB_EXTEND != 0))
|
||||
|
||||
/*
|
||||
* When the SYSCON STARTER registers are discontinuous, these functions are
|
||||
* implemented in fsl_power.c.
|
||||
*/
|
||||
#if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS)
|
||||
|
||||
void EnableDeepSleepIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
uint32_t intNumber = (uint32_t)interrupt;
|
||||
|
||||
uint32_t index = 0;
|
||||
|
||||
while (intNumber >= 32u)
|
||||
{
|
||||
index++;
|
||||
intNumber -= 32u;
|
||||
}
|
||||
|
||||
SYSCON->STARTERSET[index] = 1UL << intNumber;
|
||||
(void)EnableIRQ(interrupt); /* also enable interrupt at NVIC */
|
||||
}
|
||||
|
||||
void DisableDeepSleepIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
uint32_t intNumber = (uint32_t)interrupt;
|
||||
|
||||
(void)DisableIRQ(interrupt); /* also disable interrupt at NVIC */
|
||||
uint32_t index = 0;
|
||||
|
||||
while (intNumber >= 32u)
|
||||
{
|
||||
index++;
|
||||
intNumber -= 32u;
|
||||
}
|
||||
|
||||
SYSCON->STARTERCLR[index] = 1UL << intNumber;
|
||||
}
|
||||
#endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */
|
||||
#endif /* FSL_FEATURE_POWERLIB_EXTEND */
|
||||
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
|
||||
|
||||
#if defined(SDK_DELAY_USE_DWT) && defined(DWT)
|
||||
/* Use WDT. */
|
||||
static void enableCpuCycleCounter(void)
|
||||
{
|
||||
/* Make sure the DWT trace fucntion is enabled. */
|
||||
if (CoreDebug_DEMCR_TRCENA_Msk != (CoreDebug_DEMCR_TRCENA_Msk & CoreDebug->DEMCR))
|
||||
{
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
}
|
||||
|
||||
/* CYCCNT not supported on this device. */
|
||||
assert(DWT_CTRL_NOCYCCNT_Msk != (DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk));
|
||||
|
||||
/* Read CYCCNT directly if CYCCENT has already been enabled, otherwise enable CYCCENT first. */
|
||||
if (DWT_CTRL_CYCCNTENA_Msk != (DWT_CTRL_CYCCNTENA_Msk & DWT->CTRL))
|
||||
{
|
||||
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t getCpuCycleCount(void)
|
||||
{
|
||||
return DWT->CYCCNT;
|
||||
}
|
||||
#else /* defined(SDK_DELAY_USE_DWT) && defined(DWT) */
|
||||
/* Use software loop. */
|
||||
#if defined(__CC_ARM) /* This macro is arm v5 specific */
|
||||
/* clang-format off */
|
||||
__ASM static void DelayLoop(uint32_t count)
|
||||
{
|
||||
loop
|
||||
SUBS R0, R0, #1
|
||||
CMP R0, #0
|
||||
BNE loop
|
||||
BX LR
|
||||
}
|
||||
/* clang-format on */
|
||||
#elif defined(__ARMCC_VERSION) || defined(__ICCARM__) || defined(__GNUC__)
|
||||
/* Cortex-M0 has a smaller instruction set, SUBS isn't supported in thumb-16 mode reported from __GNUC__ compiler,
|
||||
* use SUB and CMP here for compatibility */
|
||||
static void DelayLoop(uint32_t count)
|
||||
{
|
||||
__ASM volatile(" MOV R0, %0" : : "r"(count));
|
||||
__ASM volatile(
|
||||
"loop: \n"
|
||||
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
|
||||
" SUB R0, R0, #1 \n"
|
||||
#else
|
||||
" SUBS R0, R0, #1 \n"
|
||||
#endif
|
||||
" CMP R0, #0 \n"
|
||||
|
||||
" BNE loop \n"
|
||||
:
|
||||
:
|
||||
: "r0");
|
||||
}
|
||||
#endif /* defined(__CC_ARM) */
|
||||
#endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) */
|
||||
|
||||
/*!
|
||||
* @brief Delay at least for some time.
|
||||
* Please note that, if not uses DWT, this API will use while loop for delay, different run-time environments have
|
||||
* effect on the delay time. If precise delay is needed, please enable DWT delay. The two parmeters delayTime_us and
|
||||
* coreClock_Hz have limitation. For example, in the platform with 1GHz coreClock_Hz, the delayTime_us only supports
|
||||
* up to 4294967 in current code. If long time delay is needed, please implement a new delay function.
|
||||
*
|
||||
* @param delayTime_us Delay time in unit of microsecond.
|
||||
* @param coreClock_Hz Core clock frequency with Hz.
|
||||
*/
|
||||
void SDK_DelayAtLeastUs(uint32_t delayTime_us, uint32_t coreClock_Hz)
|
||||
{
|
||||
uint64_t count;
|
||||
|
||||
if (delayTime_us > 0U)
|
||||
{
|
||||
count = USEC_TO_COUNT(delayTime_us, coreClock_Hz);
|
||||
|
||||
assert(count <= UINT32_MAX);
|
||||
|
||||
#if defined(SDK_DELAY_USE_DWT) && defined(DWT) /* Use DWT for better accuracy */
|
||||
|
||||
enableCpuCycleCounter();
|
||||
/* Calculate the count ticks. */
|
||||
count += getCpuCycleCount();
|
||||
|
||||
if (count > UINT32_MAX)
|
||||
{
|
||||
count -= UINT32_MAX;
|
||||
/* Wait for cyccnt overflow. */
|
||||
while (count < getCpuCycleCount())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for cyccnt reach count value. */
|
||||
while (count > getCpuCycleCount())
|
||||
{
|
||||
}
|
||||
#else
|
||||
/* Divide value may be different in various environment to ensure delay is precise.
|
||||
* Every loop count includes three instructions, due to Cortex-M7 sometimes executes
|
||||
* two instructions in one period, through test here set divide 1.5. Other M cores use
|
||||
* divide 4. By the way, divide 1.5 or 4 could let the count lose precision, but it does
|
||||
* not matter because other instructions outside while loop is enough to fill the time.
|
||||
*/
|
||||
#if (__CORTEX_M == 7)
|
||||
count = count / 3U * 2U;
|
||||
#else
|
||||
count = count / 4U;
|
||||
#endif
|
||||
DelayLoop((uint32_t)count);
|
||||
#endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) */
|
||||
}
|
||||
}
|
|
@ -0,0 +1,671 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2021 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_COMMON_ARM_H_
|
||||
#define _FSL_COMMON_ARM_H_
|
||||
|
||||
/*
|
||||
* For CMSIS pack RTE.
|
||||
* CMSIS pack RTE generates "RTC_Components.h" which contains the statements
|
||||
* of the related <RTE_Components_h> element for all selected software components.
|
||||
*/
|
||||
#ifdef _RTE_
|
||||
#include "RTE_Components.h"
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @addtogroup ksdk_common
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @name Atomic modification
|
||||
*
|
||||
* These macros are used for atomic access, such as read-modify-write
|
||||
* to the peripheral registers.
|
||||
*
|
||||
* - SDK_ATOMIC_LOCAL_ADD
|
||||
* - SDK_ATOMIC_LOCAL_SET
|
||||
* - SDK_ATOMIC_LOCAL_CLEAR
|
||||
* - SDK_ATOMIC_LOCAL_TOGGLE
|
||||
* - SDK_ATOMIC_LOCAL_CLEAR_AND_SET
|
||||
*
|
||||
* Take SDK_ATOMIC_LOCAL_CLEAR_AND_SET as an example: the parameter @c addr
|
||||
* means the address of the peripheral register or variable you want to modify
|
||||
* atomically, the parameter @c clearBits is the bits to clear, the parameter
|
||||
* @c setBits it the bits to set.
|
||||
* For example, to set a 32-bit register bit1:bit0 to 0b10, use like this:
|
||||
*
|
||||
* @code
|
||||
volatile uint32_t * reg = (volatile uint32_t *)REG_ADDR;
|
||||
|
||||
SDK_ATOMIC_LOCAL_CLEAR_AND_SET(reg, 0x03, 0x02);
|
||||
@endcode
|
||||
*
|
||||
* In this example, the register bit1:bit0 are cleared and bit1 is set, as a result,
|
||||
* register bit1:bit0 = 0b10.
|
||||
*
|
||||
* @note For the platforms don't support exclusive load and store, these macros
|
||||
* disable the global interrupt to pretect the modification.
|
||||
*
|
||||
* @note These macros only guarantee the local processor atomic operations. For
|
||||
* the multi-processor devices, use hardware semaphore such as SEMA42 to
|
||||
* guarantee exclusive access if necessary.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
#if ((defined(__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined(__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||
(defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||
(defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ == 1)))
|
||||
/* clang-format on */
|
||||
|
||||
/* If the LDREX and STREX are supported, use them. */
|
||||
#define _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, val, ops) \
|
||||
do \
|
||||
{ \
|
||||
(val) = __LDREXB(addr); \
|
||||
(ops); \
|
||||
} while (0UL != __STREXB((val), (addr)))
|
||||
|
||||
#define _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, val, ops) \
|
||||
do \
|
||||
{ \
|
||||
(val) = __LDREXH(addr); \
|
||||
(ops); \
|
||||
} while (0UL != __STREXH((val), (addr)))
|
||||
|
||||
#define _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, val, ops) \
|
||||
do \
|
||||
{ \
|
||||
(val) = __LDREXW(addr); \
|
||||
(ops); \
|
||||
} while (0UL != __STREXW((val), (addr)))
|
||||
|
||||
static inline void _SDK_AtomicLocalAdd1Byte(volatile uint8_t *addr, uint8_t val)
|
||||
{
|
||||
uint8_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val += val);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalAdd2Byte(volatile uint16_t *addr, uint16_t val)
|
||||
{
|
||||
uint16_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val += val);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalAdd4Byte(volatile uint32_t *addr, uint32_t val)
|
||||
{
|
||||
uint32_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val += val);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalSub1Byte(volatile uint8_t *addr, uint8_t val)
|
||||
{
|
||||
uint8_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val -= val);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalSub2Byte(volatile uint16_t *addr, uint16_t val)
|
||||
{
|
||||
uint16_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val -= val);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalSub4Byte(volatile uint32_t *addr, uint32_t val)
|
||||
{
|
||||
uint32_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val -= val);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalSet1Byte(volatile uint8_t *addr, uint8_t bits)
|
||||
{
|
||||
uint8_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val |= bits);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalSet2Byte(volatile uint16_t *addr, uint16_t bits)
|
||||
{
|
||||
uint16_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val |= bits);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalSet4Byte(volatile uint32_t *addr, uint32_t bits)
|
||||
{
|
||||
uint32_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val |= bits);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalClear1Byte(volatile uint8_t *addr, uint8_t bits)
|
||||
{
|
||||
uint8_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val &= ~bits);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalClear2Byte(volatile uint16_t *addr, uint16_t bits)
|
||||
{
|
||||
uint16_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val &= ~bits);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalClear4Byte(volatile uint32_t *addr, uint32_t bits)
|
||||
{
|
||||
uint32_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val &= ~bits);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalToggle1Byte(volatile uint8_t *addr, uint8_t bits)
|
||||
{
|
||||
uint8_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val ^= bits);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalToggle2Byte(volatile uint16_t *addr, uint16_t bits)
|
||||
{
|
||||
uint16_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val ^= bits);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalToggle4Byte(volatile uint32_t *addr, uint32_t bits)
|
||||
{
|
||||
uint32_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val ^= bits);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalClearAndSet1Byte(volatile uint8_t *addr, uint8_t clearBits, uint8_t setBits)
|
||||
{
|
||||
uint8_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalClearAndSet2Byte(volatile uint16_t *addr, uint16_t clearBits, uint16_t setBits)
|
||||
{
|
||||
uint16_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
|
||||
}
|
||||
|
||||
static inline void _SDK_AtomicLocalClearAndSet4Byte(volatile uint32_t *addr, uint32_t clearBits, uint32_t setBits)
|
||||
{
|
||||
uint32_t s_val;
|
||||
|
||||
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
|
||||
}
|
||||
|
||||
#define SDK_ATOMIC_LOCAL_ADD(addr, val) \
|
||||
((1UL == sizeof(*(addr))) ? \
|
||||
_SDK_AtomicLocalAdd1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(val)) : \
|
||||
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalAdd2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(val)) : \
|
||||
_SDK_AtomicLocalAdd4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(val))))
|
||||
|
||||
#define SDK_ATOMIC_LOCAL_SET(addr, bits) \
|
||||
((1UL == sizeof(*(addr))) ? \
|
||||
_SDK_AtomicLocalSet1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(bits)) : \
|
||||
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalSet2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(bits)) : \
|
||||
_SDK_AtomicLocalSet4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(bits))))
|
||||
|
||||
#define SDK_ATOMIC_LOCAL_CLEAR(addr, bits) \
|
||||
((1UL == sizeof(*(addr))) ? \
|
||||
_SDK_AtomicLocalClear1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(bits)) : \
|
||||
((2UL == sizeof(*(addr))) ? \
|
||||
_SDK_AtomicLocalClear2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(bits)) : \
|
||||
_SDK_AtomicLocalClear4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(bits))))
|
||||
|
||||
#define SDK_ATOMIC_LOCAL_TOGGLE(addr, bits) \
|
||||
((1UL == sizeof(*(addr))) ? \
|
||||
_SDK_AtomicLocalToggle1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(bits)) : \
|
||||
((2UL == sizeof(*(addr))) ? \
|
||||
_SDK_AtomicLocalToggle2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(bits)) : \
|
||||
_SDK_AtomicLocalToggle4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(bits))))
|
||||
|
||||
#define SDK_ATOMIC_LOCAL_CLEAR_AND_SET(addr, clearBits, setBits) \
|
||||
((1UL == sizeof(*(addr))) ? \
|
||||
_SDK_AtomicLocalClearAndSet1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(clearBits), (uint8_t)(setBits)) : \
|
||||
((2UL == sizeof(*(addr))) ? \
|
||||
_SDK_AtomicLocalClearAndSet2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(clearBits), (uint16_t)(setBits)) : \
|
||||
_SDK_AtomicLocalClearAndSet4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(clearBits), (uint32_t)(setBits))))
|
||||
#else
|
||||
|
||||
#define SDK_ATOMIC_LOCAL_ADD(addr, val) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t s_atomicOldInt; \
|
||||
s_atomicOldInt = DisableGlobalIRQ(); \
|
||||
*(addr) += (val); \
|
||||
EnableGlobalIRQ(s_atomicOldInt); \
|
||||
} while (0)
|
||||
|
||||
#define SDK_ATOMIC_LOCAL_SET(addr, bits) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t s_atomicOldInt; \
|
||||
s_atomicOldInt = DisableGlobalIRQ(); \
|
||||
*(addr) |= (bits); \
|
||||
EnableGlobalIRQ(s_atomicOldInt); \
|
||||
} while (0)
|
||||
|
||||
#define SDK_ATOMIC_LOCAL_CLEAR(addr, bits) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t s_atomicOldInt; \
|
||||
s_atomicOldInt = DisableGlobalIRQ(); \
|
||||
*(addr) &= ~(bits); \
|
||||
EnableGlobalIRQ(s_atomicOldInt); \
|
||||
} while (0)
|
||||
|
||||
#define SDK_ATOMIC_LOCAL_TOGGLE(addr, bits) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t s_atomicOldInt; \
|
||||
s_atomicOldInt = DisableGlobalIRQ(); \
|
||||
*(addr) ^= (bits); \
|
||||
EnableGlobalIRQ(s_atomicOldInt); \
|
||||
} while (0)
|
||||
|
||||
#define SDK_ATOMIC_LOCAL_CLEAR_AND_SET(addr, clearBits, setBits) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t s_atomicOldInt; \
|
||||
s_atomicOldInt = DisableGlobalIRQ(); \
|
||||
*(addr) = (*(addr) & ~(clearBits)) | (setBits); \
|
||||
EnableGlobalIRQ(s_atomicOldInt); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
/* @} */
|
||||
|
||||
/*! @name Timer utilities */
|
||||
/* @{ */
|
||||
/*! Macro to convert a microsecond period to raw count value */
|
||||
#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)(((uint64_t)(us) * (clockFreqInHz)) / 1000000U)
|
||||
/*! Macro to convert a raw count value to microsecond */
|
||||
#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count)*1000000U / (clockFreqInHz))
|
||||
|
||||
/*! Macro to convert a millisecond period to raw count value */
|
||||
#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)(ms) * (clockFreqInHz) / 1000U)
|
||||
/*! Macro to convert a raw count value to millisecond */
|
||||
#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count)*1000U / (clockFreqInHz))
|
||||
/* @} */
|
||||
|
||||
/*! @name ISR exit barrier
|
||||
* @{
|
||||
*
|
||||
* ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
|
||||
* exception return operation might vector to incorrect interrupt.
|
||||
* For Cortex-M7, if core speed much faster than peripheral register write speed,
|
||||
* the peripheral interrupt flags may be still set after exiting ISR, this results to
|
||||
* the same error similar with errata 83869.
|
||||
*/
|
||||
#if (defined __CORTEX_M) && ((__CORTEX_M == 4U) || (__CORTEX_M == 7U))
|
||||
#define SDK_ISR_EXIT_BARRIER __DSB()
|
||||
#else
|
||||
#define SDK_ISR_EXIT_BARRIER
|
||||
#endif
|
||||
|
||||
/* @} */
|
||||
|
||||
/*! @name Alignment variable definition macros */
|
||||
/* @{ */
|
||||
#if (defined(__ICCARM__))
|
||||
/*
|
||||
* Workaround to disable MISRA C message suppress warnings for IAR compiler.
|
||||
* http:/ /supp.iar.com/Support/?note=24725
|
||||
*/
|
||||
_Pragma("diag_suppress=Pm120")
|
||||
#define SDK_PRAGMA(x) _Pragma(#x)
|
||||
_Pragma("diag_error=Pm120")
|
||||
/*! Macro to define a variable with alignbytes alignment */
|
||||
#define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
|
||||
#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
|
||||
/*! Macro to define a variable with alignbytes alignment */
|
||||
#define SDK_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var
|
||||
#elif defined(__GNUC__)
|
||||
/*! Macro to define a variable with alignbytes alignment */
|
||||
#define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
|
||||
#else
|
||||
#error Toolchain not supported
|
||||
#endif
|
||||
|
||||
/*! Macro to define a variable with L1 d-cache line size alignment */
|
||||
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#define SDK_L1DCACHE_ALIGN(var) SDK_ALIGN(var, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#endif
|
||||
/*! Macro to define a variable with L2 cache line size alignment */
|
||||
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
|
||||
#define SDK_L2CACHE_ALIGN(var) SDK_ALIGN(var, FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
|
||||
#endif
|
||||
|
||||
/*! Macro to change a value to a given size aligned value */
|
||||
#define SDK_SIZEALIGN(var, alignbytes) \
|
||||
((unsigned int)((var) + ((alignbytes)-1U)) & (unsigned int)(~(unsigned int)((alignbytes)-1U)))
|
||||
/* @} */
|
||||
|
||||
/*! @name Non-cacheable region definition macros */
|
||||
/* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or
|
||||
* "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable
|
||||
* variables, please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them,
|
||||
* these zero-inited variables will be initialized to zero in system startup.
|
||||
*/
|
||||
/* @{ */
|
||||
|
||||
#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && \
|
||||
defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
|
||||
|
||||
#if (defined(__ICCARM__))
|
||||
#define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable"
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable"
|
||||
#define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init"
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
|
||||
SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init"
|
||||
|
||||
#elif (defined(__CC_ARM) || defined(__ARMCC_VERSION))
|
||||
#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
|
||||
__attribute__((section("NonCacheable.init"))) __attribute__((aligned(alignbytes))) var
|
||||
#if (defined(__CC_ARM))
|
||||
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
|
||||
__attribute__((section("NonCacheable"), zero_init)) __attribute__((aligned(alignbytes))) var
|
||||
#else
|
||||
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section(".bss.NonCacheable"))) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
|
||||
__attribute__((section(".bss.NonCacheable"))) __attribute__((aligned(alignbytes))) var
|
||||
#endif
|
||||
|
||||
#elif (defined(__GNUC__))
|
||||
/* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA"
|
||||
* in your projects to make sure the non-cacheable section variables will be initialized in system startup.
|
||||
*/
|
||||
#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
|
||||
__attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
|
||||
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
|
||||
__attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes)))
|
||||
#else
|
||||
#error Toolchain not supported.
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define AT_NONCACHEABLE_SECTION(var) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_ALIGN(var, alignbytes)
|
||||
#define AT_NONCACHEABLE_SECTION_INIT(var) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_ALIGN(var, alignbytes)
|
||||
|
||||
#endif
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Time sensitive region
|
||||
* @{
|
||||
*/
|
||||
#if (defined(__ICCARM__))
|
||||
#define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess"
|
||||
#define AT_QUICKACCESS_SECTION_DATA(var) var @"DataQuickAccess"
|
||||
#define AT_QUICKACCESS_SECTION_DATA_ALIGN(var, alignbytes) \
|
||||
SDK_PRAGMA(data_alignment = alignbytes) var @"DataQuickAccess"
|
||||
#elif (defined(__CC_ARM) || defined(__ARMCC_VERSION))
|
||||
#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
|
||||
#define AT_QUICKACCESS_SECTION_DATA(var) __attribute__((section("DataQuickAccess"))) var
|
||||
#define AT_QUICKACCESS_SECTION_DATA_ALIGN(var, alignbytes) \
|
||||
__attribute__((section("DataQuickAccess"))) __attribute__((aligned(alignbytes))) var
|
||||
#elif (defined(__GNUC__))
|
||||
#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
|
||||
#define AT_QUICKACCESS_SECTION_DATA(var) __attribute__((section("DataQuickAccess"))) var
|
||||
#define AT_QUICKACCESS_SECTION_DATA_ALIGN(var, alignbytes) \
|
||||
__attribute__((section("DataQuickAccess"))) var __attribute__((aligned(alignbytes)))
|
||||
#else
|
||||
#error Toolchain not supported.
|
||||
#endif /* defined(__ICCARM__) */
|
||||
|
||||
/*! @name Ram Function */
|
||||
#if (defined(__ICCARM__))
|
||||
#define RAMFUNCTION_SECTION_CODE(func) func @"RamFunction"
|
||||
#elif (defined(__CC_ARM) || defined(__ARMCC_VERSION))
|
||||
#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
|
||||
#elif (defined(__GNUC__))
|
||||
#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
|
||||
#else
|
||||
#error Toolchain not supported.
|
||||
#endif /* defined(__ICCARM__) */
|
||||
/* @} */
|
||||
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
void DefaultISR(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
|
||||
* defined in previous of this file.
|
||||
*/
|
||||
#include "fsl_clock.h"
|
||||
|
||||
/*
|
||||
* Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral
|
||||
*/
|
||||
#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
|
||||
(defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
|
||||
#include "fsl_reset.h"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
/*!
|
||||
* @brief Enable specific interrupt.
|
||||
*
|
||||
* Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt
|
||||
* levels. For example, there are NVIC and intmux. Here the interrupts connected
|
||||
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
|
||||
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
|
||||
* to NVIC first then routed to core.
|
||||
*
|
||||
* This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts
|
||||
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
* @retval kStatus_Success Interrupt enabled successfully
|
||||
* @retval kStatus_Fail Failed to enable the interrupt
|
||||
*/
|
||||
static inline status_t EnableIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
status_t status = kStatus_Success;
|
||||
|
||||
if (NotAvail_IRQn == interrupt)
|
||||
{
|
||||
status = kStatus_Fail;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
|
||||
else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
|
||||
{
|
||||
status = kStatus_Fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
else
|
||||
{
|
||||
#if defined(__GIC_PRIO_BITS)
|
||||
GIC_EnableIRQ(interrupt);
|
||||
#else
|
||||
NVIC_EnableIRQ(interrupt);
|
||||
#endif
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disable specific interrupt.
|
||||
*
|
||||
* Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt
|
||||
* levels. For example, there are NVIC and intmux. Here the interrupts connected
|
||||
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
|
||||
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
|
||||
* to NVIC first then routed to core.
|
||||
*
|
||||
* This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts
|
||||
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
* @retval kStatus_Success Interrupt disabled successfully
|
||||
* @retval kStatus_Fail Failed to disable the interrupt
|
||||
*/
|
||||
static inline status_t DisableIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
status_t status = kStatus_Success;
|
||||
|
||||
if (NotAvail_IRQn == interrupt)
|
||||
{
|
||||
status = kStatus_Fail;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
|
||||
else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
|
||||
{
|
||||
status = kStatus_Fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
else
|
||||
{
|
||||
#if defined(__GIC_PRIO_BITS)
|
||||
GIC_DisableIRQ(interrupt);
|
||||
#else
|
||||
NVIC_DisableIRQ(interrupt);
|
||||
#endif
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disable the global IRQ
|
||||
*
|
||||
* Disable the global interrupt and return the current primask register. User is required to provided the primask
|
||||
* register for the EnableGlobalIRQ().
|
||||
*
|
||||
* @return Current primask value.
|
||||
*/
|
||||
static inline uint32_t DisableGlobalIRQ(void)
|
||||
{
|
||||
#if defined(CPSR_I_Msk)
|
||||
uint32_t cpsr = __get_CPSR() & CPSR_I_Msk;
|
||||
|
||||
__disable_irq();
|
||||
|
||||
return cpsr;
|
||||
#else
|
||||
uint32_t regPrimask = __get_PRIMASK();
|
||||
|
||||
__disable_irq();
|
||||
|
||||
return regPrimask;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enable the global IRQ
|
||||
*
|
||||
* Set the primask register with the provided primask value but not just enable the primask. The idea is for the
|
||||
* convenience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to
|
||||
* use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair.
|
||||
*
|
||||
* @param primask value of primask register to be restored. The primask value is supposed to be provided by the
|
||||
* DisableGlobalIRQ().
|
||||
*/
|
||||
static inline void EnableGlobalIRQ(uint32_t primask)
|
||||
{
|
||||
#if defined(CPSR_I_Msk)
|
||||
__set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask);
|
||||
#else
|
||||
__set_PRIMASK(primask);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(ENABLE_RAM_VECTOR_TABLE)
|
||||
/*!
|
||||
* @brief install IRQ handler
|
||||
*
|
||||
* @param irq IRQ number
|
||||
* @param irqHandler IRQ handler address
|
||||
* @return The old IRQ handler address
|
||||
*/
|
||||
uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
|
||||
#endif /* ENABLE_RAM_VECTOR_TABLE. */
|
||||
|
||||
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
|
||||
|
||||
/*
|
||||
* When FSL_FEATURE_POWERLIB_EXTEND is defined to non-zero value,
|
||||
* powerlib should be used instead of these functions.
|
||||
*/
|
||||
#if !(defined(FSL_FEATURE_POWERLIB_EXTEND) && (FSL_FEATURE_POWERLIB_EXTEND != 0))
|
||||
/*!
|
||||
* @brief Enable specific interrupt for wake-up from deep-sleep mode.
|
||||
*
|
||||
* Enable the interrupt for wake-up from deep sleep mode.
|
||||
* Some interrupts are typically used in sleep mode only and will not occur during
|
||||
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
|
||||
* those clocks (significantly increasing power consumption in the reduced power mode),
|
||||
* making these wake-ups possible.
|
||||
*
|
||||
* @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internaly).
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
*/
|
||||
void EnableDeepSleepIRQ(IRQn_Type interrupt);
|
||||
|
||||
/*!
|
||||
* @brief Disable specific interrupt for wake-up from deep-sleep mode.
|
||||
*
|
||||
* Disable the interrupt for wake-up from deep sleep mode.
|
||||
* Some interrupts are typically used in sleep mode only and will not occur during
|
||||
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
|
||||
* those clocks (significantly increasing power consumption in the reduced power mode),
|
||||
* making these wake-ups possible.
|
||||
*
|
||||
* @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internaly).
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
*/
|
||||
void DisableDeepSleepIRQ(IRQn_Type interrupt);
|
||||
#endif /* FSL_FEATURE_POWERLIB_EXTEND */
|
||||
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus*/
|
||||
|
||||
/*! @} */
|
||||
|
||||
#endif /* _FSL_COMMON_ARM_H_ */
|
|
@ -88,11 +88,11 @@ static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *han
|
|||
/* Defines constant value arrays for the baud rate pre-scalar and scalar divider values.*/
|
||||
static const uint32_t s_baudratePrescaler[] = {2, 3, 5, 7};
|
||||
static const uint32_t s_baudrateScaler[] = {2, 4, 6, 8, 16, 32, 64, 128,
|
||||
256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
|
||||
256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
|
||||
|
||||
static const uint32_t s_delayPrescaler[] = {1, 3, 5, 7};
|
||||
static const uint32_t s_delayScaler[] = {2, 4, 8, 16, 32, 64, 128, 256,
|
||||
512, 1024, 2048, 4096, 8192, 16384, 32768, 65536};
|
||||
512, 1024, 2048, 4096, 8192, 16384, 32768, 65536};
|
||||
|
||||
/*! @brief Pointers to dspi bases for each instance. */
|
||||
static SPI_Type *const s_dspiBases[] = SPI_BASE_PTRS;
|
||||
|
@ -115,7 +115,7 @@ static dspi_master_isr_t s_dspiMasterIsr;
|
|||
static dspi_slave_isr_t s_dspiSlaveIsr;
|
||||
|
||||
/* @brief Dummy data for each instance. This data is used when user's tx buffer is NULL*/
|
||||
volatile uint8_t g_dspiDummyData[ARRAY_SIZE(s_dspiBases)] = {0};
|
||||
volatile uint16_t g_dspiDummyData[ARRAY_SIZE(s_dspiBases)] = {0};
|
||||
/**********************************************************************************************************************
|
||||
* Code
|
||||
*********************************************************************************************************************/
|
||||
|
@ -150,20 +150,20 @@ uint32_t DSPI_GetInstance(SPI_Type *base)
|
|||
*
|
||||
* param base DSPI peripheral base address.
|
||||
*/
|
||||
uint8_t DSPI_GetDummyDataInstance(SPI_Type *base)
|
||||
uint16_t DSPI_GetDummyDataInstance(SPI_Type *base)
|
||||
{
|
||||
uint8_t instance = g_dspiDummyData[DSPI_GetInstance(base)];
|
||||
uint16_t instance = g_dspiDummyData[DSPI_GetInstance(base)];
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Set up the dummy data.
|
||||
*
|
||||
* param base DSPI peripheral address.
|
||||
* param dummyData Data to be transferred when tx buffer is NULL.
|
||||
*/
|
||||
void DSPI_SetDummyData(SPI_Type *base, uint8_t dummyData)
|
||||
{
|
||||
uint32_t instance = DSPI_GetInstance(base);
|
||||
g_dspiDummyData[instance] = (((uint16_t)dummyData << 8U) | (uint16_t)dummyData);
|
||||
}
|
||||
|
||||
void DSPI_SetDummyData16Bit(SPI_Type *base, uint16_t dummyData)
|
||||
{
|
||||
uint32_t instance = DSPI_GetInstance(base);
|
||||
g_dspiDummyData[instance] = dummyData;
|
||||
|
@ -428,7 +428,7 @@ uint32_t DSPI_MasterSetBaudRate(SPI_Type *base,
|
|||
/* for master mode configuration, if slave mode detected, return 0*/
|
||||
if (!DSPI_IsMaster(base))
|
||||
{
|
||||
return 0;
|
||||
return 0U;
|
||||
}
|
||||
uint32_t temp;
|
||||
uint32_t prescaler, bestPrescaler;
|
||||
|
@ -516,7 +516,7 @@ uint32_t DSPI_MasterSetBaudRate(SPI_Type *base,
|
|||
* param whichDelay The desired delay to configure; must be of type dspi_delay_type_t
|
||||
*/
|
||||
void DSPI_MasterSetDelayScaler(
|
||||
SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay)
|
||||
SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay)
|
||||
{
|
||||
/* these settings are only relevant in master mode */
|
||||
if (DSPI_IsMaster(base))
|
||||
|
@ -577,7 +577,7 @@ uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base,
|
|||
/* for master mode configuration, if slave mode detected, return 0 */
|
||||
if (!DSPI_IsMaster(base))
|
||||
{
|
||||
return 0;
|
||||
return 0U;
|
||||
}
|
||||
|
||||
uint32_t prescaler, bestPrescaler;
|
||||
|
@ -670,8 +670,8 @@ void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command)
|
|||
(void)memset(command, 0, sizeof(*command));
|
||||
|
||||
command->isPcsContinuous = false;
|
||||
command->whichCtar = kDSPI_Ctar0;
|
||||
command->whichPcs = kDSPI_Pcs0;
|
||||
command->whichCtar = (uint8_t)kDSPI_Ctar0;
|
||||
command->whichPcs = (uint8_t)kDSPI_Pcs0;
|
||||
command->isEndOfQueue = false;
|
||||
command->clearTransferCount = false;
|
||||
}
|
||||
|
@ -888,7 +888,7 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
|
|||
|
||||
uint16_t wordToSend = 0;
|
||||
uint16_t wordReceived = 0;
|
||||
uint8_t dummyData = DSPI_GetDummyDataInstance(base);
|
||||
uint16_t dummyData = DSPI_GetDummyDataInstance(base);
|
||||
uint8_t bitsPerFrame;
|
||||
|
||||
uint32_t command;
|
||||
|
@ -916,19 +916,18 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
|
|||
|
||||
/*Calculate the command and lastCommand*/
|
||||
commandStruct.whichPcs =
|
||||
(dspi_which_pcs_t)((uint32_t)1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
|
||||
(uint8_t)((uint32_t)1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
|
||||
commandStruct.isEndOfQueue = false;
|
||||
commandStruct.clearTransferCount = false;
|
||||
commandStruct.whichCtar =
|
||||
(dspi_ctar_selection_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
|
||||
commandStruct.whichCtar = (uint8_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
|
||||
commandStruct.isPcsContinuous =
|
||||
(0U != (transfer->configFlags & (uint32_t)kDSPI_MasterPcsContinuous)) ? true : false;
|
||||
(0U != (transfer->configFlags & (uint32_t)kDSPI_MasterPcsContinuous)) ? true : false;
|
||||
|
||||
command = DSPI_MasterGetFormattedCommand(&(commandStruct));
|
||||
|
||||
commandStruct.isEndOfQueue = true;
|
||||
commandStruct.isPcsContinuous =
|
||||
(0U != (transfer->configFlags & (uint32_t)kDSPI_MasterActiveAfterTransfer)) ? true : false;
|
||||
(0U != (transfer->configFlags & (uint32_t)kDSPI_MasterActiveAfterTransfer)) ? true : false;
|
||||
lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));
|
||||
|
||||
/*Calculate the bitsPerFrame*/
|
||||
|
@ -946,7 +945,7 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
|
|||
}
|
||||
else
|
||||
{
|
||||
fifoSize = FSL_FEATURE_DSPI_FIFO_SIZEn(base);
|
||||
fifoSize = (uint32_t)FSL_FEATURE_DSPI_FIFO_SIZEn(base);
|
||||
}
|
||||
|
||||
DSPI_StartTransfer(base);
|
||||
|
@ -1156,25 +1155,24 @@ static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *han
|
|||
assert(NULL != transfer);
|
||||
|
||||
uint32_t tmpMCR = 0;
|
||||
dspi_command_data_config_t commandStruct = {false, kDSPI_Ctar0, kDSPI_Pcs0, false, false};
|
||||
dspi_command_data_config_t commandStruct = {false, (uint8_t)kDSPI_Ctar0, (uint8_t)kDSPI_Pcs0, false, false};
|
||||
|
||||
DSPI_StopTransfer(base);
|
||||
DSPI_FlushFifo(base, true, true);
|
||||
DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_AllStatusFlag);
|
||||
|
||||
commandStruct.whichPcs =
|
||||
(dspi_which_pcs_t)((uint32_t)1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
|
||||
(uint8_t)((uint32_t)1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
|
||||
commandStruct.isEndOfQueue = false;
|
||||
commandStruct.clearTransferCount = false;
|
||||
commandStruct.whichCtar =
|
||||
(dspi_ctar_selection_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
|
||||
commandStruct.whichCtar = (uint8_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
|
||||
commandStruct.isPcsContinuous =
|
||||
(0U != (transfer->configFlags & (uint32_t)kDSPI_MasterPcsContinuous)) ? true : false;
|
||||
(0U != (transfer->configFlags & (uint32_t)kDSPI_MasterPcsContinuous)) ? true : false;
|
||||
handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct));
|
||||
|
||||
commandStruct.isEndOfQueue = true;
|
||||
commandStruct.isPcsContinuous =
|
||||
(0U != (transfer->configFlags & (uint32_t)kDSPI_MasterActiveAfterTransfer)) ? true : false;
|
||||
(0U != (transfer->configFlags & (uint32_t)kDSPI_MasterActiveAfterTransfer)) ? true : false;
|
||||
handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));
|
||||
|
||||
handle->bitsPerFrame = ((base->CTAR[commandStruct.whichCtar] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1U;
|
||||
|
@ -1182,11 +1180,11 @@ static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *han
|
|||
tmpMCR = base->MCR;
|
||||
if ((0U != (tmpMCR & SPI_MCR_DIS_RXF_MASK)) || (0U != (tmpMCR & SPI_MCR_DIS_TXF_MASK)))
|
||||
{
|
||||
handle->fifoSize = 1;
|
||||
handle->fifoSize = 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
handle->fifoSize = FSL_FEATURE_DSPI_FIFO_SIZEn(base);
|
||||
handle->fifoSize = (uint8_t)FSL_FEATURE_DSPI_FIFO_SIZEn(base);
|
||||
}
|
||||
handle->txData = transfer->txData;
|
||||
handle->rxData = transfer->rxData;
|
||||
|
@ -1418,7 +1416,7 @@ static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *ha
|
|||
|
||||
/* Disable interrupt requests*/
|
||||
DSPI_DisableInterrupts(
|
||||
base, ((uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable | (uint32_t)kDSPI_TxFifoFillRequestInterruptEnable));
|
||||
base, ((uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable | (uint32_t)kDSPI_TxFifoFillRequestInterruptEnable));
|
||||
|
||||
status_t status = 0;
|
||||
if (handle->state == (uint8_t)kDSPI_Error)
|
||||
|
@ -1442,7 +1440,7 @@ static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t
|
|||
assert(NULL != handle);
|
||||
|
||||
uint16_t wordToSend = 0;
|
||||
uint8_t dummyData = DSPI_GetDummyDataInstance(base);
|
||||
uint16_t dummyData = DSPI_GetDummyDataInstance(base);
|
||||
size_t tmpRemainingSendByteCount = handle->remainingSendByteCount;
|
||||
size_t tmpRemainingReceiveByteCount = handle->remainingReceiveByteCount;
|
||||
uint8_t tmpFifoSize = handle->fifoSize;
|
||||
|
@ -1484,14 +1482,14 @@ static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t
|
|||
handle->remainingSendByteCount = 0;
|
||||
base->PUSHR = handle->lastCommand | wordToSend;
|
||||
}
|
||||
/* For all words except the last word */
|
||||
/* For all words except the last word */
|
||||
else
|
||||
{
|
||||
if (NULL != handle->txData)
|
||||
{
|
||||
wordToSend = *(handle->txData);
|
||||
++handle->txData; /* increment to next data byte */
|
||||
wordToSend |= (unsigned)(*(handle->txData)) << 8U;
|
||||
wordToSend |= (uint16_t)(*(handle->txData)) << 8U;
|
||||
++handle->txData; /* increment to next data byte */
|
||||
}
|
||||
else
|
||||
|
@ -1518,7 +1516,7 @@ static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t
|
|||
tmpFifoSize = handle->fifoSize;
|
||||
} /* End of TX FIFO fill while loop */
|
||||
}
|
||||
/* Optimized for bits/frame less than or equal to one byte. */
|
||||
/* 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
|
||||
|
@ -1584,7 +1582,7 @@ void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle)
|
|||
|
||||
/* Disable interrupt requests*/
|
||||
DSPI_DisableInterrupts(
|
||||
base, ((uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable | (uint32_t)kDSPI_TxFifoFillRequestInterruptEnable));
|
||||
base, ((uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable | (uint32_t)kDSPI_TxFifoFillRequestInterruptEnable));
|
||||
|
||||
handle->state = (uint8_t)kDSPI_Idle;
|
||||
}
|
||||
|
@ -1658,7 +1656,7 @@ void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle)
|
|||
}
|
||||
} /* End of RX FIFO drain while loop */
|
||||
}
|
||||
/* Optimized for bits/frame less than or equal to one byte. */
|
||||
/* Optimized for bits/frame less than or equal to one byte. */
|
||||
else
|
||||
{
|
||||
while ((uint32_t)kDSPI_RxFifoDrainRequestFlag ==
|
||||
|
@ -1785,7 +1783,7 @@ status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *hand
|
|||
|
||||
uint8_t whichCtar = (uint8_t)((transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT);
|
||||
handle->bitsPerFrame =
|
||||
(((base->CTAR_SLAVE[whichCtar]) & SPI_CTAR_SLAVE_FMSZ_MASK) >> SPI_CTAR_SLAVE_FMSZ_SHIFT) + 1U;
|
||||
(((base->CTAR_SLAVE[whichCtar]) & SPI_CTAR_SLAVE_FMSZ_MASK) >> SPI_CTAR_SLAVE_FMSZ_SHIFT) + 1U;
|
||||
|
||||
DSPI_StopTransfer(base);
|
||||
|
||||
|
@ -1851,7 +1849,7 @@ static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *
|
|||
assert(NULL != handle);
|
||||
|
||||
uint16_t transmitData = 0;
|
||||
uint8_t dummyPattern = DSPI_GetDummyDataInstance(base);
|
||||
uint16_t dummyPattern = DSPI_GetDummyDataInstance(base);
|
||||
|
||||
/* Service the transmitter, if transmit buffer provided, transmit the data,
|
||||
* else transmit dummy pattern
|
||||
|
@ -1879,7 +1877,7 @@ static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *
|
|||
/* Decrease remaining dataSize */
|
||||
--handle->remainingSendByteCount;
|
||||
}
|
||||
/* bits/frame is 2 bytes */
|
||||
/* bits/frame is 2 bytes */
|
||||
else
|
||||
{
|
||||
/* With multibytes per frame transmission, the transmit frame contains data from
|
||||
|
@ -1940,8 +1938,8 @@ static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *hand
|
|||
|
||||
/* Disable interrupt requests */
|
||||
DSPI_DisableInterrupts(
|
||||
base, ((uint32_t)kDSPI_TxFifoUnderflowInterruptEnable | (uint32_t)kDSPI_TxFifoFillRequestInterruptEnable |
|
||||
(uint32_t)kDSPI_RxFifoOverflowInterruptEnable | (uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable));
|
||||
base, ((uint32_t)kDSPI_TxFifoUnderflowInterruptEnable | (uint32_t)kDSPI_TxFifoFillRequestInterruptEnable |
|
||||
(uint32_t)kDSPI_RxFifoOverflowInterruptEnable | (uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable));
|
||||
|
||||
/* The transfer is complete. */
|
||||
handle->txData = NULL;
|
||||
|
@ -1949,7 +1947,7 @@ static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *hand
|
|||
handle->remainingReceiveByteCount = 0;
|
||||
handle->remainingSendByteCount = 0;
|
||||
|
||||
status_t status = 0;
|
||||
status_t status;
|
||||
if (handle->state == (uint8_t)kDSPI_Error)
|
||||
{
|
||||
status = kStatus_DSPI_Error;
|
||||
|
@ -1983,8 +1981,8 @@ void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle)
|
|||
|
||||
/* Disable interrupt requests */
|
||||
DSPI_DisableInterrupts(
|
||||
base, ((uint32_t)kDSPI_TxFifoUnderflowInterruptEnable | (uint32_t)kDSPI_TxFifoFillRequestInterruptEnable |
|
||||
(uint32_t)kDSPI_RxFifoOverflowInterruptEnable | (uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable));
|
||||
base, ((uint32_t)kDSPI_TxFifoUnderflowInterruptEnable | (uint32_t)kDSPI_TxFifoFillRequestInterruptEnable |
|
||||
(uint32_t)kDSPI_RxFifoOverflowInterruptEnable | (uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable));
|
||||
|
||||
handle->state = (uint8_t)kDSPI_Idle;
|
||||
handle->remainingSendByteCount = 0;
|
||||
|
@ -2003,7 +2001,7 @@ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle)
|
|||
{
|
||||
assert(NULL != handle);
|
||||
|
||||
uint8_t dummyPattern = DSPI_GetDummyDataInstance(base);
|
||||
uint16_t dummyPattern = DSPI_GetDummyDataInstance(base);
|
||||
uint32_t dataReceived;
|
||||
uint32_t dataSend = 0;
|
||||
uint32_t tmpRemainingReceiveByteCount = 0;
|
||||
|
@ -2079,7 +2077,7 @@ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle)
|
|||
handle->remainingReceiveByteCount -= 2U;
|
||||
}
|
||||
}
|
||||
/* If no handle->rxData*/
|
||||
/* If no handle->rxData*/
|
||||
else
|
||||
{
|
||||
if (handle->remainingReceiveByteCount == 1U)
|
||||
|
@ -2112,7 +2110,7 @@ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle)
|
|||
handle->remainingSendByteCount -= 2U;
|
||||
}
|
||||
}
|
||||
/* If no handle->txData*/
|
||||
/* If no handle->txData*/
|
||||
else
|
||||
{
|
||||
if (handle->remainingSendByteCount == 1U)
|
||||
|
@ -2156,7 +2154,7 @@ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle)
|
|||
/* Change state to error and clear flag */
|
||||
if (NULL != handle->txData)
|
||||
{
|
||||
handle->state = kDSPI_Error;
|
||||
handle->state = (uint8_t)kDSPI_Error;
|
||||
}
|
||||
handle->errorCount++;
|
||||
}
|
||||
|
@ -2171,7 +2169,7 @@ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle)
|
|||
/* Change state to error and clear flag */
|
||||
if (NULL != handle->txData)
|
||||
{
|
||||
handle->state = kDSPI_Error;
|
||||
handle->state = (uint8_t)kDSPI_Error;
|
||||
}
|
||||
handle->errorCount++;
|
||||
}
|
||||
|
@ -2188,14 +2186,11 @@ static void DSPI_CommonIRQHandler(SPI_Type *base, void *param)
|
|||
{
|
||||
s_dspiSlaveIsr(base, (dspi_slave_handle_t *)param);
|
||||
}
|
||||
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
|
||||
exception return operation might vector to incorrect interrupt */
|
||||
#if defined __CORTEX_M && (__CORTEX_M == 4U)
|
||||
__DSB();
|
||||
#endif
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
|
||||
#if defined(SPI0)
|
||||
void SPI0_DriverIRQHandler(void);
|
||||
void SPI0_DriverIRQHandler(void)
|
||||
{
|
||||
assert(NULL != g_dspiHandle[0]);
|
||||
|
@ -2204,6 +2199,7 @@ void SPI0_DriverIRQHandler(void)
|
|||
#endif
|
||||
|
||||
#if defined(SPI1)
|
||||
void SPI1_DriverIRQHandler(void);
|
||||
void SPI1_DriverIRQHandler(void)
|
||||
{
|
||||
assert(NULL != g_dspiHandle[1]);
|
||||
|
@ -2212,6 +2208,7 @@ void SPI1_DriverIRQHandler(void)
|
|||
#endif
|
||||
|
||||
#if defined(SPI2)
|
||||
void SPI2_DriverIRQHandler(void);
|
||||
void SPI2_DriverIRQHandler(void)
|
||||
{
|
||||
assert(NULL != g_dspiHandle[2]);
|
||||
|
@ -2220,6 +2217,7 @@ void SPI2_DriverIRQHandler(void)
|
|||
#endif
|
||||
|
||||
#if defined(SPI3)
|
||||
void SPI3_DriverIRQHandler(void);
|
||||
void SPI3_DriverIRQHandler(void)
|
||||
{
|
||||
assert(NULL != g_dspiHandle[3]);
|
||||
|
@ -2228,6 +2226,7 @@ void SPI3_DriverIRQHandler(void)
|
|||
#endif
|
||||
|
||||
#if defined(SPI4)
|
||||
void SPI4_DriverIRQHandler(void);
|
||||
void SPI4_DriverIRQHandler(void)
|
||||
{
|
||||
assert(NULL != g_dspiHandle[4]);
|
||||
|
@ -2236,6 +2235,7 @@ void SPI4_DriverIRQHandler(void)
|
|||
#endif
|
||||
|
||||
#if defined(SPI5)
|
||||
void SPI5_DriverIRQHandler(void);
|
||||
void SPI5_DriverIRQHandler(void)
|
||||
{
|
||||
assert(NULL != g_dspiHandle[5]);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2019 NXP
|
||||
* Copyright 2016-2020 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
|
@ -21,8 +21,8 @@
|
|||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief DSPI driver version 2.2.2. */
|
||||
#define FSL_DSPI_DRIVER_VERSION (MAKE_VERSION(2, 2, 2))
|
||||
/*! @brief DSPI driver version 2.2.4. */
|
||||
#define FSL_DSPI_DRIVER_VERSION (MAKE_VERSION(2, 2, 4))
|
||||
/*@}*/
|
||||
|
||||
#ifndef DSPI_DUMMY_DATA
|
||||
|
@ -30,8 +30,11 @@
|
|||
#define DSPI_DUMMY_DATA (0x00U) /*!< Dummy data used for Tx if there is no txData. */
|
||||
#endif
|
||||
|
||||
/*! @brief Global variable for dummy data value setting. */
|
||||
extern volatile uint16_t g_dspiDummyData[];
|
||||
|
||||
/*! @brief Status for the DSPI driver.*/
|
||||
enum _dspi_status
|
||||
enum
|
||||
{
|
||||
kStatus_DSPI_Busy = MAKE_STATUS(kStatusGroup_DSPI, 0), /*!< DSPI transfer is busy.*/
|
||||
kStatus_DSPI_Error = MAKE_STATUS(kStatusGroup_DSPI, 1), /*!< DSPI driver error. */
|
||||
|
@ -50,7 +53,7 @@ enum _dspi_flags
|
|||
kDSPI_RxFifoDrainRequestFlag = SPI_SR_RFDF_MASK, /*!< Receive FIFO Drain Flag.*/
|
||||
kDSPI_TxAndRxStatusFlag = SPI_SR_TXRXS_MASK, /*!< The module is in Stopped/Running state.*/
|
||||
kDSPI_AllStatusFlag = (int)(SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK |
|
||||
SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK | SPI_SR_TXRXS_MASK) /*!< All statuses above.*/
|
||||
SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK | SPI_SR_TXRXS_MASK) /*!< All statuses above.*/
|
||||
};
|
||||
|
||||
/*! @brief DSPI interrupt source.*/
|
||||
|
@ -85,8 +88,7 @@ typedef enum _dspi_master_slave_mode
|
|||
|
||||
/*!
|
||||
* @brief DSPI Sample Point: Controls when the DSPI master samples SIN in the Modified Transfer Format. This field is
|
||||
* valid
|
||||
* only when the CPHA bit in the CTAR register is 0.
|
||||
* valid only when the CPHA bit in the CTAR register is 0.
|
||||
*/
|
||||
typedef enum _dspi_master_sample_point
|
||||
{
|
||||
|
@ -171,10 +173,10 @@ typedef enum _dspi_ctar_selection
|
|||
kDSPI_Ctar7 = 7U /*!< CTAR7 selection option for master mode only; note that some devices do not support CTAR7. */
|
||||
} dspi_ctar_selection_t;
|
||||
|
||||
#define DSPI_MASTER_CTAR_SHIFT (0U) /*!< DSPI master CTAR shift macro; used internally. */
|
||||
#define DSPI_MASTER_CTAR_MASK (0x0FU) /*!< DSPI master CTAR mask macro; used internally. */
|
||||
#define DSPI_MASTER_PCS_SHIFT (4U) /*!< DSPI master PCS shift macro; used internally. */
|
||||
#define DSPI_MASTER_PCS_MASK (0xF0U) /*!< DSPI master PCS mask macro; used internally. */
|
||||
#define DSPI_MASTER_CTAR_SHIFT (0U) /*!< DSPI master CTAR shift macro; used internally. */
|
||||
#define DSPI_MASTER_CTAR_MASK (0x0FU) /*!< DSPI master CTAR mask macro; used internally. */
|
||||
#define DSPI_MASTER_PCS_SHIFT (4U) /*!< DSPI master PCS shift macro; used internally. */
|
||||
#define DSPI_MASTER_PCS_MASK (0xF0U) /*!< DSPI master PCS mask macro; used internally. */
|
||||
/*! @brief Use this enumeration for the DSPI master transfer configFlags. */
|
||||
enum _dspi_transfer_config_flag_for_master
|
||||
{
|
||||
|
@ -194,18 +196,18 @@ enum _dspi_transfer_config_flag_for_master
|
|||
kDSPI_MasterPcs4 = 4U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS4 signal. */
|
||||
kDSPI_MasterPcs5 = 5U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS5 signal. */
|
||||
|
||||
kDSPI_MasterPcsContinuous = 1U << 20, /*!< Indicates whether the PCS signal is continuous. */
|
||||
kDSPI_MasterActiveAfterTransfer =
|
||||
1U << 21, /*!< Indicates whether the PCS signal is active after the last frame transfer.*/
|
||||
kDSPI_MasterPcsContinuous = 1U << 20, /*!< Indicates whether the PCS signal is continuous. */
|
||||
kDSPI_MasterActiveAfterTransfer = 1U << 21,
|
||||
/*!< Indicates whether the PCS signal is active after the last frame transfer.*/
|
||||
};
|
||||
|
||||
#define DSPI_SLAVE_CTAR_SHIFT (0U) /*!< DSPI slave CTAR shift macro; used internally. */
|
||||
#define DSPI_SLAVE_CTAR_MASK (0x07U) /*!< DSPI slave CTAR mask macro; used internally. */
|
||||
#define DSPI_SLAVE_CTAR_SHIFT (0U) /*!< DSPI slave CTAR shift macro; used internally. */
|
||||
#define DSPI_SLAVE_CTAR_MASK (0x07U) /*!< DSPI slave CTAR mask macro; used internally. */
|
||||
/*! @brief Use this enumeration for the DSPI slave transfer configFlags. */
|
||||
enum _dspi_transfer_config_flag_for_slave
|
||||
{
|
||||
kDSPI_SlaveCtar0 = 0U << DSPI_SLAVE_CTAR_SHIFT, /*!< DSPI slave transfer use CTAR0 setting. */
|
||||
/*!< DSPI slave can only use PCS0. */
|
||||
kDSPI_SlaveCtar0 = 0U << DSPI_SLAVE_CTAR_SHIFT, /*!< DSPI slave transfer use CTAR0 setting.
|
||||
DSPI slave can only use PCS0. */
|
||||
};
|
||||
|
||||
/*! @brief DSPI transfer state, which is used for DSPI transactional API state machine. */
|
||||
|
@ -219,12 +221,12 @@ enum _dspi_transfer_state
|
|||
/*! @brief DSPI master command date configuration used for the SPIx_PUSHR.*/
|
||||
typedef struct _dspi_command_data_config
|
||||
{
|
||||
bool isPcsContinuous; /*!< Option to enable the continuous assertion of the chip select between transfers.*/
|
||||
dspi_ctar_selection_t whichCtar; /*!< The desired Clock and Transfer Attributes
|
||||
Register (CTAR) to use for CTAS.*/
|
||||
dspi_which_pcs_t whichPcs; /*!< The desired PCS signal to use for the data transfer.*/
|
||||
bool isEndOfQueue; /*!< Signals that the current transfer is the last in the queue.*/
|
||||
bool clearTransferCount; /*!< Clears the SPI Transfer Counter (SPI_TCNT) before transmission starts.*/
|
||||
bool isPcsContinuous; /*!< Option to enable the continuous assertion of the chip select between transfers.*/
|
||||
uint8_t whichCtar; /*!< The desired Clock and Transfer Attributes
|
||||
Register (CTAR) to use for CTAS.*/
|
||||
uint8_t whichPcs; /*!< The desired PCS signal to use for the data transfer.*/
|
||||
bool isEndOfQueue; /*!< Signals that the current transfer is the last in the queue.*/
|
||||
bool clearTransferCount; /*!< Clears the SPI Transfer Counter (SPI_TCNT) before transmission starts.*/
|
||||
} dspi_command_data_config_t;
|
||||
|
||||
/*! @brief DSPI master ctar configuration structure.*/
|
||||
|
@ -241,8 +243,9 @@ typedef struct _dspi_master_ctar_config
|
|||
uint32_t lastSckToPcsDelayInNanoSec; /*!< The last SCK to PCS delay time in nanoseconds; setting to 0 sets the
|
||||
minimum delay. It also sets the boundary value if out of range.*/
|
||||
|
||||
uint32_t betweenTransferDelayInNanoSec; /*!< After the SCK delay time in nanoseconds; setting to 0 sets the minimum
|
||||
delay. It also sets the boundary value if out of range.*/
|
||||
uint32_t betweenTransferDelayInNanoSec;
|
||||
/*!< After the SCK delay time in nanoseconds; setting to 0 sets the minimum
|
||||
delay. It also sets the boundary value if out of range.*/
|
||||
} dspi_master_ctar_config_t;
|
||||
|
||||
/*! @brief DSPI master configuration structure.*/
|
||||
|
@ -272,7 +275,7 @@ typedef struct _dspi_slave_ctar_config
|
|||
uint32_t bitsPerFrame; /*!< Bits per frame, minimum 4, maximum 16.*/
|
||||
dspi_clock_polarity_t cpol; /*!< Clock polarity. */
|
||||
dspi_clock_phase_t cpha; /*!< Clock phase. */
|
||||
/*!< Slave only supports MSB and does not support LSB.*/
|
||||
/*!< Slave only supports MSB and does not support LSB.*/
|
||||
} dspi_slave_ctar_config_t;
|
||||
|
||||
/*! @brief DSPI slave configuration structure.*/
|
||||
|
@ -293,14 +296,14 @@ typedef struct _dspi_slave_config
|
|||
} dspi_slave_config_t;
|
||||
|
||||
/*!
|
||||
* @brief Forward declaration of the _dspi_master_handle typedefs.
|
||||
* @brief Forward declaration of the @ref _dspi_master_handle typedefs.
|
||||
*/
|
||||
typedef struct _dspi_master_handle dspi_master_handle_t;
|
||||
typedef struct _dspi_master_handle dspi_master_handle_t; /*!< The master handle. */
|
||||
|
||||
/*!
|
||||
* @brief Forward declaration of the _dspi_slave_handle typedefs.
|
||||
* @brief Forward declaration of the @ref _dspi_slave_handle typedefs.
|
||||
*/
|
||||
typedef struct _dspi_slave_handle dspi_slave_handle_t;
|
||||
typedef struct _dspi_slave_handle dspi_slave_handle_t; /*!< The slave handle. */
|
||||
|
||||
/*!
|
||||
* @brief Completion callback function pointer type.
|
||||
|
@ -334,21 +337,21 @@ typedef struct _dspi_transfer
|
|||
uint8_t *rxData; /*!< Receive buffer. */
|
||||
volatile size_t dataSize; /*!< Transfer bytes. */
|
||||
|
||||
uint32_t configFlags; /*!< Transfer transfer configuration flags; set from _dspi_transfer_config_flag_for_master if
|
||||
the transfer is used for master or _dspi_transfer_config_flag_for_slave enumeration if the
|
||||
transfer is used for slave.*/
|
||||
uint32_t configFlags; /*!< Transfer transfer configuration flags. Set from @ref
|
||||
_dspi_transfer_config_flag_for_master if the transfer is used for master or @ref
|
||||
_dspi_transfer_config_flag_for_slave enumeration if the transfer is used for slave.*/
|
||||
} dspi_transfer_t;
|
||||
|
||||
/*! @brief DSPI half-duplex(master) transfer structure */
|
||||
typedef struct _dspi_half_duplex_transfer
|
||||
{
|
||||
uint8_t *txData; /*!< Send buffer */
|
||||
uint8_t *rxData; /*!< Receive buffer */
|
||||
size_t txDataSize; /*!< Transfer bytes for transmit */
|
||||
size_t rxDataSize; /*!< Transfer bytes */
|
||||
uint32_t configFlags; /*!< Transfer configuration flags; set from _dspi_transfer_config_flag_for_master. */
|
||||
uint8_t *txData; /*!< Send buffer */
|
||||
uint8_t *rxData; /*!< Receive buffer */
|
||||
size_t txDataSize; /*!< Transfer bytes for transmit */
|
||||
size_t rxDataSize; /*!< Transfer bytes */
|
||||
uint32_t configFlags; /*!< Transfer configuration flags; set from @ref _dspi_transfer_config_flag_for_master. */
|
||||
bool isPcsAssertInTransfer; /*!< If Pcs pin keep assert between transmit and receive. true for assert and false for
|
||||
deassert. */
|
||||
de-assert. */
|
||||
bool isTransmitFirst; /*!< True for transmit first and false for receive first. */
|
||||
} dspi_half_duplex_transfer_t;
|
||||
|
||||
|
@ -362,7 +365,7 @@ struct _dspi_master_handle
|
|||
uint8_t fifoSize; /*!< FIFO dataSize. */
|
||||
|
||||
volatile bool
|
||||
isPcsActiveAfterTransfer; /*!< Indicates whether the PCS signal is active after the last frame transfer.*/
|
||||
isPcsActiveAfterTransfer; /*!< Indicates whether the PCS signal is active after the last frame transfer.*/
|
||||
volatile bool isThereExtraByte; /*!< Indicates whether there are extra bytes.*/
|
||||
|
||||
uint8_t *volatile txData; /*!< Send buffer. */
|
||||
|
@ -371,7 +374,7 @@ struct _dspi_master_handle
|
|||
volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/
|
||||
size_t totalByteCount; /*!< A number of transfer bytes*/
|
||||
|
||||
volatile uint8_t state; /*!< DSPI transfer state, see _dspi_transfer_state.*/
|
||||
volatile uint8_t state; /*!< DSPI transfer state, see @ref _dspi_transfer_state.*/
|
||||
|
||||
dspi_master_transfer_callback_t callback; /*!< Completion callback. */
|
||||
void *userData; /*!< Callback user data. */
|
||||
|
@ -434,13 +437,13 @@ extern "C" {
|
|||
* @endcode
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param masterConfig Pointer to the structure dspi_master_config_t.
|
||||
* @param masterConfig Pointer to the structure @ref dspi_master_config_t.
|
||||
* @param srcClock_Hz Module source input clock in Hertz.
|
||||
*/
|
||||
void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz);
|
||||
|
||||
/*!
|
||||
* @brief Sets the dspi_master_config_t structure to default values.
|
||||
* @brief Sets the @ref dspi_master_config_t structure to default values.
|
||||
*
|
||||
* The purpose of this API is to get the configuration structure initialized for the DSPI_MasterInit().
|
||||
* Users may use the initialized structure unchanged in the DSPI_MasterInit() or modify the structure
|
||||
|
@ -450,7 +453,7 @@ void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, u
|
|||
* dspi_master_config_t masterConfig;
|
||||
* DSPI_MasterGetDefaultConfig(&masterConfig);
|
||||
* @endcode
|
||||
* @param masterConfig pointer to dspi_master_config_t structure
|
||||
* @param masterConfig pointer to @ref dspi_master_config_t structure
|
||||
*/
|
||||
void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig);
|
||||
|
||||
|
@ -472,12 +475,12 @@ void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig);
|
|||
* @endcode
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param slaveConfig Pointer to the structure dspi_master_config_t.
|
||||
* @param slaveConfig Pointer to the structure @ref dspi_master_config_t.
|
||||
*/
|
||||
void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig);
|
||||
|
||||
/*!
|
||||
* @brief Sets the dspi_slave_config_t structure to a default value.
|
||||
* @brief Sets the @ref dspi_slave_config_t structure to a default value.
|
||||
*
|
||||
* The purpose of this API is to get the configuration structure initialized for the DSPI_SlaveInit().
|
||||
* Users may use the initialized structure unchanged in the DSPI_SlaveInit() or modify the structure
|
||||
|
@ -487,7 +490,7 @@ void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig);
|
|||
* dspi_slave_config_t slaveConfig;
|
||||
* DSPI_SlaveGetDefaultConfig(&slaveConfig);
|
||||
* @endcode
|
||||
* @param slaveConfig Pointer to the dspi_slave_config_t structure.
|
||||
* @param slaveConfig Pointer to the @ref dspi_slave_config_t structure.
|
||||
*/
|
||||
void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig);
|
||||
|
||||
|
@ -538,9 +541,8 @@ static inline uint32_t DSPI_GetStatusFlags(SPI_Type *base)
|
|||
* @brief Clears the DSPI status flag.
|
||||
*
|
||||
* This function clears the desired status bit by using a write-1-to-clear. The user passes in the base and the
|
||||
* desired status bit to clear. The list of status bits is defined in the dspi_status_and_interrupt_request_t. The
|
||||
* function uses these bit positions in its algorithm to clear the desired flag state.
|
||||
* This is an example.
|
||||
* desired status bit to clear. The list of status bits is defined in the <b>dspi_status_and_interrupt_request_t</b>.
|
||||
* The function uses these bit positions in its algorithm to clear the desired flag state. This is an example.
|
||||
* @code
|
||||
* DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag|kDSPI_EndOfQueueFlag);
|
||||
* @endcode
|
||||
|
@ -565,8 +567,8 @@ static inline void DSPI_ClearStatusFlags(SPI_Type *base, uint32_t statusFlags)
|
|||
/*!
|
||||
* @brief Enables the DSPI interrupts.
|
||||
*
|
||||
* This function configures the various interrupt masks of the DSPI. The parameters are a base and an interrupt mask.
|
||||
* Note, for Tx Fill and Rx FIFO drain requests, enable the interrupt request and disable the DMA request.
|
||||
* This function configures various interrupt masks of the DSPI. The parameters are a base and an interrupt mask.
|
||||
* @note For Tx Fill and Rx FIFO drain requests, enable the interrupt request and disable the DMA request.
|
||||
* Do not use this API(write to RSER register) while DSPI is in running state.
|
||||
*
|
||||
* @code
|
||||
|
@ -574,7 +576,7 @@ static inline void DSPI_ClearStatusFlags(SPI_Type *base, uint32_t statusFlags)
|
|||
* @endcode
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param mask The interrupt mask; use the enum _dspi_interrupt_enable.
|
||||
* @param mask The interrupt mask; use the enum @ref _dspi_interrupt_enable.
|
||||
*/
|
||||
void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask);
|
||||
|
||||
|
@ -586,7 +588,7 @@ void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask);
|
|||
* @endcode
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param mask The interrupt mask; use the enum _dspi_interrupt_enable.
|
||||
* @param mask The interrupt mask; use the enum @ref _dspi_interrupt_enable.
|
||||
*/
|
||||
static inline void DSPI_DisableInterrupts(SPI_Type *base, uint32_t mask)
|
||||
{
|
||||
|
@ -611,7 +613,7 @@ static inline void DSPI_DisableInterrupts(SPI_Type *base, uint32_t mask)
|
|||
* @endcode
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param mask The interrupt mask; use the enum dspi_dma_enable.
|
||||
* @param mask The interrupt mask; use the enum @ref _dspi_dma_enable.
|
||||
*/
|
||||
static inline void DSPI_EnableDMA(SPI_Type *base, uint32_t mask)
|
||||
{
|
||||
|
@ -627,7 +629,7 @@ static inline void DSPI_EnableDMA(SPI_Type *base, uint32_t mask)
|
|||
* @endcode
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param mask The interrupt mask; use the enum dspi_dma_enable.
|
||||
* @param mask The interrupt mask; use the enum @ref _dspi_dma_enable.
|
||||
*/
|
||||
static inline void DSPI_DisableDMA(SPI_Type *base, uint32_t mask)
|
||||
{
|
||||
|
@ -692,7 +694,7 @@ uint32_t DSPI_GetInstance(SPI_Type *base);
|
|||
* @brief Configures the DSPI for master or slave.
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param mode Mode setting (master or slave) of type dspi_master_slave_mode_t.
|
||||
* @param mode Mode setting (master or slave) of type @ref dspi_master_slave_mode_t.
|
||||
*/
|
||||
static inline void DSPI_SetMasterSlaveMode(SPI_Type *base, dspi_master_slave_mode_t mode)
|
||||
{
|
||||
|
@ -707,14 +709,12 @@ static inline void DSPI_SetMasterSlaveMode(SPI_Type *base, dspi_master_slave_mod
|
|||
*/
|
||||
static inline bool DSPI_IsMaster(SPI_Type *base)
|
||||
{
|
||||
bool ismaster = false;
|
||||
if (0U != ((base->MCR) & SPI_MCR_MSTR_MASK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
ismaster = true;
|
||||
}
|
||||
return ismaster;
|
||||
}
|
||||
/*!
|
||||
* @brief Starts the DSPI transfers and clears HALT bit in MCR.
|
||||
|
@ -743,7 +743,7 @@ static inline void DSPI_StopTransfer(SPI_Type *base)
|
|||
* @brief Enables or disables the DSPI FIFOs.
|
||||
*
|
||||
* This function allows the caller to disable/enable the Tx and Rx FIFOs independently.
|
||||
* Note that to disable, pass in a logic 0 (false) for the particular FIFO configuration. To enable,
|
||||
* @note To disable, pass in a logic 0 (false) for the particular FIFO configuration. To enable,
|
||||
* pass in a logic 1 (true).
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
|
@ -777,7 +777,7 @@ static inline void DSPI_FlushFifo(SPI_Type *base, bool flushTxFifo, bool flushRx
|
|||
* DSPI_SetAllPcsPolarity(base, kDSPI_Pcs0ActiveLow | kDSPI_Pcs1ActiveLow);
|
||||
@endcode
|
||||
* @param base DSPI peripheral address.
|
||||
* @param mask The PCS polarity mask; use the enum _dspi_pcs_polarity.
|
||||
* @param mask The PCS polarity mask; use the enum @ref _dspi_pcs_polarity.
|
||||
*/
|
||||
static inline void DSPI_SetAllPcsPolarity(SPI_Type *base, uint32_t mask)
|
||||
{
|
||||
|
@ -792,7 +792,7 @@ static inline void DSPI_SetAllPcsPolarity(SPI_Type *base, uint32_t mask)
|
|||
* caller also provide the frequency of the module source clock (in Hertz).
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of the type dspi_ctar_selection_t
|
||||
* @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of the type @ref dspi_ctar_selection_t
|
||||
* @param baudRate_Bps The desired baud rate in bits per second
|
||||
* @param srcClock_Hz Module source input clock in Hertz
|
||||
* @return The actual calculated baud rate
|
||||
|
@ -808,20 +808,20 @@ uint32_t DSPI_MasterSetBaudRate(SPI_Type *base,
|
|||
* This function configures the PCS to SCK delay pre-scalar (PcsSCK) and scalar (CSSCK), after SCK delay pre-scalar
|
||||
* (PASC) and scalar (ASC), and the delay after transfer pre-scalar (PDT) and scalar (DT).
|
||||
*
|
||||
* These delay names are available in the type dspi_delay_type_t.
|
||||
* These delay names are available in the type @ref dspi_delay_type_t.
|
||||
*
|
||||
* The user passes the delay to the configuration along with the prescaler and scaler value.
|
||||
* This allows the user to directly set the prescaler/scaler values if pre-calculated or
|
||||
* to manually increment either value.
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type dspi_ctar_selection_t.
|
||||
* @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type @ref dspi_ctar_selection_t.
|
||||
* @param prescaler The prescaler delay value (can be an integer 0, 1, 2, or 3).
|
||||
* @param scaler The scaler delay value (can be any integer between 0 to 15).
|
||||
* @param whichDelay The desired delay to configure; must be of type dspi_delay_type_t
|
||||
* @param whichDelay The desired delay to configure; must be of type @ref dspi_delay_type_t
|
||||
*/
|
||||
void DSPI_MasterSetDelayScaler(
|
||||
SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay);
|
||||
SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay);
|
||||
|
||||
/*!
|
||||
* @brief Calculates the delay prescaler and scaler based on the desired delay input in nanoseconds.
|
||||
|
@ -831,7 +831,7 @@ void DSPI_MasterSetDelayScaler(
|
|||
* After SCK delay pre-scalar (PASC) and scalar (ASC), or
|
||||
* Delay after transfer pre-scalar (PDT) and scalar (DT).
|
||||
*
|
||||
* These delay names are available in the type dspi_delay_type_t.
|
||||
* These delay names are available in the type @ref dspi_delay_type_t.
|
||||
*
|
||||
* The user passes which delay to configure along with the desired delay value in nanoseconds. The function
|
||||
* calculates the values needed for the prescaler and scaler. Note that returning the calculated delay as an exact
|
||||
|
@ -842,8 +842,8 @@ void DSPI_MasterSetDelayScaler(
|
|||
* input.
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type dspi_ctar_selection_t.
|
||||
* @param whichDelay The desired delay to configure, must be of type dspi_delay_type_t
|
||||
* @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type @ref dspi_ctar_selection_t.
|
||||
* @param whichDelay The desired delay to configure, must be of type @ref dspi_delay_type_t
|
||||
* @param srcClock_Hz Module source input clock in Hertz
|
||||
* @param delayTimeInNanoSec The desired delay value in nanoseconds.
|
||||
* @return The actual calculated delay value.
|
||||
|
@ -885,17 +885,16 @@ static inline void DSPI_MasterWriteData(SPI_Type *base, dspi_command_data_config
|
|||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the dspi_command_data_config_t structure to default values.
|
||||
* @brief Sets the @ref dspi_command_data_config_t structure to default values.
|
||||
*
|
||||
* The purpose of this API is to get the configuration structure initialized for use in the DSPI_MasterWrite_xx().
|
||||
* Users may use the initialized structure unchanged in the DSPI_MasterWrite_xx() or modify the structure
|
||||
* before calling the DSPI_MasterWrite_xx().
|
||||
* This is an example.
|
||||
* The purpose of this API is to get the configuration structure initialized for use in the
|
||||
* <b>DSPI_MasterWrite_xx()</b>. Users may use the initialized structure unchanged in the DSPI_MasterWrite_xx() or
|
||||
* modify the structure before calling the DSPI_MasterWrite_xx(). This is an example.
|
||||
* @code
|
||||
* dspi_command_data_config_t command;
|
||||
* DSPI_GetDefaultDataCommandConfig(&command);
|
||||
* @endcode
|
||||
* @param command Pointer to the dspi_command_data_config_t structure.
|
||||
* @param command Pointer to the @ref dspi_command_data_config_t structure.
|
||||
*/
|
||||
void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command);
|
||||
|
||||
|
@ -918,7 +917,7 @@ void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command);
|
|||
* DSPI_MasterWriteDataBlocking(base, &commandConfig, dataWord);
|
||||
* @endcode
|
||||
*
|
||||
* Note that this function does not return until after the transmit is complete. Also note that the DSPI must be
|
||||
* @note This function does not return until after the transmit is complete. Also note that the DSPI must be
|
||||
* enabled and running to transmit data (MCR[MDIS] & [HALT] = 0). Because the SPI is a synchronous protocol,
|
||||
* the received data is available when the transmit completes.
|
||||
*
|
||||
|
@ -933,13 +932,13 @@ void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *co
|
|||
*
|
||||
* This function allows the caller to pass in the data command structure and returns the command word formatted
|
||||
* according to the DSPI PUSHR register bit field placement. The user can then "OR" the returned command word with the
|
||||
* desired data to send and use the function DSPI_HAL_WriteCommandDataMastermode or
|
||||
* DSPI_HAL_WriteCommandDataMastermodeBlocking to write the entire 32-bit command data word to the PUSHR. This helps
|
||||
* improve performance in cases where the command structure is constant. For example, the user calls this function
|
||||
* desired data to send and use the function <b>DSPI_HAL_WriteCommandDataMastermode</b> or
|
||||
* <b>DSPI_HAL_WriteCommandDataMastermodeBlocking</b> to write the entire 32-bit command data word to the PUSHR. This
|
||||
* helps improve performance in cases where the command structure is constant. For example, the user calls this function
|
||||
* before starting a transfer to generate the command word. When they are ready to transmit the data, they OR
|
||||
* this formatted command word with the desired data to transmit. This process increases transmit performance when
|
||||
* compared to calling send functions, such as DSPI_HAL_WriteDataMastermode, which format the command word each time a
|
||||
* data word is to be sent.
|
||||
* compared to calling send functions, such as <b>DSPI_HAL_WriteDataMastermode</b>, which format the command word each
|
||||
* time a data word is to be sent.
|
||||
*
|
||||
* @param command Pointer to the command structure.
|
||||
* @return The command word formatted to the PUSHR data register bit field.
|
||||
|
@ -970,25 +969,29 @@ static inline uint32_t DSPI_MasterGetFormattedCommand(dspi_command_data_config_t
|
|||
* DSPI_MasterWriteCommandDataBlocking(base, dataWord);
|
||||
* @endcode
|
||||
*
|
||||
* Note that this function does not return until after the transmit is complete. Also note that the DSPI must be
|
||||
* @note This function does not return until after the transmit is complete. Also note that the DSPI must be
|
||||
* enabled and running to transmit data (MCR[MDIS] & [HALT] = 0).
|
||||
* Because the SPI is a synchronous protocol, the received data is available when the transmit completes.
|
||||
*
|
||||
* For a blocking polling transfer, see methods below.
|
||||
* Option 1:
|
||||
* uint32_t command_to_send = DSPI_MasterGetFormattedCommand(&command);
|
||||
* uint32_t data0 = command_to_send | data_need_to_send_0;
|
||||
* uint32_t data1 = command_to_send | data_need_to_send_1;
|
||||
* uint32_t data2 = command_to_send | data_need_to_send_2;
|
||||
* <table>
|
||||
* <tr><th>Option 1
|
||||
* <tr><td>uint32_t command_to_send = DSPI_MasterGetFormattedCommand(&command);
|
||||
* <tr><td>uint32_t data0 = command_to_send | data_need_to_send_0;
|
||||
* <tr><td>uint32_t data1 = command_to_send | data_need_to_send_1;
|
||||
* <tr><td>uint32_t data2 = command_to_send | data_need_to_send_2;
|
||||
* <tr><td>
|
||||
* <tr><td>DSPI_MasterWriteCommandDataBlocking(base,data0);
|
||||
* <tr><td>DSPI_MasterWriteCommandDataBlocking(base,data1);
|
||||
* <tr><td>DSPI_MasterWriteCommandDataBlocking(base,data2);
|
||||
* </table>
|
||||
*
|
||||
* DSPI_MasterWriteCommandDataBlocking(base,data0);
|
||||
* DSPI_MasterWriteCommandDataBlocking(base,data1);
|
||||
* DSPI_MasterWriteCommandDataBlocking(base,data2);
|
||||
*
|
||||
* Option 2:
|
||||
* DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_0);
|
||||
* DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_1);
|
||||
* DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_2);
|
||||
* <table>
|
||||
* <tr><th>Option 2
|
||||
* <tr><td>DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_0);
|
||||
* <tr><td>DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_1);
|
||||
* <tr><td>DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_2);
|
||||
* </table>
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param data The data word (command and data combined) to be sent.
|
||||
|
@ -1035,18 +1038,28 @@ static inline uint32_t DSPI_ReadData(SPI_Type *base)
|
|||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param dummyData Data to be transferred when tx buffer is NULL.
|
||||
*
|
||||
* @note This version of the dummy data setter will construct the upper 8 bits of the dummy data
|
||||
* to be the same as the lower 8 bits.
|
||||
*/
|
||||
void DSPI_SetDummyData(SPI_Type *base, uint8_t dummyData);
|
||||
|
||||
/*!
|
||||
* @brief Set up the dummy data as a 16-bit value.
|
||||
*
|
||||
* @param base DSPI peripheral address.
|
||||
* @param dummyData Data to be transferred when tx buffer is NULL.
|
||||
*/
|
||||
void DSPI_SetDummyData16Bit(SPI_Type *base, uint16_t dummyData);
|
||||
|
||||
/*!
|
||||
*@}
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @name Transactional
|
||||
* @name Transactional APIs
|
||||
* @{
|
||||
*/
|
||||
/*Transactional APIs*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the DSPI master handle.
|
||||
|
@ -1055,7 +1068,7 @@ void DSPI_SetDummyData(SPI_Type *base, uint8_t dummyData);
|
|||
* specified DSPI instance, call this API once to get the initialized handle.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle DSPI handle pointer to dspi_master_handle_t.
|
||||
* @param handle DSPI handle pointer to @ref _dspi_master_handle.
|
||||
* @param callback DSPI callback.
|
||||
* @param userData Callback function parameter.
|
||||
*/
|
||||
|
@ -1071,7 +1084,7 @@ void DSPI_MasterTransferCreateHandle(SPI_Type *base,
|
|||
* have been completed.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param transfer Pointer to the dspi_transfer_t structure.
|
||||
* @param transfer Pointer to the @ref dspi_transfer_t structure.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer);
|
||||
|
@ -1083,8 +1096,8 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer);
|
|||
* data is transferred, the callback function is called.
|
||||
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
|
||||
* @param transfer Pointer to the dspi_transfer_t structure.
|
||||
* @param handle Pointer to the @ref _dspi_master_handle structure which stores the transfer state.
|
||||
* @param transfer Pointer to the @ref dspi_transfer_t structure.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer);
|
||||
|
@ -1097,7 +1110,7 @@ status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *ha
|
|||
* users can set transmit first or receive first.
|
||||
*
|
||||
* @param base DSPI base pointer
|
||||
* @param xfer pointer to dspi_half_duplex_transfer_t structure
|
||||
* @param xfer pointer to @ref dspi_half_duplex_transfer_t structure
|
||||
* @return status of status_t.
|
||||
*/
|
||||
status_t DSPI_MasterHalfDuplexTransferBlocking(SPI_Type *base, dspi_half_duplex_transfer_t *xfer);
|
||||
|
@ -1110,8 +1123,8 @@ status_t DSPI_MasterHalfDuplexTransferBlocking(SPI_Type *base, dspi_half_duplex_
|
|||
* which returns right away. When all data is transferred, the callback function is called.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle pointer to dspi_master_handle_t structure which stores the transfer state
|
||||
* @param xfer pointer to dspi_half_duplex_transfer_t structure
|
||||
* @param handle pointer to @ref _dspi_master_handle structure which stores the transfer state
|
||||
* @param xfer pointer to @ref dspi_half_duplex_transfer_t structure
|
||||
* @return status of status_t.
|
||||
*/
|
||||
status_t DSPI_MasterHalfDuplexTransferNonBlocking(SPI_Type *base,
|
||||
|
@ -1124,7 +1137,7 @@ status_t DSPI_MasterHalfDuplexTransferNonBlocking(SPI_Type *base,
|
|||
* This function gets the master transfer count.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
|
||||
* @param handle Pointer to the @ref _dspi_master_handle structure which stores the transfer state.
|
||||
* @param count The number of bytes transferred by using the non-blocking transaction.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
|
@ -1136,7 +1149,7 @@ status_t DSPI_MasterTransferGetCount(SPI_Type *base, dspi_master_handle_t *handl
|
|||
* This function aborts a transfer using an interrupt.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
|
||||
* @param handle Pointer to the @ref _dspi_master_handle structure which stores the transfer state.
|
||||
*/
|
||||
void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle);
|
||||
|
||||
|
@ -1146,7 +1159,7 @@ void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle);
|
|||
* This function processes the DSPI transmit and receive IRQ.
|
||||
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
|
||||
* @param handle Pointer to the @ref _dspi_master_handle structure which stores the transfer state.
|
||||
*/
|
||||
void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle);
|
||||
|
||||
|
@ -1156,7 +1169,7 @@ void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle);
|
|||
* This function initializes the DSPI handle, which can be used for other DSPI transactional APIs. Usually, for a
|
||||
* specified DSPI instance, call this API once to get the initialized handle.
|
||||
*
|
||||
* @param handle DSPI handle pointer to the dspi_slave_handle_t.
|
||||
* @param handle DSPI handle pointer to the @ref _dspi_slave_handle.
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param callback DSPI callback.
|
||||
* @param userData Callback function parameter.
|
||||
|
@ -1173,8 +1186,8 @@ void DSPI_SlaveTransferCreateHandle(SPI_Type *base,
|
|||
* data is transferred, the callback function is called.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state.
|
||||
* @param transfer Pointer to the dspi_transfer_t structure.
|
||||
* @param handle Pointer to the @ref _dspi_slave_handle structure which stores the transfer state.
|
||||
* @param transfer Pointer to the @ref dspi_transfer_t structure.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer);
|
||||
|
@ -1185,7 +1198,7 @@ status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *hand
|
|||
* This function gets the slave transfer count.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
|
||||
* @param handle Pointer to the @ref _dspi_master_handle structure which stores the transfer state.
|
||||
* @param count The number of bytes transferred by using the non-blocking transaction.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
|
@ -1197,7 +1210,7 @@ status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle,
|
|||
* This function aborts a transfer using an interrupt.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state.
|
||||
* @param handle Pointer to the @ref _dspi_slave_handle structure which stores the transfer state.
|
||||
*/
|
||||
void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle);
|
||||
|
||||
|
@ -1207,7 +1220,7 @@ void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle);
|
|||
* This function processes the DSPI transmit and receive IRQ.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state.
|
||||
* @param handle Pointer to the @ref _dspi_slave_handle structure which stores the transfer state.
|
||||
*/
|
||||
void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle);
|
||||
|
||||
|
@ -1215,11 +1228,11 @@ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle);
|
|||
* brief Dummy data for each instance.
|
||||
*
|
||||
* The purpose of this API is to avoid MISRA rule8.5 : Multiple declarations of
|
||||
* externally-linked object or function g_dspiDummyData.
|
||||
* externally-linked object or function @ref g_dspiDummyData.
|
||||
*
|
||||
* param base DSPI peripheral base address.
|
||||
*/
|
||||
uint8_t DSPI_GetDummyDataInstance(SPI_Type *base);
|
||||
uint16_t DSPI_GetDummyDataInstance(SPI_Type *base);
|
||||
|
||||
/*!
|
||||
*@}
|
||||
|
@ -1228,8 +1241,8 @@ uint8_t DSPI_GetDummyDataInstance(SPI_Type *base);
|
|||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /*_cplusplus*/
|
||||
/*!
|
||||
*@}
|
||||
*/
|
||||
/*!
|
||||
*@}
|
||||
*/
|
||||
|
||||
#endif /*_FSL_DSPI_H_*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* Copyright 2016-2020 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
|
@ -125,6 +125,10 @@ void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base,
|
|||
* This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
|
||||
* is transferred, the callback function is called.
|
||||
*
|
||||
* note The max transfer size of each transfer depends on whether the instance's Tx/Rx shares the same DMA request. If
|
||||
* FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x) is true, then the max transfer size is 32767 datawidth of data,
|
||||
* otherwise is 511.
|
||||
*
|
||||
* param base DSPI peripheral base address.
|
||||
* param handle A pointer to the dspi_master_edma_handle_t structure which stores the transfer state.
|
||||
* param transfer A pointer to the dspi_transfer_t structure.
|
||||
|
@ -157,7 +161,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
|
|||
|
||||
uint32_t instance = DSPI_GetInstance(base);
|
||||
uint16_t wordToSend = 0;
|
||||
uint8_t dummyData = DSPI_GetDummyDataInstance(base);
|
||||
uint16_t dummyData = DSPI_GetDummyDataInstance(base);
|
||||
uint8_t dataAlreadyFed = 0;
|
||||
uint8_t dataFedMax = 2;
|
||||
uint32_t tmpMCR = 0;
|
||||
|
@ -171,7 +175,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
|
|||
edma_transfer_config_t transferConfigA;
|
||||
edma_transfer_config_t transferConfigB;
|
||||
|
||||
handle->txBuffIfNull = ((uint32_t)dummyData << 8U) | dummyData;
|
||||
handle->txBuffIfNull = dummyData;
|
||||
|
||||
dspi_command_data_config_t commandStruct;
|
||||
DSPI_StopTransfer(base);
|
||||
|
@ -179,18 +183,17 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
|
|||
DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_AllStatusFlag);
|
||||
|
||||
commandStruct.whichPcs =
|
||||
(dspi_which_pcs_t)((uint32_t)1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
|
||||
(uint8_t)((uint32_t)1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
|
||||
commandStruct.isEndOfQueue = false;
|
||||
commandStruct.clearTransferCount = false;
|
||||
commandStruct.whichCtar =
|
||||
(dspi_ctar_selection_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
|
||||
commandStruct.whichCtar = (uint8_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
|
||||
commandStruct.isPcsContinuous =
|
||||
(0U != (transfer->configFlags & (uint32_t)kDSPI_MasterPcsContinuous)) ? true : false;
|
||||
(0U != (transfer->configFlags & (uint32_t)kDSPI_MasterPcsContinuous)) ? true : false;
|
||||
handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct));
|
||||
|
||||
commandStruct.isEndOfQueue = true;
|
||||
commandStruct.isPcsContinuous =
|
||||
(0U != (transfer->configFlags & (uint32_t)kDSPI_MasterActiveAfterTransfer)) ? true : false;
|
||||
(0U != (transfer->configFlags & (uint32_t)kDSPI_MasterActiveAfterTransfer)) ? true : false;
|
||||
handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));
|
||||
|
||||
handle->bitsPerFrame = ((base->CTAR[commandStruct.whichCtar] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1U;
|
||||
|
@ -198,11 +201,11 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
|
|||
tmpMCR = base->MCR;
|
||||
if ((0U != (tmpMCR & SPI_MCR_DIS_RXF_MASK)) || (0U != (tmpMCR & SPI_MCR_DIS_TXF_MASK)))
|
||||
{
|
||||
handle->fifoSize = 1;
|
||||
handle->fifoSize = 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
handle->fifoSize = FSL_FEATURE_DSPI_FIFO_SIZEn(base);
|
||||
handle->fifoSize = (uint8_t)FSL_FEATURE_DSPI_FIFO_SIZEn(base);
|
||||
}
|
||||
handle->txData = transfer->txData;
|
||||
handle->rxData = transfer->rxData;
|
||||
|
@ -213,31 +216,10 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
|
|||
/* 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
|
||||
*/
|
||||
uint32_t limited_size = 0;
|
||||
if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
|
||||
if (transfer->dataSize > DSPI_EDMA_MAX_TRANSFER_SIZE(base, (handle->bitsPerFrame)))
|
||||
{
|
||||
limited_size = 32767u;
|
||||
}
|
||||
else
|
||||
{
|
||||
limited_size = 511u;
|
||||
}
|
||||
|
||||
if (handle->bitsPerFrame > 8U)
|
||||
{
|
||||
if (transfer->dataSize > (limited_size << 1u))
|
||||
{
|
||||
handle->state = (uint8_t)kDSPI_Idle;
|
||||
return kStatus_DSPI_OutOfRange;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (transfer->dataSize > limited_size)
|
||||
{
|
||||
handle->state = (uint8_t)kDSPI_Idle;
|
||||
return kStatus_DSPI_OutOfRange;
|
||||
}
|
||||
handle->state = (uint8_t)kDSPI_Idle;
|
||||
return kStatus_DSPI_OutOfRange;
|
||||
}
|
||||
|
||||
/*The data size should be even if the bitsPerFrame is greater than 8 (that is 2 bytes per frame in dspi) */
|
||||
|
@ -297,7 +279,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
|
|||
}
|
||||
else
|
||||
{
|
||||
wordToSend = (((uint16_t)dummyData << 8U) | (uint16_t)dummyData);
|
||||
wordToSend = dummyData;
|
||||
}
|
||||
handle->lastCommand = (handle->lastCommand & 0xffff0000U) | wordToSend;
|
||||
handle->command = handle->lastCommand;
|
||||
|
@ -313,7 +295,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
|
|||
}
|
||||
else
|
||||
{
|
||||
wordToSend = (((uint16_t)dummyData << 8U) | (uint16_t)dummyData);
|
||||
wordToSend = dummyData;
|
||||
}
|
||||
handle->command = (handle->command & 0xffff0000U) | wordToSend;
|
||||
}
|
||||
|
@ -364,12 +346,12 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
|
|||
}
|
||||
else
|
||||
{
|
||||
wordToSend = (((uint16_t)dummyData << 8U) | (uint16_t)dummyData);
|
||||
wordToSend = dummyData;
|
||||
}
|
||||
handle->remainingSendByteCount = 0;
|
||||
base->PUSHR = (handle->lastCommand & 0xffff0000U) | wordToSend;
|
||||
}
|
||||
/* For all words except the last word */
|
||||
/* For all words except the last word */
|
||||
else
|
||||
{
|
||||
if (NULL != handle->txData)
|
||||
|
@ -381,7 +363,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
|
|||
}
|
||||
else
|
||||
{
|
||||
wordToSend = (((uint16_t)dummyData << 8U) | (uint16_t)dummyData);
|
||||
wordToSend = dummyData;
|
||||
}
|
||||
handle->remainingSendByteCount -= 2U;
|
||||
base->PUSHR = (handle->command & 0xffff0000U) | wordToSend;
|
||||
|
@ -479,6 +461,14 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
|
|||
EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
|
||||
(uint32_t)kEDMA_MajorInterruptEnable);
|
||||
|
||||
if (handle->remainingSendByteCount == 0U)
|
||||
{
|
||||
EDMA_StartTransfer(handle->edmaRxRegToRxDataHandle);
|
||||
DSPI_EnableDMA(base, (uint32_t)kDSPI_RxDmaEnable);
|
||||
DSPI_StartTransfer(base);
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
tmpRemainingSendByteCount = handle->remainingSendByteCount;
|
||||
/*Calculate the last data : handle->lastCommand*/
|
||||
if (((tmpRemainingSendByteCount > 0U) && (1U != (uint8_t)FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))) ||
|
||||
|
@ -523,14 +513,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
|
|||
}
|
||||
else
|
||||
{
|
||||
if (handle->bitsPerFrame <= 8U)
|
||||
{
|
||||
wordToSend = dummyData;
|
||||
}
|
||||
else
|
||||
{
|
||||
wordToSend = (((uint16_t)dummyData << 8U) | (uint16_t)dummyData);
|
||||
}
|
||||
wordToSend = dummyData;
|
||||
handle->lastCommand = (handle->lastCommand & 0xffff0000U) | wordToSend;
|
||||
}
|
||||
}
|
||||
|
@ -1147,7 +1130,11 @@ void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base,
|
|||
* is transferred, the callback function is called.
|
||||
* Note that the slave eDMA transfer doesn't support transfer_size is 1 when the bitsPerFrame is greater
|
||||
* than eight.
|
||||
|
||||
*
|
||||
* note The max transfer size of each transfer depends on whether the instance's Tx/Rx shares the same DMA request. If
|
||||
* FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x) is true, then the max transfer size is 32767 datawidth of data,
|
||||
* otherwise is 511.
|
||||
*
|
||||
* param base DSPI peripheral base address.
|
||||
* param handle A pointer to the dspi_slave_edma_handle_t structure which stores the transfer state.
|
||||
* param transfer A pointer to the dspi_transfer_t structure.
|
||||
|
@ -1181,36 +1168,15 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
|
|||
uint32_t instance = DSPI_GetInstance(base);
|
||||
uint8_t whichCtar = (uint8_t)((transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT);
|
||||
handle->bitsPerFrame =
|
||||
(((base->CTAR_SLAVE[whichCtar]) & SPI_CTAR_SLAVE_FMSZ_MASK) >> SPI_CTAR_SLAVE_FMSZ_SHIFT) + 1U;
|
||||
(((base->CTAR_SLAVE[whichCtar]) & SPI_CTAR_SLAVE_FMSZ_MASK) >> SPI_CTAR_SLAVE_FMSZ_SHIFT) + 1U;
|
||||
|
||||
/* 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
|
||||
*/
|
||||
uint32_t limited_size = 0;
|
||||
if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
|
||||
if (transfer->dataSize > DSPI_EDMA_MAX_TRANSFER_SIZE(base, (handle->bitsPerFrame)))
|
||||
{
|
||||
limited_size = 32767u;
|
||||
}
|
||||
else
|
||||
{
|
||||
limited_size = 511u;
|
||||
}
|
||||
|
||||
if (handle->bitsPerFrame > 8U)
|
||||
{
|
||||
if (transfer->dataSize > (limited_size << 1u))
|
||||
{
|
||||
handle->state = (uint8_t)kDSPI_Idle;
|
||||
return kStatus_DSPI_OutOfRange;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (transfer->dataSize > limited_size)
|
||||
{
|
||||
handle->state = (uint8_t)kDSPI_Idle;
|
||||
return kStatus_DSPI_OutOfRange;
|
||||
}
|
||||
handle->state = (uint8_t)kDSPI_Idle;
|
||||
return kStatus_DSPI_OutOfRange;
|
||||
}
|
||||
|
||||
/*The data size should be even if the bitsPerFrame is greater than 8 (that is 2 bytes per frame in dspi) */
|
||||
|
@ -1230,7 +1196,7 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
|
|||
handle->totalByteCount = transfer->dataSize;
|
||||
|
||||
uint32_t wordToSend = 0;
|
||||
uint8_t dummyData = DSPI_GetDummyDataInstance(base);
|
||||
uint16_t dummyData = DSPI_GetDummyDataInstance(base);
|
||||
uint8_t dataAlreadyFed = 0;
|
||||
uint8_t dataFedMax = 2;
|
||||
|
||||
|
@ -1273,7 +1239,7 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
|
|||
}
|
||||
else
|
||||
{
|
||||
wordToSend = ((uint32_t)dummyData << 8U) | dummyData;
|
||||
wordToSend = dummyData;
|
||||
}
|
||||
handle->remainingSendByteCount -= 2U; /* decrement remainingSendByteCount by 2 */
|
||||
base->PUSHR_SLAVE = wordToSend;
|
||||
|
@ -1384,14 +1350,7 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
|
|||
{
|
||||
transferConfigC.srcAddr = (uint32_t)(&handle->txBuffIfNull);
|
||||
transferConfigC.srcOffset = 0;
|
||||
if (handle->bitsPerFrame <= 8U)
|
||||
{
|
||||
handle->txBuffIfNull = dummyData;
|
||||
}
|
||||
else
|
||||
{
|
||||
handle->txBuffIfNull = ((uint32_t)dummyData << 8U) | dummyData;
|
||||
}
|
||||
handle->txBuffIfNull = dummyData;
|
||||
}
|
||||
|
||||
transferConfigC.srcTransferSize = kEDMA_TransferSize1Bytes;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* Copyright 2016-2020 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
|
@ -21,10 +21,18 @@
|
|||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief DSPI EDMA driver version 2.2.2. */
|
||||
#define FSL_DSPI_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 2, 2))
|
||||
/*! @brief DSPI EDMA driver version 2.2.4 */
|
||||
#define FSL_DSPI_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 2, 4))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief DSPI EDMA max transfer data size calculate
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param width Transfer width
|
||||
*/
|
||||
#define DSPI_EDMA_MAX_TRANSFER_SIZE(base, width) \
|
||||
((1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) ? ((width > 8U) ? 65534U : 32767U) : \
|
||||
((width > 8U) ? 1022U : 511U))
|
||||
|
||||
/*!
|
||||
* @brief Forward declaration of the DSPI eDMA master handle typedefs.
|
||||
*/
|
||||
|
@ -70,10 +78,10 @@ struct _dspi_master_edma_handle
|
|||
uint8_t fifoSize; /*!< FIFO dataSize. */
|
||||
|
||||
volatile bool
|
||||
isPcsActiveAfterTransfer; /*!< Indicates whether the PCS signal keeps active after the last frame transfer.*/
|
||||
isPcsActiveAfterTransfer; /*!< Indicates whether the PCS signal keeps active after the last frame transfer.*/
|
||||
|
||||
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
|
||||
volatile uint8_t state; /*!< DSPI transfer state , _dspi_transfer_state.*/
|
||||
volatile uint8_t state; /*!< DSPI transfer state, see @ref _dspi_transfer_state.*/
|
||||
|
||||
uint8_t *volatile txData; /*!< Send buffer. */
|
||||
uint8_t *volatile rxData; /*!< Receive buffer. */
|
||||
|
@ -127,7 +135,9 @@ struct _dspi_slave_edma_handle
|
|||
extern "C" {
|
||||
#endif /*_cplusplus*/
|
||||
|
||||
/*Transactional APIs*/
|
||||
/*! @name Transactional APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the DSPI master eDMA handle.
|
||||
|
@ -135,14 +145,14 @@ extern "C" {
|
|||
* This function initializes the DSPI eDMA handle which can be used for other DSPI transactional APIs. Usually, for a
|
||||
* specified DSPI instance, call this API once to get the initialized handle.
|
||||
*
|
||||
* Note that DSPI eDMA has separated (RX and TX as two sources) or shared (RX and TX are the same source) DMA request
|
||||
* @note DSPI eDMA has separated (RX and TX as two sources) or shared (RX and TX are the same source) DMA request
|
||||
* source.
|
||||
* (1) For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and
|
||||
* TX DMAMUX source for edmaIntermediaryToTxRegHandle.
|
||||
* (2) For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle.
|
||||
* - For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and
|
||||
* TX DMAMUX source for edmaIntermediaryToTxRegHandle.
|
||||
* - For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle DSPI handle pointer to dspi_master_edma_handle_t.
|
||||
* @param handle DSPI handle pointer to @ref _dspi_master_edma_handle.
|
||||
* @param callback DSPI callback.
|
||||
* @param userData A callback function parameter.
|
||||
* @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
|
||||
|
@ -163,9 +173,13 @@ void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base,
|
|||
* This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
|
||||
* is transferred, the callback function is called.
|
||||
*
|
||||
* @note The max transfer size of each transfer depends on whether the instance's Tx/Rx shares the same DMA request. If
|
||||
* <b>FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x)</b> is true, then the max transfer size is 32767 datawidth of
|
||||
* data, otherwise is 511.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle A pointer to the dspi_master_edma_handle_t structure which stores the transfer state.
|
||||
* @param transfer A pointer to the dspi_transfer_t structure.
|
||||
* @param handle A pointer to the @ref _dspi_master_edma_handle structure which stores the transfer state.
|
||||
* @param transfer A pointer to the @ref dspi_transfer_t structure.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, dspi_transfer_t *transfer);
|
||||
|
@ -177,8 +191,8 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
|
|||
* which returns right away. When all data is transferred, the callback function is called.
|
||||
*
|
||||
* @param base DSPI base pointer
|
||||
* @param handle A pointer to the dspi_master_edma_handle_t structure which stores the transfer state.
|
||||
* @param transfer A pointer to the dspi_half_duplex_transfer_t structure.
|
||||
* @param handle A pointer to the @ref _dspi_master_edma_handle structure which stores the transfer state.
|
||||
* @param xfer A pointer to the @ref dspi_half_duplex_transfer_t structure.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
status_t DSPI_MasterHalfDuplexTransferEDMA(SPI_Type *base,
|
||||
|
@ -191,7 +205,7 @@ status_t DSPI_MasterHalfDuplexTransferEDMA(SPI_Type *base,
|
|||
* This function aborts a transfer which is using eDMA.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle A pointer to the dspi_master_edma_handle_t structure which stores the transfer state.
|
||||
* @param handle A pointer to the @ref _dspi_master_edma_handle structure which stores the transfer state.
|
||||
*/
|
||||
void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle);
|
||||
|
||||
|
@ -201,7 +215,7 @@ void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *han
|
|||
* This function gets the master eDMA transfer count.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle A pointer to the dspi_master_edma_handle_t structure which stores the transfer state.
|
||||
* @param handle A pointer to the @ref _dspi_master_edma_handle structure which stores the transfer state.
|
||||
* @param count A number of bytes transferred by the non-blocking transaction.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
|
@ -213,14 +227,14 @@ status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle
|
|||
* This function initializes the DSPI eDMA handle which can be used for other DSPI transactional APIs. Usually, for a
|
||||
* specified DSPI instance, call this API once to get the initialized handle.
|
||||
*
|
||||
* Note that DSPI eDMA has separated (RN and TX in 2 sources) or shared (RX and TX are the same source) DMA request
|
||||
* @note DSPI eDMA has separated (RN and TX in 2 sources) or shared (RX and TX are the same source) DMA request
|
||||
* source.
|
||||
* (1)For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and
|
||||
* TX DMAMUX source for edmaTxDataToTxRegHandle.
|
||||
* (2)For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle.
|
||||
* - For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and
|
||||
* TX DMAMUX source for edmaTxDataToTxRegHandle.
|
||||
* - For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle DSPI handle pointer to dspi_slave_edma_handle_t.
|
||||
* @param handle DSPI handle pointer to @ref _dspi_slave_edma_handle.
|
||||
* @param callback DSPI callback.
|
||||
* @param userData A callback function parameter.
|
||||
* @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
|
||||
|
@ -240,10 +254,14 @@ void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base,
|
|||
* is transferred, the callback function is called.
|
||||
* Note that the slave eDMA transfer doesn't support transfer_size is 1 when the bitsPerFrame is greater
|
||||
* than eight.
|
||||
|
||||
*
|
||||
* @note The max transfer size of each transfer depends on whether the instance's Tx/Rx shares the same DMA request. If
|
||||
* <b>FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x)</b> is true, then the max transfer size is 32767 datawidth of
|
||||
* data, otherwise is 511.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle A pointer to the dspi_slave_edma_handle_t structure which stores the transfer state.
|
||||
* @param transfer A pointer to the dspi_transfer_t structure.
|
||||
* @param handle A pointer to the @ref _dspi_slave_edma_handle structure which stores the transfer state.
|
||||
* @param transfer A pointer to the @ref dspi_transfer_t structure.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, dspi_transfer_t *transfer);
|
||||
|
@ -254,7 +272,7 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
|
|||
* This function aborts a transfer which is using eDMA.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle A pointer to the dspi_slave_edma_handle_t structure which stores the transfer state.
|
||||
* @param handle A pointer to the @ref _dspi_slave_edma_handle structure which stores the transfer state.
|
||||
*/
|
||||
void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle);
|
||||
|
||||
|
@ -264,17 +282,19 @@ void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handl
|
|||
* This function gets the slave eDMA transfer count.
|
||||
*
|
||||
* @param base DSPI peripheral base address.
|
||||
* @param handle A pointer to the dspi_slave_edma_handle_t structure which stores the transfer state.
|
||||
* @param handle A pointer to the @ref _dspi_slave_edma_handle structure which stores the transfer state.
|
||||
* @param count A number of bytes transferred so far by the non-blocking transaction.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
status_t DSPI_SlaveTransferGetCountEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, size_t *count);
|
||||
|
||||
/*!@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /*_cplusplus*/
|
||||
/*!
|
||||
*@}
|
||||
*/
|
||||
/*!
|
||||
*@}
|
||||
*/
|
||||
|
||||
#endif /*_FSL_DSPI_EDMA_H_*/
|
||||
|
|
|
@ -79,6 +79,7 @@ void spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap)
|
|||
|
||||
/* Set the transfer status to idle */
|
||||
obj->spi.status = kDSPI_Idle;
|
||||
obj->spi.last_set_frequency_hz = 500000; // Match FSL HAL default, though this can really be any value
|
||||
|
||||
obj->spi.spiDmaMasterRx.dmaUsageState = DMA_USAGE_OPPORTUNISTIC;
|
||||
}
|
||||
|
@ -108,6 +109,13 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
|
|||
|
||||
void spi_free(spi_t *obj)
|
||||
{
|
||||
if(obj->spi.spiDmaMasterRx.dmaUsageState == DMA_USAGE_ALLOCATED || obj->spi.spiDmaMasterRx.dmaUsageState == DMA_USAGE_TEMPORARY_ALLOCATED)
|
||||
{
|
||||
dma_channel_free(obj->spi.spiDmaMasterRx.dmaChannel);
|
||||
dma_channel_free(obj->spi.spiDmaMasterTx.dmaChannel);
|
||||
dma_channel_free(obj->spi.spiDmaMasterIntermediary.dmaChannel);
|
||||
}
|
||||
|
||||
DSPI_Deinit(spi_address[obj->spi.instance]);
|
||||
}
|
||||
|
||||
|
@ -136,7 +144,12 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
|
|||
master_config.ctarConfig.cpol = (mode & 0x2) ? kDSPI_ClockPolarityActiveLow : kDSPI_ClockPolarityActiveHigh;
|
||||
master_config.ctarConfig.cpha = (mode & 0x1) ? kDSPI_ClockPhaseSecondEdge : kDSPI_ClockPhaseFirstEdge;
|
||||
master_config.ctarConfig.direction = kDSPI_MsbFirst;
|
||||
master_config.ctarConfig.pcsToSckDelayInNanoSec = 100;
|
||||
master_config.ctarConfig.baudRate = obj->spi.last_set_frequency_hz;
|
||||
|
||||
// Half clock period delay before and after SPI transfer, 1 clock period between transfers
|
||||
master_config.ctarConfig.pcsToSckDelayInNanoSec = 500000000 / obj->spi.last_set_frequency_hz;
|
||||
master_config.ctarConfig.lastSckToPcsDelayInNanoSec = 500000000 / obj->spi.last_set_frequency_hz;
|
||||
master_config.ctarConfig.betweenTransferDelayInNanoSec = 1000000000 / obj->spi.last_set_frequency_hz;
|
||||
|
||||
DSPI_MasterInit(spi_address[obj->spi.instance], &master_config, CLOCK_GetFreq(spi_clocks[obj->spi.instance]));
|
||||
}
|
||||
|
@ -146,8 +159,13 @@ void spi_frequency(spi_t *obj, int hz)
|
|||
{
|
||||
uint32_t busClock = CLOCK_GetFreq(spi_clocks[obj->spi.instance]);
|
||||
DSPI_MasterSetBaudRate(spi_address[obj->spi.instance], kDSPI_Ctar0, (uint32_t)hz, busClock);
|
||||
//Half clock period delay after SPI transfer
|
||||
|
||||
// Half clock period delay before and after SPI transfer, 1 clock period between transfers
|
||||
DSPI_MasterSetDelayTimes(spi_address[obj->spi.instance], kDSPI_Ctar0, kDSPI_LastSckToPcs, busClock, 500000000 / hz);
|
||||
DSPI_MasterSetDelayTimes(spi_address[obj->spi.instance], kDSPI_Ctar0, kDSPI_PcsToSck, busClock, 500000000 / hz);
|
||||
DSPI_MasterSetDelayTimes(spi_address[obj->spi.instance], kDSPI_Ctar0, kDSPI_BetweenTransfer, busClock, 1000000000 / obj->spi.last_set_frequency_hz);
|
||||
|
||||
obj->spi.last_set_frequency_hz = hz;
|
||||
}
|
||||
|
||||
static inline int spi_readable(spi_t *obj)
|
||||
|
@ -162,6 +180,12 @@ int spi_master_write(spi_t *obj, int value)
|
|||
DSPI_GetDefaultDataCommandConfig(&command);
|
||||
command.isEndOfQueue = true;
|
||||
|
||||
// Some other FSL HAL SPI functions (notably, interrupt and DMA based transfers) can leave junk in the FIFO
|
||||
// and/or leave the end of queue flag set, which blocks bytes from being transferred.
|
||||
// Clear that stuff out now, because if we don't, we will hang forever in the SPI write function!
|
||||
DSPI_FlushFifo(spi_address[obj->spi.instance], true, true);
|
||||
DSPI_ClearStatusFlags(spi_address[obj->spi.instance], kDSPI_EndOfQueueFlag);
|
||||
|
||||
DSPI_MasterWriteDataBlocking(spi_address[obj->spi.instance], &command, (uint16_t)value);
|
||||
|
||||
DSPI_ClearStatusFlags(spi_address[obj->spi.instance], kDSPI_TxFifoFillRequestFlag);
|
||||
|
@ -178,9 +202,7 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
|
|||
{
|
||||
int total = (tx_length > rx_length) ? tx_length : rx_length;
|
||||
|
||||
// Default write is done in each and every call, in future can create HAL API instead
|
||||
DSPI_SetDummyData(spi_address[obj->spi.instance], write_fill);
|
||||
|
||||
DSPI_MasterTransferBlocking(spi_address[obj->spi.instance], &(dspi_transfer_t) {
|
||||
.txData = (uint8_t *)tx_buffer,
|
||||
.rxData = (uint8_t *)rx_buffer,
|
||||
|
@ -230,7 +252,13 @@ static int32_t spi_master_transfer_asynch(spi_t *obj)
|
|||
if (obj->spi.spiDmaMasterRx.dmaUsageState == DMA_USAGE_ALLOCATED ||
|
||||
obj->spi.spiDmaMasterRx.dmaUsageState == DMA_USAGE_TEMPORARY_ALLOCATED) {
|
||||
status = DSPI_MasterTransferEDMA(spi_address[obj->spi.instance], &obj->spi.spi_dma_master_handle, &masterXfer);
|
||||
if (status == kStatus_DSPI_OutOfRange) {
|
||||
if (status == kStatus_Success)
|
||||
{
|
||||
/* Save amount of TX done by DMA */
|
||||
obj->tx_buff.pos += masterXfer.dataSize;
|
||||
obj->rx_buff.pos += masterXfer.dataSize;
|
||||
}
|
||||
else if (status == kStatus_DSPI_OutOfRange) {
|
||||
if (obj->spi.bits > 8) {
|
||||
transferSize = 1022;
|
||||
} else {
|
||||
|
@ -411,6 +439,7 @@ uint32_t spi_irq_handler_asynch(spi_t *obj)
|
|||
|
||||
/* Determine whether the current scenario is DMA or IRQ, and act accordingly */
|
||||
if (obj->spi.spiDmaMasterRx.dmaUsageState == DMA_USAGE_ALLOCATED || obj->spi.spiDmaMasterRx.dmaUsageState == DMA_USAGE_TEMPORARY_ALLOCATED) {
|
||||
|
||||
/* DMA implementation */
|
||||
/* Check If there is still data in the TX buffer */
|
||||
if (obj->tx_buff.pos < obj->tx_buff.length) {
|
||||
|
|
|
@ -74,6 +74,7 @@ struct i2c_s {
|
|||
struct spi_s {
|
||||
uint32_t instance;
|
||||
uint8_t bits;
|
||||
uint32_t last_set_frequency_hz; ///< Last frequency passed to spi_frequency()
|
||||
#if DEVICE_SPI_ASYNCH
|
||||
status_t status;
|
||||
dspi_master_handle_t spi_master_handle;
|
||||
|
|
|
@ -5,6 +5,19 @@
|
|||
# Notes:
|
||||
# 1. PyOCD did not actually work in my testing as of Apr 2024, though this device is supposed to be supported
|
||||
# 2. Be sure to update the DAPLink firmware on the board via these instructions: https://os.mbed.com/blog/entry/DAPLink-bootloader-update/
|
||||
# 3. OpenOCD 0.12 flashes this device perfectly and can enter a debug session, but cannot hit breakpoints
|
||||
# 4. LinkServer can both flash and debug, so it's the recommended upload method for this device.
|
||||
# 5. LinkServer does appear to have a bug where it doesn't map the peripheral registers as valid memory, so you can't
|
||||
# inspect them. I was able to work around this by inserting a block like this into <LinkServer install dir>/devices/FRDM-K64F.json:
|
||||
#
|
||||
# "name": "MK64FN1M0xxx12",
|
||||
# "family": "K6x",
|
||||
# "memory": [
|
||||
# + {
|
||||
# + "location": "0x40000000",
|
||||
# + "size": "0x000f0000",
|
||||
# + "type": "RAM"
|
||||
# + },
|
||||
|
||||
# General config parameters
|
||||
# -------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue