| /* |
| * Copyright (c) 2015, Freescale Semiconductor, Inc. |
| * Copyright 2016-2017 NXP |
| * |
| * Redistribution and use in source and binary forms, with or without modification, |
| * are permitted provided that the following conditions are met: |
| * |
| * o Redistributions of source code must retain the above copyright notice, this list |
| * of conditions and the following disclaimer. |
| * |
| * o Redistributions in binary form must reproduce the above copyright notice, this |
| * list of conditions and the following disclaimer in the documentation and/or |
| * other materials provided with the distribution. |
| * |
| * o Neither the name of the copyright holder nor the names of its |
| * contributors may be used to endorse or promote products derived from this |
| * software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
| * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "fsl_ltc_edma.h" |
| |
| /******************************************************************************* |
| * Definitions |
| ******************************************************************************/ |
| |
| /*<! Structure definition for ltc_edma_private_handle_t. The structure is private. */ |
| typedef struct _ltc_edma_private_handle |
| { |
| LTC_Type *base; |
| ltc_edma_handle_t *handle; |
| } ltc_edma_private_handle_t; |
| |
| /******************************************************************************* |
| * Variables |
| ******************************************************************************/ |
| |
| /*<! Private handle only used for internally. */ |
| static ltc_edma_private_handle_t s_edmaPrivateHandle[FSL_FEATURE_SOC_LTC_COUNT]; |
| |
| /* Array of LTC peripheral base address. */ |
| static LTC_Type *const s_ltcBase[] = LTC_BASE_PTRS; |
| |
| /******************************************************************************* |
| * Definitions |
| ******************************************************************************/ |
| /* State machine state.*/ |
| #define LTC_SM_STATE_START 0x0000u |
| #define LTC_SM_STATE_FINISH 0xFFFFu |
| |
| /*! Full word representing the actual bit values for the LTC mode register. */ |
| typedef uint32_t ltc_mode_t; |
| |
| #define LTC_FIFO_SZ_MAX_DOWN_ALGN (0xff0u) |
| #define LTC_MD_ALG_AES (0x10U) /*!< Bit field value for LTC_MD_ALG: AES */ |
| #define LTC_MD_ALG_DES (0x20U) /*!< Bit field value for LTC_MD_ALG: DES */ |
| #define LTC_MD_ALG_TRIPLE_DES (0x21U) /*!< Bit field value for LTC_MD_ALG: 3DES */ |
| #define LTC_MDPK_ALG_PKHA (0x80U) /*!< Bit field value for LTC_MDPK_ALG: PKHA */ |
| #define LTC_MD_ENC_DECRYPT (0U) /*!< Bit field value for LTC_MD_ENC: Decrypt. */ |
| #define LTC_MD_ENC_ENCRYPT (0x1U) /*!< Bit field value for LTC_MD_ENC: Encrypt. */ |
| #define LTC_MD_AS_UPDATE (0U) /*!< Bit field value for LTC_MD_AS: Update */ |
| #define LTC_MD_AS_INITIALIZE (0x1U) /*!< Bit field value for LTC_MD_AS: Initialize */ |
| #define LTC_MD_AS_FINALIZE (0x2U) /*!< Bit field value for LTC_MD_AS: Finalize */ |
| #define LTC_MD_AS_INIT_FINAL (0x3U) /*!< Bit field value for LTC_MD_AS: Initialize/Finalize */ |
| |
| enum _ltc_md_dk_bit_shift |
| { |
| kLTC_ModeRegBitShiftDK = 12U, |
| }; |
| |
| typedef enum _ltc_algorithm |
| { |
| kLTC_AlgorithmAES = LTC_MD_ALG_AES << LTC_MD_ALG_SHIFT, |
| #if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES |
| kLTC_AlgorithmDES = LTC_MD_ALG_DES << LTC_MD_ALG_SHIFT, |
| kLTC_Algorithm3DES = LTC_MD_ALG_TRIPLE_DES << LTC_MD_ALG_SHIFT, |
| #endif /* FSL_FEATURE_LTC_HAS_DES */ |
| } ltc_algorithm_t; |
| |
| typedef enum _ltc_mode_symmetric_alg |
| { |
| kLTC_ModeCTR = 0x00U << LTC_MD_AAI_SHIFT, |
| kLTC_ModeCBC = 0x10U << LTC_MD_AAI_SHIFT, |
| kLTC_ModeECB = 0x20U << LTC_MD_AAI_SHIFT, |
| kLTC_ModeCFB = 0x30U << LTC_MD_AAI_SHIFT, |
| kLTC_ModeOFB = 0x40U << LTC_MD_AAI_SHIFT, |
| kLTC_ModeCMAC = 0x60U << LTC_MD_AAI_SHIFT, |
| kLTC_ModeXCBCMAC = 0x70U << LTC_MD_AAI_SHIFT, |
| kLTC_ModeCCM = 0x80U << LTC_MD_AAI_SHIFT, |
| kLTC_ModeGCM = 0x90U << LTC_MD_AAI_SHIFT, |
| } ltc_mode_symmetric_alg_t; |
| |
| typedef enum _ltc_mode_encrypt |
| { |
| kLTC_ModeDecrypt = LTC_MD_ENC_DECRYPT << LTC_MD_ENC_SHIFT, |
| kLTC_ModeEncrypt = LTC_MD_ENC_ENCRYPT << LTC_MD_ENC_SHIFT, |
| } ltc_mode_encrypt_t; |
| |
| typedef enum _ltc_mode_algorithm_state |
| { |
| kLTC_ModeUpdate = LTC_MD_AS_UPDATE << LTC_MD_AS_SHIFT, |
| kLTC_ModeInit = LTC_MD_AS_INITIALIZE << LTC_MD_AS_SHIFT, |
| kLTC_ModeFinalize = LTC_MD_AS_FINALIZE << LTC_MD_AS_SHIFT, |
| kLTC_ModeInitFinal = LTC_MD_AS_INIT_FINAL << LTC_MD_AS_SHIFT |
| } ltc_mode_algorithm_state_t; |
| |
| /******************************************************************************* |
| * Prototypes |
| ******************************************************************************/ |
| |
| extern status_t ltc_get_context(LTC_Type *base, uint8_t *dest, uint8_t dataSize, uint8_t startIndex); |
| extern status_t ltc_set_context(LTC_Type *base, const uint8_t *data, uint8_t dataSize, uint8_t startIndex); |
| extern status_t ltc_symmetric_update(LTC_Type *base, |
| const uint8_t *key, |
| uint8_t keySize, |
| ltc_algorithm_t alg, |
| ltc_mode_symmetric_alg_t mode, |
| ltc_mode_encrypt_t enc); |
| extern void ltc_memcpy(void *dst, const void *src, size_t size); |
| extern bool ltc_check_key_size(const uint32_t keySize); |
| extern status_t ltc_wait(LTC_Type *base); |
| extern void ltc_clear_all(LTC_Type *base, bool addPKHA); |
| extern status_t ltc_3des_check_input_args(ltc_mode_symmetric_alg_t modeAs, |
| uint32_t size, |
| const uint8_t *key1, |
| const uint8_t *key2); |
| extern void ltc_symmetric_process(LTC_Type *base, uint32_t inSize, const uint8_t **inData, uint8_t **outData); |
| extern status_t ltc_symmetric_process_data(LTC_Type *base, const uint8_t *inData, uint32_t inSize, uint8_t *outData); |
| |
| static uint32_t LTC_GetInstance(LTC_Type *base); |
| static void ltc_symmetric_process_EDMA(LTC_Type *base, uint32_t inSize, const uint8_t **inData, uint8_t **outData); |
| static status_t ltc_process_message_in_sessions_EDMA(LTC_Type *base, ltc_edma_handle_t *handle); |
| |
| /******************************************************************************* |
| * Code |
| ******************************************************************************/ |
| |
| /******************************************************************************* |
| * LTC Common code static |
| ******************************************************************************/ |
| |
| /*! |
| * @brief Splits the LTC job into sessions. Used for CBC, CTR, CFB, OFB cipher block modes. |
| * |
| * @param base LTC peripheral base address |
| * @param inData Input data to process. |
| * @param inSize Input size of the input buffer. |
| * @param outData Output data buffer. |
| */ |
| static status_t ltc_process_message_in_sessions_EDMA(LTC_Type *base, ltc_edma_handle_t *handle) |
| { |
| status_t retval; |
| bool exit_sm = false; |
| |
| handle->modeReg = base->MD; |
| retval = kStatus_Success; |
| |
| if ((!handle->inData) || (!handle->outData)) |
| { |
| handle->state = LTC_SM_STATE_FINISH; /* END */ |
| retval = kStatus_InvalidArgument; |
| } |
| |
| while (exit_sm == false) |
| { |
| switch (handle->state) |
| { |
| case LTC_SM_STATE_START: |
| if (handle->size) |
| { |
| uint32_t sz; |
| |
| if (handle->size <= LTC_FIFO_SZ_MAX_DOWN_ALGN) |
| { |
| sz = handle->size; |
| } |
| else |
| { |
| sz = LTC_FIFO_SZ_MAX_DOWN_ALGN; |
| } |
| |
| /* retval = ltc_symmetric_process_data_EDMA(base, handle->inData, sz, handle->outData); */ |
| { |
| uint32_t lastSize; |
| uint32_t inSize = sz; |
| |
| /* Write the data size. */ |
| base->DS = inSize; |
| |
| /* Split the inSize into full 16-byte chunks and last incomplete block due to LTC AES OFIFO |
| * errata */ |
| if (inSize <= 16u) |
| { |
| lastSize = inSize; |
| inSize = 0; |
| } |
| else |
| { |
| /* Process all 16-byte data chunks. */ |
| lastSize = inSize % 16u; |
| if (lastSize == 0) |
| { |
| lastSize = 16; |
| inSize -= 16; |
| } |
| else |
| { |
| inSize -= |
| lastSize; /* inSize will be rounded down to 16 byte boundary. remaining bytes in |
| lastSize */ |
| } |
| } |
| |
| if (inSize) |
| { |
| handle->size -= inSize; |
| ltc_symmetric_process_EDMA(base, inSize, &handle->inData, &handle->outData); |
| exit_sm = true; |
| } |
| else if (lastSize) |
| { |
| ltc_symmetric_process(base, lastSize, &handle->inData, &handle->outData); |
| retval = ltc_wait(base); |
| handle->size -= lastSize; |
| } |
| else |
| { |
| } |
| } |
| } |
| else |
| { |
| handle->state = LTC_SM_STATE_FINISH; |
| } |
| break; |
| case LTC_SM_STATE_FINISH: |
| default: |
| base->MD = handle->modeReg; |
| |
| ltc_clear_all(base, false); |
| |
| if (handle->callback) |
| { |
| handle->callback(base, handle, retval, handle->userData); |
| } |
| exit_sm = true; |
| break; |
| } |
| } |
| |
| return retval; |
| } |
| |
| /*! |
| * @brief Splits the LTC job into sessions. Used for CBC, CTR, CFB, OFB cipher block modes. |
| * |
| * @param base LTC peripheral base address |
| * @param inData Input data to process. |
| * @param inSize Input size of the input buffer. |
| * @param outData Output data buffer. |
| */ |
| static status_t ltc_process_message_in_sessions_ctr_EDMA(LTC_Type *base, ltc_edma_handle_t *handle) |
| { |
| status_t retval; |
| bool exit_sm = false; |
| |
| handle->modeReg = base->MD; |
| retval = kStatus_Success; |
| |
| if ((!handle->inData) || (!handle->outData)) |
| { |
| handle->state = LTC_SM_STATE_FINISH; |
| retval = kStatus_InvalidArgument; |
| } |
| |
| while (exit_sm == false) |
| { |
| switch (handle->state) |
| { |
| case LTC_SM_STATE_START: |
| if (handle->size) |
| { |
| uint32_t sz; |
| |
| if (handle->size <= LTC_FIFO_SZ_MAX_DOWN_ALGN) |
| { |
| sz = handle->size; |
| } |
| else |
| { |
| sz = LTC_FIFO_SZ_MAX_DOWN_ALGN; |
| } |
| |
| /* retval = ltc_symmetric_process_data_EDMA(base, handle->inData, sz, handle->outData); */ |
| { |
| uint32_t lastSize; |
| uint32_t inSize = sz; |
| |
| /* Write the data size. */ |
| base->DS = inSize; |
| |
| /* Split the inSize into full 16-byte chunks and last incomplete block due to LTC AES OFIFO |
| * errata */ |
| if (inSize <= 16u) |
| { |
| lastSize = inSize; |
| inSize = 0; |
| } |
| else |
| { |
| /* Process all 16-byte data chunks. */ |
| lastSize = inSize % 16u; |
| if (lastSize == 0) |
| { |
| lastSize = 16; |
| inSize -= 16; |
| } |
| else |
| { |
| inSize -= |
| lastSize; /* inSize will be rounded down to 16 byte boundary. remaining bytes in |
| lastSize */ |
| } |
| } |
| |
| if (inSize) |
| { |
| handle->size -= inSize; |
| ltc_symmetric_process_EDMA(base, inSize, &handle->inData, &handle->outData); |
| exit_sm = true; |
| } |
| else if (lastSize) |
| { |
| ltc_symmetric_process(base, lastSize, &handle->inData, &handle->outData); |
| retval = ltc_wait(base); |
| handle->size -= lastSize; |
| } |
| else |
| { |
| } |
| } |
| } |
| else |
| { |
| handle->state = LTC_SM_STATE_FINISH; |
| } |
| break; |
| case LTC_SM_STATE_FINISH: |
| default: |
| base->MD = handle->modeReg; |
| |
| /* CTR final phase.*/ |
| if (kStatus_Success == retval) |
| { |
| const uint8_t *input = handle->inData; |
| uint8_t *output = handle->outData; |
| |
| if ((handle->counterlast != NULL) && (handle->lastSize)) |
| { |
| uint8_t zeroes[16] = {0}; |
| ltc_mode_t modeReg; |
| |
| modeReg = (uint32_t)kLTC_AlgorithmAES | (uint32_t)kLTC_ModeCTR | (uint32_t)kLTC_ModeEncrypt; |
| /* Write the mode register to the hardware. */ |
| base->MD = modeReg | (uint32_t)kLTC_ModeFinalize; |
| |
| /* context is re-used (CTRi) */ |
| |
| /* Process data and return status. */ |
| retval = ltc_symmetric_process_data(base, input, handle->lastSize, output); |
| if (kStatus_Success == retval) |
| { |
| if (handle->szLeft) |
| { |
| *handle->szLeft = 16U - handle->lastSize; |
| } |
| |
| /* Initialize algorithm state. */ |
| base->MD = modeReg | (uint32_t)kLTC_ModeUpdate; |
| |
| /* context is re-used (CTRi) */ |
| |
| /* Process data and return status. */ |
| retval = ltc_symmetric_process_data(base, zeroes, 16U, handle->counterlast); |
| } |
| } |
| if (kStatus_Success == retval) |
| { |
| ltc_get_context(base, &handle->counter[0], 16U, 4U); |
| |
| ltc_clear_all(base, false); |
| } |
| } |
| |
| if (handle->callback) |
| { |
| handle->callback(base, handle, retval, handle->userData); |
| } |
| |
| exit_sm = true; |
| break; |
| } |
| } |
| |
| return retval; |
| } |
| |
| /******************************************************************************* |
| * AES Code public |
| ******************************************************************************/ |
| |
| status_t LTC_AES_EncryptEcbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t *key, |
| uint32_t keySize) |
| { |
| status_t retval; |
| |
| if ((ltc_check_key_size(keySize) == 0) || (size < 16u) || |
| (size % 16u)) /* ECB mode, size must be 16-byte multiple */ |
| { |
| if (handle->callback) |
| { |
| handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); |
| } |
| |
| return kStatus_InvalidArgument; |
| } |
| |
| /* Initialize algorithm state. */ |
| ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeECB, kLTC_ModeEncrypt); |
| |
| /* Process data and return status. */ |
| handle->inData = &plaintext[0]; |
| handle->outData = &ciphertext[0]; |
| handle->size = size; |
| handle->state = LTC_SM_STATE_START; |
| handle->state_machine = ltc_process_message_in_sessions_EDMA; |
| retval = handle->state_machine(base, handle); |
| return retval; |
| } |
| |
| status_t LTC_AES_DecryptEcbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t *key, |
| uint32_t keySize, |
| ltc_aes_key_t keyType) |
| { |
| status_t status; |
| |
| if ((ltc_check_key_size(keySize) == 0) || (size < 16u) || |
| (size % 16u)) /* ECB mode, size must be 16-byte multiple */ |
| { |
| if (handle->callback) |
| { |
| handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); |
| } |
| |
| return kStatus_InvalidArgument; |
| } |
| |
| /* Initialize algorithm state. */ |
| ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeECB, kLTC_ModeDecrypt); |
| |
| /* set DK bit in the LTC Mode Register AAI field for directly loaded decrypt keys */ |
| if (keyType == kLTC_DecryptKey) |
| { |
| base->MD |= (1U << kLTC_ModeRegBitShiftDK); |
| } |
| |
| /* Process data and return status. */ |
| handle->inData = &ciphertext[0]; |
| handle->outData = &plaintext[0]; |
| handle->size = size; |
| handle->state = LTC_SM_STATE_START; |
| handle->state_machine = ltc_process_message_in_sessions_EDMA; |
| status = handle->state_machine(base, handle); |
| |
| return status; |
| } |
| |
| status_t LTC_AES_EncryptCbcEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t iv[LTC_AES_IV_SIZE], |
| const uint8_t *key, |
| uint32_t keySize) |
| { |
| status_t retval; |
| |
| if ((ltc_check_key_size(keySize) == 0) || (size < 16u) || |
| (size % 16u)) /* CBC mode, size must be 16-byte multiple */ |
| { |
| if (handle->callback) |
| { |
| handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); |
| } |
| |
| return kStatus_InvalidArgument; |
| } |
| |
| /* Initialize algorithm state. */ |
| ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCBC, kLTC_ModeEncrypt); |
| |
| /* Write IV data to the context register. */ |
| ltc_set_context(base, &iv[0], LTC_AES_IV_SIZE, 0); |
| |
| /* Process data and return status. */ |
| handle->inData = &plaintext[0]; |
| handle->outData = &ciphertext[0]; |
| handle->size = size; |
| handle->state = LTC_SM_STATE_START; |
| handle->state_machine = ltc_process_message_in_sessions_EDMA; |
| retval = handle->state_machine(base, handle); |
| return retval; |
| } |
| |
| status_t LTC_AES_DecryptCbcEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t iv[LTC_AES_IV_SIZE], |
| const uint8_t *key, |
| uint32_t keySize, |
| ltc_aes_key_t keyType) |
| { |
| status_t retval; |
| |
| if ((ltc_check_key_size(keySize) == 0) || (size < 16u) || |
| (size % 16u)) /* CBC mode, size must be 16-byte multiple */ |
| { |
| if (handle->callback) |
| { |
| handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); |
| } |
| |
| return kStatus_InvalidArgument; |
| } |
| |
| /* set DK bit in the LTC Mode Register AAI field for directly loaded decrypt keys */ |
| if (keyType == kLTC_DecryptKey) |
| { |
| base->MD |= (1U << kLTC_ModeRegBitShiftDK); |
| } |
| |
| /* Initialize algorithm state. */ |
| ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCBC, kLTC_ModeDecrypt); |
| |
| /* Write IV data to the context register. */ |
| ltc_set_context(base, &iv[0], LTC_AES_IV_SIZE, 0); |
| |
| /* Process data and return status. */ |
| handle->inData = &ciphertext[0]; |
| handle->outData = &plaintext[0]; |
| handle->size = size; |
| handle->state = LTC_SM_STATE_START; |
| handle->state_machine = ltc_process_message_in_sessions_EDMA; |
| retval = handle->state_machine(base, handle); |
| return retval; |
| } |
| |
| status_t LTC_AES_CryptCtrEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *input, |
| uint8_t *output, |
| uint32_t size, |
| uint8_t counter[LTC_AES_BLOCK_SIZE], |
| const uint8_t *key, |
| uint32_t keySize, |
| uint8_t counterlast[LTC_AES_BLOCK_SIZE], |
| uint32_t *szLeft) |
| { |
| status_t retval; |
| uint32_t lastSize; |
| |
| if (!ltc_check_key_size(keySize)) |
| { |
| if (handle->callback) |
| { |
| handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); |
| } |
| return kStatus_InvalidArgument; |
| } |
| |
| lastSize = 0U; |
| if (counterlast != NULL) |
| { |
| /* Split the size into full 16-byte chunks and last incomplete block due to LTC AES OFIFO errata */ |
| if (size <= 16U) |
| { |
| lastSize = size; |
| size = 0U; |
| } |
| else |
| { |
| /* Process all 16-byte data chunks. */ |
| lastSize = size % 16U; |
| if (lastSize == 0U) |
| { |
| lastSize = 16U; |
| size -= 16U; |
| } |
| else |
| { |
| size -= lastSize; /* size will be rounded down to 16 byte boundary. remaining bytes in lastSize */ |
| } |
| } |
| } |
| |
| /* Initialize algorithm state. */ |
| ltc_symmetric_update(base, key, keySize, kLTC_AlgorithmAES, kLTC_ModeCTR, kLTC_ModeEncrypt); |
| |
| /* Write initial counter data to the context register. |
| * NOTE the counter values start at 4-bytes offset into the context. */ |
| ltc_set_context(base, &counter[0], 16U, 4U); |
| |
| /* Process data and return status. */ |
| handle->inData = &input[0]; |
| handle->outData = &output[0]; |
| handle->size = size; |
| handle->state = LTC_SM_STATE_START; |
| handle->state_machine = ltc_process_message_in_sessions_ctr_EDMA; |
| |
| handle->counter = counter; |
| handle->key = key; |
| handle->keySize = keySize; |
| handle->counterlast = counterlast; |
| handle->szLeft = szLeft; |
| handle->lastSize = lastSize; |
| retval = handle->state_machine(base, handle); |
| |
| return retval; |
| } |
| |
| #if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES |
| /******************************************************************************* |
| * DES / 3DES Code static |
| ******************************************************************************/ |
| static status_t ltc_des_process_EDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *input, |
| uint8_t *output, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key[LTC_DES_KEY_SIZE], |
| ltc_mode_symmetric_alg_t modeAs, |
| ltc_mode_encrypt_t modeEnc) |
| { |
| status_t retval; |
| |
| /* all but OFB, size must be 8-byte multiple */ |
| if ((modeAs != kLTC_ModeOFB) && ((size < 8u) || (size % 8u))) |
| { |
| if (handle->callback) |
| { |
| handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); |
| } |
| return kStatus_InvalidArgument; |
| } |
| |
| /* Initialize algorithm state. */ |
| ltc_symmetric_update(base, &key[0], LTC_DES_KEY_SIZE, kLTC_AlgorithmDES, modeAs, modeEnc); |
| |
| if ((modeAs != kLTC_ModeECB)) |
| { |
| ltc_set_context(base, iv, LTC_DES_IV_SIZE, 0); |
| } |
| |
| /* Process data and return status. */ |
| handle->inData = input; |
| handle->outData = output; |
| handle->size = size; |
| handle->state = LTC_SM_STATE_START; |
| handle->state_machine = ltc_process_message_in_sessions_EDMA; |
| retval = handle->state_machine(base, handle); |
| |
| return retval; |
| } |
| |
| static status_t ltc_3des_process_EDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *input, |
| uint8_t *output, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE], |
| const uint8_t key3[LTC_DES_KEY_SIZE], |
| ltc_mode_symmetric_alg_t modeAs, |
| ltc_mode_encrypt_t modeEnc) |
| { |
| status_t retval; |
| uint8_t key[LTC_DES_KEY_SIZE * 3]; |
| uint8_t keySize = LTC_DES_KEY_SIZE * 2; |
| |
| retval = ltc_3des_check_input_args(modeAs, size, key1, key2); |
| if (kStatus_Success != retval) |
| { |
| if (handle->callback) |
| { |
| handle->callback(base, handle, kStatus_InvalidArgument, handle->userData); |
| } |
| return retval; |
| } |
| |
| ltc_memcpy(&key[0], &key1[0], LTC_DES_KEY_SIZE); |
| ltc_memcpy(&key[LTC_DES_KEY_SIZE], &key2[0], LTC_DES_KEY_SIZE); |
| if (key3) |
| { |
| ltc_memcpy(&key[LTC_DES_KEY_SIZE * 2], &key3[0], LTC_DES_KEY_SIZE); |
| keySize = sizeof(key); |
| } |
| |
| /* Initialize algorithm state. */ |
| ltc_symmetric_update(base, &key[0], keySize, kLTC_Algorithm3DES, modeAs, modeEnc); |
| |
| if ((modeAs != kLTC_ModeECB)) |
| { |
| ltc_set_context(base, iv, LTC_DES_IV_SIZE, 0); |
| } |
| |
| /* Process data and return status. */ |
| handle->inData = input; |
| handle->outData = output; |
| handle->size = size; |
| handle->state = LTC_SM_STATE_START; |
| handle->state_machine = ltc_process_message_in_sessions_EDMA; |
| retval = handle->state_machine(base, handle); |
| |
| return retval; |
| } |
| /******************************************************************************* |
| * DES / 3DES Code public |
| ******************************************************************************/ |
| status_t LTC_DES_EncryptEcbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t key[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_des_process_EDMA(base, handle, plaintext, ciphertext, size, NULL, key, kLTC_ModeECB, kLTC_ModeEncrypt); |
| } |
| |
| status_t LTC_DES_DecryptEcbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t key[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_des_process_EDMA(base, handle, ciphertext, plaintext, size, NULL, key, kLTC_ModeECB, kLTC_ModeDecrypt); |
| } |
| |
| status_t LTC_DES_EncryptCbcEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key, kLTC_ModeCBC, kLTC_ModeEncrypt); |
| } |
| |
| status_t LTC_DES_DecryptCbcEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key, kLTC_ModeCBC, kLTC_ModeDecrypt); |
| } |
| |
| status_t LTC_DES_EncryptCfbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key, kLTC_ModeCFB, kLTC_ModeEncrypt); |
| } |
| |
| status_t LTC_DES_DecryptCfbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key, kLTC_ModeCFB, kLTC_ModeDecrypt); |
| } |
| |
| status_t LTC_DES_EncryptOfbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key, kLTC_ModeOFB, kLTC_ModeEncrypt); |
| } |
| |
| status_t LTC_DES_DecryptOfbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key, kLTC_ModeOFB, kLTC_ModeDecrypt); |
| } |
| |
| status_t LTC_DES2_EncryptEcbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, NULL, key1, key2, NULL, kLTC_ModeECB, |
| kLTC_ModeEncrypt); |
| } |
| |
| status_t LTC_DES3_EncryptEcbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE], |
| const uint8_t key3[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, NULL, key1, key2, key3, kLTC_ModeECB, |
| kLTC_ModeEncrypt); |
| } |
| |
| status_t LTC_DES2_DecryptEcbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, NULL, key1, key2, NULL, kLTC_ModeECB, |
| kLTC_ModeDecrypt); |
| } |
| |
| status_t LTC_DES3_DecryptEcbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE], |
| const uint8_t key3[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, NULL, key1, key2, key3, kLTC_ModeECB, |
| kLTC_ModeDecrypt); |
| } |
| |
| status_t LTC_DES2_EncryptCbcEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key1, key2, NULL, kLTC_ModeCBC, |
| kLTC_ModeEncrypt); |
| } |
| |
| status_t LTC_DES3_EncryptCbcEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE], |
| const uint8_t key3[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key1, key2, key3, kLTC_ModeCBC, |
| kLTC_ModeEncrypt); |
| } |
| |
| status_t LTC_DES2_DecryptCbcEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key1, key2, NULL, kLTC_ModeCBC, |
| kLTC_ModeDecrypt); |
| } |
| |
| status_t LTC_DES3_DecryptCbcEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE], |
| const uint8_t key3[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key1, key2, key3, kLTC_ModeCBC, |
| kLTC_ModeDecrypt); |
| } |
| |
| status_t LTC_DES2_EncryptCfbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key1, key2, NULL, kLTC_ModeCFB, |
| kLTC_ModeEncrypt); |
| } |
| |
| status_t LTC_DES3_EncryptCfbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE], |
| const uint8_t key3[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key1, key2, key3, kLTC_ModeCFB, |
| kLTC_ModeEncrypt); |
| } |
| |
| status_t LTC_DES2_DecryptCfbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key1, key2, NULL, kLTC_ModeCFB, |
| kLTC_ModeDecrypt); |
| } |
| |
| status_t LTC_DES3_DecryptCfbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE], |
| const uint8_t key3[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key1, key2, key3, kLTC_ModeCFB, |
| kLTC_ModeDecrypt); |
| } |
| |
| status_t LTC_DES2_EncryptOfbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key1, key2, NULL, kLTC_ModeOFB, |
| kLTC_ModeEncrypt); |
| } |
| |
| status_t LTC_DES3_EncryptOfbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE], |
| const uint8_t key3[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, plaintext, ciphertext, size, iv, key1, key2, key3, kLTC_ModeOFB, |
| kLTC_ModeEncrypt); |
| } |
| |
| status_t LTC_DES2_DecryptOfbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key1, key2, NULL, kLTC_ModeOFB, |
| kLTC_ModeDecrypt); |
| } |
| |
| status_t LTC_DES3_DecryptOfbEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| uint32_t size, |
| const uint8_t iv[LTC_DES_IV_SIZE], |
| const uint8_t key1[LTC_DES_KEY_SIZE], |
| const uint8_t key2[LTC_DES_KEY_SIZE], |
| const uint8_t key3[LTC_DES_KEY_SIZE]) |
| { |
| return ltc_3des_process_EDMA(base, handle, ciphertext, plaintext, size, iv, key1, key2, key3, kLTC_ModeOFB, |
| kLTC_ModeDecrypt); |
| } |
| #endif /* FSL_FEATURE_LTC_HAS_DES */ |
| |
| /*********************** LTC EDMA tools ***************************************/ |
| |
| static uint32_t LTC_GetInstance(LTC_Type *base) |
| { |
| uint32_t instance = 0; |
| uint32_t i; |
| |
| for (i = 0; i < FSL_FEATURE_SOC_LTC_COUNT; i++) |
| { |
| if (s_ltcBase[instance] == base) |
| { |
| instance = i; |
| break; |
| } |
| } |
| return instance; |
| } |
| |
| /*! |
| * @brief Enable or disable LTC Input FIFO DMA request. |
| * |
| * This function enables or disables DMA request and done signals for Input FIFO. |
| * |
| * @param base LTC peripheral base address. |
| * @param enable True to enable, false to disable. |
| */ |
| static inline void LTC_EnableInputFifoDMA(LTC_Type *base, bool enable) |
| { |
| if (enable) |
| { |
| base->CTL |= LTC_CTL_IFE_MASK; |
| } |
| else |
| { |
| base->CTL &= ~LTC_CTL_IFE_MASK; |
| } |
| } |
| |
| /*! |
| * @brief Enable or disable LTC Output FIFO DMA request. |
| * |
| * This function enables or disables DMA request and done signals for Output FIFO. |
| * |
| * @param base LTC peripheral base address. |
| * @param enable True to enable, false to disable. |
| */ |
| static inline void LTC_EnableOutputFifoDMA(LTC_Type *base, bool enable) |
| { |
| if (enable) |
| { |
| base->CTL |= LTC_CTL_OFE_MASK; |
| } |
| else |
| { |
| base->CTL &= ~LTC_CTL_OFE_MASK; |
| } |
| } |
| |
| static void LTC_InputFifoEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) |
| { |
| ltc_edma_private_handle_t *ltcPrivateHandle = (ltc_edma_private_handle_t *)param; |
| |
| /* Avoid the warning for unused variables. */ |
| handle = handle; |
| tcds = tcds; |
| |
| if (transferDone) |
| { |
| /* Stop DMA channel. */ |
| EDMA_StopTransfer(ltcPrivateHandle->handle->inputFifoEdmaHandle); |
| |
| /* Disable Input Fifo DMA */ |
| LTC_EnableInputFifoDMA(ltcPrivateHandle->base, false); |
| } |
| } |
| |
| static void LTC_OutputFifoEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) |
| { |
| ltc_edma_private_handle_t *ltcPrivateHandle = (ltc_edma_private_handle_t *)param; |
| |
| /* Avoid the warning for unused variables. */ |
| handle = handle; |
| tcds = tcds; |
| |
| if (transferDone) |
| { |
| /* Stop DMA channel. */ |
| EDMA_StopTransfer(ltcPrivateHandle->handle->outputFifoEdmaHandle); |
| |
| /* Disable Output Fifo DMA */ |
| LTC_EnableOutputFifoDMA(ltcPrivateHandle->base, false); |
| |
| if (ltcPrivateHandle->handle->state_machine) |
| { |
| ltcPrivateHandle->handle->state_machine(ltcPrivateHandle->base, ltcPrivateHandle->handle); |
| } |
| } |
| } |
| |
| /* @brief Copy data to Input FIFO and reading from Ouput FIFO using eDMA. */ |
| static void ltc_symmetric_process_EDMA(LTC_Type *base, uint32_t inSize, const uint8_t **inData, uint8_t **outData) |
| { |
| const uint8_t *in = *inData; |
| uint8_t *out = *outData; |
| uint32_t instance = LTC_GetInstance(base); |
| uint32_t entry_number = inSize / sizeof(uint32_t); |
| const uint8_t *inputBuffer = *inData; |
| uint8_t *outputBuffer = *outData; |
| edma_transfer_config_t config; |
| |
| if (entry_number) |
| { |
| /* =========== Init Input FIFO DMA ======================*/ |
| memset(&config, 0, sizeof(config)); |
| |
| /* Prepare transfer. */ |
| EDMA_PrepareTransfer(&config, (void *)inputBuffer, 1, (void *)(&((base)->IFIFO)), 4U, 4U, entry_number * 4, |
| kEDMA_MemoryToPeripheral); |
| /* Submit transfer. */ |
| EDMA_SubmitTransfer(s_edmaPrivateHandle[instance].handle->inputFifoEdmaHandle, &config); |
| |
| /* Set request size.*/ |
| base->CTL &= ~LTC_CTL_IFR_MASK; /* 1 entry */ |
| /* Enable Input Fifo DMA */ |
| LTC_EnableInputFifoDMA(base, true); |
| |
| /* Start the DMA channel */ |
| EDMA_StartTransfer(s_edmaPrivateHandle[instance].handle->inputFifoEdmaHandle); |
| |
| /* =========== Init Output FIFO DMA ======================*/ |
| memset(&config, 0, sizeof(config)); |
| |
| /* Prepare transfer. */ |
| EDMA_PrepareTransfer(&config, (void *)(&((base)->OFIFO)), 4U, (void *)outputBuffer, 1U, 4U, entry_number * 4, |
| kEDMA_PeripheralToMemory); |
| /* Submit transfer. */ |
| EDMA_SubmitTransfer(s_edmaPrivateHandle[instance].handle->outputFifoEdmaHandle, &config); |
| |
| /* Set request size.*/ |
| base->CTL &= ~LTC_CTL_OFR_MASK; /* 1 entry */ |
| |
| /* Enable Output Fifo DMA */ |
| LTC_EnableOutputFifoDMA(base, true); |
| |
| /* Start the DMA channel */ |
| EDMA_StartTransfer(s_edmaPrivateHandle[instance].handle->outputFifoEdmaHandle); |
| |
| { /* Dummy read of LTC register. Do not delete.*/ |
| volatile uint32_t status_reg; |
| |
| status_reg = (base)->STA; |
| |
| (void)status_reg; |
| } |
| |
| out += entry_number * sizeof(uint32_t); |
| in += entry_number * sizeof(uint32_t); |
| |
| *inData = in; |
| *outData = out; |
| } |
| } |
| |
| void LTC_CreateHandleEDMA(LTC_Type *base, |
| ltc_edma_handle_t *handle, |
| ltc_edma_callback_t callback, |
| void *userData, |
| edma_handle_t *inputFifoEdmaHandle, |
| edma_handle_t *outputFifoEdmaHandle) |
| { |
| assert(handle); |
| assert(inputFifoEdmaHandle); |
| assert(outputFifoEdmaHandle); |
| |
| uint32_t instance = LTC_GetInstance(base); |
| |
| s_edmaPrivateHandle[instance].base = base; |
| s_edmaPrivateHandle[instance].handle = handle; |
| |
| memset(handle, 0, sizeof(*handle)); |
| |
| handle->inputFifoEdmaHandle = inputFifoEdmaHandle; |
| handle->outputFifoEdmaHandle = outputFifoEdmaHandle; |
| |
| handle->callback = callback; |
| handle->userData = userData; |
| |
| /* Register DMA callback functions */ |
| EDMA_SetCallback(handle->inputFifoEdmaHandle, LTC_InputFifoEDMACallback, &s_edmaPrivateHandle[instance]); |
| EDMA_SetCallback(handle->outputFifoEdmaHandle, LTC_OutputFifoEDMACallback, &s_edmaPrivateHandle[instance]); |
| |
| /* Set request size. DMA request size is 1 entry.*/ |
| base->CTL &= ~LTC_CTL_IFR_MASK; |
| base->CTL &= ~LTC_CTL_OFR_MASK; |
| } |