diff options
author | danicampora <danicampora@gmail.com> | 2015-03-15 10:05:15 +0100 |
---|---|---|
committer | danicampora <danicampora@gmail.com> | 2015-03-16 00:42:05 +0100 |
commit | 0d0646d915b51191ce55cbb2750e5422ee1766db (patch) | |
tree | 5beed462e80f529eee10a7cab2c9f45ae9999d16 | |
parent | dac79324b5a49a81435a9dafc389353a4fa8739b (diff) | |
download | micropython-0d0646d915b51191ce55cbb2750e5422ee1766db.tar.gz micropython-0d0646d915b51191ce55cbb2750e5422ee1766db.zip |
cc3200: Update HAL to SDK release version 1.1.0.
-rw-r--r-- | cc3200/bootmgr/bootloader.mk | 1 | ||||
-rw-r--r-- | cc3200/hal/adc.h | 2 | ||||
-rw-r--r-- | cc3200/hal/aes.c | 2690 | ||||
-rw-r--r-- | cc3200/hal/aes.h | 435 | ||||
-rw-r--r-- | cc3200/hal/des.c | 1774 | ||||
-rw-r--r-- | cc3200/hal/i2s.c | 1934 | ||||
-rw-r--r-- | cc3200/hal/i2s.h | 420 | ||||
-rw-r--r-- | cc3200/hal/pin.c | 2 | ||||
-rw-r--r-- | cc3200/hal/prcm.c | 91 | ||||
-rw-r--r-- | cc3200/hal/prcm.h | 1 | ||||
-rw-r--r-- | cc3200/hal/rom_patch.h | 11 | ||||
-rw-r--r-- | cc3200/hal/sdhost.c | 6 | ||||
-rw-r--r-- | cc3200/hal/sdhost.h | 2 | ||||
-rw-r--r-- | cc3200/hal/timer.c | 45 | ||||
-rw-r--r-- | cc3200/hal/timer.h | 2 | ||||
-rw-r--r-- | cc3200/hal/uart.c | 12 | ||||
-rw-r--r-- | cc3200/mods/modwlan.c | 3 |
17 files changed, 3848 insertions, 3583 deletions
diff --git a/cc3200/bootmgr/bootloader.mk b/cc3200/bootmgr/bootloader.mk index 68d80fd712..c7c7b05ef0 100644 --- a/cc3200/bootmgr/bootloader.mk +++ b/cc3200/bootmgr/bootloader.mk @@ -19,6 +19,7 @@ BOOT_CPPDEFINES = -Dgcc -DBOOTLOADER -DTARGET_IS_CC3200 -DSL_TINY BOOT_HAL_SRC_C = $(addprefix hal/,\ cpu.c \ interrupt.c \ + pin.c \ prcm.c \ shamd5.c \ spi.c \ diff --git a/cc3200/hal/adc.h b/cc3200/hal/adc.h index fce1a7305e..03e0ea52cf 100644 --- a/cc3200/hal/adc.h +++ b/cc3200/hal/adc.h @@ -48,7 +48,7 @@ //***************************************************************************** #ifdef __cplusplus extern "C" -//{ +{ #endif //***************************************************************************** diff --git a/cc3200/hal/aes.c b/cc3200/hal/aes.c index 9f3175ec2b..e0e129ef5f 100644 --- a/cc3200/hal/aes.c +++ b/cc3200/hal/aes.c @@ -1,1330 +1,1360 @@ -//***************************************************************************** -// -// aes.c -// -// Driver for the AES module. -// -// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ -// -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the -// distribution. -// -// Neither the name of Texas Instruments Incorporated nor the names of -// its contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -//***************************************************************************** -// -//! \addtogroup AES_Advanced_Encryption_Standard_api -//! @{ -// -//***************************************************************************** - -#include <stdbool.h> -#include <stdint.h> -#include "inc/hw_aes.h" -#include "inc/hw_dthe.h" -#include "inc/hw_ints.h" -#include "inc/hw_memmap.h" -#include "inc/hw_nvic.h" -#include "inc/hw_types.h" -#include "aes.h" -#include "debug.h" -#include "interrupt.h" - -#define AES_BLOCK_SIZE_IN_BYTES 16 - -//***************************************************************************** -// -//! Configures the AES module. -//! -//! \param ui32Base is the base address of the AES module. -//! \param ui32Config is the configuration of the AES module. -//! -//! This function configures the AES module based on the specified parameters. -//! It does not change any DMA- or interrupt-related parameters. -//! -//! The ui32Config parameter is a bit-wise OR of a number of configuration -//! flags. The valid flags are grouped based on their function. -//! -//! The direction of the operation is specified with only of following flags: -//! -//! - \b AES_CFG_DIR_ENCRYPT - Encryption mode -//! - \b AES_CFG_DIR_DECRYPT - Decryption mode -//! -//! The key size is specified with only one of the following flags: -//! -//! - \b AES_CFG_KEY_SIZE_128BIT - Key size of 128 bits -//! - \b AES_CFG_KEY_SIZE_192BIT - Key size of 192 bits -//! - \b AES_CFG_KEY_SIZE_256BIT - Key size of 256 bits -//! -//! The mode of operation is specified with only one of the following flags. -//! -//! - \b AES_CFG_MODE_ECB - Electronic codebook mode -//! - \b AES_CFG_MODE_CBC - Cipher-block chaining mode -//! - \b AES_CFG_MODE_CFB - Cipher feedback mode -//! - \b AES_CFG_MODE_CTR - Counter mode -//! - \b AES_CFG_MODE_ICM - Integer counter mode -//! - \b AES_CFG_MODE_XTS - Ciphertext stealing mode -//! - \b AES_CFG_MODE_XTS_TWEAKJL - XEX-based tweaked-codebook mode with -//! ciphertext stealing with previous/intermediate tweak value and j loaded -//! - \b AES_CFG_MODE_XTS_K2IJL - XEX-based tweaked-codebook mode with -//! ciphertext stealing with key2, i and j loaded -//! - \b AES_CFG_MODE_XTS_K2ILJ0 - XEX-based tweaked-codebook mode with -//! ciphertext stealing with key2 and i loaded, j = 0 -//! - \b AES_CFG_MODE_F8 - F8 mode -//! - \b AES_CFG_MODE_F9 - F9 mode -//! - \b AES_CFG_MODE_CBCMAC - Cipher block chaining message authentication -//! code mode -//! - \b AES_CFG_MODE_GCM - Galois/counter mode -//! - \b AES_CFG_MODE_GCM_HLY0ZERO - Galois/counter mode with GHASH with H -//! loaded and Y0-encrypted forced to zero -//! - \b AES_CFG_MODE_GCM_HLY0CALC - Galois/counter mode with GHASH with H -//! loaded and Y0-encrypted calculated internally -//! - \b AES_CFG_MODE_GCM_HY0CALC - Galois/Counter mode with autonomous GHASH -//! (both H and Y0-encrypted calculated internally) -//! - \b AES_CFG_MODE_CCM - Counter with CBC-MAC mode -//! -//! The following defines are used to specify the counter width. It is only -//! required to be defined when using CTR, CCM, or GCM modes, only one of the -//! following defines must be used to specify the counter width length: -//! -//! - \b AES_CFG_CTR_WIDTH_32 - Counter is 32 bits -//! - \b AES_CFG_CTR_WIDTH_64 - Counter is 64 bits -//! - \b AES_CFG_CTR_WIDTH_96 - Counter is 96 bits -//! - \b AES_CFG_CTR_WIDTH_128 - Counter is 128 bits -//! -//! Only one of the following defines must be used to specify the length field -//! for CCM operations (L): -//! -//! - \b AES_CFG_CCM_L_2 - 2 bytes -//! - \b AES_CFG_CCM_L_4 - 4 bytes -//! - \b AES_CFG_CCM_L_8 - 8 bytes -//! -//! Only one of the following defines must be used to specify the length of the -//! authentication field for CCM operations (M) through the \e ui32Config -//! argument in the AESConfigSet() function: -//! -//! - \b AES_CFG_CCM_M_4 - 4 bytes -//! - \b AES_CFG_CCM_M_6 - 6 bytes -//! - \b AES_CFG_CCM_M_8 - 8 bytes -//! - \b AES_CFG_CCM_M_10 - 10 bytes -//! - \b AES_CFG_CCM_M_12 - 12 bytes -//! - \b AES_CFG_CCM_M_14 - 14 bytes -//! - \b AES_CFG_CCM_M_16 - 16 bytes -//! -//! \return None. -// -//***************************************************************************** -void -AESConfigSet(uint32_t ui32Base, uint32_t ui32Config) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - ASSERT((ui32Config & AES_CFG_DIR_ENCRYPT) || - (ui32Config & AES_CFG_DIR_DECRYPT)); - ASSERT((ui32Config & AES_CFG_KEY_SIZE_128BIT) || - (ui32Config & AES_CFG_KEY_SIZE_192BIT) || - (ui32Config & AES_CFG_KEY_SIZE_256BIT)); - ASSERT((ui32Config & AES_CFG_MODE_ECB) || - (ui32Config & AES_CFG_MODE_CBC) || - (ui32Config & AES_CFG_MODE_CTR) || - (ui32Config & AES_CFG_MODE_ICM) || - (ui32Config & AES_CFG_MODE_CFB) || - (ui32Config & AES_CFG_MODE_XTS_TWEAKJL) || - (ui32Config & AES_CFG_MODE_XTS_K2IJL) || - (ui32Config & AES_CFG_MODE_XTS_K2ILJ0) || - (ui32Config & AES_CFG_MODE_F8) || - (ui32Config & AES_CFG_MODE_F9) || - (ui32Config & AES_CFG_MODE_CTR) || - (ui32Config & AES_CFG_MODE_CBCMAC) || - (ui32Config & AES_CFG_MODE_GCM_HLY0ZERO) || - (ui32Config & AES_CFG_MODE_GCM_HLY0CALC) || - (ui32Config & AES_CFG_MODE_GCM_HY0CALC) || - (ui32Config & AES_CFG_MODE_CCM)); - ASSERT(((ui32Config & AES_CFG_MODE_CTR) || - (ui32Config & AES_CFG_MODE_GCM_HLY0ZERO) || - (ui32Config & AES_CFG_MODE_GCM_HLY0CALC) || - (ui32Config & AES_CFG_MODE_GCM_HY0CALC) || - (ui32Config & AES_CFG_MODE_CCM)) && - ((ui32Config & AES_CFG_CTR_WIDTH_32) || - (ui32Config & AES_CFG_CTR_WIDTH_64) || - (ui32Config & AES_CFG_CTR_WIDTH_96) || - (ui32Config & AES_CFG_CTR_WIDTH_128))); - ASSERT((ui32Config & AES_CFG_MODE_CCM) && - ((ui32Config & AES_CFG_CCM_L_2) || - (ui32Config & AES_CFG_CCM_L_4) || - (ui32Config & AES_CFG_CCM_L_8)) && - ((ui32Config & AES_CFG_CCM_M_4) || - (ui32Config & AES_CFG_CCM_M_6) || - (ui32Config & AES_CFG_CCM_M_8) || - (ui32Config & AES_CFG_CCM_M_10) || - (ui32Config & AES_CFG_CCM_M_12) || - (ui32Config & AES_CFG_CCM_M_14) || - (ui32Config & AES_CFG_CCM_M_16))); - - // - // Backup the save context field before updating the register. - // - if(HWREG(ui32Base + AES_O_CTRL) & AES_CTRL_SAVE_CONTEXT) - { - ui32Config |= AES_CTRL_SAVE_CONTEXT; - } - - // - // Write the CTRL register with the new value - // - HWREG(ui32Base + AES_O_CTRL) = ui32Config; -} - -//***************************************************************************** -// -//! Writes the key 1 configuration registers, which are used for encryption or -//! decryption. -//! -//! \param ui32Base is the base address for the AES module. -//! \param pui8Key is an array of bytes, containing the key to be -//! configured. The least significant word in the 0th index. -//! \param ui32Keysize is the size of the key, which must be one of the -//! following values: \b AES_CFG_KEY_SIZE_128, \b AES_CFG_KEY_SIZE_192, or -//! \b AES_CFG_KEY_SIZE_256. -//! -//! This function writes key 1 configuration registers based on the key -//! size. This function is used in all modes. -//! -//! \return None. -// -//***************************************************************************** -void -AESKey1Set(uint32_t ui32Base, uint8_t *pui8Key, uint32_t ui32Keysize) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - ASSERT((ui32Keysize == AES_CFG_KEY_SIZE_128BIT) || - (ui32Keysize == AES_CFG_KEY_SIZE_192BIT) || - (ui32Keysize == AES_CFG_KEY_SIZE_256BIT)); - - // - // With all key sizes, the first 4 words are written. - // - HWREG(ui32Base + AES_O_KEY1_0) = * ((uint32_t *)(pui8Key + 0)); - HWREG(ui32Base + AES_O_KEY1_1) = * ((uint32_t *)(pui8Key + 4)); - HWREG(ui32Base + AES_O_KEY1_2) = * ((uint32_t *)(pui8Key + 8)); - HWREG(ui32Base + AES_O_KEY1_3) = * ((uint32_t *)(pui8Key + 12)); - - // - // The key is 192 or 256 bits. Write the next 2 words. - // - if(ui32Keysize != AES_CFG_KEY_SIZE_128BIT) - { - HWREG(ui32Base + AES_O_KEY1_4) = * ((uint32_t *)(pui8Key + 16)); - HWREG(ui32Base + AES_O_KEY1_5) = * ((uint32_t *)(pui8Key + 20)); - } - - // - // The key is 256 bits. Write the last 2 words. - // - if(ui32Keysize == AES_CFG_KEY_SIZE_256BIT) - { - HWREG(ui32Base + AES_O_KEY1_6) = * ((uint32_t *)(pui8Key + 24)); - HWREG(ui32Base + AES_O_KEY1_7) = * ((uint32_t *)(pui8Key + 28)); - } -} - -//***************************************************************************** -// -//! Writes the key 2 configuration registers, which are used for encryption or -//! decryption. -//! -//! \param ui32Base is the base address for the AES module. -//! \param pui8Key is an array of bytes, containing the key to be -//! configured. The least significant word in the 0th index. -//! \param ui32Keysize is the size of the key, which must be one of the -//! following values: \b AES_CFG_KEY_SIZE_128, \b AES_CFG_KEY_SIZE_192, or -//! \b AES_CFG_KEY_SIZE_256. -//! -//! This function writes the key 2 configuration registers based on the key -//! size. This function is used in the F8, F9, XTS, CCM, and CBC-MAC modes. -//! -//! \return None. -// -//***************************************************************************** -void -AESKey2Set(uint32_t ui32Base, uint8_t *pui8Key, uint32_t ui32Keysize) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - ASSERT((ui32Keysize == AES_CFG_KEY_SIZE_128BIT) || - (ui32Keysize == AES_CFG_KEY_SIZE_192BIT) || - (ui32Keysize == AES_CFG_KEY_SIZE_256BIT)); - - // - // With all key sizes, the first 4 words are written. - // - HWREG(ui32Base + AES_O_KEY2_0) = * ((uint32_t *)(pui8Key + 0)); - HWREG(ui32Base + AES_O_KEY2_1) = * ((uint32_t *)(pui8Key + 4)); - HWREG(ui32Base + AES_O_KEY2_2) = * ((uint32_t *)(pui8Key + 8)); - HWREG(ui32Base + AES_O_KEY2_3) = * ((uint32_t *)(pui8Key + 12)); - - // - // The key is 192 or 256 bits. Write the next 2 words. - // - if(ui32Keysize != AES_CFG_KEY_SIZE_128BIT) - { - HWREG(ui32Base + AES_O_KEY2_4) = * ((uint32_t *)(pui8Key + 16)); - HWREG(ui32Base + AES_O_KEY2_5) = * ((uint32_t *)(pui8Key + 20)); - } - - // - // The key is 256 bits. Write the last 2 words. - // - if(ui32Keysize == AES_CFG_KEY_SIZE_256BIT) - { - HWREG(ui32Base + AES_O_KEY2_6) = * ((uint32_t *)(pui8Key + 24)); - HWREG(ui32Base + AES_O_KEY2_7) = * ((uint32_t *)(pui8Key + 28)); - } -} - -//***************************************************************************** -// -//! Writes key 3 configuration registers, which are used for encryption or -//! decryption. -//! -//! \param ui32Base is the base address for the AES module. -//! \param pui8Key is a pointer to an array bytes, containing -//! the key to be configured. The least significant word is in the 0th index. -//! -//! This function writes the key 2 configuration registers with key 3 data -//! used in CBC-MAC and F8 modes. This key is always 128 bits. -//! -//! \return None. -// -//***************************************************************************** -void -AESKey3Set(uint32_t ui32Base, uint8_t *pui8Key) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - - // - // Write the key into the upper 4 key registers - // - HWREG(ui32Base + AES_O_KEY2_4) = * ((uint32_t *)(pui8Key + 0)); - HWREG(ui32Base + AES_O_KEY2_5) = * ((uint32_t *)(pui8Key + 4)); - HWREG(ui32Base + AES_O_KEY2_6) = * ((uint32_t *)(pui8Key + 8)); - HWREG(ui32Base + AES_O_KEY2_7) = * ((uint32_t *)(pui8Key + 12)); -} - -//***************************************************************************** -// -//! Writes the Initial Vector (IV) register, needed in some of the AES Modes. -//! -//! \param ui32Base is the base address of the AES module. -//! \param pui8IVdata is an array of 16 bytes (128 bits), containing the IV -//! value to be configured. The least significant word is in the 0th index. -//! -//! This functions writes the initial vector registers in the AES module. -//! -//! \return None. -// -//***************************************************************************** -void -AESIVSet(uint32_t ui32Base, uint8_t *pui8IVdata) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - - // - // Write the initial vector registers. - // - HWREG(ui32Base + AES_O_IV_IN_0) = *((uint32_t *)(pui8IVdata+0)); - HWREG(ui32Base + AES_O_IV_IN_1) = *((uint32_t *)(pui8IVdata+4)); - HWREG(ui32Base + AES_O_IV_IN_2) = *((uint32_t *)(pui8IVdata+8)); - HWREG(ui32Base + AES_O_IV_IN_3) = *((uint32_t *)(pui8IVdata+12)); -} - -//***************************************************************************** -// -//! Saves the tag registers to a user-defined location. -//! -//! \param ui32Base is the base address of the AES module. -//! \param pui8TagData is pointer to the location that stores the tag data. -//! -//! This function stores the tag data for use authenticated encryption and -//! decryption operations. -//! -//! \return None. -// -//***************************************************************************** -void -AESTagRead(uint32_t ui32Base, uint8_t *pui8TagData) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - - // - // Read the tag data. - // - *((uint32_t *)(pui8TagData+0)) = HWREG((ui32Base + AES_O_TAG_OUT_0)); - *((uint32_t *)(pui8TagData+4)) = HWREG((ui32Base + AES_O_TAG_OUT_1)); - *((uint32_t *)(pui8TagData+8)) = HWREG((ui32Base + AES_O_TAG_OUT_2)); - *((uint32_t *)(pui8TagData+12)) = HWREG((ui32Base + AES_O_TAG_OUT_3)); -} - -//***************************************************************************** -// -//! Used to set the write crypto data length in the AES module. -//! -//! \param ui32Base is the base address of the AES module. -//! \param ui64Length is the crypto data length in bytes. -//! -//! This function stores the cryptographic data length in blocks for all modes. -//! Data lengths up to (2^61 - 1) bytes are allowed. For GCM, any value up -//! to (2^36 - 2) bytes are allowed because a 32-bit block counter is used. For -//! basic modes (ECB/CBC/CTR/ICM/CFB128), zero can be programmed into the -//! length field, indicating that the length is infinite. -//! -//! When this function is called, the engine is triggered to start using -//! this context. -//! -//! \note This length does not include the authentication-only data used in -//! some modes. Use the AESAuthLengthSet() function to specify the -//! authentication data length. -//! -//! \return None -// -//***************************************************************************** -void -AESDataLengthSet(uint32_t ui32Base, uint64_t ui64Length) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - - // - // Write the length register by shifting the 64-bit ui64Length. - // - HWREG(ui32Base + AES_O_C_LENGTH_0) = (uint32_t)(ui64Length); - HWREG(ui32Base + AES_O_C_LENGTH_1) = (uint32_t)(ui64Length >> 32); -} - -//***************************************************************************** -// -//! Sets the optional additional authentication data (AAD) length. -//! -//! \param ui32Base is the base address of the AES module. -//! \param ui32Length is the length in bytes. -//! -//! This function is only used to write the authentication data length in the -//! combined modes (GCM or CCM) and XTS mode. Supported AAD lengths for CCM -//! are from 0 to (2^16 - 28) bytes. For GCM, any value up to (2^32 - 1) can -//! be used. For XTS mode, this register is used to load j. Loading of j is -//! only required if j != 0. j represents the sequential number of the 128-bit -//! blocks inside the data unit. Consequently, j must be multiplied by 16 -//! when passed to this function, thereby placing the block number in -//! bits [31:4] of the register. -//! -//! When this function is called, the engine is triggered to start using -//! this context for GCM and CCM. -//! -//! \return None -// -//***************************************************************************** -void -AESAuthDataLengthSet(uint32_t ui32Base, uint32_t ui32Length) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - - // - // Write the length into the register. - // - HWREG(ui32Base + AES_O_AUTH_LENGTH) = ui32Length; -} - -//***************************************************************************** -// -//! Reads plaintext/ciphertext from data registers without blocking. -//! This api writes data in blocks -//! -//! \param ui32Base is the base address of the AES module. -//! \param pui8Dest is a pointer to an array of words of data. -//! \param ui8Length the length can be from 1 to 16 -//! -//! This function reads a block of either plaintext or ciphertext out of the -//! AES module. If the output data is not ready, the function returns -//! false. If the read completed successfully, the function returns true. -//! A block is 16 bytes or 4 words. -//! -//! \return true or false. -// -//***************************************************************************** -bool -AESDataReadNonBlocking(uint32_t ui32Base, uint8_t *pui8Dest, uint8_t ui8Length) -{ - volatile uint32_t pui32Dest[4]; - uint8_t ui8BytCnt; - uint8_t *pui8DestTemp; - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - if((ui8Length == 0)||(ui8Length>16)) - { - return(false); - } - - // - // Check if the output is ready before reading the data. If it not ready, - // return false. - // - if((AES_CTRL_OUTPUT_READY & (HWREG(ui32Base + AES_O_CTRL))) == 0) - { - return(false); - } - - // - // Read a block of data from the data registers - // - pui32Dest[0] = HWREG(ui32Base + AES_O_DATA_IN_3); - pui32Dest[1] = HWREG(ui32Base + AES_O_DATA_IN_2); - pui32Dest[2] = HWREG(ui32Base + AES_O_DATA_IN_1); - pui32Dest[3] = HWREG(ui32Base + AES_O_DATA_IN_0); - - // - //Copy the data to a block memory - // - pui8DestTemp = (uint8_t *)pui32Dest; - for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++) - { - *(pui8Dest+ui8BytCnt) = *(pui8DestTemp+ui8BytCnt); - } - // - // Read successful, return true. - // - return(true); -} - - -//***************************************************************************** -// -//! Reads plaintext/ciphertext from data registers with blocking. -//! This api writes data in blocks -//! -//! \param ui32Base is the base address of the AES module. -//! \param pui8Dest is a pointer to an array of words. -//! \param ui8Length is the length of data in bytes to be read. -//! ui8Length can be from 1 to 16 -//! -//! This function reads a block of either plaintext or ciphertext out of the -//! AES module. If the output is not ready, the function waits until it -//! is ready. A block is 16 bytes or 4 words. -//! -//! \return None. -// -//***************************************************************************** - -void -AESDataRead(uint32_t ui32Base, uint8_t *pui8Dest, uint8_t ui8Length) -{ - volatile uint32_t pui32Dest[4]; - uint8_t ui8BytCnt; - uint8_t *pui8DestTemp; - - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - if((ui8Length == 0)||(ui8Length>16)) - { - return; - } - - - // - // Wait for the output to be ready before reading the data. - // - while((AES_CTRL_OUTPUT_READY & (HWREG(ui32Base + AES_O_CTRL))) == 0) - { - } - - // - // Read a block of data from the data registers - // - pui32Dest[0] = HWREG(ui32Base + AES_O_DATA_IN_3); - pui32Dest[1] = HWREG(ui32Base + AES_O_DATA_IN_2); - pui32Dest[2] = HWREG(ui32Base + AES_O_DATA_IN_1); - pui32Dest[3] = HWREG(ui32Base + AES_O_DATA_IN_0); - // - //Copy the data to a block memory - // - pui8DestTemp = (uint8_t *)pui32Dest; - for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++) - { - *(pui8Dest+ui8BytCnt) = *(pui8DestTemp+ui8BytCnt); - } - - return; -} - -//***************************************************************************** -// -//! Writes plaintext/ciphertext to data registers without blocking. -//! -//! \param ui32Base is the base address of the AES module. -//! \param pui8Src is a pointer to an array of words of data. -//! \param ui8Length the length can be from 1 to 16 -//! -//! This function writes a block of either plaintext or ciphertext into the -//! AES module. If the input is not ready, the function returns false -//! If the write completed successfully, the function returns true. -//! -//! \return True or false. -// -//***************************************************************************** -bool -AESDataWriteNonBlocking(uint32_t ui32Base, uint8_t *pui8Src, uint8_t ui8Length) -{ - volatile uint32_t pui32Src[4]={0,0,0,0}; - uint8_t ui8BytCnt; - uint8_t *pui8SrcTemp; - - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - if((ui8Length == 0)||(ui8Length>16)) - { - return(false); - } - - // - // Check if the input is ready. If not, then return false. - // - if(!(AES_CTRL_INPUT_READY & (HWREG(ui32Base + AES_O_CTRL)))) - { - return(false); - } - - - // - //Copy the data to a block memory - // - pui8SrcTemp = (uint8_t *)pui32Src; - for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++) - { - *(pui8SrcTemp+ui8BytCnt) = *(pui8Src+ui8BytCnt); - } - // - // Write a block of data into the data registers. - // - HWREG(ui32Base + AES_O_DATA_IN_3) = pui32Src[0]; - HWREG(ui32Base + AES_O_DATA_IN_2) = pui32Src[1]; - HWREG(ui32Base + AES_O_DATA_IN_1) = pui32Src[2]; - HWREG(ui32Base + AES_O_DATA_IN_0) = pui32Src[3]; - - // - // Write successful, return true. - // - return(true); -} - - -//***************************************************************************** -// -//! Writes plaintext/ciphertext to data registers with blocking. -//! -//! \param ui32Base is the base address of the AES module. -//! \param pui8Src is a pointer to an array of bytes. -//! \param ui8Length the length can be from 1 to 16 -//! -//! This function writes a block of either plaintext or ciphertext into the -//! AES module. If the input is not ready, the function waits until it is -//! ready before performing the write. -//! -//! \return None. -// -//***************************************************************************** - -void -AESDataWrite(uint32_t ui32Base, uint8_t *pui8Src, uint8_t ui8Length) -{ - volatile uint32_t pui32Src[4]={0,0,0,0}; - uint8_t ui8BytCnt; - uint8_t *pui8SrcTemp; - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - if((ui8Length == 0)||(ui8Length>16)) - { - return; - } - // - // Wait for input ready. - // - while((AES_CTRL_INPUT_READY & (HWREG(ui32Base + AES_O_CTRL))) == 0) - { - } - - // - //Copy the data to a block memory - // - pui8SrcTemp = (uint8_t *)pui32Src; - for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++) - { - *(pui8SrcTemp+ui8BytCnt) = *(pui8Src+ui8BytCnt); - } - - // - // Write a block of data into the data registers. - // - HWREG(ui32Base + AES_O_DATA_IN_3) = pui32Src[0]; - HWREG(ui32Base + AES_O_DATA_IN_2) = pui32Src[1]; - HWREG(ui32Base + AES_O_DATA_IN_1) = pui32Src[2]; - HWREG(ui32Base + AES_O_DATA_IN_0) = pui32Src[3]; -} - - -//***************************************************************************** -// -//! Used to process(transform) blocks of data, either encrypt or decrypt it. -//! -//! \param ui32Base is the base address of the AES module. -//! \param pui8Src is a pointer to the memory location where the input data -//! is stored. -//! \param pui8Dest is a pointer to the memory location output is written. -//! \param ui32Length is the length of the cryptographic data in bytes. -//! -//! This function iterates the encryption or decryption mechanism number over -//! the data length. Before calling this function, ensure that the AES -//! module is properly configured the key, data size, mode, etc. Only ECB, -//! CBC, CTR, ICM, CFB, XTS and F8 operating modes should be used. The data -//! is processed in 4-word (16-byte) blocks. -//! -//! \note This function only supports values of \e ui32Length less than 2^32, -//! because the memory size is restricted to between 0 to 2^32 bytes. -//! -//! \return Returns true if data was processed successfully. Returns false -//! if data processing failed. -// -//***************************************************************************** -bool -AESDataProcess(uint32_t ui32Base, uint8_t *pui8Src, uint8_t *pui8Dest, - uint32_t ui32Length) -{ - uint32_t ui32Count, ui32BlkCount, ui32ByteCount; - - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - - // - // Write the length register first, which triggers the engine to start - // using this context. - // - AESDataLengthSet(AES_BASE, (uint64_t) ui32Length); - - // - // Now loop until the blocks are written. - // - ui32BlkCount = ui32Length/16; - for(ui32Count = 0; ui32Count < ui32BlkCount; ui32Count += 1) - { - // - // Write the data registers. - // - AESDataWrite(ui32Base, pui8Src + (ui32Count*16) ,16); - - // - // Read the data registers. - // - AESDataRead(ui32Base, pui8Dest + (ui32Count*16) ,16); - - } - - // - //Now handle the residue bytes - // - ui32ByteCount = ui32Length%16; - if(ui32ByteCount) - { - // - // Write the data registers. - // - AESDataWrite(ui32Base, pui8Src + (ui32Count*ui32BlkCount) ,ui32ByteCount); - - // - // Read the data registers. - // - AESDataRead(ui32Base, pui8Dest + (ui32Count*ui32BlkCount) ,ui32ByteCount); - } - - - - // - // Return true to indicate successful completion of the function. - // - return(true); -} -//***************************************************************************** -// -//! Used to generate message authentication code (MAC) using CBC-MAC and F9 mode. -//! -//! \param ui32Base is the base address of the AES module. -//! \param pui8Src is a pointer to the memory location where the input data -//! is stored. -//! \param ui32Length is the length of the cryptographic data in bytes. -//! \param pui8Tag is a pointer to a 4-word array where the hash tag is -//! written. -//! -//! This function processes data to produce a hash tag that can be used tor -//! authentication. Before calling this function, ensure that the AES -//! module is properly configured the key, data size, mode, etc. Only -//! CBC-MAC and F9 modes should be used. -//! -//! \return Returns true if data was processed successfully. Returns false -//! if data processing failed. -// -//***************************************************************************** -bool -AESDataMAC(uint32_t ui32Base, uint8_t *pui8Src, uint32_t ui32Length, - uint8_t *pui8Tag) -{ - uint32_t ui32Count, ui32BlkCount, ui32ByteCount; - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - - // - // Write the length register first, which triggers the engine to start - // using this context. - // - AESDataLengthSet(AES_BASE, (uint64_t) ui32Length); - - // - // Write the data registers. - // - - // - // Now loop until the blocks are written. - // - ui32BlkCount = ui32Length/16; - for(ui32Count = 0; ui32Count < ui32BlkCount; ui32Count += 1) - { - // - // Write the data registers. - // - AESDataWrite(ui32Base, pui8Src + ui32Count*16 ,16); - } - - // - //Now handle the residue bytes - // - ui32ByteCount = ui32Length%16; - if(ui32ByteCount) - { - // - // Write the data registers. - // - AESDataWrite(ui32Base, pui8Src + (ui32Count*ui32BlkCount) ,ui32ByteCount); - } - - // - // Wait for the context data regsiters to be ready. - // - while((AES_CTRL_SVCTXTRDY & (HWREG(AES_BASE + AES_O_CTRL))) == 0) - { - } - - // - // Read the hash tag value. - // - AESTagRead(AES_BASE, pui8Tag); - - // - // Return true to indicate successful completion of the function. - // - return(true); -} - -//***************************************************************************** -// -//! Used for Authenticated encryption (AE) of the data. Processes and authenticates blocks of data, -//! either encrypt the data or decrypt the data. -//! -//! \param ui32Base is the base address of the AES module. -//! \param pui8Src is a pointer to the memory location where the input data -//! is stored. The data must be padded to the 16-byte boundary. -//! \param pui8Dest is a pointer to the memory location output is written. -//! The space for written data must be rounded up to the 16-byte boundary. -//! \param ui32Length is the length of the cryptographic data in bytes. -//! \param pui8AuthSrc is a pointer to the memory location where the -//! additional authentication data is stored. The data must be padded to the -//! 16-byte boundary. -//! \param ui32AuthLength is the length of the additional authentication -//! data in bytes. -//! \param pui8Tag is a pointer to a 4-word array where the hash tag is -//! written. -//! -//! This function encrypts or decrypts blocks of data in addition to -//! authentication data. A hash tag is also produced. Before calling this -//! function, ensure that the AES module is properly configured the key, -//! data size, mode, etc. Only CCM and GCM modes should be used. -//! -//! \return Returns true if data was processed successfully. Returns false -//! if data processing failed. -// -//***************************************************************************** -bool -AESDataProcessAE(uint32_t ui32Base, uint8_t *pui8Src, uint8_t *pui8Dest, - uint32_t ui32Length, uint8_t *pui8AuthSrc, - uint32_t ui32AuthLength, uint8_t *pui8Tag) -{ - uint32_t ui32Count; - - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - - // - // Set the data length. - // - AESDataLengthSet(AES_BASE, (uint64_t) ui32Length); - - // - // Set the additional authentication data length. - // - AESAuthDataLengthSet(AES_BASE, ui32AuthLength); - - // - // Now loop until the authentication data blocks are written. - // - for(ui32Count = 0; ui32Count < ui32AuthLength; ui32Count += 16) - { - // - // Write the data registers. - // - AESDataWrite(ui32Base, pui8AuthSrc + (ui32Count),16); - } - - // - // Now loop until the data blocks are written. - // - for(ui32Count = 0; ui32Count < ui32Length; ui32Count += 16) - { - // - // Write the data registers. - // - AESDataWrite(ui32Base, pui8Src + (ui32Count),16); - - // - // - // Read the data registers. - // - AESDataRead(ui32Base, pui8Dest + (ui32Count),16); - } - - // - // Wait for the context data regsiters to be ready. - // - while((AES_CTRL_SVCTXTRDY & (HWREG(AES_BASE + AES_O_CTRL))) == 0) - { - } - - // - // Read the hash tag value. - // - AESTagRead(AES_BASE, pui8Tag); - - // - // Return true to indicate successful completion of the function. - // - return(true); -} - -//***************************************************************************** -// -//! Returns the current AES module interrupt status. -//! -//! \param ui32Base is the base address of the AES module. -//! \param bMasked is \b false if the raw interrupt status is required and -//! \b true if the masked interrupt status is required. -//! -//! \return Returns a bit mask of the interrupt sources, which is a logical OR -//! of any of the following: -//! -//! - \b AES_INT_CONTEXT_IN - Context interrupt -//! - \b AES_INT_CONTEXT_OUT - Authentication tag (and IV) interrupt. -//! - \b AES_INT_DATA_IN - Data input interrupt -//! - \b AES_INT_DATA_OUT - Data output interrupt -//! - \b AES_INT_DMA_CONTEXT_IN - Context DMA done interrupt -//! - \b AES_INT_DMA_CONTEXT_OUT - Authentication tag (and IV) DMA done -//! interrupt -//! - \b AES_INT_DMA_DATA_IN - Data input DMA done interrupt -//! - \b AES_INT_DMA_DATA_OUT - Data output DMA done interrupt -// -//***************************************************************************** -uint32_t -AESIntStatus(uint32_t ui32Base, bool bMasked) -{ - uint32_t ui32Temp; - uint32_t ui32IrqEnable; - - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - - // - // Read the IRQ status register and return the value. - // - if(bMasked) - { - ui32Temp = HWREG(DTHE_BASE + DTHE_O_AES_MIS); - ui32IrqEnable = HWREG(ui32Base + AES_O_IRQENABLE); - return((HWREG(ui32Base + AES_O_IRQSTATUS) & - ui32IrqEnable) | ((ui32Temp & 0x0000000F) << 16)); - } - else - { - ui32Temp = HWREG(DTHE_BASE + DTHE_O_AES_RIS); - return(HWREG(ui32Base + AES_O_IRQSTATUS) | - ((ui32Temp & 0x0000000F) << 16)); - } -} - -//***************************************************************************** -// -//! Enables AES module interrupts. -//! -//! \param ui32Base is the base address of the AES module. -//! \param ui32IntFlags is a bit mask of the interrupt sources to enable. -//! -//! This function enables the interrupts in the AES module. The \e ui32IntFlags -//! parameter is the logical OR of any of the following: -//! -//! - \b AES_INT_CONTEXT_IN - Context interrupt -//! - \b AES_INT_CONTEXT_OUT - Authentication tag (and IV) interrupt -//! - \b AES_INT_DATA_IN - Data input interrupt -//! - \b AES_INT_DATA_OUT - Data output interrupt -//! - \b AES_INT_DMA_CONTEXT_IN - Context DMA done interrupt -//! - \b AES_INT_DMA_CONTEXT_OUT - Authentication tag (and IV) DMA done -//! interrupt -//! - \b AES_INT_DMA_DATA_IN - Data input DMA done interrupt -//! - \b AES_INT_DMA_DATA_OUT - Data output DMA done interrupt -//! -//! \note Interrupts that have been previously been enabled are not disabled -//! when this function is called. -//! -//! \return None. -// -//***************************************************************************** -void -AESIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - ASSERT((ui32IntFlags == AES_INT_CONTEXT_IN) || - (ui32IntFlags == AES_INT_CONTEXT_OUT) || - (ui32IntFlags == AES_INT_DATA_IN) || - (ui32IntFlags == AES_INT_DATA_OUT) || - (ui32IntFlags == AES_INT_DMA_CONTEXT_IN) || - (ui32IntFlags == AES_INT_DMA_CONTEXT_OUT) || - (ui32IntFlags == AES_INT_DMA_DATA_IN) || - (ui32IntFlags == AES_INT_DMA_DATA_OUT)); - - // - // Set the flags. - // - HWREG(DTHE_BASE + DTHE_O_AES_IM) &= ~((ui32IntFlags & 0x000F0000) >> 16); - HWREG(ui32Base + AES_O_IRQENABLE) |= ui32IntFlags & 0x0000ffff; -} - -//***************************************************************************** -// -//! Disables AES module interrupts. -//! -//! \param ui32Base is the base address of the AES module. -//! \param ui32IntFlags is a bit mask of the interrupt sources to disable. -//! -//! This function disables the interrupt sources in the AES module. The -//! \e ui32IntFlags parameter is the logical OR of any of the following: -//! -//! - \b AES_INT_CONTEXT_IN - Context interrupt -//! - \b AES_INT_CONTEXT_OUT - Authentication tag (and IV) interrupt -//! - \b AES_INT_DATA_IN - Data input interrupt -//! - \b AES_INT_DATA_OUT - Data output interrupt -//! - \b AES_INT_DMA_CONTEXT_IN - Context DMA done interrupt -//! - \b AES_INT_DMA_CONTEXT_OUT - Authentication tag (and IV) DMA done -//! interrupt -//! - \b AES_INT_DMA_DATA_IN - Data input DMA done interrupt -//! - \b AES_INT_DMA_DATA_OUT - Data output DMA done interrupt -//! -//! \note The DMA done interrupts are the only interrupts that can be cleared. -//! The remaining interrupts can be disabled instead using AESIntDisable(). -//! -//! \return None. -// -//***************************************************************************** -void -AESIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - ASSERT((ui32IntFlags == AES_INT_CONTEXT_IN) || - (ui32IntFlags == AES_INT_CONTEXT_OUT) || - (ui32IntFlags == AES_INT_DATA_IN) || - (ui32IntFlags == AES_INT_DATA_OUT) || - (ui32IntFlags == AES_INT_DMA_CONTEXT_IN) || - (ui32IntFlags == AES_INT_DMA_CONTEXT_OUT) || - (ui32IntFlags == AES_INT_DMA_DATA_IN) || - (ui32IntFlags == AES_INT_DMA_DATA_OUT)); - - // - // Clear the flags. - // - HWREG(DTHE_BASE + DTHE_O_AES_IM) |= ((ui32IntFlags & 0x000F0000) >> 16); - HWREG(ui32Base + AES_O_IRQENABLE) &= ~(ui32IntFlags & 0x0000ffff); -} - -//***************************************************************************** -// -//! Clears AES module interrupts. -//! -//! \param ui32Base is the base address of the AES module. -//! \param ui32IntFlags is a bit mask of the interrupt sources to disable. -//! -//! This function clears the interrupt sources in the AES module. The -//! \e ui32IntFlags parameter is the logical OR of any of the following: -//! -//! - \b AES_INT_DMA_CONTEXT_IN - Context DMA done interrupt -//! - \b AES_INT_DMA_CONTEXT_OUT - Authentication tag (and IV) DMA done -//! interrupt -//! - \b AES_INT_DMA_DATA_IN - Data input DMA done interrupt -//! - \b AES_INT_DMA_DATA_OUT - Data output DMA done interrupt -//! -//! \note Only the DMA done interrupts can be cleared. The remaining -//! interrupts should be disabled with AESIntDisable(). -//! -//! \return None. -// -//***************************************************************************** -void -AESIntClear(uint32_t ui32Base, uint32_t ui32IntFlags) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - ASSERT((ui32IntFlags == AES_INT_DMA_CONTEXT_IN) || - (ui32IntFlags == AES_INT_DMA_CONTEXT_OUT) || - (ui32IntFlags == AES_INT_DMA_DATA_IN) || - (ui32IntFlags == AES_INT_DMA_DATA_OUT)); - - HWREG(DTHE_BASE + DTHE_O_AES_IC) = ((ui32IntFlags >> 16) & 0x0000000F); -} - -//***************************************************************************** -// -//! Registers an interrupt handler for the AES module. -//! -//! \param ui32Base is the base address of the AES module. -//! \param pfnHandler is a pointer to the function to be called when the -//! enabled AES interrupts occur. -//! -//! This function registers the interrupt handler in the interrupt vector -//! table, and enables AES interrupts on the interrupt controller; specific AES -//! interrupt sources must be enabled using AESIntEnable(). The interrupt -//! handler being registered must clear the source of the interrupt using -//! AESIntClear(). -//! -//! If the application is using a static interrupt vector table stored in -//! flash, then it is not necessary to register the interrupt handler this way. -//! Instead, IntEnable() is used to enable AES interrupts on the -//! interrupt controller. -//! -//! \sa IntRegister() for important information about registering interrupt -//! handlers. -//! -//! \return None. -// -//***************************************************************************** -void -AESIntRegister(uint32_t ui32Base, void(*pfnHandler)(void)) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - - // - // Register the interrupt handler. - // - IntRegister(INT_AES, pfnHandler); - - // - // Enable the interrupt - // - IntEnable(INT_AES); -} - -//***************************************************************************** -// -//! Unregisters an interrupt handler for the AES module. -//! -//! \param ui32Base is the base address of the AES module. -//! -//! This function unregisters the previously registered interrupt handler and -//! disables the interrupt in the interrupt controller. -//! -//! \sa IntRegister() for important information about registering interrupt -//! handlers. -//! -//! \return None. -// -//***************************************************************************** -void -AESIntUnregister(uint32_t ui32Base) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - - // - // Disable the interrupt. - // - IntDisable(INT_AES); - - // - // Unregister the interrupt handler. - // - IntUnregister(INT_AES); -} - -//***************************************************************************** -// -//! Enables uDMA requests for the AES module. -//! -//! \param ui32Base is the base address of the AES module. -//! \param ui32Flags is a bit mask of the uDMA requests to be enabled. -//! -//! This function enables the uDMA request sources in the AES module. -//! The \e ui32Flags parameter is the logical OR of any of the following: -//! -//! - \b AES_DMA_DATA_IN -//! - \b AES_DMA_DATA_OUT -//! - \b AES_DMA_CONTEXT_IN -//! - \b AES_DMA_CONTEXT_OUT -//! -//! \return None. -// -//***************************************************************************** -void -AESDMAEnable(uint32_t ui32Base, uint32_t ui32Flags) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - ASSERT((ui32Flags == AES_DMA_DATA_IN) || - (ui32Flags == AES_DMA_DATA_OUT) || - (ui32Flags == AES_DMA_CONTEXT_IN) || - (ui32Flags == AES_DMA_CONTEXT_OUT)); - - // - // Set the flags in the current register value. - // - HWREG(ui32Base + AES_O_SYSCONFIG) |= ui32Flags; -} - -//***************************************************************************** -// -//! Disables uDMA requests for the AES module. -//! -//! \param ui32Base is the base address of the AES module. -//! \param ui32Flags is a bit mask of the uDMA requests to be disabled. -//! -//! This function disables the uDMA request sources in the AES module. -//! The \e ui32Flags parameter is the logical OR of any of the -//! following: -//! -//! - \b AES_DMA_DATA_IN -//! - \b AES_DMA_DATA_OUT -//! - \b AES_DMA_CONTEXT_IN -//! - \b AES_DMA_CONTEXT_OUT -//! -//! \return None. -// -//***************************************************************************** -void -AESDMADisable(uint32_t ui32Base, uint32_t ui32Flags) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == AES_BASE); - ASSERT((ui32Flags == AES_DMA_DATA_IN) || - (ui32Flags == AES_DMA_DATA_OUT) || - (ui32Flags == AES_DMA_CONTEXT_IN) || - (ui32Flags == AES_DMA_CONTEXT_OUT)); - - // - // Clear the flags in the current register value. - // - HWREG(ui32Base + AES_O_SYSCONFIG) &= ~ui32Flags; -} - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** +//*****************************************************************************
+//
+// aes.c
+//
+// Driver for the AES module.
+//
+// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+//
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the
+// distribution.
+//
+// Neither the name of Texas Instruments Incorporated nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! \addtogroup AES_Advanced_Encryption_Standard_api
+//! @{
+//
+//*****************************************************************************
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "inc/hw_aes.h"
+#include "inc/hw_dthe.h"
+#include "inc/hw_ints.h"
+#include "inc/hw_memmap.h"
+#include "inc/hw_nvic.h"
+#include "inc/hw_types.h"
+#include "aes.h"
+#include "debug.h"
+#include "interrupt.h"
+
+#define AES_BLOCK_SIZE_IN_BYTES 16
+
+//*****************************************************************************
+//
+//! Configures the AES module.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param ui32Config is the configuration of the AES module.
+//!
+//! This function configures the AES module based on the specified parameters.
+//! It does not change any DMA- or interrupt-related parameters.
+//!
+//! The ui32Config parameter is a bit-wise OR of a number of configuration
+//! flags. The valid flags are grouped based on their function.
+//!
+//! The direction of the operation is specified with only of following flags:
+//!
+//! - \b AES_CFG_DIR_ENCRYPT - Encryption mode
+//! - \b AES_CFG_DIR_DECRYPT - Decryption mode
+//!
+//! The key size is specified with only one of the following flags:
+//!
+//! - \b AES_CFG_KEY_SIZE_128BIT - Key size of 128 bits
+//! - \b AES_CFG_KEY_SIZE_192BIT - Key size of 192 bits
+//! - \b AES_CFG_KEY_SIZE_256BIT - Key size of 256 bits
+//!
+//! The mode of operation is specified with only one of the following flags.
+//!
+//! - \b AES_CFG_MODE_ECB - Electronic codebook mode
+//! - \b AES_CFG_MODE_CBC - Cipher-block chaining mode
+//! - \b AES_CFG_MODE_CFB - Cipher feedback mode
+//! - \b AES_CFG_MODE_CTR - Counter mode
+//! - \b AES_CFG_MODE_ICM - Integer counter mode
+//! - \b AES_CFG_MODE_XTS - Ciphertext stealing mode
+//! - \b AES_CFG_MODE_XTS_TWEAKJL - XEX-based tweaked-codebook mode with
+//! ciphertext stealing with previous/intermediate tweak value and j loaded
+//! - \b AES_CFG_MODE_XTS_K2IJL - XEX-based tweaked-codebook mode with
+//! ciphertext stealing with key2, i and j loaded
+//! - \b AES_CFG_MODE_XTS_K2ILJ0 - XEX-based tweaked-codebook mode with
+//! ciphertext stealing with key2 and i loaded, j = 0
+//! - \b AES_CFG_MODE_F8 - F8 mode
+//! - \b AES_CFG_MODE_F9 - F9 mode
+//! - \b AES_CFG_MODE_CBCMAC - Cipher block chaining message authentication
+//! code mode
+//! - \b AES_CFG_MODE_GCM - Galois/counter mode
+//! - \b AES_CFG_MODE_GCM_HLY0ZERO - Galois/counter mode with GHASH with H
+//! loaded and Y0-encrypted forced to zero
+//! - \b AES_CFG_MODE_GCM_HLY0CALC - Galois/counter mode with GHASH with H
+//! loaded and Y0-encrypted calculated internally
+//! - \b AES_CFG_MODE_GCM_HY0CALC - Galois/Counter mode with autonomous GHASH
+//! (both H and Y0-encrypted calculated internally)
+//! - \b AES_CFG_MODE_CCM - Counter with CBC-MAC mode
+//!
+//! The following defines are used to specify the counter width. It is only
+//! required to be defined when using CTR, CCM, or GCM modes, only one of the
+//! following defines must be used to specify the counter width length:
+//!
+//! - \b AES_CFG_CTR_WIDTH_32 - Counter is 32 bits
+//! - \b AES_CFG_CTR_WIDTH_64 - Counter is 64 bits
+//! - \b AES_CFG_CTR_WIDTH_96 - Counter is 96 bits
+//! - \b AES_CFG_CTR_WIDTH_128 - Counter is 128 bits
+//!
+//! Only one of the following defines must be used to specify the length field
+//! for CCM operations (L):
+//!
+//! - \b AES_CFG_CCM_L_2 - 2 bytes
+//! - \b AES_CFG_CCM_L_4 - 4 bytes
+//! - \b AES_CFG_CCM_L_8 - 8 bytes
+//!
+//! Only one of the following defines must be used to specify the length of the
+//! authentication field for CCM operations (M) through the \e ui32Config
+//! argument in the AESConfigSet() function:
+//!
+//! - \b AES_CFG_CCM_M_4 - 4 bytes
+//! - \b AES_CFG_CCM_M_6 - 6 bytes
+//! - \b AES_CFG_CCM_M_8 - 8 bytes
+//! - \b AES_CFG_CCM_M_10 - 10 bytes
+//! - \b AES_CFG_CCM_M_12 - 12 bytes
+//! - \b AES_CFG_CCM_M_14 - 14 bytes
+//! - \b AES_CFG_CCM_M_16 - 16 bytes
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESConfigSet(uint32_t ui32Base, uint32_t ui32Config)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+ ASSERT((ui32Config & AES_CFG_DIR_ENCRYPT) ||
+ (ui32Config & AES_CFG_DIR_DECRYPT));
+ ASSERT((ui32Config & AES_CFG_KEY_SIZE_128BIT) ||
+ (ui32Config & AES_CFG_KEY_SIZE_192BIT) ||
+ (ui32Config & AES_CFG_KEY_SIZE_256BIT));
+ ASSERT((ui32Config & AES_CFG_MODE_ECB) ||
+ (ui32Config & AES_CFG_MODE_CBC) ||
+ (ui32Config & AES_CFG_MODE_CTR) ||
+ (ui32Config & AES_CFG_MODE_ICM) ||
+ (ui32Config & AES_CFG_MODE_CFB) ||
+ (ui32Config & AES_CFG_MODE_XTS_TWEAKJL) ||
+ (ui32Config & AES_CFG_MODE_XTS_K2IJL) ||
+ (ui32Config & AES_CFG_MODE_XTS_K2ILJ0) ||
+ (ui32Config & AES_CFG_MODE_F8) ||
+ (ui32Config & AES_CFG_MODE_F9) ||
+ (ui32Config & AES_CFG_MODE_CTR) ||
+ (ui32Config & AES_CFG_MODE_CBCMAC) ||
+ (ui32Config & AES_CFG_MODE_GCM_HLY0ZERO) ||
+ (ui32Config & AES_CFG_MODE_GCM_HLY0CALC) ||
+ (ui32Config & AES_CFG_MODE_GCM_HY0CALC) ||
+ (ui32Config & AES_CFG_MODE_CCM));
+ ASSERT(((ui32Config & AES_CFG_MODE_CTR) ||
+ (ui32Config & AES_CFG_MODE_GCM_HLY0ZERO) ||
+ (ui32Config & AES_CFG_MODE_GCM_HLY0CALC) ||
+ (ui32Config & AES_CFG_MODE_GCM_HY0CALC) ||
+ (ui32Config & AES_CFG_MODE_CCM)) &&
+ ((ui32Config & AES_CFG_CTR_WIDTH_32) ||
+ (ui32Config & AES_CFG_CTR_WIDTH_64) ||
+ (ui32Config & AES_CFG_CTR_WIDTH_96) ||
+ (ui32Config & AES_CFG_CTR_WIDTH_128)));
+ ASSERT((ui32Config & AES_CFG_MODE_CCM) &&
+ ((ui32Config & AES_CFG_CCM_L_2) ||
+ (ui32Config & AES_CFG_CCM_L_4) ||
+ (ui32Config & AES_CFG_CCM_L_8)) &&
+ ((ui32Config & AES_CFG_CCM_M_4) ||
+ (ui32Config & AES_CFG_CCM_M_6) ||
+ (ui32Config & AES_CFG_CCM_M_8) ||
+ (ui32Config & AES_CFG_CCM_M_10) ||
+ (ui32Config & AES_CFG_CCM_M_12) ||
+ (ui32Config & AES_CFG_CCM_M_14) ||
+ (ui32Config & AES_CFG_CCM_M_16)));
+
+ //
+ // Backup the save context field before updating the register.
+ //
+ if(HWREG(ui32Base + AES_O_CTRL) & AES_CTRL_SAVE_CONTEXT)
+ {
+ ui32Config |= AES_CTRL_SAVE_CONTEXT;
+ }
+
+ //
+ // Write the CTRL register with the new value
+ //
+ HWREG(ui32Base + AES_O_CTRL) = ui32Config;
+}
+
+//*****************************************************************************
+//
+//! Writes the key 1 configuration registers, which are used for encryption or
+//! decryption.
+//!
+//! \param ui32Base is the base address for the AES module.
+//! \param pui8Key is an array of bytes, containing the key to be
+//! configured. The least significant word in the 0th index.
+//! \param ui32Keysize is the size of the key, which must be one of the
+//! following values: \b AES_CFG_KEY_SIZE_128, \b AES_CFG_KEY_SIZE_192, or
+//! \b AES_CFG_KEY_SIZE_256.
+//!
+//! This function writes key 1 configuration registers based on the key
+//! size. This function is used in all modes.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESKey1Set(uint32_t ui32Base, uint8_t *pui8Key, uint32_t ui32Keysize)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+ ASSERT((ui32Keysize == AES_CFG_KEY_SIZE_128BIT) ||
+ (ui32Keysize == AES_CFG_KEY_SIZE_192BIT) ||
+ (ui32Keysize == AES_CFG_KEY_SIZE_256BIT));
+
+ //
+ // With all key sizes, the first 4 words are written.
+ //
+ HWREG(ui32Base + AES_O_KEY1_0) = * ((uint32_t *)(pui8Key + 0));
+ HWREG(ui32Base + AES_O_KEY1_1) = * ((uint32_t *)(pui8Key + 4));
+ HWREG(ui32Base + AES_O_KEY1_2) = * ((uint32_t *)(pui8Key + 8));
+ HWREG(ui32Base + AES_O_KEY1_3) = * ((uint32_t *)(pui8Key + 12));
+
+ //
+ // The key is 192 or 256 bits. Write the next 2 words.
+ //
+ if(ui32Keysize != AES_CFG_KEY_SIZE_128BIT)
+ {
+ HWREG(ui32Base + AES_O_KEY1_4) = * ((uint32_t *)(pui8Key + 16));
+ HWREG(ui32Base + AES_O_KEY1_5) = * ((uint32_t *)(pui8Key + 20));
+ }
+
+ //
+ // The key is 256 bits. Write the last 2 words.
+ //
+ if(ui32Keysize == AES_CFG_KEY_SIZE_256BIT)
+ {
+ HWREG(ui32Base + AES_O_KEY1_6) = * ((uint32_t *)(pui8Key + 24));
+ HWREG(ui32Base + AES_O_KEY1_7) = * ((uint32_t *)(pui8Key + 28));
+ }
+}
+
+//*****************************************************************************
+//
+//! Writes the key 2 configuration registers, which are used for encryption or
+//! decryption.
+//!
+//! \param ui32Base is the base address for the AES module.
+//! \param pui8Key is an array of bytes, containing the key to be
+//! configured. The least significant word in the 0th index.
+//! \param ui32Keysize is the size of the key, which must be one of the
+//! following values: \b AES_CFG_KEY_SIZE_128, \b AES_CFG_KEY_SIZE_192, or
+//! \b AES_CFG_KEY_SIZE_256.
+//!
+//! This function writes the key 2 configuration registers based on the key
+//! size. This function is used in the F8, F9, XTS, CCM, and CBC-MAC modes.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESKey2Set(uint32_t ui32Base, uint8_t *pui8Key, uint32_t ui32Keysize)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+ ASSERT((ui32Keysize == AES_CFG_KEY_SIZE_128BIT) ||
+ (ui32Keysize == AES_CFG_KEY_SIZE_192BIT) ||
+ (ui32Keysize == AES_CFG_KEY_SIZE_256BIT));
+
+ //
+ // With all key sizes, the first 4 words are written.
+ //
+ HWREG(ui32Base + AES_O_KEY2_0) = * ((uint32_t *)(pui8Key + 0));
+ HWREG(ui32Base + AES_O_KEY2_1) = * ((uint32_t *)(pui8Key + 4));
+ HWREG(ui32Base + AES_O_KEY2_2) = * ((uint32_t *)(pui8Key + 8));
+ HWREG(ui32Base + AES_O_KEY2_3) = * ((uint32_t *)(pui8Key + 12));
+
+ //
+ // The key is 192 or 256 bits. Write the next 2 words.
+ //
+ if(ui32Keysize != AES_CFG_KEY_SIZE_128BIT)
+ {
+ HWREG(ui32Base + AES_O_KEY2_4) = * ((uint32_t *)(pui8Key + 16));
+ HWREG(ui32Base + AES_O_KEY2_5) = * ((uint32_t *)(pui8Key + 20));
+ }
+
+ //
+ // The key is 256 bits. Write the last 2 words.
+ //
+ if(ui32Keysize == AES_CFG_KEY_SIZE_256BIT)
+ {
+ HWREG(ui32Base + AES_O_KEY2_6) = * ((uint32_t *)(pui8Key + 24));
+ HWREG(ui32Base + AES_O_KEY2_7) = * ((uint32_t *)(pui8Key + 28));
+ }
+}
+
+//*****************************************************************************
+//
+//! Writes key 3 configuration registers, which are used for encryption or
+//! decryption.
+//!
+//! \param ui32Base is the base address for the AES module.
+//! \param pui8Key is a pointer to an array bytes, containing
+//! the key to be configured. The least significant word is in the 0th index.
+//!
+//! This function writes the key 2 configuration registers with key 3 data
+//! used in CBC-MAC and F8 modes. This key is always 128 bits.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESKey3Set(uint32_t ui32Base, uint8_t *pui8Key)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+
+ //
+ // Write the key into the upper 4 key registers
+ //
+ HWREG(ui32Base + AES_O_KEY2_4) = * ((uint32_t *)(pui8Key + 0));
+ HWREG(ui32Base + AES_O_KEY2_5) = * ((uint32_t *)(pui8Key + 4));
+ HWREG(ui32Base + AES_O_KEY2_6) = * ((uint32_t *)(pui8Key + 8));
+ HWREG(ui32Base + AES_O_KEY2_7) = * ((uint32_t *)(pui8Key + 12));
+}
+
+//*****************************************************************************
+//
+//! Writes the Initial Vector (IV) register, needed in some of the AES Modes.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param pui8IVdata is an array of 16 bytes (128 bits), containing the IV
+//! value to be configured. The least significant word is in the 0th index.
+//!
+//! This functions writes the initial vector registers in the AES module.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESIVSet(uint32_t ui32Base, uint8_t *pui8IVdata)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+
+ //
+ // Write the initial vector registers.
+ //
+ HWREG(ui32Base + AES_O_IV_IN_0) = *((uint32_t *)(pui8IVdata+0));
+ HWREG(ui32Base + AES_O_IV_IN_1) = *((uint32_t *)(pui8IVdata+4));
+ HWREG(ui32Base + AES_O_IV_IN_2) = *((uint32_t *)(pui8IVdata+8));
+ HWREG(ui32Base + AES_O_IV_IN_3) = *((uint32_t *)(pui8IVdata+12));
+}
+
+
+//*****************************************************************************
+//
+//! Reads the Initial Vector (IV) register, needed in some of the AES Modes.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param pui8IVdata is pointer to an array of 16 bytes.
+//!
+//! This functions reads the initial vector registers in the AES module.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESIVGet(uint32_t ui32Base, uint8_t *pui8IVdata)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+
+ //
+ // Write the initial vector registers.
+ //
+ *((uint32_t *)(pui8IVdata+ 0)) = HWREG(ui32Base + AES_O_IV_IN_0);
+ *((uint32_t *)(pui8IVdata+ 4)) = HWREG(ui32Base + AES_O_IV_IN_1);
+ *((uint32_t *)(pui8IVdata+ 8)) = HWREG(ui32Base + AES_O_IV_IN_2);
+ *((uint32_t *)(pui8IVdata+12)) = HWREG(ui32Base + AES_O_IV_IN_3);
+}
+
+//*****************************************************************************
+//
+//! Saves the tag registers to a user-defined location.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param pui8TagData is pointer to the location that stores the tag data.
+//!
+//! This function stores the tag data for use authenticated encryption and
+//! decryption operations.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESTagRead(uint32_t ui32Base, uint8_t *pui8TagData)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+
+ //
+ // Read the tag data.
+ //
+ *((uint32_t *)(pui8TagData+0)) = HWREG((ui32Base + AES_O_TAG_OUT_0));
+ *((uint32_t *)(pui8TagData+4)) = HWREG((ui32Base + AES_O_TAG_OUT_1));
+ *((uint32_t *)(pui8TagData+8)) = HWREG((ui32Base + AES_O_TAG_OUT_2));
+ *((uint32_t *)(pui8TagData+12)) = HWREG((ui32Base + AES_O_TAG_OUT_3));
+}
+
+//*****************************************************************************
+//
+//! Used to set the write crypto data length in the AES module.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param ui64Length is the crypto data length in bytes.
+//!
+//! This function stores the cryptographic data length in blocks for all modes.
+//! Data lengths up to (2^61 - 1) bytes are allowed. For GCM, any value up
+//! to (2^36 - 2) bytes are allowed because a 32-bit block counter is used. For
+//! basic modes (ECB/CBC/CTR/ICM/CFB128), zero can be programmed into the
+//! length field, indicating that the length is infinite.
+//!
+//! When this function is called, the engine is triggered to start using
+//! this context.
+//!
+//! \note This length does not include the authentication-only data used in
+//! some modes. Use the AESAuthLengthSet() function to specify the
+//! authentication data length.
+//!
+//! \return None
+//
+//*****************************************************************************
+void
+AESDataLengthSet(uint32_t ui32Base, uint64_t ui64Length)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+
+ //
+ // Write the length register by shifting the 64-bit ui64Length.
+ //
+ HWREG(ui32Base + AES_O_C_LENGTH_0) = (uint32_t)(ui64Length);
+ HWREG(ui32Base + AES_O_C_LENGTH_1) = (uint32_t)(ui64Length >> 32);
+}
+
+//*****************************************************************************
+//
+//! Sets the optional additional authentication data (AAD) length.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param ui32Length is the length in bytes.
+//!
+//! This function is only used to write the authentication data length in the
+//! combined modes (GCM or CCM) and XTS mode. Supported AAD lengths for CCM
+//! are from 0 to (2^16 - 28) bytes. For GCM, any value up to (2^32 - 1) can
+//! be used. For XTS mode, this register is used to load j. Loading of j is
+//! only required if j != 0. j represents the sequential number of the 128-bit
+//! blocks inside the data unit. Consequently, j must be multiplied by 16
+//! when passed to this function, thereby placing the block number in
+//! bits [31:4] of the register.
+//!
+//! When this function is called, the engine is triggered to start using
+//! this context for GCM and CCM.
+//!
+//! \return None
+//
+//*****************************************************************************
+void
+AESAuthDataLengthSet(uint32_t ui32Base, uint32_t ui32Length)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+
+ //
+ // Write the length into the register.
+ //
+ HWREG(ui32Base + AES_O_AUTH_LENGTH) = ui32Length;
+}
+
+//*****************************************************************************
+//
+//! Reads plaintext/ciphertext from data registers without blocking.
+//! This api writes data in blocks
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param pui8Dest is a pointer to an array of words of data.
+//! \param ui8Length the length can be from 1 to 16
+//!
+//! This function reads a block of either plaintext or ciphertext out of the
+//! AES module. If the output data is not ready, the function returns
+//! false. If the read completed successfully, the function returns true.
+//! A block is 16 bytes or 4 words.
+//!
+//! \return true or false.
+//
+//*****************************************************************************
+bool
+AESDataReadNonBlocking(uint32_t ui32Base, uint8_t *pui8Dest, uint8_t ui8Length)
+{
+ volatile uint32_t pui32Dest[4];
+ uint8_t ui8BytCnt;
+ uint8_t *pui8DestTemp;
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+ if((ui8Length == 0)||(ui8Length>16))
+ {
+ return(false);
+ }
+
+ //
+ // Check if the output is ready before reading the data. If it not ready,
+ // return false.
+ //
+ if((AES_CTRL_OUTPUT_READY & (HWREG(ui32Base + AES_O_CTRL))) == 0)
+ {
+ return(false);
+ }
+
+ //
+ // Read a block of data from the data registers
+ //
+ pui32Dest[0] = HWREG(ui32Base + AES_O_DATA_IN_3);
+ pui32Dest[1] = HWREG(ui32Base + AES_O_DATA_IN_2);
+ pui32Dest[2] = HWREG(ui32Base + AES_O_DATA_IN_1);
+ pui32Dest[3] = HWREG(ui32Base + AES_O_DATA_IN_0);
+
+ //
+ //Copy the data to a block memory
+ //
+ pui8DestTemp = (uint8_t *)pui32Dest;
+ for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++)
+ {
+ *(pui8Dest+ui8BytCnt) = *(pui8DestTemp+ui8BytCnt);
+ }
+ //
+ // Read successful, return true.
+ //
+ return(true);
+}
+
+
+//*****************************************************************************
+//
+//! Reads plaintext/ciphertext from data registers with blocking.
+//! This api writes data in blocks
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param pui8Dest is a pointer to an array of words.
+//! \param ui8Length is the length of data in bytes to be read.
+//! ui8Length can be from 1 to 16
+//!
+//! This function reads a block of either plaintext or ciphertext out of the
+//! AES module. If the output is not ready, the function waits until it
+//! is ready. A block is 16 bytes or 4 words.
+//!
+//! \return None.
+//
+//*****************************************************************************
+
+void
+AESDataRead(uint32_t ui32Base, uint8_t *pui8Dest, uint8_t ui8Length)
+{
+ volatile uint32_t pui32Dest[4];
+ uint8_t ui8BytCnt;
+ uint8_t *pui8DestTemp;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+ if((ui8Length == 0)||(ui8Length>16))
+ {
+ return;
+ }
+
+
+ //
+ // Wait for the output to be ready before reading the data.
+ //
+ while((AES_CTRL_OUTPUT_READY & (HWREG(ui32Base + AES_O_CTRL))) == 0)
+ {
+ }
+
+ //
+ // Read a block of data from the data registers
+ //
+ pui32Dest[0] = HWREG(ui32Base + AES_O_DATA_IN_3);
+ pui32Dest[1] = HWREG(ui32Base + AES_O_DATA_IN_2);
+ pui32Dest[2] = HWREG(ui32Base + AES_O_DATA_IN_1);
+ pui32Dest[3] = HWREG(ui32Base + AES_O_DATA_IN_0);
+ //
+ //Copy the data to a block memory
+ //
+ pui8DestTemp = (uint8_t *)pui32Dest;
+ for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++)
+ {
+ *(pui8Dest+ui8BytCnt) = *(pui8DestTemp+ui8BytCnt);
+ }
+
+ return;
+}
+
+//*****************************************************************************
+//
+//! Writes plaintext/ciphertext to data registers without blocking.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param pui8Src is a pointer to an array of words of data.
+//! \param ui8Length the length can be from 1 to 16
+//!
+//! This function writes a block of either plaintext or ciphertext into the
+//! AES module. If the input is not ready, the function returns false
+//! If the write completed successfully, the function returns true.
+//!
+//! \return True or false.
+//
+//*****************************************************************************
+bool
+AESDataWriteNonBlocking(uint32_t ui32Base, uint8_t *pui8Src, uint8_t ui8Length)
+{
+ volatile uint32_t pui32Src[4]={0,0,0,0};
+ uint8_t ui8BytCnt;
+ uint8_t *pui8SrcTemp;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+ if((ui8Length == 0)||(ui8Length>16))
+ {
+ return(false);
+ }
+
+ //
+ // Check if the input is ready. If not, then return false.
+ //
+ if(!(AES_CTRL_INPUT_READY & (HWREG(ui32Base + AES_O_CTRL))))
+ {
+ return(false);
+ }
+
+
+ //
+ //Copy the data to a block memory
+ //
+ pui8SrcTemp = (uint8_t *)pui32Src;
+ for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++)
+ {
+ *(pui8SrcTemp+ui8BytCnt) = *(pui8Src+ui8BytCnt);
+ }
+ //
+ // Write a block of data into the data registers.
+ //
+ HWREG(ui32Base + AES_O_DATA_IN_3) = pui32Src[0];
+ HWREG(ui32Base + AES_O_DATA_IN_2) = pui32Src[1];
+ HWREG(ui32Base + AES_O_DATA_IN_1) = pui32Src[2];
+ HWREG(ui32Base + AES_O_DATA_IN_0) = pui32Src[3];
+
+ //
+ // Write successful, return true.
+ //
+ return(true);
+}
+
+
+//*****************************************************************************
+//
+//! Writes plaintext/ciphertext to data registers with blocking.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param pui8Src is a pointer to an array of bytes.
+//! \param ui8Length the length can be from 1 to 16
+//!
+//! This function writes a block of either plaintext or ciphertext into the
+//! AES module. If the input is not ready, the function waits until it is
+//! ready before performing the write.
+//!
+//! \return None.
+//
+//*****************************************************************************
+
+void
+AESDataWrite(uint32_t ui32Base, uint8_t *pui8Src, uint8_t ui8Length)
+{
+ volatile uint32_t pui32Src[4]={0,0,0,0};
+ uint8_t ui8BytCnt;
+ uint8_t *pui8SrcTemp;
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+ if((ui8Length == 0)||(ui8Length>16))
+ {
+ return;
+ }
+ //
+ // Wait for input ready.
+ //
+ while((AES_CTRL_INPUT_READY & (HWREG(ui32Base + AES_O_CTRL))) == 0)
+ {
+ }
+
+ //
+ //Copy the data to a block memory
+ //
+ pui8SrcTemp = (uint8_t *)pui32Src;
+ for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++)
+ {
+ *(pui8SrcTemp+ui8BytCnt) = *(pui8Src+ui8BytCnt);
+ }
+
+ //
+ // Write a block of data into the data registers.
+ //
+ HWREG(ui32Base + AES_O_DATA_IN_3) = pui32Src[0];
+ HWREG(ui32Base + AES_O_DATA_IN_2) = pui32Src[1];
+ HWREG(ui32Base + AES_O_DATA_IN_1) = pui32Src[2];
+ HWREG(ui32Base + AES_O_DATA_IN_0) = pui32Src[3];
+}
+
+
+//*****************************************************************************
+//
+//! Used to process(transform) blocks of data, either encrypt or decrypt it.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param pui8Src is a pointer to the memory location where the input data
+//! is stored.
+//! \param pui8Dest is a pointer to the memory location output is written.
+//! \param ui32Length is the length of the cryptographic data in bytes.
+//!
+//! This function iterates the encryption or decryption mechanism number over
+//! the data length. Before calling this function, ensure that the AES
+//! module is properly configured the key, data size, mode, etc. Only ECB,
+//! CBC, CTR, ICM, CFB, XTS and F8 operating modes should be used. The data
+//! is processed in 4-word (16-byte) blocks.
+//!
+//! \note This function only supports values of \e ui32Length less than 2^32,
+//! because the memory size is restricted to between 0 to 2^32 bytes.
+//!
+//! \return Returns true if data was processed successfully. Returns false
+//! if data processing failed.
+//
+//*****************************************************************************
+bool
+AESDataProcess(uint32_t ui32Base, uint8_t *pui8Src, uint8_t *pui8Dest,
+ uint32_t ui32Length)
+{
+ uint32_t ui32Count, ui32BlkCount, ui32ByteCount;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+
+ //
+ // Write the length register first, which triggers the engine to start
+ // using this context.
+ //
+ AESDataLengthSet(AES_BASE, (uint64_t) ui32Length);
+
+ //
+ // Now loop until the blocks are written.
+ //
+ ui32BlkCount = ui32Length/16;
+ for(ui32Count = 0; ui32Count < ui32BlkCount; ui32Count += 1)
+ {
+ //
+ // Write the data registers.
+ //
+ AESDataWrite(ui32Base, pui8Src + (ui32Count*16) ,16);
+
+ //
+ // Read the data registers.
+ //
+ AESDataRead(ui32Base, pui8Dest + (ui32Count*16) ,16);
+
+ }
+
+ //
+ //Now handle the residue bytes
+ //
+ ui32ByteCount = ui32Length%16;
+ if(ui32ByteCount)
+ {
+ //
+ // Write the data registers.
+ //
+ AESDataWrite(ui32Base, pui8Src + (16*ui32BlkCount) ,ui32ByteCount);
+
+ //
+ // Read the data registers.
+ //
+ AESDataRead(ui32Base, pui8Dest + (16*ui32BlkCount) ,ui32ByteCount);
+ }
+
+
+
+ //
+ // Return true to indicate successful completion of the function.
+ //
+ return(true);
+}
+//*****************************************************************************
+//
+//! Used to generate message authentication code (MAC) using CBC-MAC and F9 mode.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param pui8Src is a pointer to the memory location where the input data
+//! is stored.
+//! \param ui32Length is the length of the cryptographic data in bytes.
+//! \param pui8Tag is a pointer to a 4-word array where the hash tag is
+//! written.
+//!
+//! This function processes data to produce a hash tag that can be used tor
+//! authentication. Before calling this function, ensure that the AES
+//! module is properly configured the key, data size, mode, etc. Only
+//! CBC-MAC and F9 modes should be used.
+//!
+//! \return Returns true if data was processed successfully. Returns false
+//! if data processing failed.
+//
+//*****************************************************************************
+bool
+AESDataMAC(uint32_t ui32Base, uint8_t *pui8Src, uint32_t ui32Length,
+ uint8_t *pui8Tag)
+{
+ uint32_t ui32Count, ui32BlkCount, ui32ByteCount;
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+
+ //
+ // Write the length register first, which triggers the engine to start
+ // using this context.
+ //
+ AESDataLengthSet(AES_BASE, (uint64_t) ui32Length);
+
+ //
+ // Write the data registers.
+ //
+
+ //
+ // Now loop until the blocks are written.
+ //
+ ui32BlkCount = ui32Length/16;
+ for(ui32Count = 0; ui32Count < ui32BlkCount; ui32Count += 1)
+ {
+ //
+ // Write the data registers.
+ //
+ AESDataWrite(ui32Base, pui8Src + ui32Count*16 ,16);
+ }
+
+ //
+ //Now handle the residue bytes
+ //
+ ui32ByteCount = ui32Length%16;
+ if(ui32ByteCount)
+ {
+ //
+ // Write the data registers.
+ //
+ AESDataWrite(ui32Base, pui8Src + (ui32Count*ui32BlkCount) ,ui32ByteCount);
+ }
+
+ //
+ // Wait for the context data regsiters to be ready.
+ //
+ while((AES_CTRL_SVCTXTRDY & (HWREG(AES_BASE + AES_O_CTRL))) == 0)
+ {
+ }
+
+ //
+ // Read the hash tag value.
+ //
+ AESTagRead(AES_BASE, pui8Tag);
+
+ //
+ // Return true to indicate successful completion of the function.
+ //
+ return(true);
+}
+
+//*****************************************************************************
+//
+//! Used for Authenticated encryption (AE) of the data. Processes and authenticates blocks of data,
+//! either encrypt the data or decrypt the data.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param pui8Src is a pointer to the memory location where the input data
+//! is stored. The data must be padded to the 16-byte boundary.
+//! \param pui8Dest is a pointer to the memory location output is written.
+//! The space for written data must be rounded up to the 16-byte boundary.
+//! \param ui32Length is the length of the cryptographic data in bytes.
+//! \param pui8AuthSrc is a pointer to the memory location where the
+//! additional authentication data is stored. The data must be padded to the
+//! 16-byte boundary.
+//! \param ui32AuthLength is the length of the additional authentication
+//! data in bytes.
+//! \param pui8Tag is a pointer to a 4-word array where the hash tag is
+//! written.
+//!
+//! This function encrypts or decrypts blocks of data in addition to
+//! authentication data. A hash tag is also produced. Before calling this
+//! function, ensure that the AES module is properly configured the key,
+//! data size, mode, etc. Only CCM and GCM modes should be used.
+//!
+//! \return Returns true if data was processed successfully. Returns false
+//! if data processing failed.
+//
+//*****************************************************************************
+bool
+AESDataProcessAE(uint32_t ui32Base, uint8_t *pui8Src, uint8_t *pui8Dest,
+ uint32_t ui32Length, uint8_t *pui8AuthSrc,
+ uint32_t ui32AuthLength, uint8_t *pui8Tag)
+{
+ uint32_t ui32Count;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+
+ //
+ // Set the data length.
+ //
+ AESDataLengthSet(AES_BASE, (uint64_t) ui32Length);
+
+ //
+ // Set the additional authentication data length.
+ //
+ AESAuthDataLengthSet(AES_BASE, ui32AuthLength);
+
+ //
+ // Now loop until the authentication data blocks are written.
+ //
+ for(ui32Count = 0; ui32Count < ui32AuthLength; ui32Count += 16)
+ {
+ //
+ // Write the data registers.
+ //
+ AESDataWrite(ui32Base, pui8AuthSrc + (ui32Count),16);
+ }
+
+ //
+ // Now loop until the data blocks are written.
+ //
+ for(ui32Count = 0; ui32Count < ui32Length; ui32Count += 16)
+ {
+ //
+ // Write the data registers.
+ //
+ AESDataWrite(ui32Base, pui8Src + (ui32Count),16);
+
+ //
+ //
+ // Read the data registers.
+ //
+ AESDataRead(ui32Base, pui8Dest + (ui32Count),16);
+ }
+
+ //
+ // Wait for the context data regsiters to be ready.
+ //
+ while((AES_CTRL_SVCTXTRDY & (HWREG(AES_BASE + AES_O_CTRL))) == 0)
+ {
+ }
+
+ //
+ // Read the hash tag value.
+ //
+ AESTagRead(AES_BASE, pui8Tag);
+
+ //
+ // Return true to indicate successful completion of the function.
+ //
+ return(true);
+}
+
+//*****************************************************************************
+//
+//! Returns the current AES module interrupt status.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param bMasked is \b false if the raw interrupt status is required and
+//! \b true if the masked interrupt status is required.
+//!
+//! \return Returns a bit mask of the interrupt sources, which is a logical OR
+//! of any of the following:
+//!
+//! - \b AES_INT_CONTEXT_IN - Context interrupt
+//! - \b AES_INT_CONTEXT_OUT - Authentication tag (and IV) interrupt.
+//! - \b AES_INT_DATA_IN - Data input interrupt
+//! - \b AES_INT_DATA_OUT - Data output interrupt
+//! - \b AES_INT_DMA_CONTEXT_IN - Context DMA done interrupt
+//! - \b AES_INT_DMA_CONTEXT_OUT - Authentication tag (and IV) DMA done
+//! interrupt
+//! - \b AES_INT_DMA_DATA_IN - Data input DMA done interrupt
+//! - \b AES_INT_DMA_DATA_OUT - Data output DMA done interrupt
+//
+//*****************************************************************************
+uint32_t
+AESIntStatus(uint32_t ui32Base, bool bMasked)
+{
+ uint32_t ui32Temp;
+ uint32_t ui32IrqEnable;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+
+ //
+ // Read the IRQ status register and return the value.
+ //
+ if(bMasked)
+ {
+ ui32Temp = HWREG(DTHE_BASE + DTHE_O_AES_MIS);
+ ui32IrqEnable = HWREG(ui32Base + AES_O_IRQENABLE);
+ return((HWREG(ui32Base + AES_O_IRQSTATUS) &
+ ui32IrqEnable) | ((ui32Temp & 0x0000000F) << 16));
+ }
+ else
+ {
+ ui32Temp = HWREG(DTHE_BASE + DTHE_O_AES_RIS);
+ return(HWREG(ui32Base + AES_O_IRQSTATUS) |
+ ((ui32Temp & 0x0000000F) << 16));
+ }
+}
+
+//*****************************************************************************
+//
+//! Enables AES module interrupts.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param ui32IntFlags is a bit mask of the interrupt sources to enable.
+//!
+//! This function enables the interrupts in the AES module. The \e ui32IntFlags
+//! parameter is the logical OR of any of the following:
+//!
+//! - \b AES_INT_CONTEXT_IN - Context interrupt
+//! - \b AES_INT_CONTEXT_OUT - Authentication tag (and IV) interrupt
+//! - \b AES_INT_DATA_IN - Data input interrupt
+//! - \b AES_INT_DATA_OUT - Data output interrupt
+//! - \b AES_INT_DMA_CONTEXT_IN - Context DMA done interrupt
+//! - \b AES_INT_DMA_CONTEXT_OUT - Authentication tag (and IV) DMA done
+//! interrupt
+//! - \b AES_INT_DMA_DATA_IN - Data input DMA done interrupt
+//! - \b AES_INT_DMA_DATA_OUT - Data output DMA done interrupt
+//!
+//! \note Interrupts that have been previously been enabled are not disabled
+//! when this function is called.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+ ASSERT((ui32IntFlags == AES_INT_CONTEXT_IN) ||
+ (ui32IntFlags == AES_INT_CONTEXT_OUT) ||
+ (ui32IntFlags == AES_INT_DATA_IN) ||
+ (ui32IntFlags == AES_INT_DATA_OUT) ||
+ (ui32IntFlags == AES_INT_DMA_CONTEXT_IN) ||
+ (ui32IntFlags == AES_INT_DMA_CONTEXT_OUT) ||
+ (ui32IntFlags == AES_INT_DMA_DATA_IN) ||
+ (ui32IntFlags == AES_INT_DMA_DATA_OUT));
+
+ //
+ // Set the flags.
+ //
+ HWREG(DTHE_BASE + DTHE_O_AES_IM) &= ~((ui32IntFlags & 0x000F0000) >> 16);
+ HWREG(ui32Base + AES_O_IRQENABLE) |= ui32IntFlags & 0x0000ffff;
+}
+
+//*****************************************************************************
+//
+//! Disables AES module interrupts.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param ui32IntFlags is a bit mask of the interrupt sources to disable.
+//!
+//! This function disables the interrupt sources in the AES module. The
+//! \e ui32IntFlags parameter is the logical OR of any of the following:
+//!
+//! - \b AES_INT_CONTEXT_IN - Context interrupt
+//! - \b AES_INT_CONTEXT_OUT - Authentication tag (and IV) interrupt
+//! - \b AES_INT_DATA_IN - Data input interrupt
+//! - \b AES_INT_DATA_OUT - Data output interrupt
+//! - \b AES_INT_DMA_CONTEXT_IN - Context DMA done interrupt
+//! - \b AES_INT_DMA_CONTEXT_OUT - Authentication tag (and IV) DMA done
+//! interrupt
+//! - \b AES_INT_DMA_DATA_IN - Data input DMA done interrupt
+//! - \b AES_INT_DMA_DATA_OUT - Data output DMA done interrupt
+//!
+//! \note The DMA done interrupts are the only interrupts that can be cleared.
+//! The remaining interrupts can be disabled instead using AESIntDisable().
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+ ASSERT((ui32IntFlags == AES_INT_CONTEXT_IN) ||
+ (ui32IntFlags == AES_INT_CONTEXT_OUT) ||
+ (ui32IntFlags == AES_INT_DATA_IN) ||
+ (ui32IntFlags == AES_INT_DATA_OUT) ||
+ (ui32IntFlags == AES_INT_DMA_CONTEXT_IN) ||
+ (ui32IntFlags == AES_INT_DMA_CONTEXT_OUT) ||
+ (ui32IntFlags == AES_INT_DMA_DATA_IN) ||
+ (ui32IntFlags == AES_INT_DMA_DATA_OUT));
+
+ //
+ // Clear the flags.
+ //
+ HWREG(DTHE_BASE + DTHE_O_AES_IM) |= ((ui32IntFlags & 0x000F0000) >> 16);
+ HWREG(ui32Base + AES_O_IRQENABLE) &= ~(ui32IntFlags & 0x0000ffff);
+}
+
+//*****************************************************************************
+//
+//! Clears AES module interrupts.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param ui32IntFlags is a bit mask of the interrupt sources to disable.
+//!
+//! This function clears the interrupt sources in the AES module. The
+//! \e ui32IntFlags parameter is the logical OR of any of the following:
+//!
+//! - \b AES_INT_DMA_CONTEXT_IN - Context DMA done interrupt
+//! - \b AES_INT_DMA_CONTEXT_OUT - Authentication tag (and IV) DMA done
+//! interrupt
+//! - \b AES_INT_DMA_DATA_IN - Data input DMA done interrupt
+//! - \b AES_INT_DMA_DATA_OUT - Data output DMA done interrupt
+//!
+//! \note Only the DMA done interrupts can be cleared. The remaining
+//! interrupts should be disabled with AESIntDisable().
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESIntClear(uint32_t ui32Base, uint32_t ui32IntFlags)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+ ASSERT((ui32IntFlags == AES_INT_DMA_CONTEXT_IN) ||
+ (ui32IntFlags == AES_INT_DMA_CONTEXT_OUT) ||
+ (ui32IntFlags == AES_INT_DMA_DATA_IN) ||
+ (ui32IntFlags == AES_INT_DMA_DATA_OUT));
+
+ HWREG(DTHE_BASE + DTHE_O_AES_IC) = ((ui32IntFlags >> 16) & 0x0000000F);
+}
+
+//*****************************************************************************
+//
+//! Registers an interrupt handler for the AES module.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param pfnHandler is a pointer to the function to be called when the
+//! enabled AES interrupts occur.
+//!
+//! This function registers the interrupt handler in the interrupt vector
+//! table, and enables AES interrupts on the interrupt controller; specific AES
+//! interrupt sources must be enabled using AESIntEnable(). The interrupt
+//! handler being registered must clear the source of the interrupt using
+//! AESIntClear().
+//!
+//! If the application is using a static interrupt vector table stored in
+//! flash, then it is not necessary to register the interrupt handler this way.
+//! Instead, IntEnable() is used to enable AES interrupts on the
+//! interrupt controller.
+//!
+//! \sa IntRegister() for important information about registering interrupt
+//! handlers.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESIntRegister(uint32_t ui32Base, void(*pfnHandler)(void))
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+
+ //
+ // Register the interrupt handler.
+ //
+ IntRegister(INT_AES, pfnHandler);
+
+ //
+ // Enable the interrupt
+ //
+ IntEnable(INT_AES);
+}
+
+//*****************************************************************************
+//
+//! Unregisters an interrupt handler for the AES module.
+//!
+//! \param ui32Base is the base address of the AES module.
+//!
+//! This function unregisters the previously registered interrupt handler and
+//! disables the interrupt in the interrupt controller.
+//!
+//! \sa IntRegister() for important information about registering interrupt
+//! handlers.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESIntUnregister(uint32_t ui32Base)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+
+ //
+ // Disable the interrupt.
+ //
+ IntDisable(INT_AES);
+
+ //
+ // Unregister the interrupt handler.
+ //
+ IntUnregister(INT_AES);
+}
+
+//*****************************************************************************
+//
+//! Enables uDMA requests for the AES module.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param ui32Flags is a bit mask of the uDMA requests to be enabled.
+//!
+//! This function enables the uDMA request sources in the AES module.
+//! The \e ui32Flags parameter is the logical OR of any of the following:
+//!
+//! - \b AES_DMA_DATA_IN
+//! - \b AES_DMA_DATA_OUT
+//! - \b AES_DMA_CONTEXT_IN
+//! - \b AES_DMA_CONTEXT_OUT
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESDMAEnable(uint32_t ui32Base, uint32_t ui32Flags)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+ ASSERT((ui32Flags == AES_DMA_DATA_IN) ||
+ (ui32Flags == AES_DMA_DATA_OUT) ||
+ (ui32Flags == AES_DMA_CONTEXT_IN) ||
+ (ui32Flags == AES_DMA_CONTEXT_OUT));
+
+ //
+ // Set the flags in the current register value.
+ //
+ HWREG(ui32Base + AES_O_SYSCONFIG) |= ui32Flags;
+}
+
+//*****************************************************************************
+//
+//! Disables uDMA requests for the AES module.
+//!
+//! \param ui32Base is the base address of the AES module.
+//! \param ui32Flags is a bit mask of the uDMA requests to be disabled.
+//!
+//! This function disables the uDMA request sources in the AES module.
+//! The \e ui32Flags parameter is the logical OR of any of the
+//! following:
+//!
+//! - \b AES_DMA_DATA_IN
+//! - \b AES_DMA_DATA_OUT
+//! - \b AES_DMA_CONTEXT_IN
+//! - \b AES_DMA_CONTEXT_OUT
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AESDMADisable(uint32_t ui32Base, uint32_t ui32Flags)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == AES_BASE);
+ ASSERT((ui32Flags == AES_DMA_DATA_IN) ||
+ (ui32Flags == AES_DMA_DATA_OUT) ||
+ (ui32Flags == AES_DMA_CONTEXT_IN) ||
+ (ui32Flags == AES_DMA_CONTEXT_OUT));
+
+ //
+ // Clear the flags in the current register value.
+ //
+ HWREG(ui32Base + AES_O_SYSCONFIG) &= ~ui32Flags;
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/cc3200/hal/aes.h b/cc3200/hal/aes.h index e3213e6101..766d3587e4 100644 --- a/cc3200/hal/aes.h +++ b/cc3200/hal/aes.h @@ -1,217 +1,218 @@ -//***************************************************************************** -// -// aes.h -// -// Defines and Macros for the AES module. -// -// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ -// -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the -// distribution. -// -// Neither the name of Texas Instruments Incorporated nor the names of -// its contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -#ifndef __DRIVERLIB_AES_H__ -#define __DRIVERLIB_AES_H__ - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" -{ -#endif - -//***************************************************************************** -// -// The following defines are used to specify the operation direction in the -// ui32Config argument in the AESConfig function. Only one is permitted. -// -//***************************************************************************** -#define AES_CFG_DIR_ENCRYPT 0x00000004 -#define AES_CFG_DIR_DECRYPT 0x00000000 - -//***************************************************************************** -// -// The following defines are used to specify the key size in the ui32Config -// argument in the AESConfig function. Only one is permitted. -// -//***************************************************************************** -#define AES_CFG_KEY_SIZE_128BIT 0x00000008 -#define AES_CFG_KEY_SIZE_192BIT 0x00000010 -#define AES_CFG_KEY_SIZE_256BIT 0x00000018 - -//***************************************************************************** -// -// The following defines are used to specify the mode of operation in the -// ui32Config argument in the AESConfig function. Only one is permitted. -// -//***************************************************************************** -#define AES_CFG_MODE_M 0x2007fe60 -#define AES_CFG_MODE_ECB 0x00000000 -#define AES_CFG_MODE_CBC 0x00000020 -#define AES_CFG_MODE_CTR 0x00000040 -#define AES_CFG_MODE_ICM 0x00000200 -#define AES_CFG_MODE_CFB 0x00000400 -#define AES_CFG_MODE_XTS_TWEAKJL \ - 0x00000800 -#define AES_CFG_MODE_XTS_K2IJL \ - 0x00001000 -#define AES_CFG_MODE_XTS_K2ILJ0 \ - 0x00001800 -#define AES_CFG_MODE_F8 0x00002000 -#define AES_CFG_MODE_F9 0x20004000 -#define AES_CFG_MODE_CBCMAC 0x20008000 -#define AES_CFG_MODE_GCM_HLY0ZERO \ - 0x20010040 -#define AES_CFG_MODE_GCM_HLY0CALC \ - 0x20020040 -#define AES_CFG_MODE_GCM_HY0CALC \ - 0x20030040 -#define AES_CFG_MODE_CCM 0x20040040 - -//***************************************************************************** -// -// The following defines are used to specify the counter width in the -// ui32Config argument in the AESConfig function. It is only required to -// be defined when using CTR, CCM, or GCM modes. Only one length is permitted. -// -//***************************************************************************** -#define AES_CFG_CTR_WIDTH_32 0x00000000 -#define AES_CFG_CTR_WIDTH_64 0x00000080 -#define AES_CFG_CTR_WIDTH_96 0x00000100 -#define AES_CFG_CTR_WIDTH_128 0x00000180 - -//***************************************************************************** -// -// The following defines are used to define the width of the length field for -// CCM operation through the ui32Config argument in the AESConfig function. -// This value is also known as L. Only one is permitted. -// -//***************************************************************************** -#define AES_CFG_CCM_L_2 0x00080000 -#define AES_CFG_CCM_L_4 0x00180000 -#define AES_CFG_CCM_L_8 0x00380000 - -//***************************************************************************** -// -// The following defines are used to define the length of the authentication -// field for CCM operations through the ui32Config argument in the AESConfig -// function. This value is also known as M. Only one is permitted. -// -//***************************************************************************** -#define AES_CFG_CCM_M_4 0x00400000 -#define AES_CFG_CCM_M_6 0x00800000 -#define AES_CFG_CCM_M_8 0x00c00000 -#define AES_CFG_CCM_M_10 0x01000000 -#define AES_CFG_CCM_M_12 0x01400000 -#define AES_CFG_CCM_M_14 0x01800000 -#define AES_CFG_CCM_M_16 0x01c00000 - -//***************************************************************************** -// -// Interrupt flags for use with the AESIntEnable, AESIntDisable, and -// AESIntStatus functions. -// -//***************************************************************************** -#define AES_INT_CONTEXT_IN 0x00000001 -#define AES_INT_CONTEXT_OUT 0x00000008 -#define AES_INT_DATA_IN 0x00000002 -#define AES_INT_DATA_OUT 0x00000004 -#define AES_INT_DMA_CONTEXT_IN 0x00010000 -#define AES_INT_DMA_CONTEXT_OUT 0x00020000 -#define AES_INT_DMA_DATA_IN 0x00040000 -#define AES_INT_DMA_DATA_OUT 0x00080000 - -//***************************************************************************** -// -// Defines used when enabling and disabling DMA requests in the -// AESEnableDMA and AESDisableDMA functions. -// -//***************************************************************************** -#define AES_DMA_DATA_IN 0x00000040 -#define AES_DMA_DATA_OUT 0x00000020 -#define AES_DMA_CONTEXT_IN 0x00000080 -#define AES_DMA_CONTEXT_OUT 0x00000100 - -//***************************************************************************** -// -// Function prototypes. -// -//***************************************************************************** -extern void AESConfigSet(uint32_t ui32Base, uint32_t ui32Config); -extern void AESKey1Set(uint32_t ui32Base, uint8_t *pui8Key, - uint32_t ui32Keysize); -extern void AESKey2Set(uint32_t ui32Base, uint8_t *pui8Key, - uint32_t ui32Keysize); -extern void AESKey3Set(uint32_t ui32Base, uint8_t *pui8Key); -extern void AESIVSet(uint32_t ui32Base, uint8_t *pui8IVdata); -extern void AESTagRead(uint32_t ui32Base, uint8_t *pui8TagData); -extern void AESDataLengthSet(uint32_t ui32Base, uint64_t ui64Length); -extern void AESAuthDataLengthSet(uint32_t ui32Base, uint32_t ui32Length); -extern bool AESDataReadNonBlocking(uint32_t ui32Base, uint8_t *pui8Dest, - uint8_t ui8Length); -extern void AESDataRead(uint32_t ui32Base, uint8_t *pui8Dest, - uint8_t ui8Length); -extern bool AESDataWriteNonBlocking(uint32_t ui32Base, uint8_t *pui8Src, - uint8_t ui8Length); -extern void AESDataWrite(uint32_t ui32Base, uint8_t *pui8Src, - uint8_t ui8Length); -extern bool AESDataProcess(uint32_t ui32Base, uint8_t *pui8Src, - uint8_t *pui8Dest, - uint32_t ui32Length); -extern bool AESDataMAC(uint32_t ui32Base, uint8_t *pui8Src, - uint32_t ui32Length, - uint8_t *pui8Tag); -extern bool AESDataProcessAE(uint32_t ui32Base, uint8_t *pui8Src, - uint8_t *pui8Dest, uint32_t ui32Length, - uint8_t *pui8AuthSrc, uint32_t ui32AuthLength, - uint8_t *pui8Tag); -extern uint32_t AESIntStatus(uint32_t ui32Base, bool bMasked); -extern void AESIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags); -extern void AESIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags); -extern void AESIntClear(uint32_t ui32Base, uint32_t ui32IntFlags); -extern void AESIntRegister(uint32_t ui32Base, void(*pfnHandler)(void)); -extern void AESIntUnregister(uint32_t ui32Base); -extern void AESDMAEnable(uint32_t ui32Base, uint32_t ui32Flags); -extern void AESDMADisable(uint32_t ui32Base, uint32_t ui32Flags); - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif - -#endif // __DRIVERLIB_AES_H__ +//*****************************************************************************
+//
+// aes.h
+//
+// Defines and Macros for the AES module.
+//
+// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+//
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the
+// distribution.
+//
+// Neither the name of Texas Instruments Incorporated nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#ifndef __DRIVERLIB_AES_H__
+#define __DRIVERLIB_AES_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The following defines are used to specify the operation direction in the
+// ui32Config argument in the AESConfig function. Only one is permitted.
+//
+//*****************************************************************************
+#define AES_CFG_DIR_ENCRYPT 0x00000004
+#define AES_CFG_DIR_DECRYPT 0x00000000
+
+//*****************************************************************************
+//
+// The following defines are used to specify the key size in the ui32Config
+// argument in the AESConfig function. Only one is permitted.
+//
+//*****************************************************************************
+#define AES_CFG_KEY_SIZE_128BIT 0x00000008
+#define AES_CFG_KEY_SIZE_192BIT 0x00000010
+#define AES_CFG_KEY_SIZE_256BIT 0x00000018
+
+//*****************************************************************************
+//
+// The following defines are used to specify the mode of operation in the
+// ui32Config argument in the AESConfig function. Only one is permitted.
+//
+//*****************************************************************************
+#define AES_CFG_MODE_M 0x2007fe60
+#define AES_CFG_MODE_ECB 0x00000000
+#define AES_CFG_MODE_CBC 0x00000020
+#define AES_CFG_MODE_CTR 0x00000040
+#define AES_CFG_MODE_ICM 0x00000200
+#define AES_CFG_MODE_CFB 0x00000400
+#define AES_CFG_MODE_XTS_TWEAKJL \
+ 0x00000800
+#define AES_CFG_MODE_XTS_K2IJL \
+ 0x00001000
+#define AES_CFG_MODE_XTS_K2ILJ0 \
+ 0x00001800
+#define AES_CFG_MODE_F8 0x00002000
+#define AES_CFG_MODE_F9 0x20004000
+#define AES_CFG_MODE_CBCMAC 0x20008000
+#define AES_CFG_MODE_GCM_HLY0ZERO \
+ 0x20010040
+#define AES_CFG_MODE_GCM_HLY0CALC \
+ 0x20020040
+#define AES_CFG_MODE_GCM_HY0CALC \
+ 0x20030040
+#define AES_CFG_MODE_CCM 0x20040040
+
+//*****************************************************************************
+//
+// The following defines are used to specify the counter width in the
+// ui32Config argument in the AESConfig function. It is only required to
+// be defined when using CTR, CCM, or GCM modes. Only one length is permitted.
+//
+//*****************************************************************************
+#define AES_CFG_CTR_WIDTH_32 0x00000000
+#define AES_CFG_CTR_WIDTH_64 0x00000080
+#define AES_CFG_CTR_WIDTH_96 0x00000100
+#define AES_CFG_CTR_WIDTH_128 0x00000180
+
+//*****************************************************************************
+//
+// The following defines are used to define the width of the length field for
+// CCM operation through the ui32Config argument in the AESConfig function.
+// This value is also known as L. Only one is permitted.
+//
+//*****************************************************************************
+#define AES_CFG_CCM_L_2 0x00080000
+#define AES_CFG_CCM_L_4 0x00180000
+#define AES_CFG_CCM_L_8 0x00380000
+
+//*****************************************************************************
+//
+// The following defines are used to define the length of the authentication
+// field for CCM operations through the ui32Config argument in the AESConfig
+// function. This value is also known as M. Only one is permitted.
+//
+//*****************************************************************************
+#define AES_CFG_CCM_M_4 0x00400000
+#define AES_CFG_CCM_M_6 0x00800000
+#define AES_CFG_CCM_M_8 0x00c00000
+#define AES_CFG_CCM_M_10 0x01000000
+#define AES_CFG_CCM_M_12 0x01400000
+#define AES_CFG_CCM_M_14 0x01800000
+#define AES_CFG_CCM_M_16 0x01c00000
+
+//*****************************************************************************
+//
+// Interrupt flags for use with the AESIntEnable, AESIntDisable, and
+// AESIntStatus functions.
+//
+//*****************************************************************************
+#define AES_INT_CONTEXT_IN 0x00000001
+#define AES_INT_CONTEXT_OUT 0x00000008
+#define AES_INT_DATA_IN 0x00000002
+#define AES_INT_DATA_OUT 0x00000004
+#define AES_INT_DMA_CONTEXT_IN 0x00010000
+#define AES_INT_DMA_CONTEXT_OUT 0x00020000
+#define AES_INT_DMA_DATA_IN 0x00040000
+#define AES_INT_DMA_DATA_OUT 0x00080000
+
+//*****************************************************************************
+//
+// Defines used when enabling and disabling DMA requests in the
+// AESEnableDMA and AESDisableDMA functions.
+//
+//*****************************************************************************
+#define AES_DMA_DATA_IN 0x00000040
+#define AES_DMA_DATA_OUT 0x00000020
+#define AES_DMA_CONTEXT_IN 0x00000080
+#define AES_DMA_CONTEXT_OUT 0x00000100
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern void AESConfigSet(uint32_t ui32Base, uint32_t ui32Config);
+extern void AESKey1Set(uint32_t ui32Base, uint8_t *pui8Key,
+ uint32_t ui32Keysize);
+extern void AESKey2Set(uint32_t ui32Base, uint8_t *pui8Key,
+ uint32_t ui32Keysize);
+extern void AESKey3Set(uint32_t ui32Base, uint8_t *pui8Key);
+extern void AESIVSet(uint32_t ui32Base, uint8_t *pui8IVdata);
+extern void AESIVGet(uint32_t ui32Base, uint8_t *pui8IVdata);
+extern void AESTagRead(uint32_t ui32Base, uint8_t *pui8TagData);
+extern void AESDataLengthSet(uint32_t ui32Base, uint64_t ui64Length);
+extern void AESAuthDataLengthSet(uint32_t ui32Base, uint32_t ui32Length);
+extern bool AESDataReadNonBlocking(uint32_t ui32Base, uint8_t *pui8Dest,
+ uint8_t ui8Length);
+extern void AESDataRead(uint32_t ui32Base, uint8_t *pui8Dest,
+ uint8_t ui8Length);
+extern bool AESDataWriteNonBlocking(uint32_t ui32Base, uint8_t *pui8Src,
+ uint8_t ui8Length);
+extern void AESDataWrite(uint32_t ui32Base, uint8_t *pui8Src,
+ uint8_t ui8Length);
+extern bool AESDataProcess(uint32_t ui32Base, uint8_t *pui8Src,
+ uint8_t *pui8Dest,
+ uint32_t ui32Length);
+extern bool AESDataMAC(uint32_t ui32Base, uint8_t *pui8Src,
+ uint32_t ui32Length,
+ uint8_t *pui8Tag);
+extern bool AESDataProcessAE(uint32_t ui32Base, uint8_t *pui8Src,
+ uint8_t *pui8Dest, uint32_t ui32Length,
+ uint8_t *pui8AuthSrc, uint32_t ui32AuthLength,
+ uint8_t *pui8Tag);
+extern uint32_t AESIntStatus(uint32_t ui32Base, bool bMasked);
+extern void AESIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags);
+extern void AESIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags);
+extern void AESIntClear(uint32_t ui32Base, uint32_t ui32IntFlags);
+extern void AESIntRegister(uint32_t ui32Base, void(*pfnHandler)(void));
+extern void AESIntUnregister(uint32_t ui32Base);
+extern void AESDMAEnable(uint32_t ui32Base, uint32_t ui32Flags);
+extern void AESDMADisable(uint32_t ui32Base, uint32_t ui32Flags);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __DRIVERLIB_AES_H__
diff --git a/cc3200/hal/des.c b/cc3200/hal/des.c index ad8de1cc3c..1620e6bafc 100644 --- a/cc3200/hal/des.c +++ b/cc3200/hal/des.c @@ -1,887 +1,887 @@ -//***************************************************************************** -// -// des.c -// -// Driver for the DES data transformation. -// -// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ -// -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the -// distribution. -// -// Neither the name of Texas Instruments Incorporated nor the names of -// its contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -//***************************************************************************** -// -//! \addtogroup DES_Data_Encryption_Standard_api -//! @{ -// -//***************************************************************************** - -#include <stdbool.h> -#include <stdint.h> -#include "inc/hw_des.h" -#include "inc/hw_dthe.h" -#include "inc/hw_ints.h" -#include "inc/hw_memmap.h" -#include "inc/hw_types.h" -#include "debug.h" -#include "des.h" -#include "interrupt.h" - - -//***************************************************************************** -// -//! Configures the DES module for operation. -//! -//! \param ui32Base is the base address of the DES module. -//! \param ui32Config is the configuration of the DES module. -//! -//! This function configures the DES module for operation. -//! -//! The \e ui32Config parameter is a bit-wise OR of a number of configuration -//! flags. The valid flags are grouped below based on their function. -//! -//! The direction of the operation is specified with one of the following two -//! flags. Only one is permitted. -//! -//! - \b DES_CFG_DIR_ENCRYPT - Encryption -//! - \b DES_CFG_DIR_DECRYPT - Decryption -//! -//! The operational mode of the DES engine is specified with one of the -//! following flags. Only one is permitted. -//! -//! - \b DES_CFG_MODE_ECB - Electronic Codebook Mode -//! - \b DES_CFG_MODE_CBC - Cipher-Block Chaining Mode -//! - \b DES_CFG_MODE_CFB - Cipher Feedback Mode -//! -//! The selection of single DES or triple DES is specified with one of the -//! following two flags. Only one is permitted. -//! -//! - \b DES_CFG_SINGLE - Single DES -//! - \b DES_CFG_TRIPLE - Triple DES -//! -//! \return None. -// -//***************************************************************************** -void -DESConfigSet(uint32_t ui32Base, uint32_t ui32Config) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - - // - // Backup the save context field. - // - ui32Config |= (HWREG(ui32Base + DES_O_CTRL) & DES_CTRL_CONTEXT); - - // - // Write the control register. - // - HWREG(ui32Base + DES_O_CTRL) = ui32Config; -} - -//***************************************************************************** -// -//! Sets the key used for DES operations. -//! -//! \param ui32Base is the base address of the DES module. -//! \param pui8Key is a pointer to an array that holds the key -//! -//! This function sets the key used for DES operations. -//! -//! \e pui8Key should be 64 bits long (2 words) if single DES is being used or -//! 192 bits (6 words) if triple DES is being used. -//! -//! \return None. -// -//***************************************************************************** -void -DESKeySet(uint32_t ui32Base, uint8_t *pui8Key) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - - // - // Write the first part of the key. - // - HWREG(ui32Base + DES_O_KEY1_L) = * ((uint32_t *)(pui8Key + 0)); - HWREG(ui32Base + DES_O_KEY1_H) = * ((uint32_t *)(pui8Key + 4)); - - // - // If we are performing triple DES, then write the key registers for - // the second and third rounds. - // - if(HWREG(ui32Base + DES_O_CTRL) & DES_CFG_TRIPLE) - { - HWREG(ui32Base + DES_O_KEY2_L) = * ((uint32_t *)(pui8Key + 8)); - HWREG(ui32Base + DES_O_KEY2_H) = * ((uint32_t *)(pui8Key + 12)); - HWREG(ui32Base + DES_O_KEY3_L) = * ((uint32_t *)(pui8Key + 16)); - HWREG(ui32Base + DES_O_KEY3_H) = * ((uint32_t *)(pui8Key + 20)); - } -} - -//***************************************************************************** -// -//! Sets the initialization vector in the DES module. -//! -//! \param ui32Base is the base address of the DES module. -//! \param pui8IVdata is a pointer to an array of 64 bits (2 words) of data to -//! be written into the initialization vectors registers. -//! -//! This function sets the initialization vector in the DES module. It returns -//! true if the registers were successfully written. If the context registers -//! cannot be written at the time the function was called, then false is -//! returned. -//! -//! \return True or false. -// -//***************************************************************************** -bool -DESIVSet(uint32_t ui32Base, uint8_t *pui8IVdata) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - - // - // Check to see if context registers can be overwritten. If not, return - // false. - // - if((HWREG(ui32Base + DES_O_CTRL) & DES_CTRL_CONTEXT) == 0) - { - return(false); - } - - // - // Write the initialization vector registers. - // - HWREG(ui32Base + DES_O_IV_L) = *((uint32_t *) (pui8IVdata + 0)); - HWREG(ui32Base + DES_O_IV_H) = *((uint32_t *) (pui8IVdata + 4)); - - // - // Return true to indicate the write was successful. - // - return(true); -} - -//***************************************************************************** -// -//! Sets the crytographic data length in the DES module. -//! -//! \param ui32Base is the base address of the DES module. -//! \param ui32Length is the length of the data in bytes. -//! -//! This function writes the cryptographic data length into the DES module. -//! When this register is written, the engine is triggersed to start using -//! this context. -//! -//! \note Data lengths up to (2^32 - 1) bytes are allowed. -//! -//! \return None. -// -//***************************************************************************** -void -DESDataLengthSet(uint32_t ui32Base, uint32_t ui32Length) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - - // - // Write the length register. - // - HWREG(ui32Base + DES_O_LENGTH) = ui32Length; -} - -//***************************************************************************** -// -//! Reads plaintext/ciphertext from data registers without blocking -//! -//! \param ui32Base is the base address of the DES module. -//! \param pui8Dest is a pointer to an array of 2 words. -//! \param ui8Length the length can be from 1 to 8 -//! -//! This function returns true if the data was ready when the function was -//! called. If the data was not ready, false is returned. -//! -//! \return True or false. -// -//***************************************************************************** -bool -DESDataReadNonBlocking(uint32_t ui32Base, uint8_t *pui8Dest, uint8_t ui8Length) -{ - volatile uint32_t pui32Dest[2]; - uint8_t ui8BytCnt; - uint8_t *pui8DestTemp; - - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - if((ui8Length == 0)||(ui8Length>8)) - { - return(false); - } - - // - // Check to see if the data is ready to be read. - // - if((DES_CTRL_OUTPUT_READY & (HWREG(ui32Base + DES_O_CTRL))) == 0) - { - return(false); - } - - // - // Read two words of data from the data registers. - // - pui32Dest[0] = HWREG(DES_BASE + DES_O_DATA_L); - pui32Dest[1] = HWREG(DES_BASE + DES_O_DATA_H); - - // - //Copy the data to a block memory - // - pui8DestTemp = (uint8_t *)pui32Dest; - for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++) - { - *(pui8Dest+ui8BytCnt) = *(pui8DestTemp+ui8BytCnt); - } - - // - // Return true to indicate a successful write. - // - return(true); -} - -//***************************************************************************** -// -//! Reads plaintext/ciphertext from data registers with blocking. -//! -//! \param ui32Base is the base address of the DES module. -//! \param pui8Dest is a pointer to an array of bytes. -//! \param ui8Length the length can be from 1 to 8 -//! -//! This function waits until the DES module is finished and encrypted or -//! decrypted data is ready. The output data is then stored in the pui8Dest -//! array. -//! -//! \return None -// -//***************************************************************************** -void -DESDataRead(uint32_t ui32Base, uint8_t *pui8Dest, uint8_t ui8Length) -{ - volatile uint32_t pui32Dest[2]; - uint8_t ui8BytCnt; - uint8_t *pui8DestTemp; - - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - if((ui8Length == 0)||(ui8Length>8)) - { - return; - } - // - // Wait for data output to be ready. - // - while((HWREG(ui32Base + DES_O_CTRL) & DES_CTRL_OUTPUT_READY) == 0) - { - } - - // - // Read two words of data from the data registers. - // - pui32Dest[0] = HWREG(DES_BASE + DES_O_DATA_L); - pui32Dest[1] = HWREG(DES_BASE + DES_O_DATA_H); - - // - //Copy the data to a block memory - // - pui8DestTemp = (uint8_t *)pui32Dest; - for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++) - { - *(pui8Dest+ui8BytCnt) = *(pui8DestTemp+ui8BytCnt); - } -} - -//***************************************************************************** -// -//! Writes plaintext/ciphertext to data registers without blocking -//! -//! \param ui32Base is the base address of the DES module. -//! \param pui8Src is a pointer to an array of 2 words. -//! \param ui8Length the length can be from 1 to 8 -//! -//! This function returns false if the DES module is not ready to accept -//! data. It returns true if the data was written successfully. -//! -//! \return true or false. -// -//***************************************************************************** -bool -DESDataWriteNonBlocking(uint32_t ui32Base, uint8_t *pui8Src, uint8_t ui8Length) -{ - - volatile uint32_t pui32Src[2]={0,0}; - uint8_t ui8BytCnt; - uint8_t *pui8SrcTemp; - - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - - if((ui8Length == 0)||(ui8Length>8)) - { - return(false); - } - - // - // Check if the DES module is ready to encrypt or decrypt data. If it - // is not, return false. - // - if(!(DES_CTRL_INPUT_READY & (HWREG(ui32Base + DES_O_CTRL)))) - { - return(false); - } - - // - // Copy the data to a block memory - // - pui8SrcTemp = (uint8_t *)pui32Src; - for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++) - { - *(pui8SrcTemp+ui8BytCnt) = *(pui8Src+ui8BytCnt); - } - - // - // Write the data. - // - HWREG(DES_BASE + DES_O_DATA_L) = pui32Src[0]; - HWREG(DES_BASE + DES_O_DATA_H) = pui32Src[1]; - - // - // Return true to indicate a successful write. - // - return(true); -} - -//***************************************************************************** -// -//! Writes plaintext/ciphertext to data registers without blocking -//! -//! \param ui32Base is the base address of the DES module. -//! \param pui8Src is a pointer to an array of bytes. -//! \param ui8Length the length can be from 1 to 8 -//! -//! This function waits until the DES module is ready before writing the -//! data contained in the pui8Src array. -//! -//! \return None. -// -//***************************************************************************** -void -DESDataWrite(uint32_t ui32Base, uint8_t *pui8Src, uint8_t ui8Length) -{ - volatile uint32_t pui32Src[2]={0,0}; - uint8_t ui8BytCnt; - uint8_t *pui8SrcTemp; - - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - - if((ui8Length == 0)||(ui8Length>8)) - { - return; - } - - // - // Wait for the input ready bit to go high. - // - while(((HWREG(ui32Base + DES_O_CTRL) & DES_CTRL_INPUT_READY)) == 0) - { - } - - // - //Copy the data to a block memory - // - pui8SrcTemp = (uint8_t *)pui32Src; - for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++) - { - *(pui8SrcTemp+ui8BytCnt) = *(pui8Src+ui8BytCnt); - } - - // - // Write the data. - // - HWREG(DES_BASE + DES_O_DATA_L) = pui32Src[0]; - HWREG(DES_BASE + DES_O_DATA_H) = pui32Src[1]; -} - -//***************************************************************************** -// -//! Processes blocks of data through the DES module. -//! -//! \param ui32Base is the base address of the DES module. -//! \param pui8Src is a pointer to an array of words that contains the -//! source data for processing. -//! \param pui8Dest is a pointer to an array of words consisting of the -//! processed data. -//! \param ui32Length is the length of the cryptographic data in bytes. -//! It must be a multiple of eight. -//! -//! This function takes the data contained in the pui8Src array and processes -//! it using the DES engine. The resulting data is stored in the -//! pui8Dest array. The function blocks until all of the data has been -//! processed. If processing is successful, the function returns true. -//! -//! \note This functions assumes that the DES module has been configured, -//! and initialization values and keys have been written. -//! -//! \return true or false. -// -//***************************************************************************** -bool -DESDataProcess(uint32_t ui32Base, uint8_t *pui8Src, uint8_t *pui8Dest, - uint32_t ui32Length) -{ - uint32_t ui32Count, ui32BlkCount, ui32ByteCount; - - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - ASSERT((ui32Length % 8) == 0); - - // - // Write the length register first. This triggers the engine to start - // using this context. - // - HWREG(ui32Base + DES_O_LENGTH) = ui32Length; - - - // - // Now loop until the blocks are written. - // - ui32BlkCount = ui32Length/8; - for(ui32Count = 0; ui32Count <ui32BlkCount; ui32Count ++) - { - // - // Check if the input ready is fine - // - while((DES_CTRL_INPUT_READY & (HWREG(ui32Base + DES_O_CTRL))) == 0) - { - } - - // - // Write the data registers. - // - DESDataWriteNonBlocking(ui32Base, pui8Src + ui32Count*8 ,8); - - // - // Wait for the output ready - // - while((DES_CTRL_OUTPUT_READY & (HWREG(ui32Base + DES_O_CTRL))) == 0) - { - } - - // - // Read the data registers. - // - DESDataReadNonBlocking(ui32Base, pui8Dest + ui32Count*8 ,8); - } - - // - //Now handle the residue bytes - // - ui32ByteCount = ui32Length%8; - if(ui32ByteCount) - { - // - // Check if the input ready is fine - // - while((DES_CTRL_INPUT_READY & (HWREG(ui32Base + DES_O_CTRL))) == 0) - { - } - // - // Write the data registers. - // - DESDataWriteNonBlocking(ui32Base, pui8Src + (ui32Count*ui32BlkCount) , - ui32ByteCount); - // - // Wait for the output ready - // - while((DES_CTRL_OUTPUT_READY & (HWREG(ui32Base + DES_O_CTRL))) == 0) - { - } - - // - // Read the data registers. - // - DESDataReadNonBlocking(ui32Base, pui8Dest + (ui32Count*ui32BlkCount) , - ui32ByteCount); - } - - - - // - // Return true to indicate the process was successful. - // - return(true); -} - -//***************************************************************************** -// -//! Returns the current interrupt status of the DES module. -//! -//! \param ui32Base is the base address of the DES module. -//! \param bMasked is \b false if the raw interrupt status is required and -//! \b true if the masked interrupt status is required. -//! -//! This function gets the current interrupt status of the DES module. -//! The value returned is a logical OR of the following values: -//! -//! - \b DES_INT_CONTEXT_IN - Context interrupt -//! - \b DES_INT_DATA_IN - Data input interrupt -//! - \b DES_INT_DATA_OUT_INT - Data output interrupt -//! - \b DES_INT_DMA_CONTEXT_IN - Context DMA done interrupt -//! - \b DES_INT_DMA_DATA_IN - Data input DMA done interrupt -//! - \b DES_INT_DMA_DATA_OUT - Data output DMA done interrupt -//! -//! \return A bit mask of the current interrupt status. -// -//***************************************************************************** -uint32_t -DESIntStatus(uint32_t ui32Base, bool bMasked) -{ - uint32_t ui32IntStatus; - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - - // - // Read the status register and return the value. - // - if(bMasked) - { - ui32IntStatus = HWREG(ui32Base + DES_O_IRQSTATUS); - ui32IntStatus &= HWREG(ui32Base + DES_O_IRQENABLE); - ui32IntStatus |= ((HWREG(DTHE_BASE + DTHE_O_DES_MIS) & 0x7) << 16); - - return(ui32IntStatus); - } - else - { - ui32IntStatus = HWREG(ui32Base + DES_O_IRQSTATUS); - ui32IntStatus |= ((HWREG(DTHE_BASE + DTHE_O_DES_MIS) & 0xD) << 16); - return(ui32IntStatus); - } -} - -//***************************************************************************** -// -//! Enables interrupts in the DES module. -//! -//! \param ui32Base is the base address of the DES module. -//! \param ui32IntFlags is a bit mask of the interrupts to be enabled. -//! -//! \e ui32IntFlags should be a logical OR of one or more of the following -//! values: -//! -//! - \b DES_INT_CONTEXT_IN - Context interrupt -//! - \b DES_INT_DATA_IN - Data input interrupt -//! - \b DES_INT_DATA_OUT - Data output interrupt -//! - \b DES_INT_DMA_CONTEXT_IN - Context DMA done interrupt -//! - \b DES_INT_DMA_DATA_IN - Data input DMA done interrupt -//! - \b DES_INT_DMA_DATA_OUT - Data output DMA done interrupt -//! -//! \return None. -// -//***************************************************************************** -void -DESIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - ASSERT((ui32IntFlags & DES_INT_CONTEXT_IN) || - (ui32IntFlags & DES_INT_DATA_IN) || - (ui32IntFlags & DES_INT_DATA_OUT) || - (ui32IntFlags & DES_INT_DMA_CONTEXT_IN) || - (ui32IntFlags & DES_INT_DMA_DATA_IN) || - (ui32IntFlags & DES_INT_DMA_DATA_OUT)); - - // - // Enable the interrupts from the flags. - // - HWREG(DTHE_BASE + DTHE_O_DES_IM) &= ~((ui32IntFlags & 0x00070000) >> 16); - HWREG(ui32Base + DES_O_IRQENABLE) |= ui32IntFlags & 0x0000ffff; -} - -//***************************************************************************** -// -//! Disables interrupts in the DES module. -//! -//! \param ui32Base is the base address of the DES module. -//! \param ui32IntFlags is a bit mask of the interrupts to be disabled. -//! -//! This function disables interrupt sources in the DES module. -//! \e ui32IntFlags should be a logical OR of one or more of the following -//! values: -//! -//! - \b DES_INT_CONTEXT_IN - Context interrupt -//! - \b DES_INT_DATA_IN - Data input interrupt -//! - \b DES_INT_DATA_OUT - Data output interrupt -//! - \b DES_INT_DMA_CONTEXT_IN - Context DMA done interrupt -//! - \b DES_INT_DMA_DATA_IN - Data input DMA done interrupt -//! - \b DES_INT_DMA_DATA_OUT - Data output DMA done interrupt -//! -//! \return None. -// -//***************************************************************************** -void -DESIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - ASSERT((ui32IntFlags & DES_INT_CONTEXT_IN) || - (ui32IntFlags & DES_INT_DATA_IN) || - (ui32IntFlags & DES_INT_DATA_OUT) || - (ui32IntFlags & DES_INT_DMA_CONTEXT_IN) || - (ui32IntFlags & DES_INT_DMA_DATA_IN) || - (ui32IntFlags & DES_INT_DMA_DATA_OUT)); - - // - // Clear the interrupts from the flags. - // - HWREG(DTHE_BASE + DTHE_O_AES_IM) |= ((ui32IntFlags & 0x00070000) >> 16); - HWREG(ui32Base + DES_O_IRQENABLE) &= ~(ui32IntFlags & 0x0000ffff); -} - -//***************************************************************************** -// -//! Clears interrupts in the DES module. -//! -//! \param ui32Base is the base address of the DES module. -//! \param ui32IntFlags is a bit mask of the interrupts to be disabled. -//! -//! This function disables interrupt sources in the DES module. -//! \e ui32IntFlags should be a logical OR of one or more of the following -//! values: -//! -//! - \b DES_INT_DMA_CONTEXT_IN - Context interrupt -//! - \b DES_INT_DMA_DATA_IN - Data input interrupt -//! - \b DES_INT_DMA_DATA_OUT - Data output interrupt -//! -//! \note The DMA done interrupts are the only interrupts that can be cleared. -//! The remaining interrupts can be disabled instead using DESIntDisable(). -//! -//! \return None. -// -//***************************************************************************** -void -DESIntClear(uint32_t ui32Base, uint32_t ui32IntFlags) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - ASSERT((ui32IntFlags & DES_INT_DMA_CONTEXT_IN) || - (ui32IntFlags & DES_INT_DMA_DATA_IN) || - (ui32IntFlags & DES_INT_DMA_DATA_OUT)); - - HWREG(DTHE_BASE + DTHE_O_DES_IC) = ((ui32IntFlags & 0x00070000) >> 16); -} - -//***************************************************************************** -// -//! Registers an interrupt handler for the DES module. -//! -//! \param ui32Base is the base address of the DES module. -//! \param pfnHandler is a pointer to the function to be called when the -//! enabled DES interrupts occur. -//! -//! This function registers the interrupt handler in the interrupt vector -//! table, and enables DES interrupts on the interrupt controller; specific DES -//! interrupt sources must be enabled using DESIntEnable(). The interrupt -//! handler being registered must clear the source of the interrupt using -//! DESIntClear(). -//! -//! If the application is using a static interrupt vector table stored in -//! flash, then it is not necessary to register the interrupt handler this way. -//! Instead, IntEnable() should be used to enable DES interrupts on the -//! interrupt controller. -//! -//! \sa IntRegister() for important information about registering interrupt -//! handlers. -//! -//! \return None. -// -//***************************************************************************** -void -DESIntRegister(uint32_t ui32Base, void(*pfnHandler)(void)) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - - // - // Register the interrupt handler. - // - IntRegister(INT_DES, pfnHandler); - - // - // Enable the interrupt. - // - IntEnable(INT_DES); -} - -//***************************************************************************** -// -//! Unregisters an interrupt handler for the DES module. -//! -//! \param ui32Base is the base address of the DES module. -//! -//! This function unregisters the previously registered interrupt handler and -//! disables the interrupt in the interrupt controller. -//! -//! \sa IntRegister() for important information about registering interrupt -//! handlers. -//! -//! \return None. -// -//***************************************************************************** -void -DESIntUnregister(uint32_t ui32Base) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - - // - // Disable the interrupt. - // - IntDisable(INT_DES); - - // - // Unregister the interrupt handler. - // - IntUnregister(INT_DES); -} - -//***************************************************************************** -// -//! Enables DMA request sources in the DES module. -//! -//! \param ui32Base is the base address of the DES module. -//! \param ui32Flags is a bit mask of the DMA requests to be enabled. -//! -//! This function enables DMA request sources in the DES module. The -//! \e ui32Flags parameter should be the logical OR of any of the following: -//! -//! - \b DES_DMA_CONTEXT_IN - Context In -//! - \b DES_DMA_DATA_OUT - Data Out -//! - \b DES_DMA_DATA_IN - Data In -//! -//! \return None. -// -//***************************************************************************** -void -DESDMAEnable(uint32_t ui32Base, uint32_t ui32Flags) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - ASSERT((ui32Flags & DES_DMA_CONTEXT_IN) || - (ui32Flags & DES_DMA_DATA_OUT) || - (ui32Flags & DES_DMA_DATA_IN)); - - // - // Set the data in and data out DMA request enable bits. - // - HWREG(ui32Base + DES_O_SYSCONFIG) |= ui32Flags; -} - -//***************************************************************************** -// -//! Disables DMA request sources in the DES module. -//! -//! \param ui32Base is the base address of the DES module. -//! \param ui32Flags is a bit mask of the DMA requests to be disabled. -//! -//! This function disables DMA request sources in the DES module. The -//! \e ui32Flags parameter should be the logical OR of any of the following: -//! -//! - \b DES_DMA_CONTEXT_IN - Context In -//! - \b DES_DMA_DATA_OUT - Data Out -//! - \b DES_DMA_DATA_IN - Data In -//! -//! \return None. -// -//***************************************************************************** -void -DESDMADisable(uint32_t ui32Base, uint32_t ui32Flags) -{ - // - // Check the arguments. - // - ASSERT(ui32Base == DES_BASE); - ASSERT((ui32Flags & DES_DMA_CONTEXT_IN) || - (ui32Flags & DES_DMA_DATA_OUT) || - (ui32Flags & DES_DMA_DATA_IN)); - - // - // Disable the DMA sources. - // - HWREG(ui32Base + DES_O_SYSCONFIG) &= ~ui32Flags; -} - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** +//*****************************************************************************
+//
+// des.c
+//
+// Driver for the DES data transformation.
+//
+// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+//
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the
+// distribution.
+//
+// Neither the name of Texas Instruments Incorporated nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! \addtogroup DES_Data_Encryption_Standard_api
+//! @{
+//
+//*****************************************************************************
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "inc/hw_des.h"
+#include "inc/hw_dthe.h"
+#include "inc/hw_ints.h"
+#include "inc/hw_memmap.h"
+#include "inc/hw_types.h"
+#include "debug.h"
+#include "des.h"
+#include "interrupt.h"
+
+
+//*****************************************************************************
+//
+//! Configures the DES module for operation.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param ui32Config is the configuration of the DES module.
+//!
+//! This function configures the DES module for operation.
+//!
+//! The \e ui32Config parameter is a bit-wise OR of a number of configuration
+//! flags. The valid flags are grouped below based on their function.
+//!
+//! The direction of the operation is specified with one of the following two
+//! flags. Only one is permitted.
+//!
+//! - \b DES_CFG_DIR_ENCRYPT - Encryption
+//! - \b DES_CFG_DIR_DECRYPT - Decryption
+//!
+//! The operational mode of the DES engine is specified with one of the
+//! following flags. Only one is permitted.
+//!
+//! - \b DES_CFG_MODE_ECB - Electronic Codebook Mode
+//! - \b DES_CFG_MODE_CBC - Cipher-Block Chaining Mode
+//! - \b DES_CFG_MODE_CFB - Cipher Feedback Mode
+//!
+//! The selection of single DES or triple DES is specified with one of the
+//! following two flags. Only one is permitted.
+//!
+//! - \b DES_CFG_SINGLE - Single DES
+//! - \b DES_CFG_TRIPLE - Triple DES
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+DESConfigSet(uint32_t ui32Base, uint32_t ui32Config)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+
+ //
+ // Backup the save context field.
+ //
+ ui32Config |= (HWREG(ui32Base + DES_O_CTRL) & DES_CTRL_CONTEXT);
+
+ //
+ // Write the control register.
+ //
+ HWREG(ui32Base + DES_O_CTRL) = ui32Config;
+}
+
+//*****************************************************************************
+//
+//! Sets the key used for DES operations.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param pui8Key is a pointer to an array that holds the key
+//!
+//! This function sets the key used for DES operations.
+//!
+//! \e pui8Key should be 64 bits long (2 words) if single DES is being used or
+//! 192 bits (6 words) if triple DES is being used.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+DESKeySet(uint32_t ui32Base, uint8_t *pui8Key)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+
+ //
+ // Write the first part of the key.
+ //
+ HWREG(ui32Base + DES_O_KEY1_L) = * ((uint32_t *)(pui8Key + 0));
+ HWREG(ui32Base + DES_O_KEY1_H) = * ((uint32_t *)(pui8Key + 4));
+
+ //
+ // If we are performing triple DES, then write the key registers for
+ // the second and third rounds.
+ //
+ if(HWREG(ui32Base + DES_O_CTRL) & DES_CFG_TRIPLE)
+ {
+ HWREG(ui32Base + DES_O_KEY2_L) = * ((uint32_t *)(pui8Key + 8));
+ HWREG(ui32Base + DES_O_KEY2_H) = * ((uint32_t *)(pui8Key + 12));
+ HWREG(ui32Base + DES_O_KEY3_L) = * ((uint32_t *)(pui8Key + 16));
+ HWREG(ui32Base + DES_O_KEY3_H) = * ((uint32_t *)(pui8Key + 20));
+ }
+}
+
+//*****************************************************************************
+//
+//! Sets the initialization vector in the DES module.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param pui8IVdata is a pointer to an array of 64 bits (2 words) of data to
+//! be written into the initialization vectors registers.
+//!
+//! This function sets the initialization vector in the DES module. It returns
+//! true if the registers were successfully written. If the context registers
+//! cannot be written at the time the function was called, then false is
+//! returned.
+//!
+//! \return True or false.
+//
+//*****************************************************************************
+bool
+DESIVSet(uint32_t ui32Base, uint8_t *pui8IVdata)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+
+ //
+ // Check to see if context registers can be overwritten. If not, return
+ // false.
+ //
+ if((HWREG(ui32Base + DES_O_CTRL) & DES_CTRL_CONTEXT) == 0)
+ {
+ return(false);
+ }
+
+ //
+ // Write the initialization vector registers.
+ //
+ HWREG(ui32Base + DES_O_IV_L) = *((uint32_t *) (pui8IVdata + 0));
+ HWREG(ui32Base + DES_O_IV_H) = *((uint32_t *) (pui8IVdata + 4));
+
+ //
+ // Return true to indicate the write was successful.
+ //
+ return(true);
+}
+
+//*****************************************************************************
+//
+//! Sets the crytographic data length in the DES module.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param ui32Length is the length of the data in bytes.
+//!
+//! This function writes the cryptographic data length into the DES module.
+//! When this register is written, the engine is triggersed to start using
+//! this context.
+//!
+//! \note Data lengths up to (2^32 - 1) bytes are allowed.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+DESDataLengthSet(uint32_t ui32Base, uint32_t ui32Length)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+
+ //
+ // Write the length register.
+ //
+ HWREG(ui32Base + DES_O_LENGTH) = ui32Length;
+}
+
+//*****************************************************************************
+//
+//! Reads plaintext/ciphertext from data registers without blocking
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param pui8Dest is a pointer to an array of 2 words.
+//! \param ui8Length the length can be from 1 to 8
+//!
+//! This function returns true if the data was ready when the function was
+//! called. If the data was not ready, false is returned.
+//!
+//! \return True or false.
+//
+//*****************************************************************************
+bool
+DESDataReadNonBlocking(uint32_t ui32Base, uint8_t *pui8Dest, uint8_t ui8Length)
+{
+ volatile uint32_t pui32Dest[2];
+ uint8_t ui8BytCnt;
+ uint8_t *pui8DestTemp;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+ if((ui8Length == 0)||(ui8Length>8))
+ {
+ return(false);
+ }
+
+ //
+ // Check to see if the data is ready to be read.
+ //
+ if((DES_CTRL_OUTPUT_READY & (HWREG(ui32Base + DES_O_CTRL))) == 0)
+ {
+ return(false);
+ }
+
+ //
+ // Read two words of data from the data registers.
+ //
+ pui32Dest[0] = HWREG(DES_BASE + DES_O_DATA_L);
+ pui32Dest[1] = HWREG(DES_BASE + DES_O_DATA_H);
+
+ //
+ //Copy the data to a block memory
+ //
+ pui8DestTemp = (uint8_t *)pui32Dest;
+ for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++)
+ {
+ *(pui8Dest+ui8BytCnt) = *(pui8DestTemp+ui8BytCnt);
+ }
+
+ //
+ // Return true to indicate a successful write.
+ //
+ return(true);
+}
+
+//*****************************************************************************
+//
+//! Reads plaintext/ciphertext from data registers with blocking.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param pui8Dest is a pointer to an array of bytes.
+//! \param ui8Length the length can be from 1 to 8
+//!
+//! This function waits until the DES module is finished and encrypted or
+//! decrypted data is ready. The output data is then stored in the pui8Dest
+//! array.
+//!
+//! \return None
+//
+//*****************************************************************************
+void
+DESDataRead(uint32_t ui32Base, uint8_t *pui8Dest, uint8_t ui8Length)
+{
+ volatile uint32_t pui32Dest[2];
+ uint8_t ui8BytCnt;
+ uint8_t *pui8DestTemp;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+ if((ui8Length == 0)||(ui8Length>8))
+ {
+ return;
+ }
+ //
+ // Wait for data output to be ready.
+ //
+ while((HWREG(ui32Base + DES_O_CTRL) & DES_CTRL_OUTPUT_READY) == 0)
+ {
+ }
+
+ //
+ // Read two words of data from the data registers.
+ //
+ pui32Dest[0] = HWREG(DES_BASE + DES_O_DATA_L);
+ pui32Dest[1] = HWREG(DES_BASE + DES_O_DATA_H);
+
+ //
+ //Copy the data to a block memory
+ //
+ pui8DestTemp = (uint8_t *)pui32Dest;
+ for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++)
+ {
+ *(pui8Dest+ui8BytCnt) = *(pui8DestTemp+ui8BytCnt);
+ }
+}
+
+//*****************************************************************************
+//
+//! Writes plaintext/ciphertext to data registers without blocking
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param pui8Src is a pointer to an array of 2 words.
+//! \param ui8Length the length can be from 1 to 8
+//!
+//! This function returns false if the DES module is not ready to accept
+//! data. It returns true if the data was written successfully.
+//!
+//! \return true or false.
+//
+//*****************************************************************************
+bool
+DESDataWriteNonBlocking(uint32_t ui32Base, uint8_t *pui8Src, uint8_t ui8Length)
+{
+
+ volatile uint32_t pui32Src[2]={0,0};
+ uint8_t ui8BytCnt;
+ uint8_t *pui8SrcTemp;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+
+ if((ui8Length == 0)||(ui8Length>8))
+ {
+ return(false);
+ }
+
+ //
+ // Check if the DES module is ready to encrypt or decrypt data. If it
+ // is not, return false.
+ //
+ if(!(DES_CTRL_INPUT_READY & (HWREG(ui32Base + DES_O_CTRL))))
+ {
+ return(false);
+ }
+
+ //
+ // Copy the data to a block memory
+ //
+ pui8SrcTemp = (uint8_t *)pui32Src;
+ for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++)
+ {
+ *(pui8SrcTemp+ui8BytCnt) = *(pui8Src+ui8BytCnt);
+ }
+
+ //
+ // Write the data.
+ //
+ HWREG(DES_BASE + DES_O_DATA_L) = pui32Src[0];
+ HWREG(DES_BASE + DES_O_DATA_H) = pui32Src[1];
+
+ //
+ // Return true to indicate a successful write.
+ //
+ return(true);
+}
+
+//*****************************************************************************
+//
+//! Writes plaintext/ciphertext to data registers without blocking
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param pui8Src is a pointer to an array of bytes.
+//! \param ui8Length the length can be from 1 to 8
+//!
+//! This function waits until the DES module is ready before writing the
+//! data contained in the pui8Src array.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+DESDataWrite(uint32_t ui32Base, uint8_t *pui8Src, uint8_t ui8Length)
+{
+ volatile uint32_t pui32Src[2]={0,0};
+ uint8_t ui8BytCnt;
+ uint8_t *pui8SrcTemp;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+
+ if((ui8Length == 0)||(ui8Length>8))
+ {
+ return;
+ }
+
+ //
+ // Wait for the input ready bit to go high.
+ //
+ while(((HWREG(ui32Base + DES_O_CTRL) & DES_CTRL_INPUT_READY)) == 0)
+ {
+ }
+
+ //
+ //Copy the data to a block memory
+ //
+ pui8SrcTemp = (uint8_t *)pui32Src;
+ for(ui8BytCnt = 0; ui8BytCnt < ui8Length ; ui8BytCnt++)
+ {
+ *(pui8SrcTemp+ui8BytCnt) = *(pui8Src+ui8BytCnt);
+ }
+
+ //
+ // Write the data.
+ //
+ HWREG(DES_BASE + DES_O_DATA_L) = pui32Src[0];
+ HWREG(DES_BASE + DES_O_DATA_H) = pui32Src[1];
+}
+
+//*****************************************************************************
+//
+//! Processes blocks of data through the DES module.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param pui8Src is a pointer to an array of words that contains the
+//! source data for processing.
+//! \param pui8Dest is a pointer to an array of words consisting of the
+//! processed data.
+//! \param ui32Length is the length of the cryptographic data in bytes.
+//! It must be a multiple of eight.
+//!
+//! This function takes the data contained in the pui8Src array and processes
+//! it using the DES engine. The resulting data is stored in the
+//! pui8Dest array. The function blocks until all of the data has been
+//! processed. If processing is successful, the function returns true.
+//!
+//! \note This functions assumes that the DES module has been configured,
+//! and initialization values and keys have been written.
+//!
+//! \return true or false.
+//
+//*****************************************************************************
+bool
+DESDataProcess(uint32_t ui32Base, uint8_t *pui8Src, uint8_t *pui8Dest,
+ uint32_t ui32Length)
+{
+ uint32_t ui32Count, ui32BlkCount, ui32ByteCount;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+ ASSERT((ui32Length % 8) == 0);
+
+ //
+ // Write the length register first. This triggers the engine to start
+ // using this context.
+ //
+ HWREG(ui32Base + DES_O_LENGTH) = ui32Length;
+
+
+ //
+ // Now loop until the blocks are written.
+ //
+ ui32BlkCount = ui32Length/8;
+ for(ui32Count = 0; ui32Count <ui32BlkCount; ui32Count ++)
+ {
+ //
+ // Check if the input ready is fine
+ //
+ while((DES_CTRL_INPUT_READY & (HWREG(ui32Base + DES_O_CTRL))) == 0)
+ {
+ }
+
+ //
+ // Write the data registers.
+ //
+ DESDataWriteNonBlocking(ui32Base, pui8Src + ui32Count*8 ,8);
+
+ //
+ // Wait for the output ready
+ //
+ while((DES_CTRL_OUTPUT_READY & (HWREG(ui32Base + DES_O_CTRL))) == 0)
+ {
+ }
+
+ //
+ // Read the data registers.
+ //
+ DESDataReadNonBlocking(ui32Base, pui8Dest + ui32Count*8 ,8);
+ }
+
+ //
+ //Now handle the residue bytes
+ //
+ ui32ByteCount = ui32Length%8;
+ if(ui32ByteCount)
+ {
+ //
+ // Check if the input ready is fine
+ //
+ while((DES_CTRL_INPUT_READY & (HWREG(ui32Base + DES_O_CTRL))) == 0)
+ {
+ }
+ //
+ // Write the data registers.
+ //
+ DESDataWriteNonBlocking(ui32Base, pui8Src + (8*ui32BlkCount) ,
+ ui32ByteCount);
+ //
+ // Wait for the output ready
+ //
+ while((DES_CTRL_OUTPUT_READY & (HWREG(ui32Base + DES_O_CTRL))) == 0)
+ {
+ }
+
+ //
+ // Read the data registers.
+ //
+ DESDataReadNonBlocking(ui32Base, pui8Dest + (8*ui32BlkCount) ,
+ ui32ByteCount);
+ }
+
+
+
+ //
+ // Return true to indicate the process was successful.
+ //
+ return(true);
+}
+
+//*****************************************************************************
+//
+//! Returns the current interrupt status of the DES module.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param bMasked is \b false if the raw interrupt status is required and
+//! \b true if the masked interrupt status is required.
+//!
+//! This function gets the current interrupt status of the DES module.
+//! The value returned is a logical OR of the following values:
+//!
+//! - \b DES_INT_CONTEXT_IN - Context interrupt
+//! - \b DES_INT_DATA_IN - Data input interrupt
+//! - \b DES_INT_DATA_OUT_INT - Data output interrupt
+//! - \b DES_INT_DMA_CONTEXT_IN - Context DMA done interrupt
+//! - \b DES_INT_DMA_DATA_IN - Data input DMA done interrupt
+//! - \b DES_INT_DMA_DATA_OUT - Data output DMA done interrupt
+//!
+//! \return A bit mask of the current interrupt status.
+//
+//*****************************************************************************
+uint32_t
+DESIntStatus(uint32_t ui32Base, bool bMasked)
+{
+ uint32_t ui32IntStatus;
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+
+ //
+ // Read the status register and return the value.
+ //
+ if(bMasked)
+ {
+ ui32IntStatus = HWREG(ui32Base + DES_O_IRQSTATUS);
+ ui32IntStatus &= HWREG(ui32Base + DES_O_IRQENABLE);
+ ui32IntStatus |= ((HWREG(DTHE_BASE + DTHE_O_DES_MIS) & 0x7) << 16);
+
+ return(ui32IntStatus);
+ }
+ else
+ {
+ ui32IntStatus = HWREG(ui32Base + DES_O_IRQSTATUS);
+ ui32IntStatus |= ((HWREG(DTHE_BASE + DTHE_O_DES_MIS) & 0xD) << 16);
+ return(ui32IntStatus);
+ }
+}
+
+//*****************************************************************************
+//
+//! Enables interrupts in the DES module.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param ui32IntFlags is a bit mask of the interrupts to be enabled.
+//!
+//! \e ui32IntFlags should be a logical OR of one or more of the following
+//! values:
+//!
+//! - \b DES_INT_CONTEXT_IN - Context interrupt
+//! - \b DES_INT_DATA_IN - Data input interrupt
+//! - \b DES_INT_DATA_OUT - Data output interrupt
+//! - \b DES_INT_DMA_CONTEXT_IN - Context DMA done interrupt
+//! - \b DES_INT_DMA_DATA_IN - Data input DMA done interrupt
+//! - \b DES_INT_DMA_DATA_OUT - Data output DMA done interrupt
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+DESIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+ ASSERT((ui32IntFlags & DES_INT_CONTEXT_IN) ||
+ (ui32IntFlags & DES_INT_DATA_IN) ||
+ (ui32IntFlags & DES_INT_DATA_OUT) ||
+ (ui32IntFlags & DES_INT_DMA_CONTEXT_IN) ||
+ (ui32IntFlags & DES_INT_DMA_DATA_IN) ||
+ (ui32IntFlags & DES_INT_DMA_DATA_OUT));
+
+ //
+ // Enable the interrupts from the flags.
+ //
+ HWREG(DTHE_BASE + DTHE_O_DES_IM) &= ~((ui32IntFlags & 0x00070000) >> 16);
+ HWREG(ui32Base + DES_O_IRQENABLE) |= ui32IntFlags & 0x0000ffff;
+}
+
+//*****************************************************************************
+//
+//! Disables interrupts in the DES module.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param ui32IntFlags is a bit mask of the interrupts to be disabled.
+//!
+//! This function disables interrupt sources in the DES module.
+//! \e ui32IntFlags should be a logical OR of one or more of the following
+//! values:
+//!
+//! - \b DES_INT_CONTEXT_IN - Context interrupt
+//! - \b DES_INT_DATA_IN - Data input interrupt
+//! - \b DES_INT_DATA_OUT - Data output interrupt
+//! - \b DES_INT_DMA_CONTEXT_IN - Context DMA done interrupt
+//! - \b DES_INT_DMA_DATA_IN - Data input DMA done interrupt
+//! - \b DES_INT_DMA_DATA_OUT - Data output DMA done interrupt
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+DESIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+ ASSERT((ui32IntFlags & DES_INT_CONTEXT_IN) ||
+ (ui32IntFlags & DES_INT_DATA_IN) ||
+ (ui32IntFlags & DES_INT_DATA_OUT) ||
+ (ui32IntFlags & DES_INT_DMA_CONTEXT_IN) ||
+ (ui32IntFlags & DES_INT_DMA_DATA_IN) ||
+ (ui32IntFlags & DES_INT_DMA_DATA_OUT));
+
+ //
+ // Clear the interrupts from the flags.
+ //
+ HWREG(DTHE_BASE + DTHE_O_AES_IM) |= ((ui32IntFlags & 0x00070000) >> 16);
+ HWREG(ui32Base + DES_O_IRQENABLE) &= ~(ui32IntFlags & 0x0000ffff);
+}
+
+//*****************************************************************************
+//
+//! Clears interrupts in the DES module.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param ui32IntFlags is a bit mask of the interrupts to be disabled.
+//!
+//! This function disables interrupt sources in the DES module.
+//! \e ui32IntFlags should be a logical OR of one or more of the following
+//! values:
+//!
+//! - \b DES_INT_DMA_CONTEXT_IN - Context interrupt
+//! - \b DES_INT_DMA_DATA_IN - Data input interrupt
+//! - \b DES_INT_DMA_DATA_OUT - Data output interrupt
+//!
+//! \note The DMA done interrupts are the only interrupts that can be cleared.
+//! The remaining interrupts can be disabled instead using DESIntDisable().
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+DESIntClear(uint32_t ui32Base, uint32_t ui32IntFlags)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+ ASSERT((ui32IntFlags & DES_INT_DMA_CONTEXT_IN) ||
+ (ui32IntFlags & DES_INT_DMA_DATA_IN) ||
+ (ui32IntFlags & DES_INT_DMA_DATA_OUT));
+
+ HWREG(DTHE_BASE + DTHE_O_DES_IC) = ((ui32IntFlags & 0x00070000) >> 16);
+}
+
+//*****************************************************************************
+//
+//! Registers an interrupt handler for the DES module.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param pfnHandler is a pointer to the function to be called when the
+//! enabled DES interrupts occur.
+//!
+//! This function registers the interrupt handler in the interrupt vector
+//! table, and enables DES interrupts on the interrupt controller; specific DES
+//! interrupt sources must be enabled using DESIntEnable(). The interrupt
+//! handler being registered must clear the source of the interrupt using
+//! DESIntClear().
+//!
+//! If the application is using a static interrupt vector table stored in
+//! flash, then it is not necessary to register the interrupt handler this way.
+//! Instead, IntEnable() should be used to enable DES interrupts on the
+//! interrupt controller.
+//!
+//! \sa IntRegister() for important information about registering interrupt
+//! handlers.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+DESIntRegister(uint32_t ui32Base, void(*pfnHandler)(void))
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+
+ //
+ // Register the interrupt handler.
+ //
+ IntRegister(INT_DES, pfnHandler);
+
+ //
+ // Enable the interrupt.
+ //
+ IntEnable(INT_DES);
+}
+
+//*****************************************************************************
+//
+//! Unregisters an interrupt handler for the DES module.
+//!
+//! \param ui32Base is the base address of the DES module.
+//!
+//! This function unregisters the previously registered interrupt handler and
+//! disables the interrupt in the interrupt controller.
+//!
+//! \sa IntRegister() for important information about registering interrupt
+//! handlers.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+DESIntUnregister(uint32_t ui32Base)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+
+ //
+ // Disable the interrupt.
+ //
+ IntDisable(INT_DES);
+
+ //
+ // Unregister the interrupt handler.
+ //
+ IntUnregister(INT_DES);
+}
+
+//*****************************************************************************
+//
+//! Enables DMA request sources in the DES module.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param ui32Flags is a bit mask of the DMA requests to be enabled.
+//!
+//! This function enables DMA request sources in the DES module. The
+//! \e ui32Flags parameter should be the logical OR of any of the following:
+//!
+//! - \b DES_DMA_CONTEXT_IN - Context In
+//! - \b DES_DMA_DATA_OUT - Data Out
+//! - \b DES_DMA_DATA_IN - Data In
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+DESDMAEnable(uint32_t ui32Base, uint32_t ui32Flags)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+ ASSERT((ui32Flags & DES_DMA_CONTEXT_IN) ||
+ (ui32Flags & DES_DMA_DATA_OUT) ||
+ (ui32Flags & DES_DMA_DATA_IN));
+
+ //
+ // Set the data in and data out DMA request enable bits.
+ //
+ HWREG(ui32Base + DES_O_SYSCONFIG) |= ui32Flags;
+}
+
+//*****************************************************************************
+//
+//! Disables DMA request sources in the DES module.
+//!
+//! \param ui32Base is the base address of the DES module.
+//! \param ui32Flags is a bit mask of the DMA requests to be disabled.
+//!
+//! This function disables DMA request sources in the DES module. The
+//! \e ui32Flags parameter should be the logical OR of any of the following:
+//!
+//! - \b DES_DMA_CONTEXT_IN - Context In
+//! - \b DES_DMA_DATA_OUT - Data Out
+//! - \b DES_DMA_DATA_IN - Data In
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+DESDMADisable(uint32_t ui32Base, uint32_t ui32Flags)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(ui32Base == DES_BASE);
+ ASSERT((ui32Flags & DES_DMA_CONTEXT_IN) ||
+ (ui32Flags & DES_DMA_DATA_OUT) ||
+ (ui32Flags & DES_DMA_DATA_IN));
+
+ //
+ // Disable the DMA sources.
+ //
+ HWREG(ui32Base + DES_O_SYSCONFIG) &= ~ui32Flags;
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/cc3200/hal/i2s.c b/cc3200/hal/i2s.c index 36ff45b22d..dbbb936d77 100644 --- a/cc3200/hal/i2s.c +++ b/cc3200/hal/i2s.c @@ -1,922 +1,1012 @@ -//***************************************************************************** -// -// i2s.c -// -// Driver for the I2S interface. -// -// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ -// -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the -// distribution. -// -// Neither the name of Texas Instruments Incorporated nor the names of -// its contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -//***************************************************************************** -// -//! \addtogroup I2S_api -//! @{ -// -//***************************************************************************** -#include "inc/hw_types.h" -#include "inc/hw_ints.h" -#include "inc/hw_memmap.h" -#include "inc/hw_mcasp.h" -#include "inc/hw_apps_config.h" -#include "interrupt.h" -#include "i2s.h" - -//***************************************************************************** -// Macros -//***************************************************************************** -#define MCASP_GBL_RCLK 0x00000001 -#define MCASP_GBL_RHCLK 0x00000002 -#define MCASP_GBL_RSER 0x00000004 -#define MCASP_GBL_RSM 0x00000008 -#define MCASP_GBL_RFSYNC 0x00000010 -#define MCASP_GBL_XCLK 0x00000100 -#define MCASP_GBL_XHCLK 0x00000200 -#define MCASP_GBL_XSER 0x00000400 -#define MCASP_GBL_XSM 0x00000800 -#define MCASP_GBL_XFSYNC 0x00001000 - - -//***************************************************************************** -// -//! \internal -//! Releases the specifed submodule out of reset. -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulFlag is one of the valid sub module. -//! -//! This function Releases the specifed submodule out of reset. -//! -//! \return None. -// -//***************************************************************************** -static void I2SGBLEnable(unsigned long ulBase, unsigned long ulFlag) -{ - unsigned long ulReg; - - // - // Read global control register - // - ulReg = HWREG(ulBase + MCASP_O_GBLCTL); - - // - // Remove the sub modules reset as specified by ulFlag parameter - // - ulReg |= ulFlag; - - // - // Write the configuration - // - HWREG(ulBase + MCASP_O_GBLCTL) = ulReg; - - // - // Wait for write completeion - // - while(HWREG(ulBase + MCASP_O_GBLCTL) != ulReg) - { - - } - -} - -//***************************************************************************** -// -//! Enables transmit and/or receive. -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulMode is one of the valid modes. -//! -//! This function enables the I2S module in specified mode. The parameter -//! \e ulMode should be one of the following -//! -//! -\b I2S_MODE_TX_ONLY -//! -\b I2S_MODE_TX_RX_SYNC -//! -//! \return None. -// -//***************************************************************************** -void I2SEnable(unsigned long ulBase, unsigned long ulMode) -{ - // - // Set FSYNC anc BitClk as output - // - HWREG(ulBase + MCASP_O_PDIR) |= 0x14000000; - - if(ulMode & 0x2) - { - // - // Remove Rx HCLK reset - // - I2SGBLEnable(ulBase, MCASP_GBL_RHCLK); - - // - // Remove Rx XCLK reset - // - I2SGBLEnable(ulBase, MCASP_GBL_RCLK); - - // - // Enable Rx SERDES(s) - // - I2SGBLEnable(ulBase, MCASP_GBL_RSER); - - // - // Enable Rx state machine - // - I2SGBLEnable(ulBase, MCASP_GBL_RSM); - - // - // Enable FSync generator - // - I2SGBLEnable(ulBase, MCASP_GBL_RFSYNC); - } - - if(ulMode & 0x1) - { - // - // Remove Tx HCLK reset - // - I2SGBLEnable(ulBase, MCASP_GBL_XHCLK); - - // - // Remove Tx XCLK reset - // - I2SGBLEnable(ulBase, MCASP_GBL_XCLK); - - // - // Enable Tx SERDES(s) - // - I2SGBLEnable(ulBase, MCASP_GBL_XSER); - - // - // Enable Tx state machine - // - I2SGBLEnable(ulBase, MCASP_GBL_XSM); - - // - // Enable FSync generator - // - I2SGBLEnable(ulBase, MCASP_GBL_XFSYNC); - } -} - -//***************************************************************************** -// -//! Disables transmit and/or receive. -//! -//! \param ulBase is the base address of the I2S module. -//! -//! This function disables transmit and/or receive from I2S module. -//! -//! \return None. -// -//***************************************************************************** -void I2SDisable(unsigned long ulBase) -{ - // - // Reset all sub modules - // - HWREG(ulBase + MCASP_O_GBLCTL) = 0; - - // - // Wait for write to complete - // - while( HWREG(ulBase + MCASP_O_GBLCTL) != 0) - { - - } -} - -//***************************************************************************** -// -//! Waits to send data over the specified data line -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulDataLine is one of the valid data lines. -//! \param ulData is the data to be transmitted. -//! -//! This function sends the \e ucData to the transmit register for the -//! specified data line. If there is no space available, this -//! function waits until there is space available before returning. -//! -//! \return None. -// -//***************************************************************************** -void I2SDataPut(unsigned long ulBase, unsigned long ulDataLine, - unsigned long ulData) -{ - // - // Compute register the offeset - // - ulDataLine = (ulDataLine-1) << 2; - - // - // Wait for free space in fifo - // - while(!( HWREG(ulBase + MCASP_O_TXSTAT) & MCASP_TXSTAT_XDATA)) - { - - } - - // - // Write Data into the FIFO - // - HWREG(ulBase + MCASP_O_TXBUF0 + ulDataLine) = ulData; -} - -//***************************************************************************** -// -//! Sends data over the specified data line -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulDataLine is one of the valid data lines. -//! \param ulData is the data to be transmitted. -//! -//! This function writes the \e ucData to the transmit register for -//! the specified data line. This function does not block, so if there is no -//! space available, then \b -1 is returned, and the application must retry the -//! function later. -//! -//! \return Returns 0 on success, -1 otherwise. -// -//***************************************************************************** -long I2SDataPutNonBlocking(unsigned long ulBase, unsigned long ulDataLine, - unsigned long ulData) -{ - - // - // Compute register the offeset - // - ulDataLine = (ulDataLine-1) << 2; - - // - // Send Data if fifo has free space - // - if( HWREG(ulBase + MCASP_O_TXSTAT) & MCASP_TXSTAT_XDATA) - { - // - // Write data into the FIFO - // - HWREG(ulBase + MCASP_O_TXBUF0 + ulDataLine) = ulData; - return 0; - } - - // - // FIFO is full - // - return(-1); -} - -//***************************************************************************** -// -//! Waits for data from the specified data line. -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulDataLine is one of the valid data lines. -//! \param pulData is pointer to receive data variable. -//! -//! This function gets data from the receive register for the specified -//! data line. If there are no data available, this function waits until a -//! receive before returning. -//! -//! \return None. -// -//***************************************************************************** -void I2SDataGet(unsigned long ulBase, unsigned long ulDataLine, - unsigned long *pulData) -{ - - // - // Compute register the offeset - // - ulDataLine = (ulDataLine-1) << 2; - - // - // Wait for atleat on word in FIFO - // - while(!(HWREG(ulBase + MCASP_O_RXSTAT) & MCASP_RXSTAT_RDATA)) - { - - } - - // - // Read the Data - // - *pulData = HWREG(ulBase + MCASP_O_RXBUF0 + ulDataLine); -} - - -//***************************************************************************** -// -//! Receives data from the specified data line. -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulDataLine is one of the valid data lines. -//! \param pulData is pointer to receive data variable. -//! -//! This function gets data from the receive register for the specified -//! data line. -//! -//! -//! \return Returns 0 on success, -1 otherwise. -// -//***************************************************************************** -long I2SDataGetNonBlocking(unsigned long ulBase, unsigned long ulDataLine, - unsigned long *pulData) -{ - - // - // Compute register the offeset - // - ulDataLine = (ulDataLine-1) << 2; - - // - // Check if data is available in FIFO - // - if(HWREG(ulBase + MCASP_O_RXSTAT) & MCASP_RXSTAT_RDATA) - { - // - // Read the Data - // - *pulData = HWREG(ulBase + MCASP_O_RXBUF0 + ulDataLine); - return 0; - } - - // - // FIFO is empty - // - return -1; -} - - -//***************************************************************************** -// -//! Sets the configuration of the I2S module. -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulI2SClk is the rate of the clock supplied to the I2S module. -//! \param ulBitClk is the desired bit rate. -//! \param ulConfig is the data format. -//! -//! This function configures the I2S for operation in the specified data -//! format. The bit rate is provided in the \e ulBitClk parameter and the data -//! format in the \e ulConfig parameter. -//! -//! The \e ulConfig parameter is the logical OR of two values: the slot size -//! and the data read/write port select. -//! -//! Following selects the slot size: -//! -\b I2S_SLOT_SIZE_24 -//! -\b I2S_SLOT_SIZE_16 -//! -//! Following selects the data read/write port: -//! -\b I2S_PORT_DMA -//! -\b I2S_PORT_CPU -//! -//! \return None. -// -//***************************************************************************** -void I2SConfigSetExpClk(unsigned long ulBase, unsigned long ulI2SClk, - unsigned long ulBitClk, unsigned long ulConfig) -{ - unsigned long ulHClkDiv; - unsigned long ulClkDiv; - - // - // Calculate clock dividers - // - ulHClkDiv = ((ulI2SClk/ulBitClk)-1); - ulClkDiv = 0; - - // - // Check if HCLK divider is overflowing - // - if(ulHClkDiv > 0xFFF) - { - ulHClkDiv = 0xFFF; - - // - // Calculate clock divider - // - ulClkDiv = ((ulI2SClk/(ulBitClk * (ulHClkDiv + 1))) & 0x1F); - } - - HWREG(ulBase + MCASP_O_ACLKXCTL) = (0xA0|ulClkDiv); - - HWREG(ulBase + MCASP_O_AHCLKXCTL) = (0x8000|ulHClkDiv); - - // - // Write the Tx format register - // - HWREG(ulBase + MCASP_O_TXFMT) = (0x18000 | (ulConfig & 0xFFFF)); - - // - // Write the Rx format register - // - HWREG(ulBase + MCASP_O_RXFMT) = (0x18000 | ((ulConfig >> 16) &0xFFFF)); - - // - // Configure Tx FSync generator in I2S mode - // - HWREG(ulBase + MCASP_O_TXFMCTL) = 0x113; - - // - // Configure Rx FSync generator in I2S mode - // - HWREG(ulBase + MCASP_O_RXFMCTL) = 0x113; - - // - // Set Tx bit valid mask - // - HWREG(ulBase + MCASP_O_TXMASK) = 0xFFFFFFFF; - - // - // Set Rx bit valid mask - // - HWREG(ulBase + MCASP_O_RXMASK) = 0xFFFFFFFF; - - // - // Set Tx slot valid mask - // - HWREG(ulBase + MCASP_O_TXTDM) = 0x3; - - // - // Set Rx slot valid mask - // - HWREG(ulBase + MCASP_O_RXTDM) = 0x3; -} - -//***************************************************************************** -// -//! Configure and enable transmit FIFO. -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulTxLevel is the transmit FIFO DMA request level. -//! \param ulWordsPerTransfer is the nuber of words transferred from the FIFO. -//! -//! This function configures and enable I2S transmit FIFO. -//! -//! The parameter \e ulTxLevel sets the level at which transmit DMA requests -//! are generated. This should be non-zero integer multiple of number of -//! serializers enabled as transmitters -//! -//! The parameter \e ulWordsPerTransfer sets the number of words that are -//! transferred from the transmit FIFO to the data line(s). This value must -//! equal the number of serializers used as transmitters. -//! -//! \return None. -// -//***************************************************************************** -void I2STxFIFOEnable(unsigned long ulBase, unsigned long ulTxLevel, - unsigned long ulWordsPerTransfer) -{ - // - // Set transmit FIFO configuration and - // enable it - // - HWREG(ulBase + MCASP_0_WFIFOCTL) = ((1 <<16) | ((ulTxLevel & 0xFF) << 8) - | (ulWordsPerTransfer & 0x1F)); - -} - -//***************************************************************************** -// -//! Disables transmit FIFO. -//! -//! \param ulBase is the base address of the I2S module. -//! -//! This function disables the I2S transmit FIFO. -//! -//! \return None. -// -//***************************************************************************** -void I2STxFIFODisable(unsigned long ulBase) -{ - // - // Disable transmit FIFO. - // - HWREG(ulBase + MCASP_0_WFIFOCTL) = 0; -} - -//***************************************************************************** -// -//! Configure and enable receive FIFO. -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulRxLevel is the receive FIFO DMA request level. -//! \param ulWordsPerTransfer is the nuber of words transferred from the FIFO. -//! -//! This function configures and enable I2S receive FIFO. -//! -//! The parameter \e ulRxLevel sets the level at which receive DMA requests -//! are generated. This should be non-zero integer multiple of number of -//! serializers enabled as receivers. -//! -//! The parameter \e ulWordsPerTransfer sets the number of words that are -//! transferred to the receive FIFO from the data line(s). This value must -//! equal the number of serializers used as receivers. -//! -//! \return None. -// -//***************************************************************************** -void I2SRxFIFOEnable(unsigned long ulBase, unsigned long ulRxLevel, - unsigned long ulWordsPerTransfer) -{ - // - // Set FIFO configuration - // - HWREG(ulBase + MCASP_0_RFIFOCTL) = ( (1 <<16) | ((ulRxLevel & 0xFF) << 8) - | (ulWordsPerTransfer & 0x1F)); - -} - -//***************************************************************************** -// -//! Disables receive FIFO. -//! -//! \param ulBase is the base address of the I2S module. -//! -//! This function disables the I2S receive FIFO. -//! -//! \return None. -// -//***************************************************************************** -void I2SRxFIFODisable(unsigned long ulBase) -{ - // - // Disable receive FIFO. - // - HWREG(ulBase + MCASP_0_RFIFOCTL) = 0; -} - -//***************************************************************************** -// -//! Get the transmit FIFO status. -//! -//! \param ulBase is the base address of the I2S module. -//! -//! This function gets the number of 32-bit words currently in the transmit -//! FIFO. -//! -//! \return Returns transmit FIFO status. -// -//***************************************************************************** -unsigned long I2STxFIFOStatusGet(unsigned long ulBase) -{ - // - // Return transmit FIFO level - // - return HWREG(ulBase + MCASP_0_WFIFOSTS); -} - -//***************************************************************************** -// -//! Get the receive FIFO status. -//! -//! \param ulBase is the base address of the I2S module. -//! -//! This function gets the number of 32-bit words currently in the receive -//! FIFO. -//! -//! \return Returns receive FIFO status. -// -//***************************************************************************** -unsigned long I2SRxFIFOStatusGet(unsigned long ulBase) -{ - // - // Return receive FIFO level - // - return HWREG(ulBase + MCASP_0_RFIFOSTS); -} - -//***************************************************************************** -// -//! Configure the serializer in specified mode. -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulDataLine is the data line (serilizer) to be configured. -//! \param ulSerMode is the required serializer mode. -//! \param ulInActState sets the inactive state of the data line. -//! -//! This function configure and enable the serializer associated with the given -//! data line in specified mode. -//! -//! The paramenter \e ulDataLine selects to data line to be configured and -//! can be one of the following: -//! -\b I2S_DATA_LINE_0 -//! -\b I2S_DATA_LINE_1 -//! -//! The parameter \e ulSerMode can be one of the following: -//! -\b I2S_SER_MODE_TX -//! -\b I2S_SER_MODE_RX -//! -\b I2S_SER_MODE_DISABLE -//! -//! The parameter \e ulInActState can be one of the following -//! -\b I2S_INACT_TRI_STATE -//! -\b I2S_INACT_LOW_LEVEL -//! -\b I2S_INACT_LOW_HIGH -//! -//! \return Returns receive FIFO status. -// -//***************************************************************************** -void I2SSerializerConfig(unsigned long ulBase, unsigned long ulDataLine, - unsigned long ulSerMode, unsigned long ulInActState) -{ - if( ulSerMode == I2S_SER_MODE_TX) - { - // - // Set the data line in output mode - // - HWREG(ulBase + MCASP_O_PDIR) |= ulDataLine; - } - else - { - // - // Set the data line in input mode - // - HWREG(ulBase + MCASP_O_PDIR) &= ~ulDataLine; - } - - // - // Set the serializer configuration. - // - HWREG(ulBase + MCASP_O_XRSRCTL0 + ((ulDataLine-1) << 2)) - = (ulSerMode | ulInActState); -} - -//***************************************************************************** -// -//! Enables individual I2S interrupt sources. -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulIntFlags is the bit mask of the interrupt sources to be enabled. -//! -//! This function enables the indicated I2S interrupt sources. Only the -//! sources that are enabled can be reflected to the processor interrupt; -//! disabled sources have no effect on the processor. -//! -//! The \e ulIntFlags parameter is the logical OR of any of the following: -//! -//! -\b I2S_INT_XUNDRN -//! -\b I2S_INT_XSYNCERR -//! -\b I2S_INT_XLAST -//! -\b I2S_INT_XDATA -//! -\b I2S_INT_XSTAFRM -//! -\b I2S_INT_XDMA -//! -\b I2S_INT_ROVRN -//! -\b I2S_INT_RSYNCERR -//! -\b I2S_INT_RLAST -//! -\b I2S_INT_RDATA -//! -\b I2S_INT_RSTAFRM -//! -\b I2S_INT_RDMA -//! -//! \return None. -// -//***************************************************************************** -void I2SIntEnable(unsigned long ulBase, unsigned long ulIntFlags) -{ - - // - // Enable DMA done interrupts - // - HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_CLR ) - |= ((ulIntFlags &0xC0000000) >> 20); - - // - // Enable specific Tx Interrupts - // - HWREG(ulBase + MCASP_O_EVTCTLX) |= (ulIntFlags & 0xFF); - - // - // Enable specific Rx Interrupts - // - HWREG(ulBase + MCASP_O_EVTCTLR) |= ((ulIntFlags >> 16) & 0xFF); -} - -//***************************************************************************** -// -//! Disables individual I2S interrupt sources. -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulIntFlags is the bit mask of the interrupt sources to be disabled. -//! -//! This function disables the indicated I2S interrupt sources. Only the -//! sources that are enabled can be reflected to the processor interrupt; -//! disabled sources have no effect on the processor. -//! -//! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags -//! parameter to I2SIntEnable(). -//! -//! \return None. -// -//***************************************************************************** -void I2SIntDisable(unsigned long ulBase, unsigned long ulIntFlags) -{ - // - // Disable DMA done interrupts - // - HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_SET) - |= ((ulIntFlags &0xC0000000) >> 20); - - // - // Disable specific Tx Interrupts - // - HWREG(ulBase + MCASP_O_EVTCTLX) &= ~(ulIntFlags & 0xFF); - - // - // Disable specific Rx Interrupts - // - HWREG(ulBase + MCASP_O_EVTCTLR) &= ~((ulIntFlags >> 16) & 0xFF); -} - - -//***************************************************************************** -// -//! Gets the current interrupt status. -//! -//! \param ulBase is the base address of the I2S module. -//! -//! This function returns the raw interrupt status for I2S enumerated -//! as a bit field of values: -//! -\b I2S_STS_XERR -//! -\b I2S_STS_XDMAERR -//! -\b I2S_STS_XSTAFRM -//! -\b I2S_STS_XDATA -//! -\b I2S_STS_XLAST -//! -\b I2S_STS_XSYNCERR -//! -\b I2S_STS_XUNDRN -//! -\b I2S_STS_XDMA -//! -\b I2S_STS_RERR -//! -\b I2S_STS_RDMAERR -//! -\b I2S_STS_RSTAFRM -//! -\b I2S_STS_RDATA -//! -\b I2S_STS_RLAST -//! -\b I2S_STS_RSYNCERR -//! -\b I2S_STS_ROVERN -//! -\b I2S_STS_RDMA -//! -//! \return Returns the current interrupt status, enumerated as a bit field of -//! values described above. -// -//***************************************************************************** -unsigned long I2SIntStatus(unsigned long ulBase) -{ - unsigned long ulStatus; - - // - // Get DMA interrupt status - // - ulStatus = - HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_STS_RAW) << 20; - - ulStatus &= 0xC0000000; - - // - // Read Tx Interrupt status - // - ulStatus |= HWREG(ulBase + MCASP_O_TXSTAT); - - // - // Read Rx Interrupt status - // - ulStatus |= HWREG(ulBase + MCASP_O_RXSTAT) << 16; - - // - // Return the status - // - return ulStatus; -} - -//***************************************************************************** -// -//! Clears I2S interrupt sources. -//! -//! \param ulBase is the base address of the I2S module. -//! \param ulStatFlags is a bit mask of the interrupt sources to be cleared. -//! -//! The specified I2S interrupt sources are cleared, so that they no longer -//! assert. This function must be called in the interrupt handler to keep the -//! interrupt from being recognized again immediately upon exit. -//! -//! The \e ulIntFlags parameter is the logical OR of any of the value -//! describe in I2SIntStatus(). -//! -//! \return None. -// -//***************************************************************************** -void I2SIntClear(unsigned long ulBase, unsigned long ulStatFlags) -{ - // - // Clear DMA done interrupts - // - HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_ACK) - |= ((ulStatFlags &0xC0000000) >> 20); - - // - // Clear Tx Interrupt - // - HWREG(ulBase + MCASP_O_TXSTAT) = ulStatFlags & 0x1FF ; - - // - // Clear Rx Interrupt - // - HWREG(ulBase + MCASP_O_RXSTAT) = (ulStatFlags >> 16) & 0x1FF; -} - -//***************************************************************************** -// -//! Registers an interrupt handler for a I2S interrupt. -//! -//! \param ulBase is the base address of the I2S module. -//! \param pfnHandler is a pointer to the function to be called when the -//! I2S interrupt occurs. -//! -//! This function does the actual registering of the interrupt handler. This -//! function enables the global interrupt in the interrupt controller; specific -//! I2S interrupts must be enabled via I2SIntEnable(). It is the interrupt -//! handler's responsibility to clear the interrupt source. -//! -//! \sa IntRegister() for important information about registering interrupt -//! handlers. -//! -//! \return None. -// -//***************************************************************************** -void I2SIntRegister(unsigned long ulBase, void (*pfnHandler)(void)) -{ - // - // Register the interrupt handler - // - IntRegister(INT_I2S,pfnHandler); - - // - // Enable the interrupt - // - IntEnable(INT_I2S); -} - -//***************************************************************************** -// -//! Unregisters an interrupt handler for a I2S interrupt. -//! -//! \param ulBase is the base address of the I2S module. -//! -//! This function does the actual unregistering of the interrupt handler. It -//! clears the handler to be called when a I2S interrupt occurs. This -//! function also masks off the interrupt in the interrupt controller so that -//! the interrupt handler no longer is called. -//! -//! \sa IntRegister() for important information about registering interrupt -//! handlers. -//! -//! \return None. -// -//***************************************************************************** -void I2SIntUnregister(unsigned long ulBase) -{ - // - // Disable interrupt - // - IntDisable(INT_I2S); - - // - // Unregister the handler - // - IntUnregister(INT_I2S); - -} - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** +//*****************************************************************************
+//
+// i2s.c
+//
+// Driver for the I2S interface.
+//
+// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+//
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the
+// distribution.
+//
+// Neither the name of Texas Instruments Incorporated nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! \addtogroup I2S_api
+//! @{
+//
+//*****************************************************************************
+#include "inc/hw_types.h"
+#include "inc/hw_ints.h"
+#include "inc/hw_memmap.h"
+#include "inc/hw_mcasp.h"
+#include "inc/hw_apps_config.h"
+#include "interrupt.h"
+#include "i2s.h"
+
+//*****************************************************************************
+// Macros
+//*****************************************************************************
+#define MCASP_GBL_RCLK 0x00000001
+#define MCASP_GBL_RHCLK 0x00000002
+#define MCASP_GBL_RSER 0x00000004
+#define MCASP_GBL_RSM 0x00000008
+#define MCASP_GBL_RFSYNC 0x00000010
+#define MCASP_GBL_XCLK 0x00000100
+#define MCASP_GBL_XHCLK 0x00000200
+#define MCASP_GBL_XSER 0x00000400
+#define MCASP_GBL_XSM 0x00000800
+#define MCASP_GBL_XFSYNC 0x00001000
+
+
+//*****************************************************************************
+//
+//! \internal
+//! Releases the specifed submodule out of reset.
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulFlag is one of the valid sub module.
+//!
+//! This function Releases the specifed submodule out of reset.
+//!
+//! \return None.
+//
+//*****************************************************************************
+static void I2SGBLEnable(unsigned long ulBase, unsigned long ulFlag)
+{
+ unsigned long ulReg;
+
+ //
+ // Read global control register
+ //
+ ulReg = HWREG(ulBase + MCASP_O_GBLCTL);
+
+ //
+ // Remove the sub modules reset as specified by ulFlag parameter
+ //
+ ulReg |= ulFlag;
+
+ //
+ // Write the configuration
+ //
+ HWREG(ulBase + MCASP_O_GBLCTL) = ulReg;
+
+ //
+ // Wait for write completeion
+ //
+ while(HWREG(ulBase + MCASP_O_GBLCTL) != ulReg)
+ {
+
+ }
+
+}
+
+//*****************************************************************************
+//
+//! Enables transmit and/or receive.
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulMode is one of the valid modes.
+//!
+//! This function enables the I2S module in specified mode. The parameter
+//! \e ulMode should be one of the following
+//!
+//! -\b I2S_MODE_TX_ONLY
+//! -\b I2S_MODE_TX_RX_SYNC
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SEnable(unsigned long ulBase, unsigned long ulMode)
+{
+ //
+ // FSYNC and Bit clock are output only in master mode
+ //
+ if( HWREG(ulBase + MCASP_O_ACLKXCTL) & 0x20)
+ {
+ //
+ // Set FSYNC anc BitClk as output
+ //
+ HWREG(ulBase + MCASP_O_PDIR) |= 0x14000000;
+ }
+
+
+ if(ulMode & 0x2)
+ {
+ //
+ // Remove Rx HCLK reset
+ //
+ I2SGBLEnable(ulBase, MCASP_GBL_RHCLK);
+
+ //
+ // Remove Rx XCLK reset
+ //
+ I2SGBLEnable(ulBase, MCASP_GBL_RCLK);
+
+ //
+ // Enable Rx SERDES(s)
+ //
+ I2SGBLEnable(ulBase, MCASP_GBL_RSER);
+
+ //
+ // Enable Rx state machine
+ //
+ I2SGBLEnable(ulBase, MCASP_GBL_RSM);
+
+ //
+ // Enable FSync generator
+ //
+ I2SGBLEnable(ulBase, MCASP_GBL_RFSYNC);
+ }
+
+
+ //
+ // Remove Tx HCLK reset
+ //
+ I2SGBLEnable(ulBase, MCASP_GBL_XHCLK);
+
+ //
+ // Remove Tx XCLK reset
+ //
+ I2SGBLEnable(ulBase, MCASP_GBL_XCLK);
+
+
+ if(ulMode & 0x1)
+ {
+ //
+ // Enable Tx SERDES(s)
+ //
+ I2SGBLEnable(ulBase, MCASP_GBL_XSER);
+
+ //
+ // Enable Tx state machine
+ //
+ I2SGBLEnable(ulBase, MCASP_GBL_XSM);
+ }
+
+ //
+ // Enable FSync generator
+ //
+ I2SGBLEnable(ulBase, MCASP_GBL_XFSYNC);
+}
+
+//*****************************************************************************
+//
+//! Disables transmit and/or receive.
+//!
+//! \param ulBase is the base address of the I2S module.
+//!
+//! This function disables transmit and/or receive from I2S module.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SDisable(unsigned long ulBase)
+{
+ //
+ // Reset all sub modules
+ //
+ HWREG(ulBase + MCASP_O_GBLCTL) = 0;
+
+ //
+ // Wait for write to complete
+ //
+ while( HWREG(ulBase + MCASP_O_GBLCTL) != 0)
+ {
+
+ }
+}
+
+//*****************************************************************************
+//
+//! Waits to send data over the specified data line
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulDataLine is one of the valid data lines.
+//! \param ulData is the data to be transmitted.
+//!
+//! This function sends the \e ucData to the transmit register for the
+//! specified data line. If there is no space available, this
+//! function waits until there is space available before returning.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SDataPut(unsigned long ulBase, unsigned long ulDataLine,
+ unsigned long ulData)
+{
+ //
+ // Compute register the offeset
+ //
+ ulDataLine = (ulDataLine-1) << 2;
+
+ //
+ // Wait for free space in fifo
+ //
+ while(!( HWREG(ulBase + MCASP_O_TXSTAT) & MCASP_TXSTAT_XDATA))
+ {
+
+ }
+
+ //
+ // Write Data into the FIFO
+ //
+ HWREG(ulBase + MCASP_O_TXBUF0 + ulDataLine) = ulData;
+}
+
+//*****************************************************************************
+//
+//! Sends data over the specified data line
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulDataLine is one of the valid data lines.
+//! \param ulData is the data to be transmitted.
+//!
+//! This function writes the \e ucData to the transmit register for
+//! the specified data line. This function does not block, so if there is no
+//! space available, then \b -1 is returned, and the application must retry the
+//! function later.
+//!
+//! \return Returns 0 on success, -1 otherwise.
+//
+//*****************************************************************************
+long I2SDataPutNonBlocking(unsigned long ulBase, unsigned long ulDataLine,
+ unsigned long ulData)
+{
+
+ //
+ // Compute register the offeset
+ //
+ ulDataLine = (ulDataLine-1) << 2;
+
+ //
+ // Send Data if fifo has free space
+ //
+ if( HWREG(ulBase + MCASP_O_TXSTAT) & MCASP_TXSTAT_XDATA)
+ {
+ //
+ // Write data into the FIFO
+ //
+ HWREG(ulBase + MCASP_O_TXBUF0 + ulDataLine) = ulData;
+ return 0;
+ }
+
+ //
+ // FIFO is full
+ //
+ return(-1);
+}
+
+//*****************************************************************************
+//
+//! Waits for data from the specified data line.
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulDataLine is one of the valid data lines.
+//! \param pulData is pointer to receive data variable.
+//!
+//! This function gets data from the receive register for the specified
+//! data line. If there are no data available, this function waits until a
+//! receive before returning.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SDataGet(unsigned long ulBase, unsigned long ulDataLine,
+ unsigned long *pulData)
+{
+
+ //
+ // Compute register the offeset
+ //
+ ulDataLine = (ulDataLine-1) << 2;
+
+ //
+ // Wait for atleat on word in FIFO
+ //
+ while(!(HWREG(ulBase + MCASP_O_RXSTAT) & MCASP_RXSTAT_RDATA))
+ {
+
+ }
+
+ //
+ // Read the Data
+ //
+ *pulData = HWREG(ulBase + MCASP_O_RXBUF0 + ulDataLine);
+}
+
+
+//*****************************************************************************
+//
+//! Receives data from the specified data line.
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulDataLine is one of the valid data lines.
+//! \param pulData is pointer to receive data variable.
+//!
+//! This function gets data from the receive register for the specified
+//! data line.
+//!
+//!
+//! \return Returns 0 on success, -1 otherwise.
+//
+//*****************************************************************************
+long I2SDataGetNonBlocking(unsigned long ulBase, unsigned long ulDataLine,
+ unsigned long *pulData)
+{
+
+ //
+ // Compute register the offeset
+ //
+ ulDataLine = (ulDataLine-1) << 2;
+
+ //
+ // Check if data is available in FIFO
+ //
+ if(HWREG(ulBase + MCASP_O_RXSTAT) & MCASP_RXSTAT_RDATA)
+ {
+ //
+ // Read the Data
+ //
+ *pulData = HWREG(ulBase + MCASP_O_RXBUF0 + ulDataLine);
+ return 0;
+ }
+
+ //
+ // FIFO is empty
+ //
+ return -1;
+}
+
+
+//*****************************************************************************
+//
+//! Sets the configuration of the I2S module.
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulI2SClk is the rate of the clock supplied to the I2S module.
+//! \param ulBitClk is the desired bit rate.
+//! \param ulConfig is the data format.
+//!
+//! This function configures the I2S for operation in the specified data
+//! format. The bit rate is provided in the \e ulBitClk parameter and the data
+//! format in the \e ulConfig parameter.
+//!
+//! The \e ulConfig parameter is the logical OR of three values: the slot size
+//! the data read/write port select, Master or Slave mode
+//!
+//! Follwoing selects the Master-Slave mode
+//! -\b I2S_MODE_MASTER
+//! -\b I2S_MODE_SLAVE
+//!
+//! Following selects the slot size:
+//! -\b I2S_SLOT_SIZE_24
+//! -\b I2S_SLOT_SIZE_16
+//!
+//! Following selects the data read/write port:
+//! -\b I2S_PORT_DMA
+//! -\b I2S_PORT_CPU
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SConfigSetExpClk(unsigned long ulBase, unsigned long ulI2SClk,
+ unsigned long ulBitClk, unsigned long ulConfig)
+{
+ unsigned long ulHClkDiv;
+ unsigned long ulClkDiv;
+ unsigned long ulSlotSize;
+ unsigned long ulBitMask;
+
+ //
+ // Calculate clock dividers
+ //
+ ulHClkDiv = ((ulI2SClk/ulBitClk)-1);
+ ulClkDiv = 0;
+
+ //
+ // Check if HCLK divider is overflowing
+ //
+ if(ulHClkDiv > 0xFFF)
+ {
+ ulHClkDiv = 0xFFF;
+
+ //
+ // Calculate clock divider
+ //
+ ulClkDiv = ((ulI2SClk/(ulBitClk * (ulHClkDiv + 1))) & 0x1F);
+ }
+
+ //
+ //
+ //
+ ulClkDiv = ((ulConfig & I2S_MODE_SLAVE )?0x80:0xA0|ulClkDiv);
+
+ HWREG(ulBase + MCASP_O_ACLKXCTL) = ulClkDiv;
+
+ HWREG(ulBase + MCASP_O_AHCLKXCTL) = (0x8000|ulHClkDiv);
+
+ //
+ // Write the Tx format register
+ //
+ HWREG(ulBase + MCASP_O_TXFMT) = (0x18000 | (ulConfig & 0x7FFF));
+
+ //
+ // Write the Rx format register
+ //
+ HWREG(ulBase + MCASP_O_RXFMT) = (0x18000 | ((ulConfig >> 16) &0x7FFF));
+
+ //
+ // Check if in master mode
+ //
+ if( ulConfig & I2S_MODE_SLAVE)
+ {
+ //
+ // Configure Tx FSync generator in I2S mode
+ //
+ HWREG(ulBase + MCASP_O_TXFMCTL) = 0x111;
+
+ //
+ // Configure Rx FSync generator in I2S mode
+ //
+ HWREG(ulBase + MCASP_O_RXFMCTL) = 0x111;
+ }
+ else
+ {
+ //
+ // Configure Tx FSync generator in I2S mode
+ //
+ HWREG(ulBase + MCASP_O_TXFMCTL) = 0x113;
+
+ //
+ // Configure Rx FSync generator in I2S mode
+ //
+ HWREG(ulBase + MCASP_O_RXFMCTL) = 0x113;
+ }
+
+ //
+ // Compute Slot Size
+ //
+ ulSlotSize = ((((ulConfig & 0xFF) >> 4) + 1) * 2);
+
+ //
+ // Creat the bit mask
+ //
+ ulBitMask = (0xFFFFFFFF >> (32 - ulSlotSize));
+
+ //
+ // Set Tx bit valid mask
+ //
+ HWREG(ulBase + MCASP_O_TXMASK) = ulBitMask;
+
+ //
+ // Set Rx bit valid mask
+ //
+ HWREG(ulBase + MCASP_O_RXMASK) = ulBitMask;
+
+ //
+ // Set Tx slot valid mask
+ //
+ HWREG(ulBase + MCASP_O_TXTDM) = 0x3;
+
+ //
+ // Set Rx slot valid mask
+ //
+ HWREG(ulBase + MCASP_O_RXTDM) = 0x3;
+}
+
+//*****************************************************************************
+//
+//! Configure and enable transmit FIFO.
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulTxLevel is the transmit FIFO DMA request level.
+//! \param ulWordsPerTransfer is the nuber of words transferred from the FIFO.
+//!
+//! This function configures and enable I2S transmit FIFO.
+//!
+//! The parameter \e ulTxLevel sets the level at which transmit DMA requests
+//! are generated. This should be non-zero integer multiple of number of
+//! serializers enabled as transmitters
+//!
+//! The parameter \e ulWordsPerTransfer sets the number of words that are
+//! transferred from the transmit FIFO to the data line(s). This value must
+//! equal the number of serializers used as transmitters.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2STxFIFOEnable(unsigned long ulBase, unsigned long ulTxLevel,
+ unsigned long ulWordsPerTransfer)
+{
+ //
+ // Set transmit FIFO configuration and
+ // enable it
+ //
+ HWREG(ulBase + MCASP_0_WFIFOCTL) = ((1 <<16) | ((ulTxLevel & 0xFF) << 8)
+ | (ulWordsPerTransfer & 0x1F));
+
+}
+
+//*****************************************************************************
+//
+//! Disables transmit FIFO.
+//!
+//! \param ulBase is the base address of the I2S module.
+//!
+//! This function disables the I2S transmit FIFO.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2STxFIFODisable(unsigned long ulBase)
+{
+ //
+ // Disable transmit FIFO.
+ //
+ HWREG(ulBase + MCASP_0_WFIFOCTL) = 0;
+}
+
+//*****************************************************************************
+//
+//! Configure and enable receive FIFO.
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulRxLevel is the receive FIFO DMA request level.
+//! \param ulWordsPerTransfer is the nuber of words transferred from the FIFO.
+//!
+//! This function configures and enable I2S receive FIFO.
+//!
+//! The parameter \e ulRxLevel sets the level at which receive DMA requests
+//! are generated. This should be non-zero integer multiple of number of
+//! serializers enabled as receivers.
+//!
+//! The parameter \e ulWordsPerTransfer sets the number of words that are
+//! transferred to the receive FIFO from the data line(s). This value must
+//! equal the number of serializers used as receivers.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SRxFIFOEnable(unsigned long ulBase, unsigned long ulRxLevel,
+ unsigned long ulWordsPerTransfer)
+{
+ //
+ // Set FIFO configuration
+ //
+ HWREG(ulBase + MCASP_0_RFIFOCTL) = ( (1 <<16) | ((ulRxLevel & 0xFF) << 8)
+ | (ulWordsPerTransfer & 0x1F));
+
+}
+
+//*****************************************************************************
+//
+//! Disables receive FIFO.
+//!
+//! \param ulBase is the base address of the I2S module.
+//!
+//! This function disables the I2S receive FIFO.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SRxFIFODisable(unsigned long ulBase)
+{
+ //
+ // Disable receive FIFO.
+ //
+ HWREG(ulBase + MCASP_0_RFIFOCTL) = 0;
+}
+
+//*****************************************************************************
+//
+//! Get the transmit FIFO status.
+//!
+//! \param ulBase is the base address of the I2S module.
+//!
+//! This function gets the number of 32-bit words currently in the transmit
+//! FIFO.
+//!
+//! \return Returns transmit FIFO status.
+//
+//*****************************************************************************
+unsigned long I2STxFIFOStatusGet(unsigned long ulBase)
+{
+ //
+ // Return transmit FIFO level
+ //
+ return HWREG(ulBase + MCASP_0_WFIFOSTS);
+}
+
+//*****************************************************************************
+//
+//! Get the receive FIFO status.
+//!
+//! \param ulBase is the base address of the I2S module.
+//!
+//! This function gets the number of 32-bit words currently in the receive
+//! FIFO.
+//!
+//! \return Returns receive FIFO status.
+//
+//*****************************************************************************
+unsigned long I2SRxFIFOStatusGet(unsigned long ulBase)
+{
+ //
+ // Return receive FIFO level
+ //
+ return HWREG(ulBase + MCASP_0_RFIFOSTS);
+}
+
+//*****************************************************************************
+//
+//! Configure the serializer in specified mode.
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulDataLine is the data line (serilizer) to be configured.
+//! \param ulSerMode is the required serializer mode.
+//! \param ulInActState sets the inactive state of the data line.
+//!
+//! This function configure and enable the serializer associated with the given
+//! data line in specified mode.
+//!
+//! The paramenter \e ulDataLine selects to data line to be configured and
+//! can be one of the following:
+//! -\b I2S_DATA_LINE_0
+//! -\b I2S_DATA_LINE_1
+//!
+//! The parameter \e ulSerMode can be one of the following:
+//! -\b I2S_SER_MODE_TX
+//! -\b I2S_SER_MODE_RX
+//! -\b I2S_SER_MODE_DISABLE
+//!
+//! The parameter \e ulInActState can be one of the following
+//! -\b I2S_INACT_TRI_STATE
+//! -\b I2S_INACT_LOW_LEVEL
+//! -\b I2S_INACT_LOW_HIGH
+//!
+//! \return Returns receive FIFO status.
+//
+//*****************************************************************************
+void I2SSerializerConfig(unsigned long ulBase, unsigned long ulDataLine,
+ unsigned long ulSerMode, unsigned long ulInActState)
+{
+ if( ulSerMode == I2S_SER_MODE_TX)
+ {
+ //
+ // Set the data line in output mode
+ //
+ HWREG(ulBase + MCASP_O_PDIR) |= ulDataLine;
+ }
+ else
+ {
+ //
+ // Set the data line in input mode
+ //
+ HWREG(ulBase + MCASP_O_PDIR) &= ~ulDataLine;
+ }
+
+ //
+ // Set the serializer configuration.
+ //
+ HWREG(ulBase + MCASP_O_XRSRCTL0 + ((ulDataLine-1) << 2))
+ = (ulSerMode | ulInActState);
+}
+
+//*****************************************************************************
+//
+//! Enables individual I2S interrupt sources.
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulIntFlags is the bit mask of the interrupt sources to be enabled.
+//!
+//! This function enables the indicated I2S interrupt sources. Only the
+//! sources that are enabled can be reflected to the processor interrupt;
+//! disabled sources have no effect on the processor.
+//!
+//! The \e ulIntFlags parameter is the logical OR of any of the following:
+//!
+//! -\b I2S_INT_XUNDRN
+//! -\b I2S_INT_XSYNCERR
+//! -\b I2S_INT_XLAST
+//! -\b I2S_INT_XDATA
+//! -\b I2S_INT_XSTAFRM
+//! -\b I2S_INT_XDMA
+//! -\b I2S_INT_ROVRN
+//! -\b I2S_INT_RSYNCERR
+//! -\b I2S_INT_RLAST
+//! -\b I2S_INT_RDATA
+//! -\b I2S_INT_RSTAFRM
+//! -\b I2S_INT_RDMA
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SIntEnable(unsigned long ulBase, unsigned long ulIntFlags)
+{
+
+ //
+ // Enable DMA done interrupts
+ //
+ HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_CLR )
+ |= ((ulIntFlags &0xC0000000) >> 20);
+
+ //
+ // Enable specific Tx Interrupts
+ //
+ HWREG(ulBase + MCASP_O_EVTCTLX) |= (ulIntFlags & 0xFF);
+
+ //
+ // Enable specific Rx Interrupts
+ //
+ HWREG(ulBase + MCASP_O_EVTCTLR) |= ((ulIntFlags >> 16) & 0xFF);
+}
+
+//*****************************************************************************
+//
+//! Disables individual I2S interrupt sources.
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulIntFlags is the bit mask of the interrupt sources to be disabled.
+//!
+//! This function disables the indicated I2S interrupt sources. Only the
+//! sources that are enabled can be reflected to the processor interrupt;
+//! disabled sources have no effect on the processor.
+//!
+//! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
+//! parameter to I2SIntEnable().
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SIntDisable(unsigned long ulBase, unsigned long ulIntFlags)
+{
+ //
+ // Disable DMA done interrupts
+ //
+ HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_SET)
+ |= ((ulIntFlags &0xC0000000) >> 20);
+
+ //
+ // Disable specific Tx Interrupts
+ //
+ HWREG(ulBase + MCASP_O_EVTCTLX) &= ~(ulIntFlags & 0xFF);
+
+ //
+ // Disable specific Rx Interrupts
+ //
+ HWREG(ulBase + MCASP_O_EVTCTLR) &= ~((ulIntFlags >> 16) & 0xFF);
+}
+
+
+//*****************************************************************************
+//
+//! Gets the current interrupt status.
+//!
+//! \param ulBase is the base address of the I2S module.
+//!
+//! This function returns the raw interrupt status for I2S enumerated
+//! as a bit field of values:
+//! -\b I2S_STS_XERR
+//! -\b I2S_STS_XDMAERR
+//! -\b I2S_STS_XSTAFRM
+//! -\b I2S_STS_XDATA
+//! -\b I2S_STS_XLAST
+//! -\b I2S_STS_XSYNCERR
+//! -\b I2S_STS_XUNDRN
+//! -\b I2S_STS_XDMA
+//! -\b I2S_STS_RERR
+//! -\b I2S_STS_RDMAERR
+//! -\b I2S_STS_RSTAFRM
+//! -\b I2S_STS_RDATA
+//! -\b I2S_STS_RLAST
+//! -\b I2S_STS_RSYNCERR
+//! -\b I2S_STS_ROVERN
+//! -\b I2S_STS_RDMA
+//!
+//! \return Returns the current interrupt status, enumerated as a bit field of
+//! values described above.
+//
+//*****************************************************************************
+unsigned long I2SIntStatus(unsigned long ulBase)
+{
+ unsigned long ulStatus;
+
+ //
+ // Get DMA interrupt status
+ //
+ ulStatus =
+ HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_STS_RAW) << 20;
+
+ ulStatus &= 0xC0000000;
+
+ //
+ // Read Tx Interrupt status
+ //
+ ulStatus |= HWREG(ulBase + MCASP_O_TXSTAT);
+
+ //
+ // Read Rx Interrupt status
+ //
+ ulStatus |= HWREG(ulBase + MCASP_O_RXSTAT) << 16;
+
+ //
+ // Return the status
+ //
+ return ulStatus;
+}
+
+//*****************************************************************************
+//
+//! Clears I2S interrupt sources.
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulStatFlags is a bit mask of the interrupt sources to be cleared.
+//!
+//! The specified I2S interrupt sources are cleared, so that they no longer
+//! assert. This function must be called in the interrupt handler to keep the
+//! interrupt from being recognized again immediately upon exit.
+//!
+//! The \e ulIntFlags parameter is the logical OR of any of the value
+//! describe in I2SIntStatus().
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SIntClear(unsigned long ulBase, unsigned long ulStatFlags)
+{
+ //
+ // Clear DMA done interrupts
+ //
+ HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_ACK)
+ |= ((ulStatFlags &0xC0000000) >> 20);
+
+ //
+ // Clear Tx Interrupt
+ //
+ HWREG(ulBase + MCASP_O_TXSTAT) = ulStatFlags & 0x1FF ;
+
+ //
+ // Clear Rx Interrupt
+ //
+ HWREG(ulBase + MCASP_O_RXSTAT) = (ulStatFlags >> 16) & 0x1FF;
+}
+
+//*****************************************************************************
+//
+//! Registers an interrupt handler for a I2S interrupt.
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param pfnHandler is a pointer to the function to be called when the
+//! I2S interrupt occurs.
+//!
+//! This function does the actual registering of the interrupt handler. This
+//! function enables the global interrupt in the interrupt controller; specific
+//! I2S interrupts must be enabled via I2SIntEnable(). It is the interrupt
+//! handler's responsibility to clear the interrupt source.
+//!
+//! \sa IntRegister() for important information about registering interrupt
+//! handlers.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SIntRegister(unsigned long ulBase, void (*pfnHandler)(void))
+{
+ //
+ // Register the interrupt handler
+ //
+ IntRegister(INT_I2S,pfnHandler);
+
+ //
+ // Enable the interrupt
+ //
+ IntEnable(INT_I2S);
+}
+
+//*****************************************************************************
+//
+//! Unregisters an interrupt handler for a I2S interrupt.
+//!
+//! \param ulBase is the base address of the I2S module.
+//!
+//! This function does the actual unregistering of the interrupt handler. It
+//! clears the handler to be called when a I2S interrupt occurs. This
+//! function also masks off the interrupt in the interrupt controller so that
+//! the interrupt handler no longer is called.
+//!
+//! \sa IntRegister() for important information about registering interrupt
+//! handlers.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SIntUnregister(unsigned long ulBase)
+{
+ //
+ // Disable interrupt
+ //
+ IntDisable(INT_I2S);
+
+ //
+ // Unregister the handler
+ //
+ IntUnregister(INT_I2S);
+
+}
+
+//*****************************************************************************
+//
+//! Set the active slots for Trasmitter
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulActSlot is the bit-mask of activ slots
+//!
+//! This function sets the active slots for the transmitter. By default both
+//! the slots are active. The parameter \e ulActSlot is logical OR follwoing
+//! values:
+//! -\b I2S_ACT_SLOT_EVEN
+//! -\b I2S_ACT_SLOT_ODD
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2STxActiveSlotSet(unsigned long ulBase, unsigned long ulActSlot)
+{
+ HWREG(ulBase + MCASP_O_TXTDM) = ulActSlot;
+}
+
+//*****************************************************************************
+//
+//! Set the active slots for Receiver
+//!
+//! \param ulBase is the base address of the I2S module.
+//! \param ulActSlot is the bit-mask of activ slots
+//!
+//! This function sets the active slots for the receiver. By default both
+//! the slots are active. The parameter \e ulActSlot is logical OR follwoing
+//! values:
+//! -\b I2S_ACT_SLOT_EVEN
+//! -\b I2S_ACT_SLOT_ODD
+//!
+//! \return None.
+//
+//*****************************************************************************
+void I2SRxActiveSlotSet(unsigned long ulBase, unsigned long ulActSlot)
+{
+ HWREG(ulBase + MCASP_O_RXTDM) = ulActSlot;
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/cc3200/hal/i2s.h b/cc3200/hal/i2s.h index b4d58ff1a9..38620aef5a 100644 --- a/cc3200/hal/i2s.h +++ b/cc3200/hal/i2s.h @@ -1,202 +1,218 @@ -//***************************************************************************** -// -// i2s.h -// -// Defines and Macros for the I2S. -// -// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ -// -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the -// distribution. -// -// Neither the name of Texas Instruments Incorporated nor the names of -// its contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//***************************************************************************** - -#ifndef __I2S_H__ -#define __I2S_H__ - -//***************************************************************************** -// -// If building with a C++ compiler, make all of the definitions in this header -// have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" -{ -#endif - -//***************************************************************************** -// -// I2S DMA ports. -// -//***************************************************************************** -#define I2S_TX_DMA_PORT 0x4401E200 -#define I2S_RX_DMA_PORT 0x4401E280 - -//***************************************************************************** -// -// Values that can be passed to I2SConfigSetExpClk() as the ulConfig parameter. -// -//***************************************************************************** -#define I2S_SLOT_SIZE_24 0x00B200B4 -#define I2S_SLOT_SIZE_16 0x00700074 - -#define I2S_PORT_CPU 0x00000008 -#define I2S_PORT_DMA 0x00000000 - -//***************************************************************************** -// -// Values that can be passed as ulDataLine parameter. -// -//***************************************************************************** -#define I2S_DATA_LINE_0 0x00000001 -#define I2S_DATA_LINE_1 0x00000002 - -//***************************************************************************** -// -// Values that can be passed to I2SSerializerConfig() as the ulSerMode -// parameter. -// -//***************************************************************************** -#define I2S_SER_MODE_TX 0x00000001 -#define I2S_SER_MODE_RX 0x00000002 -#define I2S_SER_MODE_DISABLE 0x00000000 - -//***************************************************************************** -// -// Values that can be passed to I2SSerializerConfig() as the ulInActState -// parameter. -// -//***************************************************************************** -#define I2S_INACT_TRI_STATE 0x00000000 -#define I2S_INACT_LOW_LEVEL 0x00000008 -#define I2S_INACT_HIGH_LEVEL 0x0000000C - -//***************************************************************************** -// -// Values that can be passed to I2SIntEnable() and I2SIntDisable() as the -// ulIntFlags parameter. -// -//***************************************************************************** -#define I2S_INT_XUNDRN 0x00000001 -#define I2S_INT_XSYNCERR 0x00000002 -#define I2S_INT_XLAST 0x00000010 -#define I2S_INT_XDATA 0x00000020 -#define I2S_INT_XSTAFRM 0x00000080 -#define I2S_INT_XDMA 0x80000000 -#define I2S_INT_ROVRN 0x00010000 -#define I2S_INT_RSYNCERR 0x00020000 -#define I2S_INT_RLAST 0x00100000 -#define I2S_INT_RDATA 0x00200000 -#define I2S_INT_RSTAFRM 0x00800000 -#define I2S_INT_RDMA 0x40000000 - -//***************************************************************************** -// -// Values that can be passed to I2SIntClear() as the -// ulIntFlags parameter and returned from I2SIntStatus(). -// -//***************************************************************************** -#define I2S_STS_XERR 0x00000100 -#define I2S_STS_XDMAERR 0x00000080 -#define I2S_STS_XSTAFRM 0x00000040 -#define I2S_STS_XDATA 0x00000020 -#define I2S_STS_XLAST 0x00000010 -#define I2S_STS_XSYNCERR 0x00000002 -#define I2S_STS_XUNDRN 0x00000001 -#define I2S_STS_XDMA 0x80000000 -#define I2S_STS_RERR 0x01000000 -#define I2S_STS_RDMAERR 0x00800000 -#define I2S_STS_RSTAFRM 0x00400000 -#define I2S_STS_RDATA 0x00200000 -#define I2S_STS_RLAST 0x00100000 -#define I2S_STS_RSYNCERR 0x00020000 -#define I2S_STS_ROVERN 0x00010000 -#define I2S_STS_RDMA 0x40000000 - -//***************************************************************************** -// -// Values that can be passed to I2SEnable() as the ulMode parameter. -// -//***************************************************************************** -#define I2S_MODE_TX_ONLY 0x00000001 -#define I2S_MODE_TX_RX_SYNC 0x00000003 - - -//***************************************************************************** -// -// API Function prototypes -// -//***************************************************************************** -extern void I2SEnable(unsigned long ulBase, unsigned long ulMode); -extern void I2SDisable(unsigned long ulBase); - -extern void I2SDataPut(unsigned long ulBase, unsigned long ulDataLine, - unsigned long ulData); -extern long I2SDataPutNonBlocking(unsigned long ulBase, - unsigned long ulDataLine, unsigned long ulData); - -extern void I2SDataGet(unsigned long ulBase, unsigned long ulDataLine, - unsigned long *pulData); -extern long I2SDataGetNonBlocking(unsigned long ulBase, - unsigned long ulDataLine, unsigned long *pulData); - -extern void I2SConfigSetExpClk(unsigned long ulBase, unsigned long ulI2SClk, - unsigned long ulBitClk, unsigned long ulConfig); - -extern void I2STxFIFOEnable(unsigned long ulBase, unsigned long ulTxLevel, - unsigned long ulWordsPerTransfer); -extern void I2STxFIFODisable(unsigned long ulBase); -extern void I2SRxFIFOEnable(unsigned long ulBase, unsigned long ulRxLevel, - unsigned long ulWordsPerTransfer); -extern void I2SRxFIFODisable(unsigned long ulBase); -extern unsigned long I2STxFIFOStatusGet(unsigned long ulBase); -extern unsigned long I2SRxFIFOStatusGet(unsigned long ulBase); - -extern void I2SSerializerConfig(unsigned long ulBase, unsigned long ulDataLine, - unsigned long ulSerMode, unsigned long ulInActState); - -extern void I2SIntEnable(unsigned long ulBase, unsigned long ulIntFlags); -extern void I2SIntDisable(unsigned long ulBase, unsigned long ulIntFlags); -extern unsigned long I2SIntStatus(unsigned long ulBase); -extern void I2SIntClear(unsigned long ulBase, unsigned long ulIntFlags); -extern void I2SIntRegister(unsigned long ulBase, void (*pfnHandler)(void)); -extern void I2SIntUnregister(unsigned long ulBase); - -//***************************************************************************** -// -// Mark the end of the C bindings section for C++ compilers. -// -//***************************************************************************** -#ifdef __cplusplus -} -#endif - -#endif //__I2S_H__ - +//*****************************************************************************
+//
+// i2s.h
+//
+// Defines and Macros for the I2S.
+//
+// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+//
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the
+// distribution.
+//
+// Neither the name of Texas Instruments Incorporated nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#ifndef __I2S_H__
+#define __I2S_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// I2S DMA ports.
+//
+//*****************************************************************************
+#define I2S_TX_DMA_PORT 0x4401E200
+#define I2S_RX_DMA_PORT 0x4401E280
+
+//*****************************************************************************
+//
+// Values that can be passed to I2SConfigSetExpClk() as the ulConfig parameter.
+//
+//*****************************************************************************
+#define I2S_SLOT_SIZE_8 0x00300032
+#define I2S_SLOT_SIZE_16 0x00700074
+#define I2S_SLOT_SIZE_24 0x00B000B6
+
+
+#define I2S_PORT_CPU 0x00080008
+#define I2S_PORT_DMA 0x00000000
+
+#define I2S_MODE_MASTER 0x00000000
+#define I2S_MODE_SLAVE 0x00008000
+
+//*****************************************************************************
+//
+// Values that can be passed as ulDataLine parameter.
+//
+//*****************************************************************************
+#define I2S_DATA_LINE_0 0x00000001
+#define I2S_DATA_LINE_1 0x00000002
+
+//*****************************************************************************
+//
+// Values that can be passed to I2SSerializerConfig() as the ulSerMode
+// parameter.
+//
+//*****************************************************************************
+#define I2S_SER_MODE_TX 0x00000001
+#define I2S_SER_MODE_RX 0x00000002
+#define I2S_SER_MODE_DISABLE 0x00000000
+
+//*****************************************************************************
+//
+// Values that can be passed to I2SSerializerConfig() as the ulInActState
+// parameter.
+//
+//*****************************************************************************
+#define I2S_INACT_TRI_STATE 0x00000000
+#define I2S_INACT_LOW_LEVEL 0x00000008
+#define I2S_INACT_HIGH_LEVEL 0x0000000C
+
+//*****************************************************************************
+//
+// Values that can be passed to I2SIntEnable() and I2SIntDisable() as the
+// ulIntFlags parameter.
+//
+//*****************************************************************************
+#define I2S_INT_XUNDRN 0x00000001
+#define I2S_INT_XSYNCERR 0x00000002
+#define I2S_INT_XLAST 0x00000010
+#define I2S_INT_XDATA 0x00000020
+#define I2S_INT_XSTAFRM 0x00000080
+#define I2S_INT_XDMA 0x80000000
+#define I2S_INT_ROVRN 0x00010000
+#define I2S_INT_RSYNCERR 0x00020000
+#define I2S_INT_RLAST 0x00100000
+#define I2S_INT_RDATA 0x00200000
+#define I2S_INT_RSTAFRM 0x00800000
+#define I2S_INT_RDMA 0x40000000
+
+
+//*****************************************************************************
+//
+// Values that can be passed to I2SRxActiveSlotSet() and I2STxActiveSlotSet
+//
+//*****************************************************************************
+#define I2S_ACT_SLOT_EVEN 0x00000001
+#define I2S_ACT_SLOT_ODD 0x00000002
+
+//*****************************************************************************
+//
+// Values that can be passed to I2SIntClear() as the
+// ulIntFlags parameter and returned from I2SIntStatus().
+//
+//*****************************************************************************
+#define I2S_STS_XERR 0x00000100
+#define I2S_STS_XDMAERR 0x00000080
+#define I2S_STS_XSTAFRM 0x00000040
+#define I2S_STS_XDATA 0x00000020
+#define I2S_STS_XLAST 0x00000010
+#define I2S_STS_XSYNCERR 0x00000002
+#define I2S_STS_XUNDRN 0x00000001
+#define I2S_STS_XDMA 0x80000000
+#define I2S_STS_RERR 0x01000000
+#define I2S_STS_RDMAERR 0x00800000
+#define I2S_STS_RSTAFRM 0x00400000
+#define I2S_STS_RDATA 0x00200000
+#define I2S_STS_RLAST 0x00100000
+#define I2S_STS_RSYNCERR 0x00020000
+#define I2S_STS_ROVERN 0x00010000
+#define I2S_STS_RDMA 0x40000000
+
+//*****************************************************************************
+//
+// Values that can be passed to I2SEnable() as the ulMode parameter.
+//
+//*****************************************************************************
+#define I2S_MODE_TX_ONLY 0x00000001
+#define I2S_MODE_TX_RX_SYNC 0x00000003
+
+
+//*****************************************************************************
+//
+// API Function prototypes
+//
+//*****************************************************************************
+extern void I2SEnable(unsigned long ulBase, unsigned long ulMode);
+extern void I2SDisable(unsigned long ulBase);
+
+extern void I2SDataPut(unsigned long ulBase, unsigned long ulDataLine,
+ unsigned long ulData);
+extern long I2SDataPutNonBlocking(unsigned long ulBase,
+ unsigned long ulDataLine, unsigned long ulData);
+
+extern void I2SDataGet(unsigned long ulBase, unsigned long ulDataLine,
+ unsigned long *pulData);
+extern long I2SDataGetNonBlocking(unsigned long ulBase,
+ unsigned long ulDataLine, unsigned long *pulData);
+
+extern void I2SConfigSetExpClk(unsigned long ulBase, unsigned long ulI2SClk,
+ unsigned long ulBitClk, unsigned long ulConfig);
+
+extern void I2STxFIFOEnable(unsigned long ulBase, unsigned long ulTxLevel,
+ unsigned long ulWordsPerTransfer);
+extern void I2STxFIFODisable(unsigned long ulBase);
+extern void I2SRxFIFOEnable(unsigned long ulBase, unsigned long ulRxLevel,
+ unsigned long ulWordsPerTransfer);
+extern void I2SRxFIFODisable(unsigned long ulBase);
+extern unsigned long I2STxFIFOStatusGet(unsigned long ulBase);
+extern unsigned long I2SRxFIFOStatusGet(unsigned long ulBase);
+
+extern void I2SSerializerConfig(unsigned long ulBase, unsigned long ulDataLine,
+ unsigned long ulSerMode, unsigned long ulInActState);
+
+extern void I2SIntEnable(unsigned long ulBase, unsigned long ulIntFlags);
+extern void I2SIntDisable(unsigned long ulBase, unsigned long ulIntFlags);
+extern unsigned long I2SIntStatus(unsigned long ulBase);
+extern void I2SIntClear(unsigned long ulBase, unsigned long ulIntFlags);
+extern void I2SIntRegister(unsigned long ulBase, void (*pfnHandler)(void));
+extern void I2SIntUnregister(unsigned long ulBase);
+extern void I2STxActiveSlotSet(unsigned long ulBase, unsigned long ulActSlot);
+extern void I2SRxActiveSlotSet(unsigned long ulBase, unsigned long ulActSlot);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__I2S_H__
+
diff --git a/cc3200/hal/pin.c b/cc3200/hal/pin.c index 13bb80fed3..779e287066 100644 --- a/cc3200/hal/pin.c +++ b/cc3200/hal/pin.c @@ -334,7 +334,7 @@ void PinConfigSet(unsigned long ulPin,unsigned long ulPinStrength, // // Isolate the output // - HWREG(ulPad) |= 0xC00; + HWREG(ulPad) = 0xC00; } else diff --git a/cc3200/hal/prcm.c b/cc3200/hal/prcm.c index a7cab502fa..2422680b55 100644 --- a/cc3200/hal/prcm.c +++ b/cc3200/hal/prcm.c @@ -104,9 +104,24 @@ //***************************************************************************** // Register Access and Updates // -// Tick of SCC has a resolution of 32768Hz. Therefore, scaling SCC value by 32 -// yields ~1 msec resolution. All operations of SCC in RTC context use ms unit. -//***************************************************************************** +// Tick of SCC has a resolution of 32768Hz, meaning 1 sec is equal to 32768 +// clock ticks. Ideal way of getting time in millisecond will involve floating +// point arithmetic (division by 32.768). To avoid this, we simply divide it by +// 32, which will give a range from 0 -1023(instead of 0-999). To use this +// output correctly we have to take care of this inaccuracy externally. +// following wrapper can be used to convert the value from cycles to +// millisecond: +// +// CYCLES_U16MS(cycles) ((cycles *1000)/ 1024), +// +// Similarly, before setting the value, it must be first converted (from ms to +// cycles). +// +// U16MS_CYCLES(msec) ((msec *1024)/1000) +// +// Note: There is a precision loss of 1 ms with the above scheme. +// +// #define SCC_U64MSEC_GET() (MAP_PRCMSlowClkCtrGet() >> 5) #define SCC_U64MSEC_MATCH_SET(u64Msec) (MAP_PRCMSlowClkCtrMatchSet(u64Msec << 5)) #define SCC_U64MSEC_MATCH_GET() (MAP_PRCMSlowClkCtrMatchGet() >> 5) @@ -683,14 +698,24 @@ void PRCMLPDSRestoreInfoSet(unsigned long ulStackPtr, unsigned long ulProgCntr) //! \sa PRCMLPDSRestoreInfoSet(). //! //! \return None. +//! +//! \note The Test Power Domain is shutdown whenever the system +//! enters LPDS (by default). In order to avoid this and allow for +//! connecting back the debugger after waking up from LPDS, +//! the macro KEEP_TESTPD_ALIVE has to be defined while building the library. +//! This is recommended for development purposes only as it adds to +//! the current consumption of the system. +//! // //***************************************************************************** void PRCMLPDSEnter(void) { +#ifndef DEBUG // // Disable TestPD // HWREG(0x4402E168) |= (1<<9); +#endif // // Set bandgap duty cycle to 1 @@ -700,8 +725,7 @@ void PRCMLPDSEnter(void) // // Request LPDS // - HWREG(ARCM_BASE + APPS_RCM_O_APPS_LPDS_REQ) - = APPS_RCM_APPS_LPDS_REQ_APPS_LPDS_REQ; + HWREG(ARCM_BASE + APPS_RCM_O_APPS_LPDS_REQ) = APPS_RCM_APPS_LPDS_REQ_APPS_LPDS_REQ; __asm(" nop\n" " nop\n" @@ -1848,6 +1872,63 @@ void PRCMHIBRegWrite(unsigned long ulRegAddr, unsigned long ulValue) //***************************************************************************** // +//! \param ulDivider is clock frequency divider value +//! \param ulWidth is the width of the high pulse +//! +//! This function sets the input frequency for camera module. +//! +//! The frequency is calculated as follows: +//! +//! f_out = 240MHz/ulDivider; +//! +//! The parameter \e ulWidth sets the width of the high pulse. +//! +//! For e.g.: +//! +//! ulDivider = 4; +//! ulWidth = 2; +//! +//! f_out = 30 MHz and 50% duty cycle +//! +//! And, +//! +//! ulDivider = 4; +//! ulWidth = 1; +//! +//! f_out = 30 MHz and 25% duty cycle +//! +//! \return 0 on success, 1 on error +// +//***************************************************************************** +unsigned long PRCMCameraFreqSet(unsigned char ulDivider, unsigned char ulWidth) +{ + if(ulDivider > ulWidth && ulWidth != 0 ) + { + // + // Set the hifh pulse width + // + HWREG(ARCM_BASE + + APPS_RCM_O_CAMERA_CLK_GEN) = (((ulWidth & 0x07) -1) << 8); + + // + // Set the low pulse width + // + HWREG(ARCM_BASE + + APPS_RCM_O_CAMERA_CLK_GEN) = ((ulDivider - ulWidth - 1) & 0x07); + // + // Return success + // + return 0; + } + + // + // Success; + // + return 1; +} + +//***************************************************************************** +// // Close the Doxygen group. //! @} // diff --git a/cc3200/hal/prcm.h b/cc3200/hal/prcm.h index 16090980dd..58163d7cd1 100644 --- a/cc3200/hal/prcm.h +++ b/cc3200/hal/prcm.h @@ -265,6 +265,7 @@ extern void PRCMRTCMatchGet(unsigned long *ulSecs, unsigned short *usMsec); extern void PRCMCC3200MCUInit(void); extern unsigned long PRCMHIBRegRead(unsigned long ulRegAddr); extern void PRCMHIBRegWrite(unsigned long ulRegAddr, unsigned long ulValue); +extern unsigned long PRCMCameraFreqSet(unsigned char ulDivider, unsigned char ulWidth); //***************************************************************************** diff --git a/cc3200/hal/rom_patch.h b/cc3200/hal/rom_patch.h index 9855e7c341..9fb8017f8e 100644 --- a/cc3200/hal/rom_patch.h +++ b/cc3200/hal/rom_patch.h @@ -84,4 +84,15 @@ #undef ROM_GPIODirModeGet #undef ROM_GPIOIntTypeGet #undef ROM_I2CMasterInitExpClk +#undef ROM_AESDataProcess +#undef ROM_DESDataProcess +#undef ROM_I2SEnable +#undef ROM_I2SConfigSetExpClk +#undef ROM_PinConfigSet +#undef ROM_PRCMLPDSEnter +#undef ROM_PRCMCC3200MCUInit +#undef ROM_SDHostIntStatus +#undef ROM_SDHostBlockCountSet +#undef ROM_UARTModemControlSet +#undef ROM_UARTModemControlClear diff --git a/cc3200/hal/sdhost.c b/cc3200/hal/sdhost.c index daae8d2e66..ba98e359ea 100644 --- a/cc3200/hal/sdhost.c +++ b/cc3200/hal/sdhost.c @@ -512,7 +512,7 @@ SDHostIntStatus(unsigned long ulBase) // // Get DMA done interrupt status // - ulIntStatus = HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_SET); + ulIntStatus = HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_STS_RAW); ulIntStatus = (ulIntStatus << 30); // @@ -562,7 +562,7 @@ SDHostIntClear(unsigned long ulBase,unsigned long ulIntFlags) //! \param ulErrMask is the bit mask of card status errors to be enabled //! //! This function sets the card status error mask for response type R1, R1b, -//! R5, R5b and R6 response. The parameter \ulErrMask is the bit mask of card +//! R5, R5b and R6 response. The parameter \e ulErrMask is the bit mask of card //! status errors to be enabled, if the corresponding bits in the 'card status' //! field of a respose are set then the host controller indicates a card error //! interrupt status. Only bits referenced as type E (error) in status field in @@ -732,7 +732,7 @@ SDHostBlockCountSet(unsigned long ulBase, unsigned short ulBlkCount) // // Set the number of blocks // - HWREG(ulBase + MMCHS_O_BLK) |= ((ulRegVal & 0x0000FFFF)| + HWREG(ulBase + MMCHS_O_BLK) = ((ulRegVal & 0x0000FFFF)| (ulBlkCount << 16)); } diff --git a/cc3200/hal/sdhost.h b/cc3200/hal/sdhost.h index 404655535e..d0d3984973 100644 --- a/cc3200/hal/sdhost.h +++ b/cc3200/hal/sdhost.h @@ -75,7 +75,7 @@ extern "C" #define SDHOST_INT_CEB 0x00040000 #define SDHOST_INT_DTO 0x00100000 #define SDHOST_INT_DCRC 0x00200000 -#define SDHOST_INT_DEB 0x00300000 +#define SDHOST_INT_DEB 0x00400000 #define SDHOST_INT_CERR 0x10000000 #define SDHOST_INT_BADA 0x20000000 #define SDHOST_INT_DMARD 0x40000000 diff --git a/cc3200/hal/timer.c b/cc3200/hal/timer.c index 7167dcc90b..eaa2ed1435 100644 --- a/cc3200/hal/timer.c +++ b/cc3200/hal/timer.c @@ -619,6 +619,45 @@ TimerValueGet(unsigned long ulBase, unsigned long ulTimer) //***************************************************************************** // +//! Sets the current timer value. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer; must be one of \b TIMER_A or +//! \b TIMER_B. Only \b TIMER_A should be used when the timer is configured +//! for 32-bit operation. +//! \param ulValue is the new value of the timer to be set. +//! +//! This function sets the current value of the specified timer. +//! +//! \return None. +// +//***************************************************************************** +void +TimerValueSet(unsigned long ulBase, unsigned long ulTimer, + unsigned long ulValue) +{ + // + // Check the arguments. + // + ASSERT(TimerBaseValid(ulBase)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B)); + + // + // Set the appropriate timer value. + // + if( (ulTimer == TIMER_A) ) + { + HWREG(ulBase + TIMER_O_TAV) = ulValue; + } + else + { + HWREG(ulBase + TIMER_O_TBV) = ulValue; + } +} + + +//***************************************************************************** +// //! Sets the timer match value. //! //! \param ulBase is the base address of the timer module. @@ -979,8 +1018,8 @@ TimerIntClear(unsigned long ulBase, unsigned long ulIntFlags) // //! Enables the events that can trigger a DMA request. //! -//! \param ui32Base is the base address of the timer module. -//! \param ui32DMAEvent is a bit mask of the events that can trigger DMA. +//! \param ulBase is the base address of the timer module. +//! \param ulDMAEvent is a bit mask of the events that can trigger DMA. //! //! This function enables the timer events that can trigger the start of a DMA //! sequence. The DMA trigger events are specified in the \e ui32DMAEvent @@ -1022,7 +1061,7 @@ TimerDMAEventSet(unsigned long ulBase, unsigned long ulDMAEvent) // //! Returns the events that can trigger a DMA request. //! -//! \param ui32Base is the base address of the timer module. +//! \param ulBase is the base address of the timer module. //! //! This function returns the timer events that can trigger the start of a DMA //! sequence. The DMA trigger events are the logical OR of the following diff --git a/cc3200/hal/timer.h b/cc3200/hal/timer.h index d16fc9a6e4..cbe4d2cb1b 100644 --- a/cc3200/hal/timer.h +++ b/cc3200/hal/timer.h @@ -180,6 +180,8 @@ extern unsigned long TimerLoadGet(unsigned long ulBase, unsigned long ulTimer); extern unsigned long TimerValueGet(unsigned long ulBase, unsigned long ulTimer); +extern void TimerValueSet(unsigned long ulBase, unsigned long ulTimer, + unsigned long ulValue); extern void TimerMatchSet(unsigned long ulBase, unsigned long ulTimer, unsigned long ulValue); diff --git a/cc3200/hal/uart.c b/cc3200/hal/uart.c index b00bbeeb18..33d91414ba 100644 --- a/cc3200/hal/uart.c +++ b/cc3200/hal/uart.c @@ -1167,13 +1167,8 @@ UARTIntRegister(unsigned long ulBase, void (*pfnHandler)(void)) // // Determine the interrupt number based on the UART port. // -#if 1 - ulInt = UARTIntNumberGet(ulBase); -#else - ulInt = ((ulBase == UART0_BASE) ? INT_UART0 : - ((ulBase == UART1_BASE) ? INT_UART1 : INT_UART2)); -#endif + ulInt = UARTIntNumberGet(ulBase); // // Register the interrupt handler. @@ -1216,12 +1211,7 @@ UARTIntUnregister(unsigned long ulBase) // // Determine the interrupt number based on the UART port. // -#if 1 ulInt = UARTIntNumberGet(ulBase); -#else - ulInt = ((ulBase == UART0_BASE) ? INT_UART0 : - ((ulBase == UART1_BASE) ? INT_UART1 : INT_UART2)); -#endif // // Disable the interrupt. diff --git a/cc3200/mods/modwlan.c b/cc3200/mods/modwlan.c index 010db9cf64..154d0aa54f 100644 --- a/cc3200/mods/modwlan.c +++ b/cc3200/mods/modwlan.c @@ -428,6 +428,9 @@ modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ss // Unregister mDNS services ASSERT_ON_ERROR(sl_NetAppMDNSUnRegisterService(0, 0)); + // Stop the internal HTTP server + sl_NetAppStop(SL_NET_APP_HTTP_SERVER_ID); + // Remove all 64 filters (8 * 8) _WlanRxFilterOperationCommandBuff_t RxFilterIdMask; memset ((void *)&RxFilterIdMask, 0 ,sizeof(RxFilterIdMask)); |