/**
******************************************************************************
* @file stm32h7xx_hal_otfdec.c
* @author MCD Application Team
* @brief OTFDEC HAL module driver.
* This file provides firmware functions to manage the following
* functionalities of the On-The-Fly Decryption (OTFDEC) peripheral:
* + Initialization and de-initialization functions
* + Region setting/enable functions
* + Peripheral State functions
*
******************************************************************************
* @attention
*
* Copyright (c) 2018 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
@verbatim
==============================================================================
##### How to use this driver #####
==============================================================================
[..]
The OTFDEC HAL driver can be used as follows:
(#) Declare an OTFDEC_HandleTypeDef handle structure (eg. OTFDEC_HandleTypeDef hotfdec).
(#) Initialize the OTFDEC low level resources by implementing the HAL_OTFDEC_MspInit() API:
(++) Enable the OTFDEC interface clock.
(++) NVIC configuration if interrupts are used
(+++) Configure the OTFDEC interrupt priority.
(+++) Enable the NVIC OTFDEC IRQ handle.
(#) Initialize the OTFDEC peripheral by calling the HAL_OTFDEC_Init() API.
(#) For each region,
(++) Configure the region deciphering mode by calling the HAL_OTFDEC_RegionSetMode() API.
(++) Write the region Key by calling the HAL_OTFDEC_RegionSetKey() API. If desired,
read the key CRC by calling HAL_OTFDEC_RegionGetKeyCRC() API and compare the
result with the theoretically expected CRC.
(++) Initialize the OTFDEC region config structure with the Nonce, protected
region start and end addresses and firmware version, and wrap-up the region
configuration by calling HAL_OTFDEC_RegionConfig() API.
(#) At this point, the OTFDEC region configuration is done and the deciphering
is enabled. The region can be deciphered on the fly after having made sure
the OctoSPI is configured in memory-mapped mode.
[..]
(@) Warning: the OTFDEC deciphering is based on a different endianness compared
to the AES-CTR as implemented in the AES peripheral. E.g., if the OTFEC
resorts to the Key (B0, B1, B2, B3) where Bi are 32-bit longwords and B0
is the Least Significant Word, the AES has to be configured with the Key
(B3, B2, B1, B0) to report the same result (with the same swapping applied
to the Initialization Vector).
[..]
*** Callback registration ***
=============================================
[..]
The compilation flag USE_HAL_OTFDEC_REGISTER_CALLBACKS, when set to 1,
allows the user to configure dynamically the driver callbacks.
Use Functions HAL_OTFDEC_RegisterCallback()
to register an interrupt callback.
[..]
Function HAL_OTFDEC_RegisterCallback() allows to register following callbacks:
(+) ErrorCallback : OTFDEC error callback
(+) MspInitCallback : OTFDEC Msp Init callback
(+) MspDeInitCallback : OTFDEC Msp DeInit callback
This function takes as parameters the HAL peripheral handle, the Callback ID
and a pointer to the user callback function.
[..]
Use function HAL_OTFDEC_UnRegisterCallback to reset a callback to the default
weak function.
[..]
HAL_OTFDEC_UnRegisterCallback takes as parameters the HAL peripheral handle,
and the Callback ID.
This function allows to reset following callbacks:
(+) ErrorCallback : OTFDEC error callback
(+) MspInitCallback : OTFDEC Msp Init callback
(+) MspDeInitCallback : OTFDEC Msp DeInit callback
[..]
By default, after the HAL_OTFDEC_Init() and when the state is HAL_OTFDEC_STATE_RESET
all callbacks are set to the corresponding weak functions:
example HAL_OTFDEC_ErrorCallback().
Exception done for MspInit and MspDeInit functions that are
reset to the legacy weak functions in the HAL_OTFDEC_Init()HAL_OTFDEC_DeInit() only when
these callbacks are null (not registered beforehand).
[..]
If MspInit or MspDeInit are not null, the HAL_OTFDEC_Init()/HAL_OTFDEC_DeInit()
keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
[..]
Callbacks can be registered/unregistered in HAL_OTFDEC_STATE_READY state only.
Exception done MspInit/MspDeInit functions that can be registered/unregistered
in HAL_OTFDEC_STATE_READY or HAL_OTFDEC_STATE_RESET state,
thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
[..]
Then, the user first registers the MspInit/MspDeInit user callbacks
using HAL_OTFDEC_RegisterCallback() before calling HAL_OTFDEC_DeInit()
or HAL_OTFDEC_Init() function.
[..]
When the compilation flag USE_HAL_OTFDEC_REGISTER_CALLBACKS is set to 0 or
not defined, the callback registration feature is not available and all callbacks
are set to the corresponding weak functions.
@endverbatim
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32h7xx_hal.h"
/** @addtogroup STM32H7xx_HAL_Driver
* @{
*/
/** @defgroup OTFDEC OTFDEC
* @brief OTFDEC HAL module driver.
* @{
*/
#ifdef HAL_OTFDEC_MODULE_ENABLED
#if defined(OTFDEC1)
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup OTFDEC_Exported_Functions
* @{
*/
/** @defgroup OTFDEC_Exported_Functions_Group1 Initialization and de-initialization functions
* @brief Initialization and Configuration functions.
*
@verbatim
==============================================================================
##### Initialization and de-initialization functions #####
==============================================================================
@endverbatim
* @{
*/
/**
* @brief Initialize the OTFDEC peripheral and create the associated handle.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @retval HAL status
*/
HAL_StatusTypeDef HAL_OTFDEC_Init(OTFDEC_HandleTypeDef *hotfdec)
{
/* Check the OTFDEC handle allocation */
if (hotfdec == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
if (hotfdec->State == HAL_OTFDEC_STATE_RESET)
{
/* Allocate lock resource and initialize it */
__HAL_UNLOCK(hotfdec);
#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1)
/* Init the OTFDEC Callback settings */
hotfdec->ErrorCallback = HAL_OTFDEC_ErrorCallback; /* Legacy weak callback */
if (hotfdec->MspInitCallback == NULL)
{
hotfdec->MspInitCallback = HAL_OTFDEC_MspInit; /* Legacy weak MspInit */
}
/* Init the low level hardware */
hotfdec->MspInitCallback(hotfdec);
#else
/* Init the low level hardware */
HAL_OTFDEC_MspInit(hotfdec);
#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */
}
/* Change the OTFDEC state */
hotfdec->State = HAL_OTFDEC_STATE_READY;
/* Return function status */
return HAL_OK;
}
/**
* @brief DeInitialize the OTFDEC peripheral.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @retval HAL status
*/
HAL_StatusTypeDef HAL_OTFDEC_DeInit(OTFDEC_HandleTypeDef *hotfdec)
{
/* Check the OTFDEC handle allocation */
if (hotfdec == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
/* Change the OTFDEC state */
hotfdec->State = HAL_OTFDEC_STATE_BUSY;
#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1)
if (hotfdec->MspDeInitCallback == NULL)
{
hotfdec->MspDeInitCallback = HAL_OTFDEC_MspDeInit; /* Legacy weak MspDeInit */
}
/* DeInit the low level hardware: CLOCK, NVIC */
hotfdec->MspDeInitCallback(hotfdec);
#else
/* DeInit the low level hardware: CLOCK, NVIC */
HAL_OTFDEC_MspDeInit(hotfdec);
#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */
/* Change the OTFDEC state */
hotfdec->State = HAL_OTFDEC_STATE_RESET;
/* Reset OTFDEC error status */
hotfdec->ErrorCode = HAL_OTFDEC_ERROR_NONE;
/* Release Lock */
__HAL_UNLOCK(hotfdec);
/* Return function status */
return HAL_OK;
}
/**
* @brief Initialize the OTFDEC MSP.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @retval None
*/
__weak void HAL_OTFDEC_MspInit(OTFDEC_HandleTypeDef *hotfdec)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hotfdec);
/* NOTE : This function should not be modified; when the callback is needed,
the HAL_OTFDEC_MspInit can be implemented in the user file.
*/
}
/**
* @brief DeInitialize OTFDEC MSP.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @retval None
*/
__weak void HAL_OTFDEC_MspDeInit(OTFDEC_HandleTypeDef *hotfdec)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hotfdec);
/* NOTE : This function should not be modified; when the callback is needed,
the HAL_OTFDEC_MspDeInit can be implemented in the user file.
*/
}
#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1)
/**
* @brief Register a User OTFDEC Callback
* To be used instead of the weak predefined callback
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @param CallbackID ID of the callback to be registered
* This parameter can be one of the following values:
* @arg @ref HAL_OTFDEC_ERROR_CB_ID OTFDEC error callback ID
* @arg @ref HAL_OTFDEC_MSPINIT_CB_ID MspInit callback ID
* @arg @ref HAL_OTFDEC_MSPDEINIT_CB_ID MspDeInit callback ID
* @param pCallback pointer to the Callback function
* @retval HAL status
*/
HAL_StatusTypeDef HAL_OTFDEC_RegisterCallback(OTFDEC_HandleTypeDef *hotfdec, HAL_OTFDEC_CallbackIDTypeDef CallbackID,
pOTFDEC_CallbackTypeDef pCallback)
{
HAL_StatusTypeDef status = HAL_OK;
if (pCallback == NULL)
{
/* Update the error code */
hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
return HAL_ERROR;
}
if (hotfdec->State == HAL_OTFDEC_STATE_READY)
{
switch (CallbackID)
{
case HAL_OTFDEC_ERROR_CB_ID :
hotfdec->ErrorCallback = pCallback;
break;
case HAL_OTFDEC_MSPINIT_CB_ID :
hotfdec->MspInitCallback = pCallback;
break;
case HAL_OTFDEC_MSPDEINIT_CB_ID :
hotfdec->MspDeInitCallback = pCallback;
break;
default :
/* Update the error code */
hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
/* Return error status */
status = HAL_ERROR;
break;
}
}
else if (HAL_OTFDEC_STATE_RESET == hotfdec->State)
{
switch (CallbackID)
{
case HAL_OTFDEC_MSPINIT_CB_ID :
hotfdec->MspInitCallback = pCallback;
break;
case HAL_OTFDEC_MSPDEINIT_CB_ID :
hotfdec->MspDeInitCallback = pCallback;
break;
default :
/* Update the error code */
hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
/* Return error status */
status = HAL_ERROR;
break;
}
}
else
{
/* Update the error code */
hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
/* Return error status */
status = HAL_ERROR;
}
return status;
}
/**
* @brief Unregister a OTFDEC Callback
* OTFDEC callback is redirected to the weak predefined callback
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @param CallbackID ID of the callback to be registered
* This parameter can be one of the following values:
* @arg @ref HAL_OTFDEC_ERROR_CB_ID OTFDEC error callback ID
* @arg @ref HAL_OTFDEC_MSPINIT_CB_ID MspInit callback ID
* @arg @ref HAL_OTFDEC_MSPDEINIT_CB_ID MspDeInit callback ID
* @retval HAL status
*/
HAL_StatusTypeDef HAL_OTFDEC_UnRegisterCallback(OTFDEC_HandleTypeDef *hotfdec, HAL_OTFDEC_CallbackIDTypeDef CallbackID)
{
HAL_StatusTypeDef status = HAL_OK;
if (hotfdec->State == HAL_OTFDEC_STATE_READY)
{
switch (CallbackID)
{
case HAL_OTFDEC_ERROR_CB_ID :
hotfdec->ErrorCallback = HAL_OTFDEC_ErrorCallback;
break;
case HAL_OTFDEC_MSPINIT_CB_ID :
hotfdec->MspInitCallback = HAL_OTFDEC_MspInit; /* Legacy weak MspInit */
break;
case HAL_OTFDEC_MSPDEINIT_CB_ID :
hotfdec->MspDeInitCallback = HAL_OTFDEC_MspDeInit; /* Legacy weak MspDeInit */
break;
default :
/* Update the error code */
hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
/* Return error status */
status = HAL_ERROR;
break;
}
}
else if (HAL_OTFDEC_STATE_RESET == hotfdec->State)
{
switch (CallbackID)
{
case HAL_OTFDEC_MSPINIT_CB_ID :
hotfdec->MspInitCallback = HAL_OTFDEC_MspInit; /* Legacy weak MspInit */
break;
case HAL_OTFDEC_MSPDEINIT_CB_ID :
hotfdec->MspDeInitCallback = HAL_OTFDEC_MspDeInit; /* Legacy weak MspDeInit */
break;
default :
/* Update the error code */
hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
/* Return error status */
status = HAL_ERROR;
break;
}
}
else
{
/* Update the error code */
hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK;
/* Return error status */
status = HAL_ERROR;
}
return status;
}
#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */
/**
* @}
*/
/** @defgroup OTFDEC_Exported_Functions_Group2 OTFDEC IRQ handler management
* @brief OTFDEC IRQ handler.
*
@verbatim
==============================================================================
##### OTFDEC IRQ handler management #####
==============================================================================
[..] This section provides OTFDEC IRQ handler function.
@endverbatim
* @{
*/
/**
* @brief Handle OTFDEC interrupt request.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @retval None
*/
void HAL_OTFDEC_IRQHandler(OTFDEC_HandleTypeDef *hotfdec)
{
uint32_t isr_reg;
isr_reg = READ_REG(hotfdec->Instance->ISR);
if ((isr_reg & OTFDEC_ISR_SEIF) == OTFDEC_ISR_SEIF)
{
SET_BIT(hotfdec->Instance->ICR, OTFDEC_ICR_SEIF);
hotfdec->ErrorCode |= HAL_OTFDEC_SECURITY_ERROR;
}
if ((isr_reg & OTFDEC_ISR_XONEIF) == OTFDEC_ISR_XONEIF)
{
SET_BIT(hotfdec->Instance->ICR, OTFDEC_ICR_XONEIF);
hotfdec->ErrorCode |= HAL_OTFDEC_EXECUTE_ERROR;
}
if ((isr_reg & OTFDEC_ISR_KEIF) == OTFDEC_ISR_KEIF)
{
SET_BIT(hotfdec->Instance->ICR, OTFDEC_ICR_KEIF);
hotfdec->ErrorCode |= HAL_OTFDEC_KEY_ERROR;
}
#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1)
hotfdec->ErrorCallback(hotfdec);
#else
HAL_OTFDEC_ErrorCallback(hotfdec);
#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */
}
/**
* @brief OTFDEC error callback.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @retval None
*/
__weak void HAL_OTFDEC_ErrorCallback(OTFDEC_HandleTypeDef *hotfdec)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hotfdec);
/* NOTE : This function should not be modified; when the callback is needed,
the HAL_OTFDEC_ErrorCallback can be implemented in the user file.
*/
}
/**
* @}
*/
/** @defgroup OTFDEC_Exported_Functions_Group3 Peripheral Control functions
* @brief Peripheral control functions.
*
@verbatim
==============================================================================
##### Peripheral Control functions #####
==============================================================================
[..]
This subsection permits to configure the OTFDEC peripheral
@endverbatim
* @{
*/
/**
* @brief Lock region keys.
* @note Writes to this region KEYRx registers are ignored until next OTFDEC reset.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @param RegionIndex index of region the keys of which are locked
* @retval HAL state
*/
HAL_StatusTypeDef HAL_OTFDEC_RegionKeyLock(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex)
{
OTFDEC_Region_TypeDef *region;
uint32_t address;
/* Check the parameters */
assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
/* Take Lock */
__HAL_LOCK(hotfdec);
address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
region = (OTFDEC_Region_TypeDef *)address;
SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_KEYLOCK);
/* Release Lock */
__HAL_UNLOCK(hotfdec);
/* Status is okay */
return HAL_OK;
}
/**
* @brief Set region keys.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @param RegionIndex index of region the keys of which are set
* @param pKey pointer at set of keys
* @note The API reads the key CRC computed by the peripheral and compares it with that
* theoretically expected. An error is reported if they are different.
* @retval HAL state
*/
HAL_StatusTypeDef HAL_OTFDEC_RegionSetKey(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, uint32_t *pKey)
{
OTFDEC_Region_TypeDef *region;
uint32_t address;
/* Check the parameters */
assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
if (pKey == NULL)
{
return HAL_ERROR;
}
else
{
/* Take Lock */
__HAL_LOCK(hotfdec);
address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
region = (OTFDEC_Region_TypeDef *)address;
/* Set Key */
WRITE_REG(region->REG_KEYR0, pKey[0]);
__DSB();
__ISB();
WRITE_REG(region->REG_KEYR1, pKey[1]);
__DSB();
__ISB();
WRITE_REG(region->REG_KEYR2, pKey[2]);
__DSB();
__ISB();
WRITE_REG(region->REG_KEYR3, pKey[3]);
/* Compute theoretically expected CRC and compare it with that reported by the peripheral */
if (HAL_OTFDEC_KeyCRCComputation(pKey) != HAL_OTFDEC_RegionGetKeyCRC(hotfdec, RegionIndex))
{
/* Release Lock */
__HAL_UNLOCK(hotfdec);
/* Status is okay */
return HAL_ERROR;
}
/* Release Lock */
__HAL_UNLOCK(hotfdec);
/* Status is okay */
return HAL_OK;
}
}
/**
* @brief Set region mode.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @param RegionIndex index of region the mode of which is set
* @param mode This parameter can be only:
* @arg @ref OTFDEC_REG_MODE_INSTRUCTION_ACCESSES_ONLY
Only instruction accesses are decrypted
* @arg @ref OTFDEC_REG_MODE_DATA_ACCESSES_ONLY
Only data accesses are decrypted
* @arg @ref OTFDEC_REG_MODE_INSTRUCTION_OR_DATA_ACCESSES
All read accesses are decrypted (instruction or data)
* @arg @ref OTFDEC_REG_MODE_INSTRUCTION_ACCESSES_ONLY_WITH_CIPHER
Only instruction accesses are decrypted with proprietary cipher activated
* @retval HAL state
*/
HAL_StatusTypeDef HAL_OTFDEC_RegionSetMode(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, uint32_t mode)
{
OTFDEC_Region_TypeDef *region;
uint32_t address;
/* Check the parameters */
assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
assert_param(IS_OTFDEC_REGION_OPERATING_MODE(mode));
/* Take Lock */
__HAL_LOCK(hotfdec);
address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
region = (OTFDEC_Region_TypeDef *)address;
/* Set mode */
MODIFY_REG(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_MODE, mode);
/* Release Lock */
__HAL_UNLOCK(hotfdec);
/* Status is okay */
return HAL_OK;
}
/**
* @brief Set region configuration.
* @note Region deciphering is enabled at the end of this function
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @param RegionIndex index of region that is configured
* @param Config pointer on structure containing the region configuration parameters
* @param lock configuration lock enable or disable parameter
* This parameter can be one of the following values:
* @arg @ref OTFDEC_REG_CONFIGR_LOCK_DISABLE OTFDEC region configuration is not locked
* @arg @ref OTFDEC_REG_CONFIGR_LOCK_ENABLE OTFDEC region configuration is locked
* @retval HAL state
*/
HAL_StatusTypeDef HAL_OTFDEC_RegionConfig(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex,
OTFDEC_RegionConfigTypeDef *Config, uint32_t lock)
{
OTFDEC_Region_TypeDef *region;
uint32_t address;
/* Check the parameters */
assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
assert_param(IS_OTFDEC_REGION_CONFIG_LOCK(lock));
if (Config == NULL)
{
return HAL_ERROR;
}
else
{
/* Take Lock */
__HAL_LOCK(hotfdec);
address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
region = (OTFDEC_Region_TypeDef *)address;
/* Set Nonce */
WRITE_REG(region->REG_NONCER0, Config->Nonce[0]);
WRITE_REG(region->REG_NONCER1, Config->Nonce[1]);
/* Write region protected area start and end addresses */
WRITE_REG(region->REG_START_ADDR, Config->StartAddress);
WRITE_REG(region->REG_END_ADDR, Config->EndAddress);
/* Write Version */
MODIFY_REG(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_VERSION,
(uint32_t)(Config->Version) << OTFDEC_REG_CONFIGR_VERSION_Pos);
/* Enable region deciphering or enciphering (depending of OTFDEC_CR ENC bit setting) */
SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_REG_ENABLE);
/* Lock the region configuration according to lock parameter value */
if (lock == OTFDEC_REG_CONFIGR_LOCK_ENABLE)
{
SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_LOCK_ENABLE);
}
/* Release Lock */
__HAL_UNLOCK(hotfdec);
/* Status is okay */
return HAL_OK;
}
}
/**
* @brief Compute Key CRC
* @param pKey pointer at set of keys
* @retval CRC value
*/
uint32_t HAL_OTFDEC_KeyCRCComputation(uint32_t *pKey)
{
uint8_t crc7_poly = 0x7;
uint32_t key_strobe[4] = {0xAA55AA55U, 0x3U, 0x18U, 0xC0U};
uint8_t i;
uint8_t crc = 0;
uint32_t j;
uint32_t keyval;
uint32_t k;
uint32_t *temp = pKey;
for (j = 0U; j < 4U; j++)
{
keyval = *temp;
temp++;
if (j == 0U)
{
keyval ^= key_strobe[0];
}
else
{
keyval ^= (key_strobe[j] << 24) | ((uint32_t)crc << 16) | (key_strobe[j] << 8) | crc;
}
crc = 0;
for (i = 0; i < (uint8_t)32; i++)
{
k = ((((uint32_t)crc >> 7) ^ ((keyval >> ((uint8_t)31 - i)) & ((uint8_t)0xF)))) & 1U;
crc <<= 1;
if (k != 0U)
{
crc ^= crc7_poly;
}
}
crc ^= (uint8_t)0x55;
}
return (uint32_t) crc;
}
/**
* @brief Enable region deciphering.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @param RegionIndex index of region the deciphering is enabled
* @note An error is reported when the configuration is locked.
* @retval HAL state
*/
HAL_StatusTypeDef HAL_OTFDEC_RegionEnable(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex)
{
OTFDEC_Region_TypeDef *region;
uint32_t address;
/* Check the parameters */
assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
/* Take Lock */
__HAL_LOCK(hotfdec);
address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
region = (OTFDEC_Region_TypeDef *)address;
if (READ_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_LOCK_ENABLE) == OTFDEC_REG_CONFIGR_LOCK_ENABLE)
{
/* Configuration is locked, REG_EN bit can't be modified */
__HAL_UNLOCK(hotfdec);
return HAL_ERROR;
}
/* Enable region processing */
SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_REG_ENABLE);
/* Release Lock */
__HAL_UNLOCK(hotfdec);
/* Status is okay */
return HAL_OK;
}
/**
* @brief Disable region deciphering.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @param RegionIndex index of region the deciphering is disabled
* @note An error is reported when the configuration is locked.
* @retval HAL state
*/
HAL_StatusTypeDef HAL_OTFDEC_RegionDisable(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex)
{
OTFDEC_Region_TypeDef *region;
uint32_t address;
/* Check the parameters */
assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
/* Take Lock */
__HAL_LOCK(hotfdec);
address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
region = (OTFDEC_Region_TypeDef *)address;
if (READ_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_LOCK_ENABLE) == OTFDEC_REG_CONFIGR_LOCK_ENABLE)
{
/* Configuration is locked, REG_EN bit can't be modified */
__HAL_UNLOCK(hotfdec);
return HAL_ERROR;
}
/* Disable region processing */
CLEAR_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_REG_ENABLE);
/* Release Lock */
__HAL_UNLOCK(hotfdec);
/* Status is okay */
return HAL_OK;
}
/**
* @}
*/
/** @defgroup OTFDEC_Exported_Functions_Group4 Peripheral State and Status functions
* @brief Peripheral State functions.
*
@verbatim
==============================================================================
##### Peripheral State functions #####
==============================================================================
[..]
This subsection permits to get in run-time the status of the peripheral.
@endverbatim
* @{
*/
/**
* @brief Return the OTFDEC state.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @retval HAL state
*/
HAL_OTFDEC_StateTypeDef HAL_OTFDEC_GetState(OTFDEC_HandleTypeDef *hotfdec)
{
return hotfdec->State;
}
/**
* @brief Return region keys CRC.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @param RegionIndex index of region the keys CRC of which is read
* @retval Key CRC
*/
uint32_t HAL_OTFDEC_RegionGetKeyCRC(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex)
{
OTFDEC_Region_TypeDef *region;
uint32_t address;
uint32_t keycrc;
/* Check the parameters */
assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
region = (OTFDEC_Region_TypeDef *)address;
keycrc = (READ_REG(region->REG_CONFIGR)) & OTFDEC_REG_CONFIGR_KEYCRC;
keycrc >>= OTFDEC_REG_CONFIGR_KEYCRC_Pos;
return keycrc;
}
/**
* @brief Return region configuration parameters.
* @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains
* the configuration information for OTFDEC module
* @param RegionIndex index of region the configuration of which is read
* @param Config pointer on structure that will be filled up with the region configuration parameters
* @retval HAL state
*/
HAL_StatusTypeDef HAL_OTFDEC_RegionGetConfig(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex,
OTFDEC_RegionConfigTypeDef *Config)
{
OTFDEC_Region_TypeDef *region;
uint32_t address;
/* Check the parameters */
assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance));
assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex));
if (Config == NULL)
{
return HAL_ERROR;
}
else
{
/* Take Lock */
__HAL_LOCK(hotfdec);
address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex);
region = (OTFDEC_Region_TypeDef *)address;
/* Read Nonce */
Config->Nonce[0] = READ_REG(region->REG_NONCER0);
Config->Nonce[1] = READ_REG(region->REG_NONCER1);
/* Read Addresses */
Config->StartAddress = READ_REG(region->REG_START_ADDR);
Config->EndAddress = READ_REG(region->REG_END_ADDR);
/* Read Version */
Config->Version = (uint16_t)(READ_REG(region->REG_CONFIGR) &
OTFDEC_REG_CONFIGR_VERSION) >> OTFDEC_REG_CONFIGR_VERSION_Pos;
/* Release Lock */
__HAL_UNLOCK(hotfdec);
/* Status is okay */
return HAL_OK;
}
}
/**
* @}
*/
/**
* @}
*/
#endif /* OTFDEC1 */
#endif /* HAL_OTFDEC_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/