Initial snapshot: Aliro applet, harness, Nucleo NFC10A1 reader port
Three components, all bench-validated to varying depths: - applet/: CSA Aliro v1.0 Java Card applet for J3R180. AUTH0 + AUTH1 expedited-standard flow end-to-end green via PC/SC bench reader (aliro-bench-test). Userland AES-256-GCM and HMAC-SHA-256 layered on top of J3R180's primitives because the card lacks both natively. P-256 curve params seeded explicitly per J3R180's quirk. - harness/: Python orchestrator (aliro-trustgen, aliro-personalize, aliro-bench-test) for trust-bundle generation, card personalization via PersonalizationApplet, and PC/SC AUTH0+AUTH1 transactions. 126 pytest cases passing. - reader/STM32CubeExpansion_ALIRO_V1_0_0/: ST X-CUBE-ALIRO V1.0.0 with our NFC10A1 port (NUCLEO-U545RE-Q + X-NUCLEO-NFC10A1, ST25R200 shared with NFC09A1). nfc10-only/ project, NFC10A1 BSP shim, ALIRO_TRUST_OVERRIDE include into vendor's provisioning.c, and an ALIRO_APDU_TRACE wrapper around demoTransceiveBlocking. Boots, detects the J3R180, completes SELECT + AUTH0; AUTH1 currently fails with RFAL ERR_PROTO (0xB) — under investigation, see docs/plans/2026-04-20-nucleo-nfc10a1-port.md and bench-notes/. Excluded: x-cube-aliro.zip vendor archive, harness/.venv, build dirs, generated aliro_trust.h (contains private reader scalar), all PEMs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(Aliro LANGUAGES C)
|
||||
|
||||
# Collect all source files in Src
|
||||
file(GLOB ALIRO_SRC "Src/*.c")
|
||||
|
||||
# Path to the precompiled library
|
||||
set(ALIRO_LIB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Lib/aliro.a")
|
||||
|
||||
# Create a static library from the source files
|
||||
add_library(aliro_src STATIC ${ALIRO_SRC})
|
||||
|
||||
# Create an interface target for the precompiled library
|
||||
add_library(aliro_prebuilt STATIC IMPORTED GLOBAL)
|
||||
set_target_properties(aliro_prebuilt PROPERTIES
|
||||
IMPORTED_LOCATION "${ALIRO_LIB_PATH}"
|
||||
)
|
||||
|
||||
# Create an interface target that combines both
|
||||
add_library(aliro INTERFACE)
|
||||
target_link_libraries(aliro INTERFACE aliro_prebuilt aliro_src)
|
||||
target_include_directories(aliro INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/Inc)
|
||||
|
||||
# Usage:
|
||||
# target_link_libraries(your_target PRIVATE aliro)
|
||||
|
||||
# Example
|
||||
# # Add the Aliro library directory
|
||||
# add_subdirectory(path/to/Aliro)
|
||||
|
||||
# # Link to the Aliro interface target
|
||||
# target_link_libraries(my_app PRIVATE aliro)
|
||||
@@ -0,0 +1,307 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : ST_provisioning.h
|
||||
* @brief : This file provides the provisioning profiles for User.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup USER_PROVISIONING
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Reader ID and Sub ID for User provisioning without certificate.
|
||||
* @details
|
||||
* Reader ID and Sub ID used for User provisioning without certificate.
|
||||
*/
|
||||
/* Provisioning without Certificate*/
|
||||
// reader_id_User:8f9633dd856d2a156f2aee573deb11e5
|
||||
// reader_sub_id_User:43815ef53299c92e95b052138133ed39
|
||||
#define READER_ID_2 {0x8f, 0x96, 0x33, 0xdd, 0x85, 0x6d, 0x2a, 0x15, 0x6f, 0x2a, 0xee, 0x57, 0x3d, 0xeb, 0x11, 0xe5, 0x43, 0x81, 0x5e, 0xf5, 0x32, 0x99, 0xc9, 0x2e, 0x95, 0xb0, 0x52, 0x13, 0x81, 0x33, 0xed, 0x39}
|
||||
|
||||
/**
|
||||
* @brief Reader public key for User provisioning without certificate.
|
||||
* @details
|
||||
* Reader public key for User provisioning without certificate.
|
||||
*/
|
||||
// reader_public_key_User:045bc20b2853e11fcb086192d8a5d5b7829b13d143b0da2de68e1bc94f8b016027a8854eae0226d4205e8f710d168da2f57d3fa2150b64338d212ce015e200513f
|
||||
#define READER_PUB_KEY_2 {0x5b, 0xc2, 0x0b, 0x28, 0x53, 0xe1, 0x1f, 0xcb, 0x08, 0x61, 0x92, 0xd8, 0xa5, 0xd5, 0xb7, 0x82, 0x9b, 0x13, 0xd1, 0x43, 0xb0, 0xda, 0x2d, 0xe6, 0x8e, 0x1b, 0xc9, 0x4f, 0x8b, 0x01, 0x60, 0x27, 0xa8, 0x85, 0x4e, 0xae, 0x02, 0x26, 0xd4, 0x20, 0x5e, 0x8f, 0x71, 0x0d, 0x16, 0x8d, 0xa2, 0xf5, 0x7d, 0x3f, 0xa2, 0x15, 0x0b, 0x64, 0x33, 0x8d, 0x21, 0x2c, 0xe0, 0x15, 0xe2, 0x00, 0x51, 0x3f}
|
||||
|
||||
/**
|
||||
* @brief Reader private key for User provisioning without certificate.
|
||||
* @details
|
||||
* Reader private key for User provisioning without certificate.
|
||||
*/
|
||||
// reader_private_key_User:cb64a58a5fae052d458b3bce2599a20a665987b537b157cc3cc42e1d9c652409
|
||||
#define READER_PRIVATE_KEY_2 {0xcb, 0x64, 0xa5, 0x8a, 0x5f, 0xae, 0x05, 0x2d, 0x45, 0x8b, 0x3b, 0xce, 0x25, 0x99, 0xa2, 0x0a, 0x66, 0x59, 0x87, 0xb5, 0x37, 0xb1, 0x57, 0xcc, 0x3c, 0xc4, 0x2e, 0x1d, 0x9c, 0x65, 0x24, 0x09}
|
||||
|
||||
/**
|
||||
* @brief Reader issuer public key for User provisioning without certificate.
|
||||
* @details
|
||||
* Not used for User provisioning without certificate.
|
||||
*/
|
||||
#define READER_ISSUER_PUB_KEY_2 { 0 }
|
||||
|
||||
/**
|
||||
* @brief Reader issuer private key for User provisioning without certificate.
|
||||
* @details
|
||||
* Not used for User provisioning without certificate.
|
||||
*/
|
||||
#define READER_ISSUER_PRIVATE_KEY_2 { 0 }
|
||||
|
||||
/**
|
||||
* @brief Reader certificate for User provisioning without certificate.
|
||||
* @details
|
||||
* Not used for User provisioning without certificate.
|
||||
*/
|
||||
#define READER_CERTIFICATE_2 { 0 }
|
||||
|
||||
/**
|
||||
* @brief Group resolving key for User provisioning without certificate.
|
||||
* @details
|
||||
* Group resolving key used for User provisioning without certificate.
|
||||
*/
|
||||
#define GROUP_RESOLVING_KEY_2 GROUP_RESOLVING_KEY
|
||||
|
||||
/**
|
||||
* @brief Endpoint key slot for User provisioning without certificate.
|
||||
* @details
|
||||
* Key slot identifier for endpoint.
|
||||
*/
|
||||
#define ENDPOINT_KEYSLOT_2 ENDPOINT_KEYSLOT
|
||||
|
||||
/**
|
||||
* @brief Endpoint public key for User provisioning without certificate.
|
||||
* @details
|
||||
* Endpoint public key for endpoint.
|
||||
*/
|
||||
#define ENDPOINT_PUBLIC_KEY_2 ENDPOINT_PUBLIC_KEY
|
||||
|
||||
/**
|
||||
* @brief Endpoint private key for User provisioning without certificate.
|
||||
* @details
|
||||
* Endpoint private key for endpoint.
|
||||
*/
|
||||
#define ENDPOINT_PRIVATE_KEY_2 ENDPOINT_PRIVATE_KEY
|
||||
|
||||
/**
|
||||
* @brief Endpoint name for User provisioning without certificate.
|
||||
* @details
|
||||
* Endpoint name for endpoint.
|
||||
*/
|
||||
#define ENDPOINT_NAME_2 "User"
|
||||
|
||||
/**
|
||||
* @brief Vendor specific extension for User provisioning without certificate.
|
||||
* @details
|
||||
* Vendor specific extension for endpoint.
|
||||
*/
|
||||
#define B1_VENDOR_SPECIFIC_EXTENSION_2 B1_VENDOR_SPECIFIC_EXTENSION
|
||||
|
||||
/**
|
||||
* @brief Length of vendor specific extension for User provisioning without certificate.
|
||||
* @details
|
||||
* Length of vendor specific extension for endpoint.
|
||||
*/
|
||||
#define B1_VENDOR_SPECIFIC_EXTENSION_LEN_2 B1_VENDOR_SPECIFIC_EXTENSION_LEN
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reader ID and Sub ID for User provisioning with certificate.
|
||||
* @details
|
||||
* Reader ID and Sub ID used for User provisioning with certificate.
|
||||
*/
|
||||
/* Provisioning with Certificate*/
|
||||
// reader_id_cert_User:9f9633dd856d2a156f2aee573deb11e5
|
||||
// reader_sub_id_cert_User:43815ef53299c92e95b052138133ed39
|
||||
#define READER_ID {0x9f, 0x96, 0x33, 0xdd, 0x85, 0x6d, 0x2a, 0x15, 0x6f, 0x2a, 0xee, 0x57, 0x3d, 0xeb, 0x11, 0xe5, 0x43, 0x81, 0x5e, 0xf5, 0x32, 0x99, 0xc9, 0x2e, 0x95, 0xb0, 0x52, 0x13, 0x81, 0x33, 0xed, 0x39}
|
||||
|
||||
/**
|
||||
* @brief Reader public key for User provisioning with certificate.
|
||||
* @details
|
||||
* Reader public key for User provisioning with certificate.
|
||||
*/
|
||||
// reader_public_key_cert_User:045bc20b2853e11fcb086192d8a5d5b7829b13d143b0da2de68e1bc94f8b016027a8854eae0226d4205e8f710d168da2f57d3fa2150b64338d212ce015e200513f
|
||||
#define READER_PUB_KEY {0x5b, 0xc2, 0x0b, 0x28, 0x53, 0xe1, 0x1f, 0xcb, 0x08, 0x61, 0x92, 0xd8, 0xa5, 0xd5, 0xb7, 0x82, 0x9b, 0x13, 0xd1, 0x43, 0xb0, 0xda, 0x2d, 0xe6, 0x8e, 0x1b, 0xc9, 0x4f, 0x8b, 0x01, 0x60, 0x27, 0xa8, 0x85, 0x4e, 0xae, 0x02, 0x26, 0xd4, 0x20, 0x5e, 0x8f, 0x71, 0x0d, 0x16, 0x8d, 0xa2, 0xf5, 0x7d, 0x3f, 0xa2, 0x15, 0x0b, 0x64, 0x33, 0x8d, 0x21, 0x2c, 0xe0, 0x15, 0xe2, 0x00, 0x51, 0x3f}
|
||||
|
||||
/**
|
||||
* @brief Reader private key for User provisioning with certificate.
|
||||
* @details
|
||||
* Reader private key for User provisioning with certificate.
|
||||
*/
|
||||
// reader_private_key_cert_User:cb64a58a5fae052d458b3bce2599a20a665987b537b157cc3cc42e1d9c652409
|
||||
#define READER_PRIVATE_KEY {0xcb, 0x64, 0xa5, 0x8a, 0x5f, 0xae, 0x05, 0x2d, 0x45, 0x8b, 0x3b, 0xce, 0x25, 0x99, 0xa2, 0x0a, 0x66, 0x59, 0x87, 0xb5, 0x37, 0xb1, 0x57, 0xcc, 0x3c, 0xc4, 0x2e, 0x1d, 0x9c, 0x65, 0x24, 0x09}
|
||||
|
||||
/**
|
||||
* @brief Reader issuer public key for User provisioning with certificate.
|
||||
* @details
|
||||
* Reader issuer public key for User provisioning with certificate.
|
||||
*/
|
||||
// reader_issuer_public_key_cert_User:04fbc3fdac291606a0a986862004bbe5c6188ce64098f4a65b7a6595fc31f416259141a972b916e6321dbeee22b77eec5929d80779c99f8ebe5c2588f24b24de68
|
||||
#define READER_ISSUER_PUB_KEY {0xfb, 0xc3, 0xfd, 0xac, 0x29, 0x16, 0x06, 0xa0, 0xa9, 0x86, 0x86, 0x20, 0x04, 0xbb, 0xe5, 0xc6, 0x18, 0x8c, 0xe6, 0x40, 0x98, 0xf4, 0xa6, 0x5b, 0x7a, 0x65, 0x95, 0xfc, 0x31, 0xf4, 0x16, 0x25, 0x91, 0x41, 0xa9, 0x72, 0xb9, 0x16, 0xe6, 0x32, 0x1d, 0xbe, 0xee, 0x22, 0xb7, 0x7e, 0xec, 0x59, 0x29, 0xd8, 0x07, 0x79, 0xc9, 0x9f, 0x8e, 0xbe, 0x5c, 0x25, 0x88, 0xf2, 0x4b, 0x24, 0xde, 0x68}
|
||||
|
||||
/**
|
||||
* @brief Reader issuer private key for User provisioning with certificate.
|
||||
* @details
|
||||
* Reader issuer private key for User provisioning with certificate.
|
||||
*/
|
||||
// reader_issuer_private_key_cert_User:31222ec2125a2921671e471ae67b8796668e37c0167c72bf540e4c5393599f85
|
||||
#define READER_ISSUER_PRIVATE_KEY {0x31, 0x22, 0x2e, 0xc2, 0x12, 0x5a, 0x29, 0x21, 0x67, 0x1e, 0x47, 0x1a, 0xe6, 0x7b, 0x87, 0x96, 0x66, 0x8e, 0x37, 0xc0, 0x16, 0x7c, 0x72, 0xbf, 0x54, 0x0e, 0x4c, 0x53, 0x93, 0x59, 0x9f, 0x85}
|
||||
|
||||
/**
|
||||
* @brief Reader certificate for User provisioning with certificate.
|
||||
* @details
|
||||
* Reader certificate for User provisioning with certificate.
|
||||
*/
|
||||
// reader_certificate_cert_User:3081e8040200003081e18014269e0680731d796703576be42b668a7dfe9c1e29811253544d6963726f656c656374726f6e696373820d3235313231363135343034395a830d3330313231363135343034395a840844656d6f6c6f636b854200045bc20b2853e11fcb086192d8a5d5b7829b13d143b0da2de68e1bc94f8b016027a8854eae0226d4205e8f710d168da2f57d3fa2150b64338d212ce015e200513f8649003046022100f1e0b84ad64aa078a039cc1be850a9d1534d52a26d6a5e137e0a710f59f12b49022100d089e452ee102cb5813eaded8625cc4b54b69835ec2e4c59c12e2a4a495dddaf
|
||||
#define READER_CERTIFICATE {0x30, 0x81, 0xe8, 0x04, 0x02, 0x00, 0x00, 0x30, 0x81, 0xe1, 0x80, 0x14, 0x26, 0x9e, 0x06, 0x80, 0x73, 0x1d, 0x79, 0x67, 0x03, 0x57, 0x6b, 0xe4, 0x2b, 0x66, 0x8a, 0x7d, 0xfe, 0x9c, 0x1e, 0x29, 0x81, 0x12, 0x53, 0x54, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x73, 0x82, 0x0d, 0x32, 0x35, 0x31, 0x32, 0x31, 0x36, 0x31, 0x35, 0x34, 0x30, 0x34, 0x39, 0x5a, 0x83, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x31, 0x36, 0x31, 0x35, 0x34, 0x30, 0x34, 0x39, 0x5a, 0x84, 0x08, 0x44, 0x65, 0x6d, 0x6f, 0x6c, 0x6f, 0x63, 0x6b, 0x85, 0x42, 0x00, 0x04, 0x5b, 0xc2, 0x0b, 0x28, 0x53, 0xe1, 0x1f, 0xcb, 0x08, 0x61, 0x92, 0xd8, 0xa5, 0xd5, 0xb7, 0x82, 0x9b, 0x13, 0xd1, 0x43, 0xb0, 0xda, 0x2d, 0xe6, 0x8e, 0x1b, 0xc9, 0x4f, 0x8b, 0x01, 0x60, 0x27, 0xa8, 0x85, 0x4e, 0xae, 0x02, 0x26, 0xd4, 0x20, 0x5e, 0x8f, 0x71, 0x0d, 0x16, 0x8d, 0xa2, 0xf5, 0x7d, 0x3f, 0xa2, 0x15, 0x0b, 0x64, 0x33, 0x8d, 0x21, 0x2c, 0xe0, 0x15, 0xe2, 0x00, 0x51, 0x3f, 0x86, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xf1, 0xe0, 0xb8, 0x4a, 0xd6, 0x4a, 0xa0, 0x78, 0xa0, 0x39, 0xcc, 0x1b, 0xe8, 0x50, 0xa9, 0xd1, 0x53, 0x4d, 0x52, 0xa2, 0x6d, 0x6a, 0x5e, 0x13, 0x7e, 0x0a, 0x71, 0x0f, 0x59, 0xf1, 0x2b, 0x49, 0x02, 0x21, 0x00, 0xd0, 0x89, 0xe4, 0x52, 0xee, 0x10, 0x2c, 0xb5, 0x81, 0x3e, 0xad, 0xed, 0x86, 0x25, 0xcc, 0x4b, 0x54, 0xb6, 0x98, 0x35, 0xec, 0x2e, 0x4c, 0x59, 0xc1, 0x2e, 0x2a, 0x4a, 0x49, 0x5d, 0xdd, 0xaf}
|
||||
|
||||
/**
|
||||
* @brief Reader long certificate for User provisioning with certificate.
|
||||
* @details
|
||||
* Reader long certificate for User provisioning with certificate.
|
||||
*/
|
||||
// reader_certificate_cert_long_User:3082010b0402000030820103801412c2a20661964981c92cd242e6d06d2ce8053b4f811f53544d6963726f656c656374726f6e69637353544d6963726f656c65637472820d3235313231363135343034395a830d3330313231363135343034395a841f44656d6f6c6f636b44656d6f6c6f636b44656d6f6c6f636b44656d6f6c6f63854200045bc20b2853e11fcb086192d8a5d5b7829b13d143b0da2de68e1bc94f8b016027a8854eae0226d4205e8f710d168da2f57d3fa2150b64338d212ce015e200513f864700304402206aef6a6cf112f97c16c1e844f65ef3913cbe388b4e9ee8795fbc08f240f5337702205da03ad102a63e1095da5692a463db8d18866b07e5580f6ef0f28c5153ac3400
|
||||
#define READER_LONG_CERTIFICATE {0x30, 0x82, 0x01, 0x0b, 0x04, 0x02, 0x00, 0x00, 0x30, 0x82, 0x01, 0x03, 0x80, 0x14, 0x12, 0xc2, 0xa2, 0x06, 0x61, 0x96, 0x49, 0x81, 0xc9, 0x2c, 0xd2, 0x42, 0xe6, 0xd0, 0x6d, 0x2c, 0xe8, 0x05, 0x3b, 0x4f, 0x81, 0x1f, 0x53, 0x54, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x73, 0x53, 0x54, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x82, 0x0d, 0x32, 0x35, 0x31, 0x32, 0x31, 0x36, 0x31, 0x35, 0x34, 0x30, 0x34, 0x39, 0x5a, 0x83, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x31, 0x36, 0x31, 0x35, 0x34, 0x30, 0x34, 0x39, 0x5a, 0x84, 0x1f, 0x44, 0x65, 0x6d, 0x6f, 0x6c, 0x6f, 0x63, 0x6b, 0x44, 0x65, 0x6d, 0x6f, 0x6c, 0x6f, 0x63, 0x6b, 0x44, 0x65, 0x6d, 0x6f, 0x6c, 0x6f, 0x63, 0x6b, 0x44, 0x65, 0x6d, 0x6f, 0x6c, 0x6f, 0x63, 0x85, 0x42, 0x00, 0x04, 0x5b, 0xc2, 0x0b, 0x28, 0x53, 0xe1, 0x1f, 0xcb, 0x08, 0x61, 0x92, 0xd8, 0xa5, 0xd5, 0xb7, 0x82, 0x9b, 0x13, 0xd1, 0x43, 0xb0, 0xda, 0x2d, 0xe6, 0x8e, 0x1b, 0xc9, 0x4f, 0x8b, 0x01, 0x60, 0x27, 0xa8, 0x85, 0x4e, 0xae, 0x02, 0x26, 0xd4, 0x20, 0x5e, 0x8f, 0x71, 0x0d, 0x16, 0x8d, 0xa2, 0xf5, 0x7d, 0x3f, 0xa2, 0x15, 0x0b, 0x64, 0x33, 0x8d, 0x21, 0x2c, 0xe0, 0x15, 0xe2, 0x00, 0x51, 0x3f, 0x86, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x6a, 0xef, 0x6a, 0x6c, 0xf1, 0x12, 0xf9, 0x7c, 0x16, 0xc1, 0xe8, 0x44, 0xf6, 0x5e, 0xf3, 0x91, 0x3c, 0xbe, 0x38, 0x8b, 0x4e, 0x9e, 0xe8, 0x79, 0x5f, 0xbc, 0x08, 0xf2, 0x40, 0xf5, 0x33, 0x77, 0x02, 0x20, 0x5d, 0xa0, 0x3a, 0xd1, 0x02, 0xa6, 0x3e, 0x10, 0x95, 0xda, 0x56, 0x92, 0xa4, 0x63, 0xdb, 0x8d, 0x18, 0x86, 0x6b, 0x07, 0xe5, 0x58, 0x0f, 0x6e, 0xf0, 0xf2, 0x8c, 0x51, 0x53, 0xac, 0x34, 0x00}
|
||||
|
||||
/**
|
||||
* @brief Reader short certificate for User provisioning with certificate.
|
||||
* @details
|
||||
* Reader short certificate for User provisioning with certificate.
|
||||
*/
|
||||
// reader_certificate_cert_short_User:3081940402000030818d854200045bc20b2853e11fcb086192d8a5d5b7829b13d143b0da2de68e1bc94f8b016027a8854eae0226d4205e8f710d168da2f57d3fa2150b64338d212ce015e200513f8647003044022004060b7ec96115558aaa21686b8a5cd76c3cf0ef0214ef3d93189b789624c48f022031664dc32677ff6eba89126ebd212f903dc0dc8a4c837ebb306e062ba2231be2
|
||||
#define READER_SHORT_CERTIFICATE {0x30, 0x81, 0x94, 0x04, 0x02, 0x00, 0x00, 0x30, 0x81, 0x8d, 0x85, 0x42, 0x00, 0x04, 0x5b, 0xc2, 0x0b, 0x28, 0x53, 0xe1, 0x1f, 0xcb, 0x08, 0x61, 0x92, 0xd8, 0xa5, 0xd5, 0xb7, 0x82, 0x9b, 0x13, 0xd1, 0x43, 0xb0, 0xda, 0x2d, 0xe6, 0x8e, 0x1b, 0xc9, 0x4f, 0x8b, 0x01, 0x60, 0x27, 0xa8, 0x85, 0x4e, 0xae, 0x02, 0x26, 0xd4, 0x20, 0x5e, 0x8f, 0x71, 0x0d, 0x16, 0x8d, 0xa2, 0xf5, 0x7d, 0x3f, 0xa2, 0x15, 0x0b, 0x64, 0x33, 0x8d, 0x21, 0x2c, 0xe0, 0x15, 0xe2, 0x00, 0x51, 0x3f, 0x86, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x04, 0x06, 0x0b, 0x7e, 0xc9, 0x61, 0x15, 0x55, 0x8a, 0xaa, 0x21, 0x68, 0x6b, 0x8a, 0x5c, 0xd7, 0x6c, 0x3c, 0xf0, 0xef, 0x02, 0x14, 0xef, 0x3d, 0x93, 0x18, 0x9b, 0x78, 0x96, 0x24, 0xc4, 0x8f, 0x02, 0x20, 0x31, 0x66, 0x4d, 0xc3, 0x26, 0x77, 0xff, 0x6e, 0xba, 0x89, 0x12, 0x6e, 0xbd, 0x21, 0x2f, 0x90, 0x3d, 0xc0, 0xdc, 0x8a, 0x4c, 0x83, 0x7e, 0xbb, 0x30, 0x6e, 0x06, 0x2b, 0xa2, 0x23, 0x1b, 0xe2}
|
||||
|
||||
/**
|
||||
* @brief Group resolving key for User provisioning with certificate.
|
||||
* @details
|
||||
* Group resolving key used for User provisioning with certificate.
|
||||
*/
|
||||
// group_resolving_key_User:0375ed63685570f6b2168eab7296ec01
|
||||
#define GROUP_RESOLVING_KEY {0x03, 0x75, 0xed, 0x63, 0x68, 0x55, 0x70, 0xf6, 0xb2, 0x16, 0x8e, 0xab, 0x72, 0x96, 0xec, 0x01}
|
||||
|
||||
/**
|
||||
* @brief Endpoint key slot for User provisioning with certificate.
|
||||
* @details
|
||||
* Key slot identifier for endpoint.
|
||||
*/
|
||||
// endpoint_key_slot_cert_Alice_User:54b54e27d515ac4c
|
||||
#define ENDPOINT_KEYSLOT {0x54, 0xb5, 0x4e, 0x27, 0xd5, 0x15, 0xac, 0x4c}
|
||||
|
||||
/**
|
||||
* @brief Endpoint public key for User provisioning with certificate.
|
||||
* @details
|
||||
* Endpoint public key for endpoint.
|
||||
*/
|
||||
// endpoint_public_key_cert_Alice_User:04773f9aa84ac9705161c490a2dba0b4a19a3d2a78705a801cff924e26357e4213191db83789a25916e4accea1fd6f09239b4cf2dd0d05b33b72d8a3a642e30866
|
||||
#define ENDPOINT_PUBLIC_KEY {0x77, 0x3f, 0x9a, 0xa8, 0x4a, 0xc9, 0x70, 0x51, 0x61, 0xc4, 0x90, 0xa2, 0xdb, 0xa0, 0xb4, 0xa1, 0x9a, 0x3d, 0x2a, 0x78, 0x70, 0x5a, 0x80, 0x1c, 0xff, 0x92, 0x4e, 0x26, 0x35, 0x7e, 0x42, 0x13, 0x19, 0x1d, 0xb8, 0x37, 0x89, 0xa2, 0x59, 0x16, 0xe4, 0xac, 0xce, 0xa1, 0xfd, 0x6f, 0x09, 0x23, 0x9b, 0x4c, 0xf2, 0xdd, 0x0d, 0x05, 0xb3, 0x3b, 0x72, 0xd8, 0xa3, 0xa6, 0x42, 0xe3, 0x08, 0x66}
|
||||
|
||||
/**
|
||||
* @brief Endpoint private key for User provisioning with certificate.
|
||||
* @details
|
||||
* Endpoint private key for endpoint.
|
||||
*/
|
||||
// endpoint_private_key_cert_Alice_User:db1d6524990aecce49c3c5c79ee41361b01b49302eac1cc5f9decd0d1058d14e
|
||||
#define ENDPOINT_PRIVATE_KEY {0xdb, 0x1d, 0x65, 0x24, 0x99, 0x0a, 0xec, 0xce, 0x49, 0xc3, 0xc5, 0xc7, 0x9e, 0xe4, 0x13, 0x61, 0xb0, 0x1b, 0x49, 0x30, 0x2e, 0xac, 0x1c, 0xc5, 0xf9, 0xde, 0xcd, 0x0d, 0x10, 0x58, 0xd1, 0x4e}
|
||||
|
||||
/**
|
||||
* @brief Endpoint name for User provisioning with certificate.
|
||||
* @details
|
||||
* Endpoint name for endpoint.
|
||||
*/
|
||||
#define ENDPOINT_NAME "User_cert"
|
||||
|
||||
/**
|
||||
* @brief Vendor specific extension for User provisioning with certificate.
|
||||
* @details
|
||||
* Vendor specific extension for endpoint.
|
||||
*/
|
||||
#define B1_VENDOR_SPECIFIC_EXTENSION "ST Rooms"
|
||||
|
||||
/**
|
||||
* @brief Vendor specific extension length for User provisioning with certificate.
|
||||
* @details
|
||||
* Vendor specific extension length for endpoint.
|
||||
*/
|
||||
#define B1_VENDOR_SPECIFIC_EXTENSION_LEN 8
|
||||
|
||||
|
||||
/**
|
||||
* @brief Credential issuer public key for User provisioning.
|
||||
* @details
|
||||
* Credential issuer public key for stepup menager.
|
||||
*/
|
||||
#define CREDENTIAL_ISSUER_PUB_KEY_2 { 0x7B, 0xA3, 0x19, 0x38, 0x49, 0x2E, 0x3F, 0x5E, 0x97, 0xBC, 0x91, 0x80, 0x6B, 0x58, 0x35, 0xB5, 0xD9, 0xE4, 0x26, 0x60, 0x91, 0x39, 0x00, 0x67, 0x11, 0xE5, 0xFB, 0x7A, 0x67, 0x0E, 0xE4, 0xE1, 0x2F, 0xC9, 0xF2, 0x53, 0x96, 0xC0, 0x13, 0xCC, 0x20, 0x16, 0x60, 0x29, 0xD7, 0x61, 0xA1, 0x05, 0xDE, 0xA5, 0xE0, 0x71, 0xE8, 0x4A, 0x9E, 0x49, 0x99, 0x20, 0x52, 0x4C, 0xE2, 0x30, 0x11, 0x37 }
|
||||
|
||||
/**
|
||||
* @brief Credential issuer private key for User provisioning.
|
||||
* @details
|
||||
* Credential issuer private key for stepup menager.
|
||||
*/
|
||||
#define CREDENTIAL_ISSUER_PRIVATE_KEY_2 { 0 }
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Test Harness configuration
|
||||
{
|
||||
"test_parameters": {
|
||||
"dut_reader_public_key": "045bc20b2853e11fcb086192d8a5d5b7829b13d143b0da2de68e1bc94f8b016027a8854eae0226d4205e8f710d168da2f57d3fa2150b64338d212ce015e200513f",
|
||||
"dut_reader_group_identifier": "8f9633dd856d2a156f2aee573deb11e5",
|
||||
"dut_reader_issuer_public_key": "04fbc3fdac291606a0a986862004bbe5c6188ce64098f4a65b7a6595fc31f416259141a972b916e6321dbeee22b77eec5929d80779c99f8ebe5c2588f24b24de68",
|
||||
"dut_reader_issuer_group_identifier": "9f9633dd856d2a156f2aee573deb11e5",
|
||||
"dut_reader_group_sub_identifier": "43815ef53299c92e95b052138133ed39",
|
||||
"dut_reader_group_resolving_key": "0375ed63685570f6b2168eab7296ec01",
|
||||
"th_access_credential_private_key": "db1d6524990aecce49c3c5c79ee41361b01b49302eac1cc5f9decd0d1058d14e",
|
||||
"th_access_credential_public_key": "04773f9aa84ac9705161c490a2dba0b4a19a3d2a78705a801cff924e26357e4213191db83789a25916e4accea1fd6f09239b4cf2dd0d05b33b72d8a3a642e30866",
|
||||
"th_reader_private_key": "8aefdff8d5b47aa9a3edbac7a345ed2221021512fd55abde3b8ee0f208952693",
|
||||
"th_reader_public_key": "043928f322019d4757893bde6a0fe5e13e3e537b9ca0f549c0bd2f40f79060252a0a4f291192157a95cb6eb202759428c00cd834998c5d0eab192ee8873c5d34ee",
|
||||
"th_reader_group_identifier": "00113344667799AA00113344667799AA",
|
||||
"th_reader_sub_group_identifier": "113344667799AA00113344667799AA00",
|
||||
"th_reader_certificate": "308201523081f9a003020102020101300a06082a8648ce3d0403023011310f300d06035504030c06697373756572301e170d3230303130313030303030305a170d3439303130313030303030305a30123110300e06035504030c077375626a6563743059301306072a8648ce3d020106082a8648ce3d030107034200043928f322019d4757893bde6a0fe5e13e3e537b9ca0f549c0bd2f40f79060252a0a4f291192157a95cb6eb202759428c00cd834998c5d0eab192ee8873c5d34eea341303f301f0603551d230418301680143fb5efecb9f0a8b253e4b6788dc15a5913f7c763300c0603551d130101ff04023000300e0603551d0f0101ff040403020780300a06082a8648ce3d04030203480030450220296b57afcb0f1f86e7c3e76b16f82ea0737e8105d5c5e03f3333e6ef9193c80d022100909083e76eaaf0430c7639159b00620d0c6a40fdb6e11ec52ed5bdd3dfb1706f",
|
||||
"th_reader_group_resolving_key": "0375ed63685570f6b2168eab7296ec01",
|
||||
"th_reader_spsm": "0080"
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* Reader provisioning
|
||||
{
|
||||
"MaxDevices": 8,
|
||||
"reader_identifier": "8f9633dd856d2a156f2aee573deb11e543815ef53299c92e95b052138133ed39",
|
||||
"reader_PrivK": "cb64a58a5fae052d458b3bce2599a20a665987b537b157cc3cc42e1d9c652409",
|
||||
"reader_PubK": "045bc20b2853e11fcb086192d8a5d5b7829b13d143b0da2de68e1bc94f8b016027a8854eae0226d4205e8f710d168da2f57d3fa2150b64338d212ce015e200513f",
|
||||
"issuer_Private": "31222ec2125a2921671e471ae67b8796668e37c0167c72bf540e4c5393599f85",
|
||||
"issuer_Public": "04fbc3fdac291606a0a986862004bbe5c6188ce64098f4a65b7a6595fc31f416259141a972b916e6321dbeee22b77eec5929d80779c99f8ebe5c2588f24b24de68",
|
||||
"certificate_data": "3081e8040200003081e18014269e0680731d796703576be42b668a7dfe9c1e29811253544d6963726f656c656374726f6e696373820d3235313231363135343034395a830d3330313231363135343034395a840844656d6f6c6f636b854200045bc20b2853e11fcb086192d8a5d5b7829b13d143b0da2de68e1bc94f8b016027a8854eae0226d4205e8f710d168da2f57d3fa2150b64338d212ce015e200513f8649003046022100f1e0b84ad64aa078a039cc1be850a9d1534d52a26d6a5e137e0a710f59f12b49022100d089e452ee102cb5813eaded8625cc4b54b69835ec2e4c59c12e2a4a495dddaf",
|
||||
"b1VendorSpecificExtension": "ST Rooms",
|
||||
"Devices": [
|
||||
{
|
||||
"Name": "Alice",
|
||||
"endpoint_Keyslot": "54b54e27d515ac4c",
|
||||
"endpoint_PubK": "04773f9aa84ac9705161c490a2dba0b4a19a3d2a78705a801cff924e26357e4213191db83789a25916e4accea1fd6f09239b4cf2dd0d05b33b72d8a3a642e30866",
|
||||
"endpoint_PrivK": "db1d6524990aecce49c3c5c79ee41361b01b49302eac1cc5f9decd0d1058d14e"
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
/* Terminal command for provisioning
|
||||
// setRDiden-8f9633dd856d2a156f2aee573deb11e543815ef53299c92e95b052138133ed39
|
||||
// setRDprvk-cb64a58a5fae052d458b3bce2599a20a665987b537b157cc3cc42e1d9c652409
|
||||
// setRDpubk-045bc20b2853e11fcb086192d8a5d5b7829b13d143b0da2de68e1bc94f8b016027a8854eae0226d4205e8f710d168da2f57d3fa2150b64338d212ce015e200513f
|
||||
// setDEVpbk-04773f9aa84ac9705161c490a2dba0b4a19a3d2a78705a801cff924e26357e4213191db83789a25916e4accea1fd6f09239b4cf2dd0d05b33b72d8a3a642e30866
|
||||
// setRDgrrk-0375ed63685570f6b2168eab7296ec01
|
||||
// setRisspk-04fbc3fdac291606a0a986862004bbe5c6188ce64098f4a65b7a6595fc31f416259141a972b916e6321dbeee22b77eec5929d80779c99f8ebe5c2588f24b24de68
|
||||
*/
|
||||
@@ -0,0 +1,708 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : app_aliro.h
|
||||
* @brief : Header for app_aliro.c file.
|
||||
* This file contains the public declarations for the Aliro demo.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _APP_ALIRO_H_
|
||||
#define _APP_ALIRO_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup NFCBLE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include "st_errno.h"
|
||||
#include "ACWG_Security.h"
|
||||
#include "provisioning.h"
|
||||
#if defined(STM32U545xx) || defined(STM32U585xx)
|
||||
#include "stm32u5xx_hal.h"
|
||||
#include "stm32u5xx_nucleo.h"
|
||||
#include "log_module_u5.h"
|
||||
void Log_Module_Print(Log_Verbose_Level_t VerboseLevel, Log_Region_t Region, const char * Text, ...);
|
||||
#endif //defined(STM32U545xx) || defined(STM32U585xx)
|
||||
#if defined(STM32U385xx)
|
||||
#include "stm32u3xx_hal.h"
|
||||
#include "stm32u3xx_nucleo.h"
|
||||
#include "log_module_u3.h"
|
||||
void Log_Module_Print(Log_Verbose_Level_t VerboseLevel, Log_Region_t Region, const char * Text, ...);
|
||||
#endif //defined(STM32U385xx)
|
||||
#if defined(STM32WBA52xx) || defined(STM32WBA55xx) || defined(STM32WBA65xx)
|
||||
#include "stm32wbaxx_hal.h"
|
||||
#include "stm32wbaxx_nucleo.h"
|
||||
#include "log_module.h"
|
||||
#endif //defined(STM32WBA52xx) || defined(STM32WBA55xx) || defined(STM32WBA65xx)
|
||||
|
||||
/** @addtogroup Aliro_app_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @enum verblevel_t
|
||||
* @brief Verbosity levels for logging.
|
||||
*/
|
||||
typedef enum _verblevel
|
||||
{
|
||||
VERB_NULL=0, /**< No output */
|
||||
VERB_ALWAYS=1, /**< Always output */
|
||||
VERB_CRITICAL=2, /**< Critical output */
|
||||
VERB_ERROR=3, /**< Error output */
|
||||
VERB_NORMAL=4, /**< Normal output */
|
||||
VERB_VERBOSE=5, /**< Verbose output */
|
||||
VERB_INFO=6 /**< Informational output */
|
||||
}verblevel_t;
|
||||
|
||||
|
||||
/**
|
||||
* @enum timeStampsPos_t
|
||||
* @brief Timestamp positions for performance measurement.
|
||||
*/
|
||||
typedef enum _timeStampsPos
|
||||
{
|
||||
SELECT_APP_POS, /**< Application selection */
|
||||
END_SELECT_APP_POS, /**< End of application selection */
|
||||
AUTH0_POS, /**< Start authentication 0 */
|
||||
END_AUTH0_POS, /**< End authentication 0 */
|
||||
LOADCERT_POS, /**< Certificate loading */
|
||||
END_LOADCERT_POS, /**< End certificate loading */
|
||||
AUTH1_POS, /**< Start authentication 1 */
|
||||
END_AUTH1_POS, /**< End authentication 1 */
|
||||
CONTROL_FLOW_POS, /**< Control flow */
|
||||
END_CONTROL_FLOW_POS, /**< End control flow */
|
||||
EXCHANGE_POS, /**< Data exchange */
|
||||
END_EXCHANGE_POS, /**< End data exchange */
|
||||
STEPUP_POS, /**< Step-up */
|
||||
END_STEPUP_POS, /**< End step-up */
|
||||
DOOR_IS_OPENED_POS, /**< Door opened */
|
||||
DOOR_IS_CLOSED_POS, /**< Door closed */
|
||||
DOOR_IS_DISARMED_POS, /**< Door disarmed */
|
||||
DON_T_KNOW_POS, /**< Unknown state */
|
||||
|
||||
DERIVE_PERSISTENT_KEYS_POS, /**< Derivation of persistent keys */
|
||||
END_DERIVE_PERSISTENT_KEYS_POS,/**< End derivation of persistent keys */
|
||||
|
||||
ELAPSED_TIME_POS, /**< Elapsed time */
|
||||
|
||||
NUM_TIMESTAMPS /**< Total number of timestamps (do not change) */
|
||||
}timeStampsPos_t;
|
||||
|
||||
|
||||
/**
|
||||
* @struct statItem_t
|
||||
* @brief Structure for managing timestamps and statistics.
|
||||
*/
|
||||
typedef struct _statItem
|
||||
{
|
||||
timeStampsPos_t pos; /**< Timestamp position */
|
||||
char title[10]; /**< Title */
|
||||
uint8_t toPrint; /**< Print flag */
|
||||
uint32_t ts; /**< Timestamp value */
|
||||
}statItem_t;
|
||||
|
||||
|
||||
/**
|
||||
* @struct alirosvc_param_t
|
||||
* @brief Aliro service parameters.
|
||||
*/
|
||||
typedef struct _alirosvc_param
|
||||
{
|
||||
uint8_t proposedSPSM[2]; /**< Proposed SPSM */
|
||||
uint8_t protVerSupportedLen; /**< Supported protocol version length */
|
||||
uint8_t supportedProtocolVersion[4]; /**< Supported protocol versions */
|
||||
uint8_t selectedProtocolVersion[2]; /**< Selected protocol version */
|
||||
uint8_t featuresSupportedLen; /**< Supported features length */
|
||||
uint8_t featuresSupported[1]; /**< Supported features */
|
||||
}
|
||||
alirosvc_param_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Aliro_app_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported variables ------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Aliro protocol versions supported.
|
||||
*/
|
||||
extern uint32_t xProtocolVersionSupported;
|
||||
|
||||
/**
|
||||
* @brief Current verbosity level.
|
||||
*/
|
||||
extern verblevel_t nVerbosityLevel;
|
||||
|
||||
/**
|
||||
* @brief NFC session context.
|
||||
*/
|
||||
extern ACWG_SessionContext_t context_nfc;
|
||||
|
||||
/**
|
||||
* @brief NFC session context.
|
||||
*/
|
||||
extern ACWG_SessionContext_t context_ble;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Aliro_app_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
#define VERBOSITY_SET nVerbosityLevel /**< Macro to get the current verbosity level */
|
||||
#define ALIRO_MEASURE_PERFORMANCE 0 /**< Enable performance measurement */
|
||||
#define ALIRO_CERTIFICATION_TEST 1 /**< Enable certification test */
|
||||
|
||||
//0x40 --> Bit 6: Bluetooth LE-Only Aliro flow supported.
|
||||
//0x80 --> Bit 7: Bluetooth LE + UWB Aliro flow supported.
|
||||
#define BLE_RKE_ALIRO_FLOW_SUPPORTED 0x40 /**< Bit 6: BLE-only Aliro flow supported */
|
||||
#define BLE_UWB_ALIRO_FLOW_SUPPORTED 0x80 /**< Bit 7: BLE + UWB Aliro flow supported */
|
||||
|
||||
#define BLE_ALIRO_FLOWS_SUPPORTED (BLE_UWB_ALIRO_FLOW_SUPPORTED | BLE_RKE_ALIRO_FLOW_SUPPORTED) /**< Macro for supported Aliro flows */
|
||||
|
||||
#define ALIRO_RTC_SET_STATUS_IAR 0x00F4 /**< RTC IAR status */
|
||||
#define ALIRO_RTC_SET_STATUS_GOOD 0x34F4 /**< RTC good status */
|
||||
|
||||
#define TIMEOUT_PREPARE_RANGING_DEFAULT 20000 /** Default timeout (ms) for prepare ranging operation. */
|
||||
#define TIMEOUT_EXECUTE_RANGING_DEFAULT 70000 /** Default timeout (ms) for execute ranging operation. */
|
||||
#define TIMEOUT_SUSPEND_RANGING_DEFAULT 10000 /** Default timeout (ms) for suspend ranging operation. */
|
||||
#define TIMEOUT_RESUME_RANGING_DEFAULT 20000 /** Default timeout (ms) for resume ranging operation. */
|
||||
#define TIMEOUT_DOOR_OPERATION_DEFAULT 20000 /** Default timeout (ms) for door operation. */
|
||||
|
||||
#if defined (ST25R200)
|
||||
#define X_NUCLEO_NFC_NAME "X-NUCLEO-NFC09A1/NFC10A1"
|
||||
#endif //defined (ST25R200)
|
||||
|
||||
#if defined (ST25R500)
|
||||
#define X_NUCLEO_NFC_NAME "X-NUCLEO-NFC12A1"
|
||||
#endif //defined (ST25R200)
|
||||
|
||||
#if USE_GEN2
|
||||
|
||||
#define ALIRO_BLE 1
|
||||
|
||||
#define H_ALIRO_UART huart1
|
||||
#define HH_ALIRO_UART &H_ALIRO_UART
|
||||
#define H_TIM htim2
|
||||
|
||||
extern RTC_HandleTypeDef hrtc;
|
||||
|
||||
#define ALIRO_HRTC hrtc
|
||||
#define ALIRO_RTC_BKP_TIME RTC_BKP_DR10
|
||||
|
||||
#define LD3_Pin GPIO_PIN_0
|
||||
#define LD3_GPIO_Port GPIOE
|
||||
#define LD2_Pin GPIO_PIN_1
|
||||
#define LD2_GPIO_Port GPIOE
|
||||
|
||||
//sector 125
|
||||
#define PROVISIONING_SECTOR 253
|
||||
#define PROVISIONING_START_ADDRESS (0x08000000+PROVISIONING_SECTOR*0x2000) //0x081fa000
|
||||
|
||||
//sector 124
|
||||
#define PROVISIONING_JSON_SECTOR 252
|
||||
#define PROVISIONING_JSON_START_ADDRESS (0x08000000+PROVISIONING_JSON_SECTOR*0x2000) //0x081f8000
|
||||
#else //USE_GEN2
|
||||
|
||||
#if defined(STM32WBA52xx)||defined(STM32WBA55xx)
|
||||
|
||||
#define ALIRO_BLE 1
|
||||
|
||||
#define H_ALIRO_UART huart1
|
||||
#define HH_ALIRO_UART &H_ALIRO_UART
|
||||
#define H_TIM htim2
|
||||
extern RTC_HandleTypeDef hrtc;
|
||||
|
||||
#define ALIRO_HRTC hrtc
|
||||
#define ALIRO_RTC_BKP_TIME RTC_BKP_DR10
|
||||
|
||||
#define LD3_Pin GPIO_PIN_8
|
||||
#define LD3_GPIO_Port GPIOB
|
||||
#define LD2_Pin GPIO_PIN_9
|
||||
#define LD2_GPIO_Port GPIOA
|
||||
|
||||
//sector 125
|
||||
#define PROVISIONING_SECTOR 123
|
||||
#define PROVISIONING_START_ADDRESS (0x08000000+PROVISIONING_SECTOR*0x2000) //0x080fa000
|
||||
|
||||
//sector 124
|
||||
#define PROVISIONING_JSON_SECTOR 122
|
||||
#define PROVISIONING_JSON_START_ADDRESS (0x08000000+PROVISIONING_JSON_SECTOR*0x2000) //0x080f8000
|
||||
#endif //defined(STM32WBA52xx)||defined(STM32WBA55xx)
|
||||
|
||||
|
||||
#ifdef STM32WBA65xx
|
||||
|
||||
#define ALIRO_BLE 1
|
||||
|
||||
#define H_ALIRO_UART huart1
|
||||
#define HH_ALIRO_UART &H_ALIRO_UART
|
||||
#define H_TIM htim2
|
||||
extern RTC_HandleTypeDef hrtc;
|
||||
|
||||
#define ALIRO_HRTC hrtc
|
||||
#define ALIRO_RTC_BKP_TIME RTC_BKP_DR10
|
||||
|
||||
#define LD3_Pin GPIO_PIN_0
|
||||
#define LD3_GPIO_Port GPIOE
|
||||
#define LD2_Pin GPIO_PIN_1
|
||||
#define LD2_GPIO_Port GPIOE
|
||||
|
||||
//sector 125
|
||||
#define PROVISIONING_SECTOR 253
|
||||
#define PROVISIONING_START_ADDRESS (0x08000000+PROVISIONING_SECTOR*0x2000) //0x081fa000
|
||||
|
||||
//sector 124
|
||||
#define PROVISIONING_JSON_SECTOR 252
|
||||
#define PROVISIONING_JSON_START_ADDRESS (0x08000000+PROVISIONING_JSON_SECTOR*0x2000) //0x081f8000
|
||||
#endif //STM32WBA65xx
|
||||
|
||||
|
||||
|
||||
#if defined(STM32U545xx) || defined(STM32U585xx) || defined(STM32U385xx)
|
||||
extern EXTI_HandleTypeDef H_EXTI_13;
|
||||
extern UART_HandleTypeDef huart1;
|
||||
#define HH_ALIRO_UART &huart1
|
||||
#define H_ALIRO_UART huart1
|
||||
#define H_TIM htim2
|
||||
|
||||
#define LD3_Pin GPIO_PIN_8
|
||||
#define LD3_GPIO_Port GPIOB
|
||||
#define LD2_Pin GPIO_PIN_4
|
||||
#define LD2_GPIO_Port GPIOC
|
||||
|
||||
//sector 125
|
||||
#define PROVISIONING_SECTOR 63
|
||||
#define PROVISIONING_START_ADDRESS (0x08000000+PROVISIONING_SECTOR*0x2000) //0x081fa000
|
||||
|
||||
//sector 124
|
||||
#define PROVISIONING_JSON_SECTOR 62
|
||||
#define PROVISIONING_JSON_START_ADDRESS (0x08000000+PROVISIONING_JSON_SECTOR*0x2000) //0x081f8000
|
||||
#endif //defined(STM32U545xx) || defined(STM32U585xx) || defined(STM32U385xx)
|
||||
|
||||
#endif //USE_GEN2
|
||||
|
||||
#if defined ALIRO_HRTC
|
||||
#define USE_RTC 1
|
||||
#endif //defined ALIRO_HRTC
|
||||
|
||||
#define CLEAR_SCREEN_COMMAND "\033[2J\r\n"
|
||||
#define TEXT_COLOR_1 "\033[0;32m" //green
|
||||
#define TEXT_COLOR_GREEN "\033[0;32m" //green
|
||||
#define TEXT_COLOR_2 "\033[0;33m"
|
||||
#define TEXT_COLOR_YELLOW "\033[0;33m"
|
||||
#define TEXT_COLOR_3 "\033[0;31m"
|
||||
#define TEXT_COLOR_RED "\033[0;31m"
|
||||
#define TEXT_COLOR_4 "\033[0;36m"
|
||||
#define TEXT_COLOR_CYAN "\033[0;36m"
|
||||
#define TEXT_COLOR_BLU "\033[0;34m"
|
||||
#define TEXT_COLOR_VIOLET "\033[0;35m"
|
||||
#define TEXT_COLOR_GRAY "\033[0;37m"
|
||||
#define TEXT_COLOR_NOIR "\033[0;30m"
|
||||
#define TEXT_COLOR_DEFAULT "\033[0;39m"
|
||||
|
||||
//Background
|
||||
#define TEXT_BACKGROUND_COLOR_BLACK "\033[40m"
|
||||
#define TEXT_BACKGROUND_COLOR_RED "\033[41m"
|
||||
#define TEXT_BACKGROUND_COLOR_GREEN "\033[42m"
|
||||
#define TEXT_BACKGROUND_COLOR_YELLOW "\033[43m"
|
||||
#define TEXT_BACKGROUND_COLOR_BLUE "\033[44m"
|
||||
#define TEXT_BACKGROUND_COLOR_PURPLE "\033[45m"
|
||||
#define TEXT_BACKGROUND_COLOR_CYAN "\033[46m"
|
||||
#define TEXT_BACKGROUND_COLOR_WHITE "\033[47m"
|
||||
|
||||
#define TEXT_TEST_COLOR "\033[7;34m"
|
||||
|
||||
#define TEXT_RESET "\033[0m"
|
||||
#define TEXT_BOLD "\033[1m" //used to make ligth color
|
||||
#define TEXT_UNDERSCORE "\033[4m"
|
||||
#define TEXT_BLINK "\033[5m"
|
||||
#define TEXT_REVERSE "\033[7m"
|
||||
#define TEXT_CONCEALED "\033[8m"
|
||||
|
||||
#define TEXT_COLOR_ESCAPE_CHAR '\033'
|
||||
|
||||
#define VERB_STATISTICS VERB_INFO
|
||||
#define VERB_STATISTICS_REPORT VERB_CRITICAL
|
||||
#define VERB_STATE_TITLE VERB_NORMAL
|
||||
#define VERB_FN_NAME VERB_VERBOSE
|
||||
#define VERB_TERMINAL VERB_NORMAL
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Aliro_app_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#if ALIRO_MEASURE_PERFORMANCE
|
||||
#define RESET_TIME_STAMP() do{ ResetTimeStamp();ResetAllSavedTimeStamps(); }while(0)
|
||||
#define PRINT_TIME_STAMP(pos) do{ SaveTimeStamp(pos);/*PrintTimeStamp(label);*/ }while(0)
|
||||
#define TIME_STAMP_REPORT() do{ PrintTimeStampReport(); }while(0)
|
||||
#else //ALIRO_MEASURE_PERFORMANCE
|
||||
#define RESET_TIME_STAMP()
|
||||
#define PRINT_TIME_STAMP(pos)
|
||||
#define TIME_STAMP_REPORT()
|
||||
#endif //ALIRO_MEASURE_PERFORMANCE
|
||||
|
||||
#define countof(_A_) (sizeof(_A_) / sizeof(*(_A_))) /**< Macro to count array elements */
|
||||
|
||||
#define PLATFORM_LOG(VERBOSITY, ...) do{if((uint8_t)VERBOSITY <= (uint8_t)nVerbosityLevel)LOG_INFO_APP(__VA_ARGS__);}while(0)
|
||||
#define DELAY_CONDITIONAL(D) do{if( nVerbosityLevel > VERB_VERBOSE)HAL_Delay(D);}while(0)
|
||||
|
||||
#define HIGH_BYTE(A) ((A&0xFF00)>>8)
|
||||
#define LOW_BYTE(A) (A&0x00FF)
|
||||
|
||||
#define HEX(C) (((C>='0') && (C<='9'))?(C-'0'):((C>='A') && (C<='F'))?(C-'A'+0xA):(0))
|
||||
|
||||
#define GET_IAR_YEAR_DEC(D) ((HEX(D[7])*1000 + HEX(D[8])*100 + HEX(D[9])*10 + HEX(D[10])*1) - 2000)
|
||||
#define GET_IAR_YEAR(D) (GET_IAR_YEAR_DEC(D)%10 + (GET_IAR_YEAR_DEC(D)/10)*16 - 0x30)
|
||||
#define GET_IAR_DATE(D) (HEX(D[4])*16 + HEX(D[5])*1)
|
||||
#define GET_IAR_HOURS(T) (HEX(T[0])*16 + HEX(T[1])*1)
|
||||
#define GET_IAR_MINUTES(T) (HEX(T[3])*16 + HEX(T[4])*1)
|
||||
#define GET_IAR_SECONDS(T) (HEX(T[6])*16 + HEX(T[7])*1)
|
||||
#define GET_IAR_MONTH(D) (\
|
||||
(D[0]==JAN[0] && D[1] == JAN[1] && D[2] == JAN[2])?0x1:\
|
||||
(D[0]==FEB[0] && D[1] == FEB[1] && D[2] == FEB[2])?0x2:\
|
||||
(D[0]==MAR[0] && D[1] == MAR[1] && D[2] == MAR[2])?0x3:\
|
||||
(D[0]==APR[0] && D[1] == APR[1] && D[2] == APR[2])?0x4:\
|
||||
(D[0]==MAY[0] && D[1] == MAY[1] && D[2] == MAY[2])?0x5:\
|
||||
(D[0]==JUN[0] && D[1] == JUN[1] && D[2] == JUN[2])?0x6:\
|
||||
(D[0]==JUL[0] && D[1] == JUL[1] && D[2] == JUL[2])?0x7:\
|
||||
(D[0]==AUG[0] && D[1] == AUG[1] && D[2] == AUG[2])?0x8:\
|
||||
(D[0]==SEP[0] && D[1] == SEP[1] && D[2] == SEP[2])?0x9:\
|
||||
(D[0]==OCT[0] && D[1] == OCT[1] && D[2] == OCT[2])?0x10:\
|
||||
(D[0]==NOV[0] && D[1] == NOV[1] && D[2] == NOV[2])?0x11:\
|
||||
(D[0]==DEC[0] && D[1] == DEC[1] && D[2] == DEC[2])?0x12:\
|
||||
1)
|
||||
|
||||
#define TRANSACTION_SUCCESS_OPEN() AliroPort_TRANSACTION_SUCCESS_OPEN()
|
||||
#define TRANSACTION_SUCCESS_CLOSE() AliroPort_TRANSACTION_SUCCESS_CLOSE()
|
||||
#define TRANSACTION_FAILURE() AliroPort_TRANSACTION_FAILURE()
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Aliro_app_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Returns the current timestamp.
|
||||
* @return Timestamp value.
|
||||
*/
|
||||
uint32_t GetTimeStamp(void);
|
||||
|
||||
/**
|
||||
* @brief Prints the timestamp associated with a string.
|
||||
* @param pstr Descriptive string.
|
||||
* @return Printed timestamp value.
|
||||
*/
|
||||
uint32_t PrintTimeStamp(char *pstr);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Gets the current date and time.
|
||||
* @param timeDate Pointer to struct tm to store the date and time.
|
||||
*/
|
||||
void GetTimeDate(struct tm *timeDate);
|
||||
|
||||
/**
|
||||
* @brief Shows current date and time.
|
||||
*/
|
||||
void ShowTimeDate(void);
|
||||
|
||||
#if defined(STM32WBA52xx) || defined(STM32WBA55xx) || defined(STM32WBA65xx)
|
||||
/**
|
||||
* @brief Sets the RTC configuration status.
|
||||
* @param nStatus Status to set.
|
||||
*/
|
||||
void SetRtcSettingStatus(uint32_t nStatus);
|
||||
#endif //defined(STM32WBA52xx) || defined(STM32WBA55xx) || defined(STM32WBA65xx)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Resets all saved timestamps.
|
||||
*/
|
||||
void ResetAllSavedTimeStamps(void);
|
||||
|
||||
/**
|
||||
* @brief Searches for the position of a timestamp.
|
||||
* @param pos Position to search.
|
||||
* @return Pointer to the found statItem_t structure.
|
||||
*/
|
||||
statItem_t *SearchPos(timeStampsPos_t pos);
|
||||
|
||||
/**
|
||||
* @brief Saves the timestamp in a specific position.
|
||||
* @param pos Timestamp position.
|
||||
*/
|
||||
void SaveTimeStamp(timeStampsPos_t pos);
|
||||
|
||||
/**
|
||||
* @brief Prints the timestamp report.
|
||||
*/
|
||||
void PrintTimeStampReport(void);
|
||||
|
||||
/**
|
||||
* @brief Resets the current timestamp.
|
||||
*/
|
||||
void ResetTimeStamp(void);
|
||||
|
||||
/**
|
||||
* @brief Prints a buffer in hexadecimal format.
|
||||
* @param pstr Descriptive string.
|
||||
* @param pBuf Buffer to print.
|
||||
* @param nSize Buffer size.
|
||||
*/
|
||||
void PrintBufferHex(const char *pstr, const uint8_t *pBuf, const uint32_t nSize);
|
||||
|
||||
/**
|
||||
* @brief Always prints a buffer in hexadecimal format.
|
||||
* @param pstr Descriptive string.
|
||||
* @param pBuf Buffer to print.
|
||||
* @param nSize Buffer size.
|
||||
*/
|
||||
void PrintBufferHexAlways(const char *pstr, const uint8_t *pBuf, const uint32_t nSize);
|
||||
|
||||
/**
|
||||
* @brief Prints an error string.
|
||||
* @param errstr Error string.
|
||||
* @param retval Return code.
|
||||
*/
|
||||
void PrintErrorString(char*errstr, ACWG_Status_t retval);
|
||||
|
||||
/**
|
||||
* @brief Receives a character from USART.
|
||||
* @param buf Buffer to store the character.
|
||||
* @return Number of received characters.
|
||||
*/
|
||||
uint16_t UsartGetChar(uint8_t *buf);
|
||||
|
||||
/**
|
||||
* @brief Receives a character from USART in blocking mode.
|
||||
* @param buf Buffer to store the character.
|
||||
* @return Number of received characters.
|
||||
*/
|
||||
uint16_t UsartGetCharBlocking(uint8_t *buf);
|
||||
|
||||
/**
|
||||
* @brief Initializes the Aliro module.
|
||||
* @return true if initialization is successful, false otherwise.
|
||||
*/
|
||||
bool aliro_init();
|
||||
|
||||
/**
|
||||
* @brief Executes the main Aliro process.
|
||||
*/
|
||||
void aliro_process();
|
||||
|
||||
/**
|
||||
* @brief Hook for successful transaction - Door open
|
||||
*/
|
||||
__weak void AliroPort_TRANSACTION_SUCCESS_OPEN(void);
|
||||
|
||||
/**
|
||||
* @brief Hook for successful transaction - Door close
|
||||
*/
|
||||
__weak void AliroPort_TRANSACTION_SUCCESS_CLOSE(void);
|
||||
|
||||
/**
|
||||
* @brief Hook for transaction failure
|
||||
*/
|
||||
__weak void AliroPort_TRANSACTION_FAILURE(void);
|
||||
|
||||
/**
|
||||
* @brief Delay porting for Aliro.
|
||||
* @param Delay Delay time in ms.
|
||||
*/
|
||||
void AliroPort_Delay(uint32_t Delay);
|
||||
|
||||
/**
|
||||
* @brief Writes the state of a GPIO pin.
|
||||
* @param GPIOx Pointer to GPIO.
|
||||
* @param GPIO_Pin Pin to write.
|
||||
* @param PinState State to set.
|
||||
*/
|
||||
void AliroPort_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
|
||||
|
||||
/**
|
||||
* @brief Transmits data via UART.
|
||||
* @param huart UART handle.
|
||||
* @param pData Data to transmit.
|
||||
* @param Size Data size.
|
||||
* @param Timeout Operation timeout.
|
||||
* @return HAL status.
|
||||
*/
|
||||
HAL_StatusTypeDef AliroPort_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
|
||||
|
||||
/**
|
||||
* @brief Receives data via UART.
|
||||
* @param huart UART handle.
|
||||
* @param pData Data buffer.
|
||||
* @param Size Pointer to data size.
|
||||
* @param Timeout Operation timeout.
|
||||
* @return HAL status.
|
||||
*/
|
||||
HAL_StatusTypeDef AliroPort_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t *Size, uint32_t Timeout);
|
||||
|
||||
/**
|
||||
* @brief Interrupt Service Routine for button 1.
|
||||
*/
|
||||
void Button1_isr( void );
|
||||
|
||||
/**
|
||||
* @brief Board reset.
|
||||
*/
|
||||
void board_reset();
|
||||
|
||||
/**
|
||||
* @brief Checks if the selected SPSM is valid.
|
||||
* @param selected Selected SPSM.
|
||||
* @return 1 if valid, 0 otherwise.
|
||||
*/
|
||||
uint8_t isValidSPSM(uint16_t selected);
|
||||
|
||||
/**
|
||||
* @brief Gets dynamic SPSM.
|
||||
* @param old_spsm Previous SPSM.
|
||||
* @return Dynamic SPSM.
|
||||
*/
|
||||
uint16_t get_dynamic_spsm(uint8_t old_spsm);
|
||||
|
||||
/**
|
||||
* @brief Fills the advertising buffer.
|
||||
* @param advbuf Advertising buffer.
|
||||
* @param psize Pointer to size.
|
||||
*/
|
||||
void fillAdvBuffer(uint8_t *advbuf, uint8_t *psize);
|
||||
|
||||
/**
|
||||
* @brief Gets the initial length of Aliro service parameters.
|
||||
* @param pLen Pointer to length.
|
||||
* @return Length.
|
||||
*/
|
||||
uint8_t AliroSvcParamGetInitLen(uint8_t *pLen);
|
||||
|
||||
/**
|
||||
* @brief Gets the initial buffer of Aliro service parameters.
|
||||
* @param DataBuf Pointer to data buffer.
|
||||
* @return Buffer length.
|
||||
*/
|
||||
uint8_t AliroSvcParamGetInitBuf(uint8_t **DataBuf);
|
||||
|
||||
/**
|
||||
* @brief Verifies the Aliro protocol version.
|
||||
* @param selectedProtocolVersion_16 Selected version.
|
||||
* @return 1 if valid, 0 otherwise.
|
||||
*/
|
||||
uint8_t AliroSvcVerifyProtVer(uint16_t selectedProtocolVersion_16);
|
||||
|
||||
/**
|
||||
* @brief Gets the saved selected protocol version.
|
||||
* @return Selected version.
|
||||
*/
|
||||
uint16_t AliroGetSavedSelectedProtocolVersion();
|
||||
|
||||
/**
|
||||
* @brief BLE Aliro initialization complete callback.
|
||||
*/
|
||||
void AliroBLE_Init_complete_cb();
|
||||
|
||||
/**
|
||||
* @brief BLE Aliro disconnection complete callback.
|
||||
*/
|
||||
void AliroBleDisconnection_complete_cb();
|
||||
|
||||
/**
|
||||
* @brief BLE CoC Aliro disconnection complete callback.
|
||||
*/
|
||||
void AliroBleCocDisconnection_complete_cb();
|
||||
|
||||
/**
|
||||
* @brief Fills techs2find for Aliro.
|
||||
* @param techs2find Pointer to techs2find.
|
||||
*/
|
||||
void AliroFilltechs2Find(uint16_t *techs2find);
|
||||
|
||||
/**
|
||||
* @brief Set the timeout for the prepare ranging operation.
|
||||
*
|
||||
* @param timeout_ms Timeout value in milliseconds.
|
||||
*/
|
||||
void Set_timeout_prepare_ranging(uint32_t timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Set the timeout for the execute ranging operation.
|
||||
*
|
||||
* @param timeout_ms Timeout value in milliseconds.
|
||||
*/
|
||||
void Set_timeout_execute_ranging(uint32_t timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Set the timeout for the suspend ranging operation.
|
||||
*
|
||||
* @param timeout_ms Timeout value in milliseconds.
|
||||
*/
|
||||
void Set_timeout_suspend_ranging(uint32_t timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Set the timeout for the resume ranging operation.
|
||||
*
|
||||
* @param timeout_ms Timeout value in milliseconds.
|
||||
*/
|
||||
void Set_timeout_resume_ranging(uint32_t timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Set the timeout for the door operation.
|
||||
*
|
||||
* @param timeout_ms Timeout value in milliseconds.
|
||||
*/
|
||||
void Set_timeout_door_operation(uint32_t timeout_ms);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _APP_ALIRO_H_ */
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : app_build_info.h
|
||||
* @brief : Header for app_build_info.c file.
|
||||
* This file contains the firmware build information structure.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _APP_BUILD_INFO_H_
|
||||
#define _APP_BUILD_INFO_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup NFCBLE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
|
||||
/** @addtogroup App_build_info_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Current version of @ref app_build_info
|
||||
*/
|
||||
#define ABI_VERSION 1
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup App_build_info_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Various info about the firmware build
|
||||
*
|
||||
* The build info are put at a specific address in flash (e.g. 0x0200), so that we can easily recover it with an
|
||||
* external application which would read the flash.
|
||||
*/
|
||||
typedef struct app_build_info_s {
|
||||
uint8_t magic_cookie[4]; //!< A magic cookie that external application could easily read: 'B', 'F', 'W', 'I'
|
||||
uint8_t build_info_version; //!< Version of this structure, e.g. @ref MBI_VERSION
|
||||
uint8_t app_major; //!< Major version number of the firmware
|
||||
uint8_t app_minor; //!< Minor version number of the firmware
|
||||
uint8_t app_subminor; //!< Subminor version number of the firmware
|
||||
// char revision[32]; //!< git version at the build time, based on hash
|
||||
char date[12]; //!< Build date, e.g. "Jan 1 1970"
|
||||
char time[12]; //!< Build time, e.g. "01:00:00"
|
||||
|
||||
uint8_t aliro_spec_major; //!< Major version number of the Aliro spec.
|
||||
uint8_t aliro_spec_minor; //!< Minor version number of the Aliro spec.
|
||||
uint8_t aliro_spec_subminor; //!< Subminor version number of the Aliro spec.
|
||||
uint8_t acwg_ver_major;
|
||||
uint8_t acwg_ver_minor;
|
||||
uint8_t acwg_ver_subminor;
|
||||
#define MBI_FW_DESCRIPTION_LEN 24
|
||||
char fw_description[MBI_FW_DESCRIPTION_LEN]; //!< Name of the firmware
|
||||
}app_build_info_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup App_build_info_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
// The symbol 'build_info' is defined by the linker script. See file arm-gcc-link.ld
|
||||
// Alternatively, we could use:
|
||||
// #define build_info (*(struct buildinfo*)(0x08000200))
|
||||
|
||||
/* Exported variables ------------------------------------------------------------*/
|
||||
extern const app_build_info_t app_build_info;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _APP_BUILD_INFO_H_ */
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : app_nfc.h
|
||||
* @brief : Header for app_nfc.c file.
|
||||
* This file contains the public NFC API and common NFC definitions for the Aliro application.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _APP_NFC_H_
|
||||
#define _APP_NFC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup NFC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "st_errno.h"
|
||||
#include "ACWG_Security.h"
|
||||
|
||||
|
||||
/** @addtogroup Aliro_NFC_ExportedTypes
|
||||
* @brief Exported types for Aliro NFC module
|
||||
* @{
|
||||
*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup Aliro_NFC_ExportedConstants
|
||||
* @brief Exported constants for Aliro NFC module
|
||||
* @{
|
||||
*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup Aliro_NFC_ExportedMacros
|
||||
* @brief Exported macros for Aliro NFC module
|
||||
* @{
|
||||
*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup Aliro_NFC_ExportedFunctions
|
||||
* @brief Exported functions for Aliro NFC module
|
||||
* @{
|
||||
*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Initializes the NFC module for Aliro.
|
||||
* @param context Pointer to the session context.
|
||||
* @return true if initialization is successful, false otherwise.
|
||||
*/
|
||||
bool AliroNfcIni( ACWG_SessionContext_t *context );
|
||||
|
||||
/**
|
||||
* @brief Executes the main NFC cycle for Aliro.
|
||||
* @param context Pointer to the session context.
|
||||
*/
|
||||
void AliroNfcCycle( ACWG_SessionContext_t *context );
|
||||
|
||||
/**
|
||||
* @brief Stops the NFC module for Aliro.
|
||||
*/
|
||||
void AliroNfcStop( void );
|
||||
|
||||
/**
|
||||
* @brief Gets the technologies to find during NFC discovery.
|
||||
* @return Bitmask of technologies to find.
|
||||
*/
|
||||
uint16_t AliroNfcGetDiscoverTechs2Find( void );
|
||||
|
||||
/**
|
||||
* @brief Gets the total duration for NFC discovery.
|
||||
* @return Duration in milliseconds.
|
||||
*/
|
||||
uint16_t AliroNfcGetDiscoverTotalDuration( void );
|
||||
|
||||
/**
|
||||
* @brief Initializes the NFC hardware for Aliro.
|
||||
*/
|
||||
void AliroNfcHwInit( void );
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _APP_NFC_H_ */
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : app_version.h
|
||||
* @brief : Header for app_version.c file.
|
||||
* This file defines application and specification version macros used by the Aliro firmware.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _APP_VERSION_H_
|
||||
#define _APP_VERSION_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup NFCBLE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "provisioning_info.h"
|
||||
|
||||
/** @addtogroup App_Version_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
#define APP_VERSION_MAJ 0
|
||||
#define APP_VERSION_MIN 9
|
||||
#define APP_VERSION_SUBMIN 3
|
||||
// #define APP_VERSION "0.1.0"
|
||||
// #define SW_VERSION "FW VERSION TBD"
|
||||
|
||||
#define ALIRO_SPEC_VERSION_MAJ 0
|
||||
#define ALIRO_SPEC_VERSION_MIN 9
|
||||
#define ALIRO_SPEC_VERSION_SUBMIN 5
|
||||
#define APP_ACWG_VERSION_MAJ 0
|
||||
#define APP_ACWG_VERSION_MIN 3
|
||||
#define APP_ACWG_VERSION_SUBMIN 4
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _APP_VERSION_H_ */
|
||||
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* \file certificate.h
|
||||
* \author STMicroelectronics - CS application team
|
||||
* \brief x509 certificate Parser
|
||||
******************************************************************************
|
||||
* \attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2022 STMicroelectronics</center></h2>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef CERTIFICATE_H
|
||||
#define CERTIFICATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** \defgroup certificate_core Certificate parser
|
||||
* \ingroup certificate
|
||||
* \brief Certificate parser
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \enum certificate_status_t
|
||||
* \brief response codes enumeration
|
||||
*/
|
||||
typedef enum {
|
||||
CERT_OK = 0x00, /*!< Successful processing */
|
||||
CERT_INVALID_PARAMETER = 0x01, /*!< Wrong function parameters */
|
||||
CERT_UNEXPECTED_SEQUENCE,
|
||||
CERT_UNEXPECTED_BITSTRING,
|
||||
CERT_INVALID_SIGNATURE,
|
||||
CERT_INVALID_CERTIFICATE,
|
||||
CERT_CA_NOT_MATCHING,
|
||||
CERT_UNSUPPORTED_FEATURE,
|
||||
CERT_BAD_SIZE,
|
||||
}certificate_status_t;
|
||||
|
||||
/** \brief Definitions of available signature algorithms */
|
||||
typedef enum {
|
||||
CERT_SIG_ECDSA_SHA1 = 0, /*!< ECDSA with SHA1 algorithm */
|
||||
CERT_SIG_ECDSA_SHA224, /*!< ECDSA with SHA224 algorithm */
|
||||
CERT_SIG_ECDSA_SHA256, /*!< ECDSA with SHA256 algorithm */
|
||||
CERT_SIG_ECDSA_SHA384, /*!< ECDSA with SHA384 algorithm */
|
||||
CERT_SIG_ECDSA_SHA512, /*!< ECDSA with SHA512 algorithm */
|
||||
}certificate_signature_algorithms_t;
|
||||
|
||||
/** \brief Definitions of supported Elliptic Curve Names */
|
||||
typedef enum {
|
||||
CERT_EC_P256 = 0, /*!< NIST P-256 */
|
||||
CERT_EC_P384, /*!< NIST P-384 */
|
||||
CERT_EC_P521, /*!< NIST P-521 */
|
||||
CERT_EC_bp256r1, /*!< brainpoolP256r1 */
|
||||
CERT_EC_bp256t1, /*!< brainpoolP256t1 */
|
||||
CERT_EC_bp384r1, /*!< brainpoolP384r1 */
|
||||
CERT_EC_bp384t1, /*!< brainpoolP384t1 */
|
||||
CERT_EC_bp512r1, /*!< brainpoolP512r1 */
|
||||
CERT_EC_bp512t1, /*!< brainpoolP512t1 */
|
||||
}certificate_elliptic_curves_t;
|
||||
|
||||
|
||||
/** \brief typedef for the structure keeping the validity */
|
||||
typedef struct validity_st {
|
||||
uint8_t seconds; /*!< seconds (range 0 to 59) */
|
||||
uint8_t minutes; /*!< minutes (range 0 to 59) */
|
||||
uint8_t hours; /*!< hours (range 0 to 23) */
|
||||
uint8_t days; /*!< days (range 1 to 31) */
|
||||
uint8_t month; /*!< month (range 1 to 12) */
|
||||
uint32_t year; /*!< years 0 to whatever */
|
||||
} cert_validity_t;
|
||||
|
||||
/** \brief typedef for the structure keeping the Ellipitc Curve Public Key */
|
||||
typedef struct cert_public_key_t
|
||||
{
|
||||
const uint8_t *pX; /*!< Pointer to X Coordinate */
|
||||
const uint8_t *pY; /*!< Pointer to Y Coordiante */
|
||||
uint32_t fsize; /*!< Size of the field in bytes */
|
||||
} cert_public_key_t;
|
||||
|
||||
/** \brief typedef for the structure keeping the ECDSA Signature */
|
||||
typedef struct ECDSAsign_st
|
||||
{
|
||||
const uint8_t *pR; /*!< Pointer to r */
|
||||
uint32_t rSize; /*!< size to r */
|
||||
const uint8_t *pS; /*!< Pointer to s*/
|
||||
uint32_t sSize; /*!< size to s */
|
||||
} cert_signature_t;
|
||||
|
||||
/** \brief internal structure used to keep the values parsed from the x509 */
|
||||
struct internal_certificate {
|
||||
const uint8_t *pPubKey_point_representation_id; /*!< 0x04: Uncompressed key, 0x02 or 0x03: Compressed key */
|
||||
const uint8_t *tbs; /*!< Pointer to tcs field */
|
||||
uint32_t tbsSize; /*!< Size of tcs */
|
||||
uint32_t x509Version; /*!< x509 Version */
|
||||
const uint8_t *serialNumber; /*!< Pointer to SerialNumber*/
|
||||
uint32_t serialNumberSize; /*!< Size of SerialNumber */
|
||||
uint32_t signature; /*!< Signature (algorithm) but from tcs */
|
||||
const uint8_t *issuer; /*!< Pointer to Issuer */
|
||||
uint32_t issuerSize; /*!< Size of Issuer */
|
||||
const uint8_t *validity; /*!< Pointer to Validity */
|
||||
uint32_t validitySize; /*!< Size of Validity */
|
||||
const uint8_t *subject; /*!< Pointer to subject */
|
||||
uint32_t subjectSize; /*!< Size of Subject */
|
||||
uint32_t EllipticCurve; /*!< Identifies the Elliptic Curve */
|
||||
cert_public_key_t PubKey; /*!< Contain the struct \ref cert_public_key_t */
|
||||
const uint8_t *extensions; /*!< Pointer to Extensions */
|
||||
uint32_t extensionsSize; /*!< Size of Extensions */
|
||||
uint32_t extensionsFlags; /*!< Integer encoding the fields present in the tcs: \n
|
||||
* bit 0: BasicConstraints is present \n
|
||||
* bit 1: BasicConstraints is critical \n
|
||||
* bit 2: BasicConstraints indicates this is a CA \n
|
||||
* bit 3: BasicConstraints has a pathLenConstraint \n
|
||||
* bit 4-7: PathLen \n
|
||||
* bit 8: keyUsage is present \n
|
||||
* bit 9: keyUsage is critical \n
|
||||
* bit 15: keyUsage field decipherOnly \n
|
||||
* bit 16: keyUsage field digitalSignature \n
|
||||
* bit 17: keyUsage field contentCommitment/nonRepudiation \n
|
||||
* bit 18: keyUsage field keyEncipherment \n
|
||||
* bit 19: keyUsage field dataEncipherment \n
|
||||
* bit 20: keyUsage field keyAgreement \n
|
||||
* bit 21: keyUsage field keyCertSign \n
|
||||
* bit 22: keyUsage field cRLSign \n
|
||||
* bit 23: keyUsage field encipherOnly \n
|
||||
* bit 24: ExtendedKeyUsage is present \n
|
||||
* bit 25: ExtendedKeyUsage is critical \n
|
||||
* bit 27-29: Unused
|
||||
*/
|
||||
const uint8_t *extAKIkeyIdentifier; /*!< field key identifier of extension authority key identifier */
|
||||
uint32_t extAKIkeyIdentifierSize; /*!< size of previous field */
|
||||
uint32_t SignatureAlgorithm; /*!< SignatureAlgorithm */
|
||||
cert_signature_t Sign; /*!< Contain the struct \ref cert_signature_t */
|
||||
};
|
||||
|
||||
/** \brief typedef for the certificate_t */
|
||||
typedef struct internal_certificate certificate_t;
|
||||
|
||||
|
||||
/* Exported Functions */
|
||||
|
||||
/**
|
||||
* \brief Initialize a certificate (\ref certificate_t) to an empty one
|
||||
* \param[in,out] cert pointer to the certificate_t to be initialized
|
||||
* \note This functions should be called before parsing a certificate
|
||||
* \details \include{doc} Authentication.dox
|
||||
*/
|
||||
void certificate_init(certificate_t *cert);
|
||||
|
||||
/**
|
||||
* \brief Parse an x509 certificate
|
||||
* \param[in] cert pointer to the x509 certificate to be parsed
|
||||
* \param[in] max_size maximum size of certificate to be parsed
|
||||
* \param[out] certificate pointer to the certificate_t that will be filled
|
||||
* \param[out] next pointer to cert array after the parsed certificate (it can be NULL)
|
||||
* \return \ref certificate_status_t : CERT_OK on success ; error code otherwise
|
||||
* \warning The parsed certificated could be empty, it is necessary to call a function
|
||||
* which verifies the certificate to be valid before using it.
|
||||
*/
|
||||
certificate_status_t certificate_parse(const uint8_t *cert, uint32_t max_size, certificate_t *certificate, const uint8_t **next);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Parse the top of x509 certificate to find the tbs and the signature
|
||||
* \param[in] cert pointer to the x509 certificate to be parsed
|
||||
* \param[in] max_size maximum size of certificate to be parsed
|
||||
* \param[out] certificate pointer to the certificate_t that will be filled
|
||||
* \param[out] next pointer to cert array after the parsed certificate (it can be NULL)
|
||||
* \return \ref certificate_status_t : CERT_OK on success ; error code otherwise
|
||||
* \warning The parsed certificated could be empty, it is necessary to call a function
|
||||
* which verifies the certificate to be valid before using it.
|
||||
*/
|
||||
certificate_status_t certificate_find_tbs_and_signature(const uint8_t *cert, uint32_t max_size, certificate_t *certificate, const uint8_t **next);
|
||||
|
||||
/**
|
||||
* \brief Parse the tbs part of a certificate
|
||||
* \param[in/out] *certificate pointer to the certificate_t
|
||||
*/
|
||||
void certificate_parse_tbs(certificate_t *certificate);
|
||||
|
||||
/**
|
||||
* \brief Check that an imported x509 certificate is valid
|
||||
* \param[in] certificate pointer to the parsed x509 certificate to be validated
|
||||
* \param[in] currentTime pointer to a cert_validity_t with the current DateTime. If NULL no date check is done
|
||||
* \return \ref certificate_status_t : CERT_OK on success ; error code otherwise
|
||||
* \warning If currentTime==NULL the check on the validity dates of the certificate will be bypassed.
|
||||
*/
|
||||
certificate_status_t certificate_is_valid(const certificate_t *certificate, const cert_validity_t *currentTime);
|
||||
|
||||
/**
|
||||
* \brief Check whether a certificate is marked as belonging to a CA
|
||||
* \param[in] *cert pointer to the parsed x509 certificate to be checked
|
||||
* \return \ref certificate_status_t : CERT_OK on success ; error code otherwise
|
||||
*/
|
||||
certificate_status_t certificate_is_CA(const certificate_t *cert);
|
||||
|
||||
/**
|
||||
* \brief Check whether "parent" issued "child"
|
||||
* \param[in] parent pointer to the parsed x509 certificate of the supposed issuer of child
|
||||
* \param[in] child pointer to the parsed x509 certificate of the certificated supposedly issued by parent
|
||||
* \param[in] currentTime pointer to a cert_validity_t with the current DateTime. If NULL no date check is done.
|
||||
* \return \ref certificate_status_t : CERT_OK on success ; error code otherwise
|
||||
* \note RFC 5280 mandates an extremely expensive comparison, which we don't perform.
|
||||
* As result of this simplification some legitimate parentship relation could be not acknowledged (the opposite should not occur).
|
||||
* \warning This check only a single level parent relashion (i.e. whether parent issued child)
|
||||
*/
|
||||
certificate_status_t certificate_is_parent(const certificate_t *parent, const certificate_t *child, const cert_validity_t *currentTime);
|
||||
|
||||
/**
|
||||
* \brief Copy a certificate (\ref certificate_t) into another structure
|
||||
* \param[out] copiedCert pointer to the certificate_t that will be written
|
||||
* \param[out] originalCert pointer to the certificate_t that will be copied
|
||||
* \return \ref certificate_status_t : CERT_OK on success ; error code otherwise
|
||||
*/
|
||||
void certificate_copy(certificate_t *copiedCert, const certificate_t *originalCert);
|
||||
|
||||
/**
|
||||
* \brief Iterate over the certificate chain in argument and check each child/parent pairs
|
||||
* \param[in] rootCA Pointer to the root CA certificate buffer
|
||||
* \param[in] certChain Pointer to the certificate chain buffer
|
||||
* \param[in] certChainSize Size of the certificate chain buffer
|
||||
* \param[out] leafCert Pointer to the leaf certificate structure
|
||||
* \return : ertificate_status_t 0 on success ; error code otherwise
|
||||
*/
|
||||
certificate_status_t certificate_parse_chain(
|
||||
uint8_t *rootCA,
|
||||
uint8_t *certChain,
|
||||
uint16_t certChainSize,
|
||||
certificate_t *leafCert);
|
||||
|
||||
/** @}*/
|
||||
|
||||
#endif /* CERTIFICATE_H */
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* \file certificate_crypto.h
|
||||
* \author STMicroelectronics - CS application team
|
||||
* \brief Crypto functionalities for x509 verification
|
||||
******************************************************************************
|
||||
* \attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2022 STMicroelectronics</center></h2>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef CERTIFICATE_CRYPTO_H
|
||||
#define CERTIFICATE_CRYPTO_H
|
||||
|
||||
/** \defgroup certificate_crypto Certificate cryptography
|
||||
* \ingroup certificate
|
||||
* \brief Certificate cryptography functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Verify the signature of a certificate with a public key
|
||||
* \param[in] signing_public_key pointer to the parsed x509 certificate containing the public key to be used for the signature verification
|
||||
* \param[in] signing_public_key_size size in bytes of the digest of the message to be verified
|
||||
* \param[in] certificate pointer to the parsed x509 certificate to verify
|
||||
* \return \ref certificate_status_t : CERT_OK on success ; error code otherwise
|
||||
*/
|
||||
certificate_status_t certificate_verify_signature(const uint8_t* signing_public_key, uint32_t signing_public_key_size, const certificate_t* certificate);
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* \brief Verify the signature of a digest with a public key extracted from the certificate
|
||||
* \param[in] cert pointer to the parsed x509 certificate containing the public key to be used for the signature verification
|
||||
* \param[in] digest the digest of the message to be verified
|
||||
* \param[in] digestSize size in bytes of the digest of the message to be verified
|
||||
* \param[in] signatureR the R value of the signature to be verified
|
||||
* \param[in] signatureRsize the size in bytes of signatureR
|
||||
* \param[in] signatureS the S value of the signature to be verified
|
||||
* \param[in] signatureSsize the size in bytes of signatureS
|
||||
* \return \ref certificate_status_t : CERT_OK on success ; error code otherwise
|
||||
*/
|
||||
certificate_status_t certificate_verify_signature(
|
||||
const certificate_t *cert,
|
||||
const uint8_t *digest,
|
||||
int32_t digestSize,
|
||||
const uint8_t *signatureR,
|
||||
int32_t signatureRsize,
|
||||
const uint8_t *signatureS,
|
||||
int32_t signatureSsize);
|
||||
#endif
|
||||
/**
|
||||
* \brief Check whether "parent" signed "child"
|
||||
* \param[in] parent pointer to the parsed x509 certificate of the supposed issuer of child
|
||||
* \param[in] child pointer to the parsed x509 certificate of the certificated supposedly issued by parent
|
||||
* \return \ref certificate_status_t : CERT_OK on success ; error code otherwise
|
||||
*/
|
||||
certificate_status_t certificate_verify_child_signature(
|
||||
const certificate_t *parent,
|
||||
const certificate_t *child);
|
||||
|
||||
/** @}*/
|
||||
|
||||
#endif /* CERTIFICATE_CRYPTO_H */
|
||||
@@ -0,0 +1,289 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* \file certificate_subparsing.h
|
||||
* \author STMicroelectronics - CS application team
|
||||
* \brief Helper for the x509 certificate Parser
|
||||
******************************************************************************
|
||||
* \attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2022 STMicroelectronics</center></h2>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef CERTIFICATE_SUBPARSING_H
|
||||
#define CERTIFICATE_SUBPARSING_H
|
||||
|
||||
/** \defgroup certificate_subparsing Certificate subparsing routines
|
||||
* \ingroup certificate
|
||||
* \brief Certificate subparsing routines
|
||||
* \{
|
||||
*/
|
||||
|
||||
/** \brief Definitions of X509 TAGs */
|
||||
typedef enum {
|
||||
TAG_BOOLEAN = 0x01, /*!< x509 tag for BOOLEAN */
|
||||
TAG_INTEGER, /*!< x509 tag for INTEGER */
|
||||
TAG_BITSTRING, /*!< x509 tag for BITSTRING */
|
||||
TAG_OCTETSTRING, /*!< x509 tag for OCTETSTRING */
|
||||
TAG_NULL, /*!< x509 tag for NULL */
|
||||
TAG_OBJECT_IDENTIFIER, /*!< x509 tag for OBJECT_IDENTIFIER */
|
||||
TAG_ObjectDescriptor, /*!< x509 tag for ObjectDescriptor */
|
||||
TAG_ENUMERATED = 0x0A, /*!< x509 tag for ENUMERATED */
|
||||
TAG_UTF8String = 0x0C, /*!< x509 tag for UTF8String */
|
||||
TAG_PrintableString = 0x13, /*!< x509 tag for PrintableString */
|
||||
TAG_IA5String = 0x16, /*!< x509 tag for IA5String */
|
||||
TAG_UTCTime, /*!< x509 tag for UTCTime */
|
||||
TAG_GeneralizedTime, /*!< x509 tag for GeneralizedTime */
|
||||
TAG_SEQUENCE = 0x30, /*!< x509 tag for SEQUENCE */
|
||||
TAG_SET, /*!< x509 tag for SET */
|
||||
TAG_OPTION_0 = 0x80, /*!< x509 tag for option 0 */
|
||||
TAG_OPTION_1 , /*!< x509 tag for option 1 */
|
||||
TAG_OPTION_2 , /*!< x509 tag for option 2 */
|
||||
TAG_OPTION_3 , /*!< x509 tag for option 3 */
|
||||
TAG_x509VERSION = 0xA0, /*!< x509 tag for x509VERSION */
|
||||
TAG_issuerUniqueID, /*!< x509 tag for issuerUniqueID */
|
||||
TAG_subjectUniqueID, /*!< x509 tag for subjectUniqueID */
|
||||
TAG_extensions, /*!< x509 tag for extensions */
|
||||
}certificate_tag_t;
|
||||
|
||||
/** \brief Definitions of supported Name Attributes */
|
||||
typedef enum {
|
||||
ATTR_CN = 3, /*!< CommonName */
|
||||
ATTR_SN = 5, /*!< SerialNumber */
|
||||
ATTR_C = 6, /*!< Country */
|
||||
ATTR_LN = 7, /*!< LocalityName */
|
||||
ATTR_SOPN = 8, /*!< stateOrProvinceName */
|
||||
ATTR_ON = 10, /*!< Organization Name */
|
||||
ATTR_OUN = 11, /*!< Organization Unit Name */
|
||||
ATTR_UID = 45, /*!< UniqueIdentifier */
|
||||
ATTR_DN = 49, /*!< DistinguishedName */
|
||||
}certificate_name_attributes_t;
|
||||
|
||||
/** \brief Definitions of supported Extensions types */
|
||||
typedef enum {
|
||||
EXTENSION_KU = 15, /*!< KeyUsage */
|
||||
EXTENSION_BC = 19, /*!< BasicContrains */
|
||||
EXTENSION_AKI = 35, /*!< authority key identifier */
|
||||
EXTENSION_EKU = 37, /*!< extKeyUsage */
|
||||
}certificate_extensions_type_t;
|
||||
|
||||
/** \brief Structure used to keep SignatureAlgorithm OIDs */
|
||||
struct SignatureAlgorithmOID_st
|
||||
{
|
||||
uint32_t len; /*!< size of the encoded OID */
|
||||
uint32_t type; /*!< type of OID */
|
||||
uint8_t oid[8]; /*!< encoded OID */
|
||||
};
|
||||
|
||||
/** \brief Structure used to keep Name Attribute OIDs */
|
||||
struct AttributeOID_st
|
||||
{
|
||||
uint32_t len; /*!< size of the encoded OID */
|
||||
uint32_t type; /*!< type of OID */
|
||||
uint8_t oid[3]; /*!< encoded OID */
|
||||
};
|
||||
|
||||
/** \brief Structure used to keep named Elliptic Curve OIDs */
|
||||
struct EllipticCurveOID_st
|
||||
{
|
||||
uint32_t len; /*!< size of the encoded OID */
|
||||
uint32_t type; /*!< type of OID */
|
||||
uint8_t oid[9]; /*!< encoded OID */
|
||||
};
|
||||
|
||||
/** \brief typedef for the attribute */
|
||||
typedef struct attribute_st
|
||||
{
|
||||
uint32_t type; /*!< type of attribute (corresponding to OID) */
|
||||
uint32_t strFormat; /*!< format of the string */
|
||||
const uint8_t *str; /*!< pointer to the string of the attribute */
|
||||
uint32_t strSize; /*!< size of the string */
|
||||
} cert_attribute_t;
|
||||
|
||||
/** \brief Structure used to keep Name Attribute OIDs */
|
||||
struct ExtensionOID_st
|
||||
{
|
||||
uint32_t len; /*!< size of the encoded OID */
|
||||
uint32_t type; /*!< type of OID */
|
||||
uint8_t oid[5]; /*!< encoded OID */
|
||||
};
|
||||
|
||||
/** \brief typedef for the extension */
|
||||
typedef struct extension_st
|
||||
{
|
||||
uint32_t type; /*!< type of extension (corresponding to OID) */
|
||||
uint32_t critical; /*!< critical */
|
||||
const uint8_t *value;/*!< pointer to the value hold by the extension (this is an octet string) */
|
||||
uint32_t valueSize; /*!< size of the string */
|
||||
} cert_extension_t;
|
||||
|
||||
|
||||
/* Exported Macros */
|
||||
|
||||
/** \brief Macro which checks if a TAG is valid (known) */
|
||||
#define IS_VALID_TAG(tag) (( \
|
||||
(TAG_BOOLEAN <= (tag) && (tag) <= TAG_ObjectDescriptor) || \
|
||||
(tag) == TAG_ENUMERATED || \
|
||||
(tag) == TAG_UTF8String || \
|
||||
(tag) == TAG_PrintableString || \
|
||||
(TAG_IA5String <= (tag) && (tag) <= TAG_GeneralizedTime) || \
|
||||
(tag) == TAG_SEQUENCE || \
|
||||
(tag) == TAG_SET || \
|
||||
(TAG_OPTION_0 <= (tag) && (tag) <= TAG_OPTION_3) || \
|
||||
(TAG_x509VERSION <= (tag) && (tag) <= TAG_extensions) ) ? 1 : 0)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \brief Identify the ASN.1 TLV
|
||||
* \param[in] *asn1 pointer to the ASN.1 TLV
|
||||
* \param[out] *parsed will contain the number of processed bytes (rarely used)
|
||||
* \param[out] *size will contain the size (in bytes) of the value field of this ASN.1 TLV
|
||||
* \param[out] **value will contain a pointer to the value field of this ASN.1 TLV
|
||||
* \param[in/out] *max_size maximum size left for value
|
||||
* \return The internal TAG identifier of this TLV or -1 if failure
|
||||
*/
|
||||
int32_t certificate_identify_ASN1_TLV(const uint8_t *asn1, int32_t *parsed, int32_t *size, const uint8_t **value, uint32_t* max_size);
|
||||
|
||||
/**
|
||||
* \brief Identify the Name Attribute from its OID
|
||||
* \param[in] *oid The value of the OID of the Attribute (got from \ref certificate_identify_ASN1_TLV )
|
||||
* \param[in] size size (in bytes) of the value field of this OID (got from \ref certificate_identify_ASN1_TLV )
|
||||
* \note Only a very limited set of Attributes is supported
|
||||
* \return The internal type identifing the Attribute or -1 for failure
|
||||
*/
|
||||
int32_t certificate_identify_attribute(const uint8_t *oid, int32_t size);
|
||||
|
||||
/**
|
||||
* \brief Parse an ECDSA signature
|
||||
* \param[in] *signature pointer to the expected signature field of the x509 certificate
|
||||
* \param[out] *certificate pointer to the certificate_t that will be filled
|
||||
* \param[out] **next_thing will contain a pointer to the next TLV
|
||||
*/
|
||||
void certificate_parse_ECDSA_signature(const uint8_t *signature, certificate_t *certificate, const uint8_t **next_thing, uint32_t* max_size);
|
||||
|
||||
/**
|
||||
* \brief Parse the x509 Version of a certificate
|
||||
* \param[in] *x509VersionField pointer to the version field of a certificate
|
||||
* \param[out] *certificate pointer to the certificate_t that will be filled
|
||||
* \param[out] **next_thing output pointer to next TLV
|
||||
*/
|
||||
void certificate_parse_X509_version(const uint8_t *x509VersionField, certificate_t *certificate, const uint8_t **next_thing, uint32_t* max_size);
|
||||
|
||||
/**
|
||||
* \brief Parse a SignatureAlgorithm (or signature of a tbsCertificate)
|
||||
* \param[in] *SA pointer to the SignatureAlgorithm (or signature of a tbsCertificate)
|
||||
* \param[out] *singatureAlgorithm integer that will be filled with the internal encoding of signatureAlgorithm
|
||||
* \param[out] **next_thing output pointer to next TLV
|
||||
* \note Only a very limited set of SignatureAlgorithm is supported
|
||||
*/
|
||||
void certificate_parse_signature_algorithm(const uint8_t *SA, uint32_t *singatureAlgorithm, const uint8_t **next_thing, uint32_t* max_size);
|
||||
|
||||
/**
|
||||
* \brief Parse an ECC public Key from a certificate
|
||||
* \param[in] *EccPK pointer to the ECC public Key
|
||||
* \param[out] *certificate pointer to the certificate_t that will be filled
|
||||
* \param[out] **next_thing output pointer to next TLV
|
||||
*/
|
||||
void certificate_parse_ECC_public_key(const uint8_t *EccPK, certificate_t *certificate, const uint8_t **next_thing, uint32_t* max_size);
|
||||
|
||||
/**
|
||||
* \brief Parse an ASN.1 INTEGER
|
||||
* \param[in] *integer pointer to the expected INTEGER TLV
|
||||
* \param[out] *outp will point to the starting byte of the integer
|
||||
* \param[out] *outSize will contain the size of the integer in bytes
|
||||
* \param[out] **next_thing will contain a pointer to the next TLV
|
||||
* \note This doesn't copy the integer. To keep memory small this just returns a pointer to it.
|
||||
* \warning only non-negative integers are supported
|
||||
*/
|
||||
void certificate_parse_integer(const uint8_t *integer, const uint8_t **outp, uint32_t *outSize, const uint8_t **next_thing, uint32_t* max_size);
|
||||
|
||||
/**
|
||||
* \brief Parse the validity of a certificate
|
||||
* \param[in] *p pointer to the Name Attribute SET to be parsed
|
||||
* \param[out] *notBefore_st pointer to cert_validity_t structure that will be filled with the "not before" date
|
||||
* \param[out] *notAfter_st pointer to cert_validity_t structure that will be filled with the "not after" date
|
||||
* \param[out] **next_thing output pointer to next TLV
|
||||
* \note In this function next_thing can be NULL
|
||||
*/
|
||||
void certificate_parse_validity(const uint8_t *p, cert_validity_t *notBefore_st, cert_validity_t *notAfter_st, const uint8_t **next_thing, uint32_t* max_size);
|
||||
|
||||
/**
|
||||
* \brief Parse an RelativeDistinguishedName
|
||||
* \param[in] *p pointer to the RelativeDistinguishedName (expeting a SET)
|
||||
* \param[out] **nextRDN output pointer to next RDN
|
||||
* \param[out] **attribute output pointer to RDN first attribute
|
||||
*/
|
||||
void certificate_parse_relative_distinguished_name(const uint8_t *p, const uint8_t **nextRDN, const uint8_t **attribute, uint32_t* max_size);
|
||||
|
||||
/**
|
||||
* \brief Parse a Name Attribute
|
||||
* \param[in] *p pointer to the AttributeTypeAndValue SEQUENCE to be parsed
|
||||
* \param[out] *attribute_st pointer to cert_attribute_t structure that will be filled
|
||||
* \param[out] **next_thing output pointer to next TLV
|
||||
*/
|
||||
void certificate_parse_attribute(const uint8_t *p, cert_attribute_t *attribute_st, const uint8_t **next_thing, uint32_t* max_size);
|
||||
|
||||
/**
|
||||
* \brief Compare two cert_validity_t structures
|
||||
* \param[in] *D1 pointer to the first cert_validity_t
|
||||
* \param[in] *D2 pointer to the second cert_validity_t
|
||||
* \return Result of Comparison
|
||||
* \retval -1 D1 < D2
|
||||
* \retval 0 D1 = D2
|
||||
* \retval 1 D1 > D2
|
||||
*/
|
||||
int32_t certificate_date_compare(const cert_validity_t *D1, const cert_validity_t *D2);
|
||||
|
||||
/**
|
||||
* \brief Count the number of Attributes within a NAME
|
||||
* \param[in] *p pointer to the RDNSequence to be parsed
|
||||
* \returun The number of Attributes
|
||||
*/
|
||||
int32_t certificate_count_attributes(const uint8_t *p);
|
||||
|
||||
/**
|
||||
* \brief String Comparison (case insensitive and for utf8)
|
||||
* \param[in] *p1 first string to compare
|
||||
* \param[in] *p2 second string to compare
|
||||
* \param[in] size p1/p2 size
|
||||
* \return result of comparison
|
||||
* \retval -1 strings are different
|
||||
* \retval 0 strings match
|
||||
*/
|
||||
int32_t certificate_case_insensitive_compare(const uint8_t *p1, const uint8_t *p2, int32_t size);
|
||||
|
||||
/**
|
||||
* \brief Identify the Extension from its OID
|
||||
* \param[in] *oid The value of the OID of the Extension (got from \ref certificate_identify_ASN1_TLV )
|
||||
* \param[in] size size (in bytes) of the value field of this OID (got from \ref certificate_identify_ASN1_TLV )
|
||||
* \note Only a very limited set of Extension is supported
|
||||
* \return The internal type identifing the Extension or -1 for failure
|
||||
*/
|
||||
int32_t certificate_case_identify_extension(const uint8_t *oid, int32_t size);
|
||||
|
||||
/**
|
||||
* \brief Parse an x509 Extension
|
||||
* \param[in] *ext pointer to the extension
|
||||
* \param[out] certificate structure
|
||||
* \param[out] *ext_st pointer to an cert_extension_t structure
|
||||
*/
|
||||
void certificate_parse_extension(const uint8_t *ext, certificate_t *certificate, cert_extension_t *ext_st, uint32_t* max_size);
|
||||
|
||||
/**
|
||||
* \brief Reads the value of an INTEGER and returns it as a int32_t
|
||||
* \param[in] *value pointer to the value field of an INTEGER TLV (got from \ref certificate_identify_ASN1_TLV)
|
||||
* \param[in] size size of the integer (got from \ref certificate_identify_ASN1_TLV)
|
||||
* \return the integer value as an int32_t
|
||||
* \warning only non-negative integers are supported
|
||||
*/
|
||||
int32_t certificate_get_small_integer(const uint8_t *value, int32_t size);
|
||||
|
||||
/** \}*/
|
||||
|
||||
#endif /* CERTIFICATE_SUBPARSING_H */
|
||||
@@ -0,0 +1,236 @@
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : custom_uwb.h
|
||||
* @brief : Header for custom_uwb.c file.
|
||||
* This file contains the public declarations for the custom UWB functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _CUSTOM_UWB_H_
|
||||
#define _CUSTOM_UWB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "ACWG_Security.h"
|
||||
|
||||
|
||||
/** @addtogroup BLE_UWB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup UWB_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Initialize UWB session.
|
||||
* Uses for UWB Context and ranging session initialization.
|
||||
* @param ctx Session context.
|
||||
*/
|
||||
void Initiate_uwb_ctx(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Handle UWB time synchronization frame.
|
||||
* Uses to process and apply time sync information for the current UWB session.
|
||||
* @param ctx Session context.
|
||||
*/
|
||||
void Handle_uwb_Time_Sync(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Fill outbound M1 message fields.
|
||||
* Uses to fill UWB M1 message fields:
|
||||
* The first three fields depends of the UWB capabilities.
|
||||
* 1. UWB Configuration Identifier
|
||||
* 2. Pulse Shape Combination
|
||||
* 3. Channel Bitmask
|
||||
* 4. UWB Session Identifier
|
||||
* 5. Vendor Specific attribute is optionally present.
|
||||
* @param ctx Session context.
|
||||
*/
|
||||
void Fill_uwb_M1(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Handle inbound M2 message fields.
|
||||
* Uses to handle UWB M2 message fields:
|
||||
* The first three fields is linked to the same in M1 and represents the device selection,
|
||||
* then the follow fields are session parameters/mask available by device:
|
||||
* 1. UWB Configuration Identifier
|
||||
* 2. Pulse Shape Combination
|
||||
* 3. Channel Bitmask
|
||||
* 4. SYNC Code Index Bitmask
|
||||
* 5. RAN Multiplier
|
||||
* 6. Slot Bitmask
|
||||
* 7. Hopping Configuration Bitmask
|
||||
* 8. Vendor Specific attribute is optionally present.
|
||||
* @param ctx Session context.
|
||||
*/
|
||||
void Handle_uwb_M2(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Fill outbound M3 message fields.
|
||||
* Uses to fill UWB M3 message fields:
|
||||
* The follow fields are session parameters set by the Reader based on M2 content:
|
||||
* 1. RAN Multiplier
|
||||
* 2. Number Chaps per Slot
|
||||
* 3. Number Responders Nodes
|
||||
* 4. Number Slots per Round
|
||||
* 5. SYNC Code Index Bitmask
|
||||
* 6. Hopping Configuration Bitmask
|
||||
* 7. MAC Mode
|
||||
* 8. Vendor Specific attribute is optionally present.
|
||||
* @param ctx Session context.
|
||||
*/
|
||||
void Fill_uwb_M3(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Handle inbound M4 message fields.
|
||||
* Uses to handle UWB M4 message fields.
|
||||
* The follow fields are session parameters set by the device based on M3 content:
|
||||
* 1. STS Index0
|
||||
* 2. UWB Time0
|
||||
* 3. HOP Mode Key
|
||||
* 4. SYNC Code Index
|
||||
* 5. Vendor Specific attribute is optionally present.
|
||||
* @param ctx Session context.
|
||||
*/
|
||||
void Handle_uwb_M4(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Prepare the ranging initialization step.
|
||||
* Called only once after M1/M2/M3/M4 exchange.
|
||||
* @param ctx Session context.
|
||||
*/
|
||||
void Prepare_ranging_init(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Prepare the ranging loop step.
|
||||
* Called repeatedly in the prepare ranging loop until timeout expires.
|
||||
* Uses to setup uwb ranging parameters before starting ranging.
|
||||
* @param ctx Session context.
|
||||
* @param timeout Pointer to timeout in ms. Set to 1 to exit the loop.
|
||||
*/
|
||||
void Prepare_ranging_loop(ACWG_SessionContext_t *ctx, uint32_t *timeout);
|
||||
|
||||
/**
|
||||
* @brief Execute the ranging initialization step.
|
||||
* Called only one time after prepare ranging steps.
|
||||
* Uses to start the UWB ranging .
|
||||
* @param ctx Session context.
|
||||
*/
|
||||
void Execute_ranging_init(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Execute the ranging loop step.
|
||||
* Called repeatedly in the execute ranging loop until timeout expires.
|
||||
* Uses to perform UWB ranging acquisition and evaluate ranging results.
|
||||
* Exiting this loop the Handle_lock_actuation function is called.
|
||||
* @param ctx Session context.
|
||||
* @param timeout Pointer to timeout in ms. Set to 1 to exit the loop.
|
||||
*/
|
||||
void Execute_ranging_loop(ACWG_SessionContext_t *ctx, uint32_t *timeout);
|
||||
|
||||
/**
|
||||
* @brief Close the ranging initialization step.
|
||||
* Called only one time after Handle_lock_actuation.
|
||||
* Uses to stop and deinit UWB ranging session.
|
||||
* @param ctx Session context.
|
||||
*/
|
||||
void Close_ranging_init(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Close the ranging loop step.
|
||||
* Called repeatedly in the close ranging loop until timeout expires.
|
||||
* @param ctx Session context.
|
||||
* @param timeout Pointer to timeout in ms. Set to 1 to exit the loop.
|
||||
*/
|
||||
void Close_ranging_loop(ACWG_SessionContext_t *ctx, uint32_t *timeout);
|
||||
|
||||
/**
|
||||
* @brief Suspend the ranging initialization step.
|
||||
* Called only one time after suspend response or suspend event in ranging session.
|
||||
* Uses to stop UWB ranging session.
|
||||
* @param ctx Session context.
|
||||
*/
|
||||
void Suspend_ranging_init(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Suspend the ranging loop step.
|
||||
* Called repeatedly in the suspend ranging loop until timeout expires.
|
||||
* @param ctx Session context.
|
||||
* @param timeout Pointer to timeout in ms. Set to 1 to exit the loop.
|
||||
*/
|
||||
void Suspend_ranging_loop(ACWG_SessionContext_t *ctx, uint32_t *timeout);
|
||||
|
||||
/**
|
||||
* @brief Resume the ranging initialization step.
|
||||
* Called only one time after resume response in ranging session.
|
||||
* Uses to set new Time0 and SlotIndex0 in UWB ranging session.
|
||||
* @param ctx Session context.
|
||||
*/
|
||||
void Resume_ranging_init(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Resume the ranging loop step.
|
||||
* Called repeatedly in the resume ranging loop until timeout expires.
|
||||
* After exiting this loop the Execute_ranging_init function is called.
|
||||
* @param ctx Session context.
|
||||
* @param timeout Pointer to timeout in ms. Set to 1 to exit the loop.
|
||||
*/
|
||||
void Resume_ranging_loop(ACWG_SessionContext_t *ctx, uint32_t *timeout);
|
||||
|
||||
/**
|
||||
* @brief Handle and evaluate distance results.
|
||||
* Called only one time during preparing Reader Status Exchange frame.
|
||||
* Uses to notify if distance allowed to open the lock.
|
||||
* @param ctx Session context.
|
||||
* @return 1 if distance allowed to open lock, 0 otherwise.
|
||||
*/
|
||||
uint8_t Handle_distance_result(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Trigger lock actuation based on session state.
|
||||
* Called only one time after Execute_ranging_loop.
|
||||
* Uses to actuate the lock based on distance result evaluation.
|
||||
* @param ctx Session context.
|
||||
*/
|
||||
void Handle_lock_actuation(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Initialize UWB hardware.
|
||||
* Uses for UWB hardware initialization, called only one time at startup.
|
||||
*/
|
||||
void UWB_HW_init( void );
|
||||
|
||||
/**
|
||||
* @brief Run periodic UWB hardware tasks.
|
||||
* Uses for periodic UWB hardware tasks, called repeatedly in main loop.
|
||||
*/
|
||||
void UWB_HW_loop( void );
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CUSTOM_UWB_H_ */
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : flash_mng.h
|
||||
* @brief : Header for flash_mng.c file.
|
||||
* This file declares the Flash management API used by the Aliro application (erase/write helpers).
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _FLASH_MNG_H_
|
||||
#define _FLASH_MNG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup FLASH_MNG
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "app_nfc.h"
|
||||
//#include "utils.h"
|
||||
#include "main.h"
|
||||
|
||||
/** @addtogroup Flash_mng_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @enum flashOpStatus_e
|
||||
* @brief Status codes for flash operations.
|
||||
*/
|
||||
typedef enum _flashOpStatus
|
||||
{
|
||||
FLASH_OP_OK, /**< Operation successful */
|
||||
FLASH_OP_BUSY, /**< Flash is busy */
|
||||
FLASH_OP_ERROR /**< Operation failed */
|
||||
}
|
||||
flashOpStatus_e;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Flash_mng_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Writes data to flash memory.
|
||||
* @param data Pointer to the data to write.
|
||||
* @param nBytes Number of bytes to write.
|
||||
* @param nAddress Destination address in flash.
|
||||
* @return Status of the operation.
|
||||
*/
|
||||
flashOpStatus_e WriteToFlash(void *data, uint32_t nBytes, uint32_t nAddress);
|
||||
|
||||
/**
|
||||
* @brief Erases the flash sector and writes data to it.
|
||||
* @param data Pointer to the data to write.
|
||||
* @param nBytes Number of bytes to write.
|
||||
* @param nAddress Destination address in flash.
|
||||
* @return Status of the operation.
|
||||
*/
|
||||
flashOpStatus_e EraseWriteToFlash(void *data, uint32_t nBytes, uint32_t nAddress);
|
||||
|
||||
/**
|
||||
* @brief Erases a region of flash memory.
|
||||
* @param nAddress Start address of the region to erase.
|
||||
* @param nBytes Number of bytes to erase.
|
||||
* @return Status of the operation.
|
||||
*/
|
||||
flashOpStatus_e EraseFlash(uint32_t nAddress, uint32_t nBytes);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLASH_MNG_H_ */
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : log_module_u5.h
|
||||
* @brief : Header for log_module_u5.c file.
|
||||
* Provides logging macros and prototypes for the U5 platform.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _LOG_MODULE_U5_H_
|
||||
#define _LOG_MODULE_U5_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "st_errno.h"
|
||||
|
||||
/** @addtogroup NFCBLE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup log_module_u5_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
typedef uint8_t Log_Verbose_Level_t;
|
||||
typedef uint8_t Log_Region_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup log_module_u5_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @def LOG_INFO_APP
|
||||
* @brief Macro for logging information messages in the application.
|
||||
* @param ... Arguments to be printed using DBG_PRINTF.
|
||||
*/
|
||||
#define LOG_INFO_APP(...) do{Log_Module_Print(0,0,__VA_ARGS__);}while(0)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LOG_MODULE_U5_H_ */
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : log_module_u5.h
|
||||
* @brief : Header for log_module_u5.c file.
|
||||
* Provides logging macros and prototypes for the U5 platform.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _LOG_MODULE_U5_H_
|
||||
#define _LOG_MODULE_U5_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "st_errno.h"
|
||||
|
||||
/** @addtogroup NFCBLE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup log_module_u5_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
typedef uint8_t Log_Verbose_Level_t;
|
||||
typedef uint8_t Log_Region_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup log_module_u5_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @def LOG_INFO_APP
|
||||
* @brief Macro for logging information messages in the application.
|
||||
* @param ... Arguments to be printed using DBG_PRINTF.
|
||||
*/
|
||||
#define LOG_INFO_APP(...) do{Log_Module_Print(0,0,__VA_ARGS__);}while(0)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LOG_MODULE_U5_H_ */
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,284 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : provisioning.h
|
||||
* @brief : Header for provisioning module.
|
||||
* This file contains the common defines and structures for provisioning.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _PROVISIONING_H_
|
||||
#define _PROVISIONING_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup PROVISIONING_MNG
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "ACWG_Security.h"
|
||||
#include "stdbool.h"
|
||||
#include "provisioning_info.h"
|
||||
|
||||
/** @addtogroup Provisioning_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @def PRIVATE_KEY_SIZE_BYTES
|
||||
* @brief Size of private key in bytes.
|
||||
*/
|
||||
#define PRIVATE_KEY_SIZE_BYTES ((uint32_t)32)
|
||||
/**
|
||||
* @def AUTH_PUBKEY_LEN_BYTES
|
||||
* @brief Length of authentication public key in bytes.
|
||||
*/
|
||||
#define AUTH_PUBKEY_LEN_BYTES ((uint32_t)64)
|
||||
/**
|
||||
* @def GROUP_RESOLVING_KEY_SIZE_BYTES
|
||||
* @brief Size of group resolving key in bytes.
|
||||
*/
|
||||
#define GROUP_RESOLVING_KEY_SIZE_BYTES ((uint32_t)16)
|
||||
/**
|
||||
* @def DEVICE_NAME_SIZE_BYTES
|
||||
* @brief Size of device name in bytes.
|
||||
*/
|
||||
#define DEVICE_NAME_SIZE_BYTES ((uint32_t)16)
|
||||
/**
|
||||
* @def B1_VENDOR_SPEC_EXT_SIZE_BYTES
|
||||
* @brief Size of vendor specific extension in bytes.
|
||||
*/
|
||||
#define B1_VENDOR_SPEC_EXT_SIZE_BYTES ((uint32_t)64)
|
||||
/**
|
||||
* @def RESERVED_PAIRING_KEYS_SIZE_BYTES
|
||||
* @brief Size of buffer in bytes reserved for future use .
|
||||
*/
|
||||
#define RESERVED_PAIRING_KEYS_SIZE_BYTES ((uint32_t)32)
|
||||
/**
|
||||
* @def CERTIFICATE_SIZE
|
||||
* @brief Size of certificate data in bytes.
|
||||
*/
|
||||
#define CERTIFICATE_SIZE ((uint32_t)400)
|
||||
|
||||
/**
|
||||
* @def NUM_PROV_DEVICES
|
||||
* @brief Maximum number of provisioned devices.
|
||||
*/
|
||||
#define NUM_PROV_DEVICES 5
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Provisioning_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
/* Exported variables ------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Provisioning_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @struct devices_t
|
||||
* @brief Structure representing a provisioned device.
|
||||
*/
|
||||
typedef struct devices_s
|
||||
{
|
||||
uint8_t name[DEVICE_NAME_SIZE_BYTES]; /**< Device name */
|
||||
uint8_t endpoint_Keyslot[AUTH_KEYSLOT_LEN_BYTES]; /**< Endpoint keyslot */
|
||||
uint8_t endpoint_PubK[AUTH_PUBKEY_LEN_BYTES]; /**< Endpoint public key */
|
||||
uint8_t endpoint_PrivK[PRIVATE_KEY_SIZE_BYTES]; /**< Endpoint private key */
|
||||
}devices_t;
|
||||
|
||||
|
||||
/**
|
||||
* @struct provstruct_t
|
||||
* @brief Structure representing the provisioning data.
|
||||
*/
|
||||
typedef struct provstruct_s
|
||||
{
|
||||
uint32_t isValid; /**< Validity flag */
|
||||
uint8_t readerID[AUTH_READER_GROUP_ID_LEN_BYTES + AUTH_READER_GROUP_SUB_ID_LEN_BYTES]; /**< Reader ID */
|
||||
uint8_t readerPubK[AUTH_PUBKEY_LEN_BYTES]; /**< Reader public key */
|
||||
uint8_t staticPrivateKey[PRIVATE_KEY_SIZE_BYTES]; /**< Static private key */
|
||||
uint8_t group_resolving_key[GROUP_RESOLVING_KEY_SIZE_BYTES]; /**< Group resolving key */
|
||||
uint8_t certificate_data[CERTIFICATE_SIZE]; /**< Certificate data */
|
||||
uint32_t certificate_len; /**< Certificate length */
|
||||
uint8_t readerIssuerPubK[AUTH_PUBKEY_LEN_BYTES]; /**< Reader issuer public key */
|
||||
uint8_t b1VendorSpecificExtension[B1_VENDOR_SPEC_EXT_SIZE_BYTES]; /**< Vendor specific extension */
|
||||
uint32_t b1VendorSpecificExtensionLen; /**< Vendor specific extension length */
|
||||
uint32_t numDevices; /**< Number of devices */
|
||||
devices_t devices[NUM_PROV_DEVICES]; /**< Array of provisioned devices */
|
||||
uint32_t isValidReserved; /**< RESERVED validity flag */
|
||||
uint8_t reservedPairingKeys[RESERVED_PAIRING_KEYS_SIZE_BYTES]; /**< RESERVED pairing keys */
|
||||
uint32_t struct_size; /**< Structure size */
|
||||
}provstruct_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Provisioning_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Shows the status of the JSON provisioning data.
|
||||
*/
|
||||
void showJsonStatus();
|
||||
|
||||
/**
|
||||
* @brief Shows the status of the provisioning data.
|
||||
*/
|
||||
void showProvisioningStatus();
|
||||
|
||||
/**
|
||||
* @brief Saves the provisioning data to flash memory.
|
||||
* @param profile_num Profile number to save.
|
||||
*/
|
||||
void saveProvisioningToFlash(uint32_t profile_num);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the provisioning data from flash memory.
|
||||
* @return Pointer to the provisioning structure.
|
||||
*/
|
||||
provstruct_t* getProvisioningFromFlash();
|
||||
|
||||
/**
|
||||
* @brief Loads provisioning data from a JSON address.
|
||||
* @param jsonAddress Address of the JSON data.
|
||||
* @param provstruct Pointer to the provisioning structure to fill.
|
||||
*/
|
||||
void loadProvisionFromJson(uint32_t jsonAddress, provstruct_t*provstruct);
|
||||
|
||||
/**
|
||||
* @brief Converts provisioning data from JSON format.
|
||||
* @param jsonAddress Address of the JSON data.
|
||||
*/
|
||||
void convertProvisioningFromJson(uint32_t jsonAddress);
|
||||
|
||||
/**
|
||||
* @brief Converts default provisioning data from JSON format.
|
||||
*/
|
||||
void convertDefaultProvisioningFromJson();
|
||||
|
||||
/**
|
||||
* @brief Prints the device JSON data.
|
||||
*/
|
||||
void printDeviceJson();
|
||||
|
||||
/**
|
||||
* @brief Prints the script JSON data.
|
||||
*/
|
||||
void printScriptJson();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Saves the reader public key to flash memory.
|
||||
* @param pkey Pointer to the public key.
|
||||
* @param ksize Size of the key.
|
||||
*/
|
||||
void saveRDPubKToFlash(const uint8_t *pkey, const uint8_t ksize);
|
||||
|
||||
/**
|
||||
* @brief Saves the reader private key to flash memory.
|
||||
* @param pkey Pointer to the private key.
|
||||
* @param ksize Size of the key.
|
||||
*/
|
||||
void saveRDPrvKToFlash(const uint8_t *pkey, const uint8_t ksize);
|
||||
|
||||
/**
|
||||
* @brief Saves the reader identity to flash memory.
|
||||
* @param pkey Pointer to the identity data.
|
||||
* @param ksize Size of the identity data.
|
||||
*/
|
||||
void saveRDidenToFlash(const uint8_t *pkey, const uint8_t ksize);
|
||||
|
||||
/**
|
||||
* @brief Saves the reader group resolving key to flash memory.
|
||||
* @param pkey Pointer to the group resolving key.
|
||||
* @param ksize Size of the key.
|
||||
*/
|
||||
void saveRDgrrkToFlash(const uint8_t *pkey, const uint8_t ksize);
|
||||
|
||||
/**
|
||||
* @brief Saves the credential issuer public key to flash memory.
|
||||
* @param pkey Pointer to the credential issuer public key.
|
||||
* @param ksize Size of the public key.
|
||||
*/
|
||||
void saveCredIsPkToFlash(const uint8_t *pkey, const uint8_t ksize);
|
||||
|
||||
/**
|
||||
* @brief Saves the access credential public key.
|
||||
* @param last_pkey Pointer to the last public key.
|
||||
* @param ksize Size of the key.
|
||||
* @param nSlot Slot number.
|
||||
*/
|
||||
void saveAccessCredentialPuBK(uint8_t *pkey, const uint8_t ksize, uint8_t nSlot, uint8_t *pkeyname);
|
||||
|
||||
/**
|
||||
* @brief Checks if a buffer contains only zeros.
|
||||
* @param pBuf Pointer to the buffer.
|
||||
* @param nSize Size of the buffer.
|
||||
* @return 1 if all zeros, 0 otherwise.
|
||||
*/
|
||||
uint8_t is_zeros(uint8_t* pBuf, uint32_t nSize);
|
||||
|
||||
/**
|
||||
* @brief Checks the endpoint public key for provisioning.
|
||||
* @param endp_PubK Pointer to the endpoint public key.
|
||||
* @return Status code.
|
||||
*/
|
||||
uint8_t ProvisioningCheckEndpointPubK(uint8_t *endp_PubK);
|
||||
|
||||
/**
|
||||
* @brief Gets the endpoint public key from a keyslot.
|
||||
* @param endp_PubK Pointer to the endpoint public key.
|
||||
* @param endp_Keyslot Pointer to the endpoint keyslot.
|
||||
* @param slotFound Pointer to the found slot.
|
||||
* @return Status code.
|
||||
*/
|
||||
uint8_t ProvisioningGetEndpointPubKFromKeyslot(uint8_t *endp_PubK, uint8_t *endp_Keyslot, uint8_t*slotFound);
|
||||
|
||||
/**
|
||||
* @brief Converts a hex string to a hex buffer.
|
||||
* @param p Pointer to the hex string.
|
||||
* @param len Length of the string.
|
||||
* @param hexp Pointer to the hex buffer.
|
||||
*/
|
||||
void hexStrToHex(char *p, uint32_t len, uint8_t *hexp);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //_PROVISIONING_H_
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : provisioning_info.h
|
||||
* @brief : Provisioning information and configuration defines for the application.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _PROVISIONING_INFO_H_
|
||||
#define _PROVISIONING_INFO_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup PROVISIONING_MNG
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup Provisioning_info_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/**
|
||||
* @def ALIRO_APP_NAME
|
||||
* @brief Application name string.
|
||||
*/
|
||||
#define ALIRO_APP_NAME "TruELock"
|
||||
/**
|
||||
* @def DEFAULT_CMD_PARAMS_VALUE
|
||||
* @brief Default command parameters value (0 = Standard, 1 = Fast).
|
||||
*/
|
||||
#define DEFAULT_CMD_PARAMS_VALUE 0
|
||||
|
||||
/**
|
||||
* @def NFC_PROP_BUF_CONTENT
|
||||
* @brief Default NFC property buffer content.
|
||||
*/
|
||||
#define NFC_PROP_BUF_CONTENT { 0 }
|
||||
/**
|
||||
* @def BLE_ADV_DISABLE
|
||||
* @brief Disable BLE advertising (0 = enabled).
|
||||
*/
|
||||
#define BLE_ADV_DISABLE 0
|
||||
/**
|
||||
* @def ALIRO_NFC_TOTAL_DURATION
|
||||
* @brief Total duration for NFC operations in milliseconds.
|
||||
*/
|
||||
#define ALIRO_NFC_TOTAL_DURATION 1000U
|
||||
/**
|
||||
* @def TEST_HARNESS_SIMULATION
|
||||
* @brief Enable test harness simulation (0 = disabled).
|
||||
*/
|
||||
#define TEST_HARNESS_SIMULATION 0
|
||||
/**
|
||||
* @def ALIRO_PROT_VER
|
||||
* @brief Defines the default Aliro protocol versions supported for authentication and transport.
|
||||
*/
|
||||
#define ALIRO_PROT_VER_DEFAULT ( AUTH_EXP_TRANS_PROT_VERSION )
|
||||
|
||||
/**
|
||||
* @def ALIRO_PROT_VER
|
||||
* @brief Defines the Aliro protocol versions supported for authentication and transport.
|
||||
*/
|
||||
#define ALIRO_PROT_VER xProtocolVersionSupported
|
||||
|
||||
/**
|
||||
* @def ALIRO_MAIN_PROT_VER
|
||||
* @brief Main protocol version (lower 16 bits).
|
||||
*/
|
||||
#define ALIRO_MAIN_PROT_VER (ALIRO_PROT_VER & 0xffff)
|
||||
/**
|
||||
* @def ALIRO_HAS_SEC_PROT_VER
|
||||
* @brief Check if secondary protocol version is present.
|
||||
*/
|
||||
#define ALIRO_HAS_SEC_PROT_VER ((ALIRO_PROT_VER&0xFFFF0000)?(1):(0))
|
||||
/**
|
||||
* @def ALIRO_SEC_PROT_VER
|
||||
* @brief Secondary protocol version (upper 16 bits).
|
||||
*/
|
||||
#define ALIRO_SEC_PROT_VER ((ALIRO_PROT_VER&0xFFFF0000)>>16)
|
||||
/**
|
||||
* @def DEVICE_PROVISIONING_STRUCT_IS_VALID
|
||||
* @brief Magic value indicating a valid device provisioning structure.
|
||||
*/
|
||||
#define DEVICE_PROVISIONING_STRUCT_IS_VALID 0xA5A55A5A
|
||||
/**
|
||||
* @def EXPIRY_TIME_STAMP_DEFAULT_VALUE
|
||||
* @brief Default expiry timestamp value.
|
||||
*/
|
||||
#define EXPIRY_TIME_STAMP_DEFAULT_VALUE 0x76100fe0
|
||||
|
||||
/** @} */ // end of Provisioning_info_Constants
|
||||
|
||||
/** @addtogroup Provisioning_info_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/**
|
||||
* @def DISPLAY_SPLASH
|
||||
* @brief Macro to display splash screen.
|
||||
*/
|
||||
#define DISPLAY_SPLASH()
|
||||
/**
|
||||
* @def LOAD_NFC_PROP
|
||||
* @brief Macro to load NFC properties.
|
||||
*/
|
||||
#define LOAD_NFC_PROP()
|
||||
/**
|
||||
* @def DET_NFC_PROP
|
||||
* @brief Macro to detect NFC properties.
|
||||
*/
|
||||
#define DET_NFC_PROP()
|
||||
/**
|
||||
* @def INIT_NFC_PROP
|
||||
* @brief Macro to initialize NFC properties.
|
||||
*/
|
||||
#define INIT_NFC_PROP()
|
||||
|
||||
/**
|
||||
* @def UWB_SESSION_ID_DEFAULT
|
||||
* @brief Default UWB session ID value.
|
||||
*/
|
||||
#define UWB_SESSION_ID_DEFAULT getUwbSessionId()
|
||||
|
||||
/** @} */ // end of Provisioning_info_Macros
|
||||
|
||||
/** @addtogroup Provisioning_info_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "User_provisioning.h"
|
||||
|
||||
/** @} */ // end of Provisioning_info_Includes
|
||||
|
||||
/** @} */ // end of PROVISIONING
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //_PROVISIONING_INFO_H_
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,249 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : sm_crypto.h
|
||||
* @brief : Header for sm_crypto.c file.
|
||||
* This file provides the interface for SM cryptographic operations.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _SM_CRYPTO_H_
|
||||
#define _SM_CRYPTO_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup MCU_CRYPTO
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
|
||||
/** @addtogroup SM_Crypto_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @def RAW_PRIV_KEY_BYTE_SIZE
|
||||
* @brief Size of raw private key in bytes.
|
||||
*/
|
||||
#define RAW_PRIV_KEY_BYTE_SIZE ((uint32_t)32)
|
||||
/**
|
||||
* @def SHA256_BYTE_SIZE
|
||||
* @brief Size of SHA-256 hash in bytes.
|
||||
*/
|
||||
#define SHA256_BYTE_SIZE ((uint32_t)32)
|
||||
/**
|
||||
* @def ECDSA_256_SIG_BYTE_SIZE
|
||||
* @brief Size of ECDSA-256 signature in bytes.
|
||||
*/
|
||||
#define ECDSA_256_SIG_BYTE_SIZE ((uint32_t)64)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup SM_Crypto_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @enum SM_Crypto_Error_t
|
||||
* @brief Error codes for SM cryptographic operations.
|
||||
*/
|
||||
typedef enum {
|
||||
SM_Crypto_OK = 0, /**< Operation successful */
|
||||
SM_Crypto_Error, /**< General error */
|
||||
SM_Crypto_HW_Error /**< Hardware error */
|
||||
} SM_Crypto_Error_t;
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup SM_Crypto_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Initializes the cryptographic module.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_init(void);
|
||||
|
||||
/**
|
||||
* @brief Generates random bytes.
|
||||
* @param bytes Pointer to output buffer.
|
||||
* @param size Number of bytes to generate.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_genRandomBytes(uint8_t *bytes, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Generates a keypair and returns the public key.
|
||||
* @param pub Pointer to output public key buffer.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_genKeypair(uint8_t *pub);
|
||||
|
||||
/**
|
||||
* @brief Key Derivation Function RFC5869.
|
||||
* @param pZ Input keying material.
|
||||
* @param ZSize Size of input keying material.
|
||||
* @param pSalt Pointer to salt.
|
||||
* @param saltSize Size of salt.
|
||||
* @param pFixedInfo Pointer to fixed info.
|
||||
* @param fixedInfoSize Size of fixed info.
|
||||
* @param L Length of output keying material.
|
||||
* @param pOutput Pointer to output buffer.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_KDFRFC5869(const uint8_t* pZ, uint32_t ZSize,
|
||||
const uint8_t* pSalt, uint32_t saltSize,
|
||||
const uint8_t* pFixedInfo, uint32_t fixedInfoSize,
|
||||
uint32_t L, uint8_t* pOutput);
|
||||
|
||||
/**
|
||||
* @brief Computes SHA-1 hash.
|
||||
* @param input Pointer to input data.
|
||||
* @param inputSize Size of input data.
|
||||
* @param hash Pointer to output hash buffer.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_sha1(uint8_t *input, uint32_t inputSize, uint8_t *hash);
|
||||
|
||||
/**
|
||||
* @brief Computes SHA-256 hash.
|
||||
* @param input Pointer to input data.
|
||||
* @param inputSize Size of input data.
|
||||
* @param hash Pointer to output hash buffer.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_sha256(uint8_t *input, uint32_t inputSize, uint8_t *hash);
|
||||
|
||||
/**
|
||||
* @brief Starts SHA-256 computation.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_sha256_start(void);
|
||||
|
||||
/**
|
||||
* @brief Updates SHA-256 computation with new data.
|
||||
* @param input Pointer to input data.
|
||||
* @param inputSize Size of input data.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_sha256_update(const uint8_t *input, uint32_t inputSize);
|
||||
|
||||
/**
|
||||
* @brief Finishes SHA-256 computation and returns the hash.
|
||||
* @param hash Pointer to output hash buffer.
|
||||
* @param input Pointer to input data.
|
||||
* @param inputSize Size of input data.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_sha256_finish(uint8_t *hash, const uint8_t *input, uint32_t inputSize);
|
||||
|
||||
/**
|
||||
* @brief Signs data using ECDSA.
|
||||
* @param tbs Pointer to data to be signed.
|
||||
* @param tbsSize Size of data to be signed.
|
||||
* @param signature Pointer to output signature buffer.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_sign(const uint8_t *tbs, uint32_t tbsSize, uint8_t *signature);
|
||||
|
||||
/**
|
||||
* @brief Performs ECDH key agreement.
|
||||
* @param pPublicKey Pointer to public key.
|
||||
* @param pSharedSecret Pointer to output shared secret.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_Ecdh(const uint8_t *pPublicKey, uint8_t *pSharedSecret);
|
||||
|
||||
/**
|
||||
* @brief Derives KDH key.
|
||||
* @param pZ Pointer to input keying material.
|
||||
* @param info Pointer to info data.
|
||||
* @param infoSize Size of info data.
|
||||
* @param pKdh Pointer to output KDH key.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_deriveKdh(const uint8_t *pZ, const uint8_t * info, uint32_t infoSize, uint8_t *pKdh);
|
||||
|
||||
/**
|
||||
* @brief Decrypts data using AES-256 GCM.
|
||||
* @param pKey Pointer to key.
|
||||
* @param pNonce Pointer to nonce.
|
||||
* @param pAad Pointer to additional authenticated data.
|
||||
* @param aadSize Size of AAD.
|
||||
* @param pPayload Pointer to encrypted payload.
|
||||
* @param payloadSize Size of payload.
|
||||
* @param pPlaintext Pointer to output plaintext buffer.
|
||||
* @param pTag Pointer to authentication tag.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_aes256GcmDecrypt(const uint8_t* pKey, const uint8_t* pNonce, const uint8_t* pAad, const uint32_t aadSize,
|
||||
const uint8_t* pPayload, const uint32_t payloadSize, uint8_t* pPlaintext, const uint8_t* pTag);
|
||||
|
||||
/**
|
||||
* @brief Encrypts data using AES-256 GCM.
|
||||
* @param pKey Pointer to key.
|
||||
* @param pNonce Pointer to nonce.
|
||||
* @param pAad Pointer to additional authenticated data.
|
||||
* @param aadSize Size of AAD.
|
||||
* @param pInput Pointer to input data.
|
||||
* @param inputSize Size of input data.
|
||||
* @param pOutput Pointer to output buffer.
|
||||
* @param pOutputSize Pointer to output size.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_aes256GcmEncrypt(const uint8_t* pKey, const uint8_t* pNonce, const uint8_t* pAad, const uint32_t aadSize,
|
||||
const uint8_t* pInput, const uint32_t inputSize, uint8_t* pOutput, uint32_t* pOutputSize);
|
||||
|
||||
/**
|
||||
* @brief Verifies a signature using ECDSA.
|
||||
* @param pPublicKey Pointer to public key.
|
||||
* @param tbs Pointer to data to be verified.
|
||||
* @param tbsSize Size of data to be verified.
|
||||
* @param signature Pointer to signature.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_verify(const uint8_t *pPublicKey, const uint8_t *tbs, const uint32_t tbsSize, const uint8_t *signature);
|
||||
|
||||
/**
|
||||
* @brief Gets the certificate.
|
||||
* @param certificate Pointer to output certificate buffer.
|
||||
* @param certificateSize Pointer to output certificate size.
|
||||
* @return Error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_getCertificate(uint8_t *certificate, uint32_t *certificateSize);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SM_CRYPTO_H_
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : sm_crypto_mcu.h
|
||||
* @brief : Header for sm_crypto_mcu.c file.
|
||||
* This file provides the interface for SM cryptographic operations on MCU platforms.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _SM_CRYPTO_MCU_H_
|
||||
#define _SM_CRYPTO_MCU_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup MCU_CRYPTO
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "sm_crypto.h"
|
||||
#if defined(STM32U545xx) || defined(STM32U585xx)
|
||||
#include "stm32u5xx_hal.h"
|
||||
#elif defined(STM32U385xx)
|
||||
#include "stm32u3xx_hal.h"
|
||||
#elif defined(STM32WBA52xx) || defined(STM32WBA55xx) || defined(STM32WBA65xx)
|
||||
#include "stm32wbaxx_hal.h"
|
||||
#else
|
||||
#error "product not supported"
|
||||
#endif
|
||||
|
||||
/** @addtogroup SM_crypto_mcu_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/**
|
||||
* @def MAX_FIXED_INFO_SIZE
|
||||
* @brief Maximum size for fixed info buffer in bytes.
|
||||
*/
|
||||
#define MAX_FIXED_INFO_SIZE ((uint32_t)256)
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup SM_crypto_mcu_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Initializes cryptographic hardware modules for MCU.
|
||||
* @param rng Pointer to RNG handle.
|
||||
* @param pka Pointer to PKA handle.
|
||||
* @param hash Pointer to HASH handle.
|
||||
* @param cryp Pointer to CRYP handle.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_initCryptoMCU(RNG_HandleTypeDef *rng, PKA_HandleTypeDef *pka, HASH_HandleTypeDef *hash, CRYP_HandleTypeDef *cryp);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SM_CRYPTO_MCU_H_
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : sm_crypto_stsafe.h
|
||||
* @brief : Header for sm_crypto_stsafe.c file.
|
||||
* This file provides the interface for SM cryptographic operations using STSAFE.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _SM_CRYPTO_STSAFE_H_
|
||||
#define _SM_CRYPTO_STSAFE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup MCU_CRYPTO
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "sm_crypto.h"
|
||||
#if defined(STM32U585xx)
|
||||
#include "stm32u5xx_hal.h"
|
||||
#elif defined(STM32WBA52xx) || defined(STM32WBA65xx)
|
||||
#include "stm32wbaxx_hal.h"
|
||||
#else
|
||||
#error "product not supported"
|
||||
#endif
|
||||
#include "stselib.h"
|
||||
|
||||
/** @addtogroup SM_crypto_stsafe_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Initializes cryptographic operations using STSAFE.
|
||||
* @param pairingdone Pointer to a flag indicating if pairing is done.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_initCryptoStSafe(uint8_t *pairingdone);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SM_CRYPTO_STSAFE_H_
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : stepup_mgr.h
|
||||
* @brief : Header for stepup_mgr.c file.
|
||||
* This file declares the interface for the step-up manager functionality.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STEPUP_MGR_H
|
||||
#define __STEPUP_MGR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup STEPUP_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "ACWG_Security.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
/** @addtogroup STEPUP_MGR_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
//typedef struct _access_mngr_data
|
||||
//{
|
||||
// uint8_t access_credential_PuBK_last[64];
|
||||
//}
|
||||
//access_mngr_data_t;
|
||||
//
|
||||
//extern access_mngr_data_t access_mngr_data;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STEPUP_MGR_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STEPUP_MGR_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STEPUP_MGR_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STEPUP_MGR_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Requests a step-up operation.
|
||||
* @param acwgctx Pointer to the session context.
|
||||
* @param buf Pointer to the buffer for request data.
|
||||
* @param len Pointer to the length of the buffer.
|
||||
* @return Status code.
|
||||
*/
|
||||
uint8_t stepup_request(ACWG_SessionContext_t *acwgctx, uint8_t *stringAccElem, uint32_t AccElemLen, uint8_t *stringRevElem, uint32_t RevElemLen, uint8_t *buf, uint32_t *len);
|
||||
|
||||
/**
|
||||
* @brief Pushes step-up data to the buffer.
|
||||
* @param buf Pointer to the data buffer.
|
||||
* @param len Length of the data.
|
||||
* @return Status code.
|
||||
*/
|
||||
uint8_t stepup_pushdata(uint8_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Processes the step-up operation.
|
||||
* @param acwgctx Pointer to the session context.
|
||||
* @return Status code.
|
||||
*/
|
||||
uint8_t stepup_process(ACWG_SessionContext_t *acwgctx);
|
||||
|
||||
/**
|
||||
* @brief Checks the endpoint public key for step-up.
|
||||
* @param endp_PubK Pointer to the endpoint public key.
|
||||
* @return Status code.
|
||||
*/
|
||||
uint8_t stepup_CheckEndpointPubK(uint8_t *endp_PubK);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STEPUP_MGR_H */
|
||||
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : tlv.h
|
||||
* @brief : Header for TLV (Tag-Length-Value) utilities.
|
||||
* This file contains type definitions and function
|
||||
* prototypes for TLV operations.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _TLV_H_
|
||||
#define _TLV_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup TLV_UTILITIES
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/** @addtogroup TLV_Utilities_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/**
|
||||
* @struct tlv_t
|
||||
* @brief Structure representing a TLV (Tag-Length-Value) element.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t tag; /**< Tag identifier */
|
||||
uint8_t *value; /**< Pointer to value data */
|
||||
uint32_t length; /**< Length of value data */
|
||||
} tlv_t;
|
||||
|
||||
|
||||
/**
|
||||
* @enum tlvStatus_t
|
||||
* @brief Status codes for TLV operations.
|
||||
*/
|
||||
typedef enum {
|
||||
TLV_SUCCESS, /**< Operation successful */
|
||||
TLV_ERROR_SHORT_PAYLOAD, /**< Payload too short */
|
||||
TLV_ERROR_INVALID_LENGTH, /**< Invalid length */
|
||||
TLV_ERROR_SHORT_BUFFER, /**< Buffer too short */
|
||||
TLV_ERROR_TAG_NOT_FOUND /**< Tag not found */
|
||||
} tlvStatus_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup TLV_Utilities_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
/**
|
||||
* @brief Extracts one TLV element from a buffer.
|
||||
* @param tlvBuf Pointer to the buffer pointer.
|
||||
* @param tlvLength Pointer to the buffer length.
|
||||
* @param tlv Pointer to the TLV structure to fill.
|
||||
* @return Status code.
|
||||
*/
|
||||
tlvStatus_t getOneTlv(uint8_t **tlvBuf, uint32_t *tlvLength, tlv_t *tlv);
|
||||
|
||||
/**
|
||||
* @brief Appends a TLV element to a buffer.
|
||||
* @param inputBuffer Pointer to the buffer pointer.
|
||||
* @param inputBufferLen Pointer to the buffer length.
|
||||
* @param tlv Pointer to the TLV structure to append.
|
||||
* @return Status code.
|
||||
*/
|
||||
tlvStatus_t appendTLV(uint8_t **inputBuffer, uint32_t *inputBufferLen, const tlv_t *tlv);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TLV_H_ */
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,550 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : tlwrapper.h
|
||||
* @brief : Header for tlwrapper.c file.
|
||||
* This file contains the type definitions and function
|
||||
* prototypes for the tlwrapper module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __TLWRAPPER_H
|
||||
#define __TLWRAPPER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "ACWG_Security.h"
|
||||
#include "stdbool.h"
|
||||
#include "custom_uwb.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup WRAPPER_UTILITY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TLWrapper_Utils_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @enum tlw_error_e
|
||||
* @brief Error codes for TLWrapper operations.
|
||||
*/
|
||||
typedef enum _tlw_error
|
||||
{
|
||||
TLW_ERROR_NONE = 0, /**< No error */
|
||||
TLW_NEW_OUTPUT, /**< New output available */
|
||||
TLW_NO_PREPARE_NEEDED, /**< No preparation needed */
|
||||
TLW_ERROR_FAST, /**< Fast error */
|
||||
TLW_NEED_GET_RESPONSE, /**< Need to get response */
|
||||
TLW_NEED_AUTH1, /**< Need authentication 1 */
|
||||
TLW_NEED_LOAD_CERT, /**< Need to load certificate */
|
||||
TLW_BUSY, /**< Busy state */
|
||||
TLW_FAIL_GENERATE, /**< Generation failed */
|
||||
TLW_FAIL_PROCESS, /**< Processing failed */
|
||||
TLW_FAIL_GENERIC, /**< Generic failure */
|
||||
TLW_FAIL_TIMEOUT, /**< Timeout failure */
|
||||
TLW_END /**< End of error codes */
|
||||
}
|
||||
tlw_error_e;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup NFC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TLWrapper_Nfc_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @enum tlw_state_nfc_e
|
||||
* @brief NFC state machine states for TLWrapper.
|
||||
*/
|
||||
typedef enum _tlw_state_nfc
|
||||
{
|
||||
TLW_STATE_NFC_PREPARE_SELECT = 0,
|
||||
TLW_STATE_NFC_PROCESS_SELECT,
|
||||
TLW_STATE_NFC_PREPARE_AUTH0,
|
||||
TLW_STATE_NFC_PROCESS_AUTH0,
|
||||
TLW_STATE_NFC_PREPARE_LOAD_CERT,
|
||||
TLW_STATE_NFC_PROCESS_LOAD_CERT,
|
||||
TLW_STATE_NFC_PREPARE_AUTH1,
|
||||
TLW_STATE_NFC_PROCESS_AUTH1,
|
||||
TLW_STATE_NFC_PREPARE_AUTH1_CHAINED,
|
||||
TLW_STATE_NFC_PROCESS_AUTH1_CHAINED,
|
||||
TLW_STATE_NFC_PREPARE_SELECT_STEPUP,
|
||||
TLW_STATE_NFC_PROCESS_SELECT_STEPUP,
|
||||
TLW_STATE_NFC_PREPARE_STEPUP,
|
||||
TLW_STATE_NFC_PROCESS_STEPUP,
|
||||
TLW_STATE_NFC_PREPARE_GET_RESPONSE,
|
||||
TLW_STATE_NFC_PREPARE_EXCHANGE,
|
||||
TLW_STATE_NFC_PROCESS_EXCHANGE,
|
||||
|
||||
TLW_STATE_NFC_PREPARE_CONTROL_FLOW,
|
||||
TLW_STATE_NFC_PROCESS_CONTROL_FLOW,
|
||||
|
||||
TLW_STATE_NFC_PREPARE_READER_STATUS_EXCHANGE,
|
||||
TLW_STATE_NFC_PROCESS_READER_STATUS_EXCHANGE,
|
||||
TLW_STATE_NFC_ERROR,
|
||||
TLW_STATE_NFC_END
|
||||
}
|
||||
tlw_state_nfc_e;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup BLE_UWB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TLWrapper_BleUwb_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @enum tlw_state_ble_e
|
||||
* @brief BLE state machine states for TLWrapper.
|
||||
*/
|
||||
typedef enum _tlw_state_ble
|
||||
{
|
||||
TLW_STATE_BLE_PREPARE_SELECT = 0,
|
||||
TLW_STATE_BLE_PROCESS_SELECT,
|
||||
TLW_STATE_BLE_PREPARE_AUTH0,
|
||||
TLW_STATE_BLE_PROCESS_AUTH0,
|
||||
TLW_STATE_BLE_PREPARE_LOAD_CERT,
|
||||
TLW_STATE_BLE_PROCESS_LOAD_CERT,
|
||||
TLW_STATE_BLE_PREPARE_AUTH1,
|
||||
TLW_STATE_BLE_PROCESS_AUTH1,
|
||||
|
||||
TLW_STATE_BLE_PREPARE_STEPUP,
|
||||
TLW_STATE_BLE_PROCESS_STEPUP,
|
||||
TLW_STATE_BLE_PREPARE_GET_RESPONSE,
|
||||
|
||||
TLW_STATE_BLE_PREPARE_EXCHANGE,
|
||||
TLW_STATE_BLE_PROCESS_EXCHANGE,
|
||||
TLW_STATE_BLE_PREPARE_AP_COMPLETED,
|
||||
TLW_STATE_BLE_PROCESS_AP_COMPLETED,
|
||||
|
||||
TLW_STATE_BLE_PROCESS_TIME_SYNC,
|
||||
TLW_STATE_BLE_PROCESS_INITIATE_RANGING_SESSION,
|
||||
TLW_STATE_BLE_PREPARE_M1,
|
||||
TLW_STATE_BLE_PROCESS_M2,
|
||||
TLW_STATE_BLE_PREPARE_M3,
|
||||
TLW_STATE_BLE_PROCESS_M4,
|
||||
|
||||
// Reader initiated suspension
|
||||
TLW_STATE_BLE_PREPARE_SUSPEND_RQU,
|
||||
TLW_STATE_BLE_PROCESS_SUSPEND_RSP,
|
||||
|
||||
// Device initiated suspension
|
||||
TLW_STATE_BLE_PREPARE_SUSPEND_RSP,
|
||||
TLW_STATE_BLE_PROCESS_SUSPEND,
|
||||
|
||||
// Reader impose suspension
|
||||
TLW_STATE_BLE_PREPARE_EVENT_RANGING_SUSPENDED,
|
||||
// Device impose suspension
|
||||
TLW_STATE_BLE_PROCESS_EVENT_RANGING_SUSPENDED,
|
||||
|
||||
|
||||
// Device trigger resumption
|
||||
TLW_STATE_BLE_PROCESS_EVENT_RANGING_RESUME,
|
||||
TLW_STATE_BLE_PROCESS_RESUME_RSP,
|
||||
|
||||
|
||||
TLW_STATE_BLE_PREPARE_RANGING,
|
||||
TLW_STATE_BLE_EXECUTE_RANGING,
|
||||
TLW_STATE_BLE_HANDLE_SUSPEND,
|
||||
TLW_STATE_BLE_HANDLE_RESUME,
|
||||
// Reader initiated resumption
|
||||
TLW_STATE_BLE_PREPARE_RESUME_RQU,
|
||||
TLW_STATE_BLE_HANDLE_DOOR_LOCK_OPERATION,
|
||||
|
||||
TLW_STATE_BLE_PREPARE_READER_STATUS_EXCHANGE,
|
||||
TLW_STATE_BLE_PROCESS_READER_STATUS_EXCHANGE,
|
||||
|
||||
TLW_STATE_BLE_PREPARE_NOTIFICATION_EVENT_ERR,
|
||||
|
||||
TLW_STATE_BLE_ERROR,
|
||||
TLW_STATE_BLE_END
|
||||
}
|
||||
tlw_state_ble_e;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup NFC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TLWrapper_Nfc_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @struct tlw_SM_nfc_t
|
||||
* @brief Structure for NFC state machine context in TLWrapper.
|
||||
*/
|
||||
typedef struct _tlwrapper_SM_nfc
|
||||
{
|
||||
uint8_t flags_nfc;
|
||||
tlw_state_nfc_e state;
|
||||
ACWG_SessionContext_t *ctx;
|
||||
uint8_t *input;
|
||||
uint16_t *input_len;
|
||||
uint8_t output[512];
|
||||
uint16_t output_len;
|
||||
ACWG_Status_t (*callback)(ACWG_SessionContext_t *ctx);
|
||||
}
|
||||
tlw_SM_nfc_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup WRAPPER_UTILITY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TLWrapper_Utils_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @enum General_Error_Attribute_ID_e
|
||||
* @brief General error attribute IDs for BLE operations.
|
||||
*/
|
||||
typedef enum _General_Error_Attribute_ID
|
||||
{
|
||||
GENERAL_UNKNOWN_ERROR = 0U,
|
||||
GENERAL_RESOURCE_UNAVAILABLE = 1U,
|
||||
GENERAL_WRONG_PARAMETERS = 2U,
|
||||
GENERAL_URSK_UNAVAILABLE = 3U
|
||||
}
|
||||
General_Error_Attribute_ID_e;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup BLE_UWB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TLWrapper_BleUwb_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @struct tlw_SM_ble_t
|
||||
* @brief Structure for BLE state machine context in TLWrapper.
|
||||
*/
|
||||
typedef struct _tlwrapper_SM_ble
|
||||
{
|
||||
bool isBleOnly;
|
||||
General_Error_Attribute_ID_e general_error_ble;
|
||||
uint8_t flags_ble;
|
||||
tlw_state_ble_e state;
|
||||
ACWG_SessionContext_t *ctx;
|
||||
uint8_t *input;
|
||||
uint16_t *input_len;
|
||||
uint8_t output[300];
|
||||
uint16_t output_len;
|
||||
ACWG_Status_t (*callback)(ACWG_SessionContext_t *ctx);
|
||||
uint8_t (*sendData)(uint8_t *buff, uint16_t len);
|
||||
uint8_t (*disconnect)(void);
|
||||
}
|
||||
tlw_SM_ble_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup WRAPPER_UTILITY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TLWrapper_Utils_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @struct access_mngr_data_t
|
||||
* @brief Structure for access manager data.
|
||||
*/
|
||||
typedef struct _access_mngr_data
|
||||
{
|
||||
uint8_t access_credential_PuBK_last[64];
|
||||
}
|
||||
access_mngr_data_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup NFC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TLWrapper_Nfc_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Global NFC state machine context.
|
||||
*/
|
||||
extern tlw_SM_nfc_t nfc_SM;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup BLE_UWB
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup TLWrapper_BleUwb_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Global BLE state machine context.
|
||||
*/
|
||||
extern tlw_SM_ble_t ble_SM;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup WRAPPER_UTILITY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TLWrapper_Utils_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Global access manager data.
|
||||
*/
|
||||
extern access_mngr_data_t access_mngr_data;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
|
||||
/** @addtogroup NFC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TLWrapper_Nfc_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the NFC state machine.
|
||||
* @param ctx Pointer to session context.
|
||||
* @return Error code.
|
||||
*/
|
||||
tlw_error_e tlw_init_nfc(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Reloads the NFC state machine.
|
||||
* @param ctx Pointer to session context.
|
||||
* @return Error code.
|
||||
*/
|
||||
tlw_error_e tlw_reload_nfc(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Prepares the NFC state machine for operation.
|
||||
* @return Error code.
|
||||
*/
|
||||
tlw_error_e tlw_prepare_nfc(void);
|
||||
|
||||
/**
|
||||
* @brief Processes the NFC state machine.
|
||||
* @return Error code.
|
||||
*/
|
||||
tlw_error_e tlw_process_nfc(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup BLE_UWB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TLWrapper_BleUwb_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the BLE state machine.
|
||||
* @param ctx Pointer to session context.
|
||||
* @return Error code.
|
||||
*/
|
||||
tlw_error_e tlw_init_ble(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Reloads the BLE state machine.
|
||||
* @param ctx Pointer to session context.
|
||||
* @return Error code.
|
||||
*/
|
||||
tlw_error_e tlw_reload_ble(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Prepares the BLE state machine for operation.
|
||||
* @return Error code.
|
||||
*/
|
||||
tlw_error_e tlw_prepare_ble(void);
|
||||
|
||||
/**
|
||||
* @brief Processes the BLE state machine.
|
||||
* @return Error code.
|
||||
*/
|
||||
tlw_error_e tlw_process_ble(void);
|
||||
|
||||
/**
|
||||
* @brief Handles received BLE data and sends response.
|
||||
* @param data Pointer to received data buffer.
|
||||
* @param len Pointer to length of received data.
|
||||
* @param sendData_fn Function pointer to send data.
|
||||
* @return Error code.
|
||||
*/
|
||||
tlw_error_e tlw_ble_receivedData(uint8_t *data, uint8_t *len, uint8_t (*sendData_fn)(uint8_t *, uint16_t));
|
||||
|
||||
/**
|
||||
* @brief Steps the BLE state machine.
|
||||
* @return Error code.
|
||||
*/
|
||||
tlw_error_e tlw_ble_SM_step(void);
|
||||
|
||||
/**
|
||||
* @brief Gets the current UWB session ID.
|
||||
* @return UWB session ID value.
|
||||
*/
|
||||
uint32_t getUwbSessionId( void );
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup WRAPPER_UTILITY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TLWrapper_Utils_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Checks the endpoint public key.
|
||||
* @param endpointPub Pointer to context that contains endpoint public key.
|
||||
* @return Status code.
|
||||
*/
|
||||
uint8_t tlw_CheckEndpointKey(ACWG_SessionContext_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Gets the last endpoint public key.
|
||||
* @return Pointer to the last endpoint public key.
|
||||
*/
|
||||
uint8_t* tlw_GetLastEndpointKey(void);
|
||||
|
||||
/**
|
||||
* @brief Sets the access element string.
|
||||
* @param AccElmStr Pointer to the access element string.
|
||||
*/
|
||||
void tlw_SetAccessElementString(uint8_t *AccElmStr);
|
||||
|
||||
/**
|
||||
* @brief Gets the access element string.
|
||||
* @return Pointer to the access element string.
|
||||
*/
|
||||
uint8_t *tlw_GetAccessElementString(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __TLWRAPPER_H */
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,244 @@
|
||||
#include "custom_uwb.h"
|
||||
#include "main.h"
|
||||
#include "app_aliro.h"
|
||||
|
||||
#define NUM_ITEMS 2
|
||||
#define DISTANCE_OPEN 40
|
||||
#define DEFAULT_FAR_DISTANCE 1000
|
||||
|
||||
#define TIME_CHECK_RANGING 5000
|
||||
|
||||
uint32_t nMeasures[NUM_ITEMS] = {0};
|
||||
uint32_t mean_dist_cm = 0;
|
||||
|
||||
|
||||
void responderReset(void)
|
||||
{
|
||||
for(uint32_t i=0;i<NUM_ITEMS;i++)nMeasures[i]=1000;
|
||||
mean_dist_cm = DEFAULT_FAR_DISTANCE;
|
||||
}
|
||||
|
||||
void Initiate_uwb_ctx(ACWG_SessionContext_t *ctx)
|
||||
{
|
||||
// responderReset();
|
||||
// HAL_Delay(10);
|
||||
// send_frame(...);
|
||||
|
||||
}
|
||||
|
||||
void Fill_uwb_M1(ACWG_SessionContext_t *ctx)
|
||||
{
|
||||
// UNUSED( ctx );
|
||||
|
||||
// force UWB Configuration Identifier to 0x0001
|
||||
uint8_t AliroUWB_Configuration_Identifier[] = { 0x00, 0x00 };
|
||||
memcpy(ctx->uwb_ctx.UWB_Configuration_Identifier, AliroUWB_Configuration_Identifier, sizeof(AliroUWB_Configuration_Identifier));
|
||||
|
||||
memcpy(ctx->uwb_ctx.UWB_Session_Identifier, &ctx->transId[12], 4);
|
||||
|
||||
// force pulse shape combo to 0x01
|
||||
ctx->uwb_ctx.Pulse_Shape_Combo = 0x01;
|
||||
|
||||
// force channel bitmask to 0x01 (channel 5)
|
||||
ctx->uwb_ctx.Channel_Bitmask = 0x01;
|
||||
|
||||
ctx->uwb_ctx.RAN_Multiplier = 0x02;
|
||||
ctx->uwb_ctx.Number_Chaps_per_Slot = 0x0C;
|
||||
ctx->uwb_ctx.Number_Responders_Nodes = 0x01;
|
||||
|
||||
ctx->uwb_ctx.Number_Slots_per_Round = 6;
|
||||
|
||||
ctx->uwb_ctx.MAC_Mode = 0x00;
|
||||
|
||||
}
|
||||
|
||||
void Fill_uwb_M3(ACWG_SessionContext_t *ctx)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
|
||||
uint8_t SYNC_Code_Index_Btmsk[SYNC_CODE_INDEX_BITMASK_LEN_BYTES] = {0x00, 0x00, 0x0F, 0x00};
|
||||
memcpy(ctx->uwb_ctx.SYNC_Code_Index_Bitmask, SYNC_Code_Index_Btmsk, SYNC_CODE_INDEX_BITMASK_LEN_BYTES);
|
||||
}
|
||||
|
||||
void Handle_uwb_M2(ACWG_SessionContext_t *ctx)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
}
|
||||
|
||||
void Handle_uwb_M4(ACWG_SessionContext_t *ctx)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
}
|
||||
|
||||
|
||||
void Prepare_ranging_init(ACWG_SessionContext_t *ctx)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
}
|
||||
|
||||
void Prepare_ranging_loop(ACWG_SessionContext_t *ctx, uint32_t *timeout)
|
||||
{
|
||||
// if(configurationComplete())
|
||||
// {
|
||||
// *timeout = 1;//set timeout to a low value to exit loop in the main function
|
||||
// }
|
||||
}
|
||||
|
||||
static uint32_t nTimeoutCheckRanging = 0;
|
||||
void Execute_ranging_init(ACWG_SessionContext_t *ctx)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
nTimeoutCheckRanging = HAL_GetTick() + TIME_CHECK_RANGING;
|
||||
//TODO: send start session command
|
||||
}
|
||||
|
||||
void Execute_ranging_loop(ACWG_SessionContext_t *ctx, uint32_t *timeout)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
static uint8_t is_ranging_validate = 0;
|
||||
|
||||
|
||||
//TODO: process mean_dist_cm
|
||||
if ((!is_ranging_validate) && (mean_dist_cm == DEFAULT_FAR_DISTANCE))
|
||||
{
|
||||
if (HAL_GetTick() > nTimeoutCheckRanging)
|
||||
{
|
||||
*timeout = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
is_ranging_validate = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(mean_dist_cm < DISTANCE_OPEN)
|
||||
{
|
||||
*timeout = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Close_ranging_init(ACWG_SessionContext_t *ctx)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
}
|
||||
|
||||
void Close_ranging_loop(ACWG_SessionContext_t *ctx, uint32_t *timeout)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
//TODO: send stop and deinit session commands
|
||||
|
||||
{
|
||||
*timeout = 1;//set timeout to a low value to exit loop in the main function
|
||||
}
|
||||
}
|
||||
|
||||
void Suspend_ranging_init(ACWG_SessionContext_t *ctx)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
}
|
||||
|
||||
void Suspend_ranging_loop(ACWG_SessionContext_t *ctx, uint32_t *timeout)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
|
||||
//TODO: send stop and deinit session commands
|
||||
*timeout = 1;//set timeout to a low value to exit loop in the main function
|
||||
}
|
||||
|
||||
void Resume_ranging_init(ACWG_SessionContext_t *ctx)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
}
|
||||
|
||||
void Resume_ranging_loop(ACWG_SessionContext_t *ctx, uint32_t *timeout)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
|
||||
*timeout = 1;//set timeout to a low value to exit loop in the main function
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t Handle_distance_result(ACWG_SessionContext_t *ctx)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
|
||||
if(mean_dist_cm < DISTANCE_OPEN)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Handle_lock_actuation(ACWG_SessionContext_t *ctx)
|
||||
{
|
||||
UNUSED( ctx );
|
||||
PLATFORM_LOG(VERB_VERBOSE, "\r\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Distance MEAN: %u cm\r\n\n", mean_dist_cm);
|
||||
if(mean_dist_cm < DISTANCE_OPEN)
|
||||
{
|
||||
PLATFORM_LOG(VERB_VERBOSE, "OPEN\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " OOOOOOOOO PPPPPPPPPPPPPPPPP EEEEEEEEEEEEEEEEEEEEEENNNNNNNN NNNNNNNN\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " OO:::::::::OO P::::::::::::::::P E::::::::::::::::::::EN:::::::N N::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " OO:::::::::::::OO P::::::PPPPPP:::::P E::::::::::::::::::::EN::::::::N N::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "O:::::::OOO:::::::OPP:::::P P:::::PEE::::::EEEEEEEEE::::EN:::::::::N N::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "O::::::O O::::::O P::::P P:::::P E:::::E EEEEEEN::::::::::N N::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "O:::::O O:::::O P::::P P:::::P E:::::E N:::::::::::N N::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "O:::::O O:::::O P::::PPPPPP:::::P E::::::EEEEEEEEEE N:::::::N::::N N::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "O:::::O O:::::O P:::::::::::::PP E:::::::::::::::E N::::::N N::::N N::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "O:::::O O:::::O P::::PPPPPPPPP E:::::::::::::::E N::::::N N::::N:::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "O:::::O O:::::O P::::P E::::::EEEEEEEEEE N::::::N N:::::::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "O:::::O O:::::O P::::P E:::::E N::::::N N::::::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "O::::::O O::::::O P::::P E:::::E EEEEEEN::::::N N:::::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "O:::::::OOO:::::::OPP::::::PP EE::::::EEEEEEEE:::::EN::::::N N::::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " OO:::::::::::::OO P::::::::P E::::::::::::::::::::EN::::::N N:::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " OO:::::::::OO P::::::::P E::::::::::::::::::::EN::::::N N::::::N\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " OOOOOOOOO PPPPPPPPPP EEEEEEEEEEEEEEEEEEEEEENNNNNNNN NNNNNNN\r\n");
|
||||
|
||||
AliroPort_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
PLATFORM_LOG(VERB_VERBOSE, "CLOSE\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " CCCCCCCCCCCCCLLLLLLLLLLL OOOOOOOOO SSSSSSSSSSSSSSS EEEEEEEEEEEEEEEEEEEEEE\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " CCC::::::::::::CL:::::::::L OO:::::::::OO SS:::::::::::::::SE::::::::::::::::::::E\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " CC:::::::::::::::CL:::::::::L OO:::::::::::::OO S:::::SSSSSS::::::SE::::::::::::::::::::E\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " C:::::CCCCCCCC::::CLL:::::::LL O:::::::OOO:::::::OS:::::S SSSSSSSEE::::::EEEEEEEEE::::E\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " C:::::C CCCCCC L:::::L O::::::O O::::::OS:::::S E:::::E EEEEEE\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "C:::::C L:::::L O:::::O O:::::OS:::::S E:::::E \r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "C:::::C L:::::L O:::::O O:::::O S::::SSSS E::::::EEEEEEEEEE \r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "C:::::C L:::::L O:::::O O:::::O SS::::::SSSSS E:::::::::::::::E \r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "C:::::C L:::::L O:::::O O:::::O SSS::::::::SS E:::::::::::::::E \r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "C:::::C L:::::L O:::::O O:::::O SSSSSS::::S E::::::EEEEEEEEEE \r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, "C:::::C L:::::L O:::::O O:::::O S:::::S E:::::E \r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " C:::::C CCCCCC L:::::L LLLLLLO::::::O O::::::O S:::::S E:::::E EEEEEE\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " C:::::CCCCCCCC::::CLL:::::::LLLLLLLLL:::::LO:::::::OOO:::::::OSSSSSSS S:::::SEE::::::EEEEEEEE:::::E\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " CC:::::::::::::::CL::::::::::::::::::::::L OO:::::::::::::OO S::::::SSSSSS:::::SE::::::::::::::::::::E\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " CCC::::::::::::CL::::::::::::::::::::::L OO:::::::::OO S:::::::::::::::SS E::::::::::::::::::::E\r\n");
|
||||
// PLATFORM_LOG(VERB_VERBOSE, " CCCCCCCCCCCCCLLLLLLLLLLLLLLLLLLLLLLLL OOOOOOOOO SSSSSSSSSSSSSSS EEEEEEEEEEEEEEEEEEEEEE\r\n");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void UWB_HW_init( void )
|
||||
{
|
||||
Set_timeout_prepare_ranging( TIMEOUT_PREPARE_RANGING_DEFAULT );
|
||||
Set_timeout_execute_ranging( TIMEOUT_EXECUTE_RANGING_DEFAULT );
|
||||
Set_timeout_suspend_ranging( TIMEOUT_SUSPEND_RANGING_DEFAULT );
|
||||
Set_timeout_resume_ranging( TIMEOUT_RESUME_RANGING_DEFAULT );
|
||||
Set_timeout_door_operation( TIMEOUT_DOOR_OPERATION_DEFAULT );
|
||||
|
||||
responderReset();
|
||||
HAL_Delay(10);
|
||||
}
|
||||
|
||||
void UWB_HW_loop( void )
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,370 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : flash_mng.c
|
||||
* @brief : Flash management functions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "flash_mng.h"
|
||||
#if defined(STM32WBA52xx) || defined(STM32WBA55xx) || defined(STM32WBA65xx)
|
||||
#include "app_ble.h"
|
||||
#include "flash_manager.h"
|
||||
#define FLASH_MANAGER_ENABLE 1
|
||||
#endif //defined(STM32WBA52xx) || defined(STM32WBA55xx) || defined(STM32WBA65xx)
|
||||
|
||||
#if FLASH_MANAGER_ENABLE
|
||||
#define WRITE_BUF_SZ (1400)
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
static FM_CallbackNode_t Aliro_FlashCallback;
|
||||
static uint8_t writeBuf[WRITE_BUF_SZ];
|
||||
static uint32_t writeBufSz;
|
||||
static uint32_t writeBufAddr;
|
||||
|
||||
/* Callback Definition ------------------------------------------------------*/
|
||||
void Aliro_FlashManagerCallback(FM_FlashOp_Status_t Status)
|
||||
{
|
||||
FM_Cmd_Status_t fm_result;
|
||||
if(Status == FM_OPERATION_AVAILABLE)
|
||||
{
|
||||
Aliro_FlashCallback.Callback = Aliro_FlashManagerCallback;
|
||||
fm_result = FM_Write((uint32_t*)writeBuf, (uint32_t *)writeBufAddr, writeBufSz, &Aliro_FlashCallback);
|
||||
if(fm_result == FM_BUSY)
|
||||
{
|
||||
//TODO : appropriate error handling
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif //FLASH_MANAGER_ENABLE
|
||||
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/**
|
||||
* @brief Gets the page of a given address
|
||||
* @param Addr: Address of the FLASH Memory
|
||||
* @retval The page of a given address
|
||||
*/
|
||||
static uint32_t GetPage(uint32_t Addr)
|
||||
{
|
||||
return (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;;
|
||||
}
|
||||
|
||||
|
||||
/* Public functions -----------------------------------------------*/
|
||||
flashOpStatus_e EraseFlash(uint32_t nAddress, uint32_t nBytes)
|
||||
{
|
||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||
uint32_t FirstPage = 0, NbOfPages = 0;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
UNUSED(EraseInitStruct);
|
||||
UNUSED(PageError);
|
||||
|
||||
/* Erase the user Flash area
|
||||
(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
|
||||
|
||||
/* Get the 1st page to erase */
|
||||
FirstPage = GetPage(nAddress);
|
||||
|
||||
/* Get the number of pages to erase from 1st page */
|
||||
NbOfPages = GetPage(nAddress + nBytes) - FirstPage + 1;
|
||||
|
||||
/* Fill EraseInit structure*/
|
||||
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInitStruct.Page = FirstPage;
|
||||
EraseInitStruct.NbPages = NbOfPages;
|
||||
|
||||
|
||||
|
||||
#if FLASH_MANAGER_ENABLE
|
||||
FM_Cmd_Status_t fm_result;
|
||||
|
||||
fm_result = FM_Erase(FirstPage, NbOfPages, NULL);
|
||||
if (fm_result == FM_BUSY)
|
||||
{
|
||||
return FLASH_OP_BUSY;
|
||||
}
|
||||
else if (fm_result == FM_ERROR)
|
||||
{
|
||||
return FLASH_OP_ERROR;
|
||||
}
|
||||
|
||||
#else //FLASH_MANAGER_ENABLE
|
||||
|
||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
|
||||
{
|
||||
/*
|
||||
Error occurred while page erase.
|
||||
User can add here some code to deal with this error.
|
||||
PageError will contain the faulty page and then to know the code error on this page,
|
||||
user can call function 'HAL_FLASH_GetError()'
|
||||
*/
|
||||
/* Infinite loop */
|
||||
while (1)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FLASH_MANAGER_ENABLE
|
||||
return FLASH_OP_OK;
|
||||
}
|
||||
|
||||
flashOpStatus_e EraseWriteToFlash(void *datapointer, uint32_t nBytes, uint32_t nAddress)
|
||||
{
|
||||
flashOpStatus_e result = FLASH_OP_OK;
|
||||
|
||||
/* Disable instruction cache prior to internal cacheable memory update */
|
||||
#ifndef STM32WBAxx_LL_ICACHE_H
|
||||
if (HAL_ICACHE_Disable() != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
#else //STM32WBAxx_LL_ICACHE_H
|
||||
uint32_t tickstart;
|
||||
|
||||
/* Make sure BSYENDF is reset before to disable the instruction cache */
|
||||
/* as it automatically starts a cache invalidation procedure */
|
||||
LL_ICACHE_ClearFlag_BSYEND();
|
||||
|
||||
LL_ICACHE_Disable();
|
||||
|
||||
/* Get tick */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait for instruction cache being disabled */
|
||||
while (LL_ICACHE_IsEnabled())
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > 1U)
|
||||
{
|
||||
/* New check to avoid false timeout detection in case of preemption */
|
||||
if (LL_ICACHE_IsEnabled())
|
||||
{
|
||||
// status = HAL_TIMEOUT;
|
||||
//break;
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // STM32WBAxx_LL_ICACHE_H
|
||||
|
||||
|
||||
#if FLASH_MANAGER_ENABLE
|
||||
|
||||
result = EraseFlash(nAddress, nBytes);
|
||||
|
||||
if (result != FLASH_OP_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
FM_Cmd_Status_t fm_result;
|
||||
|
||||
int32_t int32_size = 0;
|
||||
int32_size = (int32_t)(nBytes/4);
|
||||
if (nBytes%4)
|
||||
{
|
||||
int32_size++;
|
||||
}
|
||||
|
||||
if(nBytes > WRITE_BUF_SZ)
|
||||
{
|
||||
result = FLASH_OP_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
writeBufAddr = nAddress;
|
||||
writeBufSz = int32_size;
|
||||
memcpy(writeBuf, datapointer, nBytes);
|
||||
result = FLASH_OP_BUSY;
|
||||
}
|
||||
|
||||
Aliro_FlashCallback.Callback = Aliro_FlashManagerCallback;
|
||||
fm_result = FM_Write((uint32_t*)writeBuf, (uint32_t *)writeBufAddr, writeBufSz, &Aliro_FlashCallback);
|
||||
if(fm_result == FM_BUSY)
|
||||
{
|
||||
if(nBytes > WRITE_BUF_SZ)
|
||||
{
|
||||
result = FLASH_OP_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = FLASH_OP_BUSY;
|
||||
}
|
||||
}
|
||||
else if (fm_result == FM_ERROR)
|
||||
{
|
||||
result = FLASH_OP_ERROR;
|
||||
}
|
||||
result = FLASH_OP_OK;
|
||||
}
|
||||
|
||||
#else //FLASH_MANAGER_ENABLE
|
||||
|
||||
/* Unlock the Flash to enable the flash control register access *************/
|
||||
HAL_FLASH_Unlock();
|
||||
/* Program the user Flash area word by word
|
||||
(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
|
||||
|
||||
result = EraseFlash(nAddress, nBytes);
|
||||
|
||||
uint32_t AddressOffset = 0;
|
||||
|
||||
while (AddressOffset < nBytes)
|
||||
{
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, nAddress + AddressOffset, ((uint32_t)datapointer + AddressOffset)) == HAL_OK)
|
||||
{
|
||||
AddressOffset = AddressOffset + 16; /* increment to next quad word*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error occurred while writing data in Flash memory.
|
||||
User can add here some code to deal with this error */
|
||||
while (1)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the Flash to disable the flash control register access (recommended
|
||||
to protect the FLASH memory against possible unwanted operation) *********/
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
#endif //FLASH_MANAGER_ENABLE
|
||||
|
||||
/* Re-enable instruction cache */
|
||||
#ifndef STM32WBAxx_LL_ICACHE_H
|
||||
if (HAL_ICACHE_Enable() != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
#else //STM32WBAxx_LL_ICACHE_H
|
||||
LL_ICACHE_Enable();
|
||||
#endif // STM32WBAxx_LL_ICACHE_H
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
flashOpStatus_e WriteToFlash(void *datapointer, uint32_t nBytes, uint32_t nAddress)
|
||||
{
|
||||
flashOpStatus_e result = FLASH_OP_OK;
|
||||
|
||||
/* Disable instruction cache prior to internal cacheable memory update */
|
||||
#ifndef STM32WBAxx_LL_ICACHE_H
|
||||
if (HAL_ICACHE_Disable() != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
#else //STM32WBAxx_LL_ICACHE_H
|
||||
uint32_t tickstart;
|
||||
|
||||
/* Make sure BSYENDF is reset before to disable the instruction cache */
|
||||
/* as it automatically starts a cache invalidation procedure */
|
||||
LL_ICACHE_ClearFlag_BSYEND();
|
||||
|
||||
LL_ICACHE_Disable();
|
||||
|
||||
/* Get tick */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait for instruction cache being disabled */
|
||||
while (LL_ICACHE_IsEnabled())
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > 1U)
|
||||
{
|
||||
/* New check to avoid false timeout detection in case of preemption */
|
||||
if (LL_ICACHE_IsEnabled())
|
||||
{
|
||||
// status = HAL_TIMEOUT;
|
||||
//break;
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // STM32WBAxx_LL_ICACHE_H
|
||||
|
||||
|
||||
#if FLASH_MANAGER_ENABLE
|
||||
FM_Cmd_Status_t fm_result;
|
||||
|
||||
int32_t int32_size = 0;
|
||||
int32_size = (int32_t)(nBytes/4);
|
||||
if (nBytes%4)
|
||||
{
|
||||
int32_size++;
|
||||
}
|
||||
|
||||
fm_result = FM_Write((uint32_t*)datapointer, (uint32_t *)nAddress, int32_size, NULL);
|
||||
if(fm_result == FM_BUSY)
|
||||
{
|
||||
result = FLASH_OP_BUSY;
|
||||
}
|
||||
else if (fm_result == FM_ERROR)
|
||||
{
|
||||
result = FLASH_OP_ERROR;
|
||||
}
|
||||
result = FLASH_OP_OK;
|
||||
|
||||
#else //FLASH_MANAGER_ENABLE
|
||||
|
||||
/* Unlock the Flash to enable the flash control register access *************/
|
||||
HAL_FLASH_Unlock();
|
||||
/* Program the user Flash area word by word
|
||||
(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
|
||||
uint32_t AddressOffset = 0;
|
||||
|
||||
while (AddressOffset < nBytes)
|
||||
{
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, nAddress + AddressOffset, ((uint32_t)datapointer + AddressOffset)) == HAL_OK)
|
||||
{
|
||||
AddressOffset = AddressOffset + 16; /* increment to next quad word*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error occurred while writing data in Flash memory.
|
||||
User can add here some code to deal with this error */
|
||||
while (1)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the Flash to disable the flash control register access (recommended
|
||||
to protect the FLASH memory against possible unwanted operation) *********/
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
#endif //FLASH_MANAGER_ENABLE
|
||||
|
||||
|
||||
/* Re-enable instruction cache */
|
||||
#ifndef STM32WBAxx_LL_ICACHE_H
|
||||
if (HAL_ICACHE_Enable() != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
#else //STM32WBAxx_LL_ICACHE_H
|
||||
LL_ICACHE_Enable();
|
||||
#endif // STM32WBAxx_LL_ICACHE_H
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,938 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : sm_crypto_mcu.c
|
||||
* @brief : MCU cryptographic functions using hardware accelerators
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ----------------------------------------------------------*/
|
||||
#include "sm_crypto_mcu.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef STM32WBA65xx
|
||||
#include "hw.h"
|
||||
#endif //STM32WBA65xx
|
||||
|
||||
#define USE_MCU_HW_RNG
|
||||
#define USE_MCU_HW_ASYM
|
||||
|
||||
#define HASH_TIMEOUT ((uint32_t)5)
|
||||
#define KDH_INFO_MAX_LEN_BYTES ((uint32_t)32)
|
||||
#define SHA256_BYTE_SIZE ((uint32_t)32)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static HASH_HandleTypeDef *HHash = NULL;
|
||||
static CRYP_HandleTypeDef *HCryp = NULL;
|
||||
|
||||
#ifdef USE_MCU_HW_RNG
|
||||
static RNG_HandleTypeDef *HRng = NULL;
|
||||
#endif // USE_MCU_HW_RNG
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(STM32U545xx) || defined(STM32U585xx)
|
||||
#include "stm32u5xx_hal.h"
|
||||
#define HHASH_INIT_DATATYPE HASH_DATATYPE_8B
|
||||
#define SM_HASH_SHA256_START HAL_HASHEx_SHA256_Start
|
||||
#define SM_HASH_SHA256_ACCUMULATE(H, B, S, T) HAL_HASHEx_SHA256_Accmlt(H, B, S)
|
||||
#define SM_HASH_SHA256_ACCUMULATE_LAST HAL_HASHEx_SHA256_Accmlt_End
|
||||
#define SM_HASH_SHA1_START HAL_HASH_SHA1_Start
|
||||
#define HASH_SET_ALGORITHM(I, A)
|
||||
|
||||
#define SM_HMAC_SHA256_START HAL_HMACEx_SHA256_Start
|
||||
|
||||
#elif defined(STM32U385xx)
|
||||
#include "stm32u3xx_hal.h"
|
||||
#define HHASH_INIT_DATATYPE HASH_DATATYPE_8B
|
||||
#define SM_HASH_SHA256_START HAL_HASHEx_SHA256_Start
|
||||
#define SM_HASH_SHA256_ACCUMULATE(H, B, S, T) HAL_HASHEx_SHA256_Accmlt(H, B, S)
|
||||
#define SM_HASH_SHA256_ACCUMULATE_LAST HAL_HASHEx_SHA256_Accmlt_End
|
||||
#define SM_HASH_SHA1_START HAL_HASH_SHA1_Start
|
||||
#define HASH_SET_ALGORITHM(I, A)
|
||||
|
||||
#define SM_HMAC_SHA256_START HAL_HMACEx_SHA256_Start
|
||||
|
||||
#elif defined(STM32WBA52xx) || defined(STM32WBA55xx) || defined(STM32WBA65xx)
|
||||
#include "stm32wbaxx_hal.h"
|
||||
#define HHASH_INIT_DATATYPE HASH_CR_DATATYPE_1
|
||||
|
||||
#define SM_HASH_SHA1_START(hhash, pInBuffer, Size, pOutBuffer, Timeout) HAL_HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout)
|
||||
|
||||
#define SM_HASH_SHA256_START(hhash, pInBuffer, Size, pOutBuffer, Timeout) HAL_HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout)
|
||||
#define SM_HMAC_SHA256_START(hhash, pInBuffer, Size, pOutBuffer, Timeout) HAL_HASH_HMAC_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout)
|
||||
|
||||
#define SM_HASH_SHA256_ACCUMULATE(H, B, S, T) HAL_HASH_Accumulate(H, B, S, T)
|
||||
#define SM_HASH_SHA256_ACCUMULATE_LAST HAL_HASH_AccumulateLast
|
||||
#define HASH_SET_ALGORITHM(I, A) I.Algorithm = A
|
||||
|
||||
#else
|
||||
#error "product not supported"
|
||||
#endif
|
||||
|
||||
#ifdef USE_MCU_HW_ASYM
|
||||
static PKA_HandleTypeDef *HPka = NULL;
|
||||
#define PKA_TIMEOUT ((uint32_t)3000)
|
||||
#define PRIVATE_KEY_SIZE_BYTES ((uint32_t)32)
|
||||
#define MODULUS_SIZE_BYTES PRIVATE_KEY_SIZE_BYTES
|
||||
#define MODULUS_SIZE_WORDS ((MODULUS_SIZE_BYTES + 3)/4)
|
||||
#define SECP256R1_ORDER_LEN_BITS ((uint32_t)256)
|
||||
#define SECP256R1_A_SIGN ((uint32_t)1)
|
||||
static const uint8_t SECP256R1_Prime[] =
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
static const uint8_t SECP256R1_AbsA[] =
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 };
|
||||
static const uint8_t SECP256R1_B[] =
|
||||
{ 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76,
|
||||
0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6, 0x3b,
|
||||
0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b };
|
||||
static const uint8_t SECP256R1_Gx[] =
|
||||
{ 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, 0x63,
|
||||
0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, 0xf4,
|
||||
0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96 };
|
||||
static const uint8_t SECP256R1_Gy[] =
|
||||
{ 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c,
|
||||
0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb,
|
||||
0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5 };
|
||||
static const uint8_t SECP256R1_Order[] =
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3,
|
||||
0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51 };
|
||||
static const uint8_t SECP256R1_OrderMinus1[] =
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3,
|
||||
0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x50 };
|
||||
|
||||
#ifdef ALIRO_TEST
|
||||
// This is the static private key from the static test vectors
|
||||
const uint8_t staticPrivateKey[] = {0x7a, 0x9e, 0x50, 0xa1, 0x9a, 0xe3, 0x85, 0xe3, 0x9b, 0x3b, 0xf0, 0xc7, 0x5e, 0xb5, 0xf9, 0xc9, 0xa5, 0xeb, 0x4d, 0x51, 0xf8, 0x8, 0x23, 0x18, 0x35, 0x39, 0x5f, 0xd2, 0xc1, 0x7, 0x83, 0x67};
|
||||
#define STATIC_PRIVATE_KEY staticPrivateKey
|
||||
#else // ALIRO_TEST
|
||||
// This is the static private key for the mobile phone app.
|
||||
//ST OFFICE
|
||||
//const uint8_t staticPrivateKey[] = {0xCB, 0x64, 0xA5, 0x8A, 0x5F, 0xAE, 0x05, 0x2D, 0x45, 0x8B, 0x3B, 0xCE, 0x25, 0x99, 0xA2, 0x0A,
|
||||
// 0x66, 0x59, 0x87, 0xB5, 0x37, 0xB1, 0x57, 0xCC, 0x3C, 0xC4, 0x2E, 0x1D, 0x9C, 0x65, 0x24, 0x09};
|
||||
//HOME
|
||||
//const uint8_t staticPrivateKey[] = {0xBE, 0x08, 0x3F, 0xCD, 0xA3, 0x7B, 0xB2, 0xDA, 0x82, 0x66, 0xDC, 0x64, 0x61, 0x66, 0x35, 0x24,
|
||||
// 0xE5, 0x9A, 0xD4, 0xA0, 0xBB, 0x6B, 0x4D, 0xD3, 0x1C, 0x88, 0x53, 0xC2, 0x0F, 0xFB, 0xB4, 0x0D};
|
||||
|
||||
#include "provisioning.h"
|
||||
|
||||
#define STATIC_PRIVATE_KEY (getProvisioningFromFlash()->staticPrivateKey)
|
||||
#endif // ALIRO_TEST
|
||||
|
||||
uint8_t ephemeralPrivateKey[] = {0x3c, 0xf, 0x74, 0x11, 0x4c, 0xd2, 0xa0, 0x21, 0xe8, 0x6, 0x6e, 0xfb, 0xaa, 0x31, 0xdb, 0xb9, 0x7e, 0xf0, 0x5, 0x42, 0x72, 0x19, 0x26, 0x6, 0xfd, 0x96, 0x63, 0x3a, 0x4, 0xf6, 0x62, 0x14};
|
||||
|
||||
#endif // USE_MCU_HW_ASYM
|
||||
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
do { \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
} while( 0 )
|
||||
#endif //GET_UINT32_BE
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initializes MCU cryptographic hardware modules.
|
||||
* @param rng Pointer to RNG handle.
|
||||
* @param pka Pointer to PKA handle.
|
||||
* @param hash Pointer to HASH handle.
|
||||
* @param cryp Pointer to CRYP handle.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_initCryptoMCU(RNG_HandleTypeDef *rng, PKA_HandleTypeDef *pka, HASH_HandleTypeDef *hash, CRYP_HandleTypeDef *cryp)
|
||||
{
|
||||
#ifdef USE_MCU_HW_RNG
|
||||
HRng = rng;
|
||||
#endif // USE_MCU_HW_RNG
|
||||
#ifdef USE_MCU_HW_ASYM
|
||||
HPka = pka;
|
||||
#endif // USE_MCU_HW_ASYM
|
||||
HHash = hash;
|
||||
HCryp = cryp;
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
#ifdef USE_MCU_HW_RNG
|
||||
|
||||
/**
|
||||
* @brief Generates random bytes using MCU hardware RNG.
|
||||
* @param bytes Pointer to output buffer.
|
||||
* @param size Number of bytes to generate.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_genRandomBytes(uint8_t *bytes, uint32_t size)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t remain = size % 4;
|
||||
if (HRng == NULL)
|
||||
return(SM_Crypto_HW_Error);
|
||||
__HAL_RCC_RNG_CLK_ENABLE();
|
||||
__HAL_RNG_ENABLE(HRng);
|
||||
|
||||
#ifdef STM32WBA65xx
|
||||
HW_RNG_Start();
|
||||
#endif //STM32WBA65xx
|
||||
|
||||
for (uint32_t i = 0; i < size / 4; i++)
|
||||
{
|
||||
#ifdef STM32WBA65xx
|
||||
HW_RNG_Get(1, &temp);
|
||||
#endif //STM32WBA65xx
|
||||
|
||||
#if defined(STM32U545xx) || defined(STM32U585xx) || defined(STM32U385xx)
|
||||
if (HAL_RNG_GenerateRandomNumber(HRng, &temp) != HAL_OK)
|
||||
{
|
||||
/* Random number generation error */
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
#endif //defined(STM32U545xx) || defined(STM32U585xx) || defined(STM32U385xx)
|
||||
#if defined(STM32WBA52xx)||defined(STM32WBA55xx)
|
||||
if (HAL_RNG_GenerateRandomNumber(HRng, &temp) != HAL_OK)
|
||||
{
|
||||
/* Random number generation error */
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
#endif //defined(STM32WBA52xx)||defined(STM32WBA55xx)
|
||||
*(uint32_t *) bytes = temp;
|
||||
bytes += 4;
|
||||
}
|
||||
if (remain)
|
||||
{
|
||||
#ifdef STM32WBA65xx
|
||||
HW_RNG_Get(1, &temp);
|
||||
#endif //STM32WBA65xx
|
||||
|
||||
#if defined(STM32WBA52xx)||defined(STM32WBA55xx)
|
||||
if (HAL_RNG_GenerateRandomNumber(HRng, &temp) != HAL_OK)
|
||||
{
|
||||
/* Random number generation error */
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
#endif //defined(STM32WBA52xx)||defined(STM32WBA55xx)
|
||||
#if defined(STM32U545xx) || defined(STM32U585xx) || defined(STM32U385xx)
|
||||
if (HAL_RNG_GenerateRandomNumber(HRng, &temp) != HAL_OK)
|
||||
{
|
||||
/* Random number generation error */
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
#endif //defined(STM32U545xx) || defined(STM32U585xx) || defined(STM32U385xx)
|
||||
for (uint32_t i = 0; i < remain; i++)
|
||||
{
|
||||
*bytes = (temp >> i) & 0xFF;
|
||||
bytes++;
|
||||
}
|
||||
}
|
||||
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
#else //USE_MCU_HW_RNG
|
||||
#if 0
|
||||
SM_Crypto_Error_t SM_genRandomBytes(uint8_t *bytes, uint32_t size)
|
||||
{
|
||||
for(uint32_t i = 0; i< size;i++)
|
||||
{
|
||||
*bytes = i;
|
||||
}
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
#endif
|
||||
#endif // USE_MCU_HW_RNG
|
||||
|
||||
#ifdef USE_MCU_HW_ASYM
|
||||
static uint32_t NumberOfWords(uint32_t NumberOfBytes)
|
||||
{
|
||||
return ((NumberOfBytes + 3) / 4);
|
||||
}
|
||||
static SM_Crypto_Error_t GeneratePrivateKey(uint8_t *pPrivateKey)
|
||||
{
|
||||
/* for NIST compliance (to decrease bias below 2^-64)
|
||||
* generate random with 64 extra bits (2 words)
|
||||
* perform modular reduction by n-1
|
||||
* and add 1 */
|
||||
uint8_t temp[MODULUS_SIZE_BYTES + 8] = { 0 };
|
||||
uint8_t temp2[MODULUS_SIZE_BYTES + 8] = { 0 };
|
||||
uint32_t random_bitstring_len_in_bits = 0;
|
||||
PKA_ModRedInTypeDef in_modred = { 0 };
|
||||
|
||||
random_bitstring_len_in_bits = SECP256R1_ORDER_LEN_BITS + 64;
|
||||
if (SM_genRandomBytes(temp, (random_bitstring_len_in_bits + 7) / 8) != SM_Crypto_OK)
|
||||
{
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
/* Perform modular reduction by n-1 */
|
||||
in_modred.pMod = SECP256R1_OrderMinus1;
|
||||
in_modred.modSize = sizeof(SECP256R1_Order);
|
||||
in_modred.pOp1 = (uint32_t*)temp;
|
||||
in_modred.OpSize = (random_bitstring_len_in_bits + 31) / 32;
|
||||
if (HAL_PKA_ModRed(HPka, &in_modred, PKA_TIMEOUT) != HAL_OK)
|
||||
{
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
HAL_PKA_Arithmetic_GetResult(HPka, (uint32_t*)temp2);
|
||||
|
||||
/* compute reduced_random + 1 */
|
||||
memset(temp, 0, sizeof(temp));
|
||||
temp[0] = 1;
|
||||
{
|
||||
PKA_AddInTypeDef in_add;
|
||||
in_add.pOp1 = (uint32_t*)temp2;
|
||||
in_add.pOp2 = (uint32_t*)temp;
|
||||
in_add.size = NumberOfWords(sizeof(SECP256R1_Order));
|
||||
if (HAL_PKA_Add(HPka, &in_add, PKA_TIMEOUT) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
HAL_PKA_Arithmetic_GetResult(HPka, (uint32_t*)temp2);
|
||||
}
|
||||
memcpy(pPrivateKey, temp2, sizeof(SECP256R1_Order));
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
static SM_Crypto_Error_t GeneratePublicKey(const uint8_t *pPrivateKey, uint8_t *pPublicKey)
|
||||
{
|
||||
PKA_ECCMulInTypeDef in_mult =
|
||||
{ 0 };
|
||||
|
||||
/* Compute public key */
|
||||
in_mult.modulusSize = sizeof(SECP256R1_Prime);
|
||||
in_mult.coefSign = SECP256R1_A_SIGN;
|
||||
in_mult.coefA = SECP256R1_AbsA;
|
||||
in_mult.coefB = SECP256R1_B;
|
||||
in_mult.modulus = SECP256R1_Prime;
|
||||
in_mult.pointX = SECP256R1_Gx;
|
||||
in_mult.pointY = SECP256R1_Gy;
|
||||
in_mult.primeOrder = SECP256R1_Order;
|
||||
in_mult.scalarMulSize = sizeof(SECP256R1_Order); // WRONG NAMING IN HAL STRUCT: this must be the length of the ORDER
|
||||
in_mult.scalarMul = (uint8_t *)pPrivateKey;
|
||||
|
||||
{
|
||||
PKA_ECCMulOutTypeDef mulRes;
|
||||
mulRes.ptX = &pPublicKey[0];
|
||||
mulRes.ptY = &pPublicKey[sizeof(SECP256R1_Order)];
|
||||
if (HAL_PKA_ECCMul(HPka, &in_mult, PKA_TIMEOUT) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
HAL_PKA_ECCMul_GetResult(HPka, &mulRes);
|
||||
}
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Performs ECDH key agreement using MCU hardware.
|
||||
* @param pPublicKey Pointer to public key.
|
||||
* @param pSharedSecret Pointer to output shared secret.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_Ecdh(const uint8_t *pPublicKey, uint8_t *pSharedSecret)
|
||||
{
|
||||
PKA_ECCMulInTypeDef in_mult = { 0 };
|
||||
|
||||
/* Compute ECDH */
|
||||
in_mult.modulusSize = sizeof(SECP256R1_Prime);
|
||||
in_mult.coefSign = SECP256R1_A_SIGN;
|
||||
in_mult.coefA = SECP256R1_AbsA;
|
||||
in_mult.coefB = SECP256R1_B;
|
||||
in_mult.modulus = SECP256R1_Prime;
|
||||
in_mult.pointX = (uint8_t*)&pPublicKey[0];
|
||||
in_mult.pointY = (uint8_t*)&pPublicKey[sizeof(SECP256R1_Order)];
|
||||
in_mult.primeOrder = SECP256R1_Order;
|
||||
in_mult.scalarMulSize = sizeof(SECP256R1_Order); // WRONG NAMING IN HAL STRUCT: this must be the length of the ORDER
|
||||
in_mult.scalarMul = ephemeralPrivateKey;
|
||||
|
||||
if (HAL_PKA_ECCMul(HPka, &in_mult, PKA_TIMEOUT) != HAL_OK)
|
||||
{
|
||||
memset(ephemeralPrivateKey, 0, sizeof(ephemeralPrivateKey));
|
||||
return SM_Crypto_Error;
|
||||
}
|
||||
memset(ephemeralPrivateKey, 0, sizeof(ephemeralPrivateKey));
|
||||
{
|
||||
PKA_ECCMulOutTypeDef pub;
|
||||
uint8_t tmp[sizeof(SECP256R1_Order)];
|
||||
pub.ptX = pSharedSecret;
|
||||
pub.ptY = tmp;
|
||||
HAL_PKA_ECCMul_GetResult(HPka, &pub);
|
||||
}
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Signs a digest using MCU hardware.
|
||||
* @param digest Pointer to digest to sign.
|
||||
* @param digestSize Size of digest.
|
||||
* @param signature Pointer to output signature.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_sign(const uint8_t *digest, uint32_t digestSize, uint8_t *signature)
|
||||
{
|
||||
uint8_t a_k[MODULUS_SIZE_WORDS*sizeof(uint32_t)] =
|
||||
{ 0 };
|
||||
PKA_ECDSASignInTypeDef in =
|
||||
{ 0 };
|
||||
|
||||
if (digestSize != SHA256_BYTE_SIZE)
|
||||
return SM_Crypto_Error;
|
||||
/* generate random k parameter in NIST compliant way */
|
||||
if (GeneratePrivateKey(a_k) != SM_Crypto_OK)
|
||||
{
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
|
||||
/* Set input parameters */
|
||||
in.primeOrderSize = sizeof(SECP256R1_Order);
|
||||
in.modulusSize = sizeof(SECP256R1_Prime);
|
||||
in.coefSign = SECP256R1_A_SIGN;
|
||||
in.coef = SECP256R1_AbsA;
|
||||
in.coefB = SECP256R1_B;
|
||||
in.modulus = SECP256R1_Prime;
|
||||
in.basePointX = SECP256R1_Gx;
|
||||
in.basePointY = SECP256R1_Gy;
|
||||
in.primeOrder = SECP256R1_Order;
|
||||
|
||||
in.integer = a_k;
|
||||
in.hash = digest;
|
||||
|
||||
in.privateKey = STATIC_PRIVATE_KEY;
|
||||
|
||||
if (HAL_PKA_ECDSASign(HPka, &in, PKA_TIMEOUT) != HAL_OK)
|
||||
{
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
{
|
||||
PKA_ECDSASignOutTypeDef out;
|
||||
out.RSign = &signature[0];
|
||||
out.SSign = &signature[sizeof(SECP256R1_Order)];
|
||||
HAL_PKA_ECDSASign_GetResult(HPka, &out, NULL);
|
||||
}
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Generates a keypair using MCU hardware.
|
||||
* @param pub Pointer to output public key.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_genKeypair(uint8_t *pub)
|
||||
{
|
||||
if (GeneratePrivateKey(ephemeralPrivateKey) != SM_Crypto_OK)
|
||||
return SM_Crypto_Error;
|
||||
|
||||
if (GeneratePublicKey(ephemeralPrivateKey, pub) != SM_Crypto_OK)
|
||||
{
|
||||
memset(ephemeralPrivateKey, 0, sizeof(ephemeralPrivateKey));
|
||||
return SM_Crypto_Error;
|
||||
}
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Verifies a signature using MCU hardware.
|
||||
* @param pPublicKey Pointer to public key.
|
||||
* @param digest Pointer to digest.
|
||||
* @param digestSize Size of digest.
|
||||
* @param signature Pointer to signature.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_verify(const uint8_t *pPublicKey, const uint8_t *digest, const uint32_t digestSize, const uint8_t *signature)
|
||||
{
|
||||
PKA_ECDSAVerifInTypeDef in =
|
||||
{ 0 };
|
||||
if (digestSize != SHA256_BYTE_SIZE)
|
||||
return (SM_Crypto_Error);
|
||||
/* Set input parameters */
|
||||
in.primeOrderSize = sizeof(SECP256R1_Order);
|
||||
in.modulusSize = sizeof(SECP256R1_Prime);
|
||||
in.coefSign = SECP256R1_A_SIGN;
|
||||
in.coef = SECP256R1_AbsA;
|
||||
in.modulus = SECP256R1_Prime;
|
||||
in.basePointX = SECP256R1_Gx;
|
||||
in.basePointY = SECP256R1_Gy;
|
||||
in.primeOrder = SECP256R1_Order;
|
||||
|
||||
in.RSign = &signature[0];
|
||||
in.SSign = &signature[PRIVATE_KEY_SIZE_BYTES];
|
||||
in.hash = digest;
|
||||
in.pPubKeyCurvePtX = &pPublicKey[0];
|
||||
in.pPubKeyCurvePtY = &pPublicKey[MODULUS_SIZE_BYTES];
|
||||
|
||||
if (HAL_PKA_ECDSAVerif(HPka, &in, PKA_TIMEOUT) != HAL_OK)
|
||||
{
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
if (!HAL_PKA_ECDSAVerif_IsValidSignature(HPka))
|
||||
return (SM_Crypto_Error);
|
||||
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Gets the certificate from MCU hardware.
|
||||
* @param certificate Pointer to output certificate buffer.
|
||||
* @param certificateSize Pointer to output certificate size.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_getCertificate(uint8_t *certificate, uint32_t *certificateSize)
|
||||
{
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
#endif // USE_MCU_HW_ASYM
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Private function -----------------------------------------------*/
|
||||
static SM_Crypto_Error_t KDFKeyExpansionRound(const uint8_t* pKDK, const uint8_t *prev, const uint8_t* pFixedInfo, uint32_t fixedInfoSize, uint8_t counter, uint8_t* output)
|
||||
{
|
||||
/* counter and L must be big-endian, update least significant byte */
|
||||
uint32_t offset = 0;
|
||||
uint32_t hmac_input_size = 0;
|
||||
|
||||
uint8_t input[SHA256_BYTE_SIZE + MAX_FIXED_INFO_SIZE + 1 ];
|
||||
|
||||
if (fixedInfoSize > MAX_FIXED_INFO_SIZE)
|
||||
return SM_Crypto_Error;
|
||||
HHash->Init.DataType = HHASH_INIT_DATATYPE;
|
||||
HASH_SET_ALGORITHM(HHash->Init, HASH_ALGOSELECTION_SHA256);
|
||||
HHash->Init.KeySize = SHA256_BYTE_SIZE;
|
||||
HHash->Init.pKey = (uint8_t *)pKDK;
|
||||
if (HAL_HASH_Init(HHash) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
hmac_input_size = SHA256_BYTE_SIZE + fixedInfoSize + 1 ;
|
||||
if (counter != 1)
|
||||
{
|
||||
memcpy(input + offset, prev, SHA256_BYTE_SIZE);
|
||||
offset += SHA256_BYTE_SIZE;
|
||||
} else {
|
||||
/* No need to copy, but will hmac 32 bytes less */
|
||||
hmac_input_size -= SHA256_BYTE_SIZE;
|
||||
}
|
||||
/* Based on RFC 5869 */
|
||||
memcpy(input + offset, pFixedInfo, fixedInfoSize);
|
||||
offset += fixedInfoSize;
|
||||
memcpy(input + offset, &counter, 1);
|
||||
offset += 1;
|
||||
if (SM_HMAC_SHA256_START(HHash, input, hmac_input_size, output, 5000) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Public functions -----------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Computes SHA-1 hash using MCU hardware.
|
||||
* @param input Pointer to input data.
|
||||
* @param inputSize Size of input data.
|
||||
* @param hash Pointer to output hash buffer.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_sha1(uint8_t *input, uint32_t inputSize, uint8_t *hash)
|
||||
{
|
||||
HHash->Init.DataType = HHASH_INIT_DATATYPE;
|
||||
HASH_SET_ALGORITHM(HHash->Init, HASH_ALGOSELECTION_SHA1);
|
||||
if (HAL_HASH_Init(HHash) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
|
||||
if (SM_HASH_SHA1_START(HHash, input, inputSize, &hash[0], HASH_TIMEOUT) != HAL_OK)
|
||||
{
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Computes SHA-256 hash using MCU hardware.
|
||||
* @param input Pointer to input data.
|
||||
* @param inputSize Size of input data.
|
||||
* @param hash Pointer to output hash buffer.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_sha256(uint8_t *input, uint32_t inputSize, uint8_t *hash)
|
||||
{
|
||||
HHash->Init.DataType = HHASH_INIT_DATATYPE;
|
||||
HASH_SET_ALGORITHM(HHash->Init, HASH_ALGOSELECTION_SHA256);
|
||||
if (HAL_HASH_Init(HHash) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
|
||||
if (SM_HASH_SHA256_START(HHash, input, inputSize, &hash[0], HASH_TIMEOUT) != HAL_OK)
|
||||
{
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Starts SHA-256 computation using MCU hardware.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_sha256_start(void)
|
||||
{
|
||||
HHash->Init.DataType = HHASH_INIT_DATATYPE;
|
||||
HASH_SET_ALGORITHM(HHash->Init, HASH_ALGOSELECTION_SHA256);
|
||||
if (HAL_HASH_Init(HHash) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Updates SHA-256 computation with new data using MCU hardware.
|
||||
* @param input Pointer to input data.
|
||||
* @param inputSize Size of input data.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_sha256_update(const uint8_t *input, uint32_t inputSize)
|
||||
{
|
||||
if (SM_HASH_SHA256_ACCUMULATE(HHash, input, inputSize, HASH_TIMEOUT) != HAL_OK)
|
||||
{
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Finishes SHA-256 computation and returns the hash using MCU hardware.
|
||||
* @param hash Pointer to output hash buffer.
|
||||
* @param input Pointer to input data.
|
||||
* @param inputSize Size of input data.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_sha256_finish(uint8_t *hash, const uint8_t *input, uint32_t inputSize)
|
||||
{
|
||||
if (SM_HASH_SHA256_ACCUMULATE_LAST(HHash, input, inputSize, &hash[0], HASH_TIMEOUT) != HAL_OK)
|
||||
{
|
||||
return (SM_Crypto_HW_Error);
|
||||
}
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Performs randomness extraction for KDF.
|
||||
* @param Z Pointer to input keying material.
|
||||
* @param ZSize Size of input keying material.
|
||||
* @param salt Pointer to salt.
|
||||
* @param saltSize Size of salt.
|
||||
* @param output Pointer to output buffer.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t KDFRandomnessExtraction(const uint8_t* Z, uint32_t ZSize,
|
||||
const uint8_t* salt, uint32_t saltSize,
|
||||
uint8_t* output)
|
||||
{
|
||||
uint8_t null_salt[SHA256_BYTE_SIZE] = {0};
|
||||
|
||||
if ((saltSize == 0) && (salt == NULL)) // no salt (optionnal), need to use string of zeros, the size is the size of the HASH
|
||||
{
|
||||
HHash->Init.KeySize = SHA256_BYTE_SIZE;
|
||||
HHash->Init.pKey = null_salt;
|
||||
} else if (salt == NULL) // saltsize is non-zero but pointer is null -> error
|
||||
{
|
||||
return SM_Crypto_Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
HHash->Init.KeySize = saltSize;
|
||||
HHash->Init.pKey = (uint8_t *)salt;
|
||||
}
|
||||
HHash->Init.DataType = HHASH_INIT_DATATYPE;
|
||||
HASH_SET_ALGORITHM(HHash->Init, HASH_ALGOSELECTION_SHA256);
|
||||
if (HAL_HASH_Init(HHash) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
if (SM_HMAC_SHA256_START(HHash, (uint8_t *)Z, ZSize, output, 5000) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Key Derivation Function RFC5869 using MCU hardware.
|
||||
* @param pZ Pointer to input keying material.
|
||||
* @param ZSize Size of input keying material.
|
||||
* @param pSalt Pointer to salt.
|
||||
* @param saltSize Size of salt.
|
||||
* @param pFixedInfo Pointer to fixed info.
|
||||
* @param fixedInfoSize Size of fixed info.
|
||||
* @param L Length of output keying material.
|
||||
* @param pOutput Pointer to output buffer.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_KDFRFC5869(const uint8_t* pZ, uint32_t ZSize,
|
||||
const uint8_t* pSalt, uint32_t saltSize,
|
||||
const uint8_t* pFixedInfo, uint32_t fixedInfoSize,
|
||||
uint32_t L, uint8_t* pOutput)
|
||||
{
|
||||
uint8_t counter = 0;
|
||||
uint8_t KDK[SHA256_BYTE_SIZE] = {0};
|
||||
uint8_t *prev = NULL;
|
||||
|
||||
if(L >= 255*SHA256_BYTE_SIZE)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
if (KDFRandomnessExtraction(pZ, ZSize, pSalt, saltSize, KDK) != SM_Crypto_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
for(counter=1; counter<=L/SHA256_BYTE_SIZE; counter++)
|
||||
{
|
||||
/* compute full rounds */
|
||||
if(KDFKeyExpansionRound(KDK, prev, pFixedInfo, fixedInfoSize, counter, pOutput) != SM_Crypto_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
prev = pOutput;
|
||||
pOutput += SHA256_BYTE_SIZE;
|
||||
}
|
||||
if(L % SHA256_BYTE_SIZE)
|
||||
{
|
||||
/* compute non full round */
|
||||
uint8_t buffer[SHA256_BYTE_SIZE];
|
||||
if(KDFKeyExpansionRound(KDK, prev, pFixedInfo, fixedInfoSize, counter, buffer) != SM_Crypto_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
memcpy(pOutput, buffer, L % SHA256_BYTE_SIZE);
|
||||
}
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Derives KDH key using MCU hardware.
|
||||
* @param pZ Pointer to input keying material.
|
||||
* @param info Pointer to info data.
|
||||
* @param infoSize Size of info data.
|
||||
* @param pKdh Pointer to output KDH key.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_deriveKdh(const uint8_t *pZ, const uint8_t * info, uint32_t infoSize, uint8_t *pKdh)
|
||||
{
|
||||
uint8_t counter_be[4] = {0,0,0,1};
|
||||
uint32_t offset = 0;
|
||||
uint8_t buf[KDH_INFO_MAX_LEN_BYTES + 32 + 4];
|
||||
memcpy(&buf[offset], pZ, 32);
|
||||
offset += 32;
|
||||
memcpy(&buf[offset], counter_be, 4);
|
||||
offset += 4;
|
||||
memcpy(&buf[offset], info, infoSize);
|
||||
|
||||
HHash->Init.DataType = HHASH_INIT_DATATYPE;
|
||||
HASH_SET_ALGORITHM(HHash->Init, HASH_ALGOSELECTION_SHA256);
|
||||
if (HAL_HASH_Init(HHash) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
if (SM_HASH_SHA256_START(HHash, buf, 32 + 4 + infoSize, pKdh, 5000) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Decrypts data using AES-256 GCM with MCU hardware.
|
||||
* @param pKey Pointer to key.
|
||||
* @param pNonce Pointer to nonce.
|
||||
* @param pAad Pointer to additional authenticated data.
|
||||
* @param aadSize Size of AAD.
|
||||
* @param pPayload Pointer to encrypted payload.
|
||||
* @param payloadSize Size of payload.
|
||||
* @param pPlaintext Pointer to output plaintext buffer.
|
||||
* @param pTag Pointer to authentication tag.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_aes256GcmDecrypt(const uint8_t* pKey, const uint8_t* pNonce, const uint8_t* pAad, const uint32_t aadSize,
|
||||
const uint8_t* pPayload, const uint32_t payloadSize, uint8_t* pPlaintext,
|
||||
const uint8_t* pTag)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t key[8] = {0};
|
||||
uint32_t iv[4] = {0};
|
||||
uint32_t tag[4] = {0};
|
||||
uint8_t tmp = 0;
|
||||
|
||||
/* !!! Beware: the last word must be padded with 0s by the caller, otherwise tag will be wrong !!! */
|
||||
if (payloadSize % 4)
|
||||
{
|
||||
/* Must check that the padding has been properly done by caller */
|
||||
if (memcmp(&pPayload[payloadSize], &i, 4 - (payloadSize % 4)))
|
||||
return SM_Crypto_Error;
|
||||
}
|
||||
/* Format and fill AES key */
|
||||
for( i=0; i < 8; i++ )
|
||||
GET_UINT32_BE( key[i], pKey, 4*i );
|
||||
/* Set IV with invert endianness */
|
||||
for( i=0; i < 3; i++ )
|
||||
GET_UINT32_BE( iv[i], pNonce, 4*i );
|
||||
|
||||
/* counter value must be set to 2 when processing the first block of payload */
|
||||
iv[3] = 0x00000002;
|
||||
|
||||
HCryp->Instance = AES;
|
||||
HCryp->Init.DataType = CRYP_DATATYPE_8B;
|
||||
HCryp->Init.KeySize = CRYP_KEYSIZE_256B;
|
||||
HCryp->Init.pKey = key;
|
||||
HCryp->Init.pInitVect = iv;
|
||||
HCryp->Init.Algorithm = CRYP_AES_GCM_GMAC;
|
||||
HCryp->Init.Header = (uint32_t *)pAad;
|
||||
HCryp->Init.HeaderSize = aadSize;
|
||||
HCryp->Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
|
||||
HCryp->Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
|
||||
HCryp->Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
|
||||
HCryp->Init.KeyMode = CRYP_KEYMODE_NORMAL;
|
||||
if (HAL_CRYP_Init(HCryp) != HAL_OK)
|
||||
{
|
||||
return(SM_Crypto_HW_Error);
|
||||
}
|
||||
if (HAL_CRYP_Decrypt(HCryp, (uint32_t *)pPayload, (uint16_t) payloadSize, (uint32_t *)pPlaintext, 5000) != HAL_OK)
|
||||
return(SM_Crypto_HW_Error);
|
||||
/* Last 16 bytes of plaintext is the GCM tag */
|
||||
if (HAL_CRYPEx_AESGCM_GenerateAuthTAG(HCryp, (const uint32_t *)tag, 5000) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
// constant time compare
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
tmp |= pTag[i*4] ^ (uint8_t)(tag[i] & 0xFF);
|
||||
tmp |= pTag[i*4 + 1] ^ (uint8_t)((tag[i] >> 8) & 0xFF);
|
||||
tmp |= pTag[i*4 + 2] ^ (uint8_t)((tag[i] >> 16) & 0xFF);
|
||||
tmp |= pTag[i*4 + 3] ^ (uint8_t)((tag[i] >> 24) & 0xFF);
|
||||
}
|
||||
if (tmp)
|
||||
{
|
||||
memset(pPlaintext, 0, payloadSize);
|
||||
return SM_Crypto_Error;
|
||||
}
|
||||
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Encrypts data using AES-256 GCM with MCU hardware.
|
||||
* @param pKey Pointer to key.
|
||||
* @param pNonce Pointer to nonce.
|
||||
* @param pAad Pointer to additional authenticated data.
|
||||
* @param aadSize Size of AAD.
|
||||
* @param pInput Pointer to input data.
|
||||
* @param inputSize Size of input data.
|
||||
* @param pOutput Pointer to output buffer.
|
||||
* @param pOutputSize Pointer to output size.
|
||||
* @return SM_Crypto_Error_t error code.
|
||||
*/
|
||||
SM_Crypto_Error_t SM_aes256GcmEncrypt(const uint8_t* pKey, const uint8_t* pNonce, const uint8_t* pAad, const uint32_t aadSize,
|
||||
const uint8_t* pInput, const uint32_t inputSize, uint8_t* pOutput, uint32_t* pOutputSize)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t key[8] = {0};
|
||||
uint32_t iv[4] = {0};
|
||||
uint32_t tag[4] = {0};
|
||||
|
||||
|
||||
/* Workaround HAL: need to pad with 0s the last word of payload. Here we first copy the input into the output
|
||||
buffer (that is at least 16 bytes longer (for the tag), and then we encrypt in place */
|
||||
memcpy(pOutput, pInput, inputSize);
|
||||
if ((inputSize) % 4)
|
||||
memset(&pOutput[inputSize], 0, 4 - ((inputSize) % 4));
|
||||
|
||||
/* Format and fill AES key */
|
||||
for( i=0; i < 8; i++ )
|
||||
GET_UINT32_BE( key[i], pKey, 4*i );
|
||||
/* Set IV with invert endianness */
|
||||
for( i=0; i < 3; i++ )
|
||||
GET_UINT32_BE( iv[i], pNonce, 4*i );
|
||||
|
||||
/* counter value must be set to 2 when processing the first block of payload */
|
||||
iv[3] = 0x00000002;
|
||||
|
||||
HCryp->Instance = AES;
|
||||
HCryp->Init.DataType = CRYP_DATATYPE_8B;
|
||||
HCryp->Init.KeySize = CRYP_KEYSIZE_256B;
|
||||
HCryp->Init.pKey = key;
|
||||
HCryp->Init.pInitVect = iv;
|
||||
HCryp->Init.Algorithm = CRYP_AES_GCM_GMAC;
|
||||
HCryp->Init.Header = (uint32_t *)pAad;
|
||||
HCryp->Init.HeaderSize = aadSize;
|
||||
HCryp->Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
|
||||
HCryp->Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
|
||||
HCryp->Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
|
||||
HCryp->Init.KeyMode = CRYP_KEYMODE_NORMAL;
|
||||
if (HAL_CRYP_Init(HCryp) != HAL_OK)
|
||||
{
|
||||
return(SM_Crypto_HW_Error);
|
||||
}
|
||||
if (HAL_CRYP_Encrypt(HCryp, (uint32_t *)pOutput, (uint16_t)inputSize, (uint32_t *)pOutput, 5000) != HAL_OK)
|
||||
return(SM_Crypto_HW_Error);
|
||||
/* Generate the GCM tag */
|
||||
if (HAL_CRYPEx_AESGCM_GenerateAuthTAG(HCryp, (const uint32_t *)tag, 5000) != HAL_OK)
|
||||
{
|
||||
return SM_Crypto_HW_Error;
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
pOutput[inputSize + i*4] = (uint8_t)(tag[i] & 0xFF);
|
||||
pOutput[inputSize + i*4 + 1] = (uint8_t)((tag[i] >> 8) & 0xFF);
|
||||
pOutput[inputSize + i*4 + 2] = (uint8_t)((tag[i] >> 16) & 0xFF);
|
||||
pOutput[inputSize + i*4 + 3] = (uint8_t)((tag[i] >> 24) & 0xFF);
|
||||
}
|
||||
*pOutputSize = inputSize + 16;
|
||||
return SM_Crypto_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file adv_trace_usart_if.c
|
||||
* @author MCD Application Team
|
||||
* @brief : Source file for interfacing the stm32_adv_trace to hardware
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "app_conf.h"
|
||||
#include "stm32_adv_trace.h"
|
||||
#include "adv_trace_usart_if.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* list all the driver interface used by the trace application. */
|
||||
const UTIL_ADV_TRACE_Driver_s UTIL_TraceDriver =
|
||||
{
|
||||
UART_Init,
|
||||
UART_DeInit,
|
||||
UART_StartRx,
|
||||
UART_TransmitDMA
|
||||
};
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* Whether the UART should be in RX after a Transmit */
|
||||
uint8_t receive_after_transmit = 0;
|
||||
|
||||
/* Buffer to receive 1 character */
|
||||
static uint8_t cCharRx;
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
static void (*TxCpltCallback) ( void * );
|
||||
static void (*RxCpltCallback) ( uint8_t * pData, uint16_t iSize, uint8_t cError );
|
||||
|
||||
static void UsartIf_TxCpltCallback ( UART_HandleTypeDef *huart );
|
||||
static void UsartIf_RxCpltCallback ( UART_HandleTypeDef *huart );
|
||||
static IRQn_Type get_IRQn_Type_from_DMA_HandleTypeDef (DMA_HandleTypeDef * hDmaHandler );
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UTIL_ADV_TRACE_Status_t UART_Init( void (*pCallbackFunction)(void *))
|
||||
{
|
||||
TxCpltCallback = pCallbackFunction;
|
||||
|
||||
LOG_UART_HANDLER.TxCpltCallback = UsartIf_TxCpltCallback;
|
||||
|
||||
return UTIL_ADV_TRACE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UTIL_ADV_TRACE_Status_t UART_DeInit( void )
|
||||
{
|
||||
HAL_StatusTypeDef eResult;
|
||||
|
||||
eResult = HAL_UART_DeInit( &LOG_UART_HANDLER );
|
||||
if ( eResult != HAL_OK )
|
||||
{
|
||||
LOG_UART_HANDLER.TxCpltCallback = NULL;
|
||||
return UTIL_ADV_TRACE_UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
return UTIL_ADV_TRACE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UTIL_ADV_TRACE_Status_t UART_StartRx( void (*pCallbackFunction)(uint8_t * pData, uint16_t iSize, uint8_t cError ) )
|
||||
{
|
||||
/* Configure UART in Receive mode */
|
||||
HAL_UART_Receive_IT( &LOG_UART_HANDLER, &cCharRx, 1 );
|
||||
LOG_UART_HANDLER.RxCpltCallback = &UsartIf_RxCpltCallback;
|
||||
|
||||
if ( pCallbackFunction != NULL )
|
||||
{
|
||||
RxCpltCallback = pCallbackFunction;
|
||||
}
|
||||
|
||||
return UTIL_ADV_TRACE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UTIL_ADV_TRACE_Status_t UART_TransmitDMA ( uint8_t * pData, uint16_t iSize )
|
||||
{
|
||||
UTIL_ADV_TRACE_Status_t eStatus = UTIL_ADV_TRACE_OK;
|
||||
HAL_StatusTypeDef eResult;
|
||||
IRQn_Type eUseDmaTx;
|
||||
|
||||
eUseDmaTx = get_IRQn_Type_from_DMA_HandleTypeDef( LOG_UART_HANDLER.hdmatx );
|
||||
|
||||
if ( ( eUseDmaTx == GPDMA1_Channel0_IRQn ) || ( eUseDmaTx == GPDMA1_Channel1_IRQn ) ||
|
||||
( eUseDmaTx == GPDMA1_Channel2_IRQn ) || ( eUseDmaTx == GPDMA1_Channel3_IRQn ) ||
|
||||
( eUseDmaTx == GPDMA1_Channel4_IRQn ) || ( eUseDmaTx == GPDMA1_Channel5_IRQn ) ||
|
||||
( eUseDmaTx == GPDMA1_Channel6_IRQn ) || ( eUseDmaTx == GPDMA1_Channel7_IRQn ) )
|
||||
{
|
||||
eResult = HAL_UART_Transmit_DMA( &LOG_UART_HANDLER, pData, iSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
eResult = HAL_UART_Transmit_IT( &LOG_UART_HANDLER, pData, iSize );
|
||||
}
|
||||
|
||||
if ( eResult != HAL_OK )
|
||||
{
|
||||
eStatus = UTIL_ADV_TRACE_HW_ERROR;
|
||||
}
|
||||
|
||||
/* Check whether the UART should return in Receiver mode */
|
||||
if ( receive_after_transmit )
|
||||
{
|
||||
HAL_UART_Receive_IT( &LOG_UART_HANDLER, &cCharRx, 1 );
|
||||
}
|
||||
|
||||
return eStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void UsartIf_TxCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* ADV Trace callback */
|
||||
TxCpltCallback(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void UsartIf_RxCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
RxCpltCallback( &cCharRx, 1, 0 );
|
||||
HAL_UART_Receive_IT( &LOG_UART_HANDLER, &cCharRx, 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* The purpose of this function is to match a DMA_HandleTypeDef as key with the corresponding IRQn_Type as value.
|
||||
*
|
||||
* TAKE CARE : in case of an invalid parameter or e.g. an usart/lpuart not initialized, this will lead to hard fault.
|
||||
* it is up to the user to ensure the serial link is in a valid state.
|
||||
*/
|
||||
static IRQn_Type get_IRQn_Type_from_DMA_HandleTypeDef( DMA_HandleTypeDef * hDmaHandler )
|
||||
{
|
||||
if ( hDmaHandler->Instance == GPDMA1_Channel0 )
|
||||
{ return GPDMA1_Channel0_IRQn; }
|
||||
|
||||
if ( hDmaHandler->Instance == GPDMA1_Channel1 )
|
||||
{ return GPDMA1_Channel1_IRQn; }
|
||||
|
||||
if ( hDmaHandler->Instance == GPDMA1_Channel2 )
|
||||
{ return GPDMA1_Channel2_IRQn; }
|
||||
|
||||
if ( hDmaHandler->Instance == GPDMA1_Channel3 )
|
||||
{ return GPDMA1_Channel3_IRQn; }
|
||||
|
||||
if ( hDmaHandler->Instance == GPDMA1_Channel4 )
|
||||
{ return GPDMA1_Channel4_IRQn; }
|
||||
|
||||
if ( hDmaHandler->Instance == GPDMA1_Channel5 )
|
||||
{ return GPDMA1_Channel5_IRQn; }
|
||||
|
||||
if (hDmaHandler->Instance == GPDMA1_Channel6 )
|
||||
{ return GPDMA1_Channel6_IRQn; }
|
||||
|
||||
if ( hDmaHandler->Instance == GPDMA1_Channel7 )
|
||||
{ return GPDMA1_Channel7_IRQn; }
|
||||
|
||||
/* Values from (-1) to (-15) are already in used. This value isn't used so it should be safe.
|
||||
So, if you see this value, it means you used an invalid DMA handler as input. */
|
||||
return (IRQn_Type)(-666);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usart_if.h
|
||||
* @author MCD Application Team
|
||||
* @brief : Header file for stm32_adv_trace interface file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef USART_IF_H
|
||||
#define USART_IF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32_adv_trace.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ET */
|
||||
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
/* USER CODE END EV */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EM */
|
||||
|
||||
/* USER CODE END EM */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
/**
|
||||
* @brief Init the UART and associated DMA.
|
||||
* @param cb tx function callback.
|
||||
* @return @ref UTIL_ADV_TRACE_Status_t
|
||||
*/
|
||||
UTIL_ADV_TRACE_Status_t UART_Init(void (*cb)(void *));
|
||||
|
||||
/**
|
||||
* @brief DeInit the UART and associated DMA.
|
||||
* @return @ref UTIL_ADV_TRACE_Status_t
|
||||
*/
|
||||
UTIL_ADV_TRACE_Status_t UART_DeInit(void);
|
||||
|
||||
/**
|
||||
* @brief send buffer to UART using DMA
|
||||
* @param pdata data to be sent
|
||||
* @param size of buffer p_data to be sent
|
||||
* @return @ref UTIL_ADV_TRACE_Status_t
|
||||
*/
|
||||
UTIL_ADV_TRACE_Status_t UART_TransmitDMA(uint8_t *pdata, uint16_t size);
|
||||
|
||||
/**
|
||||
* @brief start Rx process
|
||||
* @param cb callback to receive the data
|
||||
* @return @ref UTIL_ADV_TRACE_Status_t
|
||||
*/
|
||||
UTIL_ADV_TRACE_Status_t UART_StartRx(void (*cb)(uint8_t *pdata, uint16_t size, uint8_t error));
|
||||
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USART_IF_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file app_bsp.h
|
||||
* @author MCD Application Team
|
||||
* @brief Interface to manage BSP.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef APP_BSP_H
|
||||
#define APP_BSP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "app_conf.h"
|
||||
#include "stm32_rtos.h"
|
||||
|
||||
#ifdef STM32WBA55xx
|
||||
#ifdef CFG_BSP_ON_DISCOVERY
|
||||
#include "stm32wba55g_discovery.h"
|
||||
#if (CFG_LCD_SUPPORTED == 1)
|
||||
#include "stm32wba55g_discovery_lcd.h"
|
||||
#include "stm32_lcd.h"
|
||||
#endif /* (CFG_LCD_SUPPORTED == 1) */
|
||||
#endif /* CFG_BSP_ON_DISCOVERY */
|
||||
#endif /* STM32WBA55xx */
|
||||
|
||||
#ifdef STM32WBA65xx
|
||||
#ifdef CFG_BSP_ON_DISCOVERY
|
||||
#include "stm32wba65i_discovery.h"
|
||||
#if (CFG_LCD_SUPPORTED == 1)
|
||||
#include "stm32wba65i_discovery_lcd.h"
|
||||
#include "stm32_lcd.h"
|
||||
#endif /* (CFG_LCD_SUPPORTED == 1) */
|
||||
#endif /* CFG_BSP_ON_DISCOVERY */
|
||||
#endif /* STM32WBA65xx */
|
||||
|
||||
#ifdef CFG_BSP_ON_CEB
|
||||
#ifdef STM32WBA5Mxx
|
||||
#include "b_wba5m_wpan.h"
|
||||
#endif
|
||||
#ifdef STM32WBA6Mxx
|
||||
#include "b_wba6m_wpan.h"
|
||||
#endif
|
||||
#endif /* CFG_BSP_ON_CEB */
|
||||
#ifdef CFG_BSP_ON_NUCLEO
|
||||
#include "stm32wbaxx_nucleo.h"
|
||||
#endif /* CFG_BSP_ON_CEB */
|
||||
|
||||
#ifdef CFG_COAP_MSG
|
||||
#include "coap.h"
|
||||
#endif
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
#if (CFG_LCD_SUPPORTED == 1)
|
||||
#define LCD1 (0u)
|
||||
#endif /* (CFG_LCD_SUPPORTED == 1) */
|
||||
|
||||
#if (defined CFG_BSP_ON_DISCOVERY) && (defined STM32WBA65xx)
|
||||
/* No Led Blue on Discovery for STM32WBA65I. Replaced by Red Led */
|
||||
#define LED_BLUE LED_RED
|
||||
#endif /* (defined CFG_BSP_ON_DISCOVERY) && (defined STM32WBA65xx) */
|
||||
|
||||
#if (CFG_JOYSTICK_SUPPORTED == 1)
|
||||
#define JOYSTICK_USE_AS_JOYSTICK (0u) /* When Joystick is not 'none', call according 'Joystick Action' every JOYSTICK_PRESS_SAMPLE_MS. */
|
||||
#define JOYSTICK_USE_AS_BUTTON (1u) /* When Joystick is pressed, call according 'Joystick Action' one time. */
|
||||
#define JOYSTICK_USE_AS_BUTTON_WITH_TIME (2u) /* When Joystick is pressed, it wait the release or the end of JOYSTICK_LONG_PRESS_THRESHOLD_MS
|
||||
before call according 'Joystick Action'. */
|
||||
#define JOYSTICK_USE_AS_CHANGE (3u) /* When Joystcik is pressed according 'Joystick Action' is called. When the Joystick is released, 'JoystickNoneAction' is called. */
|
||||
#define JOYSTICK_USE_AS_MATTER (4u) /* When Joystick is pressed, according 'Joystick Action' is called. When the Joystick is released or the end
|
||||
of JOYSTICK_LONG_PRESS_THRESHOLD_MS occurs, according 'Joystick Action' is called (same as when pressed). */
|
||||
#endif /* (CFG_JOYSTICK_SUPPORTED == 1) */
|
||||
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
#ifdef CFG_COAP_MSG
|
||||
extern uint32_t APP_Thread_TransmitPeriod_ms;
|
||||
extern uint32_t APP_Thread_CoapPayloadLength_byte;
|
||||
extern otCoapType APP_Thread_CoapType;
|
||||
#endif
|
||||
|
||||
#if (CFG_BUTTON_SUPPORTED == 1)
|
||||
#ifdef CFG_BSP_ON_THREADX
|
||||
extern TX_SEMAPHORE ButtonB1Semaphore, ButtonB2Semaphore, ButtonB3Semaphore;
|
||||
#endif /* CFG_BSP_ON_THREADX */
|
||||
#ifdef CFG_BSP_ON_FREERTOS
|
||||
extern osSemaphoreId_t ButtonB1Semaphore, ButtonB2Semaphore, ButtonB3Semaphore;
|
||||
#endif /* CFG_BSP_ON_FREERTOS */
|
||||
#endif /* (CFG_BUTTON_SUPPORTED == 1) */
|
||||
|
||||
#if (CFG_JOYSTICK_SUPPORTED == 1)
|
||||
#ifdef CFG_BSP_ON_THREADX
|
||||
extern TX_SEMAPHORE JoystickUpSemaphore, JoystickRightSemaphore, JoystickDownSemaphore, JoystickLeftSemaphore, JoystickSelectSemaphore, JoystickNoneSemaphore;
|
||||
#endif /* CFG_BSP_ON_THREADX */
|
||||
#ifdef CFG_BSP_ON_FREERTOS
|
||||
extern osSemaphoreId_t JoystickUpSemaphore, JoystickRightSemaphore, JoystickDownSemaphore, JoystickLeftSemaphore, JoystickSelectSemaphore, JoystickNoneSemaphore;
|
||||
#endif /* CFG_BSP_ON_FREERTOS */
|
||||
#endif /* (CFG_JOYSTICK_SUPPORTED == 1) */
|
||||
|
||||
/* Exported macros ------------------------------------------------------------*/
|
||||
#if ( CFG_LED_SUPPORTED == 1 )
|
||||
#define APP_BSP_LED_On( LED ) BSP_LED_On( LED )
|
||||
#define APP_BSP_LED_Off( LED ) BSP_LED_Off( LED )
|
||||
#define APP_BSP_LED_Toggle( LED ) BSP_LED_Toggle( LED )
|
||||
#else /* ( CFG_LED_SUPPORTED == 1 ) */
|
||||
#define APP_BSP_LED_On( LED )
|
||||
#define APP_BSP_LED_Off( LED )
|
||||
#define APP_BSP_LED_Toggle( LED )
|
||||
#endif /* ( CFG_LED_SUPPORTED == 1 ) */
|
||||
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void APP_BSP_Init ( void );
|
||||
void APP_BSP_PostIdle ( void );
|
||||
void APP_BSP_StandbyExit ( void );
|
||||
uint8_t APP_BSP_SerialCmdExecute ( uint8_t * pRxBuffer, uint16_t iRxBufferSize );
|
||||
|
||||
#if (CFG_LED_SUPPORTED == 1)
|
||||
void APP_BSP_LedInit ( void );
|
||||
|
||||
#endif /* (CFG_LED_SUPPORTED == 1) */
|
||||
#if (CFG_LCD_SUPPORTED == 1)
|
||||
void APP_BSP_LcdInit ( void );
|
||||
|
||||
#endif /* (CFG_LCD_SUPPORTED == 1) */
|
||||
#if ( CFG_BUTTON_SUPPORTED == 1 )
|
||||
void APP_BSP_ButtonInit ( void );
|
||||
|
||||
uint8_t APP_BSP_ButtonIsLongPressed ( uint16_t btnIdx );
|
||||
void APP_BSP_SetButtonIsLongPressed ( uint16_t btnIdx );
|
||||
|
||||
void APP_BSP_Button1Action ( void );
|
||||
void APP_BSP_Button2Action ( void );
|
||||
void APP_BSP_Button3Action ( void );
|
||||
|
||||
void BSP_PB_Callback ( Button_TypeDef button );
|
||||
|
||||
#endif /* ( CFG_BUTTON_SUPPORTED == 1 ) */
|
||||
#if ( CFG_JOYSTICK_SUPPORTED == 1 )
|
||||
void APP_BSP_JoystickInit ( void );
|
||||
uint8_t APP_BSP_JoystickIsLongPressed ( void );
|
||||
uint8_t APP_BSP_JoystickIsShortReleased ( void );
|
||||
uint8_t APP_BSP_JoystickIsInitialPress ( void );
|
||||
|
||||
void APP_BSP_JoystickUpAction ( void );
|
||||
void APP_BSP_JoystickRightAction ( void );
|
||||
void APP_BSP_JoystickDownAction ( void );
|
||||
void APP_BSP_JoystickLeftAction ( void );
|
||||
void APP_BSP_JoystickSelectAction ( void );
|
||||
void APP_BSP_JoystickNoneAction ( void );
|
||||
|
||||
void BSP_JOY_Callback ( JOY_TypeDef joyNb, JOYPin_TypeDef joyPin );
|
||||
|
||||
#endif /* CFG_JOYSTICK_SUPPORTED */
|
||||
|
||||
void APP_BSP_CliInit ( void );
|
||||
void APP_BSP_CoapMsgRateAction ( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*APP_BSP_H */
|
||||
@@ -0,0 +1,562 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hw.h
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains the interface of STM32 HW drivers.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef HW_H__
|
||||
#define HW_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stm32wbaxx.h"
|
||||
#include "app_conf.h"
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* General
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef CFG_HW_ERROR_OFFSET
|
||||
#define CFG_HW_ERROR_OFFSET 0
|
||||
#endif
|
||||
|
||||
/* Return values definition */
|
||||
enum
|
||||
{
|
||||
HW_OK = 0,
|
||||
HW_BUSY = 1
|
||||
};
|
||||
|
||||
/*
|
||||
* HW_Init
|
||||
*
|
||||
* This function must be called once after reset before calling any of the
|
||||
* other HW functions.
|
||||
*/
|
||||
extern void HW_Init( void );
|
||||
|
||||
/*
|
||||
* HW_Delay
|
||||
*
|
||||
* This function is used internally for minimum delays.
|
||||
* The input is given in microseconds and must be strictly higher than 0 (> 0)
|
||||
* and lower than 16000000 (= 16 s).
|
||||
* Be careful that the actual delay can be higher than the one programmed
|
||||
* if the function is interrupted.
|
||||
* The function is declared "weak" and can be overloaded by the user.
|
||||
*/
|
||||
extern void HW_Delay( uint32_t delay_us );
|
||||
|
||||
/*
|
||||
* HW_GetPackageType
|
||||
*
|
||||
* Returns the package type (cf Package Data Register in STM32WB UM)
|
||||
*/
|
||||
extern uint32_t HW_GetPackageType( void );
|
||||
|
||||
/*
|
||||
* HW_Config_HSE
|
||||
*/
|
||||
void HW_Config_HSE( uint8_t hsetune );
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* AES
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Mode definitions used for HW_AES_SetKey() function */
|
||||
enum
|
||||
{
|
||||
HW_AES_DEC = 0,
|
||||
HW_AES_ENC = 1,
|
||||
HW_AES_REV = 2,
|
||||
HW_AES_SWAP = 4
|
||||
};
|
||||
|
||||
extern int CRYP_MutexTake(void);
|
||||
extern int CRYP_MutexRelease(void);
|
||||
|
||||
/*
|
||||
* HW_AES_Enable
|
||||
*
|
||||
* Enables the AES hardware block.
|
||||
* If the AES was already in use, the function does nothing and returns 0;
|
||||
* otherwise it returns 1.
|
||||
* Be careful: no re-entrance is ensured for the HW_AES functions
|
||||
*/
|
||||
extern int HW_AES_Enable( void );
|
||||
|
||||
/*
|
||||
* HW_AES_SetKey
|
||||
*
|
||||
* Sets the key used for encryption/decryption.
|
||||
* The "mode" parameter must be set to HW_AES_ENC for encryption and to
|
||||
* HW_AES_DEC for decryption. It can be or-ed with HW_AES_REV for a reveresd
|
||||
* oreder of key bytes, and with HW_AES_SWAP to use data byte swapping mode.
|
||||
*/
|
||||
extern void HW_AES_SetKey( uint32_t mode,
|
||||
const uint8_t* key );
|
||||
|
||||
/*
|
||||
* HW_AES_Crypt
|
||||
*
|
||||
* Encrypts/decrypts the 16-byte input data ("input"). Result is written in the
|
||||
* 16-byte buffer ("output") allocated by the user.
|
||||
*/
|
||||
extern void HW_AES_Crypt( const uint32_t* input,
|
||||
uint32_t* output );
|
||||
|
||||
/*
|
||||
* HW_AES_Crypt
|
||||
*
|
||||
* Encrypts/decrypts the 16-byte input data ("input").
|
||||
* Result is written in the 16-byte buffer ("output") allocated by the user.
|
||||
*
|
||||
* Note : input & output are 8 bits aligned.
|
||||
*/
|
||||
extern void HW_AES_Crypt8( const uint8_t* input, uint8_t* output );
|
||||
|
||||
/*
|
||||
* HW_AES_Disable
|
||||
*
|
||||
* Disables the AES hardware block.
|
||||
*/
|
||||
extern void HW_AES_Disable( void );
|
||||
|
||||
/*
|
||||
* HW_AES_InitCcm
|
||||
*
|
||||
* Initilaizes AES for CCM encryption (decrypt = 0) or decryption (decrypt = 1)
|
||||
* Note: B0 and B1 4-word blocks must be provided by user.
|
||||
*
|
||||
*/
|
||||
extern void HW_AES_InitCcm( uint8_t decrypt,
|
||||
const uint8_t* key,
|
||||
const uint32_t* b0,
|
||||
const uint32_t* b1 );
|
||||
|
||||
/*
|
||||
* HW_AES_EndCcm
|
||||
*
|
||||
* Completes CCM processing by computing the authentication tag
|
||||
*
|
||||
*/
|
||||
extern void HW_AES_EndCcm( uint8_t tag_length,
|
||||
uint8_t* tag );
|
||||
|
||||
/*
|
||||
* HW_AES_SetLast
|
||||
*
|
||||
* Function used in CCM processing to indicate the last block of data in
|
||||
* case of decryption
|
||||
*
|
||||
*/
|
||||
extern void HW_AES_SetLast( uint8_t left_length );
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* PKA
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
extern int PKA_MutexTake(void);
|
||||
extern int PKA_MutexRelease(void);
|
||||
|
||||
/*
|
||||
* HW_PKA_Enable
|
||||
*
|
||||
* Enables the PKA hardware block.
|
||||
* If the driver is already in used, the function returns 0 immediately.
|
||||
* If the PKA semaphore is available, this function locks the PKA semaphore,
|
||||
* otherwise it returns 0.
|
||||
* Then, when PKA semaphore is locked, the function enables PKA security,
|
||||
* PKA clock and the block itself.
|
||||
* This function must not be directly called when using P-256 elliptic curve
|
||||
* dedicated functions.
|
||||
* Be careful: no re-entrance is ensured for the HW_PKA functions
|
||||
*/
|
||||
extern int HW_PKA_Enable( void );
|
||||
|
||||
/*
|
||||
* HW_PKA_WriteSingleInput
|
||||
*
|
||||
* Writes one single word into the PKA memory.
|
||||
* This function must not be directly called when using P-256 elliptic curve
|
||||
* dedicated functions.
|
||||
*/
|
||||
extern void HW_PKA_WriteSingleInput( uint32_t index,
|
||||
uint32_t word );
|
||||
|
||||
/*
|
||||
* HW_PKA_WriteOperand
|
||||
*
|
||||
* Writes one operand of size 'n' 32-bit words into the PKA memory.
|
||||
* This function must not be directly called when using P-256 elliptic curve
|
||||
* dedicated functions.
|
||||
*/
|
||||
extern void HW_PKA_WriteOperand( uint32_t index,
|
||||
int size,
|
||||
const uint32_t* in );
|
||||
|
||||
/*
|
||||
* HW_PKA_Start
|
||||
*
|
||||
* Starts the PKA operation with mode defined by the parameter "mode".
|
||||
* This function must not be directly called when using P-256 elliptic curve
|
||||
* dedicated functions.
|
||||
*
|
||||
* "mode" can be one of the LL_PKA_MODE... definitions that can be found
|
||||
* in "stm32wbxx_ll_pka.h" file.
|
||||
*/
|
||||
extern void HW_PKA_Start( uint32_t mode );
|
||||
|
||||
/*
|
||||
* HW_PKA_EndOfOperation
|
||||
*
|
||||
* Returns 0 if the PKA processing is still active.
|
||||
* Returns a value different from 0 when the PKA processing is complete.
|
||||
*/
|
||||
extern int HW_PKA_EndOfOperation( void );
|
||||
|
||||
/*
|
||||
* HW_PKA_ReadSingleOutput
|
||||
*
|
||||
* Reads one 32-bit word result from the PKA memory.
|
||||
* This function must not be directly called when using P-256 elliptic curve
|
||||
* dedicated functions.
|
||||
*/
|
||||
extern uint32_t HW_PKA_ReadSingleOutput( uint32_t index );
|
||||
|
||||
/*
|
||||
* HW_PKA_ReadResult
|
||||
*
|
||||
* Reads one multi-word result ("size" x 32-bit words) from the PKA memory.
|
||||
* This function must not be directly called when using P-256 elliptic curve
|
||||
* dedicated functions.
|
||||
*/
|
||||
extern void HW_PKA_ReadResult( uint32_t index,
|
||||
int size,
|
||||
uint32_t* out );
|
||||
|
||||
/*
|
||||
* HW_PKA_Disable
|
||||
*
|
||||
* Disables the PKA hardware block.
|
||||
* This function disables also the PKA clock and the PKA security.
|
||||
* It then releases the PKA semaphore.
|
||||
*/
|
||||
extern void HW_PKA_Disable( void );
|
||||
|
||||
/*
|
||||
* Notes:
|
||||
*
|
||||
* - this driver uses a semaphore to handle access to the PKA. The index of
|
||||
* the semaphore must be configured with CFG_HW_PKA_SEMID.
|
||||
*/
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* PKA_P256
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* HW_PKA_P256_StartRangeCheck
|
||||
*
|
||||
* Starts the range check of a point coordinate for P-256 elliptic curve.
|
||||
*
|
||||
* This function sets the parameters in PKA memory and then starts the
|
||||
* processing. The PKA has to be enabled before with HW_PKA_Enable( ).
|
||||
* The user must poll on the result availability by calling the
|
||||
* HW_PKA_EndOfOperation() function.
|
||||
*
|
||||
* The input parameter is one the point coordinate. It must be a vector of
|
||||
* 8 x 32-bit words (32 bytes).
|
||||
*
|
||||
* The check result is retrieved by calling HW_PKA_P256_IsRangeCheckOk().
|
||||
*/
|
||||
extern void HW_PKA_P256_StartRangeCheck( const uint32_t* coord );
|
||||
|
||||
/*
|
||||
* HW_PKA_P256_IsRangeCheckOk
|
||||
*
|
||||
* Reads the result of P-256 range check. This function must only be called
|
||||
* when HW_PKA_EndOfOperation() returns a non-zero value.
|
||||
*
|
||||
* Returns 0 if the check fails ; 1 otherwise.
|
||||
*/
|
||||
extern uint32_t HW_PKA_P256_IsRangeCheckOk( void );
|
||||
|
||||
/*
|
||||
* HW_PKA_P256_StartPointCheck
|
||||
*
|
||||
* Starts the check of a point for P-256 elliptic curve.
|
||||
*
|
||||
* This function sets the parameters in PKA memory and then starts the
|
||||
* processing. The PKA has to be enabled before with HW_PKA_Enable( ).
|
||||
* The user must poll on the result availability by calling the
|
||||
* HW_PKA_EndOfOperation() function.
|
||||
*
|
||||
* The input parameters are the point coordinates. Each parameter must be a
|
||||
* vector of 8 x 32-bit words (32 bytes).
|
||||
*
|
||||
* The check result is retrieved by calling HW_PKA_P256_IsPointCheckOk().
|
||||
*/
|
||||
extern void HW_PKA_P256_StartPointCheck( const uint32_t* x,
|
||||
const uint32_t* y );
|
||||
|
||||
/*
|
||||
* HW_PKA_P256_IsPointCheckOk
|
||||
*
|
||||
* Reads the result of P-256 point check. This function must only be called
|
||||
* when HW_PKA_EndOfOperation() returns a non-zero value.
|
||||
*
|
||||
* Returns 0 if the check fails ; 1 otherwise.
|
||||
*/
|
||||
extern uint32_t HW_PKA_P256_IsPointCheckOk( void );
|
||||
|
||||
/*
|
||||
* HW_PKA_P256_StartEccScalarMul
|
||||
*
|
||||
* Starts the PKA scalar multiplication using the P-256 elliptic curve.
|
||||
*
|
||||
* This function sets the parameters in PKA memory and then starts the
|
||||
* processing. The PKA has to be enabled before with HW_PKA_Enable( ).
|
||||
* The user must poll on the result availability by calling the
|
||||
* HW_PKA_EndOfOperation() function.
|
||||
*
|
||||
* The input parameter is the starting point P defined by its 2 coordinates
|
||||
* p_x and p_y, and the scalar k. Each parameter must be a vector of 8 x 32-bit
|
||||
* words (32 bytes).
|
||||
*/
|
||||
extern void HW_PKA_P256_StartEccScalarMul( const uint32_t* k,
|
||||
const uint32_t* p_x,
|
||||
const uint32_t* p_y );
|
||||
|
||||
/*
|
||||
* HW_PKA_P256_ReadEccScalarMul
|
||||
*
|
||||
* Reads the result of PKA scalar multiplication using the P-256 elliptic
|
||||
* curve. This function must only be called when HW_PKA_EndOfOperation()
|
||||
* returns a non-zero value.
|
||||
*
|
||||
* This function retrieves the result from PKA memory: coordinates of point P,
|
||||
* p_x and p_y, 8 x 32-bit words each (2 times 32 bytes).
|
||||
* Before returning, it disables the PKA block, releasing the PKA semaphore.
|
||||
*/
|
||||
extern void HW_PKA_P256_ReadEccScalarMul( uint32_t* p_x,
|
||||
uint32_t* p_y );
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* RNG
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* The RNG driver is made to generate the random numbers in background instead
|
||||
* of generating them each time they are needed by the application.
|
||||
* Thus, the function HW_RNG_Process() must be called regularly in background
|
||||
* loop to generate a pool of random numbers. The function HW_RNG_Get() reads
|
||||
* the random numbers from the pool.
|
||||
* The size of the pool must be configured with HW_RNG_POOL_SIZE.
|
||||
*/
|
||||
|
||||
/* Error codes definition for HW_RNG return values */
|
||||
enum
|
||||
{
|
||||
HW_RNG_CLOCK_ERROR = CFG_HW_ERROR_OFFSET + 0x101,
|
||||
HW_RNG_NOISE_ERROR = CFG_HW_ERROR_OFFSET + 0x102,
|
||||
HW_RNG_UFLOW_ERROR = CFG_HW_ERROR_OFFSET + 0x103,
|
||||
};
|
||||
|
||||
/* RNG pool size */
|
||||
#define HW_RNG_POOL_SIZE (CFG_HW_RNG_POOL_SIZE)
|
||||
/* Default threshold to refill RNG pool */
|
||||
#define HW_RNG_POOL_DEFAULT_THRESHOLD (12)
|
||||
|
||||
extern int RNG_MutexTake(void);
|
||||
extern int RNG_MutexRelease(void);
|
||||
|
||||
/* RNG_KERNEL_CLK_ON
|
||||
*
|
||||
* Enable RNG kernel clock.
|
||||
*/
|
||||
void RNG_KERNEL_CLK_ON(void);
|
||||
|
||||
/* RNG_KERNEL_CLK_OFF
|
||||
*
|
||||
* Called when RNG kernel clock may be disabled.
|
||||
* Weak function to be implemented by user.
|
||||
*/
|
||||
void RNG_KERNEL_CLK_OFF(void);
|
||||
|
||||
/* HW_RNG_Disable
|
||||
*
|
||||
* Disables the RNG peripheral and switch off its clock in RCC.
|
||||
*/
|
||||
extern void HW_RNG_Disable( void );
|
||||
|
||||
/* HW_RNG_Start
|
||||
*
|
||||
* Starts the generation of random numbers using the RNG IP. This function has
|
||||
* to be called only once at reset before calling HW_RNG_Get() to retrieve
|
||||
* the generated random values.
|
||||
*/
|
||||
extern void HW_RNG_Start( void );
|
||||
|
||||
/*
|
||||
* HW_RNG_Get
|
||||
*
|
||||
* Retrieves "n" random 32-bit words.
|
||||
* "n" must be in the range [1, CFG_HW_RNG_POOL_SIZE].
|
||||
* The random numbers are written in memory from "val" pointer.
|
||||
* "val" must point to a sufficient memory buffer allocated by the caller.
|
||||
*/
|
||||
extern void HW_RNG_Get( uint8_t n,
|
||||
uint32_t* val );
|
||||
|
||||
/*
|
||||
* HW_RNG_Process
|
||||
*
|
||||
* This function must be called in a separate task or in "background" loop.
|
||||
* It implements a simple state machine that enables the RNG block,
|
||||
* generates random numbers and then disables the RNG.
|
||||
* It returns 0 (HW_OK) if the low power mode can be entered.
|
||||
* It returns HW_BUSY as long as this function must be called.
|
||||
* In error conditions, it returns one of the following error codes:
|
||||
* - HW_RNG_CLOCK_ERROR for clock error,
|
||||
* - HW_RNG_NOISE_ERROR for noise source error;
|
||||
* the hardware must then be reset.
|
||||
* - HW_RNG_UFLOW_ERROR in case of pool underflow error.
|
||||
*/
|
||||
extern int HW_RNG_Process( void );
|
||||
|
||||
/*
|
||||
* HW_RNG_EnableClock
|
||||
*
|
||||
* This function enables the RNG clock for "other user" than RNG driver itself
|
||||
*/
|
||||
extern void HW_RNG_EnableClock( uint8_t user_mask );
|
||||
|
||||
/*
|
||||
* HW_RNG_DisableClock
|
||||
*
|
||||
* This function disables the RNG clock for "other user" than RNG driver itself
|
||||
*/
|
||||
extern void HW_RNG_DisableClock( uint8_t user_mask );
|
||||
|
||||
extern void HWCB_RNG_Process( void );
|
||||
|
||||
/*
|
||||
* HW_RNG_Init
|
||||
*
|
||||
* This function initializes RNG (clock, configuration ...)
|
||||
*/
|
||||
extern void HW_RNG_Init(void);
|
||||
|
||||
/*
|
||||
* HW_RNG_Init
|
||||
*
|
||||
* Sets RNG pool threshold (for refill)
|
||||
*/
|
||||
extern void HW_RNG_SetPoolThreshold(uint8_t threshold);
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* GPIO
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Index definitions used for all GPIO functions */
|
||||
enum
|
||||
{
|
||||
HW_GPIO_DBG = 0,
|
||||
HW_GPIO_GREEN_LED = 13,
|
||||
HW_GPIO_RED_LED = 14,
|
||||
HW_GPIO_BLUE_LED = 15,
|
||||
};
|
||||
|
||||
/*
|
||||
* HW_GPIO_Init
|
||||
*
|
||||
* This function initilaizes the GPIO pins used for debug.
|
||||
*/
|
||||
extern void HW_GPIO_Init( const uint32_t* dbg_pins );
|
||||
|
||||
/*
|
||||
* HW_GPIO_Read
|
||||
*
|
||||
* This function reads the output pin which index is given in parameter.
|
||||
* It returns 0 if the pin is low, 1 if the pin is high.
|
||||
*/
|
||||
extern uint8_t HW_GPIO_Read( uint8_t index );
|
||||
|
||||
/*
|
||||
* HW_GPIO_Set
|
||||
*
|
||||
* This function sets to high level the output pin which index is given
|
||||
* in parameter.
|
||||
*/
|
||||
extern void HW_GPIO_Set( uint8_t index );
|
||||
|
||||
/*
|
||||
* HW_GPIO_Reset
|
||||
*
|
||||
* This function resets to low level the output pin which index is given
|
||||
* in parameter.
|
||||
*/
|
||||
extern void HW_GPIO_Reset( uint8_t index );
|
||||
|
||||
extern void GPIO_SetDebug( int gpio_pin,
|
||||
int pin_value );
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* OTP
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
typedef __PACKED_STRUCT
|
||||
{
|
||||
uint8_t additional_data[8]; /*!< 64 bits of data to fill OTP slot */
|
||||
uint8_t bd_address[6]; /*!< Bluetooth Device Address*/
|
||||
uint8_t hsetune; /*!< Load capacitance to be applied on HSE pad */
|
||||
uint8_t index; /*!< Structure index */
|
||||
} HW_OTP_data_t;
|
||||
|
||||
/*
|
||||
* HW_OTP_Read
|
||||
*
|
||||
* Read the OTP
|
||||
*
|
||||
*/
|
||||
int HW_OTP_Read( uint8_t index,
|
||||
HW_OTP_data_t** data );
|
||||
|
||||
/*
|
||||
* HW_OTP_Write
|
||||
*
|
||||
* ReadWrite the OTP
|
||||
*
|
||||
*/
|
||||
int HW_OTP_Write( uint8_t* additional_data,
|
||||
uint8_t* bd_address,
|
||||
uint8_t hsetune,
|
||||
uint8_t index );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HW_H__ */
|
||||
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hw_aes.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains the AES driver for STM32WBA
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "app_common.h"
|
||||
#include "stm32wbaxx_ll_bus.h"
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
extern void Error_Handler(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define HW_AESX AES
|
||||
|
||||
#define HW_AES_CLOCK_ENABLE( ) LL_AHB2_GRP1_EnableClock( LL_AHB2_GRP1_PERIPH_AES )
|
||||
#define HW_AES_CLOCK_DISABLE( ) LL_AHB2_GRP1_DisableClock( LL_AHB2_GRP1_PERIPH_AES )
|
||||
|
||||
#define HW_AES_CLOCK_IS_ENABLE( ) LL_AHB2_GRP1_IsEnabledClock( LL_AHB2_GRP1_PERIPH_AES )
|
||||
|
||||
#define AES_BLOCK_SIZE_WORD (4U)
|
||||
#define AES_BLOCK_SIZE_BYTE (16U)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t run;
|
||||
} HW_AES_VAR_T;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static HW_AES_VAR_T HW_AES_var;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
__WEAK int CRYP_MutexTake(void)
|
||||
{
|
||||
return 0; /* This shall be implemented by user */
|
||||
}
|
||||
|
||||
__WEAK int CRYP_MutexRelease(void)
|
||||
{
|
||||
return 0; /* This shall be implemented by user */
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int HW_AES_Enable( void )
|
||||
{
|
||||
HW_AES_VAR_T* av = &HW_AES_var;
|
||||
|
||||
if (0 != CRYP_MutexTake())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Test if the driver is not already in use */
|
||||
if ( HW_AES_CLOCK_IS_ENABLE() )
|
||||
{
|
||||
if (0 != CRYP_MutexRelease())
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
av->run = TRUE;
|
||||
|
||||
UTILS_ENTER_CRITICAL_SECTION( );
|
||||
|
||||
/* Enable AES clock */
|
||||
HW_AES_CLOCK_ENABLE( );
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION( );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_AES_SetKey( uint32_t mode,
|
||||
const uint8_t* key )
|
||||
{
|
||||
uint32_t tmp[4];
|
||||
|
||||
/* Retrieve all bytes of key */
|
||||
memcpy( tmp, key, 16 );
|
||||
|
||||
/* Initialize the AES peripheral with default values:
|
||||
- Processing: disabled
|
||||
- Data type: 32-bit
|
||||
- Operating mode: encryption
|
||||
- Chaining mode: ECB
|
||||
- Key size: 128-bit
|
||||
*/
|
||||
HW_AESX->CR = 0;
|
||||
|
||||
/* Copy key bytes to the AES registers */
|
||||
|
||||
if ( mode & HW_AES_REV )
|
||||
{
|
||||
HW_AESX->KEYR0 = tmp[0];
|
||||
HW_AESX->KEYR1 = tmp[1];
|
||||
HW_AESX->KEYR2 = tmp[2];
|
||||
HW_AESX->KEYR3 = tmp[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
HW_AESX->KEYR3 = __REV( tmp[0] );
|
||||
HW_AESX->KEYR2 = __REV( tmp[1] );
|
||||
HW_AESX->KEYR1 = __REV( tmp[2] );
|
||||
HW_AESX->KEYR0 = __REV( tmp[3] );
|
||||
}
|
||||
|
||||
if ( !(mode & HW_AES_ENC) )
|
||||
{
|
||||
/* Set key preparation mode */
|
||||
HW_AESX->CR = AES_CR_MODE_0;
|
||||
|
||||
/* Enable AES processing */
|
||||
HW_AESX->CR |= AES_CR_EN;
|
||||
|
||||
/* Wait for CCF flag to be raised */
|
||||
while ( ! (HW_AESX->ISR & AES_ISR_CCF) );
|
||||
|
||||
/* Clear CCF Flag */
|
||||
HW_AESX->ICR |= AES_ICR_CCF;
|
||||
|
||||
/* Set decryption mode */
|
||||
HW_AESX->CR = AES_CR_MODE_1;
|
||||
}
|
||||
|
||||
/* Enable byte swapping if needed */
|
||||
if ( mode & HW_AES_SWAP )
|
||||
HW_AESX->CR |= AES_CR_DATATYPE_1;
|
||||
|
||||
/* Wait until KEYVALID is set */
|
||||
while ( !(HW_AESX->SR & AES_SR_KEYVALID) );
|
||||
|
||||
/* Enable AES processing */
|
||||
HW_AESX->CR |= AES_CR_EN;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_AES_Crypt( const uint32_t* input,
|
||||
uint32_t* output )
|
||||
{
|
||||
/* Write the input block into the input FIFO */
|
||||
HW_AESX->DINR = input[0];
|
||||
HW_AESX->DINR = input[1];
|
||||
HW_AESX->DINR = input[2];
|
||||
HW_AESX->DINR = input[3];
|
||||
|
||||
/* Wait for CCF flag to be raised */
|
||||
while ( !(HW_AESX->ISR & AES_ISR_CCF) );
|
||||
|
||||
/* Read the output block from the output FIFO */
|
||||
output[0] = HW_AESX->DOUTR;
|
||||
output[1] = HW_AESX->DOUTR;
|
||||
output[2] = HW_AESX->DOUTR;
|
||||
output[3] = HW_AESX->DOUTR;
|
||||
|
||||
/* Clear CCF Flag */
|
||||
HW_AESX->ICR |= AES_ICR_CCF;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_AES_Disable( void )
|
||||
{
|
||||
HW_AES_VAR_T* av = &HW_AES_var;
|
||||
|
||||
if ( av->run )
|
||||
{
|
||||
/* Disable AES processing */
|
||||
HW_AESX->CR = 0;
|
||||
|
||||
UTILS_ENTER_CRITICAL_SECTION( );
|
||||
|
||||
/* Disable AES clock */
|
||||
HW_AES_CLOCK_DISABLE( );
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION( );
|
||||
|
||||
if (0 != CRYP_MutexRelease())
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
av->run = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_AES_Crypt8( const uint8_t * pInput, uint8_t * pOutput )
|
||||
{
|
||||
uint32_t pTemp[AES_BLOCK_SIZE_WORD];
|
||||
|
||||
// Transfer 8 -> 32 bits */
|
||||
memcpy( pTemp, pInput, AES_BLOCK_SIZE_BYTE );
|
||||
|
||||
/* Write the input block into the input FIFO */
|
||||
HW_AESX->DINR = __REV( pTemp[0] );
|
||||
HW_AESX->DINR = __REV( pTemp[1] );
|
||||
HW_AESX->DINR = __REV( pTemp[2] );
|
||||
HW_AESX->DINR = __REV( pTemp[3] );
|
||||
|
||||
// -- Wait for CCF flag to be raised /
|
||||
while ( (HW_AESX->ISR & AES_ISR_CCF) == 0x00u )
|
||||
{ }
|
||||
|
||||
/* Read the output block from the output FIFO */
|
||||
pTemp[0] = __REV( HW_AESX->DOUTR );
|
||||
pTemp[1] = __REV( HW_AESX->DOUTR );
|
||||
pTemp[2] = __REV( HW_AESX->DOUTR );
|
||||
pTemp[3] = __REV( HW_AESX->DOUTR );
|
||||
|
||||
/* Transfer 32 -> 8 bits */
|
||||
memcpy( pOutput, pTemp, AES_BLOCK_SIZE_BYTE );
|
||||
|
||||
/* Clear CCF Flag */
|
||||
HW_AESX->ICR |= AES_ICR_CCF;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_AES_InitCcm( uint8_t decrypt,
|
||||
const uint8_t* key,
|
||||
const uint32_t* b0,
|
||||
const uint32_t* b1 )
|
||||
{
|
||||
uint32_t tmp[4], mode = decrypt ? AES_CR_MODE_1 : 0;
|
||||
|
||||
/* CCM init phase */
|
||||
HW_AESX->CR = AES_CR_CHMOD_2 | mode;
|
||||
|
||||
/* Copy key bytes to the AES registers */
|
||||
memcpy( tmp, key, 16 );
|
||||
HW_AESX->KEYR0 = tmp[0];
|
||||
HW_AESX->KEYR1 = tmp[1];
|
||||
HW_AESX->KEYR2 = tmp[2];
|
||||
HW_AESX->KEYR3 = tmp[3];
|
||||
|
||||
/* Copy B0 bytes to the AES registers */
|
||||
HW_AESX->IVR3 = __REV( b0[0] );
|
||||
HW_AESX->IVR2 = __REV( b0[1] );
|
||||
HW_AESX->IVR1 = __REV( b0[2] );
|
||||
HW_AESX->IVR0 = __REV( b0[3] );
|
||||
|
||||
/* Enable AES processing */
|
||||
HW_AESX->CR |= AES_CR_EN;
|
||||
|
||||
/* Wait for CCF flag to be raised */
|
||||
while ( ! (HW_AESX->ISR & AES_ISR_CCF) );
|
||||
|
||||
/* Clear CCF Flag */
|
||||
HW_AESX->ICR |= AES_ICR_CCF;
|
||||
|
||||
/* CCM header phase */
|
||||
HW_AESX->CR = AES_CR_CHMOD_2 | AES_CR_GCMPH_0 | AES_CR_DATATYPE_1;
|
||||
|
||||
/* Enable AES processing */
|
||||
HW_AESX->CR |= AES_CR_EN;
|
||||
|
||||
/* Write the header block B1 into the input FIFO */
|
||||
HW_AESX->DINR = b1[0];
|
||||
HW_AESX->DINR = b1[1];
|
||||
HW_AESX->DINR = b1[2];
|
||||
HW_AESX->DINR = b1[3];
|
||||
|
||||
/* Wait for CCF flag to be raised */
|
||||
while ( !(HW_AESX->ISR & AES_ISR_CCF) );
|
||||
|
||||
/* Clear CCF Flag */
|
||||
HW_AESX->ICR |= AES_ICR_CCF;
|
||||
|
||||
/* CCM payload phase */
|
||||
HW_AESX->CR = (AES_CR_EN | AES_CR_CHMOD_2 |
|
||||
AES_CR_GCMPH_1 | AES_CR_DATATYPE_1 | mode);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_AES_EndCcm( uint8_t tag_length,
|
||||
uint8_t* tag )
|
||||
{
|
||||
uint32_t tmp[4];
|
||||
|
||||
/* CCM final phase */
|
||||
HW_AESX->CR = (AES_CR_EN | AES_CR_CHMOD_2 |
|
||||
AES_CR_GCMPH_0 | AES_CR_GCMPH_1 | AES_CR_DATATYPE_1);
|
||||
|
||||
/* Wait for CCF flag to be raised */
|
||||
while ( !(HW_AESX->ISR & AES_ISR_CCF) );
|
||||
|
||||
/* Read the output block from the output FIFO */
|
||||
tmp[0] = HW_AESX->DOUTR;
|
||||
tmp[1] = HW_AESX->DOUTR;
|
||||
tmp[2] = HW_AESX->DOUTR;
|
||||
tmp[3] = HW_AESX->DOUTR;
|
||||
memcpy( tag, tmp, tag_length );
|
||||
|
||||
/* Clear CCF Flag */
|
||||
HW_AESX->ICR |= AES_ICR_CCF;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_AES_SetLast( uint8_t left_length )
|
||||
{
|
||||
HW_AESX->CR |= (16UL - left_length) << AES_CR_NPBLB_Pos;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hw_if.h
|
||||
* @author MCD Application Team
|
||||
* @brief Hardware Interface
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef HW_IF_H
|
||||
#define HW_IF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32wbaxx.h"
|
||||
#include "stm32wbaxx_hal_conf.h"
|
||||
#include "stm32wbaxx_hal_def.h"
|
||||
#include "stm32wbaxx_ll_exti.h"
|
||||
#include "stm32wbaxx_ll_system.h"
|
||||
#include "stm32wbaxx_ll_rcc.h"
|
||||
#include "stm32wbaxx_ll_bus.h"
|
||||
#include "stm32wbaxx_ll_pwr.h"
|
||||
#include "stm32wbaxx_ll_cortex.h"
|
||||
#include "stm32wbaxx_ll_utils.h"
|
||||
#include "stm32wbaxx_ll_gpio.h"
|
||||
#include "stm32wbaxx_ll_rtc.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*HW_IF_H */
|
||||
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hw_otp.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains the OTP driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "app_common.h"
|
||||
#include "stm32wbaxx_hal.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int HW_OTP_Read( uint8_t index, HW_OTP_data_t ** otp_ptr )
|
||||
{
|
||||
/* OTP data:
|
||||
* additional_data 8 bytes LSB
|
||||
* bd_address 6 bytes
|
||||
* hsetune 1 byte
|
||||
* index 1 byte MSB
|
||||
*/
|
||||
*otp_ptr = (HW_OTP_data_t*)(FLASH_OTP_BASE + FLASH_OTP_SIZE - 16);
|
||||
|
||||
while ( ( (*otp_ptr)->index != index ) &&
|
||||
( (*otp_ptr) != (HW_OTP_data_t*) FLASH_OTP_BASE ) )
|
||||
{
|
||||
(*otp_ptr) -= 1;
|
||||
}
|
||||
|
||||
if ( (*otp_ptr)->index != index )
|
||||
{
|
||||
return 1; /* error */
|
||||
}
|
||||
|
||||
return HW_OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int HW_OTP_Write( uint8_t* additional_data,
|
||||
uint8_t* bd_address,
|
||||
uint8_t hsetune,
|
||||
uint8_t index )
|
||||
{
|
||||
int err = 1; /* error */
|
||||
HW_OTP_data_t otp;
|
||||
int i;
|
||||
|
||||
/* Fill OTP_Data_s structure */
|
||||
for ( i = 0; i < sizeof(otp.additional_data); i++ )
|
||||
{
|
||||
otp.additional_data[i] = additional_data[i];
|
||||
}
|
||||
|
||||
for ( i = 0; i < sizeof(otp.bd_address); i++ )
|
||||
{
|
||||
otp.bd_address[i] = bd_address[i];
|
||||
}
|
||||
|
||||
otp.hsetune = hsetune;
|
||||
otp.index = index;
|
||||
|
||||
/* Find free space */
|
||||
uint32_t free_address = FLASH_OTP_BASE;
|
||||
while ( ( *(uint64_t*)(free_address) != 0xFFFFFFFFFFFFFFFFUL ) &&
|
||||
( *(uint64_t*)(free_address + 8u) != 0xFFFFFFFFFFFFFFFFUL ) &&
|
||||
( (free_address + 16u) != FLASH_OTP_BASE + FLASH_OTP_SIZE ) )
|
||||
{
|
||||
free_address += 16;
|
||||
}
|
||||
|
||||
if ( ( *(uint64_t*)(free_address) != 0xFFFFFFFFFFFFFFFFUL ) &&
|
||||
( *(uint64_t*)(free_address + 8u) != 0xFFFFFFFFFFFFFFFFUL ) )
|
||||
{
|
||||
return 1; /* error */
|
||||
}
|
||||
|
||||
/* Store OTP structure in OTP area */
|
||||
|
||||
/* Clear all Flash flags before write operation*/
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
|
||||
|
||||
err = HAL_FLASH_Unlock( );
|
||||
err |= HAL_FLASH_Program( FLASH_NSCR1_PG,
|
||||
free_address, (uint32_t)&otp );
|
||||
err |= HAL_FLASH_Lock( );
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hw_pka.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains the PKA driver for STM32WBA
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "app_common.h"
|
||||
#include "stm32wbaxx_ll_bus.h"
|
||||
#include "stm32wbaxx_ll_pka.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
extern void Error_Handler(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t run;
|
||||
} HW_PKA_VAR_T;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static HW_PKA_VAR_T HW_PKA_var;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
__WEAK int PKA_MutexTake(void)
|
||||
{
|
||||
return 0; /* This shall be implemented by user */
|
||||
}
|
||||
|
||||
__WEAK int PKA_MutexRelease(void)
|
||||
{
|
||||
return 0; /* This shall be implemented by user */
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int HW_PKA_Enable( void )
|
||||
{
|
||||
HW_PKA_VAR_T* pv = &HW_PKA_var;
|
||||
|
||||
/* Test if the driver is not already in use */
|
||||
|
||||
if ( pv->run )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (0 != PKA_MutexTake())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pv->run = TRUE;
|
||||
|
||||
/* Enable the RNG clock as it is needed.
|
||||
* See PKA chapter in IUM: the RNG peripheral must be clocked.
|
||||
*/
|
||||
HW_RNG_EnableClock( 2 );
|
||||
|
||||
UTILS_ENTER_CRITICAL_SECTION( );
|
||||
|
||||
/* Enable the PKA clock */
|
||||
LL_AHB2_GRP1_EnableClock( LL_AHB2_GRP1_PERIPH_PKA );
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION( );
|
||||
|
||||
/* Enable the PKA block */
|
||||
LL_PKA_Enable( PKA );
|
||||
|
||||
/* Wait for PKA initialization OK */
|
||||
while ( !(PKA->SR & PKA_SR_INITOK) );
|
||||
|
||||
/* Reset any pending flag */
|
||||
SET_BIT(PKA->CLRFR, (PKA_CLRFR_PROCENDFC | PKA_CLRFR_RAMERRFC |
|
||||
PKA_CLRFR_ADDRERRFC | PKA_CLRFR_OPERRFC));
|
||||
|
||||
/* Disable the RNG clock as it is no more needed ???
|
||||
*/
|
||||
HW_RNG_DisableClock( 2 );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_PKA_WriteSingleInput( uint32_t index, uint32_t word )
|
||||
{
|
||||
/* Write the single word into PKA RAM */
|
||||
|
||||
PKA->RAM[index] = word;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_PKA_WriteOperand( uint32_t index, int size, const uint32_t* in )
|
||||
{
|
||||
uint32_t* pka_ram = (uint32_t*)&PKA->RAM[index];
|
||||
|
||||
/* Write the input data into PKA RAM */
|
||||
|
||||
for ( ; size > 0; size-- )
|
||||
{
|
||||
*pka_ram++ = *in++;
|
||||
}
|
||||
|
||||
/* Write extra zeros into PKA RAM */
|
||||
|
||||
*pka_ram = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_PKA_Start( uint32_t mode )
|
||||
{
|
||||
/* Set the configuration */
|
||||
LL_PKA_Config( PKA, mode );
|
||||
|
||||
/* Start the PKA processing */
|
||||
LL_PKA_ClearFlag_PROCEND( PKA );
|
||||
LL_PKA_Start( PKA );
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int HW_PKA_EndOfOperation( void )
|
||||
{
|
||||
/* Return 0 if the processing is still active */
|
||||
return LL_PKA_IsActiveFlag_PROCEND( PKA );
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
uint32_t HW_PKA_ReadSingleOutput( uint32_t index )
|
||||
{
|
||||
/* Read a single word from PKA RAM */
|
||||
|
||||
return PKA->RAM[index];
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_PKA_ReadResult( uint32_t index, int size, uint32_t* out )
|
||||
{
|
||||
uint32_t* pka_ram = (uint32_t*)&PKA->RAM[index];
|
||||
|
||||
/* Read from PKA RAM */
|
||||
|
||||
for ( ; size > 0; size-- )
|
||||
{
|
||||
*out++ = *pka_ram++;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_PKA_Disable( void )
|
||||
{
|
||||
HW_PKA_VAR_T* pv = &HW_PKA_var;
|
||||
|
||||
if ( pv->run )
|
||||
{
|
||||
/* Disable the PKA block */
|
||||
LL_PKA_Disable( PKA );
|
||||
|
||||
UTILS_ENTER_CRITICAL_SECTION( );
|
||||
|
||||
/* Disable the PKA clock */
|
||||
LL_AHB2_GRP1_DisableClock( LL_AHB2_GRP1_PERIPH_PKA );
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION( );
|
||||
|
||||
if (0 != PKA_MutexRelease())
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
pv->run = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -0,0 +1,235 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hw_pka_p256.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file is an optional part of the PKA driver for STM32WBA.
|
||||
* It is dedicated to the P256 elliptic curve.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "app_common.h"
|
||||
#include "stm32wbaxx_ll_pka.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const uint32_t HW_PKA_P256_gfp[8] =
|
||||
{
|
||||
0xFFFFFFFF, /* LSB */
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000001,
|
||||
0xFFFFFFFF,
|
||||
};
|
||||
|
||||
static const uint32_t HW_PKA_P256_r2[8] =
|
||||
{
|
||||
0x00000002, /* LSB */
|
||||
0x00000005,
|
||||
0x00000003,
|
||||
0xFFFFFFFE,
|
||||
0xFFFFFFF9,
|
||||
0xFFFFFFFB,
|
||||
0xFFFFFFFC,
|
||||
0xFFFFFFFC,
|
||||
};
|
||||
|
||||
static const uint32_t HW_PKA_P256_p_x[8] =
|
||||
{
|
||||
0xD898C296, /* LSB */
|
||||
0xF4A13945,
|
||||
0x2DEB33A0,
|
||||
0x77037D81,
|
||||
0x63A440F2,
|
||||
0xF8BCE6E5,
|
||||
0xE12C4247,
|
||||
0x6B17D1F2,
|
||||
};
|
||||
|
||||
static const uint32_t HW_PKA_P256_p_y[8] =
|
||||
{
|
||||
0x37BF51F5, /* LSB */
|
||||
0xCBB64068,
|
||||
0x6B315ECE,
|
||||
0x2BCE3357,
|
||||
0x7C0F9E16,
|
||||
0x8EE7EB4A,
|
||||
0xFE1A7F9B,
|
||||
0x4FE342E2,
|
||||
};
|
||||
|
||||
static const uint32_t HW_PKA_P256_a[8] =
|
||||
{
|
||||
0x00000003, /* LSB */
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
};
|
||||
|
||||
static const uint32_t HW_PKA_P256_b[8] =
|
||||
{
|
||||
0x27D2604B, /* LSB */
|
||||
0x3BCE3C3E,
|
||||
0xCC53B0F6,
|
||||
0x651D06B0,
|
||||
0x769886BC,
|
||||
0xB3EBBD55,
|
||||
0xAA3A93E7,
|
||||
0x5AC635D8,
|
||||
};
|
||||
|
||||
static const uint32_t HW_PKA_P256_n[8] =
|
||||
{
|
||||
0XFC632551, /* LSB */
|
||||
0XF3B9CAC2,
|
||||
0XA7179E84,
|
||||
0XBCE6FAAD,
|
||||
0XFFFFFFFF,
|
||||
0XFFFFFFFF,
|
||||
0X00000000,
|
||||
0XFFFFFFFF
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_PKA_P256_StartRangeCheck( const uint32_t* coord )
|
||||
{
|
||||
/* Set the muber of bits of P */
|
||||
HW_PKA_WriteSingleInput( PKA_COMPARISON_IN_OP_NB_BITS, 256 );
|
||||
|
||||
/* Set the coordinate */
|
||||
HW_PKA_WriteOperand( PKA_COMPARISON_IN_OP1, 8, coord );
|
||||
|
||||
/* Set the modulus value p */
|
||||
HW_PKA_WriteOperand( PKA_COMPARISON_IN_OP2, 8, HW_PKA_P256_gfp );
|
||||
|
||||
/* Start PKA hardware */
|
||||
HW_PKA_Start( LL_PKA_MODE_COMPARISON );
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
uint32_t HW_PKA_P256_IsRangeCheckOk( void )
|
||||
{
|
||||
return (HW_PKA_ReadSingleOutput( PKA_COMPARISON_OUT_RESULT ) == 0x916AUL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_PKA_P256_StartPointCheck( const uint32_t* x,
|
||||
const uint32_t* y )
|
||||
{
|
||||
/* Set the muber of bits of p */
|
||||
HW_PKA_WriteSingleInput( PKA_POINT_CHECK_IN_MOD_NB_BITS, 256 );
|
||||
|
||||
/* Set the coefficient a sign */
|
||||
HW_PKA_WriteSingleInput( PKA_POINT_CHECK_IN_A_COEFF_SIGN, 1 );
|
||||
|
||||
/* Set the coefficient |a| */
|
||||
HW_PKA_WriteOperand( PKA_POINT_CHECK_IN_A_COEFF, 8, HW_PKA_P256_a );
|
||||
|
||||
/* Set the coefficient b */
|
||||
HW_PKA_WriteOperand( PKA_POINT_CHECK_IN_B_COEFF, 8, HW_PKA_P256_b );
|
||||
|
||||
/* Set the modulus value p */
|
||||
HW_PKA_WriteOperand( PKA_POINT_CHECK_IN_MOD_GF, 8, HW_PKA_P256_gfp );
|
||||
|
||||
/* Set the point coordinate x */
|
||||
HW_PKA_WriteOperand( PKA_POINT_CHECK_IN_INITIAL_POINT_X, 8, x );
|
||||
|
||||
/* Set the point coordinate y */
|
||||
HW_PKA_WriteOperand( PKA_POINT_CHECK_IN_INITIAL_POINT_Y, 8, y );
|
||||
|
||||
/* Set the Montgomery parameter */
|
||||
HW_PKA_WriteOperand( PKA_POINT_CHECK_IN_MONTGOMERY_PARAM,
|
||||
8, HW_PKA_P256_r2 );
|
||||
|
||||
/* Start PKA hardware */
|
||||
HW_PKA_Start( LL_PKA_MODE_POINT_CHECK );
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
uint32_t HW_PKA_P256_IsPointCheckOk( void )
|
||||
{
|
||||
return (HW_PKA_ReadSingleOutput( PKA_POINT_CHECK_OUT_ERROR ) == 0xD60DUL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_PKA_P256_StartEccScalarMul( const uint32_t* k,
|
||||
const uint32_t* p_x,
|
||||
const uint32_t* p_y )
|
||||
{
|
||||
/* Set the scalar multiplier k length */
|
||||
HW_PKA_WriteSingleInput( PKA_ECC_SCALAR_MUL_IN_EXP_NB_BITS, 256 );
|
||||
|
||||
/* Set the modulus length */
|
||||
HW_PKA_WriteSingleInput( PKA_ECC_SCALAR_MUL_IN_OP_NB_BITS, 256 );
|
||||
|
||||
/* Set the coefficient a sign */
|
||||
HW_PKA_WriteSingleInput( PKA_ECC_SCALAR_MUL_IN_A_COEFF_SIGN, 1 );
|
||||
|
||||
/* Set the coefficient |a| */
|
||||
HW_PKA_WriteOperand( PKA_ECC_SCALAR_MUL_IN_A_COEFF, 8, HW_PKA_P256_a );
|
||||
|
||||
/* Set the coefficient b */
|
||||
HW_PKA_WriteOperand( PKA_ECC_SCALAR_MUL_IN_B_COEFF, 8, HW_PKA_P256_b );
|
||||
|
||||
/* Set the modulus value p */
|
||||
HW_PKA_WriteOperand( PKA_ECC_SCALAR_MUL_IN_MOD_GF, 8, HW_PKA_P256_gfp );
|
||||
|
||||
/* Set the scalar multiplier k */
|
||||
HW_PKA_WriteOperand( PKA_ECC_SCALAR_MUL_IN_K, 8, k );
|
||||
|
||||
/* Set the point P coordinate x */
|
||||
HW_PKA_WriteOperand( PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_X,
|
||||
8, p_x ? p_x : HW_PKA_P256_p_x );
|
||||
|
||||
/* Set the point P coordinate y */
|
||||
HW_PKA_WriteOperand( PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_Y,
|
||||
8, p_y ? p_y : HW_PKA_P256_p_y );
|
||||
|
||||
/* Set the prime order n */
|
||||
HW_PKA_WriteOperand( PKA_ECC_SCALAR_MUL_IN_N_PRIME_ORDER,
|
||||
8, HW_PKA_P256_n );
|
||||
|
||||
/* Start PKA hardware */
|
||||
HW_PKA_Start( LL_PKA_MODE_ECC_MUL );
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_PKA_P256_ReadEccScalarMul( uint32_t* p_x,
|
||||
uint32_t* p_y )
|
||||
{
|
||||
/* Read the output point X */
|
||||
if ( p_x )
|
||||
{
|
||||
HW_PKA_ReadResult( PKA_ECC_SCALAR_MUL_OUT_RESULT_X, 8, p_x );
|
||||
}
|
||||
|
||||
/* Read the output point Y as the second half of the result */
|
||||
if ( p_y )
|
||||
{
|
||||
HW_PKA_ReadResult( PKA_ECC_SCALAR_MUL_OUT_RESULT_Y, 8, p_y );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -0,0 +1,388 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hw_rng.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains the RNG driver for STM32WBA
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "app_common.h"
|
||||
#include "stm32wbaxx_ll_bus.h"
|
||||
#include "stm32wbaxx_ll_rng.h"
|
||||
#include "RTDebug.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
extern void Error_Handler(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
__WEAK int RNG_MutexTake(void)
|
||||
{
|
||||
return 0; /* This shall be implemented by user */
|
||||
}
|
||||
|
||||
__WEAK int RNG_MutexRelease(void)
|
||||
{
|
||||
return 0; /* This shall be implemented by user */
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
__weak void RNG_KERNEL_CLK_ON(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the RNG_KERNEL_CLK_ON could be implemented in the user file
|
||||
*/
|
||||
LL_RCC_HSI_Enable();
|
||||
while(LL_RCC_HSI_IsReady() == 0)
|
||||
{
|
||||
LL_RCC_HSI_Enable();
|
||||
}
|
||||
}
|
||||
|
||||
__weak void RNG_KERNEL_CLK_OFF(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the RNG_KERNEL_CLK_OFF could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t pool[HW_RNG_POOL_SIZE];
|
||||
uint8_t size;
|
||||
uint8_t run;
|
||||
uint8_t clock_en;
|
||||
int error;
|
||||
} HW_RNG_VAR_T;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static HW_RNG_VAR_T HW_RNG_var;
|
||||
|
||||
static uint8_t hw_rng_pool_threshold = HW_RNG_POOL_DEFAULT_THRESHOLD;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void HW_RNG_WaitingClockSynchronization( void );
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_RNG_Disable( void )
|
||||
{
|
||||
SYSTEM_DEBUG_SIGNAL_SET(RNG_DISABLE);
|
||||
|
||||
LL_RNG_Disable( RNG );
|
||||
|
||||
/* Disable RNG clocks */
|
||||
HW_RNG_DisableClock( 1 );
|
||||
|
||||
SYSTEM_DEBUG_SIGNAL_RESET(RNG_DISABLE);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_RNG_EnableClock( uint8_t user_mask )
|
||||
{
|
||||
HW_RNG_VAR_T* pv = &HW_RNG_var;
|
||||
|
||||
RNG_KERNEL_CLK_ON();
|
||||
|
||||
UTILS_ENTER_CRITICAL_SECTION( );
|
||||
|
||||
if ( pv->clock_en == 0 )
|
||||
{
|
||||
LL_AHB2_GRP1_EnableClock( LL_AHB2_GRP1_PERIPH_RNG );
|
||||
}
|
||||
|
||||
pv->clock_en |= user_mask;
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION( );
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_RNG_DisableClock( uint8_t user_mask )
|
||||
{
|
||||
HW_RNG_VAR_T* pv = &HW_RNG_var;
|
||||
|
||||
{
|
||||
UTILS_ENTER_CRITICAL_SECTION( );
|
||||
|
||||
pv->clock_en &= ~user_mask;
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION( );
|
||||
}
|
||||
|
||||
/* It does not matter much if the temporisation is executed even though
|
||||
* in the meantime pv->clock_en has been updated and is not more equal to 0
|
||||
*/
|
||||
if ( pv->clock_en == 0 )
|
||||
{
|
||||
HW_RNG_WaitingClockSynchronization( );
|
||||
}
|
||||
|
||||
{
|
||||
UTILS_ENTER_CRITICAL_SECTION( );
|
||||
|
||||
if ( pv->clock_en == 0 )
|
||||
{
|
||||
LL_AHB2_GRP1_DisableClock( LL_AHB2_GRP1_PERIPH_RNG );
|
||||
}
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION( );
|
||||
}
|
||||
|
||||
RNG_KERNEL_CLK_OFF();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Wait for 2 RNG kernel clock.
|
||||
* Loop is sized with worst case : RNG kernel clock = 32Khz
|
||||
*/
|
||||
static void HW_RNG_WaitingClockSynchronization( void )
|
||||
{
|
||||
/* RNG busy flag is not available in STM32WBA5xxx */
|
||||
#if defined(STM32WBA52xx) || defined(STM32WBA54xx) || defined(STM32WBA55xx) || defined(STM32WBA5Mxx)
|
||||
volatile unsigned int cpt;
|
||||
|
||||
for(cpt = 178 ; cpt!=0 ; --cpt);
|
||||
#else
|
||||
/* wait until RNG_SR_BUSY (bit 4) is cleared */
|
||||
while(RNG->SR & (1 << 4));
|
||||
#endif /* defined(STM32WBA52xx) || defined(STM32WBA54xx) || defined(STM32WBA55xx) || defined(STM32WBA5Mxx) */
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* HW_RNG_Run: this function must be called in loop.
|
||||
* It implenments a simple state machine that enables the RNG,
|
||||
* fills the pool with generated random numbers and then disables the RNG.
|
||||
* It always returns 0 in normal conditions. In error conditions, it returns
|
||||
* an error code different from 0.
|
||||
*/
|
||||
static int HW_RNG_Run(HW_RNG_VAR_T* pv)
|
||||
{
|
||||
int i, error = HW_OK;
|
||||
|
||||
/* check for RNG clock error */
|
||||
if (LL_RNG_IsActiveFlag_CECS(RNG))
|
||||
{
|
||||
/* Clear RNG clock error interrupt status flags */
|
||||
LL_RNG_ClearFlag_CEIS(RNG);
|
||||
|
||||
error = HW_RNG_CLOCK_ERROR;
|
||||
}
|
||||
|
||||
/* check for RNG seed error */
|
||||
if (LL_RNG_IsActiveFlag_SEIS(RNG))
|
||||
{
|
||||
/* Clear RNG seed error interrupt status flags */
|
||||
LL_RNG_ClearFlag_SEIS(RNG);
|
||||
|
||||
/* Discard 12 words from RNG_DR in order to clean the pipeline */
|
||||
for ( i = 12; i > 0; i-- )
|
||||
{
|
||||
LL_RNG_ReadRandData32(RNG);
|
||||
}
|
||||
|
||||
error = HW_RNG_NOISE_ERROR;
|
||||
}
|
||||
|
||||
/* if the pool is not full, read the H/W generated values until the pool is full */
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
SYSTEM_DEBUG_SIGNAL_SET(RNG_GEN_RAND_NUM);
|
||||
|
||||
while (pv->size < HW_RNG_POOL_SIZE)
|
||||
{
|
||||
if (LL_RNG_IsActiveFlag_DRDY(RNG))
|
||||
{
|
||||
pv->pool[pv->size] = LL_RNG_ReadRandData32(RNG);
|
||||
pv->size++;
|
||||
}
|
||||
}
|
||||
|
||||
SYSTEM_DEBUG_SIGNAL_RESET(RNG_GEN_RAND_NUM);
|
||||
UTILS_EXIT_CRITICAL_SECTION( );
|
||||
|
||||
/* pool is full, disable the RNG and its RCC clock */
|
||||
HW_RNG_Disable( );
|
||||
|
||||
/* Reset flag indicating that the RNG is ON */
|
||||
pv->run = FALSE;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_RNG_Start( void )
|
||||
{
|
||||
HW_RNG_VAR_T* pv = &HW_RNG_var;
|
||||
|
||||
/* Reset global variables */
|
||||
pv->size = 0;
|
||||
pv->run = FALSE;
|
||||
pv->error = HW_OK;
|
||||
pv->clock_en = 0;
|
||||
|
||||
if (0 != RNG_MutexTake())
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* Fill the random numbers pool by calling the "run" function */
|
||||
do
|
||||
{
|
||||
pv->error = HW_RNG_Run( pv );
|
||||
}
|
||||
while ( pv->run && !pv->error );
|
||||
|
||||
if (0 != RNG_MutexRelease())
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void HW_RNG_Get( uint8_t n, uint32_t* val )
|
||||
{
|
||||
HW_RNG_VAR_T* pv = &HW_RNG_var;
|
||||
uint32_t pool_value;
|
||||
|
||||
while ( n-- )
|
||||
{
|
||||
UTILS_ENTER_CRITICAL_SECTION( );
|
||||
|
||||
if ( pv->size == 0 )
|
||||
{
|
||||
pv->error = HW_RNG_UFLOW_ERROR;
|
||||
pool_value = ~pv->pool[HW_RNG_POOL_SIZE - n];
|
||||
}
|
||||
else
|
||||
{
|
||||
pool_value = pv->pool[--pv->size];
|
||||
}
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION( );
|
||||
|
||||
*val++ = pool_value;
|
||||
}
|
||||
|
||||
/* Call the process callback function to fill the pool offline */
|
||||
HWCB_RNG_Process( );
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int HW_RNG_Process( void )
|
||||
{
|
||||
HW_RNG_VAR_T* pv = &HW_RNG_var;
|
||||
int status = HW_OK;
|
||||
|
||||
if (0 != RNG_MutexTake())
|
||||
{
|
||||
status = HW_BUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if the process is not done or if the pool is not full */
|
||||
if (pv->size < hw_rng_pool_threshold)
|
||||
{
|
||||
HW_RNG_Init();
|
||||
UTILS_ENTER_CRITICAL_SECTION( );
|
||||
|
||||
/* Check if an error occurred during a previous call to HW_RNG API */
|
||||
status = pv->error;
|
||||
pv->error = HW_OK;
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION( );
|
||||
|
||||
if ( status == HW_OK )
|
||||
{
|
||||
/* Call the "run" function that generates random data */
|
||||
status = HW_RNG_Run( pv );
|
||||
|
||||
/* If the process is not done, return "busy" status */
|
||||
if ( (status == HW_OK) && pv->run )
|
||||
{
|
||||
status = HW_BUSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != RNG_MutexRelease())
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
if (status != HW_OK)
|
||||
{
|
||||
HWCB_RNG_Process( );
|
||||
}
|
||||
|
||||
/* Return status */
|
||||
return status;
|
||||
}
|
||||
|
||||
void HW_RNG_Init(void)
|
||||
{
|
||||
HW_RNG_VAR_T* pv = &HW_RNG_var;
|
||||
|
||||
SYSTEM_DEBUG_SIGNAL_SET(RNG_ENABLE);
|
||||
|
||||
LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_HSI);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_RNG);
|
||||
LL_RNG_Disable(RNG);
|
||||
while(LL_RNG_IsEnabled(RNG));
|
||||
|
||||
/* Recommended value for NIST compliance, refer to application note AN4230 */
|
||||
/* Using LL macros to set these values is not convenient as it's split
|
||||
in 3 parts and need some bit polling at each step to check completion.
|
||||
So, for efficiency, register direct access */
|
||||
WRITE_REG(RNG->CR, RNG_CR_NIST_VALUE | RNG_CR_CONDRST | RNG_CED_DISABLE);
|
||||
/* Recommended value for NIST compliance, refer to application note AN4230 */
|
||||
|
||||
LL_RNG_DisableClkErrorDetect(RNG);
|
||||
LL_RNG_DisableCondReset(RNG);
|
||||
|
||||
#if !(defined(STM32WBA52xx) || defined(STM32WBA54xx) || defined(STM32WBA55xx) || defined(STM32WBA5Mxx))
|
||||
while((RNG->SR & (1 << 4)));
|
||||
#endif
|
||||
|
||||
while(LL_RNG_IsEnabledCondReset(RNG));
|
||||
|
||||
LL_RNG_SetHealthConfig(RNG,RNG_HTCR_NIST_VALUE);
|
||||
|
||||
LL_RNG_Enable(RNG);
|
||||
while(!LL_RNG_IsActiveFlag_DRDY(RNG)); /*wait for data to be ready*/
|
||||
|
||||
pv->run = TRUE;
|
||||
SYSTEM_DEBUG_SIGNAL_RESET(RNG_ENABLE);
|
||||
}
|
||||
|
||||
|
||||
void HW_RNG_SetPoolThreshold(uint8_t threshold)
|
||||
{
|
||||
if(threshold < HW_RNG_POOL_SIZE)
|
||||
{
|
||||
hw_rng_pool_threshold = threshold;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file timer_if.c
|
||||
* @author MCD Application Team
|
||||
* @brief Configure RTC Alarm, Tick and Calendar manager
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <math.h>
|
||||
|
||||
#include "stm32wbaxx_hal.h"
|
||||
#include "stm32wbaxx_hal_conf.h"
|
||||
#include "stm32wbaxx_ll_rtc.h"
|
||||
|
||||
#include "timer_if.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Minimum timeout delay of Alarm in ticks
|
||||
*/
|
||||
#define MIN_ALARM_DELAY 3
|
||||
|
||||
/**
|
||||
* @brief Backup seconds register
|
||||
*/
|
||||
#define RTC_BKP_SECONDS RTC_BKP_DR0
|
||||
|
||||
/**
|
||||
* @brief Backup subseconds register
|
||||
*/
|
||||
#define RTC_BKP_SUBSECONDS RTC_BKP_DR1
|
||||
|
||||
/**
|
||||
* @brief Backup msbticks register
|
||||
*/
|
||||
#define RTC_BKP_MSBTICKS RTC_BKP_DR2
|
||||
|
||||
/* #define RTIF_DEBUG */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Timer driver callbacks handler
|
||||
*/
|
||||
const UTIL_TIMER_Driver_s UTIL_TimerDriver =
|
||||
{
|
||||
TIMER_IF_Init,
|
||||
NULL,
|
||||
|
||||
TIMER_IF_StartTimer,
|
||||
TIMER_IF_StopTimer,
|
||||
|
||||
TIMER_IF_SetTimerContext,
|
||||
TIMER_IF_GetTimerContext,
|
||||
|
||||
TIMER_IF_GetTimerElapsedTime,
|
||||
TIMER_IF_GetTimerValue,
|
||||
TIMER_IF_GetMinimumTimeout,
|
||||
|
||||
TIMER_IF_Convert_ms2Tick,
|
||||
TIMER_IF_Convert_Tick2ms,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief SysTime driver callbacks handler
|
||||
*/
|
||||
const UTIL_SYSTIM_Driver_s UTIL_SYSTIMDriver =
|
||||
{
|
||||
TIMER_IF_BkUp_Write_Seconds,
|
||||
TIMER_IF_BkUp_Read_Seconds,
|
||||
TIMER_IF_BkUp_Write_SubSeconds,
|
||||
TIMER_IF_BkUp_Read_SubSeconds,
|
||||
TIMER_IF_GetTime,
|
||||
};
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/**
|
||||
* @brief RTC handle
|
||||
*/
|
||||
extern RTC_HandleTypeDef hrtc;
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Indicates if the RTC is already Initialized or not
|
||||
*/
|
||||
static bool RTC_Initialized = 0;
|
||||
|
||||
/**
|
||||
* @brief RtcTimerContext
|
||||
*/
|
||||
static uint32_t RtcTimerContext = 0;
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef RTIF_DEBUG
|
||||
#include "sys_app.h" /*for app_log*/
|
||||
/**
|
||||
* @brief Post the RTC log string format to the circular queue for printing in using the polling mode
|
||||
*/
|
||||
#define TIMER_IF_DBG_PRINTF(...) do{ {UTIL_ADV_TRACE_COND_FSend(VLEVEL_ALWAYS, T_REG_OFF, TS_OFF, __VA_ARGS__);} }while(0);
|
||||
#else
|
||||
/**
|
||||
* @brief not used
|
||||
*/
|
||||
#define TIMER_IF_DBG_PRINTF(...)
|
||||
#endif /* RTIF_DEBUG */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/**
|
||||
* @brief Get rtc timer Value in rtc tick
|
||||
* @return val the rtc timer value (upcounting)
|
||||
*/
|
||||
static inline uint32_t GetTimerTicks(void);
|
||||
|
||||
/**
|
||||
* @brief Writes MSBticks to backup register
|
||||
* Absolute RTC time in tick is (MSBticks)<<32 + (32bits binary counter)
|
||||
* @note MSBticks incremented every time the 32bits RTC timer wraps around (~44days)
|
||||
* @param[in] MSBticks
|
||||
* @return none
|
||||
*/
|
||||
static void TIMER_IF_BkUp_Write_MSBticks(uint32_t MSBticks);
|
||||
|
||||
/**
|
||||
* @brief Reads MSBticks from backup register
|
||||
* Absolute RTC time in tick is (MSBticks)<<32 + (32bits binary counter)
|
||||
* @note MSBticks incremented every time the 32bits RTC timer wraps around (~44days)
|
||||
* @retval MSBticks
|
||||
*/
|
||||
static uint32_t TIMER_IF_BkUp_Read_MSBticks(void);
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
|
||||
UTIL_TIMER_Status_t TIMER_IF_Init(void)
|
||||
{
|
||||
UTIL_TIMER_Status_t ret = UTIL_TIMER_OK;
|
||||
|
||||
if (RTC_Initialized == false)
|
||||
{
|
||||
/* Stop Timer */
|
||||
TIMER_IF_StopTimer();
|
||||
|
||||
/* DeActivate the Alarm A enabled by MX during MX_RTC_Init() */
|
||||
HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A);
|
||||
|
||||
/* Enable Direct Read of the calendar registers (not through Shadow) */
|
||||
HAL_RTCEx_EnableBypassShadow(&hrtc);
|
||||
|
||||
/* Initialise MSB ticks */
|
||||
TIMER_IF_BkUp_Write_MSBticks(0);
|
||||
|
||||
TIMER_IF_SetTimerContext();
|
||||
|
||||
RTC_Initialized = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
UTIL_TIMER_Status_t TIMER_IF_StartTimer(uint32_t timeout)
|
||||
{
|
||||
UTIL_TIMER_Status_t ret = UTIL_TIMER_OK;
|
||||
|
||||
RTC_AlarmTypeDef sAlarm = {0};
|
||||
|
||||
/* Stop timer if one is already started */
|
||||
TIMER_IF_StopTimer();
|
||||
timeout += RtcTimerContext;
|
||||
|
||||
TIMER_IF_DBG_PRINTF("Start timer: time=%d, alarm=%d\n\r", GetTimerTicks(), timeout);
|
||||
|
||||
/* Starts timer */
|
||||
sAlarm.BinaryAutoClr = RTC_ALARMSUBSECONDBIN_AUTOCLR_NO;
|
||||
sAlarm.AlarmTime.SubSeconds = UINT32_MAX - timeout;
|
||||
sAlarm.AlarmMask = RTC_ALARMMASK_NONE;
|
||||
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDBINMASK_NONE;
|
||||
sAlarm.Alarm = RTC_ALARM_A;
|
||||
|
||||
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
|
||||
{
|
||||
/* Initialization Error */
|
||||
while(1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
UTIL_TIMER_Status_t TIMER_IF_StopTimer(void)
|
||||
{
|
||||
UTIL_TIMER_Status_t ret = UTIL_TIMER_OK;
|
||||
|
||||
/* Clear RTC Alarm Flag */
|
||||
__HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAF);
|
||||
|
||||
/* Disable the Alarm A interrupt */
|
||||
HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t TIMER_IF_SetTimerContext(void)
|
||||
{
|
||||
/* Store time context */
|
||||
RtcTimerContext = GetTimerTicks();
|
||||
|
||||
TIMER_IF_DBG_PRINTF("TIMER_IF_SetTimerContext=%d\n\r", RtcTimerContext);
|
||||
|
||||
/* Return time context */
|
||||
return RtcTimerContext;
|
||||
}
|
||||
|
||||
uint32_t TIMER_IF_GetTimerContext(void)
|
||||
{
|
||||
TIMER_IF_DBG_PRINTF("TIMER_IF_GetTimerContext=%d\n\r", RtcTimerContext);
|
||||
|
||||
/* Return time context */
|
||||
return RtcTimerContext;
|
||||
}
|
||||
|
||||
uint32_t TIMER_IF_GetTimerElapsedTime(void)
|
||||
{
|
||||
return ((uint32_t)(GetTimerTicks() - RtcTimerContext));
|
||||
}
|
||||
|
||||
uint32_t TIMER_IF_GetTimerValue(void)
|
||||
{
|
||||
if (RTC_Initialized == true)
|
||||
{
|
||||
return GetTimerTicks();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t TIMER_IF_GetMinimumTimeout(void)
|
||||
{
|
||||
return (MIN_ALARM_DELAY);
|
||||
}
|
||||
|
||||
uint32_t TIMER_IF_Convert_ms2Tick(uint32_t timeMilliSec)
|
||||
{
|
||||
return ((uint32_t)( ( ( (uint64_t) timeMilliSec ) << RTC_N_PREDIV_S ) / 1000U ) );
|
||||
}
|
||||
|
||||
uint32_t TIMER_IF_Convert_Tick2ms(uint32_t tick)
|
||||
{
|
||||
return ((uint32_t)( ( ( ( int64_t)( tick ) ) * 1000U ) >> RTC_N_PREDIV_S ) );
|
||||
}
|
||||
|
||||
void TIMER_IF_DelayMs(uint32_t delay)
|
||||
{
|
||||
uint32_t delayTicks = TIMER_IF_Convert_ms2Tick(delay);
|
||||
uint32_t timeout = GetTimerTicks();
|
||||
|
||||
/* Wait delay ms */
|
||||
while (((GetTimerTicks() - timeout)) < delayTicks)
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
UTIL_TIMER_IRQ_Handler();
|
||||
}
|
||||
|
||||
void HAL_RTCEx_SSRUEventCallback(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
/* Called every 48 days with 1024 ticks per seconds */
|
||||
TIMER_IF_DBG_PRINTF(">>Handler SSRUnderflow at %d\n\r", GetTimerTicks());
|
||||
|
||||
/* Increment MSBticks */
|
||||
uint32_t MSB_ticks = TIMER_IF_BkUp_Read_MSBticks();
|
||||
TIMER_IF_BkUp_Write_MSBticks(MSB_ticks + 1);
|
||||
}
|
||||
|
||||
uint32_t TIMER_IF_GetTime(uint16_t *mSeconds)
|
||||
{
|
||||
uint64_t ticks;
|
||||
uint32_t timerValueLsb = GetTimerTicks();
|
||||
uint32_t timerValueMSB = TIMER_IF_BkUp_Read_MSBticks();
|
||||
|
||||
ticks = (((uint64_t) timerValueMSB) << 32) + timerValueLsb;
|
||||
|
||||
uint32_t seconds = (uint32_t)(ticks >> RTC_N_PREDIV_S);
|
||||
|
||||
ticks = (uint32_t) ticks & RTC_PREDIV_S;
|
||||
|
||||
*mSeconds = TIMER_IF_Convert_Tick2ms(ticks);
|
||||
|
||||
return seconds;
|
||||
}
|
||||
|
||||
void TIMER_IF_BkUp_Write_Seconds(uint32_t Seconds)
|
||||
{
|
||||
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_SECONDS, Seconds);
|
||||
}
|
||||
|
||||
void TIMER_IF_BkUp_Write_SubSeconds(uint32_t SubSeconds)
|
||||
{
|
||||
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_SUBSECONDS, SubSeconds);
|
||||
}
|
||||
|
||||
uint32_t TIMER_IF_BkUp_Read_Seconds(void)
|
||||
{
|
||||
return HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_SECONDS);
|
||||
}
|
||||
|
||||
uint32_t TIMER_IF_BkUp_Read_SubSeconds(void)
|
||||
{
|
||||
return HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_SUBSECONDS);
|
||||
}
|
||||
|
||||
static void TIMER_IF_BkUp_Write_MSBticks(uint32_t MSBticks)
|
||||
{
|
||||
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_MSBTICKS, MSBticks);
|
||||
}
|
||||
|
||||
static uint32_t TIMER_IF_BkUp_Read_MSBticks(void)
|
||||
{
|
||||
uint32_t MSBticks;
|
||||
MSBticks = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_MSBTICKS);
|
||||
return MSBticks;
|
||||
}
|
||||
|
||||
static inline uint32_t GetTimerTicks(void)
|
||||
{
|
||||
uint32_t ssr = LL_RTC_TIME_GetSubSecond(RTC);
|
||||
/* read twice to make sure value it valid*/
|
||||
while (ssr != LL_RTC_TIME_GetSubSecond(RTC))
|
||||
{
|
||||
ssr = LL_RTC_TIME_GetSubSecond(RTC);
|
||||
}
|
||||
return UINT32_MAX - ssr;
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file timer_if.h
|
||||
* @author MCD Application Team
|
||||
* @brief configuration of the timer_if.c instances
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef TIMER_IF_H
|
||||
#define TIMER_IF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32_timer.h"
|
||||
#include "stm32_systime.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#define RTC_N_PREDIV_S (10U)
|
||||
#define RTC_PREDIV_S ( ( 1U << RTC_N_PREDIV_S ) - 1U )
|
||||
#define RTC_PREDIV_A ( ( 1U << ( 15U - RTC_N_PREDIV_S ) ) - 1U )
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
/**
|
||||
* @brief Init RTC hardware
|
||||
* @return Status based on @ref UTIL_TIMER_Status_t
|
||||
*/
|
||||
UTIL_TIMER_Status_t TIMER_IF_Init(void);
|
||||
|
||||
/**
|
||||
* @brief Set the alarm
|
||||
* @note The alarm is set at timeout from timer Reference (TimerContext)
|
||||
* @param timeout Duration of the Timer in ticks
|
||||
* @return Status based on @ref UTIL_TIMER_Status_t
|
||||
*/
|
||||
UTIL_TIMER_Status_t TIMER_IF_StartTimer(uint32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Stop the Alarm
|
||||
* @return Status based on @ref UTIL_TIMER_Status_t
|
||||
*/
|
||||
UTIL_TIMER_Status_t TIMER_IF_StopTimer(void);
|
||||
|
||||
/**
|
||||
* @brief set timer Reference (TimerContext)
|
||||
* @return Timer Reference Value in Ticks
|
||||
*/
|
||||
uint32_t TIMER_IF_SetTimerContext(void);
|
||||
|
||||
/**
|
||||
* @brief Get the RTC timer Reference
|
||||
* @return Timer Value in Ticks
|
||||
*/
|
||||
uint32_t TIMER_IF_GetTimerContext(void);
|
||||
|
||||
/**
|
||||
* @brief Get the timer elapsed time since timer Reference (TimerContext) was set
|
||||
* @return RTC Elapsed time in ticks
|
||||
*/
|
||||
uint32_t TIMER_IF_GetTimerElapsedTime(void);
|
||||
|
||||
/**
|
||||
* @brief Get the timer value
|
||||
* @return RTC Timer value in ticks
|
||||
*/
|
||||
uint32_t TIMER_IF_GetTimerValue(void);
|
||||
|
||||
/**
|
||||
* @brief Return the minimum timeout in ticks the RTC is able to handle
|
||||
* @return minimum value for a timeout in ticks
|
||||
*/
|
||||
uint32_t TIMER_IF_GetMinimumTimeout(void);
|
||||
|
||||
/**
|
||||
* @brief a delay of delay ms by polling RTC
|
||||
* @param delay in ms
|
||||
*/
|
||||
void TIMER_IF_DelayMs(uint32_t delay);
|
||||
|
||||
/**
|
||||
* @brief converts time in ms to time in ticks
|
||||
* @param[in] timeMilliSec time in milliseconds
|
||||
* @return time in timer ticks
|
||||
*/
|
||||
uint32_t TIMER_IF_Convert_ms2Tick(uint32_t timeMilliSec);
|
||||
|
||||
/**
|
||||
* @brief converts time in ticks to time in ms
|
||||
* @param[in] tick time in timer ticks
|
||||
* @return time in timer milliseconds
|
||||
*/
|
||||
uint32_t TIMER_IF_Convert_Tick2ms(uint32_t tick);
|
||||
|
||||
/**
|
||||
* @brief Get rtc time
|
||||
* @param[out] subSeconds in ticks
|
||||
* @return time seconds
|
||||
*/
|
||||
uint32_t TIMER_IF_GetTime(uint16_t *subSeconds);
|
||||
|
||||
/**
|
||||
* @brief write seconds in backUp register
|
||||
* @note Used to store seconds difference between RTC time and Unix time
|
||||
* @param[in] Seconds time in seconds
|
||||
*/
|
||||
void TIMER_IF_BkUp_Write_Seconds(uint32_t Seconds);
|
||||
|
||||
/**
|
||||
* @brief reads seconds from backUp register
|
||||
* @note Used to store seconds difference between RTC time and Unix time
|
||||
* @return Time in seconds
|
||||
*/
|
||||
uint32_t TIMER_IF_BkUp_Read_Seconds(void);
|
||||
|
||||
/**
|
||||
* @brief writes SubSeconds in backUp register
|
||||
* @note Used to store SubSeconds difference between RTC time and Unix time
|
||||
* @param[in] SubSeconds time in SubSeconds
|
||||
*/
|
||||
void TIMER_IF_BkUp_Write_SubSeconds(uint32_t SubSeconds);
|
||||
|
||||
/**
|
||||
* @brief reads SubSeconds from backUp register
|
||||
* @note Used to store SubSeconds difference between RTC time and Unix time
|
||||
* @return Time in SubSeconds
|
||||
*/
|
||||
uint32_t TIMER_IF_BkUp_Read_SubSeconds(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TIMER_IF_H */
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file baes.h
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains the interface of the basic AES software module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef BAES_H__
|
||||
#define BAES_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Basic AES module dedicated to BLE stack with the following features:
|
||||
* - AES ECB encryption
|
||||
* - AES CMAC computation
|
||||
*
|
||||
* Configuration: the file "app_common.h" is included in this module.
|
||||
* It must define:
|
||||
* - CFG_BAES_SW equals to 1 for software implementation
|
||||
* - CFG_BAES_SW equals to 0 for use of hardware accelerator
|
||||
*
|
||||
* Notes:
|
||||
* - only 128-bit key is supported
|
||||
* - re-entrance is not supported
|
||||
*/
|
||||
|
||||
/* General interface */
|
||||
|
||||
extern void BAES_Reset( void );
|
||||
|
||||
/* AES ECB interface */
|
||||
|
||||
extern void BAES_EcbCrypt( const uint8_t* key,
|
||||
const uint8_t* input,
|
||||
uint8_t* output,
|
||||
int enc );
|
||||
|
||||
/* AES CMAC interface */
|
||||
|
||||
extern void BAES_CmacSetKey( const uint8_t* key );
|
||||
|
||||
extern void BAES_CmacSetVector( const uint8_t * pIV );
|
||||
|
||||
extern void BAES_CmacCompute( const uint8_t* input,
|
||||
uint32_t size,
|
||||
uint8_t* output );
|
||||
|
||||
/* AES CCM interface */
|
||||
|
||||
extern int BAES_CcmCrypt( uint8_t mode,
|
||||
const uint8_t* key,
|
||||
uint8_t iv_length,
|
||||
const uint8_t* iv,
|
||||
uint16_t add_length,
|
||||
const uint8_t* add,
|
||||
uint16_t input_length,
|
||||
const uint8_t* input,
|
||||
uint8_t tag_length,
|
||||
uint8_t* tag,
|
||||
uint8_t* output );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BAES_H__ */
|
||||
@@ -0,0 +1,120 @@
|
||||
/*****************************************************************************
|
||||
* @file baes_ccm.c
|
||||
*
|
||||
* @brief This file contains the AES CCM implementation.
|
||||
*****************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018-2024 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.
|
||||
*
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
#include "baes_global.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Byte/word manipulation macro definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Returns the least significant byte from a word */
|
||||
#define BYTE0(w) ((uint8_t)((w) >> 0))
|
||||
|
||||
/* Returns the second least significant byte from a word */
|
||||
#define BYTE1(w) ((uint8_t)((w) >> 8))
|
||||
|
||||
/* Macro to set a 16-bit word into a byte table in big endian */
|
||||
#define SET_U16_BE( b, i, v ) M_BEGIN uint16_t v_ = (uint16_t)(v); \
|
||||
uint8_t *b_ = &((uint8_t*)(b))[i]; \
|
||||
b_[1] = BYTE0(v_); \
|
||||
b_[0] = BYTE1(v_); M_END
|
||||
|
||||
int BAES_CcmCrypt( uint8_t mode,
|
||||
const uint8_t* key,
|
||||
uint8_t iv_length,
|
||||
const uint8_t* iv,
|
||||
uint16_t add_length,
|
||||
const uint8_t* add,
|
||||
uint16_t input_length,
|
||||
const uint8_t* input,
|
||||
uint8_t tag_length,
|
||||
uint8_t* tag,
|
||||
uint8_t* output )
|
||||
{
|
||||
#if CFG_BAES_SW == 0
|
||||
|
||||
/* This implementation of AES CCM only supports HW AES and it also only
|
||||
* supports the following range for input parameters:
|
||||
* - tag_length: 4..16 (multiple of 2)
|
||||
* - iv_length: 7..13
|
||||
* - add_length: 1..14
|
||||
*/
|
||||
uint32_t left_len, b0[4], bx[4];
|
||||
uint8_t len, *b;
|
||||
|
||||
/* Build B0 */
|
||||
b = (uint8_t*)b0;
|
||||
memset( b0, 0, 16 );
|
||||
b[0] = (1U << 6) | (((tag_length - 2) / 2) << 3) | (14U - iv_length);
|
||||
memcpy( b + 1, iv, iv_length );
|
||||
SET_U16_BE( b, 14, input_length );
|
||||
|
||||
/* Build B1 */
|
||||
b = (uint8_t*)bx;
|
||||
memset( bx, 0, 16 );
|
||||
b[1] = add_length;
|
||||
memcpy( b + 2, add, add_length );
|
||||
|
||||
/* Start CCM process with Init and Header phases */
|
||||
HW_AES_Enable( );
|
||||
HW_AES_InitCcm( mode, key, b0, bx );
|
||||
|
||||
/* Continue CCM process with Payload Phase */
|
||||
left_len = input_length;
|
||||
while ( left_len > 0 )
|
||||
{
|
||||
len = 16;
|
||||
if ( left_len < 16 )
|
||||
{
|
||||
len = (uint8_t)left_len;
|
||||
memset( bx, 0, 16 );
|
||||
|
||||
if ( mode )
|
||||
HW_AES_SetLast( len );
|
||||
}
|
||||
|
||||
memcpy( b, input, len );
|
||||
HW_AES_Crypt( bx, bx );
|
||||
memcpy( output, b, len );
|
||||
input += len;
|
||||
output += len;
|
||||
left_len -= len;
|
||||
}
|
||||
|
||||
/* End CCM process with Final Phase */
|
||||
HW_AES_EndCcm( tag_length, mode ? b : tag );
|
||||
HW_AES_Disable( );
|
||||
|
||||
/* Verification of the tag in case of decryption */
|
||||
if ( mode )
|
||||
{
|
||||
uint8_t diff = 0;
|
||||
for ( int i = 0; i < tag_length; i++ )
|
||||
diff |= tag[i] ^ b[i];
|
||||
|
||||
return (int)diff;
|
||||
}
|
||||
|
||||
#endif /* CFG_BAES_SW == 0 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -0,0 +1,213 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file baes_cmac.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains the AES CMAC implementation.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "baes_global.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t iv[4]; /* Temporary result/IV */
|
||||
|
||||
#if CFG_BAES_SW != 0
|
||||
|
||||
uint32_t exp_key[44]; /* Expanded AES key */
|
||||
|
||||
#endif /* CFG_BAES_SW != 0 */
|
||||
|
||||
} BAES_CMAC_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
BAES_CMAC_t BAES_CMAC_var;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* AES key roll for CMAC Mode
|
||||
*
|
||||
*/
|
||||
|
||||
static void BAES_CmacKeyRoll( uint32_t* key )
|
||||
{
|
||||
uint32_t carry = ((key[0] >> 31) & 1) * 0x87UL;
|
||||
key[0] = (key[0] << 1) | (key[1] >> 31);
|
||||
key[1] = (key[1] << 1) | (key[2] >> 31);
|
||||
key[2] = (key[2] << 1) | (key[3] >> 31);
|
||||
key[3] = (key[3] << 1) ^ carry;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* AES ECB encryption for CMAC Mode
|
||||
*
|
||||
*/
|
||||
|
||||
static void BAES_CmacRawEncrypt( const uint32_t* input,
|
||||
uint32_t* output )
|
||||
{
|
||||
#if CFG_BAES_SW == 0
|
||||
|
||||
HW_AES_Crypt( input, output );
|
||||
|
||||
#else /* CFG_BAES_SW != 0 */
|
||||
|
||||
BAES_CMAC_t *av = &BAES_CMAC_var;
|
||||
|
||||
BAES_RawEncrypt( input, output, av->exp_key );
|
||||
|
||||
#endif /* CFG_BAES_SW != 0 */
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Initialization for AES-CMAC for Authentication TAG Generation.
|
||||
* Must be called each time a new CMAC has to be computed.
|
||||
*/
|
||||
|
||||
void BAES_CmacSetKey( const uint8_t* key )
|
||||
{
|
||||
BAES_CMAC_t *av = &BAES_CMAC_var;
|
||||
|
||||
/* Initialize for ECB encoding */
|
||||
|
||||
#if CFG_BAES_SW == 0
|
||||
|
||||
HW_AES_Enable( );
|
||||
HW_AES_SetKey( HW_AES_ENC, key );
|
||||
|
||||
#else /* CFG_BAES_SW != 0 */
|
||||
|
||||
uint32_t tmp[4];
|
||||
memcpy( tmp, key, 16 );
|
||||
BAES_COPY_REV( av->exp_key, tmp );
|
||||
|
||||
BAES_EncKeySchedule( av->exp_key );
|
||||
|
||||
#endif /* CFG_BAES_SW != 0 */
|
||||
|
||||
/* set IV to zero */
|
||||
av->iv[0] = av->iv[1] = av->iv[2] = av->iv[3] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization for AES-CMAC for Authentication TAG Generation.
|
||||
* Must be called each time a new CMAC has to be computed.
|
||||
*/
|
||||
|
||||
void BAES_CmacSetVector( const uint8_t * pIV )
|
||||
{
|
||||
BAES_CMAC_t * av = &BAES_CMAC_var;
|
||||
|
||||
// -- Update IV if exist else set to zero --
|
||||
if ( pIV != NULL )
|
||||
{ memcpy( av->iv, pIV, AES_BLOCK_SIZE_BYTE ); }
|
||||
else
|
||||
{ memset( av->iv, 0x00, AES_BLOCK_SIZE_BYTE ); }
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* AES Encryption in CMAC Mode
|
||||
*
|
||||
* This function can be called multiple times with "size" multiple of 16 and
|
||||
* "output" parameter set to NULL. However, in the last call to this function,
|
||||
* any positive value for "size" is allowed and the "output" parameter must not
|
||||
* be NULL.
|
||||
*/
|
||||
|
||||
void BAES_CmacCompute( const uint8_t* input,
|
||||
uint32_t size,
|
||||
uint8_t* output )
|
||||
{
|
||||
BAES_CMAC_t *av = &BAES_CMAC_var;
|
||||
uint32_t i;
|
||||
uint32_t last_size = 0;
|
||||
uint32_t tmp[4], key[4];
|
||||
const uint8_t* ptr = input;
|
||||
|
||||
if ( output )
|
||||
{
|
||||
/* In case of final append, compute size of last block */
|
||||
last_size = size % 16;
|
||||
if ( (size != 0) && (last_size == 0) )
|
||||
last_size = 16;
|
||||
size -= last_size;
|
||||
}
|
||||
|
||||
while ( size )
|
||||
{
|
||||
/* Load the input of all blocks but the last one
|
||||
and xor data with previous tag */
|
||||
memcpy( tmp, ptr, 16 );
|
||||
BAES_REV_XOR( tmp, av->iv );
|
||||
|
||||
/* Encrypt block */
|
||||
BAES_CmacRawEncrypt( tmp, av->iv );
|
||||
|
||||
/* Next block */
|
||||
ptr += 16;
|
||||
size -= 16;
|
||||
}
|
||||
|
||||
if ( output )
|
||||
{
|
||||
/* Load the input bytes left with 0 padding */
|
||||
tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0;
|
||||
for ( i = 0; i < last_size; i++ )
|
||||
{
|
||||
BAES_OR_BYTE_BE( tmp, i, ptr[i] );
|
||||
}
|
||||
|
||||
/* Compute K1 */
|
||||
key[0] = key[1] = key[2] = key[3] = 0;
|
||||
BAES_CmacRawEncrypt( key, key );
|
||||
BAES_CmacKeyRoll( key );
|
||||
|
||||
/* Add padding and compute K2 if the last block is not full */
|
||||
if ( last_size < 16 )
|
||||
{
|
||||
BAES_OR_BYTE_BE( tmp, last_size, 0x80 );
|
||||
BAES_CmacKeyRoll( key );
|
||||
}
|
||||
|
||||
/* Xor data with previous tag and key */
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
tmp[i] ^= av->iv[i] ^ key[i];
|
||||
}
|
||||
|
||||
/* Encrypt block */
|
||||
BAES_CmacRawEncrypt( tmp, av->iv );
|
||||
|
||||
#if CFG_BAES_SW == 0
|
||||
|
||||
HW_AES_Disable( );
|
||||
|
||||
#endif /* CFG_BAES_SW == 0 */
|
||||
|
||||
/* Write the tag */
|
||||
BAES_COPY_REV( tmp, av->iv );
|
||||
memcpy( output, tmp, 16 );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file baes_ecb.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains the AES ECB functions implementation.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "baes_global.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void BAES_Reset( void )
|
||||
{
|
||||
#if CFG_BAES_SW == 0
|
||||
|
||||
HW_AES_Disable( );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void BAES_EcbCrypt( const uint8_t* key,
|
||||
const uint8_t* input,
|
||||
uint8_t* output,
|
||||
int enc )
|
||||
{
|
||||
uint32_t tmp[4];
|
||||
|
||||
#if CFG_BAES_SW == 0
|
||||
|
||||
HW_AES_Enable( );
|
||||
HW_AES_SetKey( (enc ? (HW_AES_ENC | HW_AES_REV) : (HW_AES_DEC | HW_AES_REV)),
|
||||
key );
|
||||
|
||||
#else /* CFG_BAES_SW != 0 */
|
||||
|
||||
uint32_t exp_key[44];
|
||||
|
||||
/* Retrieve all bytes from key */
|
||||
memcpy( exp_key, key, 16 );
|
||||
BAES_SWAP( exp_key );
|
||||
|
||||
#if CFG_BAES_SW_DECRYPTION != 0
|
||||
if ( !enc )
|
||||
BAES_DecKeySchedule( exp_key );
|
||||
else
|
||||
#endif /* CFG_BAES_SW_DECRYPTION != 0 */
|
||||
BAES_EncKeySchedule( exp_key );
|
||||
|
||||
#endif /* CFG_BAES_SW != 0 */
|
||||
|
||||
/* Retrieve all bytes from input */
|
||||
memcpy( tmp, input, 16 );
|
||||
BAES_SWAP( tmp );
|
||||
|
||||
#if CFG_BAES_SW == 0
|
||||
|
||||
HW_AES_Crypt( tmp, tmp );
|
||||
HW_AES_Disable( );
|
||||
|
||||
#else /* CFG_BAES_SW != 0 */
|
||||
|
||||
#if CFG_BAES_SW_DECRYPTION != 0
|
||||
if ( !enc )
|
||||
BAES_RawDecrypt( tmp, tmp, exp_key );
|
||||
else
|
||||
#endif /* CFG_BAES_SW_DECRYPTION != 0 */
|
||||
BAES_RawEncrypt( tmp, tmp, exp_key );
|
||||
|
||||
#endif /* CFG_BAES_SW != 0 */
|
||||
|
||||
/* Write all bytes to output */
|
||||
BAES_SWAP( tmp );
|
||||
memcpy( output, tmp, 16 );
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file baes_global.h
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains the internal definitions of the AES software
|
||||
* module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef BAES_GLOBAL_H__
|
||||
#define BAES_GLOBAL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_common.h"
|
||||
#include "baes.h"
|
||||
|
||||
/* Default software configuration */
|
||||
#define AES_BLOCK_SIZE_BIT 128u /* AES Size in Bits */
|
||||
#define AES_BLOCK_SIZE_BYTE 16u /* AES Size in Bytes */
|
||||
#define AES_BLOCK_SIZE_WORD 4u /* AES Size in Words */
|
||||
|
||||
#define AES_EXPANDED_KEY_SIZE 44u
|
||||
|
||||
/* By default, use of AES H/W implementation instead of S/W */
|
||||
#ifndef CFG_BAES_SW
|
||||
#define CFG_BAES_SW 0
|
||||
#endif
|
||||
|
||||
#if CFG_BAES_SW == 1
|
||||
|
||||
/* Enables to include AES S/W decryption when set to 1 */
|
||||
#ifndef CFG_BAES_SW_DECRYPTION
|
||||
#define CFG_BAES_SW_DECRYPTION 0
|
||||
#endif
|
||||
|
||||
/* Choice of the AES S/W algorithm version:
|
||||
* 1: slow version with 522 bytes of look-up tables
|
||||
* 2: fast version with 2048 bytes of look-up tables */
|
||||
#ifndef CFG_BAES_SW_ALGORITHM
|
||||
#define CFG_BAES_SW_ALGORITHM 1
|
||||
#endif
|
||||
|
||||
#endif /* CFG_BAES_SW == 1 */
|
||||
|
||||
/* Internal macros */
|
||||
|
||||
/* Reverse the words in a 4-word array */
|
||||
#define BAES_SWAP( w ) \
|
||||
M_BEGIN uint32_t t_; \
|
||||
t_ = (w)[0]; (w)[0] = (w)[3]; (w)[3] = t_; \
|
||||
t_ = (w)[1]; (w)[1] = (w)[2]; (w)[2] = t_; \
|
||||
M_END
|
||||
|
||||
/* Reverse the bytes and words in a 4-word array */
|
||||
#define BAES_SWAP_REV( w ) \
|
||||
M_BEGIN uint32_t t_; \
|
||||
t_ = (w)[0]; (w)[0] = __REV((w)[3]); (w)[3] = __REV(t_); \
|
||||
t_ = (w)[1]; (w)[1] = __REV((w)[2]); (w)[2] = __REV(t_); \
|
||||
M_END
|
||||
|
||||
/* Reverse the words of a 4-word array and xor the result */
|
||||
#define BAES_SWAP_XOR( w, x ) \
|
||||
M_BEGIN uint32_t t_; \
|
||||
t_ = (w)[0]; (w)[0] = (w)[3] ^ ((x)[0]); (w)[3] = t_ ^ ((x)[3]); \
|
||||
t_ = (w)[1]; (w)[1] = (w)[2] ^ ((x)[1]); (w)[2] = t_ ^ ((x)[2]); \
|
||||
M_END
|
||||
|
||||
/* Reverse the bytes of a 4-word array and xor the result */
|
||||
#define BAES_REV_XOR( w, x ) \
|
||||
M_BEGIN \
|
||||
(w)[0] = __REV((w)[0]) ^ ((x)[0]); (w)[1] = __REV((w)[1]) ^ ((x)[1]); \
|
||||
(w)[2] = __REV((w)[2]) ^ ((x)[2]); (w)[3] = __REV((w)[3]) ^ ((x)[3]); \
|
||||
M_END
|
||||
|
||||
/* Copy and reverse the words of a 4-word array */
|
||||
#define BAES_COPY_SWAP( d, s ) \
|
||||
M_BEGIN \
|
||||
(d)[0] = (s)[3]; (d)[1] = (s)[2]; \
|
||||
(d)[2] = (s)[1]; (d)[3] = (s)[0]; \
|
||||
M_END
|
||||
|
||||
/* Copy and reverse the bytes of a 4-word array */
|
||||
#define BAES_COPY_REV( d, s ) \
|
||||
M_BEGIN \
|
||||
(d)[0] = __REV((s)[0]); (d)[1] = __REV((s)[1]); \
|
||||
(d)[2] = __REV((s)[2]); (d)[3] = __REV((s)[3]); \
|
||||
M_END
|
||||
|
||||
/* Modifies a byte in a word array in Big Endian */
|
||||
#define BAES_OR_BYTE_BE( w, n, b ) \
|
||||
(w)[(n)/4] |= ((uint32_t)(b)) << (8 * (3-((n)%4)))
|
||||
|
||||
/* Note: BYTE0, BYTE1, BYTE2, BYTE3 and BTOW macros are also used
|
||||
but they should be defined in "common.h" */
|
||||
|
||||
/* Internal functions */
|
||||
|
||||
extern void BAES_EncKeySchedule( uint32_t* p_exp_key );
|
||||
|
||||
extern void BAES_DecKeySchedule( uint32_t* p_exp_key );
|
||||
|
||||
extern void BAES_RawEncrypt( const uint32_t* p_in,
|
||||
uint32_t* p_out,
|
||||
const uint32_t *p_exp_key );
|
||||
|
||||
extern void BAES_RawDecrypt( const uint32_t* p_in,
|
||||
uint32_t* p_out,
|
||||
const uint32_t* p_exp_key );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BAES_GLOBAL_H__ */
|
||||
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file flash_driver.c
|
||||
* @author MCD Application Team
|
||||
* @brief The Flash Driver module is the interface layer between Flash
|
||||
* management modules and HAL Flash drivers
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "flash_driver.h"
|
||||
#include "utilities_conf.h"
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
|
||||
#define FD_CTRL_NO_BIT_SET (0UL) /* value used to reset the Flash Control status */
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief variable used to represent the Flash Control status
|
||||
*/
|
||||
static volatile FD_Flash_ctrl_bm_t FD_Flash_Control_status = FD_CTRL_NO_BIT_SET;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Update Flash Control status
|
||||
* @param Flags_bm: Bit mask identifying the caller (1 bit per user)
|
||||
* @param Status: Action requested (enable or disable flash access)
|
||||
* @retval None
|
||||
*/
|
||||
void FD_SetStatus(FD_Flash_ctrl_bm_t Flags_bm, FD_FLASH_Status_t Status)
|
||||
{
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
|
||||
switch (Status)
|
||||
{
|
||||
case LL_FLASH_DISABLE:
|
||||
{
|
||||
FD_Flash_Control_status |= (1u << Flags_bm);
|
||||
break;
|
||||
}
|
||||
case LL_FLASH_ENABLE:
|
||||
{
|
||||
FD_Flash_Control_status &= ~(1u << Flags_bm);
|
||||
break;
|
||||
}
|
||||
default :
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a block of 128 bits (4 32-bit words) in Flash
|
||||
* @param Dest: Address where to write in Flash (128-bit aligned)
|
||||
* @param Payload: Address of data to be written in Flash (32-bit aligned)
|
||||
* @retval FD_FlashOp_Status_t: Success or failure of Flash write operation
|
||||
*/
|
||||
FD_FlashOp_Status_t FD_WriteData(uint32_t Dest, uint32_t Payload)
|
||||
{
|
||||
FD_FlashOp_Status_t status = FD_FLASHOP_FAILURE;
|
||||
|
||||
/* Check if RFTS OR Application allow flash access */
|
||||
if ((FD_Flash_Control_status & (1u << FD_FLASHACCESS_RFTS)) &&
|
||||
(FD_Flash_Control_status & (1u << FD_FLASHACCESS_RFTS_BYPASS)))
|
||||
{ /* Access not allowed */
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Wait for system to allow flash access */
|
||||
while (FD_Flash_Control_status & (1u << FD_FLASHACCESS_SYSTEM));
|
||||
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, Dest, Payload) == HAL_OK)
|
||||
{
|
||||
status = FD_FLASHOP_SUCCESS;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erase one sector of Flash
|
||||
* @param Sect: Identifier of the sector to erase
|
||||
* @retval FD_FlashOp_Status_t: Success or failure of Flash erase operation
|
||||
*/
|
||||
FD_FlashOp_Status_t FD_EraseSectors(uint32_t Sect)
|
||||
{
|
||||
FD_FlashOp_Status_t status = FD_FLASHOP_FAILURE;
|
||||
uint32_t page_error;
|
||||
FLASH_EraseInitTypeDef p_erase_init;
|
||||
|
||||
#ifndef FLASH_DBANK_SUPPORT
|
||||
if (FLASH_PAGE_NB < Sect)
|
||||
#else
|
||||
if ((FLASH_PAGE_NB * 2u) < Sect)
|
||||
#endif
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Check if LL allows flash access */
|
||||
if ((FD_Flash_Control_status & (1u << FD_FLASHACCESS_RFTS)) &&
|
||||
(FD_Flash_Control_status & (1u << FD_FLASHACCESS_RFTS_BYPASS)))
|
||||
{ /* Access not allowed */
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Wait for system to allow flash access */
|
||||
while (FD_Flash_Control_status & (1u << FD_FLASHACCESS_SYSTEM));
|
||||
|
||||
p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
p_erase_init.Page = (Sect & (FLASH_PAGE_NB - 1u));
|
||||
p_erase_init.NbPages = 1;
|
||||
|
||||
#if defined(FLASH_DBANK_SUPPORT)
|
||||
/* Verify which Bank is impacted */
|
||||
if ((FLASH_PAGE_NB <= Sect) ^ (OB_SWAP_BANK_ENABLE == READ_BIT (FLASH->OPTR, FLASH_OPTR_SWAP_BANK_Msk)))
|
||||
{
|
||||
p_erase_init.Banks = FLASH_BANK_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_erase_init.Banks = FLASH_BANK_1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (HAL_FLASHEx_Erase(&p_erase_init, &page_error) == HAL_OK)
|
||||
{
|
||||
status = FD_FLASHOP_SUCCESS;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file flash_driver.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for flash_driver.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef FLASH_DRIVER_H
|
||||
#define FLASH_DRIVER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "utilities_common.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/* Bit mask to modify Flash Control status */
|
||||
typedef uint32_t FD_Flash_ctrl_bm_t;
|
||||
|
||||
/* Flash operation status */
|
||||
typedef enum
|
||||
{
|
||||
FD_FLASHOP_SUCCESS,
|
||||
FD_FLASHOP_FAILURE
|
||||
} FD_FlashOp_Status_t;
|
||||
|
||||
/* Flash Driver commands to enable or disable flash access */
|
||||
typedef enum
|
||||
{
|
||||
LL_FLASH_ENABLE,
|
||||
LL_FLASH_DISABLE,
|
||||
} FD_FLASH_Status_t;
|
||||
|
||||
/**
|
||||
* @brief Bit mask to modify Flash Control status
|
||||
*
|
||||
* @details Those bitmasks are used to enable/disable access to the flash:
|
||||
* - System:
|
||||
* -# FD_FLASHACCESS_SYSTEM: Determine whether or not the flash access is allowed from a system POV.
|
||||
* This bit has a predominance over all the other bit masks, ie: No flash operation can
|
||||
* be achieved without this to be set to 0, ie: LL_FLASH_ENABLE.
|
||||
* - RFTS:
|
||||
* -# FD_FLASHACCESS_RFTS: Determine whether or not the RF Timing Synchro allows flash access. This bit is set
|
||||
* once a window has been allowed by the BLE LL, ie: set to 0.
|
||||
* This bit has no impact when FD_FLASHACCESS_RFTS_BYPASS is set, ie: set to 0.
|
||||
* -# FD_FLASHACCESS_RFTS_BYPASS: Nullify the impact of FD_FLASHACCESS_RFTS when enabled, ie: set to 0. Its role is
|
||||
* to allow flash operation without the need to request a timing window to the RFTS,
|
||||
* ie: Executing flash operation without the BLE LL.
|
||||
*
|
||||
*/
|
||||
typedef enum FD_FlashAccess_bm
|
||||
{
|
||||
/* System flash access bitfield */
|
||||
FD_FLASHACCESS_SYSTEM,
|
||||
/* RF Timing Synchro flash access bitfield */
|
||||
FD_FLASHACCESS_RFTS,
|
||||
/* Bypass of RF Timing Synchro flash access bitfield */
|
||||
FD_FLASHACCESS_RFTS_BYPASS,
|
||||
}FD_FlashAccess_bm_t;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void FD_SetStatus(FD_Flash_ctrl_bm_t Flags_bm, FD_FLASH_Status_t Status);
|
||||
FD_FlashOp_Status_t FD_WriteData(uint32_t Dest, uint32_t Payload);
|
||||
FD_FlashOp_Status_t FD_EraseSectors(uint32_t Sect);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*FLASH_DRIVER_H */
|
||||
@@ -0,0 +1,516 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file flash_manager.c
|
||||
* @author MCD Application Team
|
||||
* @brief The Flash Manager module provides an interface to write raw data
|
||||
* from SRAM to FLASH
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include "flash_manager.h"
|
||||
#include "rf_timing_synchro.h"
|
||||
#include "flash_driver.h"
|
||||
#include "utilities_conf.h"
|
||||
|
||||
#include "stm32wbaxx_hal.h"
|
||||
|
||||
/* Debug */
|
||||
#include "log_module.h"
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
||||
/* State of the background process */
|
||||
typedef enum FM_BackGround_States
|
||||
{
|
||||
FM_BKGND_NOWINDOW_FLASHOP,
|
||||
FM_BKGND_WINDOWED_FLASHOP,
|
||||
}FM_BackGround_States_t;
|
||||
|
||||
/* Flash operation type */
|
||||
typedef enum
|
||||
{
|
||||
FM_WRITE_OP,
|
||||
FM_ERASE_OP
|
||||
} FM_FlashOp_t;
|
||||
|
||||
/**
|
||||
* @brief Flash operation configuration struct
|
||||
*/
|
||||
typedef struct FM_FlashOpConfig
|
||||
{
|
||||
uint32_t *writeSrc;
|
||||
uint32_t *writeDest;
|
||||
int32_t writeSize;
|
||||
uint32_t eraseFirstSect;
|
||||
uint32_t eraseNbrSect;
|
||||
}FM_FlashOpConfig_t;
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#define FLASH_PAGE_NBR (FLASH_SIZE / FLASH_PAGE_SIZE)
|
||||
|
||||
#define FLASH_WRITE_BLOCK_SIZE 4U
|
||||
#define ALIGNMENT_32 0x00000003
|
||||
#define ALIGNMENT_128 0x0000000F
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Semaphore on Flash
|
||||
*/
|
||||
static bool busy_flash_sem = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Indicates if the flash manager module is available or not
|
||||
*/
|
||||
static bool flash_manager_busy = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Parameters for Flash Write command
|
||||
*/
|
||||
static bool fm_window_granted = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Callback node list for pending flash operation request
|
||||
*/
|
||||
static tListNode fm_cb_pending_list;
|
||||
|
||||
/**
|
||||
* @brief Pointer to current flash operation requester's callback
|
||||
*/
|
||||
static void (*fm_running_cb)(FM_FlashOp_Status_t);
|
||||
|
||||
/**
|
||||
* @brief Type of current flash operation (Write/Erase)
|
||||
*/
|
||||
static FM_FlashOp_t fm_flashop;
|
||||
|
||||
/**
|
||||
* @brief Parameters for Flash operation
|
||||
*/
|
||||
static FM_FlashOpConfig_t fm_flashop_parameters;
|
||||
|
||||
/**
|
||||
* @brief State of the Background process
|
||||
*/
|
||||
static FM_BackGround_States_t FM_CurrentBackGroundState;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
static FM_Cmd_Status_t FM_CheckFlashManagerState(FM_CallbackNode_t *CallbackNode);
|
||||
static void FM_WindowAllowed_Callback(void);
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Initialize the Flash manager module
|
||||
*/
|
||||
void FM_Init (void)
|
||||
{
|
||||
static bool fm_cb_pending_list_init = false;
|
||||
|
||||
/* Initialize pending list if not done */
|
||||
if (fm_cb_pending_list_init == false)
|
||||
{
|
||||
LST_init_head(&fm_cb_pending_list);
|
||||
fm_cb_pending_list_init = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Request the Flash Manager module to initiate a Flash Write operation
|
||||
* @param Src: Address of the data to be stored in FLASH. It shall be 32bits aligned
|
||||
* @param Dest: Address where the data shall be written. It shall be 128bits aligned
|
||||
* @param Size: This is the size of data to be written in Flash.
|
||||
The size is a multiple of 32bits (size = 1 means 32bits)
|
||||
* @param CallbackNode: Pointer to the callback node for storage in list
|
||||
* @retval FM_Cmd_Status_t: Status of the Flash Manager module
|
||||
*/
|
||||
FM_Cmd_Status_t FM_Write(uint32_t *Src, uint32_t *Dest, int32_t Size, FM_CallbackNode_t *CallbackNode)
|
||||
{
|
||||
FM_Cmd_Status_t status;
|
||||
|
||||
if (((uint32_t)Dest < FLASH_BASE) || ((uint32_t)Dest > (FLASH_BASE + FLASH_SIZE))
|
||||
|| (((uint32_t)Dest + Size) > (FLASH_BASE + FLASH_SIZE)))
|
||||
{
|
||||
LOG_ERROR_SYSTEM("\r\nFM_Write - Destination address not part of the flash");
|
||||
|
||||
/* Destination address not part of the flash */
|
||||
return FM_ERROR;
|
||||
}
|
||||
|
||||
if (((uint32_t) Src & ALIGNMENT_32) || ((uint32_t) Dest & ALIGNMENT_128))
|
||||
{
|
||||
LOG_ERROR_SYSTEM("\r\nFM_Write - Source or destination address not properly aligned");
|
||||
|
||||
/* Source or destination address not properly aligned */
|
||||
return FM_ERROR;
|
||||
}
|
||||
|
||||
status = FM_CheckFlashManagerState(CallbackNode);
|
||||
|
||||
if (status == FM_OK)
|
||||
{ /* Flash manager is available */
|
||||
|
||||
/* Save Write parameters */
|
||||
fm_flashop_parameters.writeSrc = Src;
|
||||
fm_flashop_parameters.writeDest = Dest;
|
||||
fm_flashop_parameters.writeSize = Size;
|
||||
|
||||
fm_flashop = FM_WRITE_OP;
|
||||
|
||||
FM_CurrentBackGroundState = FM_BKGND_NOWINDOW_FLASHOP;
|
||||
|
||||
/* Window request to be executed in background */
|
||||
FM_ProcessRequest();
|
||||
}
|
||||
|
||||
LOG_DEBUG_SYSTEM("\r\nFM_Write - Returned value : %d", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Request the Flash Manager module to initiate a Flash Erase operation
|
||||
* @param FirstSect: Index of the first sector to erase
|
||||
* @param NbrSect: Number of sector to erase
|
||||
* @param CallbackNode: Pointer to the callback node for storage in list
|
||||
* @retval FM_Cmd_Status_t: Status of the Flash Manager module
|
||||
*/
|
||||
FM_Cmd_Status_t FM_Erase(uint32_t FirstSect, uint32_t NbrSect, FM_CallbackNode_t *CallbackNode)
|
||||
{
|
||||
FM_Cmd_Status_t status;
|
||||
|
||||
if ((FirstSect > FLASH_PAGE_NBR) || ((FirstSect + NbrSect) > FLASH_PAGE_NBR))
|
||||
{
|
||||
LOG_ERROR_SYSTEM("\r\nFM_Erase - Inconsistent request");
|
||||
|
||||
/* Inconsistent request */
|
||||
return FM_ERROR;
|
||||
}
|
||||
|
||||
if (NbrSect == 0)
|
||||
{
|
||||
LOG_ERROR_SYSTEM("\r\nFM_Erase - Inconsistent request");
|
||||
|
||||
/* Inconsistent request */
|
||||
return FM_ERROR;
|
||||
}
|
||||
|
||||
status = FM_CheckFlashManagerState(CallbackNode);
|
||||
|
||||
if (status == FM_OK)
|
||||
{ /* Flash manager is available */
|
||||
|
||||
/* Save Erase parameters */
|
||||
fm_flashop_parameters.eraseFirstSect = FirstSect;
|
||||
fm_flashop_parameters.eraseNbrSect = NbrSect;
|
||||
|
||||
fm_flashop = FM_ERASE_OP;
|
||||
|
||||
FM_CurrentBackGroundState = FM_BKGND_NOWINDOW_FLASHOP;
|
||||
|
||||
/* Window request to be executed in background */
|
||||
FM_ProcessRequest();
|
||||
}
|
||||
|
||||
LOG_DEBUG_SYSTEM("\r\nFM_Erase - Returned value : %d", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Execute Flash Manager background tasks
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void FM_BackgroundProcess (void)
|
||||
{
|
||||
static uint32_t duration;
|
||||
bool flashop_complete = false;
|
||||
FD_FlashOp_Status_t fdReturnValue = FD_FLASHOP_SUCCESS;
|
||||
FM_CallbackNode_t *pCbNode = NULL;
|
||||
|
||||
switch (FM_CurrentBackGroundState)
|
||||
{
|
||||
case FM_BKGND_NOWINDOW_FLASHOP:
|
||||
{
|
||||
LOG_DEBUG_SYSTEM("\r\nFM_BackgroundProcess - Case FM_BKGND_NOWINDOW_FLASHOP");
|
||||
|
||||
if (fm_flashop == FM_WRITE_OP)
|
||||
{
|
||||
LOG_DEBUG_SYSTEM("\r\nFM_BackgroundProcess - Case FM_BKGND_NOWINDOW_FLASHOP - Write operation");
|
||||
|
||||
/* Update duration time value */
|
||||
duration = TIME_WINDOW_WRITE_REQUEST;
|
||||
|
||||
/* Set the next possible state - App could stop at anytime no window operation */
|
||||
FM_CurrentBackGroundState = FM_BKGND_WINDOWED_FLASHOP;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
while((fm_flashop_parameters.writeSize > 0) &&
|
||||
(fdReturnValue == FD_FLASHOP_SUCCESS))
|
||||
{
|
||||
fdReturnValue = FD_WriteData((uint32_t) fm_flashop_parameters.writeDest,
|
||||
(uint32_t) fm_flashop_parameters.writeSrc);
|
||||
|
||||
if (fdReturnValue == FD_FLASHOP_SUCCESS)
|
||||
{
|
||||
fm_flashop_parameters.writeDest += FLASH_WRITE_BLOCK_SIZE;
|
||||
fm_flashop_parameters.writeSrc += FLASH_WRITE_BLOCK_SIZE;
|
||||
fm_flashop_parameters.writeSize -= FLASH_WRITE_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
/* Is write over ? */
|
||||
if (fm_flashop_parameters.writeSize <= 0)
|
||||
{
|
||||
flashop_complete = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG_SYSTEM("\r\nFM_BackgroundProcess - Case FM_BKGND_NOWINDOW_FLASHOP - Erase operation");
|
||||
|
||||
/* Update duration time value */
|
||||
duration = TIME_WINDOW_ERASE_REQUEST;
|
||||
|
||||
/* Set the next possible state */
|
||||
FM_CurrentBackGroundState = FM_BKGND_WINDOWED_FLASHOP;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
while((fm_flashop_parameters.eraseNbrSect > 0) &&
|
||||
(fdReturnValue == FD_FLASHOP_SUCCESS))
|
||||
{
|
||||
fdReturnValue = FD_EraseSectors(fm_flashop_parameters.eraseFirstSect);
|
||||
|
||||
if (fdReturnValue == FD_FLASHOP_SUCCESS)
|
||||
{
|
||||
fm_flashop_parameters.eraseNbrSect--;
|
||||
fm_flashop_parameters.eraseFirstSect++;
|
||||
}
|
||||
}
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
if (fm_flashop_parameters.eraseNbrSect == 0)
|
||||
{
|
||||
flashop_complete = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case FM_BKGND_WINDOWED_FLASHOP:
|
||||
{
|
||||
LOG_DEBUG_SYSTEM("\r\nFM_BackgroundProcess - Case FM_BKGND_WINDOWED_FLASHOP");
|
||||
|
||||
if (fm_window_granted == false)
|
||||
{
|
||||
LOG_DEBUG_SYSTEM("\r\nFM_BackgroundProcess - Case FM_BKGND_WINDOWED_FLASHOP - No time window granted yet, request one");
|
||||
|
||||
/* No time window granted yet, request one */
|
||||
RFTS_ReqWindow(duration, &FM_WindowAllowed_Callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG_SYSTEM("\r\nFM_BackgroundProcess - Case FM_BKGND_WINDOWED_FLASHOP - Time window granted");
|
||||
|
||||
if (fm_flashop == FM_WRITE_OP)
|
||||
{
|
||||
/* Flash Write operation */
|
||||
LOG_DEBUG_SYSTEM("\r\nFM_BackgroundProcess - Case FM_BKGND_WINDOWED_FLASHOP - Write operation");
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
while((fm_flashop_parameters.writeSize > 0) &&
|
||||
(FD_WriteData((uint32_t) fm_flashop_parameters.writeDest,
|
||||
(uint32_t) fm_flashop_parameters.writeSrc) == FD_FLASHOP_SUCCESS))
|
||||
{
|
||||
fm_flashop_parameters.writeDest += FLASH_WRITE_BLOCK_SIZE;
|
||||
fm_flashop_parameters.writeSrc += FLASH_WRITE_BLOCK_SIZE;
|
||||
fm_flashop_parameters.writeSize -= FLASH_WRITE_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
if (fm_flashop_parameters.writeSize <= 0)
|
||||
{
|
||||
flashop_complete = true;
|
||||
}
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Flash Erase operation */
|
||||
LOG_DEBUG_SYSTEM("\r\nFM_BackgroundProcess - Case FM_BKGND_WINDOWED_FLASHOP - Erase operation");
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
/* Erase only one sector in a single time window */
|
||||
if (FD_EraseSectors(fm_flashop_parameters.eraseFirstSect) == FD_FLASHOP_SUCCESS)
|
||||
{
|
||||
fm_flashop_parameters.eraseNbrSect--;
|
||||
fm_flashop_parameters.eraseFirstSect++;
|
||||
}
|
||||
|
||||
if (fm_flashop_parameters.eraseNbrSect == 0)
|
||||
{
|
||||
flashop_complete = true;
|
||||
}
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
}
|
||||
|
||||
/* Release the time window */
|
||||
RFTS_RelWindow();
|
||||
|
||||
/* Indicate that there is no more window */
|
||||
fm_window_granted = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
/* Nothing to do here */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flashop_complete == true)
|
||||
{
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
|
||||
/* Release semaphore on flash */
|
||||
busy_flash_sem = false;
|
||||
|
||||
/* Set Flash Manager busy */
|
||||
flash_manager_busy = false;
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION();
|
||||
|
||||
/* Invoke the running callback if present */
|
||||
if (fm_running_cb != NULL)
|
||||
{
|
||||
fm_running_cb(FM_OPERATION_COMPLETE);
|
||||
}
|
||||
|
||||
/* notify pending requesters */
|
||||
while((LST_is_empty (&fm_cb_pending_list) == false) &&
|
||||
(busy_flash_sem == false) && (flash_manager_busy == false))
|
||||
{
|
||||
LST_remove_head (&fm_cb_pending_list, (tListNode**)&pCbNode);
|
||||
pCbNode->Callback(FM_OPERATION_AVAILABLE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Flash operation not complete yet */
|
||||
LOG_DEBUG_SYSTEM("\r\nFM_BackgroundProcess - Flash operation not complete yet, request a new time window");
|
||||
|
||||
/* Request a new time window */
|
||||
RFTS_ReqWindow(duration, &FM_WindowAllowed_Callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the Flash Manager is busy or available
|
||||
* @param CallbackNode: Pointer to the callback node for storage in list
|
||||
* @retval FM_Cmd_Status_t: Status of the Flash Manager module
|
||||
*/
|
||||
static FM_Cmd_Status_t FM_CheckFlashManagerState(FM_CallbackNode_t *CallbackNode)
|
||||
{
|
||||
bool fm_process_cmd = false;
|
||||
FM_Cmd_Status_t status = FM_ERROR;
|
||||
|
||||
/* Check if semaphore on flash is available */
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
|
||||
/* Check if semaphore on flash is available */
|
||||
if (busy_flash_sem == false)
|
||||
{ /* Check if Flash Manager is already busy */
|
||||
if (flash_manager_busy == false)
|
||||
{
|
||||
busy_flash_sem = true; /* Get semaphore on flash */
|
||||
flash_manager_busy = true; /* Set Flash Manager busy */
|
||||
fm_process_cmd = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fm_process_cmd = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fm_process_cmd = false;
|
||||
}
|
||||
UTILS_EXIT_CRITICAL_SECTION();
|
||||
|
||||
if (fm_process_cmd == false)
|
||||
{ /* Flash manager busy */
|
||||
|
||||
/* Append callback to the pending list */
|
||||
if ((CallbackNode != NULL) && (CallbackNode->Callback != NULL))
|
||||
{
|
||||
LST_insert_tail(&fm_cb_pending_list, &(CallbackNode->NodeList));
|
||||
}
|
||||
|
||||
status = FM_BUSY;
|
||||
}
|
||||
else
|
||||
{ /* Flash manager is available */
|
||||
|
||||
if ((CallbackNode != NULL) && (CallbackNode->Callback != NULL))
|
||||
{
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
|
||||
fm_running_cb = CallbackNode->Callback;
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION();
|
||||
}
|
||||
else
|
||||
{
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
|
||||
fm_running_cb = NULL;
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION();
|
||||
}
|
||||
|
||||
status = FM_OK;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback called by RF Timing Synchro module when a time window is available
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void FM_WindowAllowed_Callback(void)
|
||||
{
|
||||
fm_window_granted = true;
|
||||
|
||||
LOG_DEBUG_SYSTEM("\r\nFM_WindowAllowed_Callback");
|
||||
|
||||
/* Flash operation to be executed in background */
|
||||
FM_ProcessRequest();
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file flash_manager.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for flash_manager.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef FLASH_MANAGER_H
|
||||
#define FLASH_MANAGER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "utilities_common.h"
|
||||
#include "stm_list.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/* Flash Manager command status */
|
||||
typedef enum
|
||||
{
|
||||
FM_OK, /* The Flash Manager is available and a window request is scheduled */
|
||||
FM_BUSY, /* The Flash Manager is busy and the caller will be called back when it is available */
|
||||
FM_ERROR /* An error occurred while processing the command */
|
||||
} FM_Cmd_Status_t;
|
||||
|
||||
/* Flash operation status */
|
||||
typedef enum
|
||||
{
|
||||
FM_OPERATION_COMPLETE, /* The requested flash operation is complete */
|
||||
FM_OPERATION_AVAILABLE /* A flash operation can be requested */
|
||||
} FM_FlashOp_Status_t;
|
||||
|
||||
/**
|
||||
* @brief Flash Manager callback node type to store them in a chained list
|
||||
*/
|
||||
typedef struct FM_CallbackNode
|
||||
{
|
||||
tListNode NodeList; /* Next and previous nodes in the list */
|
||||
void (*Callback)(FM_FlashOp_Status_t Status); /* Callback function pointer for Flash Manager caller */
|
||||
}FM_CallbackNode_t;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
#define TIME_WINDOW_ERASE_DURATION 4000U /* Duration in us of the time window requested for Flash Erase */
|
||||
#define TIME_WINDOW_WRITE_DURATION 1000U /* Duration in us of the time window requested for Flash Write */
|
||||
#define TIME_WINDOW_MARGIN 100U /* Time margin added so to ensure timeout protection before actual closure */
|
||||
/* As timers use ms, amount below 1000 is removed at conversion */
|
||||
#define TIME_WINDOW_ERASE_REQUEST (TIME_WINDOW_ERASE_DURATION + TIME_WINDOW_MARGIN)
|
||||
#define TIME_WINDOW_WRITE_REQUEST (TIME_WINDOW_WRITE_DURATION + TIME_WINDOW_MARGIN)
|
||||
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void FM_Init (void);
|
||||
FM_Cmd_Status_t FM_Write(uint32_t *Src, uint32_t *Dest, int32_t Size, FM_CallbackNode_t *CallbackNode);
|
||||
FM_Cmd_Status_t FM_Erase(uint32_t FirstSect, uint32_t NbrSect, FM_CallbackNode_t *CallbackNode);
|
||||
void FM_BackgroundProcess (void);
|
||||
void FM_ProcessRequest (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*FLASH_MANAGER_H */
|
||||
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file rf_timing_synchro.c
|
||||
* @author MCD Application Team
|
||||
* @brief The RF Timing Synchronization module provides an interface to
|
||||
* synchronize the flash processing versus the RF activity to make
|
||||
* sure the RF timing is not broken
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "rf_timing_synchro.h"
|
||||
#include "evnt_schdlr_gnrc_if.h"
|
||||
#include "utilities_conf.h"
|
||||
#include "stm32_timer.h"
|
||||
#include "flash_driver.h"
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
#if (DISABLE_RFTS_EXT_EVNT_HNDLR == 0u)
|
||||
/**
|
||||
* @brief Pointer to time window requester's callback
|
||||
*/
|
||||
static void (*req_callback)(void);
|
||||
|
||||
/**
|
||||
* @brief Indicates if a time window has already been requested or not
|
||||
*/
|
||||
static bool rfts_window_req_pending = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Timer used by the RFTS module to prevent time window overrun
|
||||
*/
|
||||
static UTIL_TIMER_Object_t rfts_timer;
|
||||
|
||||
/**
|
||||
* @brief Firmware Link Layer external event handler
|
||||
*/
|
||||
static ext_evnt_hndl_t ext_event_handler;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
static void RFTS_WindowAllowed_Callback(void);
|
||||
static void RFTS_Timeout_Callback(void* Argument);
|
||||
static uint32_t event_started_callback(ext_evnt_hndl_t evnt_hndl, uint32_t slot_durn, void* priv_data_ptr);
|
||||
#endif /* (DISABLE_RFTS_EXT_EVNT_HNDLR == 0u) */
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Request a time window to the Firmware Link Layer
|
||||
* @param duration: Duration in us of the time window requested
|
||||
* @param Callback: Callback to be called when time window is allocated
|
||||
* @retval RFTS_Cmd_Status_t: Success or failure of the window request
|
||||
*/
|
||||
RFTS_Cmd_Status_t RFTS_ReqWindow(uint32_t Duration, void (*Callback)(void))
|
||||
{
|
||||
#if (DISABLE_RFTS_EXT_EVNT_HNDLR == 0u)
|
||||
extrnl_evnt_st_t extrnl_evnt_config;
|
||||
bool req_pending = false;
|
||||
|
||||
if (Callback == NULL)
|
||||
{ /* Prevent use of uninitialized callback */
|
||||
return RFTS_WINDOW_REQ_FAILED;
|
||||
}
|
||||
|
||||
/* Check no request is already pending */
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
if (rfts_window_req_pending == true)
|
||||
{
|
||||
req_pending = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
rfts_window_req_pending = true;
|
||||
}
|
||||
UTILS_EXIT_CRITICAL_SECTION();
|
||||
if (req_pending == true)
|
||||
{ /* A window request is already pending */
|
||||
return RFTS_WINDOW_REQ_FAILED;
|
||||
}
|
||||
|
||||
/* Register requester's callback */
|
||||
req_callback = Callback;
|
||||
|
||||
/* Submit request to Firmware Link Layer */
|
||||
extrnl_evnt_config.deadline = 0;
|
||||
extrnl_evnt_config.strt_min = 0;
|
||||
extrnl_evnt_config.strt_max = 0;
|
||||
extrnl_evnt_config.durn_min = Duration;
|
||||
extrnl_evnt_config.durn_max = 0;
|
||||
extrnl_evnt_config.prdc_intrvl = 0;
|
||||
extrnl_evnt_config.priority = PRIORITY_DEFAULT;
|
||||
extrnl_evnt_config.blocked = STATE_NOT_BLOCKED;
|
||||
extrnl_evnt_config.ptr_priv = NULL;
|
||||
extrnl_evnt_config.evnt_strtd_cbk = &event_started_callback;
|
||||
extrnl_evnt_config.evnt_blckd_cbk = NULL;
|
||||
extrnl_evnt_config.evnt_abortd_cbk = NULL;
|
||||
|
||||
UTIL_TIMER_Create(&rfts_timer,
|
||||
(Duration/1000),
|
||||
UTIL_TIMER_ONESHOT,
|
||||
&RFTS_Timeout_Callback,
|
||||
NULL);
|
||||
|
||||
ext_event_handler = evnt_schdlr_rgstr_gnrc_evnt(&extrnl_evnt_config);
|
||||
if (ext_event_handler == NULL)
|
||||
{
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
rfts_window_req_pending = false;
|
||||
UTILS_EXIT_CRITICAL_SECTION();
|
||||
|
||||
return RFTS_WINDOW_REQ_FAILED;
|
||||
}
|
||||
#endif /* (DISABLE_RFTS_EXT_EVNT_HNDLR == 0u) */
|
||||
|
||||
return RFTS_CMD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Execute necessary tasks to allow the time window to be released
|
||||
* @param None
|
||||
* @retval RFTS_Cmd_Status_t: Success or error in the window release procedure
|
||||
*/
|
||||
RFTS_Cmd_Status_t RFTS_RelWindow(void)
|
||||
{
|
||||
#if (DISABLE_RFTS_EXT_EVNT_HNDLR == 0u)
|
||||
RFTS_Cmd_Status_t status;
|
||||
|
||||
/* Stop RFTS module window overrun control timer */
|
||||
UTIL_TIMER_Stop(&rfts_timer);
|
||||
|
||||
/* Inform Firmware Link Layer that time window can be released */
|
||||
if (evnt_schdlr_gnrc_evnt_cmplt(ext_event_handler) == 0)
|
||||
{
|
||||
status = RFTS_CMD_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = RFTS_WINDOW_REL_ERROR;
|
||||
}
|
||||
|
||||
/* Forbid flash operation */
|
||||
FD_SetStatus(FD_FLASHACCESS_RFTS, LL_FLASH_DISABLE);
|
||||
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
rfts_window_req_pending = false;
|
||||
UTILS_EXIT_CRITICAL_SECTION();
|
||||
|
||||
return status;
|
||||
#else
|
||||
return RFTS_CMD_OK;
|
||||
#endif /* (DISABLE_RFTS_EXT_EVNT_HNDLR == 0u) */
|
||||
}
|
||||
|
||||
#if (DISABLE_RFTS_EXT_EVNT_HNDLR == 0u)
|
||||
/**
|
||||
* @brief Callback called by Firmware Link Layer when a time window is available
|
||||
* @note This callback is supposed to be called under interrupt
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void RFTS_WindowAllowed_Callback(void)
|
||||
{
|
||||
/* Allow flash operation */
|
||||
FD_SetStatus(FD_FLASHACCESS_RFTS, LL_FLASH_ENABLE);
|
||||
|
||||
/* Start timer preventing window overrun */
|
||||
UTIL_TIMER_Start(&rfts_timer);
|
||||
|
||||
/* Call back requester to inform time window is available */
|
||||
req_callback();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback triggered by a timeout when the allocated window time is elapsed
|
||||
* @note This callback is supposed to be called under interrupt
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void RFTS_Timeout_Callback(void* Argument)
|
||||
{
|
||||
/* Forbid flash operation */
|
||||
FD_SetStatus(FD_FLASHACCESS_RFTS, LL_FLASH_DISABLE);
|
||||
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
rfts_window_req_pending = false;
|
||||
UTILS_EXIT_CRITICAL_SECTION();
|
||||
}
|
||||
|
||||
static uint32_t event_started_callback(ext_evnt_hndl_t evnt_hndl, uint32_t slot_durn, void* priv_data_ptr)
|
||||
{
|
||||
RFTS_WindowAllowed_Callback();
|
||||
return 0;
|
||||
}
|
||||
#endif /* (DISABLE_RFTS_EXT_EVNT_HNDLR == 0u) */
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file rf_timing_synchro.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for rf_timing_synchro.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef RF_TIMING_SYNCHRO_H
|
||||
#define RF_TIMING_SYNCHRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "utilities_common.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/* RFTS command status */
|
||||
typedef enum
|
||||
{
|
||||
RFTS_CMD_OK, /* The RF Timing synchronization command was successfully executed */
|
||||
RFTS_WINDOW_REQ_FAILED, /* The RF Timing synchronization module failed to register the window request */
|
||||
RFTS_WINDOW_REL_ERROR /* An error occurred during the window release procedure */
|
||||
} RFTS_Cmd_Status_t;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
RFTS_Cmd_Status_t RFTS_ReqWindow(uint32_t Duration, void (*Callback)(void));
|
||||
RFTS_Cmd_Status_t RFTS_RelWindow(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*RF_TIMING_SYNCHRO_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file simple_nvm_arbiter.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for simple_nvm_arbiter.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef SIMPLE_NVM_ARBITER_H
|
||||
#define SIMPLE_NVM_ARBITER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "simple_nvm_arbiter_common.h"
|
||||
#include "simple_nvm_arbiter_conf.h"
|
||||
|
||||
#include "utilities_common.h"
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Initialize the Simple NVM Arbiter
|
||||
*
|
||||
* @param p_NvmStartAddress: Start address of the NVM to work with - Shall be aligned 128 bits
|
||||
*
|
||||
* @return Status of the command
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_OK
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NOK
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_ALREADY_INIT
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NVM_NULL
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NVM_NOT_ALIGNED
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NVM_OVERLAP_FLASH
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_CRC_INIT
|
||||
*/
|
||||
SNVMA_Cmd_Status_t SNVMA_Init (const uint32_t * p_NvmStartAddress);
|
||||
|
||||
/**
|
||||
* @brief Register a user buffer to a NVM
|
||||
*
|
||||
* @details Buffer IDs are hardcoded, please refer to SNVMA_BufferId_t enumeration
|
||||
*
|
||||
* @param BufferId: Id of the user which ask for buffer registration
|
||||
* @param p_BufferAddress: Address of the buffer to be registered - Shall be aligned 32 bits
|
||||
* @param BufferSize: Size of the buffer to be registered - Shall be a multiple of 32bits
|
||||
*
|
||||
* @return Status of the command
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_OK
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NOK
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NOT_INIT
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_CMD_PENDING
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_BUFFERID_NOT_KNOWN
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_BUFFER_NULL
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_BUFFER_NOT_ALIGNED
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_BUFFER_SIZE
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NVM_BUFFER_FULL
|
||||
*/
|
||||
SNVMA_Cmd_Status_t SNVMA_Register (const SNVMA_BufferId_t BufferId,
|
||||
const uint32_t * p_BufferAddress,
|
||||
const uint32_t BufferSize);
|
||||
|
||||
/**
|
||||
* @brief Restore a user buffer from a NVM
|
||||
*
|
||||
* @details The user buffer information shall first be provided by calling SNVMA_Register
|
||||
*
|
||||
* @details Buffer IDs are hardcoded, please refer to SNVMA_BufferId_t enumeration
|
||||
*
|
||||
* @param BufferId: Id of the user which ask for buffer registration
|
||||
*
|
||||
* @return Status of the command
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_OK
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NOK
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NOT_INIT
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_CMD_PENDING
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_BUFFERID_NOT_KNOWN
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_BUFFERID_NOT_REGISTERED
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NVM_BANK_EMPTY
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NVM_BANK_CORRUPTED
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_BUFFER_CONFIG_MISSMATCH
|
||||
*/
|
||||
SNVMA_Cmd_Status_t SNVMA_Restore (const SNVMA_BufferId_t BufferId);
|
||||
|
||||
/**
|
||||
* @brief Register a user buffer to a NVM
|
||||
*
|
||||
* @details The user buffer information shall first be provided by calling SNVMA_Register
|
||||
*
|
||||
* @details Buffer IDs are hardcoded, please refer to SNVMA_BufferId_t enumeration
|
||||
*
|
||||
* @details A buffer write request cannot be scheduled once its NVM is already on a write operation. This will lead
|
||||
* to a SNVMA_OPERATION_FAILED callback status.
|
||||
*
|
||||
* @param BufferId: Id of the user which ask for buffer registration
|
||||
* @param Callback: Callback function for operation status return - Can be NULL
|
||||
*
|
||||
* @return Status of the command
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_OK
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NOK
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_NOT_INIT
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_BUFFERID_NOT_KNOWN
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_BUFFERID_NOT_REGISTERED
|
||||
* @retval SNVMA_Cmd_Status_t::SNVMA_ERROR_FLASH_ERROR
|
||||
*/
|
||||
SNVMA_Cmd_Status_t SNVMA_Write (const SNVMA_BufferId_t BufferId,
|
||||
void (* Callback) (SNVMA_Callback_Status_t));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*SIMPLE_NVM_ARBITER_H */
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file simple_nvm_arbiter_common.h
|
||||
* @author MCD Application Team
|
||||
* @brief Common header of simple_nvm_arbiter.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef SIMPLE_NVM_ARBITER_COMMON_H
|
||||
#define SIMPLE_NVM_ARBITER_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "utilities_common.h"
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Maximum number of different NVM Identifiers */
|
||||
#define SNVMA_MAX_NUMBER_NVM 32u
|
||||
|
||||
/* Maximum number of buffer per NVM */
|
||||
#define SNVMA_MAX_NUMBER_BUFFER 4u
|
||||
|
||||
/* Minimum number of bank per NVM */
|
||||
#define SNVMA_MIN_NUMBER_BANK 2u
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/* SNVMA command status */
|
||||
typedef enum SNVMA_Cmd_Status
|
||||
{
|
||||
SNVMA_ERROR_OK,
|
||||
SNVMA_ERROR_NOK,
|
||||
SNVMA_ERROR_NOT_INIT,
|
||||
SNVMA_ERROR_ALREADY_INIT,
|
||||
SNVMA_ERROR_CMD_PENDING,
|
||||
SNVMA_ERROR_BANK_OP_ONGOING,
|
||||
SNVMA_ERROR_NVM_NULL,
|
||||
SNVMA_ERROR_NVM_NOT_ALIGNED,
|
||||
SNVMA_ERROR_NVM_OVERLAP_FLASH,
|
||||
SNVMA_ERROR_NVM_BUFFER_FULL,
|
||||
SNVMA_ERROR_NVM_BANK_EMPTY,
|
||||
SNVMA_ERROR_NVM_BANK_CORRUPTED,
|
||||
SNVMA_ERROR_CRC_INIT,
|
||||
SNVMA_ERROR_BANK_NUMBER,
|
||||
SNVMA_ERROR_BANK_SIZE,
|
||||
SNVMA_ERROR_BUFFERID_NOT_KNOWN,
|
||||
SNVMA_ERROR_BUFFERID_NOT_REGISTERED,
|
||||
SNVMA_ERROR_BUFFER_NULL,
|
||||
SNVMA_ERROR_BUFFER_NOT_ALIGNED,
|
||||
SNVMA_ERROR_BUFFER_SIZE,
|
||||
SNVMA_ERROR_BUFFER_CONFIG_MISSMATCH,
|
||||
SNVMA_ERROR_FLASH_ERROR,
|
||||
SNVMA_ERROR_UNKNOWN,
|
||||
} SNVMA_Cmd_Status_t;
|
||||
|
||||
/* SNVMA callback status */
|
||||
typedef enum SNVMA_Callback_Status
|
||||
{
|
||||
SNVMA_OPERATION_COMPLETE,
|
||||
SNVMA_OPERATION_FAILED
|
||||
}SNVMA_Callback_Status_t;
|
||||
|
||||
/* Buffer Element */
|
||||
typedef struct SNVMA_BufferElt
|
||||
{
|
||||
/* Buffer address */
|
||||
uint32_t * p_Addr;
|
||||
/* Buffer size */
|
||||
uint32_t Size;
|
||||
}SNVMA_BufferElt_t;
|
||||
|
||||
/* Bank Element */
|
||||
typedef struct SNVMA_BankElt
|
||||
{
|
||||
/* Pointer onto the start address of the bank */
|
||||
uint32_t * p_StartAddr;
|
||||
/* Pointer onto the buffer address in the bank */
|
||||
uint32_t * ap_BufferAddr[SNVMA_MAX_NUMBER_BUFFER];
|
||||
}SNVMA_BankElt_t;
|
||||
|
||||
/* NVM Element */
|
||||
typedef struct SNVMA_NvmElt
|
||||
{
|
||||
/* Bank number */
|
||||
uint8_t BankNumber;
|
||||
/* Bank size */
|
||||
uint8_t BankSize;
|
||||
/*
|
||||
* Pending buffer write operations bit mask
|
||||
*
|
||||
* ----------------------------------------
|
||||
* + 4 bits | 4 bits +
|
||||
* + ------------------------------------ +
|
||||
* + Active Request | New Request +
|
||||
* ----------------------------------------
|
||||
*
|
||||
*/
|
||||
uint8_t PendingBufferWriteOp;
|
||||
/* Pointer onto the bank list */
|
||||
SNVMA_BankElt_t * p_BankList;
|
||||
/* Pointer onto the bank being used for write operation */
|
||||
SNVMA_BankElt_t * p_BankForWrite;
|
||||
/* Pointer onto the bank being used for restore operation */
|
||||
SNVMA_BankElt_t * p_BankForRestore;
|
||||
/* Callback pointer array */
|
||||
void (* a_Callback [SNVMA_MAX_NUMBER_BUFFER]) (SNVMA_Callback_Status_t);
|
||||
/* Array of buffers in use */
|
||||
SNVMA_BufferElt_t a_Buffers [SNVMA_MAX_NUMBER_BUFFER];
|
||||
}SNVMA_NvmElt_t;
|
||||
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*SIMPLE_NVM_ARBITER_COMMON_H */
|
||||
@@ -0,0 +1,298 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file log_module.c
|
||||
* @author MCD Application Team
|
||||
* @brief Source file of the log module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdio.h> /* vsnprintf */
|
||||
|
||||
#include "log_module.h"
|
||||
#include "stm32_adv_trace.h"
|
||||
#include "utilities_conf.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Definition of 'End Of Line' */
|
||||
#define ENDOFLINE_SIZE (0x01u)
|
||||
#define ENDOFLINE_CHAR '\n'
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Global const struct variables to make the life of the user easier */
|
||||
const Log_Module_t LOG_MODULE_DEFAULT_CONFIGURATION =
|
||||
{
|
||||
.verbose_level = LOG_VERBOSE_ERROR,
|
||||
.region_mask = (LOG_REGION_ALL_REGIONS)
|
||||
};
|
||||
|
||||
const Log_Verbose_Level_t LOG_VERBOSE_DEFAULT = LOG_VERBOSE_ERROR;
|
||||
const Log_Region_t LOG_REGION_MASK_DEFAULT = LOG_REGION_ALL_REGIONS;
|
||||
const Log_Color_t LOG_COLOR_DEFAULT_CONFIGURATION[] =
|
||||
{
|
||||
LOG_COLOR_CODE_DEFAULT, // For Region BLE
|
||||
LOG_COLOR_CODE_DEFAULT, // For Region System
|
||||
LOG_COLOR_CODE_DEFAULT, // For Region APP
|
||||
LOG_COLOR_CODE_RED, // For Region LinkLayer
|
||||
LOG_COLOR_CODE_YELLOW, // For Region MAC
|
||||
LOG_COLOR_CODE_GREEN, // For Region Zigbee
|
||||
LOG_COLOR_CODE_GREEN, // For Region Thread
|
||||
LOG_COLOR_CODE_DEFAULT, // For Region RTOS
|
||||
/* USER CODE BEGIN LOG_COLOR_DEFAULT_CONFIGURATION */
|
||||
|
||||
/* USER CODE END LOG_COLOR_DEFAULT_CONFIGURATION */
|
||||
};
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
static uint32_t current_region_mask;
|
||||
static Log_Verbose_Level_t current_verbose_level;
|
||||
static Log_Color_t current_color_list[32];
|
||||
CallBack_TimeStamp * log_timestamp_function;
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static uint32_t Get_Region_Mask(Log_Region_t Region);
|
||||
|
||||
#if (LOG_INSERT_COLOR_INSIDE_THE_TRACE != 0)
|
||||
static uint16_t RegionToColor(char * TextBuffer, uint16_t SizeMax, Log_Region_t Region);
|
||||
#endif /* LOG_INSERT_COLOR_INSIDE_THE_TRACE != 0 */
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
#if (LOG_INSERT_COLOR_INSIDE_THE_TRACE != 0)
|
||||
/**
|
||||
* @brief Add the color (in function of Region) on the start of Log sentence.
|
||||
*
|
||||
* @param TextBuffer Pointer on the log buffer
|
||||
* @param SizeMax The maximum number of bytes that will be written to the buffer.
|
||||
* @param Region Region of the log to apply its corresponding color.
|
||||
*
|
||||
* @return Length of the new Log.
|
||||
*/
|
||||
static uint16_t RegionToColor(char * TextBuffer, uint16_t SizeMax, Log_Region_t Region)
|
||||
{
|
||||
uint16_t text_length = 0;
|
||||
Log_Color_t color;
|
||||
static Log_Color_t previous_color = LOG_COLOR_NONE;
|
||||
|
||||
if (Region != LOG_MODULE_ALL_REGION_MASK)
|
||||
{
|
||||
color = current_color_list[Region];
|
||||
}
|
||||
else
|
||||
{
|
||||
color = LOG_COLOR_CODE_DEFAULT;
|
||||
}
|
||||
|
||||
/* Insert Color code only if previous is not the same */
|
||||
if (color != previous_color)
|
||||
{
|
||||
if (color == LOG_COLOR_CODE_DEFAULT)
|
||||
{
|
||||
snprintf(TextBuffer, SizeMax, "\x1b[0m");
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(TextBuffer, SizeMax, "\x1b[0;%02dm", color);
|
||||
}
|
||||
|
||||
previous_color = color;
|
||||
text_length = strlen(TextBuffer);
|
||||
}
|
||||
|
||||
return text_length;
|
||||
}
|
||||
#endif /* LOG_INSERT_COLOR_INSIDE_THE_TRACE != 0 */
|
||||
|
||||
void Log_Module_PrintWithArg(Log_Verbose_Level_t VerboseLevel, Log_Region_t Region, const char * Text, va_list Args)
|
||||
{
|
||||
uint16_t tmp_size = 0;
|
||||
uint16_t buffer_size = 0;
|
||||
char full_text[UTIL_ADV_TRACE_TMP_BUF_SIZE + 1u];
|
||||
|
||||
/* USER CODE BEGIN Log_Module_PrintWithArg_1 */
|
||||
|
||||
/* USER CODE END Log_Module_PrintWithArg_1 */
|
||||
|
||||
/* If the verbose level of the given log is not enabled, then we do not print the log */
|
||||
if (VerboseLevel > current_verbose_level)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the region for the given log is not enabled, then we do not print the log */
|
||||
if ((Get_Region_Mask(Region) & current_region_mask) == 0u)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if (LOG_INSERT_COLOR_INSIDE_THE_TRACE != 0)
|
||||
/* Add to full_text the color matching the region */
|
||||
tmp_size = RegionToColor(&full_text[buffer_size], (UTIL_ADV_TRACE_TMP_BUF_SIZE - buffer_size), Region);
|
||||
buffer_size += tmp_size;
|
||||
#endif /* LOG_INSERT_COLOR_INSIDE_THE_TRACE != 0 */
|
||||
|
||||
#if (LOG_INSERT_TIME_STAMP_INSIDE_THE_TRACE != 0)
|
||||
if (log_timestamp_function != NULL)
|
||||
{
|
||||
tmp_size = UTIL_ADV_TRACE_TMP_BUF_SIZE - buffer_size;
|
||||
log_timestamp_function(&full_text[buffer_size], tmp_size, &tmp_size);
|
||||
buffer_size += tmp_size;
|
||||
}
|
||||
#endif /* LOG_INSERT_TIME_STAMP_INSIDE_THE_TRACE != 0 */
|
||||
|
||||
/* Copy the data */
|
||||
tmp_size = (uint16_t)vsnprintf(&full_text[buffer_size], (UTIL_ADV_TRACE_TMP_BUF_SIZE - buffer_size), Text, Args);
|
||||
buffer_size += tmp_size;
|
||||
|
||||
/* USER CODE BEGIN Log_Module_PrintWithArg_2 */
|
||||
|
||||
/* USER CODE END Log_Module_PrintWithArg_2 */
|
||||
|
||||
#if (LOG_INSERT_EOL_INSIDE_THE_TRACE != 0)
|
||||
/* Add End Of Line if needed */
|
||||
if (buffer_size > 1)
|
||||
{
|
||||
if ((full_text[buffer_size - 1] != ENDOFLINE_CHAR) && (full_text[buffer_size - 2] != ENDOFLINE_CHAR))
|
||||
{
|
||||
full_text[buffer_size++] = ENDOFLINE_CHAR;
|
||||
full_text[buffer_size] = 0;
|
||||
}
|
||||
}
|
||||
#endif /* LOG_INSERT_EOL_INSIDE_THE_TRACE != 0 */
|
||||
|
||||
/* USER CODE BEGIN Log_Module_PrintWithArg_3 */
|
||||
|
||||
/* USER CODE END Log_Module_PrintWithArg_3 */
|
||||
|
||||
/* Send full_text to ADV Traces */
|
||||
UTIL_ADV_TRACE_Send((const uint8_t *)full_text, buffer_size);
|
||||
}
|
||||
|
||||
void Log_Module_Print(Log_Verbose_Level_t VerboseLevel, Log_Region_t Region, const char * Text, ...)
|
||||
{
|
||||
#if (CFG_LOG_SUPPORTED != 0)
|
||||
va_list variadic_args;
|
||||
|
||||
va_start(variadic_args, Text);
|
||||
Log_Module_PrintWithArg(VerboseLevel, Region, Text, variadic_args);
|
||||
va_end(variadic_args);
|
||||
#else /* (CFG_LOG_SUPPORTED != 0) */
|
||||
UNUSED(VerboseLevel);
|
||||
UNUSED(Region);
|
||||
UNUSED(Text);
|
||||
#endif /* (CFG_LOG_SUPPORTED != 0) */
|
||||
}
|
||||
|
||||
void Log_Module_Init(Log_Module_t LogConfiguration)
|
||||
{
|
||||
UTIL_ADV_TRACE_Init();
|
||||
|
||||
memcpy(¤t_color_list, &LOG_COLOR_DEFAULT_CONFIGURATION, sizeof(LOG_COLOR_DEFAULT_CONFIGURATION));
|
||||
Log_Module_Set_Verbose_Level(LogConfiguration.verbose_level);
|
||||
Log_Module_Set_Multiple_Regions(LogConfiguration.region_mask);
|
||||
log_timestamp_function = NULL;
|
||||
}
|
||||
|
||||
void Log_Module_DeInit(void)
|
||||
{
|
||||
UTIL_ADV_TRACE_DeInit();
|
||||
}
|
||||
|
||||
void Log_Module_Set_Verbose_Level(Log_Verbose_Level_t NewVerboseLevel)
|
||||
{
|
||||
current_verbose_level = NewVerboseLevel;
|
||||
}
|
||||
|
||||
void Log_Module_Set_Region(Log_Region_t NewRegion)
|
||||
{
|
||||
current_region_mask = Get_Region_Mask(NewRegion);
|
||||
}
|
||||
|
||||
void Log_Module_Add_Region(Log_Region_t NewRegion)
|
||||
{
|
||||
current_region_mask |= Get_Region_Mask(NewRegion);
|
||||
}
|
||||
|
||||
void Log_Module_Remove_Region(Log_Region_t Region)
|
||||
{
|
||||
current_region_mask &= ~Get_Region_Mask(Region);
|
||||
}
|
||||
|
||||
void Log_Module_Enable_All_Regions(void)
|
||||
{
|
||||
Log_Module_Set_Region(LOG_REGION_ALL_REGIONS);
|
||||
}
|
||||
|
||||
static uint32_t Get_Region_Mask(Log_Region_t Region)
|
||||
{
|
||||
if (Region == LOG_REGION_ALL_REGIONS)
|
||||
{
|
||||
/* Return the full mask */
|
||||
return ((uint32_t)LOG_MODULE_ALL_REGION_MASK);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return the bit matching the region */
|
||||
return ((uint32_t)(1U << ((uint32_t)Region)));
|
||||
}
|
||||
}
|
||||
|
||||
void Log_Module_Set_Multiple_Regions(uint32_t NewRegionMask)
|
||||
{
|
||||
current_region_mask = NewRegionMask;
|
||||
}
|
||||
|
||||
void Log_Module_Set_Color(Log_Region_t Region, Log_Color_t Color)
|
||||
{
|
||||
if ( Region != LOG_MODULE_ALL_REGION_MASK )
|
||||
{
|
||||
current_color_list[Region] = Color;
|
||||
}
|
||||
}
|
||||
|
||||
void Log_Module_RegisterTimeStampFunction(CallBack_TimeStamp * TimeStampFunction)
|
||||
{
|
||||
log_timestamp_function = TimeStampFunction;
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
@@ -0,0 +1,220 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file log_module.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of the log module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef LOG_MODULE_H
|
||||
#define LOG_MODULE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "log_module_conf.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Log module types */
|
||||
/**
|
||||
* @brief Data type to initialize the module by calling Log_Module_Init.
|
||||
* verbose_level : A value of type Log_Verbose_Level_t.
|
||||
* region_mask : A mask based on Log_Region_t.
|
||||
* You can directly assign it to LOG_REGION_ALL_REGIONS,
|
||||
* or select only some regions :
|
||||
* (1U << LOG_REGION_BLE | 1U << LOG_REGION_APP)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Log_Verbose_Level_t verbose_level;
|
||||
uint32_t region_mask;
|
||||
} Log_Module_t;
|
||||
|
||||
/**
|
||||
* @brief Callback function to insert Time Stamp.
|
||||
*
|
||||
* @param Data The data into which to insert the TimeStamp.
|
||||
* @param SizeMax The maximum size for the TimeStamp insert.
|
||||
* @param TimeStampSize Pointer to update with the size of the TimeStamp inserted into data.
|
||||
*/
|
||||
typedef void CallBack_TimeStamp(char * Data, uint16_t SizeMax, uint16_t * TimeStampSize);
|
||||
|
||||
/* USER CODE BEGIN ET */
|
||||
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Global const struct variables to make the life of the user easier */
|
||||
/**
|
||||
* @brief A const struct with default parameters for the log module.
|
||||
* Its main use is to pass it as parameter to Log_Module_Init.
|
||||
*/
|
||||
extern const Log_Module_t LOG_MODULE_DEFAULT_CONFIGURATION;
|
||||
|
||||
/**
|
||||
* @brief A const enum variable with the verbose level set to LOG_VERBOSE_ERROR.
|
||||
* The levels include the lower levels in the logs.
|
||||
*
|
||||
* E.g. LOG_VERBOSE_ERROR means LOG_VERBOSE_ERROR logs will be printed,
|
||||
* as well as LOG_VERBOSE_INFO, but not the others with higher values.
|
||||
*/
|
||||
extern const Log_Verbose_Level_t LOG_VERBOSE_DEFAULT;
|
||||
|
||||
/**
|
||||
* @brief A const enum variable to include all regions in the logs.
|
||||
*/
|
||||
extern const Log_Region_t LOG_REGION_MASK_DEFAULT;
|
||||
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
/* Module API - Module configuration */
|
||||
/**
|
||||
* @brief Initialization of the log module.
|
||||
*
|
||||
* @param LogConfiguration The configuration of the log module, of type Log_Module_t.
|
||||
* @return None.
|
||||
*/
|
||||
void Log_Module_Init(Log_Module_t LogConfiguration);
|
||||
|
||||
/**
|
||||
* @brief DeInitialization of the log module.
|
||||
*
|
||||
* @param None.
|
||||
* @return None.
|
||||
*/
|
||||
void Log_Module_DeInit(void);
|
||||
|
||||
/**
|
||||
* @brief Set the verbose level of the log.
|
||||
* The levels include the lower levels in the logs.
|
||||
*
|
||||
* E.g. LOG_VERBOSE_ERROR means LOG_VERBOSE_ERROR logs will be printed,
|
||||
* as well as LOG_VERBOSE_INFO, but not the others with higher values.
|
||||
*
|
||||
* @param NewVerboseLevel The new verbose level to be set, of type Log_Verbose_Level_t
|
||||
* @return None
|
||||
*/
|
||||
void Log_Module_Set_Verbose_Level(Log_Verbose_Level_t NewVerboseLevel);
|
||||
|
||||
/**
|
||||
* @brief Replace the current regions in use and only set the given region.
|
||||
*
|
||||
* @param NewRegion The new region to use, of type Log_Region_t.
|
||||
* @return None.
|
||||
*/
|
||||
void Log_Module_Set_Region(Log_Region_t NewRegion);
|
||||
|
||||
/**
|
||||
* @brief Replace the current regions in use and set one or several as replacement.
|
||||
*
|
||||
* @param NewRegionMask A mask, of type uint32_t, where each bit corresponds to a region.
|
||||
* You can directly assign it to LOG_REGION_ALL_REGIONS to enable all of them,
|
||||
* or select only some regions, e.g. (1U << LOG_REGION_BLE | 1U << LOG_REGION_APP)
|
||||
* @return None.
|
||||
*/
|
||||
void Log_Module_Set_Multiple_Regions(uint32_t NewRegionMask);
|
||||
|
||||
/**
|
||||
* @brief Add to the current region mask the given region.
|
||||
*
|
||||
* @param NewRegion The new region to use, alongside the others, of type Log_Region_t.
|
||||
* @return None.
|
||||
*/
|
||||
void Log_Module_Add_Region(Log_Region_t NewRegion);
|
||||
|
||||
/**
|
||||
* @brief Remove from the current region mask the given region.
|
||||
*
|
||||
* @param Region The region to remove, of type Log_Region_t.
|
||||
* @return None.
|
||||
*/
|
||||
void Log_Module_Remove_Region(Log_Region_t Region);
|
||||
|
||||
/**
|
||||
* @brief Enable all the regions.
|
||||
*
|
||||
* @param None.
|
||||
* @return None.
|
||||
*/
|
||||
void Log_Module_Enable_All_Regions(void);
|
||||
|
||||
/**
|
||||
* @brief Set the color for a region.
|
||||
*
|
||||
* @param Region The region where apply the color, type Log_Region_t.
|
||||
* @param Color The color to apply to selected region, of type Log_Color_t.
|
||||
* @return None.
|
||||
*/
|
||||
void Log_Module_Set_Color(Log_Region_t Region, Log_Color_t Color);
|
||||
|
||||
/**
|
||||
* @brief Register a callback function to insert the TimeStamp into the data.
|
||||
*
|
||||
* @param TimeStampFunction Callback function to insert TimeStamp.
|
||||
* This function is typedef void (char * data, uint16_t size_max, uint16_t * timestamp_size);
|
||||
* Where data is the location where to insert the new TimeStamp, and timestamp_size is the size of this insertion.
|
||||
* @return None.
|
||||
*/
|
||||
void Log_Module_RegisterTimeStampFunction(CallBack_TimeStamp * TimeStampFunction);
|
||||
|
||||
/* Module API - Wrapper function */
|
||||
/**
|
||||
* @brief Underlying function of all the LOG_xxx macros.
|
||||
*
|
||||
* @param VerboseLevel The level of verbose used for this Log, of type Log_Verbose_Level_t.
|
||||
* @param Region The region set for this log, of type Log_Region_t.
|
||||
* @param Text The text to be printed.
|
||||
* @param ... Any other parameters to be printed with the text.
|
||||
* E.g. an int variable. as 3rd parameter, as long as %d is in text.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void Log_Module_Print(Log_Verbose_Level_t VerboseLevel, Log_Region_t Region, const char * Text, ...);
|
||||
|
||||
/**
|
||||
* @brief Function of log with already a arg list.
|
||||
*
|
||||
* @param VerboseLevel The level of verbose used for this Log, of type Log_Verbose_Level_t.
|
||||
* @param Region The region set for this log, of type Log_Region_t.
|
||||
* @param Text The text to be printed
|
||||
* @param Args Arguments list, of type va_list.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void Log_Module_PrintWithArg(Log_Verbose_Level_t VerboseLevel, Log_Region_t Region, const char * Text, va_list Args);
|
||||
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LOG_MODULE_H */
|
||||
@@ -0,0 +1,294 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file log_module_conf.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of the log module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef LOG_MODULE_CONF_H
|
||||
#define LOG_MODULE_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "app_conf.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Module configuration ------------------------------------------------------*/
|
||||
/**
|
||||
* @brief When this define is set to 0, there is no time stamp added to the trace data.
|
||||
* When this define is set to 1, the time stamp is added to the trace data,
|
||||
* according to the function registered with Log_Module_RegisterTimeStampFunction.
|
||||
*/
|
||||
#define LOG_INSERT_TIME_STAMP_INSIDE_THE_TRACE CFG_LOG_INSERT_TIME_STAMP_INSIDE_THE_TRACE
|
||||
|
||||
/**
|
||||
* @brief When this define is set to 0, the color of the trace data remains the same for all regions.
|
||||
* When this define is set to 1, the color added to the trace data is based on LOG_COLOR_DEFAULT_CONFIGURATION.
|
||||
*/
|
||||
#define LOG_INSERT_COLOR_INSIDE_THE_TRACE CFG_LOG_INSERT_COLOR_INSIDE_THE_TRACE
|
||||
|
||||
/**
|
||||
* @brief When this define is set to 0, the trace data is not modified.
|
||||
* When this define is set to 1, if there is no ENDOFLINE_CHAR as last
|
||||
* character in the trace data, then one is added.
|
||||
*/
|
||||
#define LOG_INSERT_EOL_INSIDE_THE_TRACE CFG_LOG_INSERT_EOL_INSIDE_THE_TRACE
|
||||
|
||||
/* USER CODE BEGIN Module configuration */
|
||||
|
||||
/* USER CODE END Module configuration */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/* These defines are related to the UTIL_ADV_TRACE. Do not modify them please. */
|
||||
#define LOG_MODULE_MIN_VERBOSE_LEVEL (0)
|
||||
#define LOG_MODULE_MAX_VERBOSE_LEVEL (0xFFFFFFFF)
|
||||
#define LOG_MODULE_MIN_REGION_VALUE (0)
|
||||
#define LOG_MODULE_ALL_REGION_MASK (0xFFFFFFFF)
|
||||
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Log module types */
|
||||
/**
|
||||
* @brief Customizable enum describing the verbose levels used by the log module.
|
||||
* The levels include the lower levels in the logs.
|
||||
*
|
||||
* E.g. LOG_VERBOSE_ERROR means LOG_VERBOSE_ERROR logs will be printed,
|
||||
* as well as LOG_VERBOSE_INFO, but not the others with higher values.
|
||||
*
|
||||
* The min and max ranges are defined by LOG_MODULE_MIN_VERBOSE_LEVEL
|
||||
* and LOG_MODULE_MAX_VERBOSE_LEVEL.
|
||||
*
|
||||
* The user can add its own levels but must NOT add a value to the said
|
||||
* levels. Verbose levels are handled by the UTIL_ADV_TRACE.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LOG_VERBOSE_INFO = LOG_MODULE_MIN_VERBOSE_LEVEL,
|
||||
/* USER CODE BEGIN Log_Verbose_Level_t_0 */
|
||||
|
||||
/* USER CODE END Log_Verbose_Level_t_0 */
|
||||
LOG_VERBOSE_ERROR,
|
||||
/* USER CODE BEGIN Log_Verbose_Level_t_1 */
|
||||
|
||||
/* USER CODE END Log_Verbose_Level_t_1 */
|
||||
LOG_VERBOSE_WARNING,
|
||||
/* USER CODE BEGIN Log_Verbose_Level_t_2 */
|
||||
|
||||
/* USER CODE END Log_Verbose_Level_t_2 */
|
||||
LOG_VERBOSE_DEBUG,
|
||||
/* USER CODE BEGIN Log_Verbose_Level_t_3 */
|
||||
|
||||
/* USER CODE END Log_Verbose_Level_t_3 */
|
||||
LOG_VERBOSE_ALL_LOGS = LOG_MODULE_MAX_VERBOSE_LEVEL,
|
||||
} Log_Verbose_Level_t;
|
||||
|
||||
/**
|
||||
* @brief Customizable enum describing the regions used by the log module.
|
||||
* Regions are used to separate the logs into different places.
|
||||
*
|
||||
* Let's say you have a Task 1 and a Task 2.
|
||||
* Both of them have Info and Debug logs.
|
||||
*
|
||||
* By using them as such, i.e. with the same regions, you'll
|
||||
* print the logs of the 2 tasks as long as the verbose is Info or Debug.
|
||||
*
|
||||
* If you create a region for Task 1 and another for Task 2, you can
|
||||
* split the logs between them, and, if needed, only print the Debug
|
||||
* logs for Task 1 only (i.e. Task 1 logs for Info and Debug).
|
||||
*
|
||||
* Behind the scenes is a mask into which each region is a bit.
|
||||
* The user can add its own regions but must NOT add a value to them.
|
||||
* The log module handles the mask on its own.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LOG_REGION_BLE = LOG_MODULE_MIN_REGION_VALUE,
|
||||
LOG_REGION_SYSTEM,
|
||||
LOG_REGION_APP,
|
||||
LOG_REGION_LINKLAYER,
|
||||
LOG_REGION_MAC,
|
||||
LOG_REGION_ZIGBEE,
|
||||
LOG_REGION_THREAD,
|
||||
LOG_REGION_RTOS,
|
||||
/* USER CODE BEGIN Log_Region_t */
|
||||
|
||||
/* USER CODE END Log_Region_t */
|
||||
LOG_REGION_ALL_REGIONS = LOG_MODULE_ALL_REGION_MASK,
|
||||
} Log_Region_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LOG_COLOR_NONE = 0, /* Initialization */
|
||||
LOG_COLOR_CODE_DEFAULT = 37, /* White */
|
||||
LOG_COLOR_CODE_RED = 91,
|
||||
LOG_COLOR_CODE_GREEN = 92,
|
||||
LOG_COLOR_CODE_YELLOW = 93,
|
||||
LOG_COLOR_CODE_CYAN = 96,
|
||||
/* USER CODE BEGIN Log_Color_t */
|
||||
|
||||
/* USER CODE END Log_Color_t */
|
||||
} Log_Color_t;
|
||||
|
||||
/* USER CODE BEGIN ET */
|
||||
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Display 64 bits number for all compiler. */
|
||||
/* Example : LOG_INFO_APP( "New Device : " LOG_DISPLAY64() " installed in %d seconds", LOG_NUMBER64( dlDevice ), iTime ); */
|
||||
#define LOG_DISPLAY64() "0x%08X%08X"
|
||||
#define LOG_NUMBER64( number ) (uint32_t)( number >> 32u ), (uint32_t)( number )
|
||||
|
||||
/* Module API - Log macros for each region */
|
||||
/* LOG_REGION_BLE */
|
||||
#if (CFG_LOG_SUPPORTED != 0)
|
||||
#define LOG_INFO_BLE(...) Log_Module_Print( LOG_VERBOSE_INFO, LOG_REGION_BLE, __VA_ARGS__)
|
||||
#define LOG_ERROR_BLE(...) Log_Module_Print( LOG_VERBOSE_ERROR, LOG_REGION_BLE, __VA_ARGS__)
|
||||
#define LOG_WARNING_BLE(...) Log_Module_Print( LOG_VERBOSE_WARNING, LOG_REGION_BLE, __VA_ARGS__)
|
||||
#define LOG_DEBUG_BLE(...) Log_Module_Print( LOG_VERBOSE_DEBUG, LOG_REGION_BLE, __VA_ARGS__)
|
||||
#else /* (CFG_LOG_SUPPORTED != 0) */
|
||||
#define LOG_INFO_BLE(...) do {} while(0)
|
||||
#define LOG_ERROR_BLE(...) do {} while(0)
|
||||
#define LOG_WARNING_BLE(...) do {} while(0)
|
||||
#define LOG_DEBUG_BLE(...) do {} while(0)
|
||||
#endif /* (CFG_LOG_SUPPORTED != 0) */
|
||||
|
||||
/* USER CODE BEGIN LOG_REGION_BLE */
|
||||
/**
|
||||
* Add inside this user section your defines to match the new verbose levels you
|
||||
* created into Log_Verbose_Level_t.
|
||||
* Example :
|
||||
* #define LOG_CUSTOM_BLE(...) Log_Module_Print( LOG_VERBOSE_CUSTOM, LOG_REGION_BLE, __VA_ARGS__);
|
||||
*
|
||||
* You don't need to update all regions with your custom values.
|
||||
* Do it accordingly to your needs. E.g you might not need LOG_VERBOSE_CUSTOM for a System region.
|
||||
*/
|
||||
|
||||
/* USER CODE END LOG_REGION_BLE */
|
||||
|
||||
/* LOG_REGION_SYSTEM */
|
||||
#if (CFG_LOG_SUPPORTED != 0)
|
||||
#define LOG_INFO_SYSTEM(...) Log_Module_Print( LOG_VERBOSE_INFO, LOG_REGION_SYSTEM, __VA_ARGS__)
|
||||
#define LOG_ERROR_SYSTEM(...) Log_Module_Print( LOG_VERBOSE_ERROR, LOG_REGION_SYSTEM, __VA_ARGS__)
|
||||
#define LOG_WARNING_SYSTEM(...) Log_Module_Print( LOG_VERBOSE_WARNING, LOG_REGION_SYSTEM, __VA_ARGS__)
|
||||
#define LOG_DEBUG_SYSTEM(...) Log_Module_Print( LOG_VERBOSE_DEBUG, LOG_REGION_SYSTEM, __VA_ARGS__)
|
||||
#else /* (CFG_LOG_SUPPORTED != 0) */
|
||||
#define LOG_INFO_SYSTEM(...) do {} while(0)
|
||||
#define LOG_ERROR_SYSTEM(...) do {} while(0)
|
||||
#define LOG_WARNING_SYSTEM(...) do {} while(0)
|
||||
#define LOG_DEBUG_SYSTEM(...) do {} while(0)
|
||||
#endif /* (CFG_LOG_SUPPORTED != 0) */
|
||||
|
||||
/* USER CODE BEGIN LOG_REGION_SYSTEM */
|
||||
/**
|
||||
* Add inside this user section your defines to match the new verbose levels you
|
||||
* created into Log_Verbose_Level_t.
|
||||
* Example :
|
||||
* #define LOG_CUSTOM_SYSTEM(...) Log_Module_Print( LOG_VERBOSE_CUSTOM, LOG_REGION_SYSTEM, __VA_ARGS__);
|
||||
*
|
||||
* You don't need to update all regions with your custom values.
|
||||
* Do it accordingly to your needs. E.g you might not need LOG_VERBOSE_CUSTOM for a System region.
|
||||
*/
|
||||
|
||||
/* USER CODE END LOG_REGION_SYSTEM */
|
||||
|
||||
/* LOG_REGION_APP */
|
||||
#if (CFG_LOG_SUPPORTED != 0)
|
||||
#define LOG_INFO_APP(...) Log_Module_Print( LOG_VERBOSE_INFO, LOG_REGION_APP, __VA_ARGS__)
|
||||
#define LOG_ERROR_APP(...) Log_Module_Print( LOG_VERBOSE_ERROR, LOG_REGION_APP, __VA_ARGS__)
|
||||
#define LOG_WARNING_APP(...) Log_Module_Print( LOG_VERBOSE_WARNING, LOG_REGION_APP, __VA_ARGS__)
|
||||
#define LOG_DEBUG_APP(...) Log_Module_Print( LOG_VERBOSE_DEBUG, LOG_REGION_APP, __VA_ARGS__)
|
||||
#else /* (CFG_LOG_SUPPORTED != 0) */
|
||||
#define LOG_INFO_APP(...) do {} while(0)
|
||||
#define LOG_ERROR_APP(...) do {} while(0)
|
||||
#define LOG_WARNING_APP(...) do {} while(0)
|
||||
#define LOG_DEBUG_APP(...) do {} while(0)
|
||||
#endif /* (CFG_LOG_SUPPORTED != 0) */
|
||||
|
||||
/* USER CODE BEGIN LOG_REGION_APP */
|
||||
/**
|
||||
* Add inside this user section your defines to match the new verbose levels you
|
||||
* created into Log_Verbose_Level_t.
|
||||
* Example :
|
||||
* #define LOG_CUSTOM_APP(...) Log_Module_Print( LOG_VERBOSE_CUSTOM, LOG_REGION_APP, __VA_ARGS__);
|
||||
*
|
||||
* You don't need to update all regions with your custom values.
|
||||
* Do it accordingly to your needs. E.g you might not need LOG_VERBOSE_CUSTOM for a System region.
|
||||
*/
|
||||
|
||||
/* USER CODE END LOG_REGION_APP */
|
||||
|
||||
/* LOG_REGION_LINKLAYER */
|
||||
#if (CFG_LOG_SUPPORTED != 0)
|
||||
#define LOG_INFO_LINKLAYER(...) Log_Module_Print( LOG_VERBOSE_INFO, LOG_REGION_LINKLAYER, __VA_ARGS__)
|
||||
#define LOG_ERROR_LINKLAYER(...) Log_Module_Print( LOG_VERBOSE_ERROR, LOG_REGION_LINKLAYER, __VA_ARGS__)
|
||||
#define LOG_WARNING_LINKLAYER(...)Log_Module_Print( LOG_VERBOSE_WARNING, LOG_REGION_LINKLAYER, __VA_ARGS__)
|
||||
#define LOG_DEBUG_LINKLAYER(...) Log_Module_Print( LOG_VERBOSE_DEBUG, LOG_REGION_LINKLAYER, __VA_ARGS__)
|
||||
#else /* (CFG_LOG_SUPPORTED != 0) */
|
||||
#define LOG_INFO_LINKLAYER(...) do {} while(0)
|
||||
#define LOG_ERROR_LINKLAYER(...) do {} while(0)
|
||||
#define LOG_WARNING_LINKLAYER(...)do {} while(0)
|
||||
#define LOG_DEBUG_LINKLAYER(...) do {} while(0)
|
||||
#endif /* (CFG_LOG_SUPPORTED != 0) */
|
||||
|
||||
/* USER CODE BEGIN LOG_REGION_LINKLAYER */
|
||||
/**
|
||||
* Add inside this user section your defines to match the new verbose levels you
|
||||
* created into Log_Verbose_Level_t.
|
||||
* Example :
|
||||
* #define LOG_CUSTOM_LINKLAYER(...) Log_Module_Print( LOG_VERBOSE_CUSTOM, LOG_REGION_LINKLAYER, __VA_ARGS__);
|
||||
*
|
||||
* You don't need to update all regions with your custom values.
|
||||
* Do it accordingly to your needs. E.g you might not need LOG_VERBOSE_CUSTOM for a System region.
|
||||
*/
|
||||
|
||||
/* USER CODE END LOG_REGION_LINKLAYER */
|
||||
|
||||
/* USER CODE BEGIN APP_LOG_USER_DEFINES */
|
||||
/**
|
||||
* Add inside this user section your defines to match the new regions you
|
||||
* created into Log_Region_t.
|
||||
* Example :
|
||||
#if (CFG_LOG_SUPPORTED != 0)
|
||||
#define LOG_INFO_CUSTOM(...) Log_Module_Print( LOG_VERBOSE_INFO, LOG_REGION_CUSTOM, __VA_ARGS__)
|
||||
#define LOG_ERROR_CUSTOM(...) Log_Module_Print( LOG_VERBOSE_ERROR, LOG_REGION_CUSTOM, __VA_ARGS__)
|
||||
#define LOG_WARNING_CUSTOM(...) Log_Module_Print( LOG_VERBOSE_WARNING, LOG_REGION_CUSTOM, __VA_ARGS__)
|
||||
#define LOG_DEBUG_CUSTOM(...) Log_Module_Print( LOG_VERBOSE_DEBUG, LOG_REGION_CUSTOM, __VA_ARGS__)
|
||||
#else
|
||||
#define LOG_INFO_CUSTOM(...) do {} while(0)
|
||||
#define LOG_ERROR_CUSTOM(...) do {} while(0)
|
||||
#define LOG_WARNING_CUSTOM(...) do {} while(0)
|
||||
#define LOG_DEBUG_CUSTOM(...) do {} while(0)
|
||||
#endif
|
||||
*/
|
||||
/* USER CODE END APP_LOG_USER_DEFINES */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LOG_MODULE_CONF_H */
|
||||
@@ -0,0 +1,716 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file advanced_memory_manager.c
|
||||
* @author MCD Application Team
|
||||
* @brief Memory Manager
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm_list.h"
|
||||
#include "utilities_conf.h"
|
||||
#include "advanced_memory_manager.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
|
||||
/* Defines that the module is not initialized */
|
||||
#define NOT_INITIALIZED 0x00u
|
||||
/* Defines that the module is initialized */
|
||||
#define INITIALIZED 0x01u
|
||||
|
||||
/* Defines the bit to check for 32bits aligned values */
|
||||
#define MASK_ALIGNED_32BITS 0x03u
|
||||
|
||||
/*
|
||||
Defines the length of the Virtual Memory Header in 32bits
|
||||
----------------------------------------
|
||||
| +++ 8bits +++ | +++++++ 24bits +++++++ |
|
||||
| VirtualMem ID | Buffer Size (n*32bits) |
|
||||
----------------------------------------
|
||||
*/
|
||||
#define VIRTUAL_MEMORY_HEADER_SIZE 0x01
|
||||
|
||||
/* Position of the ID field in Virtual Memory Header */
|
||||
#define VIRTUAL_MEMORY_HEADER_ID_POS 0x18
|
||||
/* Mask of the ID field in Virtual Memory Header */
|
||||
#define VIRTUAL_MEMORY_HEADER_ID_MASK 0xFF000000
|
||||
|
||||
/* Position of the Buffer Size field in Virtual Memory Header */
|
||||
#define VIRTUAL_MEMORY_HEADER_BUFFER_SIZE_POS 0x00
|
||||
/* Mask of the Buffer Size field in Virtual Memory Header */
|
||||
#define VIRTUAL_MEMORY_HEADER_BUFFER_SIZE_MASK 0x00FFFFFF
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* AMM Initialized flag */
|
||||
static uint8_t AmmInitialized = NOT_INITIALIZED;
|
||||
|
||||
/* AMM pool address */
|
||||
static uint32_t * p_AmmPoolAddress;
|
||||
|
||||
/* AMM pool size */
|
||||
static uint32_t AmmPoolSize;
|
||||
|
||||
/* AMM occupied shared pool size */
|
||||
static uint32_t AmmOccupiedSharedPoolSize;
|
||||
|
||||
#if (AMM_USE_MEMORY_STATISTICS == 1)
|
||||
/* AMM peak shared pool size */
|
||||
static uint32_t AmmPeakSharedPoolSize;
|
||||
#endif /* AMM_USE_MEMORY_STATISTICS */
|
||||
|
||||
/* AMM needed virtual memory */
|
||||
static uint32_t AmmRequiredVirtualMemorySize;
|
||||
|
||||
/* AMM virtual memory number */
|
||||
static uint32_t AmmVirtualMemoryNumber;
|
||||
|
||||
/* List of Virtual Memories info */
|
||||
static VirtualMemoryInfo_t * p_AmmVirtualMemoryList;
|
||||
|
||||
/* Handler of the Basic Memory Manager functions */
|
||||
static AMM_BasicMemoryManagerFunctions_t AmmBmmFunctionsHandler;
|
||||
|
||||
/* Pointer on the first element of the pending callbacks */
|
||||
static AMM_VirtualMemoryCallbackHeader_t AmmPendingCallback;
|
||||
|
||||
/* Pointer on the first element of the active callbacks */
|
||||
static AMM_VirtualMemoryCallbackHeader_t AmmActiveCallback;
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Push a callback structure into the Pending FIFO
|
||||
* @param p_CallbackElt: Pointer onto the callback to push
|
||||
* @return None
|
||||
*/
|
||||
static inline void pushPending (AMM_VirtualMemoryCallbackFunction_t * const p_CallbackElt);
|
||||
|
||||
/**
|
||||
* @brief Push the Pending callback(s) into the Active FIFO
|
||||
* @return None
|
||||
*/
|
||||
static inline void passPendingToActive (void);
|
||||
|
||||
/**
|
||||
* @brief Pop a callback structure from the Active FIFO
|
||||
* @return Pointer onto the popped callback
|
||||
*/
|
||||
static inline AMM_VirtualMemoryCallbackFunction_t * popActive (void);
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
#if (AMM_USE_MEMORY_STATISTICS == 1)
|
||||
uint32_t GetCurrentOccupation (const uint8_t VirtualMemoryId)
|
||||
{
|
||||
uint32_t currentOccupation = 0x00;
|
||||
|
||||
if (AmmInitialized == INITIALIZED)
|
||||
{
|
||||
/* Shared memory use case */
|
||||
if (VirtualMemoryId == AMM_NO_VIRTUAL_ID)
|
||||
{
|
||||
currentOccupation = AmmOccupiedSharedPoolSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check virtual memory info */
|
||||
for (uint32_t memIdx = 0x00;
|
||||
(memIdx < AmmVirtualMemoryNumber) && (currentOccupation == 0x00);
|
||||
memIdx++)
|
||||
{
|
||||
/* Check if ID is known */
|
||||
if (VirtualMemoryId == p_AmmVirtualMemoryList[memIdx].Id)
|
||||
{
|
||||
currentOccupation = p_AmmVirtualMemoryList[memIdx].OccupiedSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currentOccupation;
|
||||
}
|
||||
|
||||
uint32_t GetPeakOccupation (const uint8_t VirtualMemoryId)
|
||||
{
|
||||
uint32_t peakOccupation = 0x00;
|
||||
|
||||
if (AmmInitialized == INITIALIZED)
|
||||
{
|
||||
/* Shared memory use case */
|
||||
if (VirtualMemoryId == AMM_NO_VIRTUAL_ID)
|
||||
{
|
||||
peakOccupation = AmmPeakSharedPoolSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check virtual memory info */
|
||||
for (uint32_t memIdx = 0x00;
|
||||
(memIdx < AmmVirtualMemoryNumber) && (peakOccupation == 0x00);
|
||||
memIdx++)
|
||||
{
|
||||
/* Check if ID is known */
|
||||
if (VirtualMemoryId == p_AmmVirtualMemoryList[memIdx].Id)
|
||||
{
|
||||
peakOccupation = p_AmmVirtualMemoryList[memIdx].PeakOccupationSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return peakOccupation;
|
||||
}
|
||||
#endif /* AMM_USE_MEMORY_STATISTICS */
|
||||
|
||||
AMM_Function_Error_t AMM_Init (const AMM_InitParameters_t * const p_InitParams)
|
||||
{
|
||||
AMM_Function_Error_t error = AMM_ERROR_NOK;
|
||||
|
||||
uint32_t neededPoolSize = 0x00;
|
||||
|
||||
/* Check if not already initialized */
|
||||
if (AmmInitialized == INITIALIZED)
|
||||
{
|
||||
error = AMM_ERROR_ALREADY_INIT;
|
||||
}
|
||||
/* Check parameter null pointer */
|
||||
else if (p_InitParams == NULL)
|
||||
{
|
||||
error = AMM_ERROR_BAD_POINTER;
|
||||
}
|
||||
/* Check Pool address null pointer */
|
||||
else if (p_InitParams->p_PoolAddr == NULL)
|
||||
{
|
||||
error = AMM_ERROR_BAD_POOL_CONFIG;
|
||||
}
|
||||
/* Check if Pool address is 32bits aligned */
|
||||
else if ((MASK_ALIGNED_32BITS & (uint32_t)p_InitParams->p_PoolAddr) != 0)
|
||||
{
|
||||
error = AMM_ERROR_BAD_POOL_CONFIG;
|
||||
}
|
||||
/* Check Pool size shall be non zero */
|
||||
else if (p_InitParams->PoolSize == 0)
|
||||
{
|
||||
error = AMM_ERROR_BAD_POOL_CONFIG;
|
||||
}
|
||||
/* Check that Virtual memories can not be declared without a proper configuration list */
|
||||
else if ((p_InitParams->VirtualMemoryNumber != 0x00) &&
|
||||
(p_InitParams->p_VirtualMemoryConfigList == NULL))
|
||||
{
|
||||
error = AMM_ERROR_BAD_VIRTUAL_CONFIG;
|
||||
}
|
||||
else
|
||||
{
|
||||
neededPoolSize = p_InitParams->VirtualMemoryNumber * AMM_VIRTUAL_INFO_ELEMENT_SIZE;
|
||||
|
||||
/* Check the parameters relative to virtual memories */
|
||||
for (uint32_t memIdx = 0x00;
|
||||
(memIdx < p_InitParams->VirtualMemoryNumber) && (error == AMM_ERROR_NOK);
|
||||
memIdx++)
|
||||
{
|
||||
/* Add the amount of needed space for this virtual memory */
|
||||
neededPoolSize = neededPoolSize + p_InitParams->p_VirtualMemoryConfigList[memIdx].BufferSize;
|
||||
|
||||
/* Check the virtual memory ID. Shall not be zero */
|
||||
if (p_InitParams->p_VirtualMemoryConfigList[memIdx].Id == 0)
|
||||
{
|
||||
error = AMM_ERROR_BAD_VIRTUAL_CONFIG;
|
||||
}
|
||||
/* Check if size is not zero */
|
||||
else if (p_InitParams->p_VirtualMemoryConfigList[memIdx].BufferSize == 0)
|
||||
{
|
||||
error = AMM_ERROR_BAD_VIRTUAL_CONFIG;
|
||||
}
|
||||
/* Check if amount of needed memory has overlapped current pool size */
|
||||
else if (p_InitParams->PoolSize < neededPoolSize)
|
||||
{
|
||||
error = AMM_ERROR_BAD_VIRTUAL_CONFIG;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do nothing, all ok yet */
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if parameters are still ok */
|
||||
if (error == AMM_ERROR_NOK)
|
||||
{
|
||||
/* Init all private variables: Pool relative */
|
||||
p_AmmPoolAddress = NULL;
|
||||
AmmPoolSize = 0x00;
|
||||
AmmOccupiedSharedPoolSize = 0x00;
|
||||
AmmRequiredVirtualMemorySize = 0x00;
|
||||
|
||||
/* Init all private variables: Virtual Memory relative */
|
||||
AmmVirtualMemoryNumber = 0x00;
|
||||
p_AmmVirtualMemoryList = NULL;
|
||||
|
||||
/* Init all private variables: BMM relative */
|
||||
AmmBmmFunctionsHandler.Init = NULL;
|
||||
AmmBmmFunctionsHandler.Allocate = NULL;
|
||||
AmmBmmFunctionsHandler.Free = NULL;
|
||||
|
||||
/* Init all private variables: Callbacks relative */
|
||||
AmmPendingCallback.next = NULL;
|
||||
AmmPendingCallback.prev = NULL;
|
||||
AmmActiveCallback.next = NULL;
|
||||
AmmActiveCallback.prev = NULL;
|
||||
|
||||
/* First get the Basic Memory Manager functions back */
|
||||
AMM_RegisterBasicMemoryManager (&AmmBmmFunctionsHandler);
|
||||
|
||||
if ((AmmBmmFunctionsHandler.Init == NULL)
|
||||
|| (AmmBmmFunctionsHandler.Allocate == NULL)
|
||||
|| (AmmBmmFunctionsHandler.Free == NULL))
|
||||
{
|
||||
error = AMM_ERROR_BAD_BMM_REGISTRATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Store the pool info */
|
||||
p_AmmPoolAddress = p_InitParams->p_PoolAddr;
|
||||
AmmPoolSize = p_InitParams->PoolSize;
|
||||
|
||||
/* First init the Basic Memory Manager */
|
||||
AmmBmmFunctionsHandler.Init (p_AmmPoolAddress,
|
||||
AmmPoolSize);
|
||||
|
||||
/* Allocate memory for the virtual memories info */
|
||||
p_AmmVirtualMemoryList = (VirtualMemoryInfo_t *)
|
||||
(AmmBmmFunctionsHandler. Allocate (AMM_VIRTUAL_INFO_ELEMENT_SIZE
|
||||
* p_InitParams->VirtualMemoryNumber));
|
||||
|
||||
/* Check if allocation is OK*/
|
||||
if ((p_AmmVirtualMemoryList == NULL) && (p_InitParams->VirtualMemoryNumber > 0))
|
||||
{
|
||||
error = AMM_ERROR_BAD_BMM_ALLOCATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Init Critical section */
|
||||
UTIL_SEQ_INIT_CRITICAL_SECTION ();
|
||||
|
||||
/* Init both pending and active list */
|
||||
LST_init_head (&AmmPendingCallback);
|
||||
LST_init_head (&AmmActiveCallback);
|
||||
|
||||
/* Keep going on init, fulfill the virtual memories info */
|
||||
AmmVirtualMemoryNumber = p_InitParams->VirtualMemoryNumber;
|
||||
|
||||
/* Actualize actual shared pool occupied size */
|
||||
AmmOccupiedSharedPoolSize = AmmOccupiedSharedPoolSize + (AMM_VIRTUAL_INFO_ELEMENT_SIZE
|
||||
* AmmVirtualMemoryNumber);
|
||||
|
||||
#if (AMM_USE_MEMORY_STATISTICS == 1)
|
||||
AmmPeakSharedPoolSize = AmmOccupiedSharedPoolSize;
|
||||
#endif /* AMM_USE_MEMORY_STATISTICS */
|
||||
|
||||
for (uint32_t memIdx = 0x00;
|
||||
memIdx < AmmVirtualMemoryNumber;
|
||||
memIdx++)
|
||||
{
|
||||
p_AmmVirtualMemoryList[memIdx].Id = p_InitParams->p_VirtualMemoryConfigList[memIdx].Id;
|
||||
p_AmmVirtualMemoryList[memIdx].RequiredSize = p_InitParams->p_VirtualMemoryConfigList[memIdx].BufferSize;
|
||||
p_AmmVirtualMemoryList[memIdx].OccupiedSize = 0x00;
|
||||
#if (AMM_USE_MEMORY_STATISTICS == 1)
|
||||
p_AmmVirtualMemoryList[memIdx].PeakOccupationSize = 0x00;
|
||||
#endif /* AMM_USE_MEMORY_STATISTICS */
|
||||
|
||||
AmmRequiredVirtualMemorySize = AmmRequiredVirtualMemorySize + p_AmmVirtualMemoryList[memIdx].RequiredSize;
|
||||
}
|
||||
|
||||
/* Set init flag */
|
||||
AmmInitialized = INITIALIZED;
|
||||
|
||||
/* All info are stored and AMM is initialized */
|
||||
error = AMM_ERROR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
AMM_Function_Error_t AMM_DeInit (void)
|
||||
{
|
||||
AMM_Function_Error_t error = AMM_ERROR_NOK;
|
||||
|
||||
/* Check if initialized */
|
||||
if (AmmInitialized == INITIALIZED)
|
||||
{
|
||||
/* Free resources */
|
||||
AmmBmmFunctionsHandler.Free ((uint32_t *)p_AmmVirtualMemoryList);
|
||||
|
||||
/* Reset all the variables */
|
||||
AmmBmmFunctionsHandler.Init = NULL;
|
||||
AmmBmmFunctionsHandler.Allocate = NULL;
|
||||
AmmBmmFunctionsHandler.Free = NULL;
|
||||
|
||||
p_AmmPoolAddress = 0x00;
|
||||
AmmPoolSize = 0x00;
|
||||
AmmOccupiedSharedPoolSize = 0x00;
|
||||
AmmRequiredVirtualMemorySize = 0x00;
|
||||
AmmVirtualMemoryNumber = 0x00;
|
||||
|
||||
/* Unset the flag */
|
||||
AmmInitialized = 0x00;
|
||||
|
||||
error = AMM_ERROR_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = AMM_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
AMM_Function_Error_t AMM_Alloc (const uint8_t VirtualMemoryId,
|
||||
const uint32_t BufferSize,
|
||||
uint32_t ** pp_AllocBuffer,
|
||||
AMM_VirtualMemoryCallbackFunction_t * const p_CallBackFunction)
|
||||
{
|
||||
AMM_Function_Error_t error = AMM_ERROR_NOK;
|
||||
|
||||
uint32_t selfAvailable = 0x00;
|
||||
|
||||
uint32_t * p_TmpAllocAddr = NULL;
|
||||
|
||||
/* Set pointer to NULL */
|
||||
*pp_AllocBuffer = NULL;
|
||||
|
||||
if (AmmInitialized == NOT_INITIALIZED)
|
||||
{
|
||||
error = AMM_ERROR_NOT_INIT;
|
||||
}
|
||||
/* Check if buffer size is not zero */
|
||||
else if (BufferSize == 0)
|
||||
{
|
||||
error = AMM_ERROR_BAD_ALLOCATION_SIZE;
|
||||
}
|
||||
/* Check if no virtual ID requested */
|
||||
else if (VirtualMemoryId == AMM_NO_VIRTUAL_ID)
|
||||
{
|
||||
/* Enter critical section */
|
||||
UTIL_SEQ_ENTER_CRITICAL_SECTION ();
|
||||
|
||||
/* Check for enough space in the shared pool */
|
||||
if (BufferSize < (AmmPoolSize - AmmOccupiedSharedPoolSize - AmmRequiredVirtualMemorySize))
|
||||
{
|
||||
/* Try Allocation. Do not forget the header */
|
||||
p_TmpAllocAddr = AmmBmmFunctionsHandler.Allocate (BufferSize + VIRTUAL_MEMORY_HEADER_SIZE);
|
||||
|
||||
/* Check if allocation is OK */
|
||||
if (p_TmpAllocAddr != NULL)
|
||||
{
|
||||
/* Fulfill the header */
|
||||
*p_TmpAllocAddr = (uint32_t)(((uint32_t)VirtualMemoryId << VIRTUAL_MEMORY_HEADER_ID_POS)
|
||||
& VIRTUAL_MEMORY_HEADER_ID_MASK)
|
||||
| ((BufferSize << VIRTUAL_MEMORY_HEADER_BUFFER_SIZE_POS)
|
||||
& VIRTUAL_MEMORY_HEADER_BUFFER_SIZE_MASK);
|
||||
|
||||
/* Provide the right address to user, ie without the header */
|
||||
*pp_AllocBuffer = (uint32_t *)(p_TmpAllocAddr + VIRTUAL_MEMORY_HEADER_SIZE);
|
||||
|
||||
/* Actualize the current memory occupation of the shared space */
|
||||
AmmOccupiedSharedPoolSize = AmmOccupiedSharedPoolSize + BufferSize + VIRTUAL_MEMORY_HEADER_SIZE;
|
||||
|
||||
#if (AMM_USE_MEMORY_STATISTICS == 1)
|
||||
/* Check if peak occupation has to be updated */
|
||||
if (AmmOccupiedSharedPoolSize > AmmPeakSharedPoolSize)
|
||||
{
|
||||
AmmPeakSharedPoolSize = AmmOccupiedSharedPoolSize;
|
||||
}
|
||||
#endif /* AMM_USE_MEMORY_STATISTICS */
|
||||
|
||||
error = AMM_ERROR_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Register the callback for a future retry */
|
||||
pushPending (p_CallBackFunction);
|
||||
|
||||
error = AMM_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Register the callback for a future retry */
|
||||
pushPending (p_CallBackFunction);
|
||||
|
||||
error = AMM_ERROR_BAD_ALLOCATION_SIZE;
|
||||
}
|
||||
|
||||
/* Exit critical section */
|
||||
UTIL_SEQ_EXIT_CRITICAL_SECTION ();
|
||||
}
|
||||
/* A specific ID is requested */
|
||||
else
|
||||
{
|
||||
error = AMM_ERROR_UNKNOWN_ID;
|
||||
|
||||
/* Enter critical section */
|
||||
UTIL_SEQ_ENTER_CRITICAL_SECTION ();
|
||||
|
||||
/* Check virtual memory info */
|
||||
for (uint32_t memIdx = 0x00;
|
||||
(memIdx < AmmVirtualMemoryNumber) && (error == AMM_ERROR_UNKNOWN_ID);
|
||||
memIdx++)
|
||||
{
|
||||
/* Check if ID is known */
|
||||
if (VirtualMemoryId == p_AmmVirtualMemoryList[memIdx].Id)
|
||||
{
|
||||
/* Check if all the reserved memory has been consumed */
|
||||
if (p_AmmVirtualMemoryList[memIdx].OccupiedSize < p_AmmVirtualMemoryList[memIdx].RequiredSize)
|
||||
{
|
||||
/* Compute what is remaining */
|
||||
selfAvailable = p_AmmVirtualMemoryList[memIdx].RequiredSize
|
||||
- p_AmmVirtualMemoryList[memIdx].OccupiedSize;
|
||||
}
|
||||
|
||||
/* Check if there is enough space in the shared pool plus in our virtual memory pool */
|
||||
if (BufferSize < (AmmPoolSize - AmmOccupiedSharedPoolSize - AmmRequiredVirtualMemorySize + selfAvailable))
|
||||
{
|
||||
/* Try Allocation. Do not forget the header */
|
||||
p_TmpAllocAddr = AmmBmmFunctionsHandler.Allocate ((BufferSize + VIRTUAL_MEMORY_HEADER_SIZE));
|
||||
|
||||
/* Check if allocation is OK */
|
||||
if (p_TmpAllocAddr != NULL)
|
||||
{
|
||||
/* Fulfill the header */
|
||||
*p_TmpAllocAddr = (uint32_t)(((uint32_t)VirtualMemoryId << VIRTUAL_MEMORY_HEADER_ID_POS)
|
||||
& VIRTUAL_MEMORY_HEADER_ID_MASK)
|
||||
| ((BufferSize << VIRTUAL_MEMORY_HEADER_BUFFER_SIZE_POS)
|
||||
& VIRTUAL_MEMORY_HEADER_BUFFER_SIZE_MASK);
|
||||
|
||||
/* Provide the right address to user, ie without the header */
|
||||
*pp_AllocBuffer = (uint32_t *)(p_TmpAllocAddr + VIRTUAL_MEMORY_HEADER_SIZE);
|
||||
|
||||
/* Actualize our current memory occupation */
|
||||
p_AmmVirtualMemoryList[memIdx].OccupiedSize = p_AmmVirtualMemoryList[memIdx].OccupiedSize
|
||||
+ BufferSize
|
||||
+ VIRTUAL_MEMORY_HEADER_SIZE;
|
||||
|
||||
#if (AMM_USE_MEMORY_STATISTICS == 1)
|
||||
/* Check if peak occupation has to be updated */
|
||||
if (p_AmmVirtualMemoryList[memIdx].OccupiedSize > p_AmmVirtualMemoryList[memIdx].PeakOccupationSize)
|
||||
{
|
||||
p_AmmVirtualMemoryList[memIdx].PeakOccupationSize = p_AmmVirtualMemoryList[memIdx].OccupiedSize;
|
||||
}
|
||||
#endif /* AMM_USE_MEMORY_STATISTICS */
|
||||
|
||||
/* Check for overlapping the reserved memory */
|
||||
if (p_AmmVirtualMemoryList[memIdx].RequiredSize < p_AmmVirtualMemoryList[memIdx].OccupiedSize)
|
||||
{
|
||||
/* Actualize the shared memory occupation */
|
||||
AmmOccupiedSharedPoolSize = AmmOccupiedSharedPoolSize
|
||||
+ BufferSize - selfAvailable
|
||||
+ VIRTUAL_MEMORY_HEADER_SIZE;
|
||||
#if (AMM_USE_MEMORY_STATISTICS == 1)
|
||||
/* Check if peak occupation has to be updated */
|
||||
if (AmmOccupiedSharedPoolSize > AmmPeakSharedPoolSize)
|
||||
{
|
||||
AmmPeakSharedPoolSize = AmmOccupiedSharedPoolSize;
|
||||
}
|
||||
#endif /* AMM_USE_MEMORY_STATISTICS */
|
||||
}
|
||||
|
||||
error = AMM_ERROR_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Register the callback for a future retry */
|
||||
pushPending (p_CallBackFunction);
|
||||
|
||||
error = AMM_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Register the callback for a future retry */
|
||||
pushPending (p_CallBackFunction);
|
||||
|
||||
error = AMM_ERROR_BAD_ALLOCATION_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Exit critical section */
|
||||
UTIL_SEQ_EXIT_CRITICAL_SECTION ();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
AMM_Function_Error_t AMM_Free (uint32_t * const p_BufferAddr)
|
||||
{
|
||||
AMM_Function_Error_t error = AMM_ERROR_NOK;
|
||||
|
||||
uint8_t virtualId = 0x00;
|
||||
int32_t occupiedOverRequired = 0x00;
|
||||
uint32_t allocatedSize = 0x00;
|
||||
|
||||
uint32_t * p_TmpAllocAddr = NULL;
|
||||
|
||||
if (AmmInitialized == NOT_INITIALIZED)
|
||||
{
|
||||
error = AMM_ERROR_NOT_INIT;
|
||||
}
|
||||
else if (p_BufferAddr == NULL)
|
||||
{
|
||||
error = AMM_ERROR_BAD_POINTER;
|
||||
}
|
||||
else if ((MASK_ALIGNED_32BITS & (uint32_t)p_BufferAddr) != 0)
|
||||
{
|
||||
error = AMM_ERROR_NOT_ALIGNED;
|
||||
}
|
||||
/* Check if address is managed by this AMM */
|
||||
else if ((p_BufferAddr > (p_AmmPoolAddress + AmmPoolSize))
|
||||
|| (p_BufferAddr < p_AmmPoolAddress))
|
||||
{
|
||||
error = AMM_ERROR_OUT_OF_RANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enter critical section */
|
||||
UTIL_SEQ_ENTER_CRITICAL_SECTION ();
|
||||
|
||||
/* First correct the address by adding the header */
|
||||
p_TmpAllocAddr = (uint32_t *)(p_BufferAddr - VIRTUAL_MEMORY_HEADER_SIZE);
|
||||
|
||||
/* Get the virtual memory information */
|
||||
virtualId = (*p_TmpAllocAddr & VIRTUAL_MEMORY_HEADER_ID_MASK) >> VIRTUAL_MEMORY_HEADER_ID_POS;
|
||||
allocatedSize = (*p_TmpAllocAddr & VIRTUAL_MEMORY_HEADER_BUFFER_SIZE_MASK) >> VIRTUAL_MEMORY_HEADER_BUFFER_SIZE_POS;
|
||||
|
||||
/* Add header size to allocated size */
|
||||
allocatedSize = allocatedSize + VIRTUAL_MEMORY_HEADER_SIZE;
|
||||
|
||||
/* Free the allocated memory */
|
||||
AmmBmmFunctionsHandler.Free(p_TmpAllocAddr);
|
||||
|
||||
/* Update the occupation counters depending on the ID */
|
||||
if (virtualId == AMM_NO_VIRTUAL_ID)
|
||||
{
|
||||
/* Update the occupation size */
|
||||
AmmOccupiedSharedPoolSize = AmmOccupiedSharedPoolSize - allocatedSize;
|
||||
|
||||
error = AMM_ERROR_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = AMM_ERROR_UNKNOWN_ID;
|
||||
|
||||
for (uint32_t memIdx = 0x00;
|
||||
(memIdx < AmmVirtualMemoryNumber) && (error == AMM_ERROR_UNKNOWN_ID);
|
||||
memIdx++)
|
||||
{
|
||||
/* Check if it is the right ID */
|
||||
if (virtualId == p_AmmVirtualMemoryList[memIdx].Id)
|
||||
{
|
||||
occupiedOverRequired = (p_AmmVirtualMemoryList[memIdx].OccupiedSize - p_AmmVirtualMemoryList[memIdx].RequiredSize);
|
||||
|
||||
/* Check whether the occupied size has overlaped the required or not */
|
||||
if (occupiedOverRequired > 0x00)
|
||||
{
|
||||
/* Check if reserved memory is overlapped */
|
||||
if (allocatedSize > occupiedOverRequired)
|
||||
{
|
||||
/* Update the occupation size */
|
||||
AmmOccupiedSharedPoolSize = AmmOccupiedSharedPoolSize
|
||||
- (p_AmmVirtualMemoryList[memIdx].OccupiedSize
|
||||
- p_AmmVirtualMemoryList[memIdx].RequiredSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
AmmOccupiedSharedPoolSize = AmmOccupiedSharedPoolSize - allocatedSize;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the occupation size */
|
||||
p_AmmVirtualMemoryList[memIdx].OccupiedSize = p_AmmVirtualMemoryList[memIdx].OccupiedSize
|
||||
- allocatedSize;
|
||||
|
||||
error = AMM_ERROR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Pop pending callbacks and add them to the active fifo */
|
||||
passPendingToActive ();
|
||||
|
||||
/* Exit critical section */
|
||||
UTIL_SEQ_EXIT_CRITICAL_SECTION ();
|
||||
|
||||
/* Ask the user task to proceed to a background process call */
|
||||
AMM_ProcessRequest();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void AMM_BackgroundProcess (void)
|
||||
{
|
||||
AMM_VirtualMemoryCallbackFunction_t * p_tmpCallback = NULL;
|
||||
|
||||
do
|
||||
{
|
||||
/* Pop an active callback request */
|
||||
p_tmpCallback = popActive();
|
||||
|
||||
if (p_tmpCallback != NULL)
|
||||
{
|
||||
/* Invoke the callback for an alloc retry */
|
||||
p_tmpCallback->Callback();
|
||||
}
|
||||
}while (p_tmpCallback != NULL);
|
||||
}
|
||||
|
||||
/* Private Functions Definition ------------------------------------------------------*/
|
||||
|
||||
void pushPending (AMM_VirtualMemoryCallbackFunction_t * const p_CallbackElt)
|
||||
{
|
||||
if (p_CallbackElt != NULL)
|
||||
{
|
||||
/* Add the new callback */
|
||||
LST_insert_tail (&AmmPendingCallback, (tListNode *)p_CallbackElt);
|
||||
}
|
||||
}
|
||||
|
||||
void passPendingToActive (void)
|
||||
{
|
||||
AMM_VirtualMemoryCallbackFunction_t * p_TmpElt = NULL;
|
||||
|
||||
while (LST_is_empty (&AmmPendingCallback) == FALSE)
|
||||
{
|
||||
/* Remove the head element */
|
||||
LST_remove_head (&AmmPendingCallback, (tListNode**)&p_TmpElt);
|
||||
/* Add at the bottom */
|
||||
LST_insert_tail (&AmmActiveCallback, (tListNode *)p_TmpElt);
|
||||
}
|
||||
}
|
||||
|
||||
AMM_VirtualMemoryCallbackFunction_t * popActive (void)
|
||||
{
|
||||
AMM_VirtualMemoryCallbackFunction_t * p_error = NULL;
|
||||
|
||||
if (LST_is_empty (&AmmActiveCallback) == FALSE)
|
||||
{
|
||||
/* Remove last element */
|
||||
LST_remove_head (&AmmActiveCallback, (tListNode**)&p_error);
|
||||
}
|
||||
|
||||
return p_error;
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file advance_memory_manager.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for advance_memory_manager.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef ADVANCED_MEMORY_MANAGER_H
|
||||
#define ADVANCED_MEMORY_MANAGER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm_list.h"
|
||||
|
||||
/* Exported defines -----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Define for No Virtual Memory ID
|
||||
*
|
||||
* @details This ID can be used to allocate memory from the shared pool
|
||||
*/
|
||||
#define AMM_NO_VIRTUAL_ID 0x00u
|
||||
|
||||
/**
|
||||
* @brief Size of a virtual memory information element in 32bits
|
||||
*
|
||||
* @details At initialization, the Advance Memory Manager allocate as many VM info element as there
|
||||
* is Virtual Memory to manage.
|
||||
* Thus user shall provide at the initialization more space for the pool.
|
||||
*
|
||||
* ie:
|
||||
* - sizeOfDesiredPool = 8092
|
||||
* - numberOfVirtualMemory = 3
|
||||
* - actualSizeOfThePoolToGive = sizeOfDesiredPool + numberOfVirtualMemory * AMM_VIRTUAL_INFO_ELEMENT_SIZE
|
||||
*/
|
||||
#define AMM_VIRTUAL_INFO_ELEMENT_SIZE (uint32_t)(sizeof (VirtualMemoryInfo_t) / sizeof (uint32_t))
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Redefine the header for chained list */
|
||||
typedef tListNode AMM_VirtualMemoryCallbackHeader_t;
|
||||
|
||||
/* Function error enumeration */
|
||||
typedef enum AMM_Function_Error
|
||||
{
|
||||
/* No error code */
|
||||
AMM_ERROR_OK,
|
||||
/* Error that occurred before any check */
|
||||
AMM_ERROR_NOK,
|
||||
/*Bad pointer error */
|
||||
AMM_ERROR_BAD_POINTER,
|
||||
/* Bad pool configuration error */
|
||||
AMM_ERROR_BAD_POOL_CONFIG,
|
||||
/* Bad virtual memory configuration error */
|
||||
AMM_ERROR_BAD_VIRTUAL_CONFIG,
|
||||
/* Bad BMM registration error */
|
||||
AMM_ERROR_BAD_BMM_REGISTRATION,
|
||||
/* Bad BMM allocation error */
|
||||
AMM_ERROR_BAD_BMM_ALLOCATION,
|
||||
/* Not aligned address error */
|
||||
AMM_ERROR_NOT_ALIGNED,
|
||||
/* Out of range error */
|
||||
AMM_ERROR_OUT_OF_RANGE,
|
||||
/* Unknown virtual memory manager ID error */
|
||||
AMM_ERROR_UNKNOWN_ID,
|
||||
/* Bad allocation size error */
|
||||
AMM_ERROR_BAD_ALLOCATION_SIZE,
|
||||
/* Allocation failed error */
|
||||
AMM_ERROR_ALLOCATION_FAILED,
|
||||
/* Already initialized AMM error */
|
||||
AMM_ERROR_ALREADY_INIT,
|
||||
/* Not initialized AMM error */
|
||||
AMM_ERROR_NOT_INIT
|
||||
} AMM_Function_Error_t;
|
||||
|
||||
/**
|
||||
* @brief Virtual Memory information struct
|
||||
*/
|
||||
typedef struct __attribute__((packed, aligned(4))) VirtualMemoryInfo
|
||||
{
|
||||
/* Identifier of the Virtual Memory */
|
||||
uint8_t Id;
|
||||
/* Size required for this Virtual Memory buffer with a multiple of 32bits */
|
||||
uint32_t RequiredSize;
|
||||
/* Current occupation of the Virtual Memory buffer with a multiple of 32bits */
|
||||
uint32_t OccupiedSize;
|
||||
#if (AMM_USE_MEMORY_STATISTICS == 1)
|
||||
/* Peak occupation of the Virtual Memory buffer with a multiple of 32bits */
|
||||
uint32_t PeakOccupationSize;
|
||||
#endif /* AMM_USE_MEMORY_STATISTICS */
|
||||
}VirtualMemoryInfo_t;
|
||||
|
||||
/**
|
||||
* @brief Virtual Memory configuration struct
|
||||
*/
|
||||
typedef struct AMM_VirtualMemoryConfig
|
||||
{
|
||||
/* ID of the Virtual Memory */
|
||||
uint8_t Id;
|
||||
/* Size of the Virtual Memory buffer with a multiple of 32bits.
|
||||
|
||||
ie: BufferSize = 4; TotalSize = BufferSize * 32bits
|
||||
= 4 * 32bits
|
||||
= 128 bits */
|
||||
uint32_t BufferSize;
|
||||
}AMM_VirtualMemoryConfig_t;
|
||||
|
||||
/**
|
||||
* @brief Basic Memory Manager functions struct
|
||||
*
|
||||
* @details Structure that handles all the required functions of the Basic Memory Manager.
|
||||
*/
|
||||
typedef struct AMM_BasicMemoryManagerFunctions
|
||||
{
|
||||
/* Basic Memory Manager Init function - Shall be in bytes - */
|
||||
void (* Init) (uint32_t * const p_PoolAddr, const uint32_t PoolSize);
|
||||
/* Basic Memory Manager Allocate function - Shall be in bytes - */
|
||||
uint32_t * (* Allocate) (const uint32_t BufferSize);
|
||||
/* Basic Memory Manager Free function */
|
||||
void (* Free) (uint32_t * const p_BufferAddr);
|
||||
}AMM_BasicMemoryManagerFunctions_t;
|
||||
|
||||
/**
|
||||
* @brief Advance Memory Manager init struct
|
||||
*
|
||||
* @details Structure that contains all the needed parameters to initialize the
|
||||
* Advance Memory Manager.
|
||||
*/
|
||||
typedef struct AMM_InitParameters
|
||||
{
|
||||
/* Address of the pool of memory to manage */
|
||||
uint32_t * p_PoolAddr;
|
||||
/* Size of the pool with a multiple of 32bits.
|
||||
|
||||
ie: PoolSize = 4; TotalSize = PoolSize * 32bits
|
||||
= 4 * 32bits
|
||||
= 128 bits */
|
||||
uint32_t PoolSize;
|
||||
/* Number of Virtual Memory to create */
|
||||
uint32_t VirtualMemoryNumber;
|
||||
/* List of the Virtual Memory configurations */
|
||||
AMM_VirtualMemoryConfig_t * p_VirtualMemoryConfigList;
|
||||
}AMM_InitParameters_t;
|
||||
|
||||
/**
|
||||
* @brief Virtual Memory Callback function struct
|
||||
*/
|
||||
typedef struct AMM_VirtualMemoryCallbackFunction
|
||||
{
|
||||
/* Next and previous callbacks in the list */
|
||||
AMM_VirtualMemoryCallbackHeader_t Header;
|
||||
/* Callback function pointer to invoke once memory has been freed */
|
||||
void (* Callback) (void);
|
||||
}AMM_VirtualMemoryCallbackFunction_t;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
|
||||
#if (AMM_USE_MEMORY_STATISTICS == 1)
|
||||
/**
|
||||
* @brief Get the Current Occupation of the required virtual memory
|
||||
* @details @ref AMM_NO_VIRTUAL_ID can be used to get the shared pool occupation
|
||||
* @param VirtualMemoryId: ID of the Virtual Memory
|
||||
* @return Value of the current occupation in 32bits words
|
||||
*/
|
||||
uint32_t GetCurrentOccupation (const uint8_t VirtualMemoryId);
|
||||
|
||||
/**
|
||||
* @brief Get the Peak Occupation of the required virtual memory
|
||||
* @details @ref AMM_NO_VIRTUAL_ID can be used to get the shared pool peak occupation
|
||||
* @param VirtualMemoryId: ID of the Virtual Memory
|
||||
* @return Value of the peak occupation in 32bits words
|
||||
*/
|
||||
uint32_t GetPeakOccupation (const uint8_t VirtualMemoryId);
|
||||
#endif /* AMM_USE_MEMORY_STATISTICS */
|
||||
|
||||
/**
|
||||
* @brief Initialize the Advance Memory Manager Pool
|
||||
* @param p_InitParams: Struct of init parameters
|
||||
* @return Status of the initialization
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_OK
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_NOK
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_ALREADY_INIT
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_BAD_POINTER
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_BAD_POOL_CONFIG
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_BAD_VIRTUAL_CONFIG
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_BAD_BMM_REGISTRATION
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_BAD_BMM_ALLOCATION
|
||||
*/
|
||||
AMM_Function_Error_t AMM_Init (const AMM_InitParameters_t * const p_InitParams);
|
||||
|
||||
/**
|
||||
* @brief DeInitialize the Advance Memory Manager Pool
|
||||
* @details This function shall be called once every allocated memory has been freed
|
||||
* @return Status of the initialization
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_OK
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_NOK
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_NOT_INIT
|
||||
*/
|
||||
AMM_Function_Error_t AMM_DeInit (void);
|
||||
|
||||
/**
|
||||
* @brief Allocate a buffer from the Advance Memory Manager Pool
|
||||
* @param VirtualMemoryId: Virtual Memory Identifier - AMM_NO_VIRTUAL_ID Can be used -
|
||||
* @param BufferSize: Size of the pool with a multiple of 32bits.
|
||||
ie: BufferSize = 4; TotalSize = BufferSize * 32bits
|
||||
= 4 * 32bits
|
||||
= 128 bits
|
||||
* @param p_CallBackFunction: Pointer onto the Callback to call in case of failure - Can be NULL -
|
||||
* @param pp_AllocBuffer: Pointer onto the allocated buffer
|
||||
* @return Status of the allocation
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_OK
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_NOK
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_NOT_INIT
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_BAD_POINTER
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_UNKNOWN_ID
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_BAD_ALLOCATION_SIZE
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_ALLOCATION_FAILED
|
||||
*/
|
||||
AMM_Function_Error_t AMM_Alloc (const uint8_t VirtualMemoryId,
|
||||
const uint32_t BufferSize,
|
||||
uint32_t ** pp_AllocBuffer,
|
||||
AMM_VirtualMemoryCallbackFunction_t * const p_CallBackFunction);
|
||||
|
||||
/**
|
||||
* @brief Free the allocated buffer from the Advance Memory Manager Pool
|
||||
* @param p_BufferAddr: Address of the buffer to free
|
||||
* @return Status of the free
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_OK
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_NOK
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_NOT_INIT
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_BAD_POINTER
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_NOT_ALIGNED
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_OUT_OF_RANGE
|
||||
* @retval AMM_Function_Error_t::AMM_ERROR_UNKNOWN_ID
|
||||
*/
|
||||
AMM_Function_Error_t AMM_Free (uint32_t * const p_BufferAddr);
|
||||
|
||||
/**
|
||||
* @brief Background routine
|
||||
* @details Background routine that aims to call registered callbacks for an allocation retry
|
||||
* @return None
|
||||
*/
|
||||
void AMM_BackgroundProcess (void);
|
||||
|
||||
/* Exported functions to be implemented by the user if required ------------- */
|
||||
|
||||
/**
|
||||
* @brief Register the Basic Memory Manager functions to use
|
||||
* @param p_BasicMemoryManagerFunctions: Address of the basic memory manager functions
|
||||
* @return None
|
||||
*/
|
||||
void AMM_RegisterBasicMemoryManager (AMM_BasicMemoryManagerFunctions_t * const p_BasicMemoryManagerFunctions);
|
||||
|
||||
/**
|
||||
* @brief Request to application for a Background process run
|
||||
* @return None
|
||||
*/
|
||||
void AMM_ProcessRequest (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ADVANCED_MEMORY_MANAGER_H */
|
||||
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file memory_manager.c
|
||||
* @author MCD Application Team
|
||||
* @brief Memory Manager
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "utilities_common.h"
|
||||
|
||||
#include "memory_manager.h"
|
||||
#include "stm_list.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/**
|
||||
* The average timing is @32Mhz :
|
||||
* Legacy MM
|
||||
* + Alloc = 3.5us
|
||||
* + Free = 2.5us
|
||||
* New MM
|
||||
* + Alloc = 6.5us
|
||||
* + Free = 4.5us
|
||||
*/
|
||||
#define USE_NEW_MM 1
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
#if(USE_NEW_MM == 0)
|
||||
#pragma default_variable_attributes = @"MM_CONTEXT"
|
||||
|
||||
static uint8_t QueueSize;
|
||||
static tListNode BufferPool;
|
||||
static MM_pCb_t BufferFreeCb;
|
||||
static uint8_t *p_StartPoolAdd;
|
||||
static uint8_t *p_EndPoolAdd;
|
||||
|
||||
#pragma default_variable_attributes =
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Initialize the Pools
|
||||
* @param p_pool: The pool of memory to manage
|
||||
* @param pool_size: The size of the pool
|
||||
* @param elt_size: The size of one element in the pool
|
||||
* @retval None
|
||||
*/
|
||||
void MM_Init(uint8_t *p_pool, uint32_t pool_size, uint32_t elt_size)
|
||||
{
|
||||
uint32_t elt_size_corrected;
|
||||
|
||||
QueueSize = 0;
|
||||
elt_size_corrected = 4*DIVC( elt_size, 4 );
|
||||
|
||||
/**
|
||||
* Save the first and last address of the pool of memory
|
||||
*/
|
||||
p_StartPoolAdd = p_pool;
|
||||
p_EndPoolAdd = p_pool + pool_size - 1;
|
||||
|
||||
/**
|
||||
* Initialize list
|
||||
*/
|
||||
LST_init_head (&BufferPool);
|
||||
|
||||
/**
|
||||
* Initialize the queue
|
||||
*/
|
||||
while(pool_size >= elt_size_corrected)
|
||||
{
|
||||
LST_insert_tail(&BufferPool, (tListNode *)p_pool);
|
||||
p_pool += elt_size_corrected;
|
||||
QueueSize++;
|
||||
pool_size -= elt_size_corrected;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provide a buffer
|
||||
* @note The buffer allocated to the user shall be at least sizeof(tListNode) bytes
|
||||
* to store the memory manager chaining information
|
||||
*
|
||||
* @param size: The size of the buffer requested
|
||||
* @param cb: The callback to be called when a buffer is made available later on
|
||||
* if there is no buffer currently available when this API is called
|
||||
* @retval The buffer address when available or NULL when there is no buffer
|
||||
*/
|
||||
MM_pBufAdd_t MM_GetBuffer( uint32_t size, MM_pCb_t cb )
|
||||
{
|
||||
MM_pBufAdd_t buffer_address;
|
||||
uint32_t primask_bit;
|
||||
uint8_t allocation_exit = FALSE;
|
||||
|
||||
while( allocation_exit == FALSE )
|
||||
{
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
if ( QueueSize )
|
||||
{
|
||||
QueueSize--;
|
||||
LST_remove_head( &BufferPool, ( tListNode ** )&buffer_address );
|
||||
if((buffer_address >= p_StartPoolAdd) && (buffer_address <= (p_EndPoolAdd - size + 1)))
|
||||
{
|
||||
/* The buffer is in a valid range */
|
||||
BufferFreeCb = 0;
|
||||
allocation_exit = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* The buffer is not in a valid range.
|
||||
* Keep the reference out of the memory pool and try again
|
||||
*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferFreeCb = cb;
|
||||
buffer_address = 0;
|
||||
allocation_exit = TRUE;
|
||||
}
|
||||
__set_PRIMASK( primask_bit ); /**< Restore PRIMASK bit*/
|
||||
}
|
||||
|
||||
return buffer_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release a buffer
|
||||
* @param p_buffer: The data buffer address
|
||||
* @retval None
|
||||
*/
|
||||
void MM_ReleaseBuffer( MM_pBufAdd_t p_buffer )
|
||||
{
|
||||
uint32_t primask_bit;
|
||||
|
||||
if((p_buffer >= p_StartPoolAdd) && (p_buffer <= p_EndPoolAdd))
|
||||
{
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
LST_insert_tail( &BufferPool, ( tListNode * )p_buffer );
|
||||
QueueSize++;
|
||||
__set_PRIMASK( primask_bit ); /**< Restore PRIMASK bit*/
|
||||
if( BufferFreeCb )
|
||||
{
|
||||
/**
|
||||
* The application is waiting for a free buffer
|
||||
*/
|
||||
BufferFreeCb();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#include "stm32_mm.h"
|
||||
|
||||
static uint8_t *p_StartPoolAdd __attribute__((section("MM_CONTEXT")));
|
||||
static uint8_t *p_EndPoolAdd __attribute__((section("MM_CONTEXT")));
|
||||
static MM_pCb_t BufferFreeCb __attribute__((section("MM_CONTEXT")));
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
void MM_Init(uint8_t *p_pool, uint32_t pool_size, uint32_t elt_size)
|
||||
{
|
||||
/**
|
||||
* Save the first and last address of the pool of memory
|
||||
*/
|
||||
p_StartPoolAdd = p_pool;
|
||||
p_EndPoolAdd = p_pool + pool_size - 1;
|
||||
|
||||
UTIL_MM_Init(p_pool, pool_size);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provide a buffer
|
||||
* @note The buffer allocated to the user shall be at least sizeof(tListNode) bytes
|
||||
* to store the memory manager chaining information
|
||||
* During execution, this API shall not be interrupted with a call to either
|
||||
* MM_GetBuffer() or MM_ReleaseBuffer()
|
||||
* MM_GetBuffer() is called only from background so this will never happen
|
||||
* MM_ReleaseBuffer() is called from IPCC interrupt. Masking IPCC interrupt is
|
||||
* enough to comply to the requirement
|
||||
* Note that the primask bit cannot be used as the length of the critical section is too long compare to
|
||||
* the maximum latency of the BLE Irq. Therefore, the BLE Irq shall not be masked.
|
||||
*
|
||||
* @param size: The size of the buffer requested
|
||||
* @param cb: The callback to be called when a buffer is made available later on
|
||||
* if there is no buffer currently available when this API is called
|
||||
* @retval The buffer address when available or NULL when there is no buffer
|
||||
*/
|
||||
MM_pBufAdd_t MM_GetBuffer( uint32_t size, MM_pCb_t cb )
|
||||
{
|
||||
MM_pBufAdd_t buffer_address;
|
||||
/* uint32_t nvic_ipcc_status; */
|
||||
uint8_t allocation_exit = FALSE;
|
||||
|
||||
while( allocation_exit == FALSE )
|
||||
{
|
||||
|
||||
/* nvic_ipcc_status = NVIC_GetEnableIRQ(IPCC_C2_RX_C2_TX_HSEM_IRQn); */ /**< backup IPCC just in case it has been disabled by the user */
|
||||
/* NVIC_DisableIRQ(IPCC_C2_RX_C2_TX_HSEM_IRQn); */
|
||||
__disable_irq();
|
||||
buffer_address = (MM_pBufAdd_t)UTIL_MM_GetBuffer( size );
|
||||
__enable_irq();
|
||||
/*
|
||||
if(nvic_ipcc_status != 0)
|
||||
{
|
||||
NVIC_EnableIRQ(IPCC_C2_RX_C2_TX_HSEM_IRQn);
|
||||
}
|
||||
*/
|
||||
|
||||
if(buffer_address != 0)
|
||||
{
|
||||
if((buffer_address >= p_StartPoolAdd) && (buffer_address <= (p_EndPoolAdd - size + 1)))
|
||||
{
|
||||
/* The buffer is in a valid range */
|
||||
BufferFreeCb = 0;
|
||||
allocation_exit = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* The buffer is not in a valid range.
|
||||
* Keep the reference out of the memory pool and try again
|
||||
*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferFreeCb = cb;
|
||||
allocation_exit = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return buffer_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release a buffer
|
||||
* During execution, this API shall not be interrupted with a call to either
|
||||
* MM_GetBuffer() or MM_ReleaseBuffer()
|
||||
* MM_GetBuffer() is called only from background so this will never happen
|
||||
* MM_ReleaseBuffer() is called from IPCC interrupt so it cannot be nested.
|
||||
* There is no need of a critical section
|
||||
* Note that anyway, the primask bit cannot be used as the length of the critical section
|
||||
* is too long compare to the maximum latency of the BLE Irq. Therefore, the BLE Irq shall not be masked.
|
||||
*
|
||||
* @param p_buffer: The data buffer address
|
||||
* @retval None
|
||||
*/
|
||||
void MM_ReleaseBuffer( MM_pBufAdd_t p_buffer )
|
||||
{
|
||||
if((p_buffer >= p_StartPoolAdd) && (p_buffer <= p_EndPoolAdd))
|
||||
{
|
||||
UTIL_MM_ReleaseBuffer( p_buffer );
|
||||
|
||||
if( BufferFreeCb )
|
||||
{
|
||||
/**
|
||||
* The application is waiting for a free buffer
|
||||
*/
|
||||
BufferFreeCb();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file memory_manager.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for memory_manager.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef MEMORY_MANAGER_H
|
||||
#define MEMORY_MANAGER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported defines -----------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
typedef void (*MM_pCb_t)( void );
|
||||
typedef uint8_t (*MM_pBufAdd_t);
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void MM_Init(uint8_t *p_pool, uint32_t pool_size, uint32_t elt_size);
|
||||
MM_pBufAdd_t MM_GetBuffer(uint32_t size, MM_pCb_t cb );
|
||||
void MM_ReleaseBuffer( MM_pBufAdd_t p_buffer );
|
||||
|
||||
/* Exported functions to be implemented by the user if required ------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MEMORY_MANAGER_H */
|
||||
@@ -0,0 +1,576 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.4.1
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32_mm.c
|
||||
* @author MCD Application Team
|
||||
* @brief Memory Manager Utility
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* A sample implementation of pvPortMalloc() and vPortFree() that combines
|
||||
* (coalescences) adjacent memory blocks as they are freed, and in so doing
|
||||
* limits memory fragmentation.
|
||||
*
|
||||
* See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the
|
||||
* memory management pages of https://www.FreeRTOS.org for more information.
|
||||
*/
|
||||
#if (KEEP_ORIGINAL_CODE_FROM_FREERTOS != 0)
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||
* all the API functions to use the MPU wrappers. That should only be done when
|
||||
* task.h is included from an application file. */
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
|
||||
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include "utilities_common.h"
|
||||
#include "stm32_mm.h"
|
||||
|
||||
#undef PRIVILEGED_DATA
|
||||
#define PRIVILEGED_DATA
|
||||
|
||||
#undef PRIVILEGED_FUNCTION
|
||||
#define PRIVILEGED_FUNCTION
|
||||
|
||||
#undef portBYTE_ALIGNMENT
|
||||
#define portBYTE_ALIGNMENT (8)
|
||||
|
||||
#undef portBYTE_ALIGNMENT_MASK
|
||||
#if portBYTE_ALIGNMENT == 8
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||
#endif
|
||||
#if portBYTE_ALIGNMENT == 4
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
|
||||
#endif
|
||||
|
||||
/* No test marker by default. */
|
||||
#undef mtCOVERAGE_TEST_MARKER
|
||||
#define mtCOVERAGE_TEST_MARKER()
|
||||
|
||||
#undef configASSERT
|
||||
#define configASSERT( x )
|
||||
|
||||
/* No tracing by default. */
|
||||
#undef traceMALLOC
|
||||
#define traceMALLOC( pvReturn, xWantedSize )
|
||||
|
||||
#undef traceFREE
|
||||
#define traceFREE( pvAddress, uiSize )
|
||||
|
||||
#undef vTaskSuspendAll
|
||||
#define vTaskSuspendAll()
|
||||
|
||||
#undef xTaskResumeAll
|
||||
#define xTaskResumeAll() (0)
|
||||
|
||||
#endif
|
||||
|
||||
/* Block sizes must not get too small. */
|
||||
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
|
||||
|
||||
/* Assumes 8bit bytes! */
|
||||
#define heapBITS_PER_BYTE ( ( size_t ) 8 )
|
||||
|
||||
#if (KEEP_ORIGINAL_CODE_FROM_FREERTOS != 0)
|
||||
/* Allocate the memory for the heap. */
|
||||
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
|
||||
|
||||
/* The application writer has already defined the array used for the RTOS
|
||||
* heap - probably so it can be placed in a special segment or address. */
|
||||
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
|
||||
#else
|
||||
PRIVILEGED_DATA static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
|
||||
#endif /* configAPPLICATION_ALLOCATED_HEAP */
|
||||
#endif
|
||||
|
||||
/* Define the linked list structure. This is used to link free blocks in order
|
||||
* of their memory address. */
|
||||
typedef struct A_BLOCK_LINK
|
||||
{
|
||||
struct A_BLOCK_LINK * pxNextFreeBlock; /*<< The next free block in the list. */
|
||||
size_t xBlockSize; /*<< The size of the free block. */
|
||||
} BlockLink_t;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Inserts a block of memory that is being freed into the correct position in
|
||||
* the list of free memory blocks. The block being freed will be merged with
|
||||
* the block in front it and/or the block behind it if the memory blocks are
|
||||
* adjacent to each other.
|
||||
*/
|
||||
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Called automatically to setup the required heap structures the first time
|
||||
* pvPortMalloc() is called.
|
||||
*/
|
||||
#if (KEEP_ORIGINAL_CODE_FROM_FREERTOS != 0)
|
||||
static void prvHeapInit( void ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The size of the structure placed at the beginning of each allocated memory
|
||||
* block must by correctly byte aligned. */
|
||||
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
|
||||
|
||||
/* Create a couple of list links to mark the start and end of the list. */
|
||||
PRIVILEGED_DATA static BlockLink_t xStart, * pxEnd = NULL;
|
||||
|
||||
/* Keeps track of the number of calls to allocate and free memory as well as the
|
||||
* number of free bytes remaining, but says nothing about fragmentation. */
|
||||
PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U;
|
||||
PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U;
|
||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0;
|
||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0;
|
||||
|
||||
/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize
|
||||
* member of an BlockLink_t structure is set then the block belongs to the
|
||||
* application. When the bit is free the block is still part of the free heap
|
||||
* space. */
|
||||
PRIVILEGED_DATA static size_t xBlockAllocatedBit = 0;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
#if (KEEP_ORIGINAL_CODE_FROM_FREERTOS == 0)
|
||||
void * UTIL_MM_GetBuffer( size_t xWantedSize )
|
||||
#else
|
||||
void * pvPortMalloc( size_t xWantedSize )
|
||||
#endif
|
||||
{
|
||||
BlockLink_t * pxBlock, * pxPreviousBlock, * pxNewBlockLink;
|
||||
void * pvReturn = NULL;
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
/* If this is the first call to malloc then the heap will require
|
||||
* initialisation to setup the list of free blocks. */
|
||||
#if (KEEP_ORIGINAL_CODE_FROM_FREERTOS != 0)
|
||||
if( pxEnd == NULL )
|
||||
{
|
||||
prvHeapInit();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* Check the requested block size is not so large that the top bit is
|
||||
* set. The top bit of the block size member of the BlockLink_t structure
|
||||
* is used to determine who owns the block - the application or the
|
||||
* kernel, so it must be free. */
|
||||
if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
|
||||
{
|
||||
/* The wanted size is increased so it can contain a BlockLink_t
|
||||
* structure in addition to the requested amount of bytes. */
|
||||
if( xWantedSize > 0 )
|
||||
{
|
||||
xWantedSize += xHeapStructSize;
|
||||
|
||||
/* Ensure that blocks are always aligned to the required number
|
||||
* of bytes. */
|
||||
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
|
||||
{
|
||||
/* Byte alignment required. */
|
||||
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
|
||||
configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
|
||||
{
|
||||
/* Traverse the list from the start (lowest address) block until
|
||||
* one of adequate size is found. */
|
||||
pxPreviousBlock = &xStart;
|
||||
pxBlock = xStart.pxNextFreeBlock;
|
||||
|
||||
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
||||
{
|
||||
pxPreviousBlock = pxBlock;
|
||||
pxBlock = pxBlock->pxNextFreeBlock;
|
||||
}
|
||||
|
||||
/* If the end marker was reached then a block of adequate size
|
||||
* was not found. */
|
||||
if( pxBlock != pxEnd )
|
||||
{
|
||||
/* Return the memory space pointed to - jumping over the
|
||||
* BlockLink_t structure at its start. */
|
||||
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
|
||||
|
||||
/* This block is being returned for use so must be taken out
|
||||
* of the list of free blocks. */
|
||||
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
|
||||
|
||||
/* If the block is larger than required it can be split into
|
||||
* two. */
|
||||
if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
|
||||
{
|
||||
/* This block is to be split into two. Create a new
|
||||
* block following the number of bytes requested. The void
|
||||
* cast is used to prevent byte alignment warnings from the
|
||||
* compiler. */
|
||||
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
|
||||
configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
|
||||
/* Calculate the sizes of two blocks split from the
|
||||
* single block. */
|
||||
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
|
||||
pxBlock->xBlockSize = xWantedSize;
|
||||
|
||||
/* Insert the new block into the list of free blocks. */
|
||||
prvInsertBlockIntoFreeList( pxNewBlockLink );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
xFreeBytesRemaining -= pxBlock->xBlockSize;
|
||||
|
||||
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
|
||||
{
|
||||
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* The block is being returned - it is allocated and owned
|
||||
* by the application and has no "next" block. */
|
||||
pxBlock->xBlockSize |= xBlockAllocatedBit;
|
||||
pxBlock->pxNextFreeBlock = NULL;
|
||||
xNumberOfSuccessfulAllocations++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
traceMALLOC( pvReturn, xWantedSize );
|
||||
}
|
||||
( void ) xTaskResumeAll();
|
||||
|
||||
#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
extern void vApplicationMallocFailedHook( void );
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||
|
||||
configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
return pvReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
#if (KEEP_ORIGINAL_CODE_FROM_FREERTOS == 0)
|
||||
void UTIL_MM_ReleaseBuffer( void * pv )
|
||||
#else
|
||||
void vPortFree( void * pv )
|
||||
#endif
|
||||
{
|
||||
uint8_t * puc = ( uint8_t * ) pv;
|
||||
BlockLink_t * pxLink;
|
||||
|
||||
if( pv != NULL )
|
||||
{
|
||||
/* The memory being freed will have an BlockLink_t structure immediately
|
||||
* before it. */
|
||||
puc -= xHeapStructSize;
|
||||
|
||||
/* This casting is to keep the compiler from issuing warnings. */
|
||||
pxLink = ( void * ) puc;
|
||||
|
||||
/* Check the block is actually allocated. */
|
||||
configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
|
||||
configASSERT( pxLink->pxNextFreeBlock == NULL );
|
||||
|
||||
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
|
||||
{
|
||||
if( pxLink->pxNextFreeBlock == NULL )
|
||||
{
|
||||
/* The block is being returned to the heap - it is no longer
|
||||
* allocated. */
|
||||
pxLink->xBlockSize &= ~xBlockAllocatedBit;
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
/* Add this block to the list of free blocks. */
|
||||
xFreeBytesRemaining += pxLink->xBlockSize;
|
||||
traceFREE( pv, pxLink->xBlockSize );
|
||||
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
|
||||
xNumberOfSuccessfulFrees++;
|
||||
}
|
||||
( void ) xTaskResumeAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
#if (KEEP_ORIGINAL_CODE_FROM_FREERTOS != 0)
|
||||
size_t xPortGetFreeHeapSize( void )
|
||||
{
|
||||
return xFreeBytesRemaining;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
size_t xPortGetMinimumEverFreeHeapSize( void )
|
||||
{
|
||||
return xMinimumEverFreeBytesRemaining;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortInitialiseBlocks( void )
|
||||
{
|
||||
/* This just exists to keep the linker quiet. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */
|
||||
#else
|
||||
void UTIL_MM_Init(uint8_t *p_pool, uint32_t pool_size)
|
||||
#endif
|
||||
{
|
||||
BlockLink_t * pxFirstFreeBlock;
|
||||
uint8_t * pucAlignedHeap;
|
||||
size_t uxAddress;
|
||||
#if (KEEP_ORIGINAL_CODE_FROM_FREERTOS != 0)
|
||||
size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;
|
||||
#else
|
||||
size_t xTotalHeapSize;
|
||||
xTotalHeapSize = pool_size;
|
||||
#endif
|
||||
|
||||
/* Ensure the heap starts on a correctly aligned boundary. */
|
||||
uxAddress = ( size_t ) p_pool;
|
||||
|
||||
if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
|
||||
{
|
||||
uxAddress += ( portBYTE_ALIGNMENT - 1 );
|
||||
uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
|
||||
xTotalHeapSize -= uxAddress - ( size_t ) p_pool;
|
||||
}
|
||||
|
||||
pucAlignedHeap = ( uint8_t * ) uxAddress;
|
||||
|
||||
/* xStart is used to hold a pointer to the first item in the list of free
|
||||
* blocks. The void cast is used to prevent compiler warnings. */
|
||||
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
|
||||
xStart.xBlockSize = ( size_t ) 0;
|
||||
|
||||
/* pxEnd is used to mark the end of the list of free blocks and is inserted
|
||||
* at the end of the heap space. */
|
||||
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
|
||||
uxAddress -= xHeapStructSize;
|
||||
uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
|
||||
pxEnd = ( void * ) uxAddress;
|
||||
pxEnd->xBlockSize = 0;
|
||||
pxEnd->pxNextFreeBlock = NULL;
|
||||
|
||||
/* To start with there is a single free block that is sized to take up the
|
||||
* entire heap space, minus the space taken by pxEnd. */
|
||||
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
|
||||
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
|
||||
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
|
||||
|
||||
/* Only one block exists - and it covers the entire usable heap space. */
|
||||
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||
|
||||
/* Work out the position of the top bit in a size_t variable. */
|
||||
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
BlockLink_t * pxIterator;
|
||||
uint8_t * puc;
|
||||
|
||||
/* Iterate through the list until a block is found that has a higher address
|
||||
* than the block being inserted. */
|
||||
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
|
||||
{
|
||||
/* Nothing to do here, just iterate to the right position. */
|
||||
}
|
||||
|
||||
/* Do the block being inserted, and the block it is being inserted after
|
||||
* make a contiguous block of memory? */
|
||||
puc = ( uint8_t * ) pxIterator;
|
||||
|
||||
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
|
||||
{
|
||||
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
|
||||
pxBlockToInsert = pxIterator;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* Do the block being inserted, and the block it is being inserted before
|
||||
* make a contiguous block of memory? */
|
||||
puc = ( uint8_t * ) pxBlockToInsert;
|
||||
|
||||
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
|
||||
{
|
||||
if( pxIterator->pxNextFreeBlock != pxEnd )
|
||||
{
|
||||
/* Form one big block from the two blocks. */
|
||||
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
|
||||
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
|
||||
}
|
||||
else
|
||||
{
|
||||
pxBlockToInsert->pxNextFreeBlock = pxEnd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
|
||||
}
|
||||
|
||||
/* If the block being inserted plugged a gab, so was merged with the block
|
||||
* before and the block after, then it's pxNextFreeBlock pointer will have
|
||||
* already been set, and should not be set here as that would make it point
|
||||
* to itself. */
|
||||
if( pxIterator != pxBlockToInsert )
|
||||
{
|
||||
pxIterator->pxNextFreeBlock = pxBlockToInsert;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
#if (KEEP_ORIGINAL_CODE_FROM_FREERTOS != 0)
|
||||
void vPortGetHeapStats( HeapStats_t * pxHeapStats )
|
||||
{
|
||||
BlockLink_t * pxBlock;
|
||||
size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
pxBlock = xStart.pxNextFreeBlock;
|
||||
|
||||
/* pxBlock will be NULL if the heap has not been initialised. The heap
|
||||
* is initialised automatically when the first allocation is made. */
|
||||
if( pxBlock != NULL )
|
||||
{
|
||||
do
|
||||
{
|
||||
/* Increment the number of blocks and record the largest block seen
|
||||
* so far. */
|
||||
xBlocks++;
|
||||
|
||||
if( pxBlock->xBlockSize > xMaxSize )
|
||||
{
|
||||
xMaxSize = pxBlock->xBlockSize;
|
||||
}
|
||||
|
||||
if( pxBlock->xBlockSize < xMinSize )
|
||||
{
|
||||
xMinSize = pxBlock->xBlockSize;
|
||||
}
|
||||
|
||||
/* Move to the next block in the chain until the last block is
|
||||
* reached. */
|
||||
pxBlock = pxBlock->pxNextFreeBlock;
|
||||
} while( pxBlock != pxEnd );
|
||||
}
|
||||
}
|
||||
( void ) xTaskResumeAll();
|
||||
|
||||
pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize;
|
||||
pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize;
|
||||
pxHeapStats->xNumberOfFreeBlocks = xBlocks;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining;
|
||||
pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations;
|
||||
pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees;
|
||||
pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32_mm.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for stm32_mm.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32_MM_H
|
||||
#define STM32_MM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported defines -----------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
/**
|
||||
* @brief Initialize the Pool
|
||||
* @param p_pool: The pool of memory to manage
|
||||
* @param pool_size: The size of the pool
|
||||
* @retval None
|
||||
*/
|
||||
void UTIL_MM_Init(uint8_t *p_pool, uint32_t pool_size);
|
||||
|
||||
/**
|
||||
* @brief Provide a buffer
|
||||
* @param xWantedSize: The size of the buffer requested
|
||||
* @retval The buffer address when available or NULL when there is no buffer
|
||||
*/
|
||||
|
||||
void * UTIL_MM_GetBuffer(size_t xWantedSize);
|
||||
|
||||
/**
|
||||
* @brief Release a buffer
|
||||
* @param pv: The data buffer address
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void UTIL_MM_ReleaseBuffer( void * pv );
|
||||
|
||||
/* Exported functions to be implemented by the user if required ------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32_MM_H */
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file rf_antenna_switch.c
|
||||
* @author MCD Application Team
|
||||
* @brief RF related module to handle dedictated GPIOs for antenna switch
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "rf_antenna_switch.h"
|
||||
#include "ll_intf.h"
|
||||
#include "app_conf.h"
|
||||
|
||||
#if (SUPPORT_AOA_AOD == 1) || (SUPPORT_ANT_DIV == 1)
|
||||
|
||||
static void RF_CONTROL_AntennaSwitch_Enable(void);
|
||||
static void RF_CONTROL_AntennaSwitch_Disable(void);
|
||||
|
||||
static void RF_CONTROL_AntennaSwitch_Enable(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
uint32_t table_size = sizeof(rt_antenna_switch_gpio_table)/sizeof(rt_antenna_switch_gpio_table[0]);
|
||||
|
||||
for(unsigned int cpt = 0; cpt<table_size; cpt++)
|
||||
{
|
||||
GPIO_InitStruct.Pin = rt_antenna_switch_gpio_table[cpt].GPIO_pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Alternate = rt_antenna_switch_gpio_table[cpt].GPIO_alternate;
|
||||
HAL_GPIO_Init(rt_antenna_switch_gpio_table[cpt].GPIO_port, &GPIO_InitStruct);
|
||||
}
|
||||
}
|
||||
|
||||
static void RF_CONTROL_AntennaSwitch_Disable(void)
|
||||
{
|
||||
uint32_t table_size = sizeof(rt_antenna_switch_gpio_table)/sizeof(rt_antenna_switch_gpio_table[0]);
|
||||
|
||||
for(unsigned int cpt = 0; cpt<table_size; cpt++)
|
||||
{
|
||||
HAL_GPIO_DeInit(rt_antenna_switch_gpio_table[cpt].GPIO_port, rt_antenna_switch_gpio_table[cpt].GPIO_pin);
|
||||
}
|
||||
}
|
||||
|
||||
void RF_CONTROL_AntennaSwitch(rf_antenna_switch_state_t state)
|
||||
{
|
||||
#if (SUPPORT_AOA_AOD == 1)
|
||||
ble_stat_t status = GENERAL_FAILURE;
|
||||
#endif
|
||||
|
||||
if(state == RF_ANTSW_ENABLE)
|
||||
{
|
||||
#if (SUPPORT_AOA_AOD == 1)
|
||||
status = ll_intf_set_num_of_antennas(CFG_RADIO_NUM_OF_ANTENNAS);
|
||||
if(status != SUCCESS)
|
||||
{
|
||||
/* Specified number of antennas is not supported */
|
||||
assert_param(0);
|
||||
return;
|
||||
}
|
||||
#endif /* SUPPORT_AOA_AOD */
|
||||
RF_CONTROL_AntennaSwitch_Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
RF_CONTROL_AntennaSwitch_Disable();
|
||||
}
|
||||
}
|
||||
|
||||
#else /* SUPPORT_AOA_AOD || SUPPORT_ANT_DIV */
|
||||
void RF_CONTROL_AntennaSwitch(rf_antenna_switch_state_t state)
|
||||
{
|
||||
/* AoA-AoD or antenna diversity feature is not supported with this Link Layer configuration */
|
||||
assert_param(0);
|
||||
}
|
||||
#endif /* SUPPORT_AOA_AOD || SUPPORT_ANT_DIV */
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file rf_antenna_switch.h
|
||||
* @author MCD Application Team
|
||||
* @brief RF related module to handle dedictated GPIOs for antenna switch
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef RF_ANTENNA_SWITCH_H
|
||||
#define RF_ANTENNA_SWITCH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stm32wbaxx.h"
|
||||
|
||||
#define RF_ANTSW0 {GPIOA, GPIO_PIN_12, GPIO_AF11_RF_ANTSW0}
|
||||
#define RF_ANTSW1 {GPIOA, GPIO_PIN_11, GPIO_AF11_RF_ANTSW1}
|
||||
#define RF_ANTSW2 {GPIOB, GPIO_PIN_2, GPIO_AF11_RF_ANTSW2}
|
||||
|
||||
typedef struct {
|
||||
GPIO_TypeDef* GPIO_port;
|
||||
uint16_t GPIO_pin;
|
||||
uint8_t GPIO_alternate;
|
||||
} st_gpio_antsw_t;
|
||||
|
||||
typedef enum {
|
||||
RF_ANTSW_DISABLE = 0,
|
||||
RF_ANTSW_ENABLE
|
||||
} rf_antenna_switch_state_t;
|
||||
|
||||
static const st_gpio_antsw_t rt_antenna_switch_gpio_table[] =
|
||||
{
|
||||
RF_ANTSW0,
|
||||
RF_ANTSW1,
|
||||
RF_ANTSW2
|
||||
};
|
||||
|
||||
void RF_CONTROL_AntennaSwitch(rf_antenna_switch_state_t state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RF_ANTENNA_SWITCH_H */
|
||||
@@ -0,0 +1,89 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file rf_external_pa.c
|
||||
* @author MCD Application Team
|
||||
* @brief RF related module to handle dedictated GPIOs for external PA
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#include "rf_external_pa.h"
|
||||
#include "power_table.h"
|
||||
#include "ll_intf.h"
|
||||
#include "app_conf.h"
|
||||
|
||||
static void RF_CONTROL_ExternalPA_Enable(void);
|
||||
static void RF_CONTROL_ExternalPA_Disable(void);
|
||||
static uint8_t RF_CONTROL_ExternalPA_Enable_cb(uint8_t epa_enable);
|
||||
|
||||
static void RF_CONTROL_ExternalPA_Enable(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
uint32_t table_size = sizeof(rf_external_pa_gpio_table)/sizeof(rf_external_pa_gpio_table[0]);
|
||||
|
||||
for(unsigned int cpt = 0; cpt<table_size; cpt++)
|
||||
{
|
||||
GPIO_InitStruct.Pin = rf_external_pa_gpio_table[cpt].GPIO_pin;
|
||||
GPIO_InitStruct.Mode = rf_external_pa_gpio_table[cpt].GPIO_mode;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Alternate = rf_external_pa_gpio_table[cpt].GPIO_alternate;
|
||||
HAL_GPIO_Init(rf_external_pa_gpio_table[cpt].GPIO_port, &GPIO_InitStruct);
|
||||
}
|
||||
}
|
||||
|
||||
static void RF_CONTROL_ExternalPA_Disable(void)
|
||||
{
|
||||
uint32_t table_size = sizeof(rf_external_pa_gpio_table)/sizeof(rf_external_pa_gpio_table[0]);
|
||||
|
||||
for(unsigned int cpt = 0; cpt<table_size; cpt++)
|
||||
{
|
||||
HAL_GPIO_DeInit(rf_external_pa_gpio_table[cpt].GPIO_port, rf_external_pa_gpio_table[cpt].GPIO_pin);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t RF_CONTROL_ExternalPA_Enable_cb(uint8_t epa_enable)
|
||||
{
|
||||
if(epa_enable == 1)
|
||||
{
|
||||
HAL_GPIO_WritePin(rf_external_pa_gpio_table[RF_EPA_SIGNAL_CSD].GPIO_port, rf_external_pa_gpio_table[RF_EPA_SIGNAL_CSD].GPIO_pin, GPIO_PIN_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_GPIO_WritePin(rf_external_pa_gpio_table[RF_EPA_SIGNAL_CSD].GPIO_port, rf_external_pa_gpio_table[RF_EPA_SIGNAL_CSD].GPIO_pin, GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RF_CONTROL_ExternalPA(rf_external_pa_state_t state)
|
||||
{
|
||||
ble_stat_t status = GENERAL_FAILURE;
|
||||
|
||||
if(state == RF_EPA_ENABLE)
|
||||
{
|
||||
status = ll_tx_pwr_if_epa_init(1, RF_CONTROL_ExternalPA_Enable_cb);
|
||||
if(status != SUCCESS)
|
||||
{
|
||||
/* EPA callback is not defined */
|
||||
assert_param(0);
|
||||
return;
|
||||
}
|
||||
RF_CONTROL_ExternalPA_Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
RF_CONTROL_ExternalPA_Disable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file rf_external_pa.h
|
||||
* @author MCD Application Team
|
||||
* @brief RF related module to handle dedictated GPIOs for external PA
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
#ifndef RF_EXTERNAL_PA_H
|
||||
#define RF_EXTERNAL_PA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stm32wbaxx.h"
|
||||
|
||||
#define RF_EPA_CSD {GPIOA, GPIO_PIN_9, GPIO_MODE_OUTPUT_PP, GPIO_AF15_EVENTOUT}
|
||||
#define RF_EPA_CTX {GPIOB, GPIO_PIN_15, GPIO_MODE_AF_PP, GPIO_AF11_RF_IO1}
|
||||
|
||||
typedef struct {
|
||||
GPIO_TypeDef* GPIO_port;
|
||||
uint16_t GPIO_pin;
|
||||
uint32_t GPIO_mode;
|
||||
uint8_t GPIO_alternate;
|
||||
} st_gpio_epa_t;
|
||||
|
||||
typedef enum {
|
||||
RF_EPA_DISABLE = 0,
|
||||
RF_EPA_ENABLE
|
||||
} rf_external_pa_state_t;
|
||||
|
||||
typedef enum {
|
||||
RF_EPA_SIGNAL_CSD = 0,
|
||||
RF_EPA_SIGNAL_CTX
|
||||
} rf_external_pa_signal_t;
|
||||
|
||||
static const st_gpio_epa_t rf_external_pa_gpio_table[] =
|
||||
{
|
||||
[RF_EPA_SIGNAL_CSD] = RF_EPA_CSD,
|
||||
[RF_EPA_SIGNAL_CTX] = RF_EPA_CTX
|
||||
};
|
||||
|
||||
void RF_CONTROL_ExternalPA(rf_external_pa_state_t state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RF_EXTERNAL_PA_H */
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file RTDebug.c
|
||||
* @author MCD Application Team
|
||||
* @brief Real Time Debug module API definition
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "RTDebug.h"
|
||||
#include "local_debug_tables.h"
|
||||
#include "stm32wbaxx_hal.h"
|
||||
#include <assert.h>
|
||||
|
||||
#if(CFG_RT_DEBUG_GPIO_MODULE == 1)
|
||||
static_assert((sizeof(general_debug_table)/sizeof(st_gpio_debug_t)) == RT_DEBUG_SIGNALS_TOTAL_NUM,
|
||||
"Debug signals number is different from debug signal table size."
|
||||
);
|
||||
#endif /* CFG_RT_DEBUG_GPIO_MODULE */
|
||||
|
||||
/***********************/
|
||||
/** System debug APIs **/
|
||||
/***********************/
|
||||
|
||||
void SYSTEM_DEBUG_SIGNAL_SET(system_debug_signal_t signal)
|
||||
{
|
||||
#if(CFG_RT_DEBUG_GPIO_MODULE == 1)
|
||||
GENERIC_DEBUG_GPIO_SET(signal, system_debug_table);
|
||||
#endif /* CFG_RT_DEBUG_GPIO_MODULE */
|
||||
}
|
||||
|
||||
void SYSTEM_DEBUG_SIGNAL_RESET(system_debug_signal_t signal)
|
||||
{
|
||||
#if(CFG_RT_DEBUG_GPIO_MODULE == 1)
|
||||
GENERIC_DEBUG_GPIO_RESET(signal, system_debug_table);
|
||||
#endif /* CFG_RT_DEBUG_GPIO_MODULE */
|
||||
}
|
||||
|
||||
void SYSTEM_DEBUG_SIGNAL_TOGGLE(system_debug_signal_t signal)
|
||||
{
|
||||
#if(CFG_RT_DEBUG_GPIO_MODULE == 1)
|
||||
GENERIC_DEBUG_GPIO_TOGGLE(signal, system_debug_table);
|
||||
#endif /* CFG_RT_DEBUG_GPIO_MODULE */
|
||||
}
|
||||
|
||||
/***************************/
|
||||
/** Link Layer debug APIs **/
|
||||
/***************************/
|
||||
|
||||
/* Link Layer debug API definition */
|
||||
void LINKLAYER_DEBUG_SIGNAL_SET(linklayer_debug_signal_t signal)
|
||||
{
|
||||
#if(CFG_RT_DEBUG_GPIO_MODULE == 1)
|
||||
GENERIC_DEBUG_GPIO_SET(signal, linklayer_debug_table);
|
||||
#endif /* CFG_RT_DEBUG_GPIO_MODULE */
|
||||
}
|
||||
|
||||
void LINKLAYER_DEBUG_SIGNAL_RESET(linklayer_debug_signal_t signal)
|
||||
{
|
||||
#if(CFG_RT_DEBUG_GPIO_MODULE == 1)
|
||||
GENERIC_DEBUG_GPIO_RESET(signal, linklayer_debug_table);
|
||||
#endif /* CFG_RT_DEBUG_GPIO_MODULE */
|
||||
}
|
||||
|
||||
void LINKLAYER_DEBUG_SIGNAL_TOGGLE(linklayer_debug_signal_t signal)
|
||||
{
|
||||
#if(CFG_RT_DEBUG_GPIO_MODULE == 1)
|
||||
GENERIC_DEBUG_GPIO_TOGGLE(signal, linklayer_debug_table);
|
||||
#endif /* CFG_RT_DEBUG_GPIO_MODULE */
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file RTDebug.h
|
||||
* @author MCD Application Team
|
||||
* @brief Real Time Debug module API declaration
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_DEBUG_H
|
||||
#define SYSTEM_DEBUG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "debug_config.h"
|
||||
|
||||
#if(CFG_RT_DEBUG_GPIO_MODULE == 1)
|
||||
|
||||
/**************************************************************/
|
||||
/** Generic macros for local signal table index recuperation **/
|
||||
/** and global signal table GPIO manipulation **/
|
||||
/**************************************************************/
|
||||
|
||||
#define GENERIC_DEBUG_GPIO_SET(signal, table) do { \
|
||||
uint32_t debug_table_idx = 0; \
|
||||
if(signal >= sizeof(table)) \
|
||||
{ \
|
||||
return; \
|
||||
} \
|
||||
debug_table_idx = table[signal]; \
|
||||
if(debug_table_idx != RT_DEBUG_SIGNAL_UNUSED) \
|
||||
{ \
|
||||
LL_GPIO_SetOutputPin(general_debug_table[debug_table_idx].GPIO_port, \
|
||||
general_debug_table[debug_table_idx].GPIO_pin); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define GENERIC_DEBUG_GPIO_RESET(signal, table) do { \
|
||||
uint32_t debug_table_idx = 0; \
|
||||
if(signal >= sizeof(table)) \
|
||||
{ \
|
||||
return; \
|
||||
} \
|
||||
debug_table_idx = table[signal]; \
|
||||
if(debug_table_idx != RT_DEBUG_SIGNAL_UNUSED) \
|
||||
{ \
|
||||
LL_GPIO_ResetOutputPin(general_debug_table[debug_table_idx].GPIO_port, \
|
||||
general_debug_table[debug_table_idx].GPIO_pin); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define GENERIC_DEBUG_GPIO_TOGGLE(signal, table) do { \
|
||||
uint32_t debug_table_idx = 0; \
|
||||
if(signal >= sizeof(table)) \
|
||||
{ \
|
||||
return; \
|
||||
} \
|
||||
debug_table_idx = table[signal]; \
|
||||
if(debug_table_idx != RT_DEBUG_SIGNAL_UNUSED) \
|
||||
{ \
|
||||
LL_GPIO_TogglePin(general_debug_table[debug_table_idx].GPIO_port, \
|
||||
general_debug_table[debug_table_idx].GPIO_pin); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#endif /* CFG_RT_DEBUG_GPIO_MODULE */
|
||||
|
||||
/* System debug API definition */
|
||||
void SYSTEM_DEBUG_SIGNAL_SET(system_debug_signal_t signal);
|
||||
void SYSTEM_DEBUG_SIGNAL_RESET(system_debug_signal_t signal);
|
||||
void SYSTEM_DEBUG_SIGNAL_TOGGLE(system_debug_signal_t signal);
|
||||
|
||||
/* Link Layer debug API definition */
|
||||
void LINKLAYER_DEBUG_SIGNAL_SET(linklayer_debug_signal_t signal);
|
||||
void LINKLAYER_DEBUG_SIGNAL_RESET(linklayer_debug_signal_t signal);
|
||||
void LINKLAYER_DEBUG_SIGNAL_TOGGLE(linklayer_debug_signal_t signal);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_DEBUG_H */
|
||||
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file RTDebug_dtb.c
|
||||
* @author MCD Application Team
|
||||
* @brief Real Time Debug module API definition for DTB usage
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* The DEBUG DTB interface is INTENDED TO BE USED ONLY ON REQUEST FROM ST SUPPORT.
|
||||
* It provides HW signals from RF PHY activity.
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "RTDebug_dtb.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
#if(CFG_RT_DEBUG_DTB == 1)
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void RT_DEBUG_SetDTBMode(uint8_t dtb, uint8_t mode);
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
static void RT_DEBUG_SetDTBMode(uint8_t dtb, uint8_t mode)
|
||||
{
|
||||
/* Set SYSCFG for DTB */
|
||||
uint32_t addr = (uint32_t)(&SYSCFG->SECCFGR);
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
addr += 0x100; /* contains SYSCFG->DBTCR address */
|
||||
|
||||
/* Keep others DTB in current modes */
|
||||
*(uint32_t*)addr |= (0xF<<(dtb*4)); /* Selected DTB unmask mode */
|
||||
*(uint32_t*)addr ^= (0xF<<(dtb*4)); /* Selected DTB unset mode */
|
||||
|
||||
/* Selected DTB set to mode */
|
||||
*(uint32_t*)addr |= (mode<<(dtb*4));
|
||||
}
|
||||
|
||||
void RT_DEBUG_DTBInit(void)
|
||||
{
|
||||
/** access_match PA7 DTB[7] on TL_10 **/
|
||||
/*
|
||||
LL_GPIO_SetPinSpeed(GPIOA,LL_GPIO_PIN_7,LL_GPIO_SPEED_FREQ_HIGH);
|
||||
LL_GPIO_SetPinMode(GPIOA,LL_GPIO_PIN_7,LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetAFPin_0_7(GPIOA,LL_GPIO_PIN_7,LL_GPIO_AF_15);
|
||||
LL_PWR_EnableGPIOStandbyRetention(LL_PWR_GPIO_STATE_RETENTION_ENABLE_PORTA, LL_PWR_GPIO_PIN_7);
|
||||
*/
|
||||
|
||||
/** long_range_iq_vld PA6 DTB[6] on TL_9 **/
|
||||
LL_GPIO_SetPinMode(GPIOA,LL_GPIO_PIN_6,LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetAFPin_0_7(GPIOA,LL_GPIO_PIN_6,LL_GPIO_AF_15);
|
||||
|
||||
|
||||
/** tx_data PA5 DTB[5] on TL_8 **/
|
||||
/*
|
||||
LL_GPIO_SetPinMode(GPIOA,LL_GPIO_PIN_5,LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetAFPin_0_7(GPIOA,LL_GPIO_PIN_5,LL_GPIO_AF_15);
|
||||
*/
|
||||
|
||||
/** rx_data PB9 DTB[4] on TL_31 **/
|
||||
/*
|
||||
LL_GPIO_SetPinMode(GPIOB,LL_GPIO_PIN_9,LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetAFPin_8_15(GPIOB,LL_GPIO_PIN_9,LL_GPIO_AF_15);
|
||||
LL_PWR_EnableGPIOStandbyRetention(LL_PWR_GPIO_STATE_RETENTION_ENABLE_PORTB, LL_PWR_GPIO_PIN_9);
|
||||
*/
|
||||
|
||||
/** tx_data_clk PB8 DTB[3] on TL_30 **/
|
||||
/*
|
||||
LL_GPIO_SetPinMode(GPIOB,LL_GPIO_PIN_8,LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetAFPin_8_15(GPIOB,LL_GPIO_PIN_8,LL_GPIO_AF_15);
|
||||
*/
|
||||
|
||||
/** rx_data_clk PA2 DTB[2] on TL_3 **/
|
||||
/*
|
||||
LL_GPIO_SetPinMode(GPIOA,LL_GPIO_PIN_2,LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetAFPin_0_7(GPIOA,LL_GPIO_PIN_2,LL_GPIO_AF_15);
|
||||
LL_PWR_EnableGPIOStandbyRetention(LL_PWR_GPIO_STATE_RETENTION_ENABLE_PORTA, LL_PWR_GPIO_PIN_2);
|
||||
*/
|
||||
|
||||
/** tx_on PA1 DTB[1] on TL_2 **/
|
||||
LL_GPIO_SetPinMode(GPIOA,LL_GPIO_PIN_1,LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetAFPin_0_7(GPIOA,LL_GPIO_PIN_1,LL_GPIO_AF_15);
|
||||
LL_PWR_EnableGPIOStandbyRetention(LL_PWR_GPIO_STATE_RETENTION_ENABLE_PORTA, LL_PWR_GPIO_PIN_1);
|
||||
|
||||
/** rx_on PA0 DTB[0] on TL_1 **/
|
||||
/*
|
||||
LL_GPIO_SetPinMode(GPIOA,LL_GPIO_PIN_0,LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetAFPin_0_7(GPIOA,LL_GPIO_PIN_0,LL_GPIO_AF_15);
|
||||
LL_PWR_EnableGPIOStandbyRetention(LL_PWR_GPIO_STATE_RETENTION_ENABLE_PORTA, LL_PWR_GPIO_PIN_0);
|
||||
*/
|
||||
|
||||
/* Set SYSCFG for DTB */
|
||||
uint32_t addr = (uint32_t)(&SYSCFG->SECCFGR);
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
addr += 0x100; /* contains SYSCFG->DBTCR address */
|
||||
|
||||
/* Default DTB in test mode 0 */
|
||||
*(uint32_t*)addr = 0x00000000;
|
||||
}
|
||||
|
||||
/* Public functions ----------------------------------------------------------*/
|
||||
void RT_DEBUG_DTBConfig(void)
|
||||
{
|
||||
|
||||
/*
|
||||
** Monitor DTB **
|
||||
* A0 o PA0 AF15 DTB[0] mode 1 rx_on
|
||||
* A1 o PA1 AF15 DTB[1] mode 1 tx_on
|
||||
* A2 o PB9 AF15 DTB[4] mode 5 radio_bbclk
|
||||
* A3 o PA7 AF15 DTB[7] mode 3 slptmr_irq
|
||||
* A4 o PA2 AF15 DTB[2] mode 5 CM33_sleepdeep
|
||||
* A5 o PA6 AF00 PWR_CSTOP
|
||||
* A6 o PA8 as SYSclk source
|
||||
* A7 o PB1 Monitor wakeup GPIO
|
||||
* A8 o PB0 Debug PIN
|
||||
* A9 o PC0 o_pm_sleep_sw
|
||||
* A10 o PC1 o_pm_act_com_sw
|
||||
**/
|
||||
|
||||
RT_DEBUG_SetDTBMode(6, 3) ; /* Radio IRQ */
|
||||
RT_DEBUG_SetDTBMode(1, 1); /* tx_on */
|
||||
|
||||
//RT_DEBUG_SetDTBMode(0, 1); /* rx_on */
|
||||
//RT_DEBUG_SetDTBMode(1, 3); /* sleep timer irq */
|
||||
//RT_DEBUG_SetDTBMode(2, 5); /* CM33_sleepdeep */
|
||||
//RT_DEBUG_SetDTBMode(4, 5); /* radio_bbclk */
|
||||
//RT_DEBUG_SetDTBMode(7, 3); /* slptm_irq */
|
||||
//RT_DEBUG_SetDTBMode(7, 5); /* radio_bus_clk */
|
||||
//RT_DEBUG_SetDTBMode(7, 6); /* test tm 00 */
|
||||
//RT_DEBUG_SetDTBMode(6, 6); /* test tm 01 */
|
||||
}
|
||||
|
||||
#endif /* CFG_RT_DEBUG_DTB */
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file RTDebug_dtb.h
|
||||
* @author MCD Application Team
|
||||
* @brief Real Time Debug module API declaration for DTB usage
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef RT_DEBUG_DTB_H
|
||||
#define RT_DEBUG_DTB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The DEBUG DTB interface is INTENDED TO BE USED ONLY ON REQUEST FROM ST SUPPORT.
|
||||
* It provides HW signals from RF PHY activity.
|
||||
*/
|
||||
|
||||
#include "app_conf.h"
|
||||
|
||||
#if(CFG_RT_DEBUG_DTB == 1)
|
||||
void RT_DEBUG_DTBConfig(void);
|
||||
void RT_DEBUG_DTBInit(void);
|
||||
#endif /* CFG_RT_DEBUG_DTB */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RT_DEBUG_DTB_H */
|
||||
|
||||
@@ -0,0 +1,833 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file debug_signals.h
|
||||
* @author MCD Application Team
|
||||
* @brief Real Time Debug module System and Link Layer signal definition
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef DEBUG_SIGNALS_H
|
||||
#define DEBUG_SIGNALS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "bsp.h"
|
||||
|
||||
/**************************************************/
|
||||
/** Specific Link Layer debug signals definition **/
|
||||
/**************************************************/
|
||||
typedef Debug_GPIO_t linklayer_debug_signal_t;
|
||||
|
||||
/**********************************************/
|
||||
/** Specific System debug signals definition **/
|
||||
/**********************************************/
|
||||
typedef enum {
|
||||
ADC_ACTIVATION,
|
||||
ADC_DEACTIVATION,
|
||||
ADC_TEMPERATURE_ACQUISITION,
|
||||
RNG_ENABLE,
|
||||
RNG_DISABLE,
|
||||
RNG_GEN_RAND_NUM,
|
||||
LOW_POWER_STOP_MODE_ENTER,
|
||||
LOW_POWER_STOP_MODE_EXIT,
|
||||
LOW_POWER_STOP_MODE_ACTIVE,
|
||||
LOW_POWER_STOP2_MODE_ENTER,
|
||||
LOW_POWER_STOP2_MODE_EXIT,
|
||||
LOW_POWER_STOP2_MODE_ACTIVE,
|
||||
LOW_POWER_STANDBY_MODE_ENTER,
|
||||
LOW_POWER_STANDBY_MODE_EXIT,
|
||||
LOW_POWER_STANDBY_MODE_ACTIVE,
|
||||
SCM_SETUP,
|
||||
SCM_SYSTEM_CLOCK_CONFIG,
|
||||
SCM_HSERDY_ISR,
|
||||
} system_debug_signal_t;
|
||||
|
||||
#if(CFG_RT_DEBUG_GPIO_MODULE == 1)
|
||||
|
||||
/*************************************/
|
||||
/** Global debug signals definition **/
|
||||
/*************************************/
|
||||
|
||||
typedef enum {
|
||||
RT_DEBUG_SIGNAL_UNUSED = 0x0,
|
||||
|
||||
/********************/
|
||||
/** System signals **/
|
||||
/********************/
|
||||
|
||||
#if (USE_RT_DEBUG_SCM_SETUP == 1)
|
||||
RT_DEBUG_SCM_SETUP,
|
||||
#endif /* USE_RT_DEBUG_SCM_SETUP */
|
||||
|
||||
#if (USE_RT_DEBUG_SCM_HSERDY_ISR == 1)
|
||||
RT_DEBUG_SCM_HSERDY_ISR,
|
||||
#endif /* USE_RT_DEBUG_SCM_HSERDY_ISR */
|
||||
|
||||
#if (USE_RT_DEBUG_SCM_SYSTEM_CLOCK_CONFIG == 1)
|
||||
RT_DEBUG_SCM_SYSTEM_CLOCK_CONFIG,
|
||||
#endif /* USE_RT_DEBUG_SCM_SYSTEM_CLOCK_CONFIG */
|
||||
|
||||
#if (USE_RT_DEBUG_ADC_ACTIVATION == 1)
|
||||
RT_DEBUG_ADC_ACTIVATION,
|
||||
#endif /* USE_RT_DEBUG_ADC_ACTIVATION */
|
||||
|
||||
#if (USE_RT_DEBUG_ADC_DEACTIVATION == 1)
|
||||
RT_DEBUG_ADC_DEACTIVATION,
|
||||
#endif /* USE_RT_DEBUG_ADC_DEACTIVATION */
|
||||
|
||||
#if (USE_RT_DEBUG_ADC_TEMPERATURE_ACQUISITION == 1)
|
||||
RT_DEBUG_ADC_TEMPERATURE_ACQUISITION,
|
||||
#endif /* USE_RT_DEBUG_ADC_TEMPERATURE_ACQUISITION */
|
||||
|
||||
#if (USE_RT_DEBUG_RNG_ENABLE == 1)
|
||||
RT_DEBUG_RNG_ENABLE,
|
||||
#endif /* USE_RT_DEBUG_RNG_ENABLE */
|
||||
|
||||
#if (USE_RT_DEBUG_RNG_DISABLE == 1)
|
||||
RT_DEBUG_RNG_DISABLE,
|
||||
#endif /* USE_RT_DEBUG_RNG_DISABLE */
|
||||
|
||||
#if (USE_RT_DEBUG_RNG_GEN_RAND_NUM == 1)
|
||||
RT_DEBUG_RNG_GEN_RAND_NUM,
|
||||
#endif /* USE_RT_DEBUG_RNG_GEN_RAND_NUM */
|
||||
|
||||
#if (USE_RT_DEBUG_LOW_POWER_STOP_MODE_ENTER == 1)
|
||||
RT_DEBUG_LOW_POWER_STOP_MODE_ENTER,
|
||||
#endif /* USE_RT_DEBUG_LOW_POWER_STOP_MODE_ENTER */
|
||||
|
||||
#if (USE_RT_DEBUG_LOW_POWER_STOP_MODE_EXIT == 1)
|
||||
RT_DEBUG_LOW_POWER_STOP_MODE_EXIT,
|
||||
#endif /* USE_RT_DEBUG_LOW_POWER_STOP_MODE_EXIT */
|
||||
|
||||
#if (USE_RT_DEBUG_LOW_POWER_STOP_MODE_ACTIVE == 1)
|
||||
RT_DEBUG_LOW_POWER_STOP_MODE_ACTIVE,
|
||||
#endif /* USE_RT_DEBUG_LOW_POWER_STOP_MODE_ACTIVE */
|
||||
|
||||
#if (USE_RT_DEBUG_LOW_POWER_STOP2_MODE_ENTER == 1)
|
||||
RT_DEBUG_LOW_POWER_STOP2_MODE_ENTER,
|
||||
#endif /* USE_RT_DEBUG_LOW_POWER_STOP2_MODE_ENTER */
|
||||
|
||||
#if (USE_RT_DEBUG_LOW_POWER_STOP2_MODE_EXIT == 1)
|
||||
RT_DEBUG_LOW_POWER_STOP2_MODE_EXIT,
|
||||
#endif /* USE_RT_DEBUG_LOW_POWER_STOP2_MODE_EXIT */
|
||||
|
||||
#if (USE_RT_DEBUG_LOW_POWER_STOP2_MODE_ACTIVE == 1)
|
||||
RT_DEBUG_LOW_POWER_STOP2_MODE_ACTIVE,
|
||||
#endif /* USE_RT_DEBUG_LOW_POWER_STOP2_MODE_ACTIVE */
|
||||
|
||||
#if (USE_RT_DEBUG_LOW_POWER_STANDBY_MODE_ENTER == 1)
|
||||
RT_DEBUG_LOW_POWER_STANDBY_MODE_ENTER,
|
||||
#endif /* USE_RT_DEBUG_LOW_POWER_STANDBY_MODE_ENTER */
|
||||
|
||||
#if (USE_RT_DEBUG_LOW_POWER_STANDBY_MODE_EXIT == 1)
|
||||
RT_DEBUG_LOW_POWER_STANDBY_MODE_EXIT,
|
||||
#endif /* USE_RT_DEBUG_LOW_POWER_STANDBY_MODE_EXIT */
|
||||
|
||||
#if (USE_RT_DEBUG_LOW_POWER_STANDBY_MODE_ACTIVE == 1)
|
||||
RT_DEBUG_LOW_POWER_STANDBY_MODE_ACTIVE,
|
||||
#endif /* USE_RT_DEBUG_LOW_POWER_STANDBY_MODE_ACTIVE */
|
||||
|
||||
/************************/
|
||||
/** Link Layer signals **/
|
||||
/************************/
|
||||
|
||||
#if (USE_RT_DEBUG_HCI_READ_DONE == 1)
|
||||
RT_DEBUG_HCI_READ_DONE,
|
||||
#endif /* USE_RT_DEBUG_HCI_READ_DONE */
|
||||
|
||||
#if (USE_RT_DEBUG_HCI_RCVD_CMD == 1)
|
||||
RT_DEBUG_HCI_RCVD_CMD,
|
||||
#endif /* USE_RT_DEBUG_HCI_RCVD_CMD */
|
||||
|
||||
#if (USE_RT_DEBUG_HCI_WRITE_DONE == 1)
|
||||
RT_DEBUG_HCI_WRITE_DONE,
|
||||
#endif /* USE_RT_DEBUG_HCI_WRITE_DONE */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_EVNT_UPDATE == 1)
|
||||
RT_DEBUG_SCHDLR_EVNT_UPDATE,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_EVNT_UPDATE */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_TIMER_SET == 1)
|
||||
RT_DEBUG_SCHDLR_TIMER_SET,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_TIMER_SET */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_PHY_CLBR_TIMER == 1)
|
||||
RT_DEBUG_SCHDLR_PHY_CLBR_TIMER,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_PHY_CLBR_TIMER */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_EVNT_SKIPPED == 1)
|
||||
RT_DEBUG_SCHDLR_EVNT_SKIPPED,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_EVNT_SKIPPED */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_HNDL_NXT_TRACE == 1)
|
||||
RT_DEBUG_SCHDLR_HNDL_NXT_TRACE,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_HNDL_NXT_TRACE */
|
||||
|
||||
#if (USE_RT_DEBUG_ACTIVE_SCHDLR_NEAR_DETEDTED == 1)
|
||||
RT_DEBUG_ACTIVE_SCHDLR_NEAR_DETEDTED,
|
||||
#endif /* USE_RT_DEBUG_ACTIVE_SCHDLR_NEAR_DETEDTED */
|
||||
|
||||
#if (USE_RT_DEBUG_ACTIVE_SCHDLR_NEAR_GAP_CHECK == 1)
|
||||
RT_DEBUG_ACTIVE_SCHDLR_NEAR_GAP_CHECK,
|
||||
#endif /* USE_RT_DEBUG_ACTIVE_SCHDLR_NEAR_GAP_CHECK */
|
||||
|
||||
#if (USE_RT_DEBUG_ACTIVE_SCHDLR_NEAR_TIME_CHECK == 1)
|
||||
RT_DEBUG_ACTIVE_SCHDLR_NEAR_TIME_CHECK,
|
||||
#endif /* USE_RT_DEBUG_ACTIVE_SCHDLR_NEAR_TIME_CHECK */
|
||||
|
||||
#if (USE_RT_DEBUG_ACTIVE_SCHDLR_NEAR_TRACE == 1)
|
||||
RT_DEBUG_ACTIVE_SCHDLR_NEAR_TRACE,
|
||||
#endif /* USE_RT_DEBUG_ACTIVE_SCHDLR_NEAR_TRACE */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_EVNT_RGSTR == 1)
|
||||
RT_DEBUG_SCHDLR_EVNT_RGSTR,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_EVNT_RGSTR */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_ADD_CONFLICT_Q == 1)
|
||||
RT_DEBUG_SCHDLR_ADD_CONFLICT_Q,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_ADD_CONFLICT_Q */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_HNDL_MISSED_EVNT == 1)
|
||||
RT_DEBUG_SCHDLR_HNDL_MISSED_EVNT,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_HNDL_MISSED_EVNT */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_UNRGSTR_EVNT == 1)
|
||||
RT_DEBUG_SCHDLR_UNRGSTR_EVNT,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_UNRGSTR_EVNT */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_EXEC_EVNT_TRACE == 1)
|
||||
RT_DEBUG_SCHDLR_EXEC_EVNT_TRACE,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_EXEC_EVNT_TRACE */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_EXEC_EVNT_PROFILE == 1)
|
||||
RT_DEBUG_SCHDLR_EXEC_EVNT_PROFILE,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_EXEC_EVNT_PROFILE */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_EXEC_EVNT_ERROR == 1)
|
||||
RT_DEBUG_SCHDLR_EXEC_EVNT_ERROR,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_EXEC_EVNT_ERROR */
|
||||
|
||||
#if (USE_RT_DEBUG_SCHDLR_EXEC_EVNT_WINDOW_WIDENING == 1)
|
||||
RT_DEBUG_SCHDLR_EXEC_EVNT_WINDOW_WIDENING,
|
||||
#endif /* USE_RT_DEBUG_SCHDLR_EXEC_EVNT_WINDOW_WIDENING */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_CMN_CLR_ISR == 1)
|
||||
RT_DEBUG_LLHWC_CMN_CLR_ISR,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_CMN_CLR_ISR */
|
||||
|
||||
#if (USE_RT_DEBUG_LLWCC_CMN_HG_ISR == 1)
|
||||
RT_DEBUG_LLWCC_CMN_HG_ISR,
|
||||
#endif /* USE_RT_DEBUG_LLWCC_CMN_HG_ISR */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_CMN_LW_ISR == 1)
|
||||
RT_DEBUG_LLHWC_CMN_LW_ISR,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_CMN_LW_ISR */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_CMN_CLR_TIMER_ERROR == 1)
|
||||
RT_DEBUG_LLHWC_CMN_CLR_TIMER_ERROR,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_CMN_CLR_TIMER_ERROR */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_LL_ISR == 1)
|
||||
RT_DEBUG_LLHWC_LL_ISR,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_LL_ISR */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_SPLTMR_SET == 1)
|
||||
RT_DEBUG_LLHWC_SPLTMR_SET,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_SPLTMR_SET */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_SPLTMR_GET == 1)
|
||||
RT_DEBUG_LLHWC_SPLTMR_GET,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_SPLTMR_GET */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_LOW_ISR == 1)
|
||||
RT_DEBUG_LLHWC_LOW_ISR,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_LOW_ISR */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_STOP_SCN == 1)
|
||||
RT_DEBUG_LLHWC_STOP_SCN,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_STOP_SCN */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_WAIT_ENVT_ON_AIR == 1)
|
||||
RT_DEBUG_LLHWC_WAIT_ENVT_ON_AIR,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_WAIT_ENVT_ON_AIR */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_SET_CONN_EVNT_PARAM == 1)
|
||||
RT_DEBUG_LLHWC_SET_CONN_EVNT_PARAM,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_SET_CONN_EVNT_PARAM */
|
||||
|
||||
#if (USE_RT_DEBUG_POST_EVNT == 1)
|
||||
RT_DEBUG_POST_EVNT,
|
||||
#endif /* USE_RT_DEBUG_POST_EVNT */
|
||||
|
||||
#if (USE_RT_DEBUG_HNDL_ALL_EVNTS == 1)
|
||||
RT_DEBUG_HNDL_ALL_EVNTS,
|
||||
#endif /* USE_RT_DEBUG_HNDL_ALL_EVNTS */
|
||||
|
||||
#if (USE_RT_DEBUG_PROCESS_EVNT == 1)
|
||||
RT_DEBUG_PROCESS_EVNT,
|
||||
#endif /* USE_RT_DEBUG_PROCESS_EVNT */
|
||||
|
||||
#if (USE_RT_DEBUG_PROCESS_ISO_DATA == 1)
|
||||
RT_DEBUG_PROCESS_ISO_DATA,
|
||||
#endif /* USE_RT_DEBUG_PROCESS_ISO_DATA */
|
||||
|
||||
#if (USE_RT_DEBUG_ALLOC_TX_ISO_EMPTY_PKT == 1)
|
||||
RT_DEBUG_ALLOC_TX_ISO_EMPTY_PKT,
|
||||
#endif /* USE_RT_DEBUG_ALLOC_TX_ISO_EMPTY_PKT */
|
||||
|
||||
#if (USE_RT_DEBUG_BIG_FREE_EMPTY_PKTS == 1)
|
||||
RT_DEBUG_BIG_FREE_EMPTY_PKTS,
|
||||
#endif /* USE_RT_DEBUG_BIG_FREE_EMPTY_PKTS */
|
||||
|
||||
#if (USE_RT_DEBUG_RECOMBINE_UNFRMD_DATA_OK == 1)
|
||||
RT_DEBUG_RECOMBINE_UNFRMD_DATA_OK,
|
||||
#endif /* USE_RT_DEBUG_RECOMBINE_UNFRMD_DATA_OK */
|
||||
|
||||
#if (USE_RT_DEBUG_RECOMBINE_UNFRMD_DATA_CRC == 1)
|
||||
RT_DEBUG_RECOMBINE_UNFRMD_DATA_CRC,
|
||||
#endif /* USE_RT_DEBUG_RECOMBINE_UNFRMD_DATA_CRC */
|
||||
|
||||
#if (USE_RT_DEBUG_RECOMBINE_UNFRMD_DATA_NoRX == 1)
|
||||
RT_DEBUG_RECOMBINE_UNFRMD_DATA_NoRX,
|
||||
#endif /* USE_RT_DEBUG_RECOMBINE_UNFRMD_DATA_NoRX */
|
||||
|
||||
#if (USE_RT_DEBUG_RECOMBINE_UNFRMD_DATA_TRACE == 1)
|
||||
RT_DEBUG_RECOMBINE_UNFRMD_DATA_TRACE,
|
||||
#endif /* USE_RT_DEBUG_RECOMBINE_UNFRMD_DATA_TRACE */
|
||||
|
||||
#if (USE_RT_DEBUG_ISO_HNDL_SDU == 1)
|
||||
RT_DEBUG_ISO_HNDL_SDU,
|
||||
#endif /* USE_RT_DEBUG_ISO_HNDL_SDU */
|
||||
|
||||
#if (USE_RT_DEBUG_LL_INTF_INIT == 1)
|
||||
RT_DEBUG_LL_INTF_INIT,
|
||||
#endif /* USE_RT_DEBUG_LL_INTF_INIT */
|
||||
|
||||
#if (USE_RT_DEBUG_DATA_TO_CNTRLR == 1)
|
||||
RT_DEBUG_DATA_TO_CNTRLR,
|
||||
#endif /* USE_RT_DEBUG_DATA_TO_CNTRLR */
|
||||
|
||||
#if (USE_RT_DEBUG_FREE_LL_PKT_HNDLR == 1)
|
||||
RT_DEBUG_FREE_LL_PKT_HNDLR,
|
||||
#endif /* USE_RT_DEBUG_FREE_LL_PKT_HNDLR */
|
||||
|
||||
#if (USE_RT_DEBUG_PHY_INIT_CLBR_TRACE == 1)
|
||||
RT_DEBUG_PHY_INIT_CLBR_TRACE,
|
||||
#endif /* USE_RT_DEBUG_PHY_INIT_CLBR_TRACE */
|
||||
|
||||
#if (USE_RT_DEBUG_PHY_RUNTIME_CLBR_TRACE == 1)
|
||||
RT_DEBUG_PHY_RUNTIME_CLBR_TRACE,
|
||||
#endif /* USE_RT_DEBUG_PHY_RUNTIME_CLBR_TRACE */
|
||||
|
||||
#if (USE_RT_DEBUG_PHY_CLBR_ISR == 1)
|
||||
RT_DEBUG_PHY_CLBR_ISR,
|
||||
#endif /* USE_RT_DEBUG_PHY_CLBR_ISR */
|
||||
|
||||
#if (USE_RT_DEBUG_PHY_INIT_CLBR_SINGLE_CH == 1)
|
||||
RT_DEBUG_PHY_INIT_CLBR_SINGLE_CH,
|
||||
#endif /* USE_RT_DEBUG_PHY_INIT_CLBR_SINGLE_CH */
|
||||
|
||||
#if (USE_RT_DEBUG_PHY_CLBR_STRTD == 1)
|
||||
RT_DEBUG_PHY_CLBR_STRTD,
|
||||
#endif /* USE_RT_DEBUG_PHY_CLBR_STRTD */
|
||||
|
||||
#if (USE_RT_DEBUG_PHY_CLBR_EXEC == 1)
|
||||
RT_DEBUG_PHY_CLBR_EXEC,
|
||||
#endif /* USE_RT_DEBUG_PHY_CLBR_EXEC */
|
||||
|
||||
#if (USE_RT_DEBUG_RCO_STRT_STOP_RUNTIME_CLBR_ACTV == 1)
|
||||
RT_DEBUG_RCO_STRT_STOP_RUNTIME_CLBR_ACTV,
|
||||
#endif /* USE_RT_DEBUG_RCO_STRT_STOP_RUNTIME_CLBR_ACTV */
|
||||
|
||||
#if (USE_RT_DEBUG_RCO_STRT_STOP_RUNTIME_RCO_CLBR == 1)
|
||||
RT_DEBUG_RCO_STRT_STOP_RUNTIME_RCO_CLBR,
|
||||
#endif /* USE_RT_DEBUG_RCO_STRT_STOP_RUNTIME_RCO_CLBR */
|
||||
|
||||
#if (USE_RT_DEBUG_STRT_STOP_RUNTIME_RCO_CLBR_SWT == 1)
|
||||
RT_DEBUG_STRT_STOP_RUNTIME_RCO_CLBR_SWT,
|
||||
#endif /* USE_RT_DEBUG_STRT_STOP_RUNTIME_RCO_CLBR_SWT */
|
||||
|
||||
#if (USE_RT_DEBUG_STRT_STOP_RUNTIME_RCO_CLBR_TRACE == 1)
|
||||
RT_DEBUG_STRT_STOP_RUNTIME_RCO_CLBR_TRACE,
|
||||
#endif /* USE_RT_DEBUG_STRT_STOP_RUNTIME_RCO_CLBR_TRACE */
|
||||
|
||||
#if (USE_RT_DEBUG_RCO_ISR_TRACE == 1)
|
||||
RT_DEBUG_RCO_ISR_TRACE,
|
||||
#endif /* USE_RT_DEBUG_RCO_ISR_TRACE */
|
||||
|
||||
#if (USE_RT_DEBUG_RCO_ISR_COMPENDATE == 1)
|
||||
RT_DEBUG_RCO_ISR_COMPENDATE,
|
||||
#endif /* USE_RT_DEBUG_RCO_ISR_COMPENDATE */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_STRT_TX == 1)
|
||||
RT_DEBUG_RAL_STRT_TX,
|
||||
#endif /* USE_RT_DEBUG_RAL_STRT_TX */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_ISR_TIMER_ERROR == 1)
|
||||
RT_DEBUG_RAL_ISR_TIMER_ERROR,
|
||||
#endif /* USE_RT_DEBUG_RAL_ISR_TIMER_ERROR */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_ISR_TRACE == 1)
|
||||
RT_DEBUG_RAL_ISR_TRACE,
|
||||
#endif /* USE_RT_DEBUG_RAL_ISR_TRACE */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_STOP_OPRTN == 1)
|
||||
RT_DEBUG_RAL_STOP_OPRTN,
|
||||
#endif /* USE_RT_DEBUG_RAL_STOP_OPRTN */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_STRT_RX == 1)
|
||||
RT_DEBUG_RAL_STRT_RX,
|
||||
#endif /* USE_RT_DEBUG_RAL_STRT_RX */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_DONE_CLBK_TX == 1)
|
||||
RT_DEBUG_RAL_DONE_CLBK_TX,
|
||||
#endif /* USE_RT_DEBUG_RAL_DONE_CLBK_TX */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_DONE_CLBK_RX == 1)
|
||||
RT_DEBUG_RAL_DONE_CLBK_RX,
|
||||
#endif /* USE_RT_DEBUG_RAL_DONE_CLBK_RX */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_DONE_CLBK_ED == 1)
|
||||
RT_DEBUG_RAL_DONE_CLBK_ED,
|
||||
#endif /* USE_RT_DEBUG_RAL_DONE_CLBK_ED */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_ED_SCAN == 1)
|
||||
RT_DEBUG_RAL_ED_SCAN,
|
||||
#endif /* USE_RT_DEBUG_RAL_ED_SCAN */
|
||||
|
||||
#if (USE_RT_DEBUG_ERROR_MEM_CAP_EXCED == 1)
|
||||
RT_DEBUG_ERROR_MEM_CAP_EXCED,
|
||||
#endif /* USE_RT_DEBUG_ERROR_MEM_CAP_EXCED */
|
||||
|
||||
#if (USE_RT_DEBUG_ERROR_COMMAND_DISALLOWED == 1)
|
||||
RT_DEBUG_ERROR_COMMAND_DISALLOWED,
|
||||
#endif /* USE_RT_DEBUG_ERROR_COMMAND_DISALLOWED */
|
||||
|
||||
#if (USE_RT_DEBUG_PTA_INIT == 1)
|
||||
RT_DEBUG_PTA_INIT,
|
||||
#endif /* USE_RT_DEBUG_PTA_INIT */
|
||||
|
||||
#if (USE_RT_DEBUG_PTA_EN == 1)
|
||||
RT_DEBUG_PTA_EN,
|
||||
#endif /* USE_RT_DEBUG_PTA_EN */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_PTA_SET_EN == 1)
|
||||
RT_DEBUG_LLHWC_PTA_SET_EN,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_PTA_SET_EN */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_PTA_SET_PARAMS == 1)
|
||||
RT_DEBUG_LLHWC_PTA_SET_PARAMS,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_PTA_SET_PARAMS */
|
||||
|
||||
#if (USE_RT_DEBUG_COEX_STRT_ON_IDLE == 1)
|
||||
RT_DEBUG_COEX_STRT_ON_IDLE,
|
||||
#endif /* USE_RT_DEBUG_COEX_STRT_ON_IDLE */
|
||||
|
||||
#if (USE_RT_DEBUG_COEX_ASK_FOR_AIR == 1)
|
||||
RT_DEBUG_COEX_ASK_FOR_AIR,
|
||||
#endif /* USE_RT_DEBUG_COEX_ASK_FOR_AIR */
|
||||
|
||||
#if (USE_RT_DEBUG_COEX_TIMER_EVNT_CLBK == 1)
|
||||
RT_DEBUG_COEX_TIMER_EVNT_CLBK,
|
||||
#endif /* USE_RT_DEBUG_COEX_TIMER_EVNT_CLBK */
|
||||
|
||||
#if (USE_RT_DEBUG_COEX_STRT_ONE_SHOT == 1)
|
||||
RT_DEBUG_COEX_STRT_ONE_SHOT,
|
||||
#endif /* USE_RT_DEBUG_COEX_STRT_ONE_SHOT */
|
||||
|
||||
#if (USE_RT_DEBUG_COEX_FORCE_STOP_RX == 1)
|
||||
RT_DEBUG_COEX_FORCE_STOP_RX,
|
||||
#endif /* USE_RT_DEBUG_COEX_FORCE_STOP_RX */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_ADV_DONE == 1)
|
||||
RT_DEBUG_LLHWC_ADV_DONE,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_ADV_DONE */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_SCN_DONE == 1)
|
||||
RT_DEBUG_LLHWC_SCN_DONE,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_SCN_DONE */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_INIT_DONE == 1)
|
||||
RT_DEBUG_LLHWC_INIT_DONE,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_INIT_DONE */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_CONN_DONE == 1)
|
||||
RT_DEBUG_LLHWC_CONN_DONE,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_CONN_DONE */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_CIG_DONE == 1)
|
||||
RT_DEBUG_LLHWC_CIG_DONE,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_CIG_DONE */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_BIG_DONE == 1)
|
||||
RT_DEBUG_LLHWC_BIG_DONE,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_BIG_DONE */
|
||||
|
||||
#if (USE_RT_DEBUG_OS_TMR_CREATE == 1)
|
||||
RT_DEBUG_OS_TMR_CREATE,
|
||||
#endif /* USE_RT_DEBUG_OS_TMR_CREATE */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_TIMEOUT_CBK == 1)
|
||||
RT_DEBUG_ADV_EXT_TIMEOUT_CBK,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_TIMEOUT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_SCN_DUR_CBK == 1)
|
||||
RT_DEBUG_ADV_EXT_SCN_DUR_CBK,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_SCN_DUR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_SCN_PERIOD_CBK == 1)
|
||||
RT_DEBUG_ADV_EXT_SCN_PERIOD_CBK,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_SCN_PERIOD_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_PRDC_SCN_TIMEOUT_CBK == 1)
|
||||
RT_DEBUG_ADV_EXT_PRDC_SCN_TIMEOUT_CBK,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_PRDC_SCN_TIMEOUT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_BIS_SYNC_TIMEOUT_TMR_CBK == 1)
|
||||
RT_DEBUG_BIS_SYNC_TIMEOUT_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_BIS_SYNC_TIMEOUT_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_BIS_TERM_TMR_CBK == 1)
|
||||
RT_DEBUG_BIS_TERM_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_BIS_TERM_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_BIS_TST_MODE_CBK == 1)
|
||||
RT_DEBUG_BIS_TST_MODE_CBK,
|
||||
#endif /* USE_RT_DEBUG_BIS_TST_MODE_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_BIS_TST_MODE_TMR_CBK == 1)
|
||||
RT_DEBUG_BIS_TST_MODE_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_BIS_TST_MODE_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ISO_POST_TMR_CBK == 1)
|
||||
RT_DEBUG_ISO_POST_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_ISO_POST_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ISO_TST_MODE_TMR_CBK == 1)
|
||||
RT_DEBUG_ISO_TST_MODE_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_ISO_TST_MODE_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_CONN_POST_TMR_CBK == 1)
|
||||
RT_DEBUG_CONN_POST_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_CONN_POST_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_EVNT_SCHDLR_TMR_CBK == 1)
|
||||
RT_DEBUG_EVNT_SCHDLR_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_EVNT_SCHDLR_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_HCI_POST_TMR_CBK == 1)
|
||||
RT_DEBUG_HCI_POST_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_HCI_POST_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_LLCP_POST_TMR_CBK == 1)
|
||||
RT_DEBUG_LLCP_POST_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_LLCP_POST_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_ENRGY_DETECT_CBK == 1)
|
||||
RT_DEBUG_LLHWC_ENRGY_DETECT_CBK,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_ENRGY_DETECT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_PRVCY_POST_TMR_CBK == 1)
|
||||
RT_DEBUG_PRVCY_POST_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_PRVCY_POST_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ANT_PRPR_TMR_CBK == 1)
|
||||
RT_DEBUG_ANT_PRPR_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_ANT_PRPR_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_COEX_TMR_FRC_STOP_AIR_GRANT_CBK == 1)
|
||||
RT_DEBUG_COEX_TMR_FRC_STOP_AIR_GRANT_CBK,
|
||||
#endif /* USE_RT_DEBUG_COEX_TMR_FRC_STOP_AIR_GRANT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_MLME_RX_EN_TMR_CBK == 1)
|
||||
RT_DEBUG_MLME_RX_EN_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_MLME_RX_EN_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_MLME_GNRC_TMR_CBK == 1)
|
||||
RT_DEBUG_MLME_GNRC_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_MLME_GNRC_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_MIB_JOIN_LST_TMR_CBK == 1)
|
||||
RT_DEBUG_MIB_JOIN_LST_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_MIB_JOIN_LST_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_MLME_PWR_PRES_TMR_CBK == 1)
|
||||
RT_DEBUG_MLME_PWR_PRES_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_MLME_PWR_PRES_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_PRESISTENCE_TMR_CBK == 1)
|
||||
RT_DEBUG_PRESISTENCE_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_PRESISTENCE_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_RADIO_PHY_PRDC_CLBK_TMR_CBK == 1)
|
||||
RT_DEBUG_RADIO_PHY_PRDC_CLBK_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_RADIO_PHY_PRDC_CLBK_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_RADIO_CSMA_TMR_CBK == 1)
|
||||
RT_DEBUG_RADIO_CSMA_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_RADIO_CSMA_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_RADIO_CSL_RCV_TMR_CBK == 1)
|
||||
RT_DEBUG_RADIO_CSL_RCV_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_RADIO_CSL_RCV_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ED_TMR_CBK == 1)
|
||||
RT_DEBUG_ED_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_ED_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_DIO_EXT_TMR_CBK == 1)
|
||||
RT_DEBUG_DIO_EXT_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_DIO_EXT_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_RCO_CLBR_TMR_CBK == 1)
|
||||
RT_DEBUG_RCO_CLBR_TMR_CBK,
|
||||
#endif /* USE_RT_DEBUG_RCO_CLBR_TMR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_MNGR_ADV_CBK == 1)
|
||||
RT_DEBUG_ADV_EXT_MNGR_ADV_CBK,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_MNGR_ADV_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_MNGR_SCN_CBK == 1)
|
||||
RT_DEBUG_ADV_EXT_MNGR_SCN_CBK,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_MNGR_SCN_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_MNGR_SCN_ERR_CBK == 1)
|
||||
RT_DEBUG_ADV_EXT_MNGR_SCN_ERR_CBK,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_MNGR_SCN_ERR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_MNGR_PRDC_SCN_CBK == 1)
|
||||
RT_DEBUG_ADV_EXT_MNGR_PRDC_SCN_CBK,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_MNGR_PRDC_SCN_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_MNGR_PRDC_SCN_ERR_CBK == 1)
|
||||
RT_DEBUG_ADV_EXT_MNGR_PRDC_SCN_ERR_CBK,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_MNGR_PRDC_SCN_ERR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_BIG_ADV_CBK == 1)
|
||||
RT_DEBUG_BIG_ADV_CBK,
|
||||
#endif /* USE_RT_DEBUG_BIG_ADV_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_BIG_ADV_ERR_CBK == 1)
|
||||
RT_DEBUG_BIG_ADV_ERR_CBK,
|
||||
#endif /* USE_RT_DEBUG_BIG_ADV_ERR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_BIG_SYNC_CBK == 1)
|
||||
RT_DEBUG_BIG_SYNC_CBK,
|
||||
#endif /* USE_RT_DEBUG_BIG_SYNC_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_BIG_SYNC_ERR_CBK == 1)
|
||||
RT_DEBUG_BIG_SYNC_ERR_CBK,
|
||||
#endif /* USE_RT_DEBUG_BIG_SYNC_ERR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ISO_CIS_PKT_TRNSM_RECEIVED_CBK == 1)
|
||||
RT_DEBUG_ISO_CIS_PKT_TRNSM_RECEIVED_CBK,
|
||||
#endif /* USE_RT_DEBUG_ISO_CIS_PKT_TRNSM_RECEIVED_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ISO_CIG_ERR_CBK == 1)
|
||||
RT_DEBUG_ISO_CIG_ERR_CBK,
|
||||
#endif /* USE_RT_DEBUG_ISO_CIG_ERR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_CONN_PKT_TRNSM_RECEIVED_CBK == 1)
|
||||
RT_DEBUG_CONN_PKT_TRNSM_RECEIVED_CBK,
|
||||
#endif /* USE_RT_DEBUG_CONN_PKT_TRNSM_RECEIVED_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_PRDC_CLBR_EXTRL_CBK == 1)
|
||||
RT_DEBUG_PRDC_CLBR_EXTRL_CBK,
|
||||
#endif /* USE_RT_DEBUG_PRDC_CLBR_EXTRL_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_PTR_PRDC_ADV_SYNC_CBK == 1)
|
||||
RT_DEBUG_PTR_PRDC_ADV_SYNC_CBK,
|
||||
#endif /* USE_RT_DEBUG_PTR_PRDC_ADV_SYNC_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_NCONN_SCN_CBK == 1)
|
||||
RT_DEBUG_NCONN_SCN_CBK,
|
||||
#endif /* USE_RT_DEBUG_NCONN_SCN_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_NCONN_ADV_CBK == 1)
|
||||
RT_DEBUG_NCONN_ADV_CBK,
|
||||
#endif /* USE_RT_DEBUG_NCONN_ADV_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_NCONN_INIT_CBK == 1)
|
||||
RT_DEBUG_NCONN_INIT_CBK,
|
||||
#endif /* USE_RT_DEBUG_NCONN_INIT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ANT_RADIO_CMPLT_EVNT_CBK == 1)
|
||||
RT_DEBUG_ANT_RADIO_CMPLT_EVNT_CBK,
|
||||
#endif /* USE_RT_DEBUG_ANT_RADIO_CMPLT_EVNT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ANT_STACK_EVNT_CBK == 1)
|
||||
RT_DEBUG_ANT_STACK_EVNT_CBK,
|
||||
#endif /* USE_RT_DEBUG_ANT_STACK_EVNT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_PROCESS_TMOUT_EVNT_CBK == 1)
|
||||
RT_DEBUG_ADV_EXT_PROCESS_TMOUT_EVNT_CBK,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_PROCESS_TMOUT_EVNT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_MNGR_SCN_DUR_EVNT == 1)
|
||||
RT_DEBUG_ADV_EXT_MNGR_SCN_DUR_EVNT,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_MNGR_SCN_DUR_EVNT */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_MNGR_SCN_PERIODIC_EVNT == 1)
|
||||
RT_DEBUG_ADV_EXT_MNGR_SCN_PERIODIC_EVNT,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_MNGR_SCN_PERIODIC_EVNT */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_MNGR_PRDC_SCN_TMOUT_EVNT == 1)
|
||||
RT_DEBUG_ADV_EXT_MNGR_PRDC_SCN_TMOUT_EVNT,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_MNGR_PRDC_SCN_TMOUT_EVNT */
|
||||
|
||||
#if (USE_RT_DEBUG_ADV_EXT_MNGR_PRDC_SCN_CNCEL_EVNT == 1)
|
||||
RT_DEBUG_ADV_EXT_MNGR_PRDC_SCN_CNCEL_EVNT,
|
||||
#endif /* USE_RT_DEBUG_ADV_EXT_MNGR_PRDC_SCN_CNCEL_EVNT */
|
||||
|
||||
#if (USE_RT_DEBUG_BIS_MNGR_BIG_TERM_CBK == 1)
|
||||
RT_DEBUG_BIS_MNGR_BIG_TERM_CBK,
|
||||
#endif /* USE_RT_DEBUG_BIS_MNGR_BIG_TERM_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_BIS_MNGR_SYNC_TMOUT_CBK == 1)
|
||||
RT_DEBUG_BIS_MNGR_SYNC_TMOUT_CBK,
|
||||
#endif /* USE_RT_DEBUG_BIS_MNGR_SYNC_TMOUT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ISOAL_MNGR_SDU_GEN == 1)
|
||||
RT_DEBUG_ISOAL_MNGR_SDU_GEN,
|
||||
#endif /* USE_RT_DEBUG_ISOAL_MNGR_SDU_GEN */
|
||||
|
||||
#if (USE_RT_DEBUG_ISO_MNGR_CIS_PROCESS_EVNT_CBK == 1)
|
||||
RT_DEBUG_ISO_MNGR_CIS_PROCESS_EVNT_CBK,
|
||||
#endif /* USE_RT_DEBUG_ISO_MNGR_CIS_PROCESS_EVNT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_CONN_MNGR_PROCESS_EVNT_CLBK == 1)
|
||||
RT_DEBUG_CONN_MNGR_PROCESS_EVNT_CLBK,
|
||||
#endif /* USE_RT_DEBUG_CONN_MNGR_PROCESS_EVNT_CLBK */
|
||||
|
||||
#if (USE_RT_DEBUG_CONN_MNGR_UPDT_CONN_PARAM_CBK == 1)
|
||||
RT_DEBUG_CONN_MNGR_UPDT_CONN_PARAM_CBK,
|
||||
#endif /* USE_RT_DEBUG_CONN_MNGR_UPDT_CONN_PARAM_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_EVNT_SCHDLR_HW_EVNT_CMPLT == 1)
|
||||
RT_DEBUG_EVNT_SCHDLR_HW_EVNT_CMPLT,
|
||||
#endif /* USE_RT_DEBUG_EVNT_SCHDLR_HW_EVNT_CMPLT */
|
||||
|
||||
#if (USE_RT_DEBUG_HCI_EVENT_HNDLR == 1)
|
||||
RT_DEBUG_HCI_EVENT_HNDLR,
|
||||
#endif /* USE_RT_DEBUG_HCI_EVENT_HNDLR */
|
||||
|
||||
#if (USE_RT_DEBUG_MLME_TMRS_CBK == 1)
|
||||
RT_DEBUG_MLME_TMRS_CBK,
|
||||
#endif /* USE_RT_DEBUG_MLME_TMRS_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_DIRECT_TX_EVNT_CBK == 1)
|
||||
RT_DEBUG_DIRECT_TX_EVNT_CBK,
|
||||
#endif /* USE_RT_DEBUG_DIRECT_TX_EVNT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_INDIRECT_PKT_TOUR_CBK == 1)
|
||||
RT_DEBUG_INDIRECT_PKT_TOUR_CBK,
|
||||
#endif /* USE_RT_DEBUG_INDIRECT_PKT_TOUR_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_RADIO_CSMA_TMR == 1)
|
||||
RT_DEBUG_RADIO_CSMA_TMR,
|
||||
#endif /* USE_RT_DEBUG_RADIO_CSMA_TMR */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_SM_DONE_EVNT_CBK == 1)
|
||||
RT_DEBUG_RAL_SM_DONE_EVNT_CBK,
|
||||
#endif /* USE_RT_DEBUG_RAL_SM_DONE_EVNT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_ED_TMR_HNDL == 1)
|
||||
RT_DEBUG_ED_TMR_HNDL,
|
||||
#endif /* USE_RT_DEBUG_ED_TMR_HNDL */
|
||||
|
||||
#if (USE_RT_DEBUG_OS_TMR_EVNT_CBK == 1)
|
||||
RT_DEBUG_OS_TMR_EVNT_CBK,
|
||||
#endif /* USE_RT_DEBUG_OS_TMR_EVNT_CBK */
|
||||
|
||||
#if (USE_RT_DEBUG_PROFILE_MARKER_PHY_WAKEUP_TIME == 1)
|
||||
RT_DEBUG_PROFILE_MARKER_PHY_WAKEUP_TIME,
|
||||
#endif /* USE_RT_DEBUG_PROFILE_MARKER_PHY_WAKEUP_TIME */
|
||||
|
||||
#if (USE_RT_DEBUG_PROFILE_END_DRIFT_TIME == 1)
|
||||
RT_DEBUG_PROFILE_END_DRIFT_TIME,
|
||||
#endif /* USE_RT_DEBUG_PROFILE_END_DRIFT_TIME */
|
||||
|
||||
#if (USE_RT_DEBUG_PROC_RADIO_RCV == 1)
|
||||
RT_DEBUG_PROC_RADIO_RCV,
|
||||
#endif /* USE_RT_DEBUG_PROC_RADIO_RCV */
|
||||
|
||||
#if (USE_RT_DEBUG_EVNT_TIME_UPDT == 1)
|
||||
RT_DEBUG_EVNT_TIME_UPDT,
|
||||
#endif /* USE_RT_DEBUG_EVNT_TIME_UPDT */
|
||||
|
||||
#if (USE_RT_DEBUG_MAC_RECEIVE_DONE == 1)
|
||||
RT_DEBUG_MAC_RECEIVE_DONE,
|
||||
#endif /* USE_RT_DEBUG_MAC_RECEIVE_DONE */
|
||||
|
||||
#if (USE_RT_DEBUG_MAC_TX_DONE == 1)
|
||||
RT_DEBUG_MAC_TX_DONE,
|
||||
#endif /* USE_RT_DEBUG_MAC_TX_DONE */
|
||||
|
||||
#if (USE_RT_DEBUG_RADIO_APPLY_CSMA == 1)
|
||||
RT_DEBUG_RADIO_APPLY_CSMA,
|
||||
#endif /* USE_RT_DEBUG_RADIO_APPLY_CSMA */
|
||||
|
||||
#if (USE_RT_DEBUG_RADIO_TRANSMIT == 1)
|
||||
RT_DEBUG_RADIO_TRANSMIT,
|
||||
#endif /* USE_RT_DEBUG_RADIO_TRANSMIT */
|
||||
|
||||
#if (USE_RT_DEBUG_PROC_RADIO_TX == 1)
|
||||
RT_DEBUG_PROC_RADIO_TX,
|
||||
#endif /* USE_RT_DEBUG_PROC_RADIO_TX */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_TX_DONE == 1)
|
||||
RT_DEBUG_RAL_TX_DONE,
|
||||
#endif /* USE_RT_DEBUG_RAL_TX_DONE */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_TX_DONE_INCREMENT_BACKOFF_COUNT == 1)
|
||||
RT_DEBUG_RAL_TX_DONE_INCREMENT_BACKOFF_COUNT,
|
||||
#endif /* USE_RT_DEBUG_RAL_TX_DONE_INCREMENT_BACKOFF_COUNT */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_TX_DONE_RST_BACKOFF_COUNT == 1)
|
||||
RT_DEBUG_RAL_TX_DONE_RST_BACKOFF_COUNT,
|
||||
#endif /* USE_RT_DEBUG_RAL_TX_DONE_RST_BACKOFF_COUNT */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_CONTINUE_RX == 1)
|
||||
RT_DEBUG_RAL_CONTINUE_RX,
|
||||
#endif /* USE_RT_DEBUG_RAL_CONTINUE_RX */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_PERFORM_CCA == 1)
|
||||
RT_DEBUG_RAL_PERFORM_CCA,
|
||||
#endif /* USE_RT_DEBUG_RAL_PERFORM_CCA */
|
||||
|
||||
#if (USE_RT_DEBUG_RAL_ENABLE_TRANSMITTER == 1)
|
||||
RT_DEBUG_RAL_ENABLE_TRANSMITTER,
|
||||
#endif /* USE_RT_DEBUG_RAL_ENABLE_TRANSMITTER */
|
||||
|
||||
#if (USE_RT_DEBUG_LLHWC_GET_CH_IDX_ALGO_2 == 1)
|
||||
RT_DEBUG_LLHWC_GET_CH_IDX_ALGO_2,
|
||||
#endif /* USE_RT_DEBUG_LLHWC_GET_CH_IDX_ALGO_2 */
|
||||
|
||||
#if (USE_RT_DEBUG_BACK_FROM_DEEP_SLEEP == 1)
|
||||
RT_DEBUG_BACK_FROM_DEEP_SLEEP,
|
||||
#endif /* USE_RT_DEBUG_BACK_FROM_DEEP_SLEEP */
|
||||
|
||||
#include "app_debug_signal_def.h"
|
||||
|
||||
RT_DEBUG_SIGNALS_TOTAL_NUM
|
||||
} rt_debug_signal_t;
|
||||
|
||||
#endif /* CFG_RT_DEBUG_GPIO_MODULE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DEBUG_SIGNALS_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file serial_cmd_interpreter.c
|
||||
* @author MCD Application Team
|
||||
* @brief Source file for the serial commands interpreter module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "log_module.h"
|
||||
#include "app_conf.h"
|
||||
#include "stm32_adv_trace.h"
|
||||
#include "serial_cmd_interpreter.h"
|
||||
|
||||
/* Private includes -----------------------------------------------------------*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#define RX_BUFF_SIZE (256U)
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
static uint8_t RxBuffer[RX_BUFF_SIZE];
|
||||
static uint16_t indexRxBuffer = 0;
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
|
||||
/* Private functions prototypes ----------------------------------------------*/
|
||||
static void UART_Rx_Callback(uint8_t *PData, uint16_t Size, uint8_t Error);
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
void Serial_CMD_Interpreter_Init(void)
|
||||
{
|
||||
/* Init Communication reception. Need that Log/Traces are activated */
|
||||
UTIL_ADV_TRACE_StartRxProcess(UART_Rx_Callback);
|
||||
}
|
||||
|
||||
__weak void Serial_CMD_Interpreter_CmdExecute( uint8_t * pRxBuffer, uint16_t iRxBufferSize )
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the enter_standby_notification could be implemented in the user file
|
||||
*/
|
||||
|
||||
/*
|
||||
This user function is in charge of interpreting the received data.
|
||||
|
||||
Here is an example of how to use them.
|
||||
In this simple case, we'll generate a SW IT on GPIO14 if the received data is a string "TEST".
|
||||
Add the following code into the user code section :
|
||||
|
||||
// Extended line handler on which we will generate the IT
|
||||
EXTI_HandleTypeDef exti_handle;
|
||||
|
||||
// Check RxBuffer's content to know if we're matching our case
|
||||
if( strcmp( (char const*)pRxBuffer, "TEST" ) == 0 )
|
||||
{
|
||||
LOG_INFO_APP("TEST has been received in Uart_Cmd_Execute.\n");
|
||||
exti_handle.Line = EXTI_LINE_14;
|
||||
HAL_EXTI_GenerateSWI(&exti_handle);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/* Private functions definition ----------------------------------------------*/
|
||||
static void UART_Rx_Callback( uint8_t * pData, uint16_t Size, uint8_t Error )
|
||||
{
|
||||
/* Filling buffer and wait for '\r' charactere to execute actions */
|
||||
if ( indexRxBuffer < RX_BUFF_SIZE )
|
||||
{
|
||||
if ( *pData == '\r' )
|
||||
{
|
||||
Serial_CMD_Interpreter_CmdExecute( RxBuffer, indexRxBuffer );
|
||||
|
||||
/* Clear receive buffer and character counter*/
|
||||
indexRxBuffer = 0;
|
||||
memset( &RxBuffer[0], 0, RX_BUFF_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ( * pData == '\n' ) && ( indexRxBuffer == 0 ) )
|
||||
{
|
||||
/* discard this first charactere if it's a delimiter */
|
||||
}
|
||||
else
|
||||
{
|
||||
RxBuffer[indexRxBuffer++] = *pData;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
indexRxBuffer = 0;
|
||||
memset(&RxBuffer[0], 0, RX_BUFF_SIZE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file serial_cmd_interpreter.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file for the serial commands interpreter module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef SERIAL_CMD_INTERPRETER_H
|
||||
#define SERIAL_CMD_INTERPRETER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void Serial_CMD_Interpreter_Init(void);
|
||||
void Serial_CMD_Interpreter_CmdExecute( uint8_t * pRxBuffer, uint16_t iRxBufferSize );
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SERIAL_CMD_INTERPRETER_H */
|
||||
@@ -0,0 +1,892 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file adc_ctrl.c
|
||||
* @author MCD Application Team
|
||||
* @brief Source file for ADC controller module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
/* Utilities */
|
||||
#include "utilities_common.h"
|
||||
|
||||
/* Real time trace for debug */
|
||||
#include "RTDebug.h"
|
||||
|
||||
/* Own header files */
|
||||
#include "adc_ctrl.h"
|
||||
#include "adc_ctrl_conf.h"
|
||||
|
||||
/* LL ADC header */
|
||||
#include "stm32wbaxx_ll_adc.h"
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Initial value define for configuration tracking number
|
||||
*/
|
||||
#define ADCCTRL_NO_CONFIG (uint32_t)(0x00000000u)
|
||||
|
||||
/**
|
||||
* @brief Init variable out of expected ADC conversion data range
|
||||
*/
|
||||
#define VAR_CONVERTED_DATA_INIT_VALUE_12B (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B) + 1)
|
||||
#define VAR_CONVERTED_DATA_INIT_VALUE_10B (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_10B) + 1)
|
||||
#define VAR_CONVERTED_DATA_INIT_VALUE_8B (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_8B) + 1)
|
||||
#define VAR_CONVERTED_DATA_INIT_VALUE_6B (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_6B) + 1)
|
||||
|
||||
/**
|
||||
* @brief Internal temperature sensor, parameter V30 (unit: mV).
|
||||
*
|
||||
* @details Refer to device datasheet for min/typ/max values.
|
||||
*
|
||||
*/
|
||||
#define TEMPSENSOR_TYP_CAL1_V (( int32_t) 760)
|
||||
|
||||
/**
|
||||
* @brief Internal temperature sensor, parameter Avg_Slope (unit: uV/DegCelsius).
|
||||
*
|
||||
* @details Refer to device datasheet for min/typ/max values.
|
||||
*
|
||||
*/
|
||||
#define TEMPSENSOR_TYP_AVGSLOPE (( int32_t) 2500)
|
||||
|
||||
/* Definitions of environment analog values */
|
||||
/**
|
||||
* @brief Value of analog reference voltage (Vref+), connected to analog voltage
|
||||
*
|
||||
* @details supply Vdda (unit: mV).
|
||||
*
|
||||
*/
|
||||
#define VDDA_APPLI (3300UL)
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/**
|
||||
* @brief ADC IP Client list
|
||||
*/
|
||||
static uint32_t ClientList;
|
||||
|
||||
/**
|
||||
* @brief Tracker of the current applied configuration
|
||||
*/
|
||||
static uint32_t CurrentConfig = ADCCTRL_NO_CONFIG;
|
||||
|
||||
/**
|
||||
* @brief Higher registered handle ID
|
||||
*/
|
||||
static uint32_t MaxRegisteredId = ADCCTRL_NO_CONFIG;
|
||||
|
||||
/**
|
||||
* @brief Handle of the ADC
|
||||
*/
|
||||
static ADC_TypeDef * p_ADCHandle = ADCCTRL_HWADDR;
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
/* Error Handler */
|
||||
extern void Error_Handler(void);
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/**
|
||||
* @brief Activate ADC.
|
||||
* Activation order is as follow:
|
||||
* - Enable ADC peripharal clock
|
||||
* - Enable ADC internal voltage regulator
|
||||
* - Enable ADC
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static inline void AdcActivate (void);
|
||||
|
||||
/**
|
||||
* @brief Deactivate ADC IP.
|
||||
* Deactivation order is as follow:
|
||||
* - Disable ADC
|
||||
* - Disable ADC internal voltage regulator
|
||||
* - Disable ADC peripharal clock
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static inline void AdcDeactivate (void);
|
||||
|
||||
/**
|
||||
* @brief Configure ADC IP.
|
||||
* @param p_Handle: Handle to work with
|
||||
* @retval State of the configuration
|
||||
*/
|
||||
static inline ADCCTRL_Cmd_Status_t AdcConfigure (const ADCCTRL_Handle_t * const p_Handle);
|
||||
|
||||
/**
|
||||
* @brief Read the raw value
|
||||
* @param p_Handle: Handle to work with
|
||||
* @return Raw value
|
||||
*/
|
||||
static inline uint16_t AdcReadRaw (const ADCCTRL_Handle_t * const p_Handle);
|
||||
|
||||
/**
|
||||
* @brief Perform ADC group regular conversion start, poll for conversion
|
||||
* completion.
|
||||
* (ADCCTRL_HWADDR instance: ADC).
|
||||
* @note This function does not perform ADC group regular conversion stop:
|
||||
* intended to be used with ADC in single mode, trigger SW start
|
||||
* (only 1 ADC conversion done at each trigger, no conversion stop
|
||||
* needed).
|
||||
* In case of continuous mode or conversion trigger set to
|
||||
* external trigger, ADC group regular conversion stop must be added.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static inline void ConversionStartPoll_ADC_GrpRegular (void);
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
__WEAK ADCCTRL_Cmd_Status_t ADCCTRL_Init (void)
|
||||
{
|
||||
ADCCTRL_Cmd_Status_t error = ADCCTRL_UNKNOWN;
|
||||
|
||||
/* Try to take the ADC mutex */
|
||||
error = ADCCTRL_MutexTake ();
|
||||
|
||||
if (ADCCTRL_OK == error)
|
||||
{
|
||||
CurrentConfig = ADCCTRL_NO_CONFIG;
|
||||
|
||||
p_ADCHandle = ADCCTRL_HWADDR;
|
||||
|
||||
/* Reset ADC Client list */
|
||||
ClientList = 0x00u;
|
||||
|
||||
/* Deactivate the ADC */
|
||||
AdcDeactivate();
|
||||
|
||||
/* Release the mutex */
|
||||
ADCCTRL_MutexRelease ();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
__WEAK ADCCTRL_Cmd_Status_t ADCCTRL_RegisterHandle (ADCCTRL_Handle_t * const p_Handle)
|
||||
{
|
||||
ADCCTRL_Cmd_Status_t error = ADCCTRL_UNKNOWN;
|
||||
|
||||
if (NULL == p_Handle)
|
||||
{
|
||||
error = ADCCTRL_ERROR_NULL_POINTER;
|
||||
}
|
||||
else if (ADCCTRL_HANDLE_REG == p_Handle->State)
|
||||
{
|
||||
error = ADCCTRL_HANDLE_ALREADY_REGISTERED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try to take the ADC mutex */
|
||||
error = ADCCTRL_MutexTake ();
|
||||
|
||||
if (ADCCTRL_OK == error)
|
||||
{
|
||||
/* Update the maximum registered handle */
|
||||
MaxRegisteredId = MaxRegisteredId + 1u;
|
||||
/* Update the handle UUID */
|
||||
p_Handle->Uid = MaxRegisteredId;
|
||||
/* Set handle as initialized */
|
||||
p_Handle->State = ADCCTRL_HANDLE_REG;
|
||||
|
||||
/* Release the mutex */
|
||||
ADCCTRL_MutexRelease ();
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
__WEAK ADCCTRL_Cmd_Status_t ADCCTRL_RequestIpState (const ADCCTRL_Handle_t * const p_Handle,
|
||||
const ADCCTRL_Ip_State_t State)
|
||||
{
|
||||
ADCCTRL_Cmd_Status_t error = ADCCTRL_UNKNOWN;
|
||||
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
|
||||
if (ADC_OFF == State)
|
||||
{
|
||||
ClientList &= (~(1U << p_Handle->Uid));
|
||||
|
||||
error = ADCCTRL_OK;
|
||||
}
|
||||
else if (ADC_ON == State)
|
||||
{
|
||||
ClientList |= (1U << p_Handle->Uid);
|
||||
|
||||
error = ADCCTRL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = ADCCTRL_ERROR_STATE;
|
||||
}
|
||||
|
||||
if (0x00u == ClientList)
|
||||
{
|
||||
/* Disable ADC as there is no request anymore */
|
||||
AdcDeactivate();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enable ADC as there at least one request */
|
||||
AdcActivate();
|
||||
}
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
__WEAK ADCCTRL_Cmd_Status_t ADCCTRL_RequestRawValue (const ADCCTRL_Handle_t * const p_Handle,
|
||||
uint16_t * const p_ReadValue)
|
||||
{
|
||||
ADCCTRL_Cmd_Status_t error = ADCCTRL_UNKNOWN;
|
||||
|
||||
/* Null pointer for handle or payload */
|
||||
if ((NULL == p_Handle) || (NULL == p_ReadValue))
|
||||
{
|
||||
error = ADCCTRL_ERROR_NULL_POINTER;
|
||||
}
|
||||
/* Handle not init */
|
||||
else if (ADCCTRL_HANDLE_NOT_REG == p_Handle->State)
|
||||
{
|
||||
error = ADCCTRL_HANDLE_NOT_REGISTERED;
|
||||
}
|
||||
/* Handle not in the range */
|
||||
else if ((MaxRegisteredId < p_Handle->Uid) ||
|
||||
(ADCCTRL_NO_CONFIG >= p_Handle->Uid))
|
||||
{
|
||||
error = ADCCTRL_HANDLE_NOT_VALID;
|
||||
}
|
||||
/* Check ADC state */
|
||||
else if (0x00u == (ClientList & (1U << p_Handle->Uid)))
|
||||
{
|
||||
error = ADCCTRL_ERROR_STATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try to take the ADC mutex */
|
||||
error = ADCCTRL_MutexTake ();
|
||||
|
||||
if (ADCCTRL_OK == error)
|
||||
{
|
||||
/* Is the current config IS NOT the same as the one requested ? */
|
||||
if (CurrentConfig != p_Handle->Uid)
|
||||
{
|
||||
/* Configure the ADC before use */
|
||||
error = AdcConfigure (p_Handle);
|
||||
|
||||
/* Enable ADC */
|
||||
LL_ADC_Enable(p_ADCHandle);
|
||||
}
|
||||
|
||||
if (ADCCTRL_OK == error)
|
||||
{
|
||||
/* Return the read value */
|
||||
*p_ReadValue = AdcReadRaw (p_Handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = ADCCTRL_ERROR_CONFIG;
|
||||
}
|
||||
|
||||
/* Release the mutex */
|
||||
ADCCTRL_MutexRelease ();
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
__WEAK ADCCTRL_Cmd_Status_t ADCCTRL_RequestTemperature (const ADCCTRL_Handle_t * const p_Handle,
|
||||
int16_t * const p_ReadValue)
|
||||
{
|
||||
ADCCTRL_Cmd_Status_t error = ADCCTRL_UNKNOWN;
|
||||
|
||||
/* Variables for ADC conversion data */
|
||||
__IO uint16_t uhADCxConvertedData = 0x00;
|
||||
|
||||
SYSTEM_DEBUG_SIGNAL_SET(ADC_TEMPERATURE_ACQUISITION);
|
||||
|
||||
/* Null pointer for handle or payload */
|
||||
if ((NULL == p_Handle) || (NULL == p_ReadValue))
|
||||
{
|
||||
error = ADCCTRL_ERROR_NULL_POINTER;
|
||||
}
|
||||
/* Handle not init */
|
||||
else if (ADCCTRL_HANDLE_NOT_REG == p_Handle->State)
|
||||
{
|
||||
error = ADCCTRL_HANDLE_NOT_REGISTERED;
|
||||
}
|
||||
/* Handle not in the range */
|
||||
else if ((MaxRegisteredId < p_Handle->Uid) ||
|
||||
(ADCCTRL_NO_CONFIG >= p_Handle->Uid))
|
||||
{
|
||||
error = ADCCTRL_HANDLE_NOT_VALID;
|
||||
}
|
||||
/* Check ADC state */
|
||||
else if (0x00u == (ClientList & (1U << p_Handle->Uid)))
|
||||
{
|
||||
error = ADCCTRL_ERROR_STATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try to take the ADC mutex */
|
||||
error = ADCCTRL_MutexTake ();
|
||||
|
||||
if (ADCCTRL_OK == error)
|
||||
{
|
||||
/* Is the current config IS NOT the same as the one requested ? */
|
||||
if (CurrentConfig != p_Handle->Uid)
|
||||
{
|
||||
/* Configure the ADC before use */
|
||||
error = AdcConfigure (p_Handle);
|
||||
|
||||
/* Enable ADC */
|
||||
LL_ADC_Enable(p_ADCHandle);
|
||||
}
|
||||
|
||||
if (ADCCTRL_OK == error)
|
||||
{
|
||||
/* Return the read value */
|
||||
uhADCxConvertedData = AdcReadRaw (p_Handle);
|
||||
|
||||
/* Computation of ADC conversions raw data to physical values */
|
||||
/* using LL ADC driver helper macro. */
|
||||
if(*TEMPSENSOR_CAL1_ADDR == *TEMPSENSOR_CAL2_ADDR)
|
||||
{
|
||||
/* Case of samples not calibrated in production */
|
||||
*p_ReadValue = __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS (TEMPSENSOR_TYP_AVGSLOPE,
|
||||
TEMPSENSOR_TYP_CAL1_V,
|
||||
TEMPSENSOR_CAL1_TEMP,
|
||||
VDDA_APPLI,
|
||||
uhADCxConvertedData,
|
||||
p_Handle->InitConf.ConvParams.Resolution);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Case of samples calibrated in production */
|
||||
*p_ReadValue = __LL_ADC_CALC_TEMPERATURE (VDDA_APPLI,
|
||||
uhADCxConvertedData,
|
||||
p_Handle->InitConf.ConvParams.Resolution);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = ADCCTRL_ERROR_CONFIG;
|
||||
}
|
||||
|
||||
/* Release the mutex */
|
||||
ADCCTRL_MutexRelease ();
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
__WEAK ADCCTRL_Cmd_Status_t ADCCTRL_RequestCoreVoltage (const ADCCTRL_Handle_t * const p_Handle,
|
||||
uint16_t * const p_ReadValue)
|
||||
{
|
||||
ADCCTRL_Cmd_Status_t error = ADCCTRL_UNKNOWN;
|
||||
|
||||
/* Variables for ADC conversion data */
|
||||
__IO uint16_t uhADCxConvertedData = 0x00;
|
||||
|
||||
SYSTEM_DEBUG_SIGNAL_SET(ADC_TEMPERATURE_ACQUISITION);
|
||||
|
||||
/* Null pointer for handle or payload */
|
||||
if ((NULL == p_Handle) || (NULL == p_ReadValue))
|
||||
{
|
||||
error = ADCCTRL_ERROR_NULL_POINTER;
|
||||
}
|
||||
/* Handle not init */
|
||||
else if (ADCCTRL_HANDLE_NOT_REG == p_Handle->State)
|
||||
{
|
||||
error = ADCCTRL_HANDLE_NOT_REGISTERED;
|
||||
}
|
||||
/* Handle not in the range */
|
||||
else if ((MaxRegisteredId < p_Handle->Uid) ||
|
||||
(ADCCTRL_NO_CONFIG >= p_Handle->Uid))
|
||||
{
|
||||
error = ADCCTRL_HANDLE_NOT_VALID;
|
||||
}
|
||||
/* Check ADC state */
|
||||
else if (0x00u == (ClientList & (1U << p_Handle->Uid)))
|
||||
{
|
||||
error = ADCCTRL_ERROR_STATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try to take the ADC mutex */
|
||||
error = ADCCTRL_MutexTake ();
|
||||
|
||||
if (ADCCTRL_OK == error)
|
||||
{
|
||||
/* Is the current config IS NOT the same as the one requested ? */
|
||||
if (CurrentConfig != p_Handle->Uid)
|
||||
{
|
||||
/* Configure the ADC before use */
|
||||
error = AdcConfigure (p_Handle);
|
||||
|
||||
/* Enable ADC */
|
||||
LL_ADC_Enable(p_ADCHandle);
|
||||
}
|
||||
|
||||
if (ADCCTRL_OK == error)
|
||||
{
|
||||
/* Return the read value */
|
||||
uhADCxConvertedData = AdcReadRaw (p_Handle);
|
||||
|
||||
/* Computation of ADC conversions raw data to physical values */
|
||||
/* using LL ADC driver helper macro. */
|
||||
*p_ReadValue = __LL_ADC_CALC_DATA_TO_VOLTAGE (VDDA_APPLI,
|
||||
uhADCxConvertedData,
|
||||
p_Handle->InitConf.ConvParams.Resolution);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = ADCCTRL_ERROR_CONFIG;
|
||||
}
|
||||
|
||||
/* Release the mutex */
|
||||
ADCCTRL_MutexRelease ();
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
__WEAK ADCCTRL_Cmd_Status_t ADCCTRL_RequestRefVoltage (const ADCCTRL_Handle_t * const p_Handle,
|
||||
uint16_t * const p_ReadValue)
|
||||
{
|
||||
ADCCTRL_Cmd_Status_t error = ADCCTRL_UNKNOWN;
|
||||
|
||||
/* Variables for ADC conversion data */
|
||||
__IO uint16_t uhADCxConvertedData = 0x00;
|
||||
|
||||
SYSTEM_DEBUG_SIGNAL_SET(ADC_TEMPERATURE_ACQUISITION);
|
||||
|
||||
/* Null pointer for handle or payload */
|
||||
if ((NULL == p_Handle) || (NULL == p_ReadValue))
|
||||
{
|
||||
error = ADCCTRL_ERROR_NULL_POINTER;
|
||||
}
|
||||
/* Handle not init */
|
||||
else if (ADCCTRL_HANDLE_NOT_REG == p_Handle->State)
|
||||
{
|
||||
error = ADCCTRL_HANDLE_NOT_REGISTERED;
|
||||
}
|
||||
/* Handle not in the range */
|
||||
else if ((MaxRegisteredId < p_Handle->Uid) ||
|
||||
(ADCCTRL_NO_CONFIG >= p_Handle->Uid))
|
||||
{
|
||||
error = ADCCTRL_HANDLE_NOT_VALID;
|
||||
}
|
||||
/* Check ADC state */
|
||||
else if (0x00u == (ClientList & (1U << p_Handle->Uid)))
|
||||
{
|
||||
error = ADCCTRL_ERROR_STATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try to take the ADC mutex */
|
||||
error = ADCCTRL_MutexTake ();
|
||||
|
||||
if (ADCCTRL_OK == error)
|
||||
{
|
||||
/* Is the current config IS NOT the same as the one requested ? */
|
||||
if (CurrentConfig != p_Handle->Uid)
|
||||
{
|
||||
/* Configure the ADC before use */
|
||||
error = AdcConfigure (p_Handle);
|
||||
|
||||
/* Enable ADC */
|
||||
LL_ADC_Enable(p_ADCHandle);
|
||||
}
|
||||
|
||||
if (ADCCTRL_OK == error)
|
||||
{
|
||||
/* Return the read value */
|
||||
uhADCxConvertedData = AdcReadRaw (p_Handle);
|
||||
|
||||
/* Computation of ADC conversions raw data to physical values */
|
||||
/* using LL ADC driver helper macro. */
|
||||
*p_ReadValue = __LL_ADC_CALC_VREFANALOG_VOLTAGE (uhADCxConvertedData,
|
||||
p_Handle->InitConf.ConvParams.Resolution);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = ADCCTRL_ERROR_CONFIG;
|
||||
}
|
||||
|
||||
/* Release the mutex */
|
||||
ADCCTRL_MutexRelease ();
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Private function Definition -----------------------------------------------*/
|
||||
void AdcActivate (void)
|
||||
{
|
||||
__IO uint32_t backup_setting_adc_dma_transfer = 0U;
|
||||
|
||||
SYSTEM_DEBUG_SIGNAL_SET(ADC_ACTIVATION);
|
||||
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
|
||||
/*## Operation on ADC hierarchical scope: ADC instance #####################*/
|
||||
|
||||
/* Note: Hardware constraint (refer to description of the functions */
|
||||
/* below): */
|
||||
/* On this STM32 series, setting of these features is conditioned to */
|
||||
/* ADC state: */
|
||||
/* ADC must be disabled. */
|
||||
/* Note: In this example, all these checks are not necessary but are */
|
||||
/* implemented anyway to show the best practice usages */
|
||||
/* corresponding to reference manual procedure. */
|
||||
/* Software can be optimized by removing some of these checks, if */
|
||||
/* they are not relevant considering previous settings and actions */
|
||||
/* in user application. */
|
||||
if (LL_ADC_IsEnabled(p_ADCHandle) == 0)
|
||||
{
|
||||
/* Select clock source */
|
||||
ADCTCTRL_SET_CLOCK_SOURCE ();
|
||||
|
||||
/* Peripheral clock enable */
|
||||
ADCCTRL_ENABLE_CLOCK ();
|
||||
|
||||
/* Enable ADC internal voltage regulator */
|
||||
LL_ADC_EnableInternalRegulator(p_ADCHandle);
|
||||
|
||||
/* Waiting for ADC internal voltage regulator stabilization. */
|
||||
while(LL_ADC_IsInternalRegulatorEnabled(p_ADCHandle) == 0);
|
||||
|
||||
/* Disable ADC DMA transfer request during calibration */
|
||||
/* Note: Specificity of this STM32 series: Calibration factor is */
|
||||
/* available in data register and also transferred by DMA. */
|
||||
/* To not insert ADC calibration factor among ADC conversion data */
|
||||
/* in DMA destination address, DMA transfer must be disabled during */
|
||||
/* calibration. */
|
||||
backup_setting_adc_dma_transfer = LL_ADC_REG_GetDMATransfer(p_ADCHandle);
|
||||
LL_ADC_REG_SetDMATransfer(p_ADCHandle, LL_ADC_REG_DMA_TRANSFER_NONE);
|
||||
|
||||
/* Run ADC self calibration */
|
||||
LL_ADC_StartCalibration(p_ADCHandle);
|
||||
|
||||
/* Poll for ADC effectively calibrated */
|
||||
while (LL_ADC_IsCalibrationOnGoing(p_ADCHandle) != 0);
|
||||
|
||||
/* Restore ADC DMA transfer request after calibration */
|
||||
LL_ADC_REG_SetDMATransfer(p_ADCHandle, backup_setting_adc_dma_transfer);
|
||||
|
||||
/* Delay required between ADC end of calibration and ADC enable */
|
||||
/* LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES --> 2 cycles */
|
||||
__asm("mov r0, r0");
|
||||
__asm("mov r0, r0");
|
||||
|
||||
/* Enable ADC */
|
||||
LL_ADC_Enable(p_ADCHandle);
|
||||
|
||||
/* Poll for ADC ready to convert */
|
||||
while (LL_ADC_IsActiveFlag_ADRDY(p_ADCHandle) == 0);
|
||||
|
||||
/* Note: ADC flag ADRDY is not cleared here to be able to check ADC */
|
||||
/* status afterwards. */
|
||||
/* This flag should be cleared at ADC Deactivation, before a new */
|
||||
/* ADC activation, using function "LL_ADC_ClearFlag_ADRDY()". */
|
||||
}
|
||||
|
||||
/*## Operation on ADC hierarchical scope: ADC group regular ################*/
|
||||
/* Note: No operation on ADC group regular performed here. */
|
||||
/* ADC group regular conversions to be performed after this function */
|
||||
/* using function: */
|
||||
/* "LL_ADC_REG_StartConversion();" */
|
||||
|
||||
/*## Operation on ADC hierarchical scope: ADC group injected ###############*/
|
||||
/* Note: Feature not available on this STM32 series */
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION();
|
||||
|
||||
SYSTEM_DEBUG_SIGNAL_RESET(ADC_ACTIVATION);
|
||||
}
|
||||
|
||||
void AdcDeactivate (void)
|
||||
{
|
||||
SYSTEM_DEBUG_SIGNAL_SET(ADC_DEACTIVATION);
|
||||
|
||||
UTILS_ENTER_CRITICAL_SECTION();
|
||||
|
||||
if(LL_ADC_IsEnabled(p_ADCHandle))
|
||||
{
|
||||
/* Disable ADC */
|
||||
LL_ADC_Disable(p_ADCHandle);
|
||||
|
||||
/* Clear flag ADC ready */
|
||||
LL_ADC_ClearFlag_ADRDY(p_ADCHandle);
|
||||
|
||||
/* Wait until ADC_CR_ADEN bit is reset before turning off ADC internal regulator */
|
||||
while(LL_ADC_IsEnabled(p_ADCHandle) == 1UL);
|
||||
|
||||
/* Wait until ADC_CR_ADSTP bit is reset before turning off ADC internal regulator */
|
||||
while(LL_ADC_REG_IsStopConversionOngoing(p_ADCHandle) == 1U);
|
||||
|
||||
/* Disable ADC internal voltage regulator */
|
||||
LL_ADC_DisableInternalRegulator(p_ADCHandle);
|
||||
while(LL_ADC_IsInternalRegulatorEnabled(p_ADCHandle) == 1U);
|
||||
|
||||
/* Peripharal clock disable */
|
||||
ADCCTRL_DISABLE_CLOCK ();
|
||||
}
|
||||
|
||||
UTILS_EXIT_CRITICAL_SECTION();
|
||||
|
||||
SYSTEM_DEBUG_SIGNAL_RESET(ADC_DEACTIVATION);
|
||||
}
|
||||
|
||||
ADCCTRL_Cmd_Status_t AdcConfigure (const ADCCTRL_Handle_t * const p_Handle)
|
||||
{
|
||||
ADCCTRL_Cmd_Status_t error = ADCCTRL_OK;
|
||||
|
||||
__IO uint32_t backup_setting_adc_dma_transfer = 0U;
|
||||
|
||||
LL_ADC_InitTypeDef ADC_InitStruct = {0};
|
||||
LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
|
||||
|
||||
/* DeInit the ADC module */
|
||||
if (SUCCESS != LL_ADC_DeInit (p_ADCHandle))
|
||||
{
|
||||
error = ADCCTRL_NOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Restart a calibration */
|
||||
/* Disable ADC DMA transfer request during calibration */
|
||||
/* Note: Specificity of this STM32 series: Calibration factor is */
|
||||
/* available in data register and also transferred by DMA. */
|
||||
/* To not insert ADC calibration factor among ADC conversion data */
|
||||
/* in DMA destination address, DMA transfer must be disabled during */
|
||||
/* calibration. */
|
||||
backup_setting_adc_dma_transfer = LL_ADC_REG_GetDMATransfer(p_ADCHandle);
|
||||
LL_ADC_REG_SetDMATransfer(p_ADCHandle, LL_ADC_REG_DMA_TRANSFER_NONE);
|
||||
|
||||
/* Run ADC self calibration */
|
||||
LL_ADC_StartCalibration(p_ADCHandle);
|
||||
|
||||
/* Poll for ADC effectively calibrated */
|
||||
while (LL_ADC_IsCalibrationOnGoing(p_ADCHandle) != 0);
|
||||
|
||||
/* Restore ADC DMA transfer request after calibration */
|
||||
LL_ADC_REG_SetDMATransfer(p_ADCHandle, backup_setting_adc_dma_transfer);
|
||||
|
||||
/* Delay required between ADC end of calibration and ADC enable */
|
||||
/* LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES --> 2 cycles */
|
||||
__asm("mov r0, r0");
|
||||
__asm("mov r0, r0");
|
||||
}
|
||||
|
||||
/* All OK ? */
|
||||
if (ADCCTRL_OK == error)
|
||||
{
|
||||
/* Update init and configuration parameters with requested values */
|
||||
ADC_InitStruct.Resolution = p_Handle->InitConf.ConvParams.Resolution;
|
||||
ADC_InitStruct.DataAlignment = p_Handle->InitConf.ConvParams.DataAlign;
|
||||
|
||||
ADC_REG_InitStruct.TriggerSource = p_Handle->InitConf.ConvParams.TriggerStart;
|
||||
ADC_REG_InitStruct.SequencerLength = p_Handle->InitConf.SeqParams.Length;
|
||||
ADC_REG_InitStruct.SequencerDiscont = p_Handle->InitConf.SeqParams.DiscMode;
|
||||
ADC_REG_InitStruct.ContinuousMode = p_Handle->InitConf.ConvParams.ConversionMode;
|
||||
ADC_REG_InitStruct.DMATransfer = p_Handle->InitConf.ConvParams.DmaTransfer;
|
||||
ADC_REG_InitStruct.Overrun = p_Handle->InitConf.ConvParams.Overrun;
|
||||
|
||||
/* Configure Regular Channel - Only for internal channels */
|
||||
if (LL_ADC_CHANNEL_VREFINT == p_Handle->ChannelConf.Channel)
|
||||
{
|
||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(p_ADCHandle),
|
||||
LL_ADC_PATH_INTERNAL_VREFINT);
|
||||
}
|
||||
else if (LL_ADC_CHANNEL_TEMPSENSOR == p_Handle->ChannelConf.Channel)
|
||||
{
|
||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(p_ADCHandle),
|
||||
LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(p_ADCHandle),
|
||||
LL_ADC_PATH_INTERNAL_NONE);
|
||||
}
|
||||
|
||||
/* Set trigger frequency */
|
||||
LL_ADC_SetTriggerFrequencyMode(p_ADCHandle,
|
||||
p_Handle->InitConf.ConvParams.TriggerFrequencyMode);
|
||||
|
||||
/* Apply the requested ADC configuration - Init part */
|
||||
if (SUCCESS != LL_ADC_Init(p_ADCHandle,
|
||||
&ADC_InitStruct))
|
||||
{
|
||||
error = ADCCTRL_NOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set Sequencer if configurable */
|
||||
LL_ADC_REG_SetSequencerConfigurable(p_ADCHandle,
|
||||
p_Handle->InitConf.SeqParams.Setup);
|
||||
|
||||
/* Apply the requested ADC configuration - Register init part */
|
||||
if (SUCCESS != LL_ADC_REG_Init(p_ADCHandle,
|
||||
&ADC_REG_InitStruct))
|
||||
{
|
||||
error = ADCCTRL_NOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set Low power characteristics */
|
||||
LL_ADC_SetLPModeAutoPowerOff(p_ADCHandle,
|
||||
p_Handle->InitConf.LowPowerParams.AutoPowerOff);
|
||||
LL_ADC_SetLPModeAutonomousDPD(p_ADCHandle,
|
||||
p_Handle->InitConf.LowPowerParams.AutonomousDPD);
|
||||
|
||||
/* Set Sampling time for channels */
|
||||
LL_ADC_SetSamplingTimeCommonChannels(p_ADCHandle,
|
||||
LL_ADC_SAMPLINGTIME_COMMON_1,
|
||||
p_Handle->InitConf.ConvParams.SamplingTimeCommon1);
|
||||
LL_ADC_SetSamplingTimeCommonChannels(p_ADCHandle,
|
||||
LL_ADC_SAMPLINGTIME_COMMON_2,
|
||||
p_Handle->InitConf.ConvParams.SamplingTimeCommon2);
|
||||
|
||||
/* Configure the channel */
|
||||
LL_ADC_REG_SetSequencerRanks(p_ADCHandle,
|
||||
p_Handle->ChannelConf.Rank,
|
||||
p_Handle->ChannelConf.Channel);
|
||||
LL_ADC_SetChannelSamplingTime(p_ADCHandle,
|
||||
p_Handle->ChannelConf.Channel,
|
||||
p_Handle->ChannelConf.SamplingTime);
|
||||
|
||||
/* Update the current configuration */
|
||||
CurrentConfig = p_Handle->Uid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
uint16_t AdcReadRaw (const ADCCTRL_Handle_t * const p_Handle)
|
||||
{
|
||||
/* Variables for ADC conversion data */
|
||||
__IO uint16_t uhADCxConvertedData = 0x00;
|
||||
|
||||
/* Perform ADC group regular conversion start, poll for conversion */
|
||||
/* completion. */
|
||||
ConversionStartPoll_ADC_GrpRegular ();
|
||||
|
||||
/* Retrieve ADC conversion data */
|
||||
switch (p_Handle->InitConf.ConvParams.Resolution)
|
||||
{
|
||||
case LL_ADC_RESOLUTION_12B:
|
||||
{
|
||||
uhADCxConvertedData = VAR_CONVERTED_DATA_INIT_VALUE_12B;
|
||||
|
||||
uhADCxConvertedData = LL_ADC_REG_ReadConversionData12(p_ADCHandle);
|
||||
|
||||
break;
|
||||
}
|
||||
case LL_ADC_RESOLUTION_10B:
|
||||
{
|
||||
uhADCxConvertedData = VAR_CONVERTED_DATA_INIT_VALUE_10B;
|
||||
|
||||
uhADCxConvertedData = LL_ADC_REG_ReadConversionData10(p_ADCHandle);
|
||||
|
||||
break;
|
||||
}
|
||||
case LL_ADC_RESOLUTION_8B:
|
||||
{
|
||||
uhADCxConvertedData = VAR_CONVERTED_DATA_INIT_VALUE_8B;
|
||||
|
||||
uhADCxConvertedData = LL_ADC_REG_ReadConversionData8(p_ADCHandle);
|
||||
|
||||
break;
|
||||
}
|
||||
case LL_ADC_RESOLUTION_6B:
|
||||
{
|
||||
uhADCxConvertedData = VAR_CONVERTED_DATA_INIT_VALUE_6B;
|
||||
|
||||
uhADCxConvertedData = LL_ADC_REG_ReadConversionData6(p_ADCHandle);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* Do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return uhADCxConvertedData;
|
||||
}
|
||||
|
||||
void ConversionStartPoll_ADC_GrpRegular (void)
|
||||
{
|
||||
|
||||
/* Start ADC group regular conversion */
|
||||
/* Note: Hardware constraint (refer to description of the function */
|
||||
/* below): */
|
||||
/* On this STM32 series, setting of this feature is conditioned to */
|
||||
/* ADC state: */
|
||||
/* ADC must be enabled without conversion on going on group regular, */
|
||||
/* without ADC disable command on going. */
|
||||
/* Note: In this example, all these checks are not necessary but are */
|
||||
/* implemented anyway to show the best practice usages */
|
||||
/* corresponding to reference manual procedure. */
|
||||
/* Software can be optimized by removing some of these checks, if */
|
||||
/* they are not relevant considering previous settings and actions */
|
||||
/* in user application. */
|
||||
if ((LL_ADC_IsEnabled(p_ADCHandle) == 1) &&
|
||||
(LL_ADC_IsDisableOngoing(p_ADCHandle) == 0) &&
|
||||
(LL_ADC_REG_IsConversionOngoing(p_ADCHandle) == 0) )
|
||||
{
|
||||
LL_ADC_REG_StartConversion(p_ADCHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error: ADC conversion start could not be performed */
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
while (LL_ADC_IsActiveFlag_EOC(p_ADCHandle) == 0);
|
||||
|
||||
/* Clear flag ADC group regular end of unitary conversion */
|
||||
/* Note: This action is not needed here, because flag ADC group regular */
|
||||
/* end of unitary conversion is cleared automatically when */
|
||||
/* software reads conversion data from ADC data register. */
|
||||
/* Nevertheless, this action is done anyway to show how to clear */
|
||||
/* this flag, needed if conversion data is not always read */
|
||||
/* or if group injected end of unitary conversion is used (for */
|
||||
/* devices with group injected available). */
|
||||
LL_ADC_ClearFlag_EOC(p_ADCHandle);
|
||||
}
|
||||
|
||||
/* Weak function Definition --------------------------------------------------*/
|
||||
__WEAK ADCCTRL_Cmd_Status_t ADCCTRL_MutexTake (void)
|
||||
{
|
||||
return ADCCTRL_OK;
|
||||
}
|
||||
|
||||
__WEAK ADCCTRL_Cmd_Status_t ADCCTRL_MutexRelease (void)
|
||||
{
|
||||
return ADCCTRL_OK;
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file adc_ctrl.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for ADC client manager module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ADC_CTRL_H
|
||||
#define ADC_CTRL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Utilities */
|
||||
#include "utilities_common.h"
|
||||
|
||||
/* Exported defines ----------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief ADC command status codes
|
||||
*/
|
||||
typedef enum ADCCTRL_Cmd_Status
|
||||
{
|
||||
ADCCTRL_OK,
|
||||
ADCCTRL_NOK,
|
||||
ADCCTRL_BUSY,
|
||||
ADCCTRL_HANDLE_ALREADY_REGISTERED,
|
||||
ADCCTRL_HANDLE_NOT_REGISTERED,
|
||||
ADCCTRL_HANDLE_NOT_VALID,
|
||||
ADCCTRL_ERROR_NULL_POINTER,
|
||||
ADCCTRL_ERROR_CONFIG,
|
||||
ADCCTRL_ERROR_STATE,
|
||||
ADCCTRL_UNKNOWN,
|
||||
} ADCCTRL_Cmd_Status_t;
|
||||
|
||||
/**
|
||||
* @brief ADC IP state
|
||||
*/
|
||||
typedef enum ADCCTRL_Ip_State
|
||||
{
|
||||
ADC_OFF,
|
||||
ADC_ON
|
||||
} ADCCTRL_Ip_State_t;
|
||||
|
||||
/**
|
||||
* @brief ADC handle states
|
||||
*/
|
||||
typedef enum ADCCTRL_HandleState
|
||||
{
|
||||
ADCCTRL_HANDLE_NOT_REG,
|
||||
ADCCTRL_HANDLE_REG,
|
||||
} ADCCTRL_HandleState_t;
|
||||
|
||||
/**
|
||||
* @brief ADC Init configuration structure - Conversion parameters
|
||||
*/
|
||||
typedef struct ADCCTRL_ConvParameters
|
||||
{
|
||||
uint32_t TriggerFrequencyMode; /*!< Set ADC Trigger frequency mode.
|
||||
This parameter can be a value of @ref ADC_LL_EC_REG_TRIGGER_FREQ */
|
||||
|
||||
uint32_t Resolution; /*!< Configure the ADC resolution.
|
||||
This parameter can be a value of @ref ADC_LL_EC_RESOLUTION */
|
||||
|
||||
uint32_t DataAlign; /*!< Specify ADC data alignment in conversion data register (right or left).
|
||||
This parameter can be a value of @ref ADC_LL_EC_DATA_ALIGN */
|
||||
|
||||
uint32_t TriggerStart; /*!< Select the source used to trigger ADC conversion
|
||||
start.
|
||||
This parameter can be a value of @ref ADC_LL_EC_REG_TRIGGER_SOURCE.*/
|
||||
|
||||
uint32_t TriggerEdge; /*!< Select the Edge used for trigger.
|
||||
This parameter can be a value of @ref ADC_LL_EC_REG_TRIGGER_EDGE.*/
|
||||
|
||||
uint32_t ConversionMode; /*!< Configure the conversion mode of ADC.
|
||||
This parameter can be a value of @ref ADC_LL_EC_REG_CONTINUOUS_MODE */
|
||||
|
||||
uint32_t DmaTransfer; /*!< DMA transfer of ADC conversion data.
|
||||
This parameter can be a value of @ref ADC_LL_EC_REG_DMA_TRANSFER */
|
||||
|
||||
uint32_t Overrun; /*!< Select the behavior in case of overrun: data overwritten or preserved (default).
|
||||
This parameter can be a value of @ref ADC_LL_EC_REG_OVR_DATA_BEHAVIOR. */
|
||||
|
||||
uint32_t SamplingTimeCommon1; /*!< Set sampling time common to a group of channels.
|
||||
This parameter can be a value of @ref ADC_LL_EC_CHANNEL_SAMPLINGTIME */
|
||||
|
||||
uint32_t SamplingTimeCommon2; /*!< Set sampling time common to a group of channels, second common setting possible.
|
||||
This parameter can be a value of @ref ADC_LL_EC_CHANNEL_SAMPLINGTIME */
|
||||
}ADCCTRL_ConvParameters_t;
|
||||
|
||||
/**
|
||||
* @brief ADC Init configuration structure - Sequencer parameters
|
||||
*/
|
||||
typedef struct ADCCTRL_SeqParameters
|
||||
{
|
||||
uint32_t Setup; /*!< Set ADC sequencer configuration flexibility.
|
||||
This parameter can be a value of @ref ADC_LL_EC_REG_SEQ_MODE */
|
||||
|
||||
uint32_t Length; /*!< Set ADC sequencer scan length.
|
||||
This parameter can be a value of @ref ADC_LL_EC_REG_SEQ_SCAN_LENGTH */
|
||||
|
||||
uint32_t DiscMode; /*!< Set ADC sequencer discontinuous mode.
|
||||
This parameter can be a value of @ref ADC_LL_EC_REG_SEQ_DISCONT_MODE */
|
||||
}ADCCTRL_SeqParameters_t;
|
||||
|
||||
/**
|
||||
* @brief ADC Init configuration structure - Low power parameters
|
||||
*/
|
||||
typedef struct ADCCTRL_LowPowerParameters
|
||||
{
|
||||
FunctionalState AutoPowerOff; /*!< Enable or Disable ADC Auto Power OFF mode.
|
||||
This parameter can be set to ENABLE or DISABLE */
|
||||
|
||||
uint32_t AutonomousDPD; /*!< Enable or Disable ADC Autonomous Deep Power Down Mode.
|
||||
This parameter can be a value of @ref ADC_LL_EC_AUTONOMOUS_DEEP_POWER_DOWN_MODE */
|
||||
}ADCCTRL_LowPowerParameters_t;
|
||||
|
||||
/**
|
||||
* @brief ADC Init configuration structure
|
||||
*/
|
||||
typedef struct ADCCTRL_InitConfig
|
||||
{
|
||||
ADCCTRL_ConvParameters_t ConvParams;
|
||||
ADCCTRL_SeqParameters_t SeqParams;
|
||||
ADCCTRL_LowPowerParameters_t LowPowerParams;
|
||||
} ADCCTRL_InitConfig_t;
|
||||
|
||||
/**
|
||||
* @brief ADC Channel configuration structure
|
||||
*/
|
||||
typedef struct ADCCTRL_ChannelConfig
|
||||
{
|
||||
uint32_t Channel; /*!< Specify the channel to configure into ADC regular group.
|
||||
This parameter can be a value of @ref ADC_LL_EC_CHANNEL */
|
||||
|
||||
uint32_t Rank; /*!< Add or remove the channel from ADC regular group sequencer and specify its
|
||||
conversion rank.
|
||||
This parameter can be a value of @ref ADC_LL_EC_REG_SEQ_RANKS */
|
||||
|
||||
uint32_t SamplingTime; /*!< Sampling time value to be set for the selected channel.
|
||||
This parameter can be a value of @ref ADC_LL_EC_SAMPLINGTIME_COMMON */
|
||||
} ADCCTRL_ChannelConfig_t;
|
||||
|
||||
/**
|
||||
* @brief ADC handle typedef
|
||||
*/
|
||||
typedef struct ADCCTRL_Handle
|
||||
{
|
||||
uint32_t Uid; /* Id of the Handle instance */
|
||||
ADCCTRL_HandleState_t State; /* State of the ADC Controller handle */
|
||||
ADCCTRL_InitConfig_t InitConf; /* Init configuration of the ADC */
|
||||
ADCCTRL_ChannelConfig_t ChannelConf; /* Channel configuration of the ADC */
|
||||
} ADCCTRL_Handle_t;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
/**
|
||||
* @brief Initialize the adc controller
|
||||
*
|
||||
* @retval State of the initialization
|
||||
*/
|
||||
ADCCTRL_Cmd_Status_t ADCCTRL_Init(void);
|
||||
|
||||
/**
|
||||
* @brief Register a ADC handle
|
||||
*
|
||||
* @param p_Handle: Handle to register
|
||||
*
|
||||
* @return State of the handle initialization
|
||||
*/
|
||||
ADCCTRL_Cmd_Status_t ADCCTRL_RegisterHandle (ADCCTRL_Handle_t * const p_Handle);
|
||||
|
||||
/**
|
||||
* @brief Request a specific state for the ADC IP - Either On or Off
|
||||
*
|
||||
* @param p_Handle: ADC handle
|
||||
* @param State: Requested state to apply
|
||||
*
|
||||
* @return State of the operation
|
||||
*/
|
||||
ADCCTRL_Cmd_Status_t ADCCTRL_RequestIpState (const ADCCTRL_Handle_t * const p_Handle,
|
||||
const ADCCTRL_Ip_State_t State);
|
||||
|
||||
/**
|
||||
* @brief Read raw value of the ADC
|
||||
*
|
||||
* @param p_Handle: ADC handle
|
||||
* @param p_ReadValue: Raw ADC value
|
||||
*
|
||||
* @retval Operation state
|
||||
*/
|
||||
ADCCTRL_Cmd_Status_t ADCCTRL_RequestRawValue (const ADCCTRL_Handle_t * const p_Handle,
|
||||
uint16_t * const p_ReadValue);
|
||||
|
||||
/**
|
||||
* @brief Read temperature from ADC temperature sensor
|
||||
*
|
||||
* @details The returned value is actual temperature sensor value
|
||||
*
|
||||
* @param p_Handle: ADC handle
|
||||
* @param p_ReadValue: Temperature measurement
|
||||
*
|
||||
* @retval Operation state
|
||||
*/
|
||||
ADCCTRL_Cmd_Status_t ADCCTRL_RequestTemperature (const ADCCTRL_Handle_t * const p_Handle,
|
||||
int16_t * const p_ReadValue);
|
||||
|
||||
/**
|
||||
* @brief Read Voltage from ADC
|
||||
*
|
||||
* @details The returned value is actual Voltage value in mVolts
|
||||
*
|
||||
* @param p_Handle: ADC handle
|
||||
* @param p_ReadValue: Core Voltage measurement
|
||||
*
|
||||
* @retval Operation state
|
||||
*/
|
||||
ADCCTRL_Cmd_Status_t ADCCTRL_RequestCoreVoltage (const ADCCTRL_Handle_t * const p_Handle,
|
||||
uint16_t * const p_ReadValue);
|
||||
|
||||
/**
|
||||
* @brief Read reference Voltage from ADC
|
||||
*
|
||||
* @details The returned value is actual reference Voltage value in mVolts
|
||||
*
|
||||
* @param p_Handle: ADC handle
|
||||
* @param p_ReadValue: Reference Voltage measurement
|
||||
*
|
||||
* @retval Operation state
|
||||
*/
|
||||
ADCCTRL_Cmd_Status_t ADCCTRL_RequestRefVoltage (const ADCCTRL_Handle_t * const p_Handle,
|
||||
uint16_t * const p_ReadValue);
|
||||
|
||||
/* Exported functions to be implemented by the user ------------------------- */
|
||||
/**
|
||||
* @brief Take ownership on the ADC mutex
|
||||
*
|
||||
* @details This function shall be implemented by the user
|
||||
*
|
||||
* @return Status of the command
|
||||
* @retval ADCCTRL_Cmd_Status_t::ADCCTRL_OK
|
||||
* @retval ADCCTRL_Cmd_Status_t::ADCCTRL_NOK
|
||||
*/
|
||||
extern ADCCTRL_Cmd_Status_t ADCCTRL_MutexTake (void);
|
||||
|
||||
/**
|
||||
* @brief Release ownership on the ADC mutex
|
||||
*
|
||||
* @details This function shall be implemented by the user
|
||||
*
|
||||
* @return Status of the command
|
||||
* @retval ADCCTRL_Cmd_Status_t::ADCCTRL_OK
|
||||
* @retval ADCCTRL_Cmd_Status_t::ADCCTRL_NOK
|
||||
*/
|
||||
extern ADCCTRL_Cmd_Status_t ADCCTRL_MutexRelease (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ADC_CTRL_H */
|
||||
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file app_sys.c
|
||||
* @author MCD Application Team
|
||||
* @brief Application system for STM32WPAN Middleware.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "app_sys.h"
|
||||
#include "app_conf.h"
|
||||
#include "timer_if.h"
|
||||
#include "stm32_lpm.h"
|
||||
#include "ll_intf.h"
|
||||
#include "ll_sys.h"
|
||||
#if (UTIL_LPM_LEGACY_ENABLED == 0)
|
||||
#include "stm32_lpm_if.h"
|
||||
#endif
|
||||
|
||||
#if MAC
|
||||
#include "ral.h"
|
||||
#endif
|
||||
|
||||
/* External functions --------------------------------------------------------*/
|
||||
extern uint32_t llhwc_cmn_is_dp_slp_enabled(void);
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
|
||||
/* Private variables --------------------------------------------------------*/
|
||||
static uint32_t wakeup_offset = RADIO_DEEPSLEEP_WAKEUP_TIME_US;
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
#if SUPPORT_BLE
|
||||
void APP_SYS_BLE_EnterDeepSleep(void)
|
||||
{
|
||||
ble_stat_t cmd_status;
|
||||
uint32_t radio_remaining_time = 0;
|
||||
|
||||
if (ll_sys_dp_slp_get_state() == LL_SYS_DP_SLP_DISABLED)
|
||||
{
|
||||
/* Enable radio to retrieve next radio activity */
|
||||
|
||||
/* Getting next radio event time if any */
|
||||
cmd_status = ll_intf_le_get_remaining_time_for_next_event(&radio_remaining_time);
|
||||
UNUSED(cmd_status);
|
||||
assert_param(cmd_status == SUCCESS);
|
||||
|
||||
if (radio_remaining_time == LL_DP_SLP_NO_WAKEUP)
|
||||
{
|
||||
/* No next radio event scheduled */
|
||||
(void)ll_sys_dp_slp_enter(LL_DP_SLP_NO_WAKEUP);
|
||||
}
|
||||
else if (radio_remaining_time > wakeup_offset)
|
||||
{
|
||||
/* No event in a "near" futur */
|
||||
(void)ll_sys_dp_slp_enter(radio_remaining_time - wakeup_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (UTIL_LPM_LEGACY_ENABLED == 1)
|
||||
UTIL_LPM_SetOffMode(1U << CFG_LPM_LL_DEEPSLEEP, UTIL_LPM_DISABLE);
|
||||
#else /* (UTIL_LPM_LEGACY_ENABLED == 1) */
|
||||
#if (CFG_LPM_STOP1_SUPPORTED == 1)
|
||||
UTIL_LPM_SetMaxMode(1U << CFG_LPM_LL_DEEPSLEEP, UTIL_LPM_STOP1_MODE);
|
||||
#else /* (CFG_LPM_STOP1_SUPPORTED == 1) */
|
||||
UTIL_LPM_SetMaxMode(1U << CFG_LPM_LL_DEEPSLEEP, UTIL_LPM_SLEEP_MODE);
|
||||
#endif /* (CFG_LPM_STOP1_SUPPORTED == 1) */
|
||||
#endif /* (UTIL_LPM_LEGACY_ENABLED == 1) */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else /* SUPPORT_BLE */
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void APP_SYS_LPM_EnterLowPowerMode(void)
|
||||
{
|
||||
ral_instance_t radio_instance;
|
||||
uint8_t channel;
|
||||
uint64_t next_radio_evt;
|
||||
|
||||
/* Ensure there are no radio events (implement bsp function like bsp_is_radio_idle() ) */
|
||||
ral_event_state_enum_t radio_state = ral_get_current_event_state( &radio_instance, &channel );
|
||||
LL_UNUSED(radio_instance);
|
||||
LL_UNUSED(channel);
|
||||
if (radio_state != RAL_IDLE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
next_radio_evt = os_timer_get_earliest_time();
|
||||
if ( llhwc_cmn_is_dp_slp_enabled() == 0 )
|
||||
{
|
||||
if ( next_radio_evt > wakeup_offset )
|
||||
{
|
||||
/* No event in a "near" futur */
|
||||
ll_sys_dp_slp_enter( next_radio_evt - wakeup_offset );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SUPPORT_BLE */
|
||||
|
||||
void APP_SYS_SetWakeupOffset(uint32_t wakeup_offset_us)
|
||||
{
|
||||
wakeup_offset = wakeup_offset_us;
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file crc_ctrl.c
|
||||
* @author MCD Application Team
|
||||
* @brief Source for CRC client controller module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
/* Utilities */
|
||||
#include "utilities_common.h"
|
||||
|
||||
/* Own header files */
|
||||
#include "crc_ctrl.h"
|
||||
#include "crc_ctrl_conf.h"
|
||||
|
||||
/* HAL CRC header */
|
||||
#include "stm32wbaxx_hal_crc.h"
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Initial value define for configuration tracking number
|
||||
*
|
||||
*/
|
||||
#define CRCCTRL_NO_CONFIG (uint32_t)(0x00000000u)
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Tracker of the current applied configuration
|
||||
*/
|
||||
static uint32_t CurrentConfig = CRCCTRL_NO_CONFIG;
|
||||
|
||||
/**
|
||||
* @brief Higher registered handle ID
|
||||
*/
|
||||
static uint32_t MaxRegisteredId = CRCCTRL_NO_CONFIG;
|
||||
|
||||
/**
|
||||
* @brief Handle of the HAL CRC
|
||||
*/
|
||||
static CRC_HandleTypeDef CRCHandle =
|
||||
{
|
||||
.Instance = CRCCTRL_HWADDR,
|
||||
};
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/**
|
||||
* @brief Configure CRC IP
|
||||
* @param p_Handle: CRC handle
|
||||
* @retval State of the configuration
|
||||
*/
|
||||
static inline HAL_StatusTypeDef CrcConfigure (CRCCTRL_Handle_t * const p_Handle);
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
__WEAK CRCCTRL_Cmd_Status_t CRCCTRL_Init (void)
|
||||
{
|
||||
CRCCTRL_Cmd_Status_t error = CRCCTRL_UNKNOWN;
|
||||
|
||||
/* Try to take the CRC mutex */
|
||||
error = CRCCTRL_MutexTake ();
|
||||
|
||||
if (CRCCTRL_OK == error)
|
||||
{
|
||||
CurrentConfig = CRCCTRL_NO_CONFIG;
|
||||
|
||||
CRCHandle.State = HAL_CRC_STATE_RESET;
|
||||
|
||||
CRCHandle.Instance = CRCCTRL_HWADDR;
|
||||
|
||||
/* Release the mutex */
|
||||
CRCCTRL_MutexRelease ();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
__WEAK CRCCTRL_Cmd_Status_t CRCCTRL_RegisterHandle (CRCCTRL_Handle_t * const p_Handle)
|
||||
{
|
||||
CRCCTRL_Cmd_Status_t error = CRCCTRL_UNKNOWN;
|
||||
|
||||
if (NULL == p_Handle)
|
||||
{
|
||||
error = CRCCTRL_ERROR_NULL_POINTER;
|
||||
}
|
||||
else if (HANDLE_REG == p_Handle->State)
|
||||
{
|
||||
error = CRCCTRL_HANDLE_ALREADY_REGISTERED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try to take the CRC mutex */
|
||||
error = CRCCTRL_MutexTake ();
|
||||
|
||||
if (CRCCTRL_OK == error)
|
||||
{
|
||||
/* Update the maximum registered handle */
|
||||
MaxRegisteredId = MaxRegisteredId + 1u;
|
||||
/* Update the handle UUID */
|
||||
p_Handle->Uid = MaxRegisteredId;
|
||||
/* Init the previous value */
|
||||
p_Handle->PreviousComputedValue = p_Handle->Configuration.InitValue;
|
||||
/* Set handle as initialized */
|
||||
p_Handle->State = HANDLE_REG;
|
||||
|
||||
/* Release the mutex */
|
||||
CRCCTRL_MutexRelease ();
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
__WEAK CRCCTRL_Cmd_Status_t CRCCTRL_Calculate (CRCCTRL_Handle_t * const p_Handle,
|
||||
uint32_t a_Payload[],
|
||||
const uint32_t PayloadSize,
|
||||
uint32_t * const p_ConmputedValue)
|
||||
{
|
||||
CRCCTRL_Cmd_Status_t error = CRCCTRL_UNKNOWN;
|
||||
HAL_StatusTypeDef eReturn = HAL_OK;
|
||||
|
||||
/* Null pointer for handle or payload */
|
||||
if ((NULL == p_Handle) || (NULL == a_Payload) || (NULL == p_ConmputedValue))
|
||||
{
|
||||
error = CRCCTRL_ERROR_NULL_POINTER;
|
||||
}
|
||||
/* Handle not init */
|
||||
else if (HANDLE_NOT_REG == p_Handle->State)
|
||||
{
|
||||
error = CRCCTRL_HANDLE_NOT_REGISTERED;
|
||||
}
|
||||
/* Handle not in the range */
|
||||
else if ((MaxRegisteredId < p_Handle->Uid) ||
|
||||
(CRCCTRL_NO_CONFIG >= p_Handle->Uid))
|
||||
{
|
||||
error = CRCCTRL_HANDLE_NOT_VALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try to take the CRC mutex */
|
||||
error = CRCCTRL_MutexTake ();
|
||||
|
||||
if (CRCCTRL_OK == error)
|
||||
{
|
||||
/* Is the current config IS NOT the same as the one requested ? */
|
||||
if (CurrentConfig != p_Handle->Uid)
|
||||
{
|
||||
/* Configure the CRC before use */
|
||||
eReturn = CrcConfigure (p_Handle);
|
||||
}
|
||||
|
||||
if (eReturn == HAL_OK)
|
||||
{
|
||||
*p_ConmputedValue = HAL_CRC_Calculate (&CRCHandle, a_Payload, PayloadSize);
|
||||
|
||||
/* Update the handle with the computed value */
|
||||
p_Handle->PreviousComputedValue = *p_ConmputedValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = CRCCTRL_ERROR_CONFIG;
|
||||
}
|
||||
|
||||
/* Release the mutex */
|
||||
CRCCTRL_MutexRelease ();
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
__WEAK CRCCTRL_Cmd_Status_t CRCCTRL_Accumulate (CRCCTRL_Handle_t * const p_Handle,
|
||||
uint32_t a_Payload[],
|
||||
const uint32_t PayloadSize,
|
||||
uint32_t * const p_ConmputedValue)
|
||||
{
|
||||
CRCCTRL_Cmd_Status_t error = CRCCTRL_UNKNOWN;
|
||||
|
||||
/* Null pointer for handle or payload */
|
||||
if ((NULL == p_Handle) || (NULL == a_Payload) || (NULL == p_ConmputedValue))
|
||||
{
|
||||
error = CRCCTRL_ERROR_NULL_POINTER;
|
||||
}
|
||||
/* Handle not init */
|
||||
else if (HANDLE_NOT_REG == p_Handle->State)
|
||||
{
|
||||
error = CRCCTRL_HANDLE_NOT_REGISTERED;
|
||||
}
|
||||
/* Handle not in the range */
|
||||
else if ((MaxRegisteredId < p_Handle->Uid) ||
|
||||
(CRCCTRL_NO_CONFIG >= p_Handle->Uid))
|
||||
{
|
||||
error = CRCCTRL_HANDLE_NOT_VALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try to take the CRC mutex */
|
||||
error = CRCCTRL_MutexTake ();
|
||||
|
||||
if (CRCCTRL_OK == error)
|
||||
{
|
||||
/* Check if the config has to change */
|
||||
if (CurrentConfig == p_Handle->Uid)
|
||||
{
|
||||
*p_ConmputedValue = HAL_CRC_Accumulate (&CRCHandle,
|
||||
a_Payload,
|
||||
PayloadSize);
|
||||
|
||||
/* Update the handle with the computed value */
|
||||
p_Handle->PreviousComputedValue = *p_ConmputedValue;
|
||||
}
|
||||
/* Configure the CRC before use */
|
||||
else if (HAL_OK == CrcConfigure (p_Handle))
|
||||
{
|
||||
/* Before starting the accumulation, the init register shall be written with the previous value */
|
||||
CRCHandle.Instance->INIT = p_Handle->PreviousComputedValue;
|
||||
|
||||
*p_ConmputedValue = HAL_CRC_Calculate (&CRCHandle,
|
||||
a_Payload,
|
||||
PayloadSize);
|
||||
|
||||
/* Update the handle with the computed value */
|
||||
p_Handle->PreviousComputedValue = *p_ConmputedValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = CRCCTRL_ERROR_CONFIG;
|
||||
}
|
||||
|
||||
/* Release the mutex */
|
||||
CRCCTRL_MutexRelease ();
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Private function Definition -----------------------------------------------*/
|
||||
HAL_StatusTypeDef CrcConfigure (CRCCTRL_Handle_t * const p_Handle)
|
||||
{
|
||||
HAL_StatusTypeDef error = HAL_OK;
|
||||
|
||||
/* No need to DeInit if the CRC if it is not yet initialized */
|
||||
if (HAL_CRC_STATE_RESET != CRCHandle.State)
|
||||
{
|
||||
/* DeInit the CRC module */
|
||||
error = HAL_CRC_DeInit(&CRCHandle);
|
||||
}
|
||||
|
||||
/* All OK ? */
|
||||
if (HAL_OK == error)
|
||||
{
|
||||
/* Fulfill the configuration part */
|
||||
CRCHandle.Init.CRCLength = p_Handle->Configuration.CRCLength;
|
||||
CRCHandle.Init.DefaultInitValueUse = p_Handle->Configuration.DefaultInitValueUse;
|
||||
CRCHandle.Init.DefaultPolynomialUse = p_Handle->Configuration.DefaultPolynomialUse;
|
||||
CRCHandle.Init.GeneratingPolynomial = p_Handle->Configuration.GeneratingPolynomial;
|
||||
CRCHandle.Init.InitValue = p_Handle->Configuration.InitValue;
|
||||
CRCHandle.Init.InputDataInversionMode = p_Handle->Configuration.InputDataInversionMode;
|
||||
CRCHandle.Init.OutputDataInversionMode = p_Handle->Configuration.OutputDataInversionMode;
|
||||
CRCHandle.InputDataFormat = p_Handle->Configuration.InputDataFormat;
|
||||
|
||||
/* Apply the requested CRC configuration */
|
||||
error = HAL_CRC_Init(&CRCHandle);
|
||||
|
||||
if (HAL_OK == error)
|
||||
{
|
||||
/* Update the current configuration */
|
||||
CurrentConfig = p_Handle->Uid;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There must be an issue with configuration, clean the configuration */
|
||||
memset ((void *)(&CRCHandle.Init),
|
||||
0x00,
|
||||
sizeof (CRC_InitTypeDef));
|
||||
|
||||
CRCHandle.InputDataFormat = 0x00u;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Weak function Definition --------------------------------------------------*/
|
||||
__WEAK CRCCTRL_Cmd_Status_t CRCCTRL_MutexTake (void)
|
||||
{
|
||||
return CRCCTRL_OK;
|
||||
}
|
||||
|
||||
__WEAK CRCCTRL_Cmd_Status_t CRCCTRL_MutexRelease (void)
|
||||
{
|
||||
return CRCCTRL_OK;
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file crc_ctrl.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for CRC client manager module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef CRC_CTRL_H
|
||||
#define CRC_CTRL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Utilities */
|
||||
#include "utilities_common.h"
|
||||
|
||||
/* HAL CRC header */
|
||||
#include "stm32wbaxx_hal_crc.h"
|
||||
|
||||
/* Exported defines ----------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief CRC command status codes
|
||||
*/
|
||||
typedef enum CRCCTRL_Cmd_Status
|
||||
{
|
||||
CRCCTRL_OK,
|
||||
CRCCTRL_NOK,
|
||||
CRCCTRL_BUSY,
|
||||
CRCCTRL_HANDLE_ALREADY_REGISTERED,
|
||||
CRCCTRL_HANDLE_NOT_REGISTERED,
|
||||
CRCCTRL_HANDLE_NOT_VALID,
|
||||
CRCCTRL_ERROR_NULL_POINTER,
|
||||
CRCCTRL_ERROR_CONFIG,
|
||||
CRCCTRL_UNKNOWN,
|
||||
} CRCCTRL_Cmd_Status_t;
|
||||
|
||||
/**
|
||||
* @brief CRC command status codes
|
||||
*/
|
||||
typedef enum CRCCTRL_HandleState
|
||||
{
|
||||
HANDLE_NOT_REG,
|
||||
HANDLE_REG,
|
||||
} CRCCTRL_HandleState_t;
|
||||
|
||||
/**
|
||||
* @brief CRC configuration structure
|
||||
*
|
||||
*/
|
||||
typedef struct CRCCTRL_Config
|
||||
{
|
||||
uint8_t DefaultPolynomialUse; /*!< This parameter is a value of @ref CRC_Default_Polynomial and indicates if default polynomial is used.
|
||||
If set to DEFAULT_POLYNOMIAL_ENABLE, resort to default
|
||||
X^32 + X^26 + X^23 + X^22 + X^16 + X^12 + X^11 + X^10 +X^8 + X^7 + X^5 +
|
||||
X^4 + X^2+ X +1.
|
||||
In that case, there is no need to set GeneratingPolynomial field.
|
||||
If otherwise set to DEFAULT_POLYNOMIAL_DISABLE, GeneratingPolynomial and
|
||||
CRCLength fields must be set. */
|
||||
|
||||
uint8_t DefaultInitValueUse; /*!< This parameter is a value of @ref CRC_Default_InitValue_Use and indicates if default init value is used.
|
||||
If set to DEFAULT_INIT_VALUE_ENABLE, resort to default
|
||||
0xFFFFFFFF value. In that case, there is no need to set InitValue field. If
|
||||
otherwise set to DEFAULT_INIT_VALUE_DISABLE, InitValue field must be set. */
|
||||
|
||||
uint32_t GeneratingPolynomial; /*!< Set CRC generating polynomial as a 7, 8, 16 or 32-bit long value for a polynomial degree
|
||||
respectively equal to 7, 8, 16 or 32. This field is written in normal,
|
||||
representation e.g., for a polynomial of degree 7, X^7 + X^6 + X^5 + X^2 + 1
|
||||
is written 0x65. No need to specify it if DefaultPolynomialUse is set to
|
||||
DEFAULT_POLYNOMIAL_ENABLE. */
|
||||
|
||||
uint32_t CRCLength; /*!< This parameter is a value of @ref CRC_Polynomial_Sizes and indicates CRC length.
|
||||
Value can be either one of
|
||||
@arg @ref CRC_POLYLENGTH_32B (32-bit CRC),
|
||||
@arg @ref CRC_POLYLENGTH_16B (16-bit CRC),
|
||||
@arg @ref CRC_POLYLENGTH_8B (8-bit CRC),
|
||||
@arg @ref CRC_POLYLENGTH_7B (7-bit CRC). */
|
||||
|
||||
uint32_t InitValue; /*!< Init value to initiate CRC computation. No need to specify it if DefaultInitValueUse
|
||||
is set to DEFAULT_INIT_VALUE_ENABLE. */
|
||||
|
||||
uint32_t InputDataInversionMode; /*!< This parameter is a value of @ref CRCEx_Input_Data_Inversion and specifies input data inversion mode.
|
||||
Can be either one of the following values
|
||||
@arg @ref CRC_INPUTDATA_INVERSION_NONE no input data inversion
|
||||
@arg @ref CRC_INPUTDATA_INVERSION_BYTE byte-wise inversion, 0x1A2B3C4D
|
||||
becomes 0x58D43CB2
|
||||
@arg @ref CRC_INPUTDATA_INVERSION_HALFWORD halfword-wise inversion,
|
||||
0x1A2B3C4D becomes 0xD458B23C
|
||||
@arg @ref CRC_INPUTDATA_INVERSION_WORD word-wise inversion, 0x1A2B3C4D
|
||||
becomes 0xB23CD458 */
|
||||
|
||||
uint32_t OutputDataInversionMode; /*!< This parameter is a value of @ref CRCEx_Output_Data_Inversion and specifies output data (i.e. CRC) inversion mode.
|
||||
Can be either
|
||||
@arg @ref CRC_OUTPUTDATA_INVERSION_DISABLE no CRC inversion,
|
||||
@arg @ref CRC_OUTPUTDATA_INVERSION_ENABLE CRC 0x11223344 is converted
|
||||
into 0x22CC4488 */
|
||||
|
||||
uint32_t InputDataFormat; /*!< This parameter is a value of @ref CRC_Input_Buffer_Format and specifies input data format.
|
||||
Can be either
|
||||
@arg @ref CRC_INPUTDATA_FORMAT_BYTES input data is a stream of bytes
|
||||
(8-bit data)
|
||||
@arg @ref CRC_INPUTDATA_FORMAT_HALFWORDS input data is a stream of
|
||||
half-words (16-bit data)
|
||||
@arg @ref CRC_INPUTDATA_FORMAT_WORDS input data is a stream of words
|
||||
(32-bit data)
|
||||
|
||||
Note that constant CRC_INPUT_FORMAT_UNDEFINED is defined but an initialization
|
||||
error must occur if InputBufferFormat is not one of the three values listed
|
||||
above */
|
||||
} CRCCTRL_Config_t;
|
||||
|
||||
typedef struct CRCCTRL_Handle
|
||||
{
|
||||
uint32_t Uid; /* Id of the Handle instance */
|
||||
uint32_t PreviousComputedValue; /* Previous CRC computed value for Accumulate purposes */
|
||||
CRCCTRL_HandleState_t State; /* State of the CRC Controller handle */
|
||||
CRCCTRL_Config_t Configuration; /* Configuration of the CRC */
|
||||
} CRCCTRL_Handle_t;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
/**
|
||||
* @brief Init the CRC Ctrl variables
|
||||
*
|
||||
* @return State of the handle initialization
|
||||
*/
|
||||
CRCCTRL_Cmd_Status_t CRCCTRL_Init (void);
|
||||
|
||||
/**
|
||||
* @brief Register a CRC handle
|
||||
*
|
||||
* @param p_Handle: Handle to register
|
||||
*
|
||||
* @return State of the handle registration
|
||||
*/
|
||||
CRCCTRL_Cmd_Status_t CRCCTRL_RegisterHandle (CRCCTRL_Handle_t * const p_Handle);
|
||||
|
||||
/**
|
||||
* @brief Compute the CRC of the given payload
|
||||
*
|
||||
* @param p_Handle: CRC handle
|
||||
* @param a_Payload: Address of the first payload element
|
||||
* @param PayloadSize: Size of the payload to compute the CRC
|
||||
* @param p_ComputedValue: Computed CRC (returned value LSBs for CRC shorter than 32 bits)
|
||||
*
|
||||
* @return State of the operation
|
||||
*/
|
||||
CRCCTRL_Cmd_Status_t CRCCTRL_Calculate (CRCCTRL_Handle_t * const p_Handle,
|
||||
uint32_t a_Payload[],
|
||||
const uint32_t PayloadSize,
|
||||
uint32_t * const p_ConmputedValue);
|
||||
|
||||
/**
|
||||
* @brief Keep computing the CRC of a given payload
|
||||
*
|
||||
* @details Computation starts with the previous computed CRC as initialization value.
|
||||
*
|
||||
* @details The CRCCTRL_Calculate shall be used before any call of this API.
|
||||
*
|
||||
* @param p_Handle: Address of the first payload element
|
||||
* @param a_Payload: Address of the first payload element
|
||||
* @param PayloadSize: Size of the payload to compute the CRC
|
||||
* @param p_ComputedValue: Computed CRC (returned value LSBs for CRC shorter than 32 bits)
|
||||
*
|
||||
* @return State of the operation
|
||||
*/
|
||||
CRCCTRL_Cmd_Status_t CRCCTRL_Accumulate (CRCCTRL_Handle_t * const p_Handle,
|
||||
uint32_t a_Payload[],
|
||||
const uint32_t PayloadSize,
|
||||
uint32_t * const p_ConmputedValue);
|
||||
|
||||
/* Exported functions to be implemented by the user ------------------------- */
|
||||
/**
|
||||
* @brief Take ownership on the CRC mutex
|
||||
*
|
||||
* @details This function shall be implemented by the user
|
||||
*
|
||||
* @return Status of the command
|
||||
* @retval CRCCTRL_Cmd_Status_t::CRCCTRL_OK
|
||||
* @retval CRCCTRL_Cmd_Status_t::CRCCTRL_NOK
|
||||
*/
|
||||
extern CRCCTRL_Cmd_Status_t CRCCTRL_MutexTake (void);
|
||||
|
||||
/**
|
||||
* @brief Release ownership on the CRC mutex
|
||||
*
|
||||
* @details This function shall be implemented by the user
|
||||
*
|
||||
* @return Status of the command
|
||||
* @retval CRCCTRL_Cmd_Status_t::CRCCTRL_OK
|
||||
* @retval CRCCTRL_Cmd_Status_t::CRCCTRL_NOK
|
||||
*/
|
||||
extern CRCCTRL_Cmd_Status_t CRCCTRL_MutexRelease (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CRC_CTRL_H */
|
||||
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file dbg_trace.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for dbg_trace.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef DBG_TRACE_H
|
||||
#define DBG_TRACE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
#if ( ( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 ) )
|
||||
#define PRINT_LOG_BUFF_DBG(...) DbgTraceBuffer(__VA_ARGS__)
|
||||
#if ( CFG_DEBUG_TRACE_FULL != 0 )
|
||||
#define PRINT_MESG_DBG(...) do{printf("\r\n [%s][%s][%d] ", DbgTraceGetFileName(__FILE__),__FUNCTION__,__LINE__);printf(__VA_ARGS__);}while(0);
|
||||
#else
|
||||
#define PRINT_MESG_DBG printf
|
||||
#endif
|
||||
#else
|
||||
#define PRINT_LOG_BUFF_DBG(...)
|
||||
#define PRINT_MESG_DBG(...)
|
||||
#endif
|
||||
|
||||
#define PRINT_NO_MESG(...)
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Request the user to initialize the peripheral to output traces
|
||||
*
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
extern void DbgOutputInit( void );
|
||||
|
||||
/**
|
||||
* @brief Request the user to sent the traces on the output peripheral
|
||||
*
|
||||
* @param p_data: Address of the buffer to be sent
|
||||
* @param size: Size of the data to be sent
|
||||
* @param cb: Function to be called when the data has been sent
|
||||
* @retval None
|
||||
*/
|
||||
extern void DbgOutputTraces( uint8_t *p_data, uint16_t size, void (*cb)(void) );
|
||||
|
||||
/**
|
||||
* @brief DbgTraceInit Initialize Logging feature.
|
||||
*
|
||||
* @param: None
|
||||
* @retval: None
|
||||
*/
|
||||
void DbgTraceInit( void );
|
||||
|
||||
/**********************************************************************************************************************/
|
||||
/** This function outputs into the log the buffer (in hex) and the provided format string and arguments.
|
||||
***********************************************************************************************************************
|
||||
*
|
||||
* @param pBuffer Buffer to be output into the logs.
|
||||
* @param u32Length Length of the buffer, in bytes.
|
||||
* @param strFormat The format string in printf() style.
|
||||
* @param ... Arguments of the format string.
|
||||
*
|
||||
**********************************************************************************************************************/
|
||||
void DbgTraceBuffer( const void *pBuffer , uint32_t u32Length , const char *strFormat , ... );
|
||||
|
||||
const char *DbgTraceGetFileName( const char *fullpath );
|
||||
|
||||
/**
|
||||
* @brief Override the standard lib function to redirect printf to USART.
|
||||
* @param handle output handle (STDIO, STDERR...)
|
||||
* @param buf buffer to write
|
||||
* @param bufsize buffer size
|
||||
* @retval Number of elements written
|
||||
*/
|
||||
size_t DbgTraceWrite(int handle, const unsigned char * buf, size_t bufSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DBG_TRACE_H */
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file otp.c
|
||||
* @author MCD HW Board & MCD Application Team
|
||||
* @brief Source file for One Time Programmable (OTP) area
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "otp.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
HAL_StatusTypeDef OTP_Read(uint8_t index, OTP_Data_s** otp_ptr)
|
||||
{
|
||||
*otp_ptr = (OTP_Data_s*) (FLASH_OTP_BASE + FLASH_OTP_SIZE - 16);
|
||||
|
||||
while ( (*otp_ptr)->index != index && (*otp_ptr) != (OTP_Data_s*) FLASH_OTP_BASE)
|
||||
{
|
||||
(*otp_ptr) -= 1;
|
||||
}
|
||||
|
||||
if ((*otp_ptr)->index != index)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef OTP_Write(uint8_t* additional_data, uint8_t* bd_address, uint8_t hsetune, uint8_t index)
|
||||
{
|
||||
HAL_StatusTypeDef err = HAL_ERROR;
|
||||
OTP_Data_s otp_data;
|
||||
int i;
|
||||
|
||||
/* Fill OTP_Data_s structure */
|
||||
for (i = 0; i < sizeof(otp_data.additional_data); i++)
|
||||
{
|
||||
otp_data.additional_data[i] = additional_data[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(otp_data.bd_address); i++)
|
||||
{
|
||||
otp_data.bd_address[i] = bd_address[i];
|
||||
}
|
||||
|
||||
otp_data.hsetune = hsetune;
|
||||
otp_data.index = index;
|
||||
|
||||
/* Find free space */
|
||||
uint32_t free_address = FLASH_OTP_BASE;
|
||||
while ( ( *(uint64_t*)(free_address) != 0xFFFFFFFFFFFFFFFFUL ) &&
|
||||
( *(uint64_t*)(free_address + 8) != 0xFFFFFFFFFFFFFFFFUL ) &&
|
||||
( (free_address + 16) != FLASH_OTP_BASE + FLASH_OTP_SIZE ) )
|
||||
{
|
||||
free_address += 16;
|
||||
}
|
||||
|
||||
if ( ( *(uint64_t*)(free_address) == 0xFFFFFFFFFFFFFFFFUL ) &&
|
||||
( *(uint64_t*)(free_address + 8) == 0xFFFFFFFFFFFFFFFFUL ) )
|
||||
{
|
||||
/* Store OTP structure in OTP area */
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); /* Clear all Flash flags before write operation*/
|
||||
|
||||
err = HAL_FLASH_Unlock();
|
||||
err |= HAL_FLASH_Program(FLASH_NSCR1_PG, free_address, (uint32_t) &otp_data);
|
||||
err |= HAL_FLASH_Lock();
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file otp.h
|
||||
* @author MCD HW Board & MCD Application Team
|
||||
* @brief Header file for One Time Programmable (OTP) area
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OTP_H
|
||||
#define OTP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "stm32wbaxx_hal.h"
|
||||
#include "cmsis_compiler.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
--------------------------------------------------------------------------------
|
||||
|LSB MSB|
|
||||
--------------------------------------------------------------------------------
|
||||
| additional_data 8-bytes | bd_address 6 bytes | hsetune 1 byte | index 1 byte |
|
||||
--------------------------------------------------------------------------------
|
||||
*/
|
||||
typedef __PACKED_STRUCT
|
||||
{
|
||||
uint8_t additional_data[8]; /*!< 64 bits of data to fill OTP slot Ex: MB184510 */
|
||||
uint8_t bd_address[6]; /*!< Bluetooth Device Address*/
|
||||
uint8_t hsetune; /*!< Load capacitance to be applied on HSE pad */
|
||||
uint8_t index; /*!< Structure index */
|
||||
} OTP_Data_s;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
#define DEFAULT_OTP_IDX 0
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported variables ------------------------------------------------------- */
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* * @brief Minimal code to use the OTP_Read function:
|
||||
*
|
||||
OTP_Data_s* otp_ptr = NULL;
|
||||
|
||||
if (OTP_Read(DEFAULT_OTP_IDX, &otp_ptr) != HAL_OK) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
uint64_t bd_addr = (uint64_t) otp_ptr->bd_address[0] |
|
||||
(uint64_t) otp_ptr->bd_address[1] << 8 |
|
||||
(uint64_t) otp_ptr->bd_address[2] << 16 |
|
||||
(uint64_t) otp_ptr->bd_address[3] << 24 |
|
||||
(uint64_t) otp_ptr->bd_address[4] << 32 |
|
||||
(uint64_t) otp_ptr->bd_address[5] << 40 ;
|
||||
|
||||
uint8_t hsetune = otp_ptr->hsetune;
|
||||
uint8_t index = otp_ptr->index;
|
||||
*/
|
||||
HAL_StatusTypeDef OTP_Read(uint8_t index, OTP_Data_s** data);
|
||||
|
||||
/**
|
||||
* @brief Write OTP
|
||||
*/
|
||||
HAL_StatusTypeDef OTP_Write(uint8_t* additional_data, uint8_t* bd_address, uint8_t hsetune, uint8_t index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OTP_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,286 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file scm.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for scm.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef SCM_H
|
||||
#define SCM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
#if (CFG_SCM_SUPPORTED == 1)
|
||||
#include "stm32wbaxx_hal.h"
|
||||
#include "stm32wbaxx_ll_pwr.h"
|
||||
#include "stm32wbaxx_ll_rcc.h"
|
||||
#include "stm32wbaxx_ll_tim.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
typedef enum {
|
||||
NO_CLOCK_CONFIG = 0,
|
||||
HSE_16MHZ,
|
||||
HSE_32MHZ,
|
||||
SYS_PLL,
|
||||
} scm_clockconfig_t;
|
||||
|
||||
typedef enum {
|
||||
LP,
|
||||
RUN,
|
||||
HSE16,
|
||||
HSE32,
|
||||
PLL,
|
||||
} scm_ws_lp_t;
|
||||
|
||||
typedef enum {
|
||||
HSEPRE_DISABLE = 0,
|
||||
HSEPRE_ENABLE
|
||||
} scm_hse_hsepre_t;
|
||||
|
||||
typedef enum {
|
||||
SCM_USER_APP,
|
||||
SCM_USER_LL_FW,
|
||||
SCM_USER_LL_HW_RCO_CLBR,
|
||||
TOTAL_CLIENT_NUM, /* To be at the end of the enum */
|
||||
} scm_user_id_t;
|
||||
|
||||
typedef enum {
|
||||
NO_PLL,
|
||||
PLL_INTEGER_MODE,
|
||||
PLL_FRACTIONAL_MODE,
|
||||
} scm_pll_mode_t;
|
||||
|
||||
typedef enum {
|
||||
SCM_RADIO_NOT_ACTIVE = 0,
|
||||
SCM_RADIO_ACTIVE,
|
||||
} scm_radio_state_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t are_pll_params_initialized;
|
||||
scm_pll_mode_t pll_mode;
|
||||
uint32_t PLLM;
|
||||
uint32_t PLLN;
|
||||
uint32_t PLLP;
|
||||
uint32_t PLLQ;
|
||||
uint32_t PLLR;
|
||||
uint32_t PLLFractional;
|
||||
uint32_t AHB5_PLL1_CLKDivider;
|
||||
} scm_pll_config_t;
|
||||
|
||||
typedef struct{
|
||||
scm_clockconfig_t targeted_clock_freq;
|
||||
uint32_t flash_ws_cfg;
|
||||
uint32_t sram_ws_cfg;
|
||||
scm_pll_config_t pll;
|
||||
} scm_system_clock_t;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief System Clock Manager init code
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void scm_init(void);
|
||||
|
||||
/**
|
||||
* @brief Setup the system clock source in usable configuration for Connectivity use cases.
|
||||
* Called at startup or out of low power modes.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void scm_setup(void);
|
||||
|
||||
/**
|
||||
* @brief Configure the PLL mode and parameters before PLL selection as system clock.
|
||||
* @param p_pll_config PLL coniguration to apply
|
||||
* @retval None
|
||||
* @note scm_pll_setconfig to be called before PLL activation (PLL set as system core clock)
|
||||
*/
|
||||
void scm_pll_setconfig(const scm_pll_config_t *p_pll_config);
|
||||
|
||||
/**
|
||||
* @brief Restore system clock configuration when moving out of standby.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void scm_standbyexit(void);
|
||||
|
||||
/**
|
||||
* @brief Return the state of the Radio.
|
||||
* @param None
|
||||
* @retval radio_state
|
||||
*/
|
||||
scm_radio_state_t isRadioActive(void);
|
||||
|
||||
/**
|
||||
* @brief Configure the PLL for switching fractional parameters on the fly.
|
||||
* @param pll_frac Up to date fractional configuration.
|
||||
* @retval None
|
||||
* @note A PLL update is requested only when the system clock is
|
||||
* running on the PLL with a different configuration that the
|
||||
* one required.
|
||||
*/
|
||||
void scm_pll_fractional_update(uint32_t pll_frac);
|
||||
|
||||
/**
|
||||
* @brief Set the HSE clock to the requested frequency.
|
||||
* @param user_id This parameter can be one of the following:
|
||||
* @arg SCM_USER_APP
|
||||
* @arg SCM_USER_LL_FW
|
||||
* @param sysclockconfig This parameter can be one of the following:
|
||||
* @arg HSE_16MHZ
|
||||
* @arg HSE_32MHZ
|
||||
* @arg SYS_PLL
|
||||
* @retval None
|
||||
*/
|
||||
void scm_setsystemclock (scm_user_id_t user_id, scm_clockconfig_t sysclockconfig);
|
||||
|
||||
/**
|
||||
* @brief Called each time the PLL is ready
|
||||
* @param None
|
||||
* @retval None
|
||||
* @note This function is defined as weak in SCM module.
|
||||
* Can be overridden by user.
|
||||
*/
|
||||
void scm_pllready(void);
|
||||
|
||||
/**
|
||||
* @brief Configure the Flash and SRAMs wait cycle (when required for system clock source change)
|
||||
* @param ws_lp_config: This parameter can be one of the following:
|
||||
* @arg LP
|
||||
* @arg RUN
|
||||
* @arg HSE16
|
||||
* @arg HSE32
|
||||
* @arg PLL
|
||||
* @retval None
|
||||
*/
|
||||
void scm_setwaitstates(const scm_ws_lp_t ws_lp_config);
|
||||
|
||||
/**
|
||||
* @brief Notify the state of the Radio
|
||||
* @param radio_state: This parameter can be one of the following:
|
||||
* @arg SCM_RADIO_ACTIVE
|
||||
* @arg SCM_RADIO_NOT_ACTIVE
|
||||
* @retval None
|
||||
*/
|
||||
void scm_notifyradiostate(const scm_radio_state_t radio_state);
|
||||
|
||||
/**
|
||||
* @brief SCM HSERDY interrupt handler.
|
||||
* Switch system clock on HSE.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void scm_hserdy_isr(void);
|
||||
|
||||
/**
|
||||
* @brief SCM PLLRDY interrupt handler.
|
||||
* Switch system clock on PLL.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void scm_pllrdy_isr(void);
|
||||
|
||||
/* SCM HSE BEGIN */
|
||||
/**
|
||||
* @brief Getter for SW HSERDY flag
|
||||
*/
|
||||
uint8_t SCM_HSE_Get_SW_HSERDY(void);
|
||||
|
||||
/**
|
||||
* @brief Setter for SW HSERDY flag
|
||||
*/
|
||||
void SCM_HSE_Set_SW_HSERDY(void);
|
||||
|
||||
/**
|
||||
* @brief Clean of SW HSERDY flag
|
||||
*/
|
||||
void SCM_HSE_Clear_SW_HSERDY(void);
|
||||
|
||||
/**
|
||||
* @brief Polling function to wait until HSE is ready
|
||||
*/
|
||||
void SCM_HSE_WaitUntilReady(void);
|
||||
|
||||
/**
|
||||
* @brief Start the HSE stabilization timer
|
||||
*/
|
||||
void SCM_HSE_StartStabilizationTimer(void);
|
||||
|
||||
/**
|
||||
* @brief Stop the HSE stabilization timer
|
||||
*/
|
||||
void SCM_HSE_StopStabilizationTimer(void);
|
||||
|
||||
/**
|
||||
* @brief HSE stabilization timer interrupt handler
|
||||
*/
|
||||
void SCM_HSE_SW_HSERDY_isr(void);
|
||||
/* SCM HSE END */
|
||||
|
||||
/* Exported functions - To be implemented by the user ------------------------- */
|
||||
|
||||
/**
|
||||
* @brief SCM HSI clock enable
|
||||
* @details A weak version is implemented in the module sources.
|
||||
* @details It can be overridden by user.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
extern void SCM_HSI_CLK_ON(void);
|
||||
|
||||
/**
|
||||
* @brief SCM HSI clock may be disabled when this function is called
|
||||
* @details A weak version is implemented in the module sources.
|
||||
* @details It can be overridden by user.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
extern void SCM_HSI_CLK_OFF(void);
|
||||
|
||||
/* SCM HSE BEGIN */
|
||||
/**
|
||||
* @brief Entry hook for HSI switch
|
||||
*/
|
||||
extern void SCM_HSI_SwithSystemClock_Entry(void);
|
||||
|
||||
/**
|
||||
* @brief Exit hook for HSI switch
|
||||
*/
|
||||
extern void SCM_HSI_SwithSystemClock_Exit(void);
|
||||
/* SCM HSE END */
|
||||
#else /* CFG_SCM_SUPPORTED */
|
||||
|
||||
/* Unused empty functions */
|
||||
void scm_hserdy_isr(void);
|
||||
void scm_pllrdy_isr(void);
|
||||
|
||||
#endif /* CFG_SCM_SUPPORTED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SCM_H */
|
||||
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm_list.c
|
||||
* @author MCD Application Team
|
||||
* @brief TCircular Linked List Implementation.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Include Files
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#include "stm_list.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Function Definitions
|
||||
******************************************************************************/
|
||||
void LST_init_head (tListNode * listHead)
|
||||
{
|
||||
listHead->next = listHead;
|
||||
listHead->prev = listHead;
|
||||
}
|
||||
|
||||
uint8_t LST_is_empty (tListNode * listHead)
|
||||
{
|
||||
uint32_t primask_bit;
|
||||
uint8_t return_value;
|
||||
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
if(listHead->next == listHead)
|
||||
{
|
||||
return_value = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return_value = FALSE;
|
||||
}
|
||||
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
void LST_insert_head (tListNode * listHead, tListNode * node)
|
||||
{
|
||||
uint32_t primask_bit;
|
||||
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
|
||||
node->next = listHead->next;
|
||||
node->prev = listHead;
|
||||
listHead->next = node;
|
||||
(node->next)->prev = node;
|
||||
|
||||
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
|
||||
}
|
||||
|
||||
void LST_insert_tail (tListNode * listHead, tListNode * node)
|
||||
{
|
||||
uint32_t primask_bit;
|
||||
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
|
||||
node->next = listHead;
|
||||
node->prev = listHead->prev;
|
||||
listHead->prev = node;
|
||||
(node->prev)->next = node;
|
||||
|
||||
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
|
||||
}
|
||||
|
||||
void LST_remove_node (tListNode * node)
|
||||
{
|
||||
uint32_t primask_bit;
|
||||
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
|
||||
(node->prev)->next = node->next;
|
||||
(node->next)->prev = node->prev;
|
||||
|
||||
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
|
||||
}
|
||||
|
||||
void LST_remove_head (tListNode * listHead, tListNode ** node )
|
||||
{
|
||||
uint32_t primask_bit;
|
||||
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
|
||||
*node = listHead->next;
|
||||
LST_remove_node (listHead->next);
|
||||
|
||||
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
|
||||
}
|
||||
|
||||
void LST_remove_tail (tListNode * listHead, tListNode ** node )
|
||||
{
|
||||
uint32_t primask_bit;
|
||||
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
|
||||
*node = listHead->prev;
|
||||
LST_remove_node (listHead->prev);
|
||||
|
||||
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
|
||||
}
|
||||
|
||||
void LST_insert_node_after (tListNode * node, tListNode * ref_node)
|
||||
{
|
||||
uint32_t primask_bit;
|
||||
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
|
||||
node->next = ref_node->next;
|
||||
node->prev = ref_node;
|
||||
ref_node->next = node;
|
||||
(node->next)->prev = node;
|
||||
|
||||
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
|
||||
}
|
||||
|
||||
void LST_insert_node_before (tListNode * node, tListNode * ref_node)
|
||||
{
|
||||
uint32_t primask_bit;
|
||||
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
|
||||
node->next = ref_node;
|
||||
node->prev = ref_node->prev;
|
||||
ref_node->prev = node;
|
||||
(node->prev)->next = node;
|
||||
|
||||
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
|
||||
}
|
||||
|
||||
int LST_get_size (tListNode * listHead)
|
||||
{
|
||||
int size = 0;
|
||||
tListNode * temp;
|
||||
uint32_t primask_bit;
|
||||
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
|
||||
temp = listHead->next;
|
||||
while (temp != listHead)
|
||||
{
|
||||
size++;
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
|
||||
|
||||
return (size);
|
||||
}
|
||||
|
||||
void LST_get_next_node (tListNode * ref_node, tListNode ** node)
|
||||
{
|
||||
uint32_t primask_bit;
|
||||
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
|
||||
*node = ref_node->next;
|
||||
|
||||
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
|
||||
}
|
||||
|
||||
void LST_get_prev_node (tListNode * ref_node, tListNode ** node)
|
||||
{
|
||||
uint32_t primask_bit;
|
||||
|
||||
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
|
||||
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
||||
|
||||
*node = ref_node->prev;
|
||||
|
||||
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm_list.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file for linked list library.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef STM_LIST_H
|
||||
#define STM_LIST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32_wpan_common.h"
|
||||
|
||||
typedef __PACKED_STRUCT _tListNode {
|
||||
struct _tListNode * next;
|
||||
struct _tListNode * prev;
|
||||
} tListNode;
|
||||
|
||||
void LST_init_head (tListNode * listHead);
|
||||
|
||||
uint8_t LST_is_empty (tListNode * listHead);
|
||||
|
||||
void LST_insert_head (tListNode * listHead, tListNode * node);
|
||||
|
||||
void LST_insert_tail (tListNode * listHead, tListNode * node);
|
||||
|
||||
void LST_remove_node (tListNode * node);
|
||||
|
||||
void LST_remove_head (tListNode * listHead, tListNode ** node );
|
||||
|
||||
void LST_remove_tail (tListNode * listHead, tListNode ** node );
|
||||
|
||||
void LST_insert_node_after (tListNode * node, tListNode * ref_node);
|
||||
|
||||
void LST_insert_node_before (tListNode * node, tListNode * ref_node);
|
||||
|
||||
int LST_get_size (tListNode * listHead);
|
||||
|
||||
void LST_get_next_node (tListNode * ref_node, tListNode ** node);
|
||||
|
||||
void LST_get_prev_node (tListNode * ref_node, tListNode ** node);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM_LIST_H */
|
||||
@@ -0,0 +1,384 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm_queue.c
|
||||
* @author MCD Application Team
|
||||
* @brief Queue management
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "utilities_common.h"
|
||||
|
||||
#include "stm_queue.h"
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private typedef -------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
#define MOD(X,Y) (((X) >= (Y)) ? ((X)-(Y)) : (X))
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
/* Extern variables ----------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/* Public functions ----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Initilialze queue structure .
|
||||
* @note This function is used to initialize the global queue structure.
|
||||
* @param q: pointer on queue structure to be initialised
|
||||
* @param queueBuffer: pointer on Queue Buffer
|
||||
* @param queueSize: Size of Queue Buffer
|
||||
* @param elementSize: Size of an element in the queue. if =0, the queue will manage variable sizze elements
|
||||
* @retval always 0
|
||||
*/
|
||||
int CircularQueue_Init(queue_t *q, uint8_t* queueBuffer, uint32_t queueSize, uint16_t elementSize, uint8_t optionFlags)
|
||||
{
|
||||
q->qBuff = queueBuffer;
|
||||
q->first = 0;
|
||||
q->last = 0; /* queueSize-1; */
|
||||
q->byteCount = 0;
|
||||
q->elementCount = 0;
|
||||
q->queueMaxSize = queueSize;
|
||||
q->elementSize = elementSize;
|
||||
q->optionFlags = optionFlags;
|
||||
|
||||
if ((optionFlags & CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG) && q-> elementSize)
|
||||
{
|
||||
/* can not deal with splitting at the end of buffer with fixed size element */
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add element to the queue .
|
||||
* @note This function is used to add one or more element(s) to the Circular Queue .
|
||||
* @param q: pointer on queue structure to be handled
|
||||
* @param X; pointer on element(s) to be added
|
||||
* @param elementSize: Size of element to be added to the queue. Only used if the queue manage variable size elements
|
||||
* @param nbElements: number of elements in the in buffer pointed by x
|
||||
* @retval pointer on last element just added to the queue, NULL if the element to be added do not fit in the queue (too big)
|
||||
*/
|
||||
uint8_t* CircularQueue_Add(queue_t *q, uint8_t* x, uint16_t elementSize, uint32_t nbElements)
|
||||
{
|
||||
|
||||
uint8_t* ptr = NULL; /* fct return ptr to the element freshly added, if no room fct return NULL */
|
||||
uint16_t curElementSize = 0; /* the size of the element currently stored at q->last position */
|
||||
uint8_t elemSizeStorageRoom = 0 ; /* Indicate the header (which contain only size) of element in case of varaibale size element (q->elementsize == 0) */
|
||||
uint32_t curBuffPosition; /* the current position in the queue buffer */
|
||||
uint32_t i; /* loop counter */
|
||||
uint32_t NbBytesToCopy = 0, NbCopiedBytes = 0 ; /* Indicators for copying bytes in queue */
|
||||
uint32_t eob_free_size; /* Eof End of Quque Buffer Free Size */
|
||||
uint8_t wrap_will_occur = 0; /* indicate if a wrap around will occurs */
|
||||
uint8_t wrapped_element_eob_size; /* In case of Wrap around, indicate size of parta of element that fit at thened of the queuue buffer */
|
||||
uint16_t overhead = 0; /* In case of CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG or CIRCULAR_QUEUE_NO_WRAP_FLAG options,
|
||||
indcate the size overhead that will be generated by adding the element with wrap management (split or no wrap ) */
|
||||
|
||||
|
||||
elemSizeStorageRoom = (q->elementSize == 0) ? 2 : 0;
|
||||
/* retrieve the size of last element sored: the value stored at the beginning of the queue element if element size is variable otherwise take it from fixed element Size member */
|
||||
if (q->byteCount)
|
||||
{
|
||||
curElementSize = (q->elementSize == 0) ? q->qBuff[q->last] + ((q->qBuff[MOD((q->last+1), q->queueMaxSize)])<<8) + 2 : q->elementSize;
|
||||
}
|
||||
/* if queue element have fixed size , reset the elementSize arg with fixed element size value */
|
||||
if (q->elementSize > 0)
|
||||
{
|
||||
elementSize = q->elementSize;
|
||||
}
|
||||
|
||||
eob_free_size = (q->last >= q->first) ? q->queueMaxSize - (q->last + curElementSize) : 0;
|
||||
|
||||
/* check how many bytes of wrapped element (if anay) are at end of buffer */
|
||||
wrapped_element_eob_size = (((elementSize + elemSizeStorageRoom )*nbElements) < eob_free_size) ? 0 : (eob_free_size % (elementSize + elemSizeStorageRoom));
|
||||
wrap_will_occur = wrapped_element_eob_size > elemSizeStorageRoom;
|
||||
|
||||
overhead = (wrap_will_occur && (q->optionFlags & CIRCULAR_QUEUE_NO_WRAP_FLAG)) ? wrapped_element_eob_size : overhead;
|
||||
overhead = (wrap_will_occur && (q->optionFlags & CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG)) ? elemSizeStorageRoom : overhead;
|
||||
|
||||
|
||||
/* Store now the elements if ennough room for all elements */
|
||||
if (elementSize && ((q->byteCount + ((elementSize + elemSizeStorageRoom )*nbElements) + overhead) <= q->queueMaxSize))
|
||||
{
|
||||
/* loop to add all elements */
|
||||
for (i=0; i < nbElements; i++)
|
||||
{
|
||||
q->last = MOD ((q->last + curElementSize),q->queueMaxSize);
|
||||
curBuffPosition = q->last;
|
||||
|
||||
/* store the element */
|
||||
/* store first the element size if element size is variable */
|
||||
if (q->elementSize == 0)
|
||||
{
|
||||
q->qBuff[curBuffPosition++]= elementSize & 0xFF;
|
||||
curBuffPosition = MOD(curBuffPosition, q->queueMaxSize);
|
||||
q->qBuff[curBuffPosition++]= (elementSize & 0xFF00) >> 8 ;
|
||||
curBuffPosition = MOD(curBuffPosition, q->queueMaxSize);
|
||||
q->byteCount += 2;
|
||||
}
|
||||
|
||||
/* Identify number of bytes of copy takeing account possible wrap, in this case NbBytesToCopy will contains size that fit at end of the queue buffer */
|
||||
NbBytesToCopy = MIN((q->queueMaxSize-curBuffPosition),elementSize);
|
||||
/* check if no wrap (NbBytesToCopy == elementSize) or if Wrap and no spsicf option;
|
||||
In this case part of data will copied at the end of the buffer and the rest a the beginning */
|
||||
if ((NbBytesToCopy == elementSize) || ((NbBytesToCopy < elementSize) && (q->optionFlags == CIRCULAR_QUEUE_NO_FLAG)))
|
||||
{
|
||||
/* Copy First part (or emtire buffer ) from current position up to the end of the buffer queue (or before if enough room) */
|
||||
memcpy(&q->qBuff[curBuffPosition],&x[i*elementSize],NbBytesToCopy);
|
||||
/* Adjust bytes count */
|
||||
q->byteCount += NbBytesToCopy;
|
||||
/* Wrap */
|
||||
curBuffPosition = 0;
|
||||
/* set NbCopiedBytes bytes with ampount copied */
|
||||
NbCopiedBytes = NbBytesToCopy;
|
||||
/* set the rest to copy if wrao , if no wrap will be 0 */
|
||||
NbBytesToCopy = elementSize - NbBytesToCopy;
|
||||
/* set the current element Size, will be used to calaculate next last position at beginning of loop */
|
||||
curElementSize = (elementSize) + elemSizeStorageRoom ;
|
||||
}
|
||||
else if (NbBytesToCopy) /* We have a wrap to manage */
|
||||
{
|
||||
/* case of CIRCULAR_QUEUE_NO_WRAP_FLAG option */
|
||||
if (q->optionFlags & CIRCULAR_QUEUE_NO_WRAP_FLAG)
|
||||
{
|
||||
/* if element size are variable and NO_WRAP option, Invalidate end of buffer setting 0xFFFF size*/
|
||||
if (q->elementSize == 0)
|
||||
{
|
||||
q->qBuff[curBuffPosition-2] = 0xFF;
|
||||
q->qBuff[curBuffPosition-1] = 0xFF;
|
||||
}
|
||||
q->byteCount += NbBytesToCopy; /* invalid data at the end of buffer are take into account in byteCount */
|
||||
/* No bytes coped a the end of buffer */
|
||||
NbCopiedBytes = 0;
|
||||
/* all element to be copied at the begnning of buffer */
|
||||
NbBytesToCopy = elementSize;
|
||||
/* Wrap */
|
||||
curBuffPosition = 0;
|
||||
/* if variable size element, invalidate end of buffer setting OxFFFF in element header (size) */
|
||||
if (q->elementSize == 0)
|
||||
{
|
||||
q->qBuff[curBuffPosition++] = NbBytesToCopy & 0xFF;
|
||||
q->qBuff[curBuffPosition++] = (NbBytesToCopy & 0xFF00) >> 8 ;
|
||||
q->byteCount += 2;
|
||||
}
|
||||
|
||||
}
|
||||
/* case of CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG option */
|
||||
else if (q->optionFlags & CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG)
|
||||
{
|
||||
if (q->elementSize == 0)
|
||||
{
|
||||
/* reset the size of current element to the nb bytes fitting at the end of buffer */
|
||||
q->qBuff[curBuffPosition-2] = NbBytesToCopy & 0xFF;
|
||||
q->qBuff[curBuffPosition-1] = (NbBytesToCopy & 0xFF00) >> 8 ;
|
||||
/* copy the bytes */
|
||||
memcpy(&q->qBuff[curBuffPosition],&x[i*elementSize],NbBytesToCopy);
|
||||
q->byteCount += NbBytesToCopy;
|
||||
/* set the number of copied bytes */
|
||||
NbCopiedBytes = NbBytesToCopy;
|
||||
/* set rest of data to be copied to begnning of buffer */
|
||||
NbBytesToCopy = elementSize - NbBytesToCopy;
|
||||
/* one element more dur to split in 2 elements */
|
||||
q->elementCount++;
|
||||
/* Wrap */
|
||||
curBuffPosition = 0;
|
||||
/* Set new size for rest of data */
|
||||
q->qBuff[curBuffPosition++] = NbBytesToCopy & 0xFF;
|
||||
q->qBuff[curBuffPosition++] = (NbBytesToCopy & 0xFF00) >> 8 ;
|
||||
q->byteCount += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Should not occur */
|
||||
/* can not manage split Flag on Fixed size element */
|
||||
/* Buffer is corrupted */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
curElementSize = (NbBytesToCopy) + elemSizeStorageRoom ;
|
||||
q->last = 0;
|
||||
}
|
||||
|
||||
/* some remaining byte to copy */
|
||||
if (NbBytesToCopy)
|
||||
{
|
||||
memcpy(&q->qBuff[curBuffPosition],&x[(i*elementSize)+NbCopiedBytes],NbBytesToCopy);
|
||||
q->byteCount += NbBytesToCopy;
|
||||
}
|
||||
|
||||
/* One more element */
|
||||
q->elementCount++;
|
||||
}
|
||||
|
||||
ptr = q->qBuff + (MOD((q->last+elemSizeStorageRoom ),q->queueMaxSize));
|
||||
}
|
||||
/* for Breakpoint only...to remove */
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Remove element from the queue and copy it in provided buffer
|
||||
* @note This function is used to remove and element from the Circular Queue .
|
||||
* @param q: pointer on queue structure to be handled
|
||||
* @param elementSize: Pointer to return Size of element to be removed
|
||||
* @param buffer: destination buffer where to copy element
|
||||
* @retval Pointer on removed element. NULL if queue was empty
|
||||
*/
|
||||
uint8_t* CircularQueue_Remove_Copy(queue_t *q, uint16_t* elementSize, uint8_t* buffer)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Remove element from the queue.
|
||||
* @note This function is used to remove and element from the Circular Queue .
|
||||
* @param q: pointer on queue structure to be handled
|
||||
* @param elementSize: Pointer to return Size of element to be removed (ignored if NULL)
|
||||
* @retval Pointer on removed element. NULL if queue was empty
|
||||
*/
|
||||
uint8_t* CircularQueue_Remove(queue_t *q, uint16_t* elementSize)
|
||||
{
|
||||
uint8_t elemSizeStorageRoom = 0;
|
||||
uint8_t* ptr= NULL;
|
||||
elemSizeStorageRoom = (q->elementSize == 0) ? 2 : 0;
|
||||
uint16_t eltSize = 0;
|
||||
if (q->byteCount > 0)
|
||||
{
|
||||
/* retrieve element Size */
|
||||
eltSize = (q->elementSize == 0) ? q->qBuff[q->first] + ((q->qBuff[MOD((q->first+1), q->queueMaxSize)])<<8) : q->elementSize;
|
||||
|
||||
if ((q->optionFlags & CIRCULAR_QUEUE_NO_WRAP_FLAG) && !(q->optionFlags & CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG))
|
||||
{
|
||||
if (((eltSize == 0xFFFF) && q->elementSize == 0 ) ||
|
||||
((q->first > q->last) && q->elementSize && ((q->queueMaxSize - q->first) < q->elementSize)))
|
||||
{
|
||||
/* all data from current position up to the end of buffer are invalid */
|
||||
q->byteCount -= (q->queueMaxSize - q->first);
|
||||
/* Adjust first element pos */
|
||||
q->first = 0;
|
||||
/* retrieve the right size after the wrap [if variable size element] */
|
||||
eltSize = (q->elementSize == 0) ? q->qBuff[q->first] + ((q->qBuff[MOD((q->first+1), q->queueMaxSize)])<<8) : q->elementSize;
|
||||
}
|
||||
}
|
||||
|
||||
/* retrieve element */
|
||||
ptr = q->qBuff + (MOD((q->first + elemSizeStorageRoom), q->queueMaxSize));
|
||||
|
||||
/* adjust byte count */
|
||||
q->byteCount -= (eltSize + elemSizeStorageRoom) ;
|
||||
|
||||
/* Adjust q->first */
|
||||
if (q->byteCount > 0)
|
||||
{
|
||||
q->first = MOD((q->first+ eltSize + elemSizeStorageRoom ), q->queueMaxSize);
|
||||
}
|
||||
/* adjust element count */
|
||||
--q->elementCount;
|
||||
}
|
||||
if (elementSize != NULL)
|
||||
{
|
||||
*elementSize = eltSize;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief "Sense" first element of the queue, without removing it and copy it in provided buffer
|
||||
* @note This function is used to return a pointer on the first element of the queue without removing it.
|
||||
* @param q: pointer on queue structure to be handled
|
||||
* @param elementSize: Pointer to return Size of element to be removed
|
||||
* @param buffer: destination buffer where to copy element
|
||||
* @retval Pointer on sensed element. NULL if queue was empty
|
||||
*/
|
||||
|
||||
uint8_t* CircularQueue_Sense_Copy(queue_t *q, uint16_t* elementSize, uint8_t* buffer)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief "Sense" first element of the queue, without removing it.
|
||||
* @note This function is used to return a pointer on the first element of the queue without removing it.
|
||||
* @param q: pointer on queue structure to be handled
|
||||
* @param elementSize: Pointer to return Size of element to be removed (ignored if NULL)
|
||||
* @retval Pointer on sensed element. NULL if queue was empty
|
||||
*/
|
||||
uint8_t* CircularQueue_Sense(queue_t *q, uint16_t* elementSize)
|
||||
{
|
||||
uint8_t elemSizeStorageRoom = 0;
|
||||
uint8_t* x= NULL;
|
||||
elemSizeStorageRoom = (q->elementSize == 0) ? 2 : 0;
|
||||
uint16_t eltSize = 0;
|
||||
uint32_t FirstElemetPos = 0;
|
||||
|
||||
if (q->byteCount > 0)
|
||||
{
|
||||
FirstElemetPos = q->first;
|
||||
eltSize = (q->elementSize == 0) ? q->qBuff[q->first] + ((q->qBuff[MOD((q->first+1), q->queueMaxSize)])<<8) : q->elementSize;
|
||||
|
||||
if ((q->optionFlags & CIRCULAR_QUEUE_NO_WRAP_FLAG) && !(q->optionFlags & CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG))
|
||||
{
|
||||
if (((eltSize == 0xFFFF) && q->elementSize == 0 ) ||
|
||||
((q->first > q->last) && q->elementSize && ((q->queueMaxSize - q->first) < q->elementSize)))
|
||||
|
||||
{
|
||||
/* all data from current position up to the end of buffer are invalid */
|
||||
FirstElemetPos = 0; /* wrap to the begiining of buffer */
|
||||
|
||||
/* retrieve the right size after the wrap [if variable size element] */
|
||||
eltSize = (q->elementSize == 0) ? q->qBuff[FirstElemetPos]+ ((q->qBuff[MOD((FirstElemetPos+1), q->queueMaxSize)])<<8) : q->elementSize;
|
||||
}
|
||||
}
|
||||
/* retrieve element */
|
||||
x = q->qBuff + (MOD((FirstElemetPos + elemSizeStorageRoom), q->queueMaxSize));
|
||||
}
|
||||
if (elementSize != NULL)
|
||||
{
|
||||
*elementSize = eltSize;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if queue is empty.
|
||||
* @note This function is used to to check if the queue is empty.
|
||||
* @param q: pointer on queue structure to be handled
|
||||
* @retval TRUE (!0) if the queue is empyu otherwise FALSE (0)
|
||||
*/
|
||||
int CircularQueue_Empty(queue_t *q)
|
||||
{
|
||||
int ret=FALSE;
|
||||
if (q->byteCount <= 0)
|
||||
{
|
||||
ret=TRUE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CircularQueue_NbElement(queue_t *q)
|
||||
{
|
||||
return q->elementCount;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm_queue.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for stm_queue.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM_QUEUE_H
|
||||
#define __STM_QUEUE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported define -----------------------------------------------------------*/
|
||||
/* Options flags */
|
||||
#define CIRCULAR_QUEUE_NO_FLAG 0
|
||||
#define CIRCULAR_QUEUE_NO_WRAP_FLAG 1
|
||||
#define CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG 2
|
||||
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
uint8_t* qBuff; /* queue buffer, , provided by init fct */
|
||||
uint32_t queueMaxSize; /* size of the queue, provided by init fct (in bytes)*/
|
||||
uint16_t elementSize; /* -1 variable. If variable element size the size is stored in the 4 first of the queue element */
|
||||
uint32_t first; /* position of first element */
|
||||
uint32_t last; /* position of last element */
|
||||
uint32_t byteCount; /* number of bytes in the queue */
|
||||
uint32_t elementCount; /* number of element in the queue */
|
||||
uint8_t optionFlags; /* option to enable specific features */
|
||||
} queue_t;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
int CircularQueue_Init(queue_t *q, uint8_t* queueBuffer, uint32_t queueSize, uint16_t elementSize, uint8_t optionlags);
|
||||
uint8_t* CircularQueue_Add(queue_t *q, uint8_t* x, uint16_t elementSize, uint32_t nbElements);
|
||||
uint8_t* CircularQueue_Remove(queue_t *q, uint16_t* elementSize);
|
||||
uint8_t* CircularQueue_Sense(queue_t *q, uint16_t* elementSize);
|
||||
int CircularQueue_Empty(queue_t *q);
|
||||
int CircularQueue_NbElement(queue_t *q);
|
||||
uint8_t* CircularQueue_Remove_Copy(queue_t *q, uint16_t* elementSize, uint8_t* buffer);
|
||||
uint8_t* CircularQueue_Sense_Copy(queue_t *q, uint16_t* elementSize, uint8_t* buffer);
|
||||
|
||||
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM_QUEUE_H */
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file temp_measurement.c
|
||||
* @author MCD Application Team
|
||||
* @brief Temp measurement module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
/* Common utilites */
|
||||
#include "utilities_common.h"
|
||||
|
||||
#if (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1)
|
||||
/* Own header file */
|
||||
#include "temp_measurement.h"
|
||||
/* ADC Controller module */
|
||||
#include "adc_ctrl.h"
|
||||
#include "adc_ctrl_conf.h"
|
||||
|
||||
/* Link layer interfaces */
|
||||
#include "ll_intf.h"
|
||||
#include "ll_intf_cmn.h"
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
/* Error Handler */
|
||||
extern void Error_Handler(void);
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
TEMPMEAS_Cmd_Status_t TEMPMEAS_Init (void)
|
||||
{
|
||||
TEMPMEAS_Cmd_Status_t error = TEMPMEAS_UNKNOWN;
|
||||
|
||||
ADCCTRL_Cmd_Status_t eReturn = ADCCTRL_UNKNOWN;
|
||||
|
||||
eReturn = ADCCTRL_RegisterHandle (&LLTempRequest_Handle);
|
||||
|
||||
if ((ADCCTRL_HANDLE_ALREADY_REGISTERED == eReturn) ||
|
||||
(ADCCTRL_OK == eReturn))
|
||||
{
|
||||
error = TEMPMEAS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = TEMPMEAS_ADC_INIT;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void TEMPMEAS_RequestTemperatureMeasurement (void)
|
||||
{
|
||||
int16_t temperature_value = 0;
|
||||
|
||||
/* Enter limited critical section : disable all the interrupts with priority higher than RCC one
|
||||
* Concerns link layer interrupts (high and SW low) or any other high priority user system interrupt
|
||||
*/
|
||||
UTILS_ENTER_LIMITED_CRITICAL_SECTION(RCC_INTR_PRIO<<4);
|
||||
|
||||
/* Request ADC IP activation */
|
||||
ADCCTRL_RequestIpState(&LLTempRequest_Handle, ADC_ON);
|
||||
|
||||
/* Get temperature from ADC dedicated channel */
|
||||
ADCCTRL_RequestTemperature (&LLTempRequest_Handle,
|
||||
&temperature_value);
|
||||
|
||||
/* Request ADC IP deactivation */
|
||||
ADCCTRL_RequestIpState(&LLTempRequest_Handle, ADC_OFF);
|
||||
|
||||
/* Give shifted value of the temperature to the link layer */
|
||||
ll_intf_cmn_set_temperature_value((uint32_t)(temperature_value + TEMPMEAS_MIN_TEMP_LIMIT));
|
||||
|
||||
/* Exit limited critical section */
|
||||
UTILS_EXIT_LIMITED_CRITICAL_SECTION();
|
||||
}
|
||||
#endif /* USE_TEMPERATURE_BASED_RADIO_CALIBRATION */
|
||||
/* Private Functions Definition ------------------------------------------------------*/
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file temp_measurement.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for temp_measurement.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef TEMP_MEASUREMENT_H
|
||||
#define TEMP_MEASUREMENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "utilities_common.h"
|
||||
|
||||
/* Exported defines ----------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Minimum operating temperature limit absolute value
|
||||
*
|
||||
* @details I.e.: Operating temperature is between -40C and 105degC,
|
||||
* Minimum value expected is 40u.
|
||||
*/
|
||||
#define TEMPMEAS_MIN_TEMP_LIMIT ((uint32_t)40u)
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Temperature Measurement command status codes
|
||||
*/
|
||||
typedef enum TEMPMEAS_Cmd_Status
|
||||
{
|
||||
TEMPMEAS_OK,
|
||||
TEMPMEAS_NOK,
|
||||
TEMPMEAS_ADC_INIT,
|
||||
TEMPMEAS_UNKNOWN,
|
||||
} TEMPMEAS_Cmd_Status_t;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the temperature measurement
|
||||
*
|
||||
* @retval Operation state
|
||||
*/
|
||||
TEMPMEAS_Cmd_Status_t TEMPMEAS_Init (void);
|
||||
|
||||
/**
|
||||
* @brief Request temperature measurement
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void TEMPMEAS_RequestTemperatureMeasurement (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TEMP_MEASUREMENT_H */
|
||||
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file utilities_common.h
|
||||
* @author MCD Application Team
|
||||
* @brief Common file to utilities
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef UTILITIES_COMMON_H
|
||||
#define UTILITIES_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "app_conf.h"
|
||||
|
||||
/* -------------------------------- *
|
||||
* Basic definitions *
|
||||
* -------------------------------- */
|
||||
|
||||
#undef NULL
|
||||
#define NULL 0
|
||||
|
||||
#undef FALSE
|
||||
#define FALSE 0
|
||||
|
||||
#undef TRUE
|
||||
#define TRUE (!0)
|
||||
|
||||
/* -------------------------------- *
|
||||
* Critical Section definition *
|
||||
* -------------------------------- */
|
||||
#undef BACKUP_PRIMASK
|
||||
#define BACKUP_PRIMASK() uint32_t primask_bit= __get_PRIMASK()
|
||||
|
||||
#undef DISABLE_IRQ
|
||||
#define DISABLE_IRQ() __disable_irq()
|
||||
|
||||
#undef RESTORE_PRIMASK
|
||||
#define RESTORE_PRIMASK() __set_PRIMASK(primask_bit)
|
||||
|
||||
/* -------------------------------- *
|
||||
* Macro delimiters *
|
||||
* -------------------------------- */
|
||||
#undef M_BEGIN
|
||||
#define M_BEGIN do {
|
||||
|
||||
#undef M_END
|
||||
#define M_END } while(0)
|
||||
|
||||
/* -------------------------------- *
|
||||
* Some useful macro definitions *
|
||||
* -------------------------------- */
|
||||
#undef MAX
|
||||
#define MAX( x, y ) (((x)>(y))?(x):(y))
|
||||
|
||||
#undef MIN
|
||||
#define MIN( x, y ) (((x)<(y))?(x):(y))
|
||||
|
||||
#undef MODINC
|
||||
#define MODINC( a, m ) M_BEGIN (a)++; if ((a)>=(m)) (a)=0; M_END
|
||||
|
||||
#undef MODDEC
|
||||
#define MODDEC( a, m ) M_BEGIN if ((a)==0) (a)=(m); (a)--; M_END
|
||||
|
||||
#undef MODADD
|
||||
#define MODADD( a, b, m ) M_BEGIN (a)+=(b); if ((a)>=(m)) (a)-=(m); M_END
|
||||
|
||||
#undef MODSUB
|
||||
#define MODSUB( a, b, m ) MODADD( a, (m)-(b), m )
|
||||
|
||||
#undef ALIGN
|
||||
#ifdef WIN32
|
||||
#define ALIGN(n)
|
||||
#else
|
||||
#define ALIGN(n) __attribute__((aligned(n)))
|
||||
#endif
|
||||
|
||||
#undef PAUSE
|
||||
#define PAUSE( t ) M_BEGIN \
|
||||
volatile int _i; \
|
||||
for ( _i = t; _i > 0; _i -- ); \
|
||||
M_END
|
||||
#undef DIVF
|
||||
#define DIVF( x, y ) ((x)/(y))
|
||||
|
||||
#undef DIVC
|
||||
#define DIVC( x, y ) (((x)+(y)-1)/(y))
|
||||
|
||||
#undef DIVR
|
||||
#define DIVR( x, y ) (((x)+((y)/2))/(y))
|
||||
|
||||
#undef SHRR
|
||||
#define SHRR( x, n ) ((((x)>>((n)-1))+1)>>1)
|
||||
|
||||
#undef BITN
|
||||
#define BITN( w, n ) (((w)[(n)/32] >> ((n)%32)) & 1)
|
||||
|
||||
#undef BITNSET
|
||||
#define BITNSET( w, n, b ) M_BEGIN (w)[(n)/32] |= ((U32)(b))<<((n)%32); M_END
|
||||
|
||||
/* -------------------------------- *
|
||||
* Section attribute *
|
||||
* -------------------------------- */
|
||||
#define PLACE_IN_SECTION( __x__ ) __attribute__((section (__x__)))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SYS_WAITING_CYCLES_25() do {\
|
||||
__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");\
|
||||
__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");\
|
||||
__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");\
|
||||
__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");\
|
||||
__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");__asm("mov r0, r0");\
|
||||
} while(0)
|
||||
|
||||
#define SYS_WAITING_RNGCLK_DEACTIVATION() do {\
|
||||
for(volatile unsigned int cpt = 178 ; cpt!=0 ; --cpt);\
|
||||
} while(0)
|
||||
|
||||
#define STM32WBA5x_DEFAULT_SCA_RANGE (0)
|
||||
#define STM32WBA5x_REV_ID_A_SCA_RANGE (0)
|
||||
#define STM32WBA5x_REV_ID_B_SCA_RANGE (0)
|
||||
#ifdef STM32WBA65xx
|
||||
#define STM32WBA6x_SCA_RANGE (0)
|
||||
#endif
|
||||
|
||||
/* Macro helper for optimizing by speed specific functions.
|
||||
* For IAR only: The functions with this definition will be optimized
|
||||
* by speed only if the project uses a High optimisation level.
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#define OPTIMIZED _Pragma("optimize=speed")
|
||||
#elif defined(__clang__)
|
||||
#define OPTIMIZED _Pragma("pragma Ofast")
|
||||
#elif defined(__GNUC__)
|
||||
#define OPTIMIZED __attribute__((optimize("Ofast")))
|
||||
#endif
|
||||
|
||||
#define UTIL_UNUSED(X) (void)X /* To avoid gcc/g++ warnings */
|
||||
|
||||
#endif /* UTILITIES_COMMON_H */
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
;********************************************************************************
|
||||
;* File Name : stm32wbaxx_ResetHandler.s
|
||||
;* Author : MCD Application Team
|
||||
;* Description : STM32WBA5xx Ultra Low Power Devices specific
|
||||
; Reset handler for connectivity applications.
|
||||
; EWARM toolchain.
|
||||
;********************************************************************************
|
||||
;* @attention
|
||||
;*
|
||||
;* Copyright (c) 2022 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.
|
||||
;*
|
||||
;*******************************************************************************
|
||||
;
|
||||
; Cortex-M version
|
||||
;
|
||||
EXTERN __iar_program_start
|
||||
EXTERN SystemInit
|
||||
EXTERN is_boot_from_standby
|
||||
EXTERN SYS_WAITING_CYCLES_25
|
||||
|
||||
IMPORT backup_MSP
|
||||
IMPORT register_backup_table
|
||||
IMPORT register_backup_table_size
|
||||
|
||||
EXPORT CPUcontextSave
|
||||
EXPORT backup_system_register
|
||||
EXPORT restore_system_register
|
||||
|
||||
PUBLIC Reset_Handler
|
||||
SECTION .text:CODE:NOROOT:REORDER(2)
|
||||
Reset_Handler
|
||||
/* If we exit from standby mode, restore CPU context and jump to asleep point. */
|
||||
BL is_boot_from_standby
|
||||
CMP R0, #1
|
||||
BEQ CPUcontextRestore
|
||||
/* buffer for local variables (up to 10)from is_boot_from_standby*/
|
||||
SUB SP, SP, #0x28
|
||||
/* end of specific code section for standby */
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__iar_program_start
|
||||
BX R0
|
||||
|
||||
/* These 2 functions are designed to save and then restore CPU context. */
|
||||
CPUcontextSave
|
||||
PUSH { R4 - R12, LR } /* store R4 to R12 and LR (10 words) onto C stack */
|
||||
LDR R4, =backup_MSP /* load address of backup_MSP into R4 */
|
||||
MOV R3, SP /* load the stack pointer into R3 */
|
||||
STR R3, [R4] /* store the MSP into backup_MSP */
|
||||
DSB
|
||||
WFI /* all saved, trigger deep sleep */
|
||||
|
||||
CPUcontextRestore
|
||||
/* Even if we fall through the WFI instruction, we will immediately
|
||||
* execute a context restore and end up where we left off with no
|
||||
* ill effects. Normally at this point the core will either be
|
||||
* powered off or reset (depending on the deep sleep level). */
|
||||
LDR R4, =backup_MSP /* load address of backup_MSP into R4 */
|
||||
LDR R4, [R4] /* load the SP from backup_MSP */
|
||||
MOV SP, R4 /* restore the SP from R4 */
|
||||
POP { R4 - R12, PC } /* load R4 to R12 and PC (10 words) from C stack */
|
||||
|
||||
backup_system_register
|
||||
/* R0 -> register_backup_table array current item address */
|
||||
/* R1 -> loop counter (from register_backup_table_size to 0) */
|
||||
/* R2 -> register_backup_table array current item value */
|
||||
|
||||
backup_loop_init:
|
||||
LDR R0, =register_backup_table /* R0 points to the first array item */
|
||||
LDR R1, =register_backup_table_size
|
||||
LDR R1, [R1] /* R1 contains the number of registers in the array */
|
||||
|
||||
backup_loop_iter:
|
||||
/* Offset processing */
|
||||
LDR R2, [R0], #4 /* R2 contains the register_backup_table current item (register address) */
|
||||
/* R0 points to the next register_backup_table item (uint32_t items -> 4 bytes added to previous address) */
|
||||
|
||||
/* Register value backup */
|
||||
LDR R2, [R2] /* R2 contains now the register value to backup */
|
||||
PUSH {R2} /* Push register value into the stack */
|
||||
|
||||
/* Loop iteration control */
|
||||
SUBS R1, #1 /* Decrement loop counter by 1 and update APSR (Application Processor Status Register) */
|
||||
BNE backup_loop_iter /* Loop continues until Z flag is set (still array item to handle) */
|
||||
|
||||
backup_loop_end:
|
||||
BX LR /* Return to caller */
|
||||
|
||||
restore_system_register
|
||||
/* R0 -> register_backup_table array current item address */
|
||||
/* R1 -> loop counter (from register_backup_table_size to 0) */
|
||||
/* R2 -> register_backup_table array current item value */
|
||||
|
||||
restore_loop_init:
|
||||
LDR R0, =register_backup_table /* R0 points to the first array item */
|
||||
|
||||
/* Reverse loop: counter initial value processing */
|
||||
LDR R1, =register_backup_table_size
|
||||
LDR R1, [R1] /* R1 contains the number of registers in the array */
|
||||
SUB R1, #1 /* R1 now contains last array item index (register_backup_table_size - 1) */
|
||||
|
||||
/* Reverse loop: apply offset to current array index (point to last array element) */
|
||||
ADD R0, R1, LSL #2 /* R0 now points to last array item (register_backup_table + (register_backup_table_size - 1) * 4) */
|
||||
|
||||
ADD R1, #1 /* Re-add 1 to R1 (array length) */
|
||||
|
||||
/* Reverse loop */
|
||||
restore_loop_iter:
|
||||
/* Offset processing */
|
||||
LDR R2, [R0], #-4 /* R2 contains the register_backup_table current item (register address) */
|
||||
/* R0 now points to the previous register_backup_table item (uint32_t items -> 4 bytes subtracted to previous address) */
|
||||
|
||||
/* Register value restoration */
|
||||
POP {R3} /* Head of stack popped into R3. R3 contains register value to restore */
|
||||
STR R3, [R2] /* Write backuped value into the register */
|
||||
|
||||
/* Loop iteration control */
|
||||
SUBS R1, #1 /* Decrement loop counter by 1 and update APSR (Application Processor Status Register) */
|
||||
BNE restore_loop_iter /* Loop continues until Z flag is set (still array item to handle) */
|
||||
|
||||
restore_loop_end:
|
||||
BX LR /* Return to caller */
|
||||
|
||||
/* end of specific code section for standby */
|
||||
|
||||
END
|
||||
@@ -0,0 +1,189 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : stm32wbaxx_ResetHandler.s
|
||||
* Author : MCD Application Team
|
||||
* Description : STM32WBA5xx Ultra Low Power Devices specific
|
||||
* Reset handler for connectivity applications.
|
||||
GCC toolchain.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Cortex-M version
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m33
|
||||
.fpu softvfp
|
||||
.thumb
|
||||
|
||||
.extern SystemInit
|
||||
.extern is_boot_from_standby
|
||||
.extern SYS_WAITING_CYCLES_25
|
||||
|
||||
.global backup_system_register
|
||||
.global restore_system_register
|
||||
|
||||
/* INIT_BSS macro is used to fill the specified region [start : end] with zeros */
|
||||
.macro INIT_BSS start, end
|
||||
ldr r0, =\start
|
||||
ldr r1, =\end
|
||||
movs r3, #0
|
||||
bl LoopFillZerobss
|
||||
.endm
|
||||
|
||||
/* INIT_DATA macro is used to copy data in the region [start : end] starting from 'src' */
|
||||
.macro INIT_DATA start, end, src
|
||||
ldr r0, =\start
|
||||
ldr r1, =\end
|
||||
ldr r2, =\src
|
||||
movs r3, #0
|
||||
bl LoopCopyDataInit
|
||||
.endm
|
||||
|
||||
.section .text.data_initializers
|
||||
CopyDataInit:
|
||||
ldr r4, [r2, r3]
|
||||
str r4, [r0, r3]
|
||||
adds r3, r3, #4
|
||||
|
||||
LoopCopyDataInit:
|
||||
adds r4, r0, r3
|
||||
cmp r4, r1
|
||||
bcc CopyDataInit
|
||||
bx lr
|
||||
|
||||
FillZerobss:
|
||||
str r3, [r0]
|
||||
adds r0, r0, #4
|
||||
|
||||
LoopFillZerobss:
|
||||
cmp r0, r1
|
||||
bcc FillZerobss
|
||||
bx lr
|
||||
|
||||
.section .text.Reset_Handler
|
||||
.global Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
ldr r0, =_estack
|
||||
mov sp, r0 /* set stack pointer */
|
||||
/* If we exit from standby mode, restore CPU context and jump to asleep point. */
|
||||
BL is_boot_from_standby
|
||||
CMP R0, #1
|
||||
BEQ CPUcontextRestore
|
||||
/* buffer for local variables (up to 10)from is_boot_from_standby*/
|
||||
SUB SP, SP, #0x28
|
||||
/* end of specific code section for standby */
|
||||
/* Call the clock system initialization function.*/
|
||||
bl SystemInit
|
||||
|
||||
/* Copy the data segment initializers from flash to SRAM */
|
||||
INIT_DATA _sdata, _edata, _sidata
|
||||
|
||||
/* Zero fill the bss segments. */
|
||||
INIT_BSS _sbss, _ebss
|
||||
|
||||
/* Call static constructors */
|
||||
bl __libc_init_array
|
||||
/* Call the application s entry point.*/
|
||||
bl main
|
||||
|
||||
LoopForever:
|
||||
b LoopForever
|
||||
|
||||
/* These 2 functions are designed to save and then restore CPU context. */
|
||||
.global CPUcontextSave
|
||||
.type CPUcontextSave, %function
|
||||
CPUcontextSave:
|
||||
PUSH { R4 - R12, LR } /* store R4 to R12 and LR (10 words) onto C stack */
|
||||
LDR R4, =backup_MSP /* load address of backup_MSP into R4 */
|
||||
MOV R3, SP /* load the stack pointer into R3 */
|
||||
STR R3, [R4] /* store the MSP into backup_MSP */
|
||||
DSB
|
||||
WFI /* all saved, trigger deep sleep */
|
||||
|
||||
CPUcontextRestore:
|
||||
/* Even if we fall through the WFI instruction, we will immediately
|
||||
* execute a context restore and end up where we left off with no
|
||||
* ill effects. Normally at this point the core will either be
|
||||
* powered off or reset (depending on the deep sleep level). */
|
||||
LDR R4, =backup_MSP /* load address of backup_MSP into R4 */
|
||||
LDR R4, [R4] /* load the SP from backup_MSP */
|
||||
MOV SP, R4 /* restore the SP from R4 */
|
||||
POP { R4 - R12, PC } /* load R4 to R12 and PC (10 words) from C stack */
|
||||
|
||||
backup_system_register:
|
||||
/* R0 -> register_backup_table array current item address */
|
||||
/* R1 -> loop counter (from register_backup_table_size to 0) */
|
||||
/* R2 -> register_backup_table array current item value */
|
||||
|
||||
backup_loop_init:
|
||||
LDR R0, =register_backup_table /* R0 points to the first array item */
|
||||
LDR R1, =register_backup_table_size
|
||||
LDR R1, [R1] /* R1 contains the number of registers in the array */
|
||||
|
||||
backup_loop_iter:
|
||||
/* Offset processing */
|
||||
LDR R2, [R0], #4 /* R2 contains the register_backup_table current item (register address) */
|
||||
/* R0 points to the next register_backup_table item (uint32_t items -> 4 bytes added to previous address) */
|
||||
|
||||
/* Register value backup */
|
||||
LDR R2, [R2] /* R2 contains now the register value to backup */
|
||||
PUSH {R2} /* Push register value into the stack */
|
||||
|
||||
/* Loop iteration control */
|
||||
SUBS R1, #1 /* Decrement loop counter by 1 and update APSR (Application Processor Status Register) */
|
||||
BNE backup_loop_iter /* Loop continues until Z flag is set (still array item to handle) */
|
||||
|
||||
backup_loop_end:
|
||||
BX LR /* Return to caller */
|
||||
|
||||
restore_system_register:
|
||||
/* R0 -> register_backup_table array current item address */
|
||||
/* R1 -> loop counter (from register_backup_table_size to 0) */
|
||||
/* R2 -> register_backup_table array current item value */
|
||||
|
||||
restore_loop_init:
|
||||
LDR R0, =register_backup_table /* R0 points to the first array item */
|
||||
|
||||
/* Reverse loop: counter initial value processing */
|
||||
LDR R1, =register_backup_table_size
|
||||
LDR R1, [R1] /* R1 contains the number of registers in the array */
|
||||
SUB R1, #1 /* R1 now contains last array item index (register_backup_table_size - 1) */
|
||||
|
||||
/* Reverse loop: apply offset to current array index (point to last array element) */
|
||||
LSL R1, #2 /* Left shift R1 by 2 */
|
||||
ADD R0, R1 /* R0 now points to last array item (register_backup_table + (register_backup_table_size - 1) * 4) */
|
||||
|
||||
LSR R1, #2 /* Reverse left shift operation on R1 */
|
||||
ADD R1, #1 /* Re-add 1 to R1 (array length) */
|
||||
|
||||
/* Reverse loop */
|
||||
restore_loop_iter:
|
||||
/* Offset processing */
|
||||
LDR R2, [R0], #-4 /* R2 contains the register_backup_table current item (register address) */
|
||||
/* R0 now points to the previous register_backup_table item (uint32_t items -> 4 bytes subtracted to previous address) */
|
||||
|
||||
/* Register value restoration */
|
||||
POP {R3} /* Head of stack popped into R3. R3 contains register value to restore */
|
||||
STR R3, [R2] /* Write backuped value into the register */
|
||||
|
||||
/* Loop iteration control */
|
||||
SUBS R1, #1 /* Decrement loop counter by 1 and update APSR (Application Processor Status Register) */
|
||||
BNE restore_loop_iter /* Loop continues until Z flag is set (still array item to handle) */
|
||||
|
||||
restore_loop_end:
|
||||
BX LR /* Return to caller */
|
||||
/* end of specific code section for standby */
|
||||
.end
|
||||
@@ -0,0 +1,134 @@
|
||||
;********************************************************************************
|
||||
;* File Name : stm32wbaxx_ResetHandler.s
|
||||
;* Author : MCD Application Team
|
||||
;* Description : STM32WBA5xx Ultra Low Power Devices specific
|
||||
; Reset handler for connectivity applications.
|
||||
; MDK-ARM toolchain.
|
||||
;********************************************************************************
|
||||
;* @attention
|
||||
;*
|
||||
;* Copyright (c) 2022 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.
|
||||
;*
|
||||
;*******************************************************************************
|
||||
;
|
||||
; Cortex-M version
|
||||
;
|
||||
PRESERVE8
|
||||
THUMB
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
; Reset_Handler
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler
|
||||
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
IMPORT is_boot_from_standby
|
||||
IMPORT backup_MSP
|
||||
IMPORT register_backup_table
|
||||
IMPORT register_backup_table_size
|
||||
|
||||
EXPORT CPUcontextSave
|
||||
EXPORT backup_system_register
|
||||
EXPORT restore_system_register
|
||||
; If we exit from standby mode, restore CPU context and jump to asleep point.
|
||||
BL is_boot_from_standby
|
||||
CMP R0, #1
|
||||
BEQ CPUcontextRestore
|
||||
; buffer for local variables (up to 10)from is_boot_from_standby.
|
||||
SUB SP, SP, #0x28
|
||||
; end of specific code section for standby
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
; These 2 functions are designed to save and then restore CPU context.
|
||||
CPUcontextSave
|
||||
PUSH { R4 - R12, lr } ; store R4 to R12 and LR (10 words) onto C stack
|
||||
LDR R4, =backup_MSP ; load address of backup_MSP into R4
|
||||
MOV R3, SP ; load the stack pointer into R3
|
||||
STR R3, [R4] ; store the MSP into backup_MSP
|
||||
DSB
|
||||
WFI ; all saved, trigger deep sleep
|
||||
|
||||
CPUcontextRestore
|
||||
; Even if we fall through the WFI instruction, we will immediately
|
||||
; execute a context restore and end up where we left off with no
|
||||
; ill effects. Normally at this point the core will either be
|
||||
; powered off or reset (depending on the deep sleep level).
|
||||
LDR R4, =backup_MSP ; load address of backup_MSP into R4.
|
||||
LDR R4, [R4] ; load the SP from backup_MSP.
|
||||
MOV SP, R4 ; restore the SP from R4.
|
||||
POP { R4 - R12, PC } ; load R4-R12 and PC (10 words) from C stack
|
||||
; end of specific code section for standby.
|
||||
|
||||
backup_system_register
|
||||
; R0 -> register_backup_table array current item address
|
||||
; R1 -> loop counter (from register_backup_table_size to 0)
|
||||
; R2 -> register_backup_table array current item value
|
||||
|
||||
backup_loop_init
|
||||
LDR R0, =register_backup_table ; R0 points to the first array item
|
||||
LDR R1, =register_backup_table_size
|
||||
LDR R1, [R1] ; R1 contains the number of registers in the array
|
||||
|
||||
backup_loop_iter
|
||||
; Offset processing
|
||||
LDR R2, [R0], #4 ; R2 contains the register_backup_table current item (register address)
|
||||
; R0 points to the next register_backup_table item (uint32_t items -> 4 bytes added to previous address)
|
||||
|
||||
; Register value backup
|
||||
LDR R2, [R2] ; R2 contains now the register value to backup
|
||||
PUSH {R2} ; Push register value into the stack
|
||||
|
||||
; Loop iteration control
|
||||
SUBS R1, #1 ; Decrement loop counter by 1 and update APSR (Application Processor Status Register)
|
||||
BNE backup_loop_iter ; Loop continues until Z flag is set (still array item to handle)
|
||||
|
||||
backup_loop_end
|
||||
BX LR ; Return to caller
|
||||
|
||||
restore_system_register
|
||||
; R0 -> register_backup_table array current item address
|
||||
; R1 -> loop counter (from register_backup_table_size to 0)
|
||||
; R2 -> register_backup_table array current item value
|
||||
|
||||
restore_loop_init
|
||||
LDR R0, =register_backup_table ; R0 points to the first array item
|
||||
|
||||
; Reverse loop: counter initial value processing
|
||||
LDR R1, =register_backup_table_size
|
||||
LDR R1, [R1] ; R1 contains the number of registers in the array
|
||||
SUB R1, #1 ; R1 now contains last array item index (register_backup_table_size - 1)
|
||||
|
||||
; Reverse loop: apply offset to current array index (point to last array element)
|
||||
ADD R0, R1, LSL #2 ; R0 now points to last array item (register_backup_table + (register_backup_table_size - 1) * 4)
|
||||
|
||||
ADD R1, #1 ; Re-add 1 to R1 (array length)
|
||||
|
||||
; Reverse loop
|
||||
restore_loop_iter
|
||||
; Offset processing
|
||||
LDR R2, [R0], #-4 ; R2 contains the register_backup_table current item (register address)
|
||||
; R0 now points to the previous register_backup_table item (uint32_t items -> 4 bytes subtracted to previous address)
|
||||
|
||||
; Register value restoration
|
||||
POP {R3} ; Head of stack popped into R3. R3 contains register value to restore
|
||||
STR R3, [R2] ; Write backuped value into the register
|
||||
|
||||
; Loop iteration control
|
||||
SUBS R1, #1 ; Decrement loop counter by 1 and update APSR (Application Processor Status Register)
|
||||
BNE restore_loop_iter ; Loop continues until Z flag is set (still array item to handle)
|
||||
|
||||
restore_loop_end
|
||||
BX LR ; Return to caller
|
||||
|
||||
END
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
[ProjectFiles]
|
||||
HeaderPath=../../../../../../Drivers/BSP/STM32U5xx_Nucleo;../../../../../Common/Aliro/Inc;../../../../../../Middlewares/Third_Party/t_cose/inc;../../../../../../Middlewares/Third_Party/t_cose/src;../../../../../../Middlewares/Third_Party/QCBOR/inc;../../../../../../Middlewares/ST/ACWG_Security/inc;
|
||||
|
||||
[Others]
|
||||
Define=T_COSE_DISABLE_SHORT_CIRCUIT_SIGN;T_COSE_DISABLE_ES512;T_COSE_DISABLE_ES384;T_COSE_DISABLE_PS256;T_COSE_DISABLE_PS384;T_COSE_DISABLE_PS512;T_COSE_DISABLE_EDDSA;
|
||||
[Groups]
|
||||
Drivers/BSP/STM32U5xx_Nucleo=../../../../../../Drivers/BSP/STM32U5xx_Nucleo/stm32u5xx_nucleo.c;
|
||||
Common/Aliro=../../../../../Common/Aliro/Src/app_aliro.c;../../../../../Common/Aliro/Src/app_nfc.c;../../../../../Common/Aliro/Src/provisioning.c;../../../../../Common/Aliro/Src/flash_mng.c;../../../../../Common/Aliro/Src/sm_crypto_mcu.c;../../../../../Common/Aliro/Lib/Aliro.a;
|
||||
Middlewares/Third_Party/t_cose=../../../../../../Middlewares/Third_Party/t_cose/src/t_cose_parameters.c;../../../../../../Middlewares/Third_Party/t_cose/src/t_cose_signature_verify_main.c;../../../../../../Middlewares/Third_Party/t_cose/src/t_cose_sign_verify.c;../../../../../../Middlewares/Third_Party/t_cose/src/t_cose_signature_verify_eddsa.c;../../../../../../Middlewares/Third_Party/t_cose/src/t_cose_sign1_verify.c;../../../../../../Middlewares/Third_Party/t_cose/src/t_cose_qcbor_gap.c;../../../../../../Middlewares/Third_Party/t_cose/src/t_cose_util.c;
|
||||
Middlewares/Third_Party/QCBOR=../../../../../../Middlewares/Third_Party/QCBOR/src/ieee754.c;../../../../../../Middlewares/Third_Party/QCBOR/src/qcbor_number_decode.c;../../../../../../Middlewares/Third_Party/QCBOR/src/qcbor_tag_decode.c;../../../../../../Middlewares/Third_Party/QCBOR/src/qcbor_main_decode.c;../../../../../../Middlewares/Third_Party/QCBOR/src/qcbor_spiffy_decode.c;../../../../../../Middlewares/Third_Party/QCBOR/src/qcbor_main_encode.c;../../../../../../Middlewares/Third_Party/QCBOR/src/UsefulBuf.c;
|
||||
Middlewares/ACWG_Security=../../../../../../Middlewares/ST/ACWG_Security/lib/ACWG_Security.a;
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,68 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
#
|
||||
# This file is generated only once,
|
||||
# and is not re-generated if converter is called multiple times.
|
||||
#
|
||||
# User is free to modify the file as much as necessary
|
||||
#
|
||||
|
||||
# Setup compiler settings
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS ON)
|
||||
|
||||
|
||||
# Define the build type
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
endif()
|
||||
|
||||
# Set the project name
|
||||
set(CMAKE_PROJECT_NAME Aliro_U5)
|
||||
|
||||
# Enable compile command to ease indexing with e.g. clangd
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
|
||||
|
||||
# Core project settings
|
||||
project(${CMAKE_PROJECT_NAME})
|
||||
message("Build type: " ${CMAKE_BUILD_TYPE})
|
||||
|
||||
# Enable CMake support for ASM and C languages
|
||||
enable_language(C ASM)
|
||||
|
||||
# Create an executable object type
|
||||
add_executable(${CMAKE_PROJECT_NAME})
|
||||
|
||||
# Add STM32CubeMX generated sources
|
||||
add_subdirectory(cmake/stm32cubemx)
|
||||
|
||||
# Link directories setup
|
||||
target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE
|
||||
# Add user defined library search paths
|
||||
)
|
||||
|
||||
# Add sources to executable
|
||||
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
|
||||
# Add user sources here
|
||||
)
|
||||
|
||||
# Add include paths
|
||||
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
|
||||
# Add user defined include paths
|
||||
)
|
||||
|
||||
# Add project symbols (macros)
|
||||
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
|
||||
# Add user defined symbols
|
||||
)
|
||||
|
||||
# Remove wrong libob.a library dependency when using cpp files
|
||||
list(REMOVE_ITEM CMAKE_C_IMPLICIT_LINK_LIBRARIES ob)
|
||||
|
||||
# Add linked libraries
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||
stm32cubemx
|
||||
|
||||
# Add user defined libraries
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"hidden": true,
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||
"toolchainFile": "${sourceDir}/cmake/gcc-arm-none-eabi.cmake",
|
||||
"cacheVariables": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Debug",
|
||||
"inherits": "default",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Release",
|
||||
"inherits": "default",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "Debug",
|
||||
"configurePreset": "Debug"
|
||||
},
|
||||
{
|
||||
"name": "Release",
|
||||
"configurePreset": "Release"
|
||||
}
|
||||
]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user