text:
#define IS_ACL_HANDLE(_handle) ((_handle) < CONFIG_BT_MAX_CONN)

enum llcp {
	LLCP_NONE,
	LLCP_CONN_UPD,
	LLCP_CHAN_MAP,

	/*
	 * LLCP_TERMINATE,
	 * LLCP_FEATURE_EXCHANGE,
	 * LLCP_VERSION_EXCHANGE,
	 */

#if defined(CONFIG_BT_CTLR_LE_ENC)
	LLCP_ENCRYPTION,
#endif /* CONFIG_BT_CTLR_LE_ENC */

	LLCP_CONNECTION_PARAM_REQ,

#if defined(CONFIG_BT_CTLR_LE_PING)
	LLCP_PING,
#endif /* CONFIG_BT_CTLR_LE_PING */

#if defined(CONFIG_BT_CTLR_PHY)
	LLCP_PHY_UPD,
#endif /* CONFIG_BT_CTLR_PHY */
};

#if defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
struct ll_conn {
	struct ull_hdr  ull;
	struct lll_conn lll;

	uint16_t connect_expire;
	uint16_t supervision_reload;
	uint16_t supervision_expire;
	uint16_t procedure_reload;
	uint16_t procedure_expire;

#if defined(CONFIG_BT_CTLR_LE_PING)
	uint16_t appto_reload;
	uint16_t appto_expire;
	uint16_t apto_reload;
	uint16_t apto_expire;
#endif /* CONFIG_BT_CTLR_LE_PING */

#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
	uint16_t default_tx_octets;

#if defined(CONFIG_BT_CTLR_PHY)
	uint16_t default_tx_time;
#endif /* CONFIG_BT_CTLR_PHY */
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */

#if defined(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN)
	uint8_t own_id_addr_type:1;
	uint8_t peer_id_addr_type:1;
	uint8_t own_id_addr[BDADDR_SIZE];
	uint8_t peer_id_addr[BDADDR_SIZE];
#endif /* CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN */

	union {
		struct {
			uint8_t fex_valid:1;
			uint8_t txn_lock:1;
#if defined(CONFIG_BT_CTLR_CONN_META)
			uint8_t is_must_expire:1;
#endif /* CONFIG_BT_CTLR_CONN_META */
		} common;

#if defined(CONFIG_BT_PERIPHERAL)
		struct {
			uint8_t  fex_valid:1;
			uint8_t  txn_lock:1;
#if defined(CONFIG_BT_CTLR_CONN_META)
			uint8_t  is_must_expire:1;
#endif /* CONFIG_BT_CTLR_CONN_META */
			uint8_t  latency_cancel:1;
			uint8_t  sca:3;
#if defined(CONFIG_BT_CTLR_LE_ENC)
			uint8_t  llcp_type;
#endif /* CONFIG_BT_CTLR_LE_ENC */
#if defined(CONFIG_BT_CTLR_CONN_RANDOM_FORCE)
			uint32_t force;
#endif /* CONFIG_BT_CTLR_CONN_RANDOM_FORCE */
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
			uint32_t ticks_to_offset;
#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
		} periph;
#endif /* CONFIG_BT_PERIPHERAL */

#if defined(CONFIG_BT_CENTRAL)
		struct {
			uint8_t fex_valid:1;
			uint8_t txn_lock:1;
#if defined(CONFIG_BT_CTLR_CONN_META)
			uint8_t is_must_expire:1;
#endif /* CONFIG_BT_CTLR_CONN_META */
			uint8_t terminate_ack:1;
		} central;
#endif /* CONFIG_BT_CENTRAL */
	};

	uint8_t llcp_req;
	uint8_t llcp_ack;

	uint8_t llcp_type;

	struct {
		union {
			struct {
				uint16_t instant;
				uint16_t *pdu_win_offset;
				uint32_t ticks_anchor;
			} conn_upd;

			struct {
				uint8_t  initiate:1;
				uint8_t  chm[5];
				uint16_t instant;
			} chan_map;

#if defined(CONFIG_BT_CTLR_PHY)
			struct {
				uint8_t initiate:1;
				uint8_t cmd:1;
				uint8_t tx:3;
				uint8_t rx:3;
				uint16_t instant;
			} phy_upd_ind;
#endif /* CONFIG_BT_CTLR_PHY */
		};

#if defined(CONFIG_BT_CTLR_LE_ENC)
		struct {
			enum {
				LLCP_ENC_STATE_INPROG,
				LLCP_ENC_STATE_INIT,
				LLCP_ENC_STATE_LTK_WAIT,
				LLCP_ENC_STATE_ENC_WAIT,
			} state:2 __packed;
			uint8_t  error_code;
			uint8_t  skd[16];
		} encryption;
#endif /* CONFIG_BT_CTLR_LE_ENC */
	} llcp;

	struct node_rx_pdu *llcp_rx;

#if defined(CONFIG_BT_CTLR_RX_ENQUEUE_HOLD)
	struct node_rx_pdu *llcp_rx_hold;
#endif /* CONFIG_BT_CTLR_RX_ENQUEUE_HOLD */

	struct {
		uint8_t  req;
		uint8_t  ack;
		enum {
			LLCP_CUI_STATE_INPROG,
			LLCP_CUI_STATE_USE,
			LLCP_CUI_STATE_SELECT,
			LLCP_CUI_STATE_OFFS_REQ,
			LLCP_CUI_STATE_OFFS_RDY,
			LLCP_CUI_STATE_REJECT,
		} state:3 __packed;
		uint8_t  cmd:1;
		uint16_t interval;
		uint16_t latency;
		uint16_t timeout;
		uint32_t win_offset_us;
		uint8_t  win_size;
	} llcp_cu;

	struct {
		uint8_t  req;
		uint8_t  ack;
		/* TODO: 8, 16, 32 or 64 based on local supported features */
		uint64_t features_conn;
		uint64_t features_peer;
	} llcp_feature;

	struct {
		uint8_t  req;
		uint8_t  ack;
		uint8_t  tx:1;
		uint8_t  rx:1;
		uint8_t  version_number;
		uint16_t company_id;
		uint16_t sub_version_number;
	} llcp_version;

	struct {
		uint8_t req;
		uint8_t ack;
		uint8_t reason_own;
		uint8_t reason_final;
		/* node rx type with memory aligned storage for terminate
		 * reason.
		 * HCI will reference the value using the pdu member of
		 * struct node_rx_pdu.
		 */
		struct {
			struct node_rx_hdr hdr;
			union {
				uint8_t    pdu[0] __aligned(4);
				uint8_t    reason;
			};
		} node_rx;
	} llcp_terminate;

#if defined(CONFIG_BT_CTLR_LE_ENC)
	struct {
		uint8_t req;
		uint8_t ack;
		uint8_t pause_rx:1;
		uint8_t pause_tx:1;
		uint8_t refresh:1;
		uint8_t ediv[2];
		uint8_t rand[8];
		uint8_t ltk[16];
	} llcp_enc;
#endif /* CONFIG_BT_CTLR_LE_ENC */

#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
	struct {
		uint8_t  req;
		uint8_t  ack;
		enum {
			LLCP_CPR_STATE_REQ,
			LLCP_CPR_STATE_RSP,
			LLCP_CPR_STATE_APP_REQ,
			LLCP_CPR_STATE_APP_WAIT,
			LLCP_CPR_STATE_RSP_WAIT,
			LLCP_CPR_STATE_UPD_WAIT,
			LLCP_CPR_STATE_UPD,
			LLCP_CPR_STATE_OFFS_REQ,
			LLCP_CPR_STATE_OFFS_RDY,
		} state:4 __packed;
		uint8_t  cmd:1;
		uint8_t  disabled:1;
		uint8_t  status;
		uint16_t interval_min;
		uint16_t interval_max;
		uint16_t latency;
		uint16_t timeout;
		uint8_t  preferred_periodicity;
		uint16_t reference_conn_event_count;
		uint16_t offset0;
		uint16_t offset1;
		uint16_t offset2;
		uint16_t offset3;
		uint16_t offset4;
		uint16_t offset5;
		uint16_t *pdu_win_offset0;
		uint32_t ticks_ref;
		uint32_t ticks_to_offset_next;
	} llcp_conn_param;
#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */

#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
	struct {
		uint8_t  req;
		uint8_t  ack;
		uint8_t  state:3;
#define LLCP_LENGTH_STATE_REQ                 0
#define LLCP_LENGTH_STATE_REQ_ACK_WAIT        1
#define LLCP_LENGTH_STATE_RSP_WAIT            2
#define LLCP_LENGTH_STATE_RSP_ACK_WAIT        3
#define LLCP_LENGTH_STATE_RESIZE              4
#define LLCP_LENGTH_STATE_RESIZE_RSP          5
#define LLCP_LENGTH_STATE_RESIZE_RSP_ACK_WAIT 6
		uint8_t  disabled:1;
		uint16_t rx_octets;
		uint16_t tx_octets;
#if defined(CONFIG_BT_CTLR_PHY)
		uint16_t rx_time;
		uint16_t tx_time;
#endif /* CONFIG_BT_CTLR_PHY */
		struct {
			uint16_t tx_octets;
#if defined(CONFIG_BT_CTLR_PHY)
			uint16_t tx_time;
#endif /* CONFIG_BT_CTLR_PHY */
		} cache;
	} llcp_length;
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */

#if defined(CONFIG_BT_CTLR_PHY)
	struct {
		uint8_t req;
		uint8_t ack;
		uint8_t state:2;
#define LLCP_PHY_STATE_REQ      0
#define LLCP_PHY_STATE_ACK_WAIT 1
#define LLCP_PHY_STATE_RSP_WAIT 2
#define LLCP_PHY_STATE_UPD      3
		uint8_t tx:3;
		uint8_t rx:3;
		uint8_t pause_tx:1;
		uint8_t flags:1;
		uint8_t cmd:1;
		uint8_t disabled:1;
	} llcp_phy;

	uint8_t phy_pref_tx:3;
	uint8_t phy_pref_rx:3;
#endif /* CONFIG_BT_CTLR_PHY */

#if defined(CONFIG_BT_CTLR_LLID_DATA_START_EMPTY)
	/* Detect empty L2CAP start frame */
	uint8_t  start_empty:1;
#endif /* CONFIG_BT_CTLR_LLID_DATA_START_EMPTY */

	struct node_tx *tx_head;
	struct node_tx *tx_ctrl;
	struct node_tx *tx_ctrl_last;
	struct node_tx *tx_data;
	struct node_tx *tx_data_last;

	uint8_t chm_updated;

#if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
	struct {
		uint8_t  req;
		uint8_t  ack;
		enum {
			LLCP_CIS_STATE_REQ,
			LLCP_CIS_STATE_RSP_WAIT,
			LLCP_CIS_STATE_IND_WAIT,
			LLCP_CIS_STATE_INST_WAIT
		} state:8 __packed;
		uint8_t  cig_id;
		uint16_t cis_handle;
		uint8_t  cis_id;
		uint32_t cis_offset_min;
		uint32_t cis_offset_max;
		uint16_t conn_event_count;
	} llcp_cis;
#endif /* CONFIG_BT_CTLR_PERIPHERAL_ISO */

#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
	struct lll_df_conn_rx_params df_rx_params;
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
};
#else
/*
 * This is for the refactored LLCP
 *
 * to reduce length and unreadability of the ll_conn struct the
 * structures inside it have been defined first
 */
struct llcp_struct {
	/* Local Request */
	struct {
		sys_slist_t pend_proc_list;
		uint8_t state;
		/* Procedure Response Timeout timer expire value */
		uint16_t prt_expire;
		uint8_t pause;
	} local;

	/* Remote Request */
	struct {
		sys_slist_t pend_proc_list;
		uint8_t state;
		/* Procedure Response Timeout timer expire value */
		uint16_t prt_expire;
		uint8_t pause;
		uint8_t collision;
		uint8_t incompat;
		uint8_t reject_opcode;
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP) || defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
		uint8_t paused_cmd;
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP || CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
	} remote;

	/* Procedure Response Timeout timer reload value */
	uint16_t prt_reload;

	/* Prepare parameters */
	struct {
		uint32_t ticks_at_expire;
		uint16_t lazy;
	} prep;

	/* Version Exchange Procedure State */
	struct {
		uint8_t sent;
		uint8_t valid;
		struct pdu_data_llctrl_version_ind cached;
	} vex;

	/*
	 * As of today only 36 feature bits are in use,
	 * so some optimisation is possible
	 * we also need to keep track of the features of the
	 * other node, so that we can send a proper
	 * reply over HCI to the host
	 * see BT Core spec 5.2 Vol 6, Part B, sec. 5.1.4
	 */
	struct {
		uint8_t sent;
		uint8_t valid;
		/*
		 * Stores features supported by peer device. The content of the member may be
		 * verified when feature exchange procedure has completed, valid member is set to 1.
		 */
		uint64_t features_peer;
		/*
		 * Stores features common for two connected devices. Before feature exchange
		 * procedure is completed, the member stores information about all features
		 * supported by local device. After completion of the procedure, the feature set
		 * may be limited to features that are common.
		 */
		uint64_t features_used;
	} fex;

	/* Minimum used channels procedure state */
	struct {
		uint8_t phys;
		uint8_t min_used_chans;
	} muc;

	/* TODO: we'll need the next few structs eventually,
	 * Thomas and Szymon please comment on names etc.
	 */
	struct {
		uint16_t *pdu_win_offset;
		uint32_t ticks_anchor;
	} conn_upd;

#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
	/* @brief Constant Tone Extension configuration for CTE request control procedure. */
	struct llcp_df_req_cfg {
		/* Procedure may be active periodically, active state must be stored.
		 * If procedure is active, request parameters update may not be issued.
		 */
		volatile uint8_t is_enabled;
		uint8_t cte_type;
		/* Minimum requested CTE length in 8us units */
		uint8_t min_cte_len;
		uint16_t req_interval;
		uint16_t req_expire;
	} cte_req;
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */

#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)
	struct llcp_df_rsp_cfg {
		uint8_t is_enabled:1;
		uint8_t is_active:1;
		uint8_t cte_types;
		uint8_t max_cte_len;
		void *disable_param;
		void (*disable_cb)(void *param);
	} cte_rsp;
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */

	struct {
		uint8_t terminate_ack;
	} cis;

	uint8_t tx_buffer_alloc;
	uint8_t tx_q_pause_data_mask;
}; /* struct llcp_struct */

struct ll_conn {
	struct ull_hdr  ull;
	struct lll_conn lll;

	struct ull_tx_q tx_q;
	struct llcp_struct llcp;

	struct {
		uint8_t reason_final;
		/* node rx type with memory aligned storage for terminate
		 * reason.
		 * HCI will reference the value using the pdu member of
		 * struct node_rx_pdu.
		 */
		struct {
			struct node_rx_hdr hdr;

			uint8_t reason __aligned(4);
		} node_rx;
	} llcp_terminate;

/*
 * TODO: all the following comes from the legacy LL llcp structure
 * and/or needs to be properly integrated in the control procedures
 */
	union {
		struct {
#if defined(CONFIG_BT_CTLR_CONN_META)
			uint8_t  is_must_expire:1;
#endif /* CONFIG_BT_CTLR_CONN_META */
		} common;
#if defined(CONFIG_BT_PERIPHERAL)
		struct {
#if defined(CONFIG_BT_CTLR_CONN_META)
			uint8_t  is_must_expire:1;
#endif /* CONFIG_BT_CTLR_CONN_META */
			uint8_t  latency_cancel:1;
			uint8_t  sca:3;
			uint32_t force;
			uint32_t ticks_to_offset;
		} periph;
#endif /* CONFIG_BT_PERIPHERAL */

#if defined(CONFIG_BT_CENTRAL)
		struct {
#if defined(CONFIG_BT_CTLR_CONN_META)
			uint8_t  is_must_expire:1;
#endif /* CONFIG_BT_CTLR_CONN_META */
			uint8_t terminate_ack:1;
		} central;
#endif /* CONFIG_BT_CENTRAL */
	};

	/* Cancel the prepare in the instant a Connection Update takes place */
	uint8_t cancel_prepare:1;

#if defined(CONFIG_BT_CTLR_LE_ENC)
	/* Pause Rx data PDU's */
	uint8_t pause_rx_data:1;
#endif /* CONFIG_BT_CTLR_LE_ENC */

#if defined(CONFIG_BT_CTLR_LE_PING)
	uint16_t appto_reload;
	uint16_t appto_expire;
	uint16_t apto_reload;
	uint16_t apto_expire;
#endif /* CONFIG_BT_CTLR_LE_PING */

	uint16_t connect_expire;
	uint16_t supervision_reload;
	uint16_t supervision_expire;
	uint32_t connect_accept_to;

#if defined(CONFIG_BT_CTLR_PHY)
	uint8_t phy_pref_tx:3;
	uint8_t phy_pref_rx:3;
#endif /* CONFIG_BT_CTLR_PHY */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
	uint16_t default_tx_octets;

#if defined(CONFIG_BT_CTLR_PHY)
	uint16_t default_tx_time;
#endif /* CONFIG_BT_CTLR_PHY */
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */

#if defined(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN)
	uint8_t own_id_addr_type:1;
	uint8_t peer_id_addr_type:1;
	uint8_t own_id_addr[BDADDR_SIZE];
	uint8_t peer_id_addr[BDADDR_SIZE];
#endif /* CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN */

#if defined(CONFIG_BT_CTLR_LLID_DATA_START_EMPTY)
	/* Detect empty L2CAP start frame */
	uint8_t  start_empty:1;
#endif /* CONFIG_BT_CTLR_LLID_DATA_START_EMPTY */
}; /* struct ll_conn */
#endif /* BT_LL_SW_SPLIT_LEGACY */

struct node_rx_cc {
	uint8_t  status;
	uint8_t  role;
	uint8_t  peer_addr_type;
	uint8_t  peer_addr[BDADDR_SIZE];
#if defined(CONFIG_BT_CTLR_PRIVACY)
	uint8_t  peer_rpa[BDADDR_SIZE];
	uint8_t  local_rpa[BDADDR_SIZE];
#endif /* CONFIG_BT_CTLR_PRIVACY */
	uint16_t interval;
	uint16_t latency;
	uint16_t timeout;
	uint8_t  sca;
};

struct node_rx_cu {
	uint8_t  status;
	uint16_t interval;
	uint16_t latency;
	uint16_t timeout;
};

struct node_rx_cs {
	uint8_t csa;
};

struct node_rx_pu {
	uint8_t status;
	uint8_t tx;
	uint8_t rx;
};


text:
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"

/** @addtogroup STM32F4xx_HAL_Driver
  * @{
  */

/** @defgroup HASHEx HASHEx
  * @brief HASH Extension HAL module driver.
  * @{
  */

#ifdef HAL_HASH_MODULE_ENABLED

#if defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F479xx)

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/** @addtogroup HASHEx_Private_Functions
  * @{
  */
static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma);
static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size);
static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size);
static void HASHEx_DMAError(DMA_HandleTypeDef *hdma);
/**
  * @}
  */

/* Private functions ---------------------------------------------------------*/

/** @addtogroup HASHEx_Private_Functions
  * @{
  */

/**
  * @brief  Writes the input buffer in data register.
  * @param  pInBuffer: Pointer to input buffer
  * @param  Size: The size of input buffer
  * @retval None
  */
static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size)
{
  uint32_t buffercounter;
  uint32_t inputaddr = (uint32_t) pInBuffer;

  for(buffercounter = 0U; buffercounter < Size; buffercounter+=4U)
  {
    HASH->DIN = *(uint32_t*)inputaddr;
    inputaddr+=4U;
  }
}

/**
  * @brief  Provides the message digest result.
  * @param  pMsgDigest: Pointer to the message digest
  * @param  Size: The size of the message digest in bytes
  * @retval None
  */
static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size)
{
  uint32_t msgdigest = (uint32_t)pMsgDigest;

  switch(Size)
  {
  case 16U:
    /* Read the message digest */
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
    break;
  case 20U:
    /* Read the message digest */
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]);
    break;
  case 28U:
    /* Read the message digest */
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6U]);
    break;
  case 32U:
    /* Read the message digest */
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[0U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[1U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[2U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[3U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH->HR[4U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6U]);
    msgdigest+=4U;
    *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7U]);
    break;
  default:
    break;
  }
}

/**
  * @brief  DMA HASH Input Data complete callback.
  * @param  hdma: DMA handle
  * @retval None
  */
static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma)
{
  HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  uint32_t inputaddr = 0U;
  uint32_t buffersize = 0U;

  if((HASH->CR & HASH_CR_MODE) != HASH_CR_MODE)
  {
    /* Disable the DMA transfer */
    HASH->CR &= (uint32_t)(~HASH_CR_DMAE);

    /* Change HASH peripheral state */
    hhash->State = HAL_HASH_STATE_READY;

    /* Call Input data transfer complete callback */
    HAL_HASH_InCpltCallback(hhash);
  }
  else
  {
    /* Increment Interrupt counter */
    hhash->HashInCount++;
    /* Disable the DMA transfer before starting the next transfer */
    HASH->CR &= (uint32_t)(~HASH_CR_DMAE);

    if(hhash->HashInCount <= 2U)
    {
      /* In case HashInCount = 1, set the DMA to transfer data to HASH DIN register */
      if(hhash->HashInCount == 1U)
      {
        inputaddr = (uint32_t)hhash->pHashInBuffPtr;
        buffersize = hhash->HashBuffSize;
      }
      /* In case HashInCount = 2, set the DMA to transfer key to HASH DIN register */
      else if(hhash->HashInCount == 2U)
      {
        inputaddr = (uint32_t)hhash->Init.pKey;
        buffersize = hhash->Init.KeySize;
      }
      /* Configure the number of valid bits in last word of the message */
      MODIFY_REG(HASH->STR, HASH_STR_NBLW, 8U * (buffersize % 4U));

      /* Set the HASH DMA transfer complete */
      hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;

      /* Enable the DMA In DMA Stream */
      HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (buffersize%4U ? (buffersize+3U)/4U:buffersize/4U));

      /* Enable DMA requests */
      HASH->CR |= (HASH_CR_DMAE);
    }
    else
    {
      /* Disable the DMA transfer */
      HASH->CR &= (uint32_t)(~HASH_CR_DMAE);

      /* Reset the InCount */
      hhash->HashInCount = 0U;

      /* Change HASH peripheral state */
      hhash->State = HAL_HASH_STATE_READY;

      /* Call Input data transfer complete callback */
      HAL_HASH_InCpltCallback(hhash);
    }
  }
}

/**
  * @brief  DMA HASH communication error callback.
  * @param  hdma: DMA handle
  * @retval None
  */
static void HASHEx_DMAError(DMA_HandleTypeDef *hdma)
{
  HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  hhash->State= HAL_HASH_STATE_READY;
  HAL_HASH_ErrorCallback(hhash);
}

 /**
  * @}
  */

/* Exported functions --------------------------------------------------------*/
/** @addtogroup HASHEx_Exported_Functions
  * @{
  */

/** @defgroup  HASHEx_Group1 HASH processing functions
 *  @brief   processing functions using polling mode
 *
@verbatim
 ===============================================================================
              ##### HASH processing using polling mode functions #####
 ===============================================================================
    [..]  This section provides functions allowing to calculate in polling mode
          the hash value using one of the following algorithms:
      (+) SHA224
      (+) SHA256

@endverbatim
  * @{
  */

/**
  * @brief  Initializes the HASH peripheral in SHA224 mode
  *         then processes pInBuffer. The digest is available in pOutBuffer
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 28 bytes.
  * @param  Timeout: Specify Timeout value
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASHEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
{
  uint32_t tickstart = 0U;

  /* Process Locked */
  __HAL_LOCK(hhash);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;

  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
       the message digest of a new message */
    HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
  }

  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;

  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);

  /* Write input buffer in data register */
  HASHEx_WriteData(pInBuffer, Size);

  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();

  /* Get tick */
  tickstart = HAL_GetTick();

  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;

        /* Process Unlocked */
        __HAL_UNLOCK(hhash);

        return HAL_TIMEOUT;
      }
    }
  }

  /* Read the message digest */
  HASHEx_GetDigest(pOutBuffer, 28U);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;

  /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
            The digest is available in pOutBuffer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 32 bytes.
  * @param  Timeout: Specify Timeout value
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASHEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
{
  uint32_t tickstart = 0U;

  /* Process Locked */
  __HAL_LOCK(hhash);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;

  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
       the message digest of a new message */
    HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
  }

  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;

  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);

  /* Write input buffer in data register */
  HASHEx_WriteData(pInBuffer, Size);

  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();

  /* Get tick */
  tickstart = HAL_GetTick();

  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;

        /* Process Unlocked */
        __HAL_UNLOCK(hhash);

        return HAL_TIMEOUT;
      }
    }
  }

  /* Read the message digest */
  HASHEx_GetDigest(pOutBuffer, 32U);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;

  /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in SHA224 mode
  *         then processes pInBuffer. The digest is available in pOutBuffer
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASHEx_SHA224_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
{
  /* Process Locked */
  __HAL_LOCK(hhash);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;

  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
       the message digest of a new message */
    HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
  }

  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;

  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);

  /* Write input buffer in data register */
  HASHEx_WriteData(pInBuffer, Size);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;

  /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
            The digest is available in pOutBuffer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASHEx_SHA256_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
{
   /* Process Locked */
  __HAL_LOCK(hhash);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;

  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
       the message digest of a new message */
    HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
  }

  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;

  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);

  /* Write input buffer in data register */
  HASHEx_WriteData(pInBuffer, Size);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;

  /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @}
  */

/** @defgroup HASHEx_Group2 HMAC processing functions using polling mode
 *  @brief   HMAC processing functions using polling mode .
 *
@verbatim
 ===============================================================================
            ##### HMAC processing using polling mode functions #####
 ===============================================================================
    [..]  This section provides functions allowing to calculate in polling mode
          the HMAC value using one of the following algorithms:
      (+) SHA224
      (+) SHA256

@endverbatim
  * @{
  */

/**
  * @brief  Initializes the HASH peripheral in HMAC SHA224 mode
  *         then processes pInBuffer. The digest is available in pOutBuffer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
  * @param  Timeout: Timeout value
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HMACEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
{
  uint32_t tickstart = 0U;

   /* Process Locked */
  __HAL_LOCK(hhash);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;

  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Check if key size is greater than 64 bytes */
    if(hhash->Init.KeySize > 64U)
    {
      /* Select the HMAC SHA224 mode */
      HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
    }
    else
    {
      /* Select the HMAC SHA224 mode */
      HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
    }
  }

  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;

  /************************** STEP 1 ******************************************/
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);

  /* Write input buffer in data register */
  HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);

  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();

  /* Get tick */
  tickstart = HAL_GetTick();

  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;

        /* Process Unlocked */
        __HAL_UNLOCK(hhash);

        return HAL_TIMEOUT;
      }
    }
  }
  /************************** STEP 2 ******************************************/
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);

  /* Write input buffer in data register */
  HASHEx_WriteData(pInBuffer, Size);

  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();

  /* Get tick */
  tickstart = HAL_GetTick();

  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((HAL_GetTick() - tickstart ) > Timeout)
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;

        /* Process Unlocked */
        __HAL_UNLOCK(hhash);

        return HAL_TIMEOUT;
      }
    }
  }
  /************************** STEP 3 ******************************************/
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);

  /* Write input buffer in data register */
  HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);

  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();

  /* Get tick */
  tickstart = HAL_GetTick();

  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((HAL_GetTick() - tickstart ) > Timeout)
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;

        /* Process Unlocked */
        __HAL_UNLOCK(hhash);

        return HAL_TIMEOUT;
      }
    }
  }
  /* Read the message digest */
  HASHEx_GetDigest(pOutBuffer, 28U);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;

  /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in HMAC SHA256 mode
  *         then processes pInBuffer. The digest is available in pOutBuffer
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
  * @param  Timeout: Timeout value
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HMACEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout)
{
  uint32_t tickstart = 0U;

  /* Process Locked */
  __HAL_LOCK(hhash);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;

  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Check if key size is greater than 64 bytes */
    if(hhash->Init.KeySize > 64U)
    {
      /* Select the HMAC SHA256 mode */
      HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY);
    }
    else
    {
      /* Select the HMAC SHA256 mode */
      HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC);
    }
    /* Reset the HASH processor core, so that the HASH will be ready to compute
       the message digest of a new message */
    HASH->CR |= HASH_CR_INIT;
  }

  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;

  /************************** STEP 1 ******************************************/
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);

  /* Write input buffer in data register */
  HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);

  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();

  /* Get tick */
  tickstart = HAL_GetTick();

  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;

        /* Process Unlocked */
        __HAL_UNLOCK(hhash);

        return HAL_TIMEOUT;
      }
    }
  }
  /************************** STEP 2 ******************************************/
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);

  /* Write input buffer in data register */
  HASHEx_WriteData(pInBuffer, Size);

  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();

  /* Get tick */
  tickstart = HAL_GetTick();

  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((HAL_GetTick() - tickstart ) > Timeout)
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;

        /* Process Unlocked */
        __HAL_UNLOCK(hhash);

        return HAL_TIMEOUT;
      }
    }
  }
  /************************** STEP 3 ******************************************/
  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);

  /* Write input buffer in data register */
  HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize);

  /* Start the digest calculation */
  __HAL_HASH_START_DIGEST();

  /* Get tick */
  tickstart = HAL_GetTick();

  while((HASH->SR & HASH_FLAG_BUSY) == HASH_FLAG_BUSY)
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((HAL_GetTick() - tickstart ) > Timeout)
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;

        /* Process Unlocked */
        __HAL_UNLOCK(hhash);

        return HAL_TIMEOUT;
      }
    }
  }
  /* Read the message digest */
  HASHEx_GetDigest(pOutBuffer, 32U);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_READY;

   /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @}
  */

/** @defgroup HASHEx_Group3 HASH processing functions using interrupt mode
 *  @brief   processing functions using interrupt mode.
 *
@verbatim
 ===============================================================================
              ##### HASH processing using interrupt functions #####
 ===============================================================================
    [..]  This section provides functions allowing to calculate in interrupt mode
          the hash value using one of the following algorithms:
      (+) SHA224
      (+) SHA256

@endverbatim
  * @{
  */

/**
  * @brief  Initializes the HASH peripheral in SHA224 mode then processes pInBuffer.
  *         The digest is available in pOutBuffer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
{
  uint32_t inputaddr;
  uint32_t buffercounter;
  uint32_t inputcounter;

  /* Process Locked */
  __HAL_LOCK(hhash);

  if(hhash->State == HAL_HASH_STATE_READY)
  {
    /* Change the HASH state */
    hhash->State = HAL_HASH_STATE_BUSY;

    hhash->HashInCount = Size;
    hhash->pHashInBuffPtr = pInBuffer;
    hhash->pHashOutBuffPtr = pOutBuffer;

    /* Check if initialization phase has already been performed */
    if(hhash->Phase == HAL_HASH_PHASE_READY)
    {
      /* Select the SHA224 mode */
      HASH->CR |= HASH_ALGOSELECTION_SHA224;
      /* Reset the HASH processor core, so that the HASH will be ready to compute
         the message digest of a new message */
      HASH->CR |= HASH_CR_INIT;
    }
    /* Reset interrupt counter */
    hhash->HashITCounter = 0U;

    /* Set the phase */
    hhash->Phase = HAL_HASH_PHASE_PROCESS;

    /* Process Unlocked */
    __HAL_UNLOCK(hhash);

    /* Enable Interrupts */
    HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);

    /* Return function status */
    return HAL_OK;
  }
  if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
  {
    /* Read the message digest */
    HASHEx_GetDigest(hhash->pHashOutBuffPtr, 28U);
    if(hhash->HashInCount == 0U)
    {
      /* Disable Interrupts */
      HASH->IMR = 0U;
      /* Change the HASH state */
      hhash->State = HAL_HASH_STATE_READY;
      /* Call digest computation complete callback */
      HAL_HASH_DgstCpltCallback(hhash);

      /* Process Unlocked */
      __HAL_UNLOCK(hhash);

      /* Return function status */
      return HAL_OK;
    }
  }
  if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
  {
    if(hhash->HashInCount >= 68U)
    {
      inputaddr = (uint32_t)hhash->pHashInBuffPtr;
      /* Write the Input block in the Data IN register */
      for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U)
      {
        HASH->DIN = *(uint32_t*)inputaddr;
        inputaddr+=4U;
      }
      if(hhash->HashITCounter == 0U)
      {
        HASH->DIN = *(uint32_t*)inputaddr;

        if(hhash->HashInCount >= 68U)
        {
          /* Decrement buffer counter */
          hhash->HashInCount -= 68U;
          hhash->pHashInBuffPtr+= 68U;
        }
        else
        {
          hhash->HashInCount = 0U;
          hhash->pHashInBuffPtr+= hhash->HashInCount;
        }
        /* Set Interrupt counter */
        hhash->HashITCounter = 1U;
      }
      else
      {
        /* Decrement buffer counter */
        hhash->HashInCount -= 64U;
        hhash->pHashInBuffPtr+= 64U;
      }
    }
    else
    {
      /* Get the buffer address */
      inputaddr = (uint32_t)hhash->pHashInBuffPtr;
      /* Get the buffer counter */
      inputcounter = hhash->HashInCount;
      /* Disable Interrupts */
      HASH->IMR &= ~(HASH_IT_DINI);
      /* Configure the number of valid bits in last word of the message */
      __HAL_HASH_SET_NBVALIDBITS(inputcounter);

      if((inputcounter > 4U) && (inputcounter%4U))
      {
        inputcounter = (inputcounter+4U-inputcounter%4U);
      }
      else if ((inputcounter < 4U) && (inputcounter != 0U))
      {
        inputcounter = 4U;
      }
      /* Write the Input block in the Data IN register */
      for(buffercounter = 0U; buffercounter < inputcounter/4U; buffercounter++)
      {
        HASH->DIN = *(uint32_t*)inputaddr;
        inputaddr+=4U;
      }
      /* Start the digest calculation */
      __HAL_HASH_START_DIGEST();
      /* Reset buffer counter */
      hhash->HashInCount = 0U;
      /* Call Input data transfer complete callback */
      HAL_HASH_InCpltCallback(hhash);
    }
  }

  /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in SHA256 mode then processes pInBuffer.
  *         The digest is available in pOutBuffer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 20 bytes.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer)
{
  uint32_t inputaddr;
  uint32_t buffercounter;
  uint32_t inputcounter;

  /* Process Locked */
  __HAL_LOCK(hhash);

  if(hhash->State == HAL_HASH_STATE_READY)
  {
    /* Change the HASH state */
    hhash->State = HAL_HASH_STATE_BUSY;

    hhash->HashInCount = Size;
    hhash->pHashInBuffPtr = pInBuffer;
    hhash->pHashOutBuffPtr = pOutBuffer;

    /* Check if initialization phase has already been performed */
    if(hhash->Phase == HAL_HASH_PHASE_READY)
    {
      /* Select the SHA256 mode */
      HASH->CR |= HASH_ALGOSELECTION_SHA256;
      /* Reset the HASH processor core, so that the HASH will be ready to compute
         the message digest of a new message */
      HASH->CR |= HASH_CR_INIT;
    }
    /* Reset interrupt counter */
    hhash->HashITCounter = 0U;

    /* Set the phase */
    hhash->Phase = HAL_HASH_PHASE_PROCESS;

    /* Process Unlocked */
    __HAL_UNLOCK(hhash);

    /* Enable Interrupts */
    HASH->IMR = (HASH_IT_DINI | HASH_IT_DCI);

    /* Return function status */
    return HAL_OK;
  }
  if(__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS))
  {
    /* Read the message digest */
    HASHEx_GetDigest(hhash->pHashOutBuffPtr, 32U);
    if(hhash->HashInCount == 0U)
    {
      /* Disable Interrupts */
      HASH->IMR = 0U;
      /* Change the HASH state */
      hhash->State = HAL_HASH_STATE_READY;
      /* Call digest computation complete callback */
      HAL_HASH_DgstCpltCallback(hhash);

      /* Process Unlocked */
      __HAL_UNLOCK(hhash);

      /* Return function status */
      return HAL_OK;
    }
  }
  if(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))
  {
    if(hhash->HashInCount >= 68U)
    {
      inputaddr = (uint32_t)hhash->pHashInBuffPtr;
      /* Write the Input block in the Data IN register */
      for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U)
      {
        HASH->DIN = *(uint32_t*)inputaddr;
        inputaddr+=4U;
      }
      if(hhash->HashITCounter == 0U)
      {
        HASH->DIN = *(uint32_t*)inputaddr;

        if(hhash->HashInCount >= 68U)
        {
          /* Decrement buffer counter */
          hhash->HashInCount -= 68U;
          hhash->pHashInBuffPtr+= 68U;
        }
        else
        {
          hhash->HashInCount = 0U;
          hhash->pHashInBuffPtr+= hhash->HashInCount;
        }
        /* Set Interrupt counter */
        hhash->HashITCounter = 1U;
      }
      else
      {
        /* Decrement buffer counter */
        hhash->HashInCount -= 64U;
        hhash->pHashInBuffPtr+= 64U;
      }
    }
    else
    {
      /* Get the buffer address */
      inputaddr = (uint32_t)hhash->pHashInBuffPtr;
      /* Get the buffer counter */
      inputcounter = hhash->HashInCount;
      /* Disable Interrupts */
      HASH->IMR &= ~(HASH_IT_DINI);
      /* Configure the number of valid bits in last word of the message */
      __HAL_HASH_SET_NBVALIDBITS(inputcounter);

      if((inputcounter > 4U) && (inputcounter%4U))
      {
        inputcounter = (inputcounter+4U-inputcounter%4U);
      }
      else if ((inputcounter < 4U) && (inputcounter != 0U))
      {
        inputcounter = 4U;
      }
      /* Write the Input block in the Data IN register */
      for(buffercounter = 0U; buffercounter < inputcounter/4U; buffercounter++)
      {
        HASH->DIN = *(uint32_t*)inputaddr;
        inputaddr+=4U;
      }
      /* Start the digest calculation */
      __HAL_HASH_START_DIGEST();
      /* Reset buffer counter */
      hhash->HashInCount = 0U;
      /* Call Input data transfer complete callback */
      HAL_HASH_InCpltCallback(hhash);
    }
  }

  /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief This function handles HASH interrupt request.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @retval None
  */
void HAL_HASHEx_IRQHandler(HASH_HandleTypeDef *hhash)
{
  switch(HASH->CR & HASH_CR_ALGO)
  {

    case HASH_ALGOSELECTION_SHA224:
       HAL_HASHEx_SHA224_Start_IT(hhash, NULL, 0U, NULL);
    break;

    case HASH_ALGOSELECTION_SHA256:
      HAL_HASHEx_SHA256_Start_IT(hhash, NULL, 0U, NULL);
    break;

    default:
    break;
  }
}

/**
  * @}
  */

/** @defgroup HASHEx_Group4 HASH processing functions using DMA mode
 *  @brief   processing functions using DMA mode.
 *
@verbatim
 ===============================================================================
                ##### HASH processing using DMA functions #####
 ===============================================================================
    [..]  This section provides functions allowing to calculate in DMA mode
          the hash value using one of the following algorithms:
      (+) SHA224
      (+) SHA256

@endverbatim
  * @{
  */

/**
  * @brief  Initializes the HASH peripheral in SHA224 mode then enables DMA to
            control data transfer. Use HAL_HASH_SHA224_Finish() to get the digest.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
{
  uint32_t inputaddr  = (uint32_t)pInBuffer;

   /* Process Locked */
  __HAL_LOCK(hhash);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;

  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Select the SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
       the message digest of a new message */
    HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
  }

  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);

  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;

  /* Set the HASH DMA transfer complete callback */
  hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
  /* Set the DMA error callback */
  hhash->hdmain->XferErrorCallback = HASHEx_DMAError;

  /* Enable the DMA In DMA Stream */
  HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4U ? (Size+3U)/4U:Size/4U));

  /* Enable DMA requests */
  HASH->CR |= (HASH_CR_DMAE);

   /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Returns the computed digest in SHA224
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 28 bytes.
  * @param  Timeout: Timeout value
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASHEx_SHA224_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
{
  uint32_t tickstart = 0U;

  /* Process Locked */
  __HAL_LOCK(hhash);

  /* Change HASH peripheral state */
  hhash->State = HAL_HASH_STATE_BUSY;

  /* Get tick */
  tickstart = HAL_GetTick();

  while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;

        /* Process Unlocked */
        __HAL_UNLOCK(hhash);

        return HAL_TIMEOUT;
      }
    }
  }

  /* Read the message digest */
  HASHEx_GetDigest(pOutBuffer, 28U);

  /* Change HASH peripheral state */
  hhash->State = HAL_HASH_STATE_READY;

   /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in SHA256 mode then enables DMA to
            control data transfer. Use HAL_HASH_SHA256_Finish() to get the digest.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
{
  uint32_t inputaddr  = (uint32_t)pInBuffer;

   /* Process Locked */
  __HAL_LOCK(hhash);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;

  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Select the SHA256 mode and reset the HASH processor core, so that the HASH will be ready to compute
       the message digest of a new message */
    HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
  }

  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(Size);

  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;

  /* Set the HASH DMA transfer complete callback */
  hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
  /* Set the DMA error callback */
  hhash->hdmain->XferErrorCallback = HASHEx_DMAError;

  /* Enable the DMA In DMA Stream */
  HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (Size%4U ? (Size+3U)/4U:Size/4U));

  /* Enable DMA requests */
  HASH->CR |= (HASH_CR_DMAE);

   /* Process UnLock */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Returns the computed digest in SHA256.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pOutBuffer: Pointer to the computed digest. Its size must be 32 bytes.
  * @param  Timeout: Timeout value
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HASHEx_SHA256_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout)
{
  uint32_t tickstart = 0U;

   /* Process Locked */
  __HAL_LOCK(hhash);

  /* Change HASH peripheral state */
  hhash->State = HAL_HASH_STATE_BUSY;

  /* Get tick */
  tickstart = HAL_GetTick();

  while(HAL_IS_BIT_CLR(HASH->SR, HASH_FLAG_DCIS))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        /* Change state */
        hhash->State = HAL_HASH_STATE_TIMEOUT;

        /* Process Unlocked */
        __HAL_UNLOCK(hhash);

        return HAL_TIMEOUT;
      }
    }
  }

  /* Read the message digest */
  HASHEx_GetDigest(pOutBuffer, 32U);

  /* Change HASH peripheral state */
  hhash->State = HAL_HASH_STATE_READY;

   /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @}
  */
/** @defgroup HASHEx_Group5 HMAC processing functions using DMA mode
 *  @brief   HMAC processing functions using DMA mode .
 *
@verbatim
 ===============================================================================
                ##### HMAC processing using DMA functions #####
 ===============================================================================
    [..]  This section provides functions allowing to calculate in DMA mode
          the HMAC value using one of the following algorithms:
      (+) SHA224
      (+) SHA256

@endverbatim
  * @{
  */

/**
  * @brief  Initializes the HASH peripheral in HMAC SHA224 mode
  *         then enables DMA to control data transfer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HMACEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
{
  uint32_t inputaddr;

  /* Process Locked */
  __HAL_LOCK(hhash);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;

  /* Save buffer pointer and size in handle */
  hhash->pHashInBuffPtr = pInBuffer;
  hhash->HashBuffSize = Size;
  hhash->HashInCount = 0U;

  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Check if key size is greater than 64 bytes */
    if(hhash->Init.KeySize > 64U)
    {
      /* Select the HMAC SHA224 mode */
      HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT);
    }
    else
    {
      /* Select the HMAC SHA224 mode */
      HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_CR_INIT);
    }
  }

  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;

  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);

  /* Get the key address */
  inputaddr = (uint32_t)(hhash->Init.pKey);

  /* Set the HASH DMA transfer complete callback */
  hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
  /* Set the DMA error callback */
  hhash->hdmain->XferErrorCallback = HASHEx_DMAError;

  /* Enable the DMA In DMA Stream */
  HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4U ? (hhash->Init.KeySize+3U)/4U:hhash->Init.KeySize/4U));
  /* Enable DMA requests */
  HASH->CR |= (HASH_CR_DMAE);

  /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initializes the HASH peripheral in HMAC SHA256 mode
  *         then enables DMA to control data transfer.
  * @param  hhash: pointer to a HASH_HandleTypeDef structure that contains
  *         the configuration information for HASH module
  * @param  pInBuffer: Pointer to the input buffer (buffer to be hashed).
  * @param  Size: Length of the input buffer in bytes.
  *          If the Size is not multiple of 64 bytes, the padding is managed by hardware.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HMACEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size)
{
  uint32_t inputaddr;

  /* Process Locked */
  __HAL_LOCK(hhash);

  /* Change the HASH state */
  hhash->State = HAL_HASH_STATE_BUSY;

  /* Save buffer pointer and size in handle */
  hhash->pHashInBuffPtr = pInBuffer;
  hhash->HashBuffSize = Size;
  hhash->HashInCount = 0U;

  /* Check if initialization phase has already been performed */
  if(hhash->Phase == HAL_HASH_PHASE_READY)
  {
    /* Check if key size is greater than 64 bytes */
    if(hhash->Init.KeySize > 64U)
    {
      /* Select the HMAC SHA256 mode */
      HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY);
    }
    else
    {
      /* Select the HMAC SHA256 mode */
      HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC);
    }
    /* Reset the HASH processor core, so that the HASH will be ready to compute
       the message digest of a new message */
    HASH->CR |= HASH_CR_INIT;
  }

  /* Set the phase */
  hhash->Phase = HAL_HASH_PHASE_PROCESS;

  /* Configure the number of valid bits in last word of the message */
  __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize);

  /* Get the key address */
  inputaddr = (uint32_t)(hhash->Init.pKey);

  /* Set the HASH DMA transfer complete callback */
  hhash->hdmain->XferCpltCallback = HASHEx_DMAXferCplt;
  /* Set the DMA error callback */
  hhash->hdmain->XferErrorCallback = HASHEx_DMAError;

  /* Enable the DMA In DMA Stream */
  HAL_DMA_Start_IT(hhash->hdmain, inputaddr, (uint32_t)&HASH->DIN, (hhash->Init.KeySize%4U ? (hhash->Init.KeySize+3U)/4U:hhash->Init.KeySize/4U));
  /* Enable DMA requests */
  HASH->CR |= (HASH_CR_DMAE);

  /* Process Unlocked */
  __HAL_UNLOCK(hhash);

  /* Return function status */
  return HAL_OK;
}

/**
  * @}
  */

/**
  * @}
  */
#endif /* STM32F437xx || STM32F439xx || STM32F479xx */

#endif /* HAL_HASH_MODULE_ENABLED */
/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

redpajama_set_name: RedPajamaGithub


text:
package com.comps.model;

public class EquilibrioRetaguarda extends AbstractModel{

	private float result;

	public EquilibrioRetaguarda() {
		setTipo(AbstractModel.EQUILIBRIO_RETAGUARDA);
	}

	public EquilibrioRetaguarda(int result){
		setTipo(AbstractModel.EQUILIBRIO_RETAGUARDA);
		this.result = result;

	}

	public float getResult() {return result;}

	public void setResult(float result) {this.result = result;}

}