V1.0
This commit is contained in:
@@ -0,0 +1,402 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file aes.h
|
||||
*
|
||||
* @brief Header file for AES crypto module
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2017-2018
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef AES_H_
|
||||
#define AES_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @defgroup AES Crypto module
|
||||
* @ingroup ROOT
|
||||
* @brief AES Crypto module
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include "rwip_config.h"
|
||||
|
||||
#include "co_bt.h" // Common defines
|
||||
|
||||
|
||||
/*
|
||||
* Defines
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Size of an a AES Message block in bytes
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
/*
|
||||
* TYPE DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Call back definition of the function that can handle result of an AES based algorithm
|
||||
*
|
||||
* @param[in] status Execution status
|
||||
* @param[in] aes_res 16 bytes block result
|
||||
* @param[in] src_info Information provided by requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
typedef void (*aes_func_result_cb) (uint8_t status, const uint8_t* aes_res, uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Call back definition of the function that can handle result of AES-CCM Cipher/Decipher
|
||||
*
|
||||
* @param[in] mic_error True if a MIC error detected when Decipher, False else
|
||||
* In case of MIC error output message is considered invalid
|
||||
* @param[in] src_info Information provided by requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
typedef void (*aes_ccm_func_result_cb) (bool mic_error, uint32_t src_info);
|
||||
|
||||
#if (BLE_EMB_PRESENT || BLE_HOST_PRESENT)
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Call back definition of the Resolvable Private Address resolution function
|
||||
*
|
||||
* @param[in] index Index of the IRK used to resolve the provided RPA (number of IRK if not resolved)
|
||||
* @param[in] src_info Information provided by requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
typedef void (*aes_rpa_func_result_cb) (uint8_t index, uint32_t src_info);
|
||||
#endif // (BLE_EMB_PRESENT || BLE_HOST_PRESENT)
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize AES function management
|
||||
*
|
||||
* @param[in] init_type Type of initialization (@see enum rwip_init_type)
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_init(uint8_t init_type);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Handler of AES execution (HW accelerator if BLE controller present, HCI Encrypt for BLE Host Stack)
|
||||
*
|
||||
* @param[in] status Status of AES execution
|
||||
* @param[in] result 16 bytes result of AES execution
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_result_handler(uint8_t status, uint8_t* result);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Perform an AES encryption - result within callback
|
||||
* @param[in] key Key used for the encryption
|
||||
* @param[in] val Value to encrypt using AES
|
||||
* @param[in] copy Copy parameters because source is destroyed
|
||||
* @param[in] res_cb Function that will handle the AES based result (16 bytes)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_encrypt(const uint8_t* key, const uint8_t *val, bool copy, aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Generate a random number using AES encryption - result within callback
|
||||
*
|
||||
* @param[in] res_cb Function that will handle the AES based result (16 bytes)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_rand(aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
#if (BLE_HOST_PRESENT)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Compute Confirm value
|
||||
*
|
||||
* @param[in] k Key used for aes functions
|
||||
* @param[in] r Random number
|
||||
* @param[in] p1 p1 = pres || preq || rat’ || iat’
|
||||
* @param[in] p2 p2 = padding || ia || ra
|
||||
* @param[in] res_cb Function that will handle the AES based result (16 bytes)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_c1(const uint8_t* k, const uint8_t* r, const uint8_t* p1, const uint8_t* p2,
|
||||
aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Compute LE Secure Connections Confirm Value Generation Function f4
|
||||
*
|
||||
* @param[in] u U is 256 bits
|
||||
* @param[in] v V is 256 bits
|
||||
* @param[in] x X is 128 bits
|
||||
* @param[in] z Z is 8 bits
|
||||
* @param[in] res_cb Function that will handle the AES based result (16 bytes)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_f4(const uint8_t* u, const uint8_t* v, const uint8_t* x, uint8_t z,
|
||||
aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Compute LE Secure Connections Key Generation Function f5
|
||||
*
|
||||
* @param[in] w W is 256 bits
|
||||
* @param[in] n1 N1 is 128 bits
|
||||
* @param[in] n2 N2 is 128 bits
|
||||
* @param[in] a1 A1 is 56 bits
|
||||
* @param[in] a2 A2 is 56 bits
|
||||
* @param[in] res_cb Function that will handle the AES based result (16 bytes)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_f5(const uint8_t* w, const uint8_t* n1, const uint8_t* n2, const uint8_t* a1, const uint8_t* a2,
|
||||
aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Compute LE Secure Connections Check Value Generation Function f6
|
||||
*
|
||||
* @param[in] w W is 128 bits
|
||||
* @param[in] n1 N1 is 128 bits
|
||||
* @param[in] n2 N2 is 128 bits
|
||||
* @param[in] r R is 128 bits
|
||||
* @param[in] iocap IOcap is 24 bits
|
||||
* @param[in] a1 A1 is 56 bits
|
||||
* @param[in] a2 A2 is 56 bits
|
||||
*
|
||||
* @param[in] res_cb Function that will handle the AES based result (16 bytes)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_f6(const uint8_t* w, const uint8_t* n1, const uint8_t* n2, const uint8_t* r, const uint8_t* iocap,
|
||||
const uint8_t* a1, const uint8_t* a2, aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Compute LE Secure Connections Numeric Comparison Value Generation Function g2
|
||||
*
|
||||
* @param[in] u U is 256 bits
|
||||
* @param[in] v V is 256 bits
|
||||
* @param[in] x X is 128 bits
|
||||
* @param[in] y Y is 128 bits
|
||||
*
|
||||
* @param[in] res_cb Function that will handle the AES based result (16 bytes)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_g2(const uint8_t* u, const uint8_t* v, const uint8_t* x, const uint8_t* y,
|
||||
aes_func_result_cb res_cb, uint32_t src_info);
|
||||
#endif // (BLE_HOST_PRESENT)
|
||||
|
||||
|
||||
|
||||
#if (BLE_EMB_PRESENT || BLE_HOST_PRESENT)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Start the AES CMAC crypto function. Allocate memory for the CMAC and
|
||||
* begins the subkey generation
|
||||
*
|
||||
* @param[in] key Pointer to the Key to be used
|
||||
* @param[in] message Pointer to the block of data the data on which the CMAC is performed
|
||||
* @param[in] message_len Length (in bytes) of the block of data M
|
||||
* @param[in] res_cb Function that will handle the AES based result (16 bytes)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_cmac(const uint8_t* key, const uint8_t* message, uint16_t message_len,
|
||||
aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
#if (BLE_MESH)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Start the AES S1 crypto function.
|
||||
*
|
||||
* @param[in] message Message used to generate Salted key
|
||||
* @param[in] message_len Length (in bytes) of the block of data M
|
||||
* @param[in] res_cb Function that will handle the AES based result (16 bytes)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_s1(const uint8_t* message, uint8_t message_len, aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Start the AES K1 crypto function.
|
||||
*
|
||||
* @param[in] salt Salted Key to use
|
||||
* @param[in] n Value of N
|
||||
* @param[in] n_len Length of N
|
||||
* @param[in] p Value of P
|
||||
* @param[in] p_len Length of P
|
||||
* @param[in] res_cb Function that will handle the AES based result (16 bytes)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_k1(const uint8_t* salt, const uint8_t* n, uint8_t n_len, const uint8_t* p, uint8_t p_len,
|
||||
aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Start the AES K2 crypto function.
|
||||
*
|
||||
* @param[in] n Value of N - 128 bits
|
||||
* @param[in] p Value of P
|
||||
* @param[in] p_len Length of P
|
||||
* @param[in] res_cb Function that will handle the AES based result (33 bytes)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_k2(const uint8_t* n, const uint8_t* p, uint8_t p_len, aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Start the AES K3 crypto function.
|
||||
*
|
||||
* @param[in] n Value of N - 128 bits
|
||||
* @param[in] res_cb Function that will handle the AES based result (8 bytes)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_k3(const uint8_t* n, aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Start the AES K4 crypto function.
|
||||
*
|
||||
* @param[in] n Value of N - 128 bits
|
||||
* @param[in] res_cb Function that will handle the AES based result (1 byte)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_k4(const uint8_t* n, aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Start the AES CCM crypto function. Allocate memory for the CCM and start processing it
|
||||
* Execute result callback at end of function execution
|
||||
*
|
||||
* @param[in] key Pointer to the Key to be used
|
||||
* @param[in] nonce 13 Bytes Nonce to use for cipher/decipher
|
||||
* @param[in] in_message Input message for AES-CCM exectuion
|
||||
* @param[out] out_message Output message that will contain cipher+mic or decipher data
|
||||
* @param[in] message_len Length of Input/Output message without mic
|
||||
* @param[in] mic_len Length of the mic to use (2, 4, 6, 8, 10, 12, 14, 16 valid)
|
||||
* @param[in] cipher True to encrypt message, False to decrypt it.
|
||||
* @param[in] add_auth_data Additional Authentication data used for computation of MIC
|
||||
* @param[in] add_auth_data_len Length of Additional Authentication data
|
||||
* @param[in] res_cb Function that will handle the AES CCM result
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_ccm(const uint8_t* key, const uint8_t* nonce, const uint8_t* in_message,
|
||||
uint8_t* out_message, uint16_t message_len, uint8_t mic_len, bool cipher,
|
||||
const uint8_t* add_auth_data, uint8_t add_auth_data_len, aes_ccm_func_result_cb res_cb, uint32_t src_info);
|
||||
#endif // (BLE_MESH)
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Key Conversion Function h6
|
||||
*
|
||||
* @param[in] w W is a 128bits data
|
||||
* @param[in] keyId KeyID is a 32 bits data
|
||||
* @param[in] res_cb Function that will handle the AES CCM result
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_h6(const uint8_t* w, const uint8_t* key_id, aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Key Conversion Function h7
|
||||
*
|
||||
* @param[in] salt SALT is a 128bits data
|
||||
* @param[in] w W is a 128bits key
|
||||
* @param[in] res_cb Function that will handle the AES CCM result
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_h7(const uint8_t* salt, const uint8_t* w, aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Group Session Key Derivation Function h8
|
||||
*
|
||||
* @param[in] k K is a 128bits data
|
||||
* @param[in] s S is a 128bits key
|
||||
* @param[in] keyId KeyID is a 32 bits data
|
||||
* @param[in] res_cb Function that will handle the AES CCM result
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_h8(const uint8_t* k, const uint8_t* s, const uint8_t* key_id, aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Group Long Term Key Generation Function h9
|
||||
*
|
||||
* @param[in] w W is a 128bits data
|
||||
* @param[in] keyId KeyID is a 32 bits data
|
||||
* @param[in] res_cb Function that will handle the AES CCM result
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_h9(const uint8_t* w, const uint8_t* key_id, aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
#endif // (BLE_EMB_PRESENT || BLE_HOST_PRESENT)
|
||||
|
||||
#if (BLE_EMB_PRESENT || BLE_HOST_PRESENT)
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Resolvable Private Address generation Function
|
||||
*
|
||||
* @param[in] irk Pointer to IRK (local IRK to generate a local RPA)
|
||||
* @param[in] res_cb Function that will handle the AES RPA generation result (address generated in the 6 LSBs of the returned buffer)
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_rpa_gen(struct irk* irk, aes_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Resolvable Private Address resolution Function
|
||||
*
|
||||
* @param[in] nb_irk Number of IRKs provided
|
||||
* @param[in] irk Table of IRKs (stored internally to AES RPA, caller can destroy the table)
|
||||
* @param[in] addr BD address to resolve
|
||||
* @param[in] res_cb Function that will handle the AES RPA resolution result
|
||||
* @param[in] src_info Information used retrieve requester
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_rpa_resolve(uint8_t nb_irk, struct irk* irk, struct bd_addr* addr, aes_rpa_func_result_cb res_cb, uint32_t src_info);
|
||||
|
||||
#endif // (BLE_EMB_PRESENT || BLE_HOST_PRESENT)
|
||||
|
||||
/// @} AES
|
||||
///
|
||||
#endif /* AES_H_ */
|
||||
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file aes_int.h
|
||||
*
|
||||
* @brief Header file for AES Internal crypto module
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2017-2018
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef AES_INT_H_
|
||||
#define AES_INT_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @defgroup AES_INT
|
||||
* @ingroup AES
|
||||
* @brief AES_INT Crypto internal definitions
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include "rwip_config.h"
|
||||
#include "aes.h"
|
||||
|
||||
|
||||
#include "co_bt.h" // Common defines
|
||||
#include "co_list.h" // List usage
|
||||
|
||||
/*
|
||||
* Defines
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
// Size of an a AES Message block in bytes
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
/*
|
||||
* TYPE DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
struct aes_func_env;
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* Callback used to continue execution of the AES based function.
|
||||
*
|
||||
* @param[in] aes_result Result of the AES (aes(key , val))
|
||||
*
|
||||
* @return True if function execution is over
|
||||
****************************************************************************************
|
||||
*/
|
||||
typedef bool (*aes_func_continue_cb) (struct aes_func_env* aes_env, uint8_t* aes_result);
|
||||
|
||||
/// Environment variable required for an AES based function
|
||||
/// This structure must be Header of all function environment variables
|
||||
struct aes_func_env
|
||||
{
|
||||
/// used to put AES function in the AES execution queue
|
||||
struct co_list_hdr hdr;
|
||||
/// AES continue callback
|
||||
aes_func_continue_cb aes_continue_cb;
|
||||
/// AES End callback
|
||||
aes_func_result_cb aes_res_cb;
|
||||
|
||||
/// Key to use for the AES execution
|
||||
const uint8_t* key;
|
||||
/// Value to use for AES Cypher/Decypher
|
||||
const uint8_t* val;
|
||||
/// Information put in source id message to retrieve requester
|
||||
uint32_t src_info;
|
||||
};
|
||||
|
||||
#if (BLE_EMB_PRESENT || BLE_HOST_PRESENT)
|
||||
// Structure definition of the AES CMAC algorithm
|
||||
struct aes_cmac_env
|
||||
{
|
||||
/// AES Environment structure
|
||||
struct aes_func_env aes_env;
|
||||
|
||||
/// M: Pointer to the message to be authenticated
|
||||
const uint8_t* message; // pointer to memory allocated by calling function
|
||||
|
||||
/// K: authentication key
|
||||
const uint8_t* auth_key;
|
||||
|
||||
/// T: message authentication code
|
||||
uint8_t auth_code[AES_BLOCK_SIZE];
|
||||
|
||||
/// Length of the message
|
||||
uint16_t message_len;
|
||||
/// Number of blocks (1 block = 16 bytes)
|
||||
uint8_t num_blocks;
|
||||
/// Current block to process
|
||||
uint8_t cur_block;
|
||||
};
|
||||
#endif // (BLE_EMB_PRESENT || BLE_HOST_PRESENT)
|
||||
|
||||
/*
|
||||
* GLOBAL VARIABLE DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// zero block
|
||||
extern const uint8_t aes_cmac_zero[AES_BLOCK_SIZE];
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Allocate environment for the AES based function execution
|
||||
*
|
||||
* @param[in] size Size of the environment to allocate (must be >= sizeof(struct aes_func_env))
|
||||
* @param[in] aes_continue_cb Callback used to send the AES result
|
||||
* @param[in] res_cb Function that will handle end of AES Based algorithm
|
||||
* @param[in] src_info Information used to retrieve requester
|
||||
*
|
||||
* @return Allocated environment variable
|
||||
****************************************************************************************
|
||||
*/
|
||||
struct aes_func_env* aes_alloc(uint16_t size, aes_func_continue_cb aes_continue_cb, aes_func_result_cb res_cb,
|
||||
uint32_t src_info);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief AES Cypher request function.
|
||||
*
|
||||
* This will queue AES request in the AES execution queue
|
||||
* When the AES result is received, the AES continue callback is executed.
|
||||
*
|
||||
* If AES continue function returns that AES execution is over, a message will be send to destination task
|
||||
* with latest AES result.
|
||||
*
|
||||
* @param[in] env AES environment
|
||||
* @param[in] key Key used for cyphering
|
||||
* @param[in] val Value to cypher
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_start(struct aes_func_env* env, const uint8_t* key, const uint8_t *val);
|
||||
|
||||
#if (BLE_EMB_PRESENT || BLE_HOST_PRESENT)
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Start the AES CMAC crypto function. Allocate memory for the CMAC and
|
||||
* begins the subkey generation
|
||||
*
|
||||
* @param[in] enc AES CMAC Environment
|
||||
* @param[in] key Pointer to the Key to be used
|
||||
* @param[in] message Pointer to the block of data the data on which the CMAC is performed
|
||||
* @param[in] message_len Length (in bytes) of the block of data M
|
||||
****************************************************************************************
|
||||
*/
|
||||
void aes_cmac_start(struct aes_cmac_env* env, const uint8_t* key, const uint8_t* message, uint16_t message_len);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Continue AES CMAC algorithm
|
||||
*
|
||||
* @param[in] env AES CMAC Environment
|
||||
* @param[in] aes_res AES Result
|
||||
*
|
||||
* @return True if algorithm is over, False else
|
||||
****************************************************************************************
|
||||
*/
|
||||
bool aes_cmac_continue(struct aes_cmac_env* env, uint8_t* aes_res);
|
||||
|
||||
/**
|
||||
* @brief Perform a XOR of two numbers.
|
||||
*
|
||||
* @param[out] result Output 128 bits number: result = a ^ b
|
||||
* @param[in] a first 128 bits operand
|
||||
* @param[in] b second 128 bits operand
|
||||
* @param[in] size number of bytes to XOR
|
||||
*/
|
||||
void aes_xor_128(uint8_t* result, const uint8_t* a, const uint8_t* b, uint8_t size);
|
||||
|
||||
/**
|
||||
* @brief Perform shift left of a 128 bits numvber
|
||||
*
|
||||
* @param[in] input Input 128 bits number
|
||||
* @param[out] output Output 128 bits number: output = input << 1
|
||||
*/
|
||||
void aes_shift_left_128(const uint8_t* input,uint8_t* output);
|
||||
#endif // (BLE_EMB_PRESENT || BLE_HOST_PRESENT)
|
||||
|
||||
/// @} AES_INT
|
||||
///
|
||||
#endif /* AES_INT_H_ */
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file co_bt.h
|
||||
*
|
||||
* @brief This file contains the common Bluetooth defines, enumerations and structures
|
||||
* definitions for use by all modules in RW stack.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef CO_BT_H_
|
||||
#define CO_BT_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup COMMON Common SW Block
|
||||
* @ingroup ROOT
|
||||
* @brief The Common RW SW Block.
|
||||
*
|
||||
* The COMMON is the block with Bluetooth definitions and structures shared
|
||||
* to all the protocol stack blocks. This also contain software wide error code
|
||||
* definitions, mathematical functions, help functions, list and buffer definitions.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup CO_BT Common Bluetooth defines
|
||||
* @ingroup COMMON
|
||||
* @brief Common Bluetooth definitions and structures.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include <stdbool.h> // standard boolean definitions
|
||||
#include <stddef.h> // standard definitions
|
||||
#include <stdint.h> // standard integer definitions
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include "co_bt_defines.h" // Bluetooth defines
|
||||
#include "co_lmp.h" // Bluetooth LMP definitions
|
||||
#include "co_hci.h" // Bluetooth HCI definitions
|
||||
#include "co_error.h" // Bluetooth error codes definitions
|
||||
|
||||
/// @} CO_BT
|
||||
#endif // CO_BT_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,643 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file co_buf.h
|
||||
*
|
||||
* @brief The Common Time module provides buffer used for manipulation of data for network
|
||||
* protocol that uses encapsulation of header or trailing information.
|
||||
* A buffer is a contiguous memory section used to store message information including
|
||||
* several protocol layers.
|
||||
* Since a unique buffer can be used by multiple layers, a mechanism monitors the
|
||||
* buffer life cycle. Finally, if data usage information are kept within the buffer,
|
||||
* it speeds up software to retrieve the execution context.
|
||||
*
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2019
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
#ifndef _CO_BUF_H_
|
||||
#define _CO_BUF_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @defgroup CO_BUF Utilities
|
||||
* @ingroup COMMON
|
||||
* @brief Time utilities
|
||||
*
|
||||
* This module contains the Common time utilities functions and macros.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdint.h> // standard definitions
|
||||
#include <stddef.h> // standard definitions
|
||||
|
||||
#include "arch.h" // Arch defines
|
||||
#include "co_list.h" // List manipulation
|
||||
#include "co_utils.h" // Bit Field manipulation
|
||||
|
||||
/*
|
||||
* MACRO DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* ENUMERATIONS DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
/// size of meta-data variables 32 bytes
|
||||
#define CO_BUF_META_DATA_SIZE (32 >> 2)
|
||||
|
||||
/// Buffer Error status codes
|
||||
enum co_buf_err
|
||||
{
|
||||
/// No Error
|
||||
CO_BUF_ERR_NO_ERROR = 0x00,
|
||||
/// Invalid parameter(s)
|
||||
CO_BUF_ERR_INVALID_PARAM = 0x01,
|
||||
/// Not enough resources
|
||||
CO_BUF_ERR_INSUFFICIENT_RESOURCE = 0x02,
|
||||
/// Resource is busy, operation cannot be performed
|
||||
CO_BUF_ERR_RESOURCE_BUSY = 0x03,
|
||||
};
|
||||
|
||||
|
||||
/// Buffer meta-data bit field
|
||||
enum co_buf_metadata_bf
|
||||
{
|
||||
/// Size of meta-data data frozen. This size has a step of 4 bytes
|
||||
CO_BUF_METADATA_FROZEN_SIZE_LSB = 0,
|
||||
CO_BUF_METADATA_FROZEN_SIZE_MASK = 0x0F,
|
||||
/// If equals 1, a callback is executed before freeing the buffer.
|
||||
CO_BUF_METADATA_FREE_CB_POS = 4,
|
||||
CO_BUF_METADATA_FREE_CB_BIT = 0x10,
|
||||
};
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* TYPE DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/// Buffer structure
|
||||
typedef struct co_buf
|
||||
{
|
||||
/// List header for chaining
|
||||
co_list_hdr_t hdr;
|
||||
/// Length of the data part
|
||||
uint16_t data_len;
|
||||
/// Prefix length available
|
||||
uint16_t head_len;
|
||||
/// Suffix length available
|
||||
uint16_t tail_len;
|
||||
/// Pool identifier (@see enum co_buf_pool_id)
|
||||
uint8_t pool_id;
|
||||
/// Acquisition counter
|
||||
uint8_t acq_cnt;
|
||||
/// Meta-data variable that can be used for multiple purposes
|
||||
/// meta-data is always 32 bits aligned
|
||||
uint32_t metadata[CO_BUF_META_DATA_SIZE];
|
||||
/// Pattern used to verify that meta-data didn�t overflow
|
||||
uint8_t pattern;
|
||||
/// Meta-data bit field (@see enum co_buf_metadata_bf)
|
||||
uint8_t metadata_bf;
|
||||
/// Padding
|
||||
uint16_t padding;
|
||||
|
||||
/// Variable buffer array that contains header, data and tail payload
|
||||
/// Length is buf_len = (head_len + data_len + tail_len)
|
||||
uint8_t buf[__ARRAY_EMPTY];
|
||||
} co_buf_t;
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function is called when all software modules has release the buffer.
|
||||
*
|
||||
* @param[in] p_env Pointer to environment that will be used as callback parameter.
|
||||
****************************************************************************************
|
||||
*/
|
||||
typedef void (*co_buf_free_cb)(co_buf_t* p_buf, void* p_env);
|
||||
|
||||
/*
|
||||
* CONSTANT DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Allocate a buffer and specify initial length of head, data and tail parts.
|
||||
* When doing a buffer allocation, acquisition counter is equals to 1.
|
||||
*
|
||||
* If total length is lower than @see CO_BUF_SMALL_SIZE and small buffer pool is not empty:
|
||||
* A buffer will be picked from small buffer pool.
|
||||
* else if total length is lower than @see CO_BUF_BIG_SIZE and big buffer pool is not empty:
|
||||
* A buffer will be picked from big buffer pool.
|
||||
* else:
|
||||
* the buffer will be dynamically allocated.
|
||||
*
|
||||
* @param[out] pp_buf Pointer to a variable that will contain the address of the allocated buffer.
|
||||
* @param[in] head_len Initial Head Length.
|
||||
* @param[in] data_len Initial Data Length.
|
||||
* @param[in] tail_len Initial Tail Length.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if buffer can be allocated.
|
||||
* CO_BUF_ERR_INSUFFICIENT_RESOURCE if no more buffers are available.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_alloc(co_buf_t** pp_buf, uint16_t head_len, uint16_t data_len, uint16_t tail_len);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Prepare a buffer and specify initial length of head, data and tail parts.
|
||||
*
|
||||
* Buffer pointer provided must have a total length greater or equals to head_len + data_len + tail_len
|
||||
* When doing a buffer allocation, acquisition counter is equals to 1.
|
||||
* Buffer isn�t free by @see co_buf_release function when acquisition counter is equals to 0.
|
||||
|
||||
*
|
||||
* @param[out] p_buf Pointer to buffer to prepare.
|
||||
* @param[in] head_len Initial Head Length.
|
||||
* @param[in] data_len Initial Data Length.
|
||||
* @param[in] tail_len Initial Tail Length.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if buffer can be allocated.
|
||||
****************************************************************************************
|
||||
*/
|
||||
// uint8_t co_buf_prepare(co_buf_t* p_buf, uint16_t head_len, uint16_t data_len, uint16_t tail_len);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function used to increment value of acquire counter of a buffer during processing
|
||||
* of buffer content.
|
||||
*
|
||||
* @param[in] p_buf Pointer to acquired buffer
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if operation succeed
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_acquire(co_buf_t *p_buf);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function used to release previously acquired buffer. The acquire counter for
|
||||
* this buffer is decremented. If the acquire counter value becomes zero,
|
||||
* the buffer is freed as no more entity is using the buffer anymore.
|
||||
*
|
||||
* if acquire counter becomes zero
|
||||
* if a free callback has been configured using @see co_buf_cb_set:
|
||||
* call the free callback
|
||||
*
|
||||
* if buffer comes from a buffer pool:
|
||||
* buffer is pushed to the corresponding pool, and available for another
|
||||
* software module
|
||||
*
|
||||
* else if buffer comes from dynamic memory:
|
||||
* corresponding memory is free
|
||||
*
|
||||
* else if a buffer has been initialized with @see co_buf_prepare:
|
||||
* nothing is done
|
||||
*
|
||||
* @note A software module shall not use a buffer after releasing it.
|
||||
*
|
||||
* @param[in] p_buf Pointer to acquired buffer.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if buffer has been released.
|
||||
* CO_BUF_ERR_INVALID_PARAM if buffer was free.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_release(co_buf_t *p_buf);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve buffer data pointer.
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
*
|
||||
* @return Pointer to first byte of data field ; NULL if an error occurs
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint8_t* co_buf_data(co_buf_t *p_buf)
|
||||
{
|
||||
uint8_t* p_ret = NULL;
|
||||
|
||||
if(p_buf)
|
||||
{
|
||||
p_ret = &(p_buf->buf[p_buf->head_len]);
|
||||
}
|
||||
|
||||
return (p_ret);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve buffer data length.
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
*
|
||||
* @return Buffer data field size. 0 if an error occurs.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint16_t co_buf_data_len(const co_buf_t *p_buf)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
|
||||
if(p_buf)
|
||||
{
|
||||
ret = p_buf->data_len;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve buffer available prefix length.
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
*
|
||||
* @return Buffer data prefix size available. 0 if an error occurs.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint16_t co_buf_head_len(const co_buf_t *p_buf)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
|
||||
if(p_buf)
|
||||
{
|
||||
ret = p_buf->head_len;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Memory Size of the buffer
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
*
|
||||
* @return Memory size of the buffer
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint16_t co_buf_size(const co_buf_t *p_buf);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve buffer head pointer.
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
*
|
||||
* @return Pointer to first byte of tail field ; NULL if an error occurs
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint8_t* co_buf_head(co_buf_t *p_buf)
|
||||
{
|
||||
uint8_t* p_ret = NULL;
|
||||
|
||||
if(p_buf)
|
||||
{
|
||||
p_ret = &(p_buf->buf[0]);
|
||||
}
|
||||
|
||||
return (p_ret);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Prefix the data with a given header length, it is mandatory that data reserved
|
||||
* length is less or equals to header length.
|
||||
* Header length is reduced according to number of byte reserved.
|
||||
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
* @param[in] length Length of prefix data to reserve.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if needed length has been reserved.
|
||||
* CO_BUF_ERR_INVALID_PARAM if provided length is higher than current length of head part.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_head_reserve(co_buf_t *p_buf, uint16_t length);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Remove a data prefix of a specific length header length, it is mandatory that
|
||||
* data released length is less or equals to data length.
|
||||
* Header length is increased according to number of byte released.
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
* @param[in] length Length of prefix data to release.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if needed length has been released.
|
||||
* CO_BUF_ERR_INVALID_PARAM if provided length is higher than current length of data part.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_head_release(co_buf_t *p_buf, uint16_t length);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve buffer tail pointer.
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
*
|
||||
* @return Pointer to first byte of tail field ; NULL if an error occurs
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint8_t* co_buf_tail(co_buf_t *p_buf)
|
||||
{
|
||||
uint8_t* p_ret = NULL;
|
||||
|
||||
if(p_buf)
|
||||
{
|
||||
p_ret = &(p_buf->buf[p_buf->head_len + p_buf->data_len]);
|
||||
}
|
||||
|
||||
return (p_ret);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve buffer available suffix length.
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
*
|
||||
* @return Buffer data suffix size available. 0 if an error occurs.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint16_t co_buf_tail_len(const co_buf_t *p_buf)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
|
||||
if(p_buf)
|
||||
{
|
||||
ret = p_buf->tail_len;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Prefix the data with a given tail length, it is mandatory that data reserved
|
||||
* length is less or equals to header length.
|
||||
* Tail length is reduced according to number of byte reserved.
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
* @param[in] length Length of suffix data to reserve.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if needed length has been reserved.
|
||||
* CO_BUF_ERR_INVALID_PARAM if provided length is higher than current length of tail part.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_tail_reserve(co_buf_t *p_buf, uint16_t length);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Remove a data suffix of a specific length header length, it is mandatory that
|
||||
* data released length is less or equals to data length.
|
||||
* Tail length is increased according to number of byte released.
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
* @param[in] length Length of suffix data to release.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if needed length has been released.
|
||||
* CO_BUF_ERR_INVALID_PARAM if provided length is higher than current length of data part.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_tail_release(co_buf_t *p_buf, uint16_t length);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve pointer to buffer meta-data. This pointer is 32-bit aligned, and
|
||||
* corresponds to buffer meta-data start pointer plus blocked meta-data length
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
*
|
||||
* @return Pointer to the available meta-data pointer ;NULL if an error occurs
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint8_t* co_buf_metadata(co_buf_t *p_buf)
|
||||
{
|
||||
uint8_t* p_ret = NULL;
|
||||
|
||||
if((p_buf) && (GETF(p_buf->metadata_bf, CO_BUF_METADATA_FROZEN_SIZE) < CO_BUF_META_DATA_SIZE))
|
||||
{
|
||||
p_ret = (uint8_t*) &(p_buf->metadata[GETF(p_buf->metadata_bf, CO_BUF_METADATA_FROZEN_SIZE)]);
|
||||
}
|
||||
|
||||
return (p_ret);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Freeze some meta-data into the buffer, this update the meta-data
|
||||
* pointer given by @see co_buf_metadata function .
|
||||
* Frozen meta-data should not be updated. A software module that has frozen some
|
||||
* meta-data must unblock it before using it or before releasing buffer.
|
||||
*
|
||||
* Length provided is aligned to 4 bytes in order to ensure that meta-data pointer
|
||||
* is always 32-bits aligned. Length parameter cannot exceed remaining meta-data
|
||||
* length.
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
* @param[in] length Number of byte in buffer meta-data to freeze.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if needed length has been frozen.
|
||||
* CO_BUF_ERR_INVALID_PARAM if provided length is higher than remaining meta-data size
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_metadata_freeze(co_buf_t *p_buf, uint8_t length);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Unfreeze some meta-data into the buffer, this update the meta-data
|
||||
* pointer given by @see co_buf_metadata function.
|
||||
* Length provided is aligned to 4 bytes in order to ensure that meta-data
|
||||
* pointer is always 32-bits aligned.
|
||||
*
|
||||
* Length parameter cannot exceed meta-data frozen length
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
* @param[in] length Number of byte in buffer meta-data to un-freeze.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if needed length has been frozen.
|
||||
* CO_BUF_ERR_INVALID_PARAM if provided length is higher than frozen meta-data size
|
||||
****************************************************************************************
|
||||
*/
|
||||
// uint8_t co_buf_metadata_unfreeze(co_buf_t *p_buf, uint8_t length);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve number of bytes in meta-data field that can be used by software layer
|
||||
*
|
||||
* @param[in] p_buf Pointer to buffer
|
||||
*
|
||||
* @return Number of byte in buffer meta-data remains 0 if an error occurs
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint8_t co_buf_metadata_len(const co_buf_t *p_buf)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
|
||||
if(p_buf)
|
||||
{
|
||||
ret = (CO_BUF_META_DATA_SIZE - GETF(p_buf->metadata_bf, CO_BUF_METADATA_FROZEN_SIZE)) << 2;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Allocate a new buffer, specify initial length of head and tail parts, plus copy
|
||||
* data of input buffer.
|
||||
*
|
||||
* @see m_buf_alloc function is used to allocate output buffer.
|
||||
*
|
||||
* @note meta-data isn't copied
|
||||
*
|
||||
* @param[in] p_buf_in Pointer to input buffer.
|
||||
* @param[in] p_buf_out Pointer to output buffer.
|
||||
* @param[in] length Length of data to copy
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if buffer can be allocated.
|
||||
* CO_BUF_ERR_INSUFFICIENT_RESOURCE if no more buffers are available.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_duplicate(const co_buf_t *p_buf_in, co_buf_t **pp_buf_out, uint16_t head_len, uint16_t tail_len);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Copy content of a buffer to another buffer.
|
||||
*
|
||||
* @param[in] p_buf_in Pointer to input buffer.
|
||||
* @param[in] p_buf_out Pointer to output buffer.
|
||||
* @param[in] length Length of data to copy
|
||||
* @param[in] copy_meta_size Indicate size of meta-data to copy. It doesn't copy frozen data.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if copy has been properly performed.
|
||||
* CO_BUF_ERR_INVALID_PARAM if the output buffer data size is cannot accept input data length.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_copy(const co_buf_t *p_buf_in, co_buf_t *p_buf_out, uint16_t length, uint8_t copy_meta_size);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Reuse a given buffer with keeping data information. This can be done only if
|
||||
* buffer has been released by other software module. meta-data data can be
|
||||
* considered empty if function execution succeeds.
|
||||
*
|
||||
* If this function succeeds it must be considered as an old buffer release and
|
||||
* new buffer allocation.
|
||||
* If function execution fails, the buffer is not considered as released
|
||||
*
|
||||
* @param[in] p_buf Pointer to the buffer.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if buffer has been properly released and reused
|
||||
* CO_BUF_ERR_RESOURCE_BUSY if buffer acquisition counter > 1
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_reuse(co_buf_t *p_buf);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Reuse a given buffer without keeping data information. This can be done only if
|
||||
* buffer has been released by other software module. meta-data data can be
|
||||
* considered empty if function execution succeeds.
|
||||
*
|
||||
* Size of header, data_ and trailing length must not exceed size of the buffer.
|
||||
*
|
||||
* If this function succeeds it must be considered as an old buffer release and
|
||||
* new buffer allocation.
|
||||
* If function execution fails, the buffer is not considered as released.
|
||||
*
|
||||
* @param[in] p_buf Pointer to the buffer.
|
||||
* @param[in] head_len Initial Head Length.
|
||||
* @param[in] data_len Initial Data Length.
|
||||
* @param[in] tail_len Initial Tail Length.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if buffer has been properly released and reused
|
||||
* CO_BUF_ERR_RESOURCE_BUSY if buffer acquisition counter > 1
|
||||
* CO_BUF_ERR_INVALID_PARAM if length fields exceed length of initial buffer
|
||||
****************************************************************************************
|
||||
*/
|
||||
// uint8_t co_buf_reuse_full(co_buf_t *p_buf, uint16_t head_len, uint16_t data_len, uint16_t tail_len);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief TThis function allows a software module to be informed when buffer is free.
|
||||
* It freezes 8 bytes in buffer meta-data.
|
||||
*
|
||||
* This function shall be called only after a buffer allocation or reuse.
|
||||
*
|
||||
* @param[in] p_buf Pointer to the buffer.
|
||||
* @param[in] cb_free Pointer to the function called when the buffer is free.
|
||||
* @param[in] p_env Pointer to environment that will be used as callback parameter.
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR callback has been properly set
|
||||
* CO_BUF_ERR_RESOURCE_BUSY if some buffer meta-data already frozen
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_cb_free_set(co_buf_t *p_buf, co_buf_free_cb cb_free, void* p_env);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function copies content of an input memory data to the data part of a
|
||||
* buffer. The length field shall not exceed buffer data length.
|
||||
*
|
||||
* @param[in] p_buf Pointer to the buffer.
|
||||
* @param[in] p_in Pointer to input data.
|
||||
* @param[in] length Length of data to copy
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if copy has been properly performed.
|
||||
* CO_BUF_ERR_INVALID_PARAM if data length fields < length parameter
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_copy_data_from_mem(co_buf_t *p_buf, const uint8_t *p_in, uint16_t length);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function copies data part of a buffer into an output memory block.
|
||||
* The length field shall not exceed buffer data length..
|
||||
*
|
||||
* @param[in] p_buf Pointer to the buffer.
|
||||
* @param[in] p_out Pointer to output data.
|
||||
* @param[in] length Length of data to copy
|
||||
*
|
||||
* @return CO_BUF_ERR_NO_ERROR if copy has been properly performed.
|
||||
* CO_BUF_ERR_INVALID_PARAM if data length fields < length parameter
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t co_buf_copy_data_to_mem(const co_buf_t *p_buf, uint8_t *p_out, uint16_t length);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize Common buffer module.
|
||||
*
|
||||
* @param[in] init_type Type of initialization (@see enum rwip_init_type)
|
||||
* @param[in] p_big_pool Pointer to the Big pool memory Array
|
||||
* @param[in] p_small_pool Pointer to the Small pool memory Array
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_buf_init(uint8_t init_type, uint32_t* p_big_pool, uint32_t* p_small_pool);
|
||||
|
||||
/// @} CO_BUF
|
||||
|
||||
#endif // _CO_BUF_H_
|
||||
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file co_djob.h
|
||||
*
|
||||
* @brief Common delayed job definitions
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2019
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
#ifndef _CO_DJOB_H_
|
||||
#define _CO_DJOB_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @defgroup CO_DJOB Utilities
|
||||
* @ingroup COMMON
|
||||
* @brief Delayed job utilities
|
||||
*
|
||||
* This module contains the delayed job utilities functions and macros.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdint.h> // standard definitions
|
||||
#include <stddef.h> // standard definitions
|
||||
#include "co_list.h" // common bt definitions
|
||||
|
||||
|
||||
/*
|
||||
* MACRO DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* ENUMERATIONS DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* TYPE DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Job function to called into a background context
|
||||
*
|
||||
* @param[in] p_env Pointer to environment that will be used as callback parameter.
|
||||
****************************************************************************************
|
||||
*/
|
||||
typedef void (*co_djob_cb)(void* p_env);
|
||||
|
||||
/// Job element structure
|
||||
typedef struct co_djob
|
||||
{
|
||||
/// List element header
|
||||
co_list_hdr_t hdr;
|
||||
/// Pointer to environment that will be used as callback parameter.
|
||||
void* p_env;
|
||||
/// Callback to execute in background context
|
||||
co_djob_cb cb;
|
||||
} co_djob_t;
|
||||
|
||||
|
||||
/*
|
||||
* CONSTANT DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************************
|
||||
* Delayed Job functions
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Prepare Delayed job structure
|
||||
*
|
||||
* @param[in] p_djob Pointer to the delayed job structure
|
||||
* @param[in] cb Callback to execute in background context
|
||||
* @param[in] p_env Pointer to environment that will be used as callback parameter.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_djob_prepare(co_djob_t* p_djob, co_djob_cb cb, void* p_env);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Register to execute a job delayed in background
|
||||
*
|
||||
* @param[in] p_djob Pointer to the delayed job structure
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_djob_reg(co_djob_t* p_djob);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Un-register a job that waits to be executed
|
||||
*
|
||||
* @param[in] p_djob Pointer to the delayed job structure
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_djob_unreg(co_djob_t* p_djob);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize Common delayed job module.
|
||||
*
|
||||
* @param[in] init_type Type of initialization (@see enum rwip_init_type)
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_djob_init(uint8_t init_type);
|
||||
/// @} CO_DJOB
|
||||
|
||||
#endif // _CO_DJOB_H_
|
||||
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file co_endian.h
|
||||
*
|
||||
* @brief Common endianness conversion functions
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _CO_ENDIAN_H_
|
||||
#define _CO_ENDIAN_H_
|
||||
|
||||
#include <stdint.h> // standard integer definitions
|
||||
#include "rwip_config.h" // stack configuration
|
||||
#include "arch.h" // architectural platform definition
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @defgroup CO_ENDIAN Endianness
|
||||
* @ingroup COMMON
|
||||
* @brief Endianness conversion functions.
|
||||
*
|
||||
* This set of functions converts values between the local system
|
||||
* and a external one. It is inspired from the <tt>htonl</tt>-like functions
|
||||
* from the standard C library.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* struct eth_header *header = get_header(); // get pointer on Eth II packet header
|
||||
* uint16_t eth_id; // will contain the type of the packet
|
||||
* eth_id = co_ntohs(header->eth_id); // retrieve the type with correct endianness
|
||||
* @endcode
|
||||
*
|
||||
* @{
|
||||
* ****************************************************************************************
|
||||
* */
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Swap bytes of an array of bytes
|
||||
* .
|
||||
* The swap is done in every case. Should not be called directly.
|
||||
*
|
||||
* @param[in] p_val_out The output value.
|
||||
* @param[in] p_val_in The input value.
|
||||
*
|
||||
* @param[in] len number of bytes to swap
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE void co_bswap(uint8_t* p_val_out, const uint8_t* p_val_in, uint16_t len)
|
||||
{
|
||||
while (len > 0)
|
||||
{
|
||||
len--;
|
||||
*p_val_out = p_val_in[len];
|
||||
p_val_out++;
|
||||
}
|
||||
}
|
||||
/// @} CO_ENDIAN
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Swap bytes of a 32 bits value.
|
||||
* The swap is done in every case. Should not be called directly.
|
||||
* @param[in] val32 The 32 bits value to swap.
|
||||
* @return The 32 bit swapped value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_bswap32(uint32_t val32)
|
||||
{
|
||||
return (val32<<24) | ((val32<<8)&0xFF0000) | ((val32>>8)&0xFF00) | ((val32>>24)&0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Swap bytes of a 24 bits value.
|
||||
* The swap is done in every case. Should not be called directly.
|
||||
* @param[in] val24 The 24 bits value to swap.
|
||||
* @return The 24 bit swapped value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_bswap24(uint32_t val24)
|
||||
{
|
||||
return ((val24<<16)&0xFF0000) | ((val24)&0xFF00) | ((val24>>16)&0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Swap bytes of a 16 bits value.
|
||||
* The swap is done in every case. Should not be called directly.
|
||||
* @param[in] val16 The 16 bit value to swap.
|
||||
* @return The 16 bit swapped value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint16_t co_bswap16(uint16_t val16)
|
||||
{
|
||||
return ((val16<<8)&0xFF00) | ((val16>>8)&0xFF);
|
||||
}
|
||||
/// @} CO_ENDIAN
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ****************************************************************************************
|
||||
* @defgroup CO_ENDIAN_NET Endianness (Network)
|
||||
* @ingroup CO_ENDIAN
|
||||
* @brief Endianness conversion functions for Network data
|
||||
*
|
||||
* Converts values between the local system and big-endian network data
|
||||
* (e.g. IP, Ethernet, but NOT WLAN).
|
||||
*
|
||||
* The \b host term in the descriptions of these functions refers
|
||||
* to the local system, i.e. \b application or \b embedded system.
|
||||
* Therefore, these functions will behave differently depending on which
|
||||
* side they are used. The reason of this terminology is to keep the
|
||||
* same name than the standard C function.
|
||||
*
|
||||
* Behavior will depends on the endianness of the host:
|
||||
* - little endian: swap bytes;
|
||||
* - big endian: identity function.
|
||||
*
|
||||
* @{
|
||||
* ****************************************************************************************
|
||||
* */
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert host to network long word.
|
||||
*
|
||||
* @param[in] hostlong Long word value to convert.
|
||||
*
|
||||
* @return The converted long word.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_htonl(uint32_t hostlong)
|
||||
{
|
||||
#if (!CPU_LE)
|
||||
return hostlong;
|
||||
#else
|
||||
return co_bswap32(hostlong);
|
||||
#endif // CPU_LE
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert host to network long 24-bit value.
|
||||
*
|
||||
* @param[in] val24 24-bit value to convert.
|
||||
*
|
||||
* @return The converted 24-but value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_hton24(uint32_t host24)
|
||||
{
|
||||
#if (!CPU_LE)
|
||||
return host24;
|
||||
#else
|
||||
return co_bswap24(host24);
|
||||
#endif // CPU_LE
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert host to network short word.
|
||||
*
|
||||
* @param[in] hostshort Short word value to convert.
|
||||
*
|
||||
* @return The converted short word.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint16_t co_htons(uint16_t hostshort)
|
||||
{
|
||||
#if (!CPU_LE)
|
||||
return hostshort;
|
||||
#else
|
||||
return co_bswap16(hostshort);
|
||||
#endif // CPU_LE
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert network to host long word.
|
||||
*
|
||||
* @param[in] netlong Long word value to convert.
|
||||
*
|
||||
* @return The converted long word.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_ntohl(uint32_t netlong)
|
||||
{
|
||||
return co_htonl(netlong);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert network to host 24-bit value.
|
||||
*
|
||||
* @param[in] val24 24-bit to convert.
|
||||
*
|
||||
* @return The converted 24-bit value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_ntoh24(uint32_t val24)
|
||||
{
|
||||
return co_hton24(val24);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert network to host short word.
|
||||
*
|
||||
* @param[in] netshort Short word value to convert.
|
||||
*
|
||||
* @return The converted short word.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint16_t co_ntohs(uint16_t netshort)
|
||||
{
|
||||
return co_htons(netshort);
|
||||
}
|
||||
/// @} CO_ENDIAN_NET
|
||||
|
||||
/**
|
||||
* ****************************************************************************************
|
||||
* @defgroup CO_ENDIAN_BT Endianness (BT)
|
||||
* @ingroup CO_ENDIAN
|
||||
* @brief Endianness conversion functions for Bluetooth data (HCI and protocol)
|
||||
*
|
||||
* Converts values between the local system and little-endian Bluetooth data.
|
||||
*
|
||||
* The \b host term in the descriptions of these functions refers
|
||||
* to the local system (check \ref CO_ENDIAN_NET "this comment").
|
||||
*
|
||||
* Behavior will depends on the endianness of the host:
|
||||
* - little endian: identity function;
|
||||
* - big endian: swap bytes.
|
||||
*
|
||||
* @addtogroup CO_ENDIAN_BT
|
||||
* @{
|
||||
* ****************************************************************************************
|
||||
* */
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert Bluetooth to host 24-bit value.
|
||||
*
|
||||
* @param[in] val24 24-bit to convert.
|
||||
*
|
||||
* @return The converted 24-bit value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_htob24(uint32_t val24)
|
||||
{
|
||||
#if (CPU_LE)
|
||||
return val24;
|
||||
#else
|
||||
return co_hton24(val24);
|
||||
#endif // CPU_LE
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert host to Bluetooth long word.
|
||||
*
|
||||
* @param[in] hostlong Long word value to convert.
|
||||
*
|
||||
* @return The converted long word.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_htobl(uint32_t hostlong)
|
||||
{
|
||||
#if (CPU_LE)
|
||||
return hostlong;
|
||||
#else
|
||||
return co_bswap32(hostlong);
|
||||
#endif // CPU_LE
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert host to Bluetooth short word.
|
||||
*
|
||||
* @param[in] hostshort Short word value to convert.
|
||||
*
|
||||
* @return The converted short word.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint16_t co_htobs(uint16_t hostshort)
|
||||
{
|
||||
#if (CPU_LE)
|
||||
return hostshort;
|
||||
#else
|
||||
return co_bswap16(hostshort);
|
||||
#endif // CPU_LE
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert Bluetooth to host 24-bit value.
|
||||
*
|
||||
* @param[in] val24 24-bit to convert.
|
||||
*
|
||||
* @return The converted 24-bit value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_btoh24(uint32_t val24)
|
||||
{
|
||||
return co_htob24(val24);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert Bluetooth to host long word.
|
||||
*
|
||||
* @param[in] btlong Long word value to convert.
|
||||
*
|
||||
* @return The converted long word.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_btohl(uint32_t btlong)
|
||||
{
|
||||
return co_htobl(btlong);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert Bluetooth to host short word.
|
||||
*
|
||||
* @param[in] btshort Short word value to convert.
|
||||
*
|
||||
* @return The converted short word.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint16_t co_btohs(uint16_t btshort)
|
||||
{
|
||||
return co_htobs(btshort);
|
||||
}
|
||||
/// @} CO_ENDIAN
|
||||
|
||||
#endif // _CO_ENDIAN_H_
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file co_error.h
|
||||
*
|
||||
* @brief List of codes for error in RW Software.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef CO_ERROR_H_
|
||||
#define CO_ERROR_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup CO_ERROR Error Codes
|
||||
* @ingroup COMMON
|
||||
* @brief Defines error codes in messages.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
****************************************************************************************
|
||||
*/
|
||||
enum co_error
|
||||
{
|
||||
/*****************************************************
|
||||
*** ERROR CODES ***
|
||||
*****************************************************/
|
||||
|
||||
CO_ERROR_NO_ERROR = 0x00,
|
||||
CO_ERROR_UNKNOWN_HCI_COMMAND = 0x01,
|
||||
CO_ERROR_UNKNOWN_CONNECTION_ID = 0x02,
|
||||
CO_ERROR_HARDWARE_FAILURE = 0x03,
|
||||
CO_ERROR_PAGE_TIMEOUT = 0x04,
|
||||
CO_ERROR_AUTH_FAILURE = 0x05,
|
||||
CO_ERROR_PIN_MISSING = 0x06,
|
||||
CO_ERROR_MEMORY_CAPA_EXCEED = 0x07,
|
||||
CO_ERROR_CON_TIMEOUT = 0x08,
|
||||
CO_ERROR_CON_LIMIT_EXCEED = 0x09,
|
||||
CO_ERROR_SYNC_CON_LIMIT_DEV_EXCEED = 0x0A,
|
||||
CO_ERROR_CON_ALREADY_EXISTS = 0x0B,
|
||||
CO_ERROR_COMMAND_DISALLOWED = 0x0C,
|
||||
CO_ERROR_CONN_REJ_LIMITED_RESOURCES = 0x0D,
|
||||
CO_ERROR_CONN_REJ_SECURITY_REASONS = 0x0E,
|
||||
CO_ERROR_CONN_REJ_UNACCEPTABLE_BDADDR = 0x0F,
|
||||
CO_ERROR_CONN_ACCEPT_TIMEOUT_EXCEED = 0x10,
|
||||
CO_ERROR_UNSUPPORTED = 0x11,
|
||||
CO_ERROR_INVALID_HCI_PARAM = 0x12,
|
||||
CO_ERROR_REMOTE_USER_TERM_CON = 0x13,
|
||||
CO_ERROR_REMOTE_DEV_TERM_LOW_RESOURCES = 0x14,
|
||||
CO_ERROR_REMOTE_DEV_POWER_OFF = 0x15,
|
||||
CO_ERROR_CON_TERM_BY_LOCAL_HOST = 0x16,
|
||||
CO_ERROR_REPEATED_ATTEMPTS = 0x17,
|
||||
CO_ERROR_PAIRING_NOT_ALLOWED = 0x18,
|
||||
CO_ERROR_UNKNOWN_LMP_PDU = 0x19,
|
||||
CO_ERROR_UNSUPPORTED_REMOTE_FEATURE = 0x1A,
|
||||
CO_ERROR_SCO_OFFSET_REJECTED = 0x1B,
|
||||
CO_ERROR_SCO_INTERVAL_REJECTED = 0x1C,
|
||||
CO_ERROR_SCO_AIR_MODE_REJECTED = 0x1D,
|
||||
CO_ERROR_INVALID_LMP_PARAM = 0x1E,
|
||||
CO_ERROR_UNSPECIFIED_ERROR = 0x1F,
|
||||
CO_ERROR_UNSUPPORTED_LMP_PARAM_VALUE = 0x20,
|
||||
CO_ERROR_ROLE_CHANGE_NOT_ALLOWED = 0x21,
|
||||
CO_ERROR_LMP_RSP_TIMEOUT = 0x22,
|
||||
CO_ERROR_LMP_COLLISION = 0x23,
|
||||
CO_ERROR_LMP_PDU_NOT_ALLOWED = 0x24,
|
||||
CO_ERROR_ENC_MODE_NOT_ACCEPT = 0x25,
|
||||
CO_ERROR_LINK_KEY_CANT_CHANGE = 0x26,
|
||||
CO_ERROR_QOS_NOT_SUPPORTED = 0x27,
|
||||
CO_ERROR_INSTANT_PASSED = 0x28,
|
||||
CO_ERROR_PAIRING_WITH_UNIT_KEY_NOT_SUP = 0x29,
|
||||
CO_ERROR_DIFF_TRANSACTION_COLLISION = 0x2A,
|
||||
CO_ERROR_QOS_UNACCEPTABLE_PARAM = 0x2C,
|
||||
CO_ERROR_QOS_REJECTED = 0x2D,
|
||||
CO_ERROR_CHANNEL_CLASS_NOT_SUP = 0x2E,
|
||||
CO_ERROR_INSUFFICIENT_SECURITY = 0x2F,
|
||||
CO_ERROR_PARAM_OUT_OF_MAND_RANGE = 0x30,
|
||||
CO_ERROR_ROLE_SWITCH_PEND = 0x32, /* LM_ROLE_SWITCH_PENDING */
|
||||
CO_ERROR_RESERVED_SLOT_VIOLATION = 0x34, /* LM_RESERVED_SLOT_VIOLATION */
|
||||
CO_ERROR_ROLE_SWITCH_FAIL = 0x35, /* LM_ROLE_SWITCH_FAILED */
|
||||
CO_ERROR_EIR_TOO_LARGE = 0x36, /* LM_EXTENDED_INQUIRY_RESPONSE_TOO_LARGE */
|
||||
CO_ERROR_SP_NOT_SUPPORTED_HOST = 0x37,
|
||||
CO_ERROR_HOST_BUSY_PAIRING = 0x38,
|
||||
CO_ERROR_CONTROLLER_BUSY = 0x3A,
|
||||
CO_ERROR_UNACCEPTABLE_CONN_PARAM = 0x3B,
|
||||
CO_ERROR_ADV_TO = 0x3C,
|
||||
CO_ERROR_TERMINATED_MIC_FAILURE = 0x3D,
|
||||
CO_ERROR_CONN_FAILED_TO_BE_EST = 0x3E,
|
||||
CO_ERROR_CCA_REJ_USE_CLOCK_DRAG = 0x40,
|
||||
CO_ERROR_TYPE0_SUBMAP_NOT_DEFINED = 0x41,
|
||||
CO_ERROR_UNKNOWN_ADVERTISING_ID = 0x42,
|
||||
CO_ERROR_LIMIT_REACHED = 0x43,
|
||||
CO_ERROR_OPERATION_CANCELED_BY_HOST = 0x44,
|
||||
CO_ERROR_PKT_TOO_LONG = 0x45,
|
||||
|
||||
CO_ERROR_UNDEFINED = 0xFF,
|
||||
|
||||
|
||||
/*****************************************************
|
||||
*** HW ERROR CODES ***
|
||||
*****************************************************/
|
||||
|
||||
CO_ERROR_HW_UART_OUT_OF_SYNC = 0x00,
|
||||
CO_ERROR_HW_MEM_ALLOC_FAIL = 0x01,
|
||||
};
|
||||
|
||||
/// @} CO_ERROR
|
||||
|
||||
#endif // CO_ERROR_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,316 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file co_list.h
|
||||
*
|
||||
* @brief Common list structures definitions
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _CO_LIST_H_
|
||||
#define _CO_LIST_H_
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @defgroup CO_LIST List management
|
||||
* @ingroup COMMON
|
||||
*
|
||||
* @brief List management.
|
||||
*
|
||||
* This module contains the list structures and handling functions.
|
||||
* @{
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include <stdint.h> // standard definition
|
||||
#include <stdbool.h> // boolean definition
|
||||
#include <stddef.h> // for NULL and size_t
|
||||
#include "rwip_config.h" // stack configuration
|
||||
#include "compiler.h" // for __INLINE
|
||||
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// structure of a list element header
|
||||
/*@TRACE*/
|
||||
struct co_list_hdr
|
||||
{
|
||||
/// Pointer to next co_list_hdr
|
||||
struct co_list_hdr *next;
|
||||
};
|
||||
|
||||
/// simplify type name of list element header
|
||||
typedef struct co_list_hdr co_list_hdr_t;
|
||||
|
||||
/// structure of a list
|
||||
struct co_list
|
||||
{
|
||||
/// pointer to first element of the list
|
||||
struct co_list_hdr *first;
|
||||
/// pointer to the last element
|
||||
struct co_list_hdr *last;
|
||||
|
||||
#if (KE_PROFILING)
|
||||
/// number of element in the list
|
||||
uint32_t cnt;
|
||||
/// max number of element in the list
|
||||
uint32_t maxcnt;
|
||||
/// min number of element in the list
|
||||
uint32_t mincnt;
|
||||
#endif //KE_PROFILING
|
||||
};
|
||||
|
||||
/// simplify type name of list
|
||||
typedef struct co_list co_list_t;
|
||||
|
||||
/*
|
||||
* MACROS
|
||||
****************************************************************************************
|
||||
*/
|
||||
/// pop a specific element from the list
|
||||
#define CO_LIST_POP_ELT(list, elt) co_list_extract(&(list), &(elt->hdr));
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize a list to defaults values.
|
||||
*
|
||||
* @param list Pointer to the list structure.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_list_init(struct co_list *list);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Construct a list of free elements representing a pool
|
||||
*
|
||||
* @param list Pointer to the list structure
|
||||
* @param pool Pointer to the pool to be initialized
|
||||
* @param elmt_size Size of one element of the pool (in bytes)
|
||||
* @param elmt_cnt Number of elements available in the pool
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_list_pool_init(struct co_list *list,
|
||||
void *pool,
|
||||
size_t elmt_size,
|
||||
uint32_t elmt_cnt);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Add an element as last on the list.
|
||||
*
|
||||
* @param list Pointer to the list structure
|
||||
* @param list_hdr Pointer to the header to add at the end of the list
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_list_push_back(struct co_list *list, struct co_list_hdr *list_hdr);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Append a sequence of elements at the end of a list.
|
||||
*
|
||||
* Note: the elements to append shall be linked together
|
||||
*
|
||||
* @param list Pointer to the list structure
|
||||
* @param first_hdr Pointer to the first element to append
|
||||
* @param last_hdr Pointer to the last element to append
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_list_push_back_sublist(struct co_list *list, struct co_list_hdr *first_hdr, struct co_list_hdr *last_hdr);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Add an element as first on the list.
|
||||
*
|
||||
* @param list Pointer to the list structure
|
||||
* @param list_hdr Pointer to the header to add at the beginning of the list
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_list_push_front(struct co_list *list, struct co_list_hdr *list_hdr);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Extract the first element of the list.
|
||||
* @param list Pointer to the list structure
|
||||
* @return The pointer to the element extracted, and NULL if the list is empty.
|
||||
****************************************************************************************
|
||||
*/
|
||||
struct co_list_hdr *co_list_pop_front(struct co_list *list);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Search for a given element in the list, and extract it if found.
|
||||
*
|
||||
* @param list Pointer to the list structure
|
||||
* @param list_hdr Element to extract
|
||||
*
|
||||
* @return true if the element is found in the list, false otherwise
|
||||
****************************************************************************************
|
||||
*/
|
||||
bool co_list_extract(struct co_list *list, struct co_list_hdr *list_hdr);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Extract an element when the previous element is known
|
||||
*
|
||||
* Note: the element to remove shall follow immediately the reference within the list
|
||||
*
|
||||
* @param list Pointer to the list structure
|
||||
* @param elt_ref_hdr Pointer to the referenced element (NULL if element to extract is the first in the list)
|
||||
* @param elt_to_rem_hdr Pointer to the element to be extracted
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_list_extract_after(struct co_list *list, struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_rem_hdr);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Extract a sub-list when the previous element is known
|
||||
*
|
||||
* Note: the elements to remove shall be linked together and follow immediately the reference element
|
||||
*
|
||||
* @param[in] list Pointer to the list structure
|
||||
* @param[in] ref_hdr Pointer to the referenced element (NULL if first element to extract is first in the list)
|
||||
* @param[in] last_hdr Pointer to the last element to extract ()
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_list_extract_sublist(struct co_list *list, struct co_list_hdr *ref_hdr, struct co_list_hdr *last_hdr);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Searched a given element in the list.
|
||||
*
|
||||
* @param list Pointer to the list structure
|
||||
* @param list_hdr Pointer to the searched element
|
||||
*
|
||||
* @return true if the element is found in the list, false otherwise
|
||||
****************************************************************************************
|
||||
*/
|
||||
// bool co_list_find(struct co_list *list, struct co_list_hdr *list_hdr);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Merge two lists in a single one.
|
||||
*
|
||||
* This function appends the list pointed by list2 to the list pointed by list1. Once the
|
||||
* merge is done, it empties list2.
|
||||
*
|
||||
* @param list1 Pointer to the destination list
|
||||
* @param list2 Pointer to the list to append to list1
|
||||
****************************************************************************************
|
||||
*/
|
||||
// void co_list_merge(struct co_list *list1, struct co_list *list2);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Insert a given element in the list before the referenced element.
|
||||
*
|
||||
* @param list Pointer to the list structure
|
||||
* @param elt_ref_hdr Pointer to the referenced element
|
||||
* @param elt_to_add_hdr Pointer to the element to be inserted
|
||||
*
|
||||
* @return true if the element is found in the list, false otherwise
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_list_insert_before(struct co_list *list,
|
||||
struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_add_hdr);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Insert a given element in the list after the referenced element.
|
||||
*
|
||||
* @param list Pointer to the list structure
|
||||
* @param elt_ref_hdr Pointer to the referenced element
|
||||
* @param elt_to_add_hdr Pointer to the element to be inserted
|
||||
*
|
||||
* @return true if the element is found in the list, false otherwise
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_list_insert_after(struct co_list *list,
|
||||
struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_add_hdr);
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Count number of elements present in the list
|
||||
*
|
||||
* @param list Pointer to the list structure
|
||||
*
|
||||
* @return Number of elements present in the list
|
||||
****************************************************************************************
|
||||
*/
|
||||
// uint16_t co_list_size(struct co_list *list);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Test if the list is empty.
|
||||
* @param list Pointer to the list structure.
|
||||
* @return true if the list is empty, false else otherwise.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE bool co_list_is_empty(const struct co_list *const list)
|
||||
{
|
||||
bool listempty;
|
||||
listempty = (list->first == NULL);
|
||||
return (listempty);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Pick the first element from the list without removing it.
|
||||
*
|
||||
* @param list Pointer to the list structure.
|
||||
*
|
||||
* @return First element address. Returns NULL pointer if the list is empty.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE struct co_list_hdr *co_list_pick(const struct co_list *const list)
|
||||
{
|
||||
return(list->first);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Pick last element from the list without removing it.
|
||||
*
|
||||
* @param list Pointer to the list structure.
|
||||
*
|
||||
* @return Last element address. Returns NULL pointer if the list is empty.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE struct co_list_hdr *co_list_tail(const struct co_list *const list)
|
||||
{
|
||||
return(list->last);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Return following element of a list element.
|
||||
*
|
||||
* @param list_hdr Pointer to the list element.
|
||||
*
|
||||
* @return The pointer to the next element.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE struct co_list_hdr *co_list_next(const struct co_list_hdr *const list_hdr)
|
||||
{
|
||||
return(list_hdr->next);
|
||||
}
|
||||
|
||||
/// @} CO_LIST
|
||||
#endif // _CO_LIST_H_
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,307 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file co_math.h
|
||||
*
|
||||
* @brief Common optimized math functions
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _CO_MATH_H_
|
||||
#define _CO_MATH_H_
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @defgroup CO_MATH Math functions
|
||||
* @ingroup COMMON
|
||||
* @brief Optimized math functions and other computations.
|
||||
*
|
||||
* @{
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include <stdint.h> // standard integer definitions
|
||||
#include <stdbool.h> // boolean definitions
|
||||
#include <stdlib.h> // standard library
|
||||
#include "compiler.h" // for __INLINE
|
||||
#include "arch.h" // for ASSERT_ERR
|
||||
|
||||
extern void srand (unsigned int seed);
|
||||
extern int rand (void);
|
||||
|
||||
/*
|
||||
* MACROS
|
||||
****************************************************************************************
|
||||
*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Return value with one bit set.
|
||||
*
|
||||
* @param[in] pos Position of the bit to set.
|
||||
*
|
||||
* @return Value with one bit set. There is no return type since this is a macro and this
|
||||
* will be resolved by the compiler upon assignment to an l-value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CO_BIT(pos) (1UL<<(pos))
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Return value bit into a bit field.
|
||||
*
|
||||
* @param[in] bf Bit Field
|
||||
* @param[in] pos Position of the bit
|
||||
*
|
||||
* @return value of a bit into a bit field
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CO_BIT_GET(bf, pos) (((((uint8_t*)bf)[((pos) >> 3)])>>((pos) & 0x7)) & 0x1)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Update value bit into a bit field.
|
||||
*
|
||||
* @param[in] bf Bit Field
|
||||
* @param[in] pos Position of the bit
|
||||
* @param[in] val New value of the bit (0 or 1)
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CO_BIT_SET(bf, pos, val) (((uint8_t*)bf)[((pos) >> 3)]) = ((((uint8_t*)bf)[((pos) >> 3)]) & ~CO_BIT(((pos) & 0x7))) \
|
||||
| (((val) & 0x1) << ((pos) & 0x7))
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Align val on the multiple of 4 equal or nearest higher.
|
||||
* @param[in] val Value to align.
|
||||
* @return Value aligned.
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CO_ALIGN4_HI(val) (((val)+3)&~3)
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Align val on the multiple of 4 equal or nearest lower.
|
||||
* @param[in] val Value to align.
|
||||
* @return Value aligned.
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CO_ALIGN4_LO(val) ((val)&~3)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Align val on the multiple of 2 equal or nearest higher.
|
||||
* @param[in] val Value to align.
|
||||
* @return Value aligned.
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CO_ALIGN2_HI(val) (((val)+1)&~1)
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Align val on the multiple of 2 equal or nearest lower.
|
||||
* @param[in] val Value to align.
|
||||
* @return Value aligned.
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CO_ALIGN2_LO(val) ((val)&~1)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* Perform a division and ceil up the result
|
||||
*
|
||||
* @param[in] val Value to divide
|
||||
* @param[in] div Divide value
|
||||
* @return ceil(val/div)
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CO_DIVIDE_CEIL(val, div) (((val) + ((div) - 1))/ (div))
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* Perform a division and round the result
|
||||
*
|
||||
* @param[in] val Value to divide
|
||||
* @param[in] div Divide value
|
||||
* @return round(val/div)
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CO_DIVIDE_ROUND(val, div) (((val) + ((div) >> 1))/ (div))
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* Perform a modulo operation
|
||||
*
|
||||
* @param[in] val Dividend
|
||||
* @param[in] div Divisor
|
||||
* @return val/div)
|
||||
****************************************************************************************
|
||||
*/
|
||||
//#define CO_MOD(val, div) ((val) % (div))
|
||||
__INLINE uint32_t co_mod(uint32_t val, uint32_t div)
|
||||
{
|
||||
ASSERT_ERR(div);
|
||||
return ((val) % (div));
|
||||
}
|
||||
#define CO_MOD(val, div) co_mod(val, div)
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION DEFINTIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Count leading zeros.
|
||||
* @param[in] val Value to count the number of leading zeros on.
|
||||
* @return Number of leading zeros when value is written as 32 bits.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_clz(uint32_t val)
|
||||
{
|
||||
#if defined(__arm__)
|
||||
return __builtin_clz(val);
|
||||
#elif defined(__GNUC__)
|
||||
if (val == 0)
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
return __builtin_clz(val);
|
||||
#else
|
||||
uint32_t i;
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (val & CO_BIT(31 - i))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
#endif // defined(__arm__)
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Count trailing zeros.
|
||||
* @param[in] val Value to count the number of trailing zeros on.
|
||||
* @return Number of trailing zeros when value is written as 32 bits.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_ctz(uint32_t val)
|
||||
{
|
||||
#if defined(__arm__)
|
||||
return __builtin_ctz(val);
|
||||
#elif defined(__GNUC__)
|
||||
if (val == 0)
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
return __builtin_ctz(val);
|
||||
#else
|
||||
uint32_t i;
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (val & CO_BIT(i))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
#endif // defined(__arm__)
|
||||
}
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function to initialize the random seed.
|
||||
* @param[in] seed The seed number to use to generate the random sequence.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE void co_random_init(uint32_t seed)
|
||||
{
|
||||
srand(seed);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function to get an 8 bit random number.
|
||||
* @return Random byte value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint8_t co_rand_byte(void)
|
||||
{
|
||||
return (uint8_t)(rand() & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function to get an 16 bit random number.
|
||||
* @return Random half word value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint16_t co_rand_hword(void)
|
||||
{
|
||||
return (uint16_t)(rand() & 0xFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function to get an 32 bit random number.
|
||||
* @return Random word value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_rand_word(void)
|
||||
{
|
||||
return (uint32_t)rand();
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function to return the smallest of 2 unsigned 32 bits words.
|
||||
* @return The smallest value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_min(uint32_t a, uint32_t b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function to return the smallest of 2 signed 32 bits words.
|
||||
* @return The smallest value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE int32_t co_min_s(int32_t a, int32_t b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function to return the greatest of 2 unsigned 32 bits words.
|
||||
* @return The greatest value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_max(uint32_t a, uint32_t b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function to return the absolute value of a signed integer.
|
||||
* @return The absolute value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE int co_abs(int val)
|
||||
{
|
||||
return (val < 0) ? (0 - val) : val;
|
||||
}
|
||||
|
||||
/// @} CO_MATH
|
||||
|
||||
|
||||
#endif // _CO_MATH_H_
|
||||
@@ -0,0 +1,210 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file co_time.h
|
||||
*
|
||||
* @brief The Common Time module provides information about the device time and a
|
||||
* scheduler for timers used by the different modules. It maintains a list of
|
||||
* pending timers sorted by ascending expiration time. One timer is programmed
|
||||
* at a given time. A callback is associated with each timer and is called upon
|
||||
* expiration of the timer.
|
||||
*
|
||||
* Timers shall be used for non real time software.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2019
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
#ifndef _CO_TIME_H_
|
||||
#define _CO_TIME_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @defgroup CO_TIME Utilities
|
||||
* @ingroup COMMON
|
||||
* @brief Time utilities
|
||||
*
|
||||
* This module contains the Common time utilities functions and macros.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdint.h> // standard definitions
|
||||
#include <stddef.h> // standard definitions
|
||||
|
||||
/*
|
||||
* MACRO DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* ENUMERATIONS DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* TYPE DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Function to called once timer expires
|
||||
*
|
||||
* @param[in] p_env Pointer to environment that will be used as callback parameter.
|
||||
****************************************************************************************
|
||||
*/
|
||||
typedef void (*co_time_timer_cb)(void* p_env);
|
||||
|
||||
/// Timer structure
|
||||
typedef struct co_time_timer
|
||||
{
|
||||
/// Pointer to next timer in timer list
|
||||
struct co_time_timer * p_next;
|
||||
/// Pointer to environment that will be used as callback parameter.
|
||||
void* p_env;
|
||||
/// Callback to execute in background context upon timer expiration
|
||||
co_time_timer_cb cb;
|
||||
/// Expiration time [0-31] part (in milliseconds)
|
||||
uint32_t exp_time_ms_lsb;
|
||||
/// Timer bit field (@see enum co_time_timer_bf)
|
||||
uint32_t timer_bf;
|
||||
} co_time_timer_t;
|
||||
|
||||
|
||||
/// Time Structure
|
||||
typedef struct co_time
|
||||
{
|
||||
/// Current time [0-31] part (in milliseconds)
|
||||
uint32_t ms_lsb;
|
||||
/// Current time [32-39] part (in milliseconds)
|
||||
uint8_t ms_msb;
|
||||
} co_time_t;
|
||||
|
||||
|
||||
/*
|
||||
* CONSTANT DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize Common time module.
|
||||
*
|
||||
* @param[in] init_type Type of initialization (@see enum rwip_init_type)
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_time_init(uint8_t init_type);
|
||||
|
||||
/*
|
||||
****************************************************************************************
|
||||
* Time and timer functions
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve current time in milliseconds.
|
||||
*
|
||||
* Time value can be either Up-time of the device or Time since the device has been
|
||||
* started for the first time.
|
||||
*
|
||||
* This depends if system is able to compensate power-off time to update internal time value
|
||||
*
|
||||
* @return current time in milliseconds.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
co_time_t co_time_get(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve current time in milliseconds.
|
||||
*
|
||||
* Compensate device time. This compensation should be done after power-up of the device.
|
||||
* The time compensation is automatically performed by device when wake-up from sleep mode.
|
||||
* This function shall be called when no timer are programmed at device start-up.
|
||||
*
|
||||
* @param[in] delta_time_ms_lsb Delta time [0-31] part (in milliseconds)
|
||||
* @param[in] delta_time_ms_msb Delta time [32-39] part (in milliseconds)
|
||||
****************************************************************************************
|
||||
*/
|
||||
// void co_time_compensate(uint32_t delta_time_ms_lsb, uint8_t delta_time_ms_msb);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize timer structure.
|
||||
*
|
||||
* @param[in] p_timer Pointer to the timer structure.
|
||||
* @param[in] cb Function to be called upon timer expiration.
|
||||
* @param[in] p_env Pointer to be passed to the callback
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_time_timer_init(co_time_timer_t* p_timer, co_time_timer_cb cb, void* p_env);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Program a timer to be scheduled in the future.
|
||||
* If timer is already programmed, it is restarted.
|
||||
* If delay is less than 10ms, delay is set to 10ms.
|
||||
*
|
||||
* @param[in] p_timer Pointer to the timer structure.
|
||||
* @param[in] delay_ms Duration before expiration of the timer (in milliseconds).
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_time_timer_set(co_time_timer_t* p_timer, uint32_t delay_ms);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Program a timer to be scheduled in the future with duration greater than 49 days.
|
||||
* If timer is already programmed, it is restarted.
|
||||
* If delay is less than 10ms, delay is set to 10ms.
|
||||
*
|
||||
* @param[in] p_timer Pointer to the timer structure.
|
||||
* @param[in] delay_ms_lsb Duration before expiration of the timer [0-31] part (in milliseconds)
|
||||
* @param[in] delay_ms_msb Duration before expiration of the timer [32-39] part (in milliseconds)
|
||||
****************************************************************************************
|
||||
*/
|
||||
// void co_time_timer_long_set(co_time_timer_t* p_timer, uint32_t delay_ms_lsb, uint8_t delay_ms_msb);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Program a timer to be scheduled periodically. If timer is already programmed,
|
||||
* it is restarted.
|
||||
* If period exceed maximum value, timer is programmed using maximum period.
|
||||
* If period less than 10ms, period is set to 10ms.
|
||||
*
|
||||
* @param[in] p_timer Pointer to the timer structure.
|
||||
* @param[in] period_ms Periodic duration (in milliseconds). Range [10, 48388607] max ~2 hours
|
||||
****************************************************************************************
|
||||
*/
|
||||
// void co_time_timer_periodic_set(co_time_timer_t* p_timer, uint32_t period_ms);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Stop a programmed timer.
|
||||
*
|
||||
* @param[in] p_timer Pointer to the timer structure.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_time_timer_stop(co_time_timer_t* p_timer);
|
||||
|
||||
/// @} CO_TIME
|
||||
|
||||
#endif // _CO_TIME_H_
|
||||
@@ -0,0 +1,721 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file co_utils.h
|
||||
*
|
||||
* @brief Common utilities definitions
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
#ifndef _CO_UTILS_H_
|
||||
#define _CO_UTILS_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @defgroup CO_UTILS Utilities
|
||||
* @ingroup COMMON
|
||||
* @brief Common utilities
|
||||
*
|
||||
* This module contains the common utilities functions and macros.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdint.h> // standard definitions
|
||||
#include <stddef.h> // standard definitions
|
||||
#include "co_bt.h" // common bt definitions
|
||||
#include "rwip_config.h" // SW configuration
|
||||
#include "rwip.h" // SW configuration
|
||||
#include "compiler.h" // for inline functions
|
||||
|
||||
|
||||
/*
|
||||
* MACRO DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Common constants - bit field definitions
|
||||
#define BIT0 0x0001
|
||||
#define BIT1 0x0002
|
||||
#define BIT2 0x0004
|
||||
#define BIT3 0x0008
|
||||
#define BIT4 0x0010
|
||||
#define BIT5 0x0020
|
||||
#define BIT6 0x0040
|
||||
#define BIT7 0x0080
|
||||
#define BIT8 0x0100
|
||||
#define BIT9 0x0200
|
||||
#define BIT10 0x0400
|
||||
#define BIT11 0x0800
|
||||
#define BIT12 0x1000
|
||||
#define BIT13 0x2000
|
||||
#define BIT14 0x4000
|
||||
#define BIT15 0x8000
|
||||
|
||||
/// Number of '1' bits in a byte
|
||||
#define NB_ONE_BITS(byte) (one_bits[byte & 0x0F] + one_bits[byte >> 4])
|
||||
|
||||
/// Get the number of elements within an array, give also number of rows in a 2-D array
|
||||
#define ARRAY_LEN(array) (sizeof((array))/sizeof((array)[0]))
|
||||
|
||||
/// Get the number of columns within a 2-D array
|
||||
#define ARRAY_NB_COLUMNS(array) (sizeof((array[0]))/sizeof((array)[0][0]))
|
||||
|
||||
|
||||
/// Macro for LMP message handler function declaration or definition
|
||||
#define LMP_MSG_HANDLER(msg_name) int lmp_##msg_name##_handler(struct lmp_##msg_name const *param, \
|
||||
ke_task_id_t const dest_id)
|
||||
/// Macro for LMP message handler function declaration or definition
|
||||
#define LLCP_MSG_HANDLER(msg_name) int llcp_##msg_name##_handler(struct llcp_##msg_name const *param, \
|
||||
ke_task_id_t const dest_id)
|
||||
|
||||
/// Macro for HCI message handler function declaration or definition (for multi-instantiated tasks)
|
||||
#define HCI_CMD_HANDLER_C(cmd_name, param_struct) int hci_##cmd_name##_cmd_lc_handler(param_struct const *param, \
|
||||
ke_task_id_t const dest_id, \
|
||||
uint16_t opcode)
|
||||
|
||||
/// Macro for HCI message handler function declaration or definition (with parameters)
|
||||
#define HCI_CMD_HANDLER(cmd_name, param_struct) int hci_##cmd_name##_cmd_handler(param_struct const *param, \
|
||||
uint16_t opcode)
|
||||
|
||||
/// Macro for HCI message handler function declaration or definition (with parameters)
|
||||
#define HCI_CMD_HANDLER_TAB(task) const struct task##_hci_cmd_handler task##_hci_command_handler_tab[] =
|
||||
|
||||
|
||||
/// MACRO to build a subversion field from the Minor and Release fields
|
||||
#define CO_SUBVERSION_BUILD(minor, release) (((minor) << 8) | (release))
|
||||
|
||||
|
||||
/// Macro to get a structure from one of its structure field
|
||||
#define CONTAINER_OF(ptr, type, member) ((type *)( (char *)ptr - offsetof(type,member) ))
|
||||
|
||||
/// count number of bit into a long field
|
||||
#define CO_BIT_CNT(val) (co_bit_cnt((uint8_t*) &(val), sizeof(val)))
|
||||
|
||||
/// Increment value and make sure it's never greater or equals max (else wrap to 0)
|
||||
#define CO_VAL_INC(_val, _max) \
|
||||
(_val) = (_val) + 1; \
|
||||
if((_val) >= (_max)) (_val) = 0
|
||||
|
||||
|
||||
/// Add value and make sure it's never greater or equals max (else wrap)
|
||||
/// _add must be less that _max
|
||||
#define CO_VAL_ADD(_val, _add, _max) \
|
||||
(_val) = (_val) + (_add); \
|
||||
if((_val) >= (_max)) (_val) -= (_max)
|
||||
|
||||
/// sub value and make sure it's never greater or equals max (else wrap)
|
||||
/// _sub must be less that _max
|
||||
#define CO_VAL_SUB(_val, _sub, _max) \
|
||||
if((_val) < (_sub)) (_val) += _max; \
|
||||
(_val) = (_val) - (_sub)
|
||||
|
||||
/*
|
||||
* ENUMERATIONS DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Status returned by generic packer-unpacker
|
||||
enum CO_UTIL_PACK_STATUS
|
||||
{
|
||||
CO_UTIL_PACK_OK,
|
||||
CO_UTIL_PACK_IN_BUF_OVFLW,
|
||||
CO_UTIL_PACK_OUT_BUF_OVFLW,
|
||||
CO_UTIL_PACK_WRONG_FORMAT,
|
||||
CO_UTIL_PACK_ERROR,
|
||||
};
|
||||
|
||||
|
||||
/// Rate information
|
||||
/*@TRACE*/
|
||||
enum phy_rate
|
||||
{
|
||||
/// 1 Mbits/s Rate
|
||||
CO_RATE_1MBPS = 0,
|
||||
/// 2 Mbits/s Rate
|
||||
CO_RATE_2MBPS = 1,
|
||||
/// 125 Kbits/s Rate
|
||||
CO_RATE_125KBPS = 2,
|
||||
/// 500 Kbits/s Rate
|
||||
CO_RATE_500KBPS = 3,
|
||||
/// Undefined rate (used for reporting when no packet is received)
|
||||
CO_RATE_UNDEF = 4,
|
||||
|
||||
CO_RATE_MAX = 4,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* TYPE DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* CONSTANT DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Number of '1' bits in values from 0 to 15, used to fasten bit counting
|
||||
extern const unsigned char one_bits[16];
|
||||
|
||||
/// Conversion table Sleep Clock Accuracy to PPM
|
||||
extern const uint16_t co_sca2ppm[];
|
||||
|
||||
/// NULL BD address
|
||||
extern const struct bd_addr co_null_bdaddr;
|
||||
|
||||
/// Default BD address
|
||||
extern struct bd_addr co_default_bdaddr;
|
||||
|
||||
/// NULL Key
|
||||
extern const uint8_t co_null_key[KEY_LEN];
|
||||
|
||||
/// Table for converting rate to PHY
|
||||
extern const uint8_t co_rate_to_phy[];
|
||||
|
||||
/// Table for converting PHY to rate (Warning: the coded PHY is converted to 125K by default)
|
||||
extern const uint8_t co_phy_to_rate[];
|
||||
|
||||
/// Convert PHY mask (with one single bit set) to a value
|
||||
extern const uint8_t co_phy_mask_to_value[];
|
||||
|
||||
/// Convert PHY a value to the corresponding mask bit
|
||||
extern const uint8_t co_phy_value_to_mask[];
|
||||
|
||||
/// Convert Rate value to the corresponding PHY mask bit
|
||||
extern const uint8_t co_rate_to_phy_mask[];
|
||||
|
||||
/// Convert PHY mask bit to the corresponding Rate value
|
||||
extern const uint8_t co_phy_mask_to_rate[];
|
||||
|
||||
#if BLE_PWR_CTRL
|
||||
|
||||
/// Convert PHY rate value of power control to the corresponding PHY mask bit
|
||||
extern const uint8_t co_phypwr_value_to_mask[];
|
||||
|
||||
/// Convert PHY mask bit of power control to the corresponding PHY rate value
|
||||
extern const uint8_t co_phypwr_mask_to_value[];
|
||||
|
||||
/// Convert PHY rate value of power control to Rate value
|
||||
extern const uint8_t co_phypwr_to_rate[];
|
||||
|
||||
/// Convert Rate value to PHY rate value of power control
|
||||
extern const uint8_t co_rate_to_phypwr[];
|
||||
|
||||
/// Convert Rate value to PHY mask value of power control
|
||||
extern const uint8_t co_rate_to_phypwr_mask[];
|
||||
|
||||
#endif // BLE_PWR_CTRL
|
||||
|
||||
/// Convert Rate value to byte duration in us
|
||||
extern const uint8_t co_rate_to_byte_dur_us[];
|
||||
|
||||
|
||||
/*
|
||||
* OPERATIONS ON BT CLOCK
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Clocks addition with 2 operands
|
||||
*
|
||||
* @param[in] clock_a 1st operand value (in BT half-slots)
|
||||
* @param[in] clock_b 2nd operand value (in BT half-slots)
|
||||
* @return result operation result (in BT half-slots)
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CLK_ADD_2(clock_a, clock_b) ((uint32_t)(((clock_a) + (clock_b)) & RWIP_MAX_CLOCK_TIME))
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Clocks addition with 3 operands
|
||||
*
|
||||
* @param[in] clock_a 1st operand value (in BT half-slots)
|
||||
* @param[in] clock_b 2nd operand value (in BT half-slots)
|
||||
* @param[in] clock_c 3rd operand value (in BT half-slots)
|
||||
* @return result operation result (in BT half-slots)
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CLK_ADD_3(clock_a, clock_b, clock_c) ((uint32_t)(((clock_a) + (clock_b) + (clock_c)) & RWIP_MAX_CLOCK_TIME))
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Clocks subtraction
|
||||
*
|
||||
* @param[in] clock_a 1st operand value (in BT half-slots)
|
||||
* @param[in] clock_b 2nd operand value (in BT half-slots)
|
||||
* @return result operation result (in BT half-slots)
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CLK_SUB(clock_a, clock_b) ((uint32_t)(((clock_a) - (clock_b)) & RWIP_MAX_CLOCK_TIME))
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Bluetooth timestamp Clocks subtraction
|
||||
*
|
||||
* @param[in] clock_a 1st operand value (in microseconds)
|
||||
* @param[in] clock_b 2nd operand value (in microseconds)
|
||||
* @return result operation result (in microseconds)
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CLK_BTS_SUB(clock_a, clock_b) (((int32_t) ((clock_a) - (clock_b))))
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Check if clock_a is lower than or equal to clock_b
|
||||
*
|
||||
* @param[in] clock_a Clock A value (in BT half-slots)
|
||||
* @param[in] clock_b Clock B value (in BT half-slots)
|
||||
* @return result True: clock_a lower than or equal to clock_b | False: else
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CLK_BTS_LOWER_EQ(clock_a, clock_b) (CLK_BTS_SUB(clock_b, clock_a) < (RWIP_MAX_BTS_TIME >> 1))
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Clocks time difference
|
||||
*
|
||||
* @param[in] clock_a 1st operand value (in BT half-slots)
|
||||
* @param[in] clock_b 2nd operand value (in BT half-slots)
|
||||
* @return result return the time difference from clock A to clock B
|
||||
* - result < 0 => clock_b is in the past
|
||||
* - result == 0 => clock_a is equal to clock_b
|
||||
* - result > 0 => clock_b is in the future
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CLK_DIFF(clock_a, clock_b) ( (CLK_SUB((clock_b), (clock_a)) > ((RWIP_MAX_CLOCK_TIME+1) >> 1)) ? \
|
||||
((int32_t)((-CLK_SUB((clock_a), (clock_b))))) : ((int32_t)((CLK_SUB((clock_b), (clock_a))))) )
|
||||
|
||||
|
||||
|
||||
/// macro to extract a field from a value containing several fields
|
||||
/// @param[in] __r bit field value
|
||||
/// @param[in] __f field name
|
||||
/// @return the value of the register masked and shifted
|
||||
#define GETF(__r, __f) \
|
||||
(( (__r) & (__f##_MASK) ) >> (__f##_LSB))
|
||||
|
||||
/// macro to set a field value into a value containing several fields.
|
||||
/// @param[in] __r bit field value
|
||||
/// @param[in] __f field name
|
||||
/// @param[in] __v value to put in field
|
||||
#define SETF(__r, __f, __v) \
|
||||
do { \
|
||||
ASSERT_INFO( ( ( ( (__v) << (__f##_LSB) ) & ( ~(__f##_MASK) ) ) ) == 0 ,(__f##_MASK), (__v)); \
|
||||
__r = (((__r) & ~(__f##_MASK)) | (__v) << (__f##_LSB)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
/// macro to extract a bit field from a value containing several fields
|
||||
/// @param[in] __r bit field value
|
||||
/// @param[in] __b bit field name
|
||||
/// @return the value of the register masked and shifted
|
||||
#define GETB(__r, __b) \
|
||||
(( (__r) & (__b##_BIT) ) >> (__b##_POS))
|
||||
|
||||
/// macro to set a bit field value into a value containing several fields.
|
||||
/// @param[in] __r bit field value
|
||||
/// @param[in] __b bit field name
|
||||
/// @param[in] __v value to put in field
|
||||
#define SETB(__r, __b, __v) \
|
||||
do { \
|
||||
ASSERT_ERR( ( ( ( (__v ? 1 : 0) << (__b##_POS) ) & ( ~(__b##_BIT) ) ) ) == 0 ); \
|
||||
__r = (((__r) & ~(__b##_BIT)) | (__v ? 1 : 0) << (__b##_POS)); \
|
||||
} while (0)
|
||||
|
||||
/// macro to toggle a bit into a value containing several bits.
|
||||
/// @param[in] __r bit field value
|
||||
/// @param[in] __b bit field name
|
||||
#define TOGB(__r, __b) \
|
||||
do { \
|
||||
__r = ((__r) ^ (__b##_BIT)); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Check if clock_a is equal to clock_b
|
||||
*
|
||||
* @param[in] clock_a Clock A value (in BT half-slots)
|
||||
* @param[in] clock_b Clock B value (in BT half-slots)
|
||||
* @return result True: clock_a lower than or equal to clock_b | False: else
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CLK_EQ(clock_a, clock_b) (clock_b == clock_a)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Check if clock_a is lower than or equal to clock_b
|
||||
*
|
||||
* @param[in] clock_a Clock A value (in BT half-slots)
|
||||
* @param[in] clock_b Clock B value (in BT half-slots)
|
||||
* @return result True: clock_a lower than or equal to clock_b | False: else
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CLK_LOWER_EQ(clock_a, clock_b) (CLK_SUB(clock_b, clock_a) < (RWIP_MAX_CLOCK_TIME >> 1))
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Check if clock A is lower than or equal to clock B (with half-us precision)
|
||||
*
|
||||
* @param[in] int_a Integer part of clock A (in BT half-slots)
|
||||
* @param[in] fract_a Fractional part of clock A (in half-us) (range: 0 to 624)
|
||||
* @param[in] int_b Integer part of clock B (in BT half-slots)
|
||||
* @param[in] fract_b Fractional part of clock B (in half-us) (range: 0 to 624)
|
||||
* @return result True: clock A lower than or equal to clock B | False: else
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CLK_LOWER_EQ_HUS(int_a, fract_a, int_b, fract_b) ( CLK_GREATER_THAN(int_b, int_a) \
|
||||
|| ( CLK_EQ(int_a, int_b) \
|
||||
&& (fract_a <= fract_b) ) ) \
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Check if clock_a is greater than clock_b
|
||||
*
|
||||
* @param[in] clock_a Clock A value (in BT half-slots)
|
||||
* @param[in] clock_b Clock B value (in BT half-slots)
|
||||
* @return result True: clock_a is greater than clock_b | False: else
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CLK_GREATER_THAN(clock_a, clock_b) !(CLK_LOWER_EQ(clock_a, clock_b))
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Check if clock A is greater than clock B (with half-us precision)
|
||||
*
|
||||
* @param[in] int_a Integer part of clock A (in BT half-slots)
|
||||
* @param[in] fract_a Fractional part of clock A (in half-us) (range: 0 to 624)
|
||||
* @param[in] int_b Integer part of clock B (in BT half-slots)
|
||||
* @param[in] fract_b Fractional part of clock B (in half-us) (range: 0 to 624)
|
||||
* @return result True: clock A greater than clock B | False: else
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define CLK_GREATER_THAN_HUS(int_a, fract_a, int_b, fract_b) ( CLK_GREATER_THAN(int_a, int_b) \
|
||||
|| ( CLK_EQ(int_a, int_b) \
|
||||
&& (fract_a > fract_b) ) ) \
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Read an aligned 32 bit word.
|
||||
* @param[in] ptr32 The address of the first byte of the 32 bit word.
|
||||
* @return The 32 bit value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_read32(void const *ptr32)
|
||||
{
|
||||
return *((uint32_t*)ptr32);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Read an aligned 16 bits word.
|
||||
* @param[in] ptr16 The address of the first byte of the 16 bits word.
|
||||
* @return The 16 bits value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint16_t co_read16(void const *ptr16)
|
||||
{
|
||||
return *((uint16_t*)ptr16);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Write an aligned 32 bits word.
|
||||
* @param[in] ptr32 The address of the first byte of the 32 bits word.
|
||||
* @param[in] value The value to write.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE void co_write32(void const *ptr32, uint32_t value)
|
||||
{
|
||||
*(uint32_t*)ptr32 = value;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Write an aligned 16 bits word.
|
||||
* @param[in] ptr16 The address of the first byte of the 16 bits word.
|
||||
* @param[in] value The value to write.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE void co_write16(void const *ptr16, uint32_t value)
|
||||
{
|
||||
*(uint16_t*)ptr16 = value;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Write a 8 bits word.
|
||||
* @param[in] ptr8 The address of the first byte of the 8 bits word.
|
||||
* @param[in] value The value to write.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE void co_write8(void const *ptr8, uint32_t value)
|
||||
{
|
||||
*(uint8_t*)ptr8 = value;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Read a packed 16 bits word.
|
||||
* @param[in] ptr16 The address of the first byte of the 16 bits word.
|
||||
* @return The 16 bits value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint16_t co_read16p(void const *ptr16)
|
||||
{
|
||||
uint16_t value = ((uint8_t *)ptr16)[0] | ((uint8_t *)ptr16)[1] << 8;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Read a packed 24 bits word.
|
||||
* @param[in] ptr24 The address of the first byte of the 24 bits word.
|
||||
* @return The 24 bits value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_read24p(void const *ptr24)
|
||||
{
|
||||
uint16_t addr_l, addr_h;
|
||||
addr_l = co_read16p(ptr24);
|
||||
addr_h = *((uint8_t *)ptr24 + 2) & 0x00FF;
|
||||
return ((uint32_t)addr_l | (uint32_t)addr_h << 16);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Write a packed 24 bits word.
|
||||
* @param[in] ptr24 The address of the first byte of the 24 bits word.
|
||||
* @param[in] value The value to write.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE void co_write24p(void const *ptr24, uint32_t value)
|
||||
{
|
||||
uint8_t *ptr=(uint8_t*)ptr24;
|
||||
|
||||
*ptr++ = (uint8_t)(value&0xff);
|
||||
*ptr++ = (uint8_t)((value&0xff00)>>8);
|
||||
*ptr++ = (uint8_t)((value&0xff0000)>>16);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Read a packed 32 bits word.
|
||||
* @param[in] ptr32 The address of the first byte of the 32 bits word.
|
||||
* @return The 32 bits value.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint32_t co_read32p(void const *ptr32)
|
||||
{
|
||||
uint16_t addr_l, addr_h;
|
||||
addr_l = co_read16p(ptr32);
|
||||
addr_h = co_read16p((uint8_t *)ptr32 + 2);
|
||||
return ((uint32_t)addr_l | (uint32_t)addr_h << 16);
|
||||
}
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Write a packed 32 bits word.
|
||||
* @param[in] ptr32 The address of the first byte of the 32 bits word.
|
||||
* @param[in] value The value to write.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE void co_write32p(void const *ptr32, uint32_t value)
|
||||
{
|
||||
uint8_t *ptr=(uint8_t*)ptr32;
|
||||
|
||||
*ptr++ = (uint8_t)(value&0xff);
|
||||
*ptr++ = (uint8_t)((value&0xff00)>>8);
|
||||
*ptr++ = (uint8_t)((value&0xff0000)>>16);
|
||||
*ptr = (uint8_t)((value&0xff000000)>>24);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Write a packed 16 bits word.
|
||||
* @param[in] ptr16 The address of the first byte of the 16 bits word.
|
||||
* @param[in] value The value to write.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE void co_write16p(void const *ptr16, uint16_t value)
|
||||
{
|
||||
uint8_t *ptr=(uint8_t*)ptr16;
|
||||
|
||||
*ptr++ = value&0xff;
|
||||
*ptr = (value&0xff00)>>8;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* Count number of bit set to 1 in a value with variable length
|
||||
*
|
||||
* @param[in] p_val Pointer to value
|
||||
* @param[in] size Number of Bytes
|
||||
* @return Number of bit counted
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE uint8_t co_bit_cnt(const uint8_t* p_val, uint8_t size)
|
||||
{
|
||||
uint8_t nb_bit = 0;
|
||||
while(size-- > 0)
|
||||
{
|
||||
nb_bit += NB_ONE_BITS(*p_val);
|
||||
p_val++;
|
||||
}
|
||||
return (nb_bit);
|
||||
}
|
||||
|
||||
#if (RW_DEBUG || DISPLAY_SUPPORT)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert bytes to hexadecimal string
|
||||
*
|
||||
* @param[out] dest Pointer to the destination string (must be 2x longer than input table)
|
||||
* @param[in] src Pointer to the bytes table
|
||||
* @param[in] nb_bytes Number of bytes to display in the string
|
||||
****************************************************************************************
|
||||
*/
|
||||
void co_bytes_to_string(char* dest, uint8_t* src, uint8_t nb_bytes);
|
||||
#endif //(RW_DEBUG || DISPLAY_SUPPORT)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Compares two Bluetooth device addresses
|
||||
*
|
||||
* This function checks if the two bd address are equal.
|
||||
*
|
||||
* @param[in] bd_address1 Pointer on the first bd address to be compared.
|
||||
* @param[in] bd_address2 Pointer on the second bd address to be compared.
|
||||
*
|
||||
* @return result of the comparison (true: equal | false: different).
|
||||
****************************************************************************************
|
||||
*/
|
||||
bool co_bdaddr_compare(struct bd_addr const *bd_address1, struct bd_addr const *bd_address2);
|
||||
|
||||
#if (BT_EMB_PRESENT)
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief Convert an duration in baseband slot to a duration in number of ticks.
|
||||
* @param[in] slot_cnt Duration in number of baseband slot
|
||||
* @return Duration (in number of ticks).
|
||||
******************************************************************************
|
||||
*/
|
||||
uint32_t co_slot_to_duration(uint32_t slot_cnt);
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief Count the number of good channels in a map
|
||||
* @param[in] map Channel Map (bit fields for the 79 BT RF channels)
|
||||
* @return Number of good channels
|
||||
******************************************************************************
|
||||
*/
|
||||
uint8_t co_nb_good_channels(const struct chnl_map* map);
|
||||
|
||||
#endif //BT_EMB_PRESENT
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Pack parameters from a C structure to a packed buffer
|
||||
*
|
||||
* This function packs parameters according to a specific format. It takes care of the
|
||||
* endianess, padding, required by the compiler.
|
||||
*
|
||||
* By default output format is LSB but it can be changed with first character of format string
|
||||
* - < : LSB output format
|
||||
* - > : MSB output format
|
||||
*
|
||||
* Format strings are the mechanism used to specify the expected layout when packing and unpacking data. They are built
|
||||
* up from Format Characters, which specify the type of data being packed/unpacked.
|
||||
* - B : byte - 8bits value
|
||||
* - H : word - 16bits value
|
||||
* - L : long - 32-bits value
|
||||
* - D : 24 bits value
|
||||
* - XXB: table of several bytes, where XX is the byte number, in decimal
|
||||
* - XXG: Number of several bytes, where XX is the byte number, in decimal - subject to be swapped according to endianess
|
||||
* - nB : table size over 1 byte, followed by the table of bytes
|
||||
* - NB : table size over 2 bytes, followed by the table of bytes
|
||||
*
|
||||
* Example: "BBLH12BLnB" => 1 byte | 1 byte | 1 long | 1 short | 12-bytes table | 1 long | table size over 1 byte | n-bytes table
|
||||
*
|
||||
* Note: the function works in the same buffer
|
||||
*
|
||||
* @param[out] out Output Data Buffer
|
||||
* @param[in] in Input Data Buffer
|
||||
* @param[out] out_len Output size of packed data (in bytes)
|
||||
* @param[in] in_len Input buffer size (in bytes)
|
||||
* @param[in] format Parameters format
|
||||
*
|
||||
* @return Status of the packing operation
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint8_t co_util_pack(uint8_t* out, uint8_t* in, uint16_t* out_len, uint16_t in_len, const char* format);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Unpack parameters from an unpacked buffer to a C structure
|
||||
*
|
||||
* This function unpacks parameters according to a specific format. It takes care of the
|
||||
* endianess, padding, required by the compiler.
|
||||
*
|
||||
* By default input format is LSB but it can be changed with first character of format string
|
||||
* - < : LSB input format
|
||||
* - > : MSB input format
|
||||
*
|
||||
* Format strings are the mechanism used to specify the expected layout when packing and unpacking data. They are built
|
||||
* up from Format Characters, which specify the type of data being packed/unpacked.
|
||||
* - B : byte - 8bits value
|
||||
* - H : word - 16bits value
|
||||
* - L : long - 32-bits value
|
||||
* - D : 24 bits value
|
||||
* - XXB: table of several bytes, where XX is the byte number, in decimal
|
||||
* - XXG: Number of several bytes, where XX is the byte number, in decimal - subject to be swapped according to endianess
|
||||
* - nB : table size over 1 byte, followed by the table of bytes
|
||||
* - NB : table size over 2 bytes, followed by the table of bytes
|
||||
*
|
||||
* Example: "BBLH12BLnB" => 1 byte | 1 byte | 1 long | 1 short | 12-bytes table | 1 long | table size over 1 byte | n-bytes table
|
||||
*
|
||||
* Note: the output buffer provided must be large enough to contain the unpacked data.
|
||||
* Note2: if a NULL output buffer is provided, the function does not copy the unpacked parameters. It still parses the
|
||||
* format string and input buffer to return the number of unpacked bytes. Can be used to compute the expected unpacked
|
||||
* buffer size.
|
||||
*
|
||||
* @param[out] out Unpacked parameters buffer
|
||||
* @param[in] in Packed parameters buffer
|
||||
* @param[inout] out_len Input: buffer size / Output: size of unpacked data (in bytes)
|
||||
* @param[in] in_len Size of the packed data (in bytes)
|
||||
* @param[in] format Parameters format
|
||||
*
|
||||
* @return Status of the unpacking operation
|
||||
*****************************************************************************************
|
||||
*/
|
||||
uint8_t co_util_unpack(uint8_t* out, uint8_t* in, uint16_t* out_len, uint16_t in_len, const char* format);
|
||||
|
||||
// void set_ble_mac_addr(struct bd_addr* addr);
|
||||
// struct bd_addr* get_ble_mac_addr(void);
|
||||
|
||||
/// @} CO_UTILS
|
||||
|
||||
#endif // _CO_UTILS_H_
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file co_version.h
|
||||
*
|
||||
* @brief Version definitions for BT5.1
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2018
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _CO_VERSION_H_
|
||||
#define _CO_VERSION_H_
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @defgroup CO_VERSION Version Defines
|
||||
* @ingroup COMMON
|
||||
*
|
||||
* @brief Bluetooth Controller Version definitions.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include "co_bt.h" // BT standard definitions
|
||||
|
||||
|
||||
/// RWBT SW Major Version
|
||||
#define RWBT_SW_VERSION_MAJOR (BT52_VERSION)
|
||||
/// RWBT SW Minor Version
|
||||
#define RWBT_SW_VERSION_MINOR 0
|
||||
/// RWBT SW Build Version
|
||||
#define RWBT_SW_VERSION_BUILD 4
|
||||
/// RWBT SW Major Version
|
||||
#define RWBT_SW_VERSION_SUB_BUILD 0
|
||||
|
||||
|
||||
/// @} CO_VERSION
|
||||
|
||||
|
||||
#endif // _CO_VERSION_H_
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file dbg.h
|
||||
*
|
||||
* @brief Debug function
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
#ifndef DBG_H_
|
||||
#define DBG_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup DBG
|
||||
* @ingroup CONTROLLER
|
||||
* @brief Debug
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include "rwip_config.h" // stack configuration
|
||||
|
||||
#include "dbg_swdiag.h" // sw profiling definitions
|
||||
|
||||
#include "dbg_trc.h" // debug tracer definition
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATION
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#if CMD_TEST
|
||||
#define TEST_LOGI(...) DEBUG(__VA_ARGS__)
|
||||
#else
|
||||
#define TEST_LOGI(...)
|
||||
#endif
|
||||
|
||||
|
||||
#if _DEBUG_
|
||||
#define LOGI(...) DEBUG(__VA_ARGS__)
|
||||
#define DUMP_DATA_PRINTF(data, length) printf_hexdump((uint8_t *)data, length)
|
||||
#define LOGI_ERR(...) \
|
||||
do { \
|
||||
DEBUG("[%s] [%d]: ", __FILE__, __LINE__); \
|
||||
DEBUG(__VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define LOGI(...)
|
||||
#define DUMP_DATA_PRINTF(data, length)
|
||||
#define LOGI_ERR(...)
|
||||
#endif
|
||||
|
||||
#define _TOSTRING(s) #s
|
||||
#define TOSTRING(s) _TOSTRING(s)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialization of the BT Debug task
|
||||
*
|
||||
* This function initializes the the DBG task
|
||||
*
|
||||
* @param[in] init_type Type of initialization (@see enum rwip_init_type)
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_init(uint8_t init_type);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Send back to host status of platform reset request.
|
||||
*
|
||||
* @param status Reset error code
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_platform_reset_complete(uint32_t error);
|
||||
|
||||
void printf_hexdump(const void *data, int length);
|
||||
|
||||
///@} DBG
|
||||
|
||||
#endif // DBG_H_
|
||||
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file dbg_iqgen.h
|
||||
*
|
||||
* @brief I&Q Samples Generator API.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2018
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef DBG_IQGEN_H_
|
||||
#define DBG_IQGEN_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup DBGIQGEN
|
||||
* @ingroup IQ
|
||||
* @brief Debug SW - I&Q samples Generator.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include "rwip_config.h"
|
||||
|
||||
#if BLE_IQ_GEN
|
||||
|
||||
#include "reg_iqgen.h" // I&Q sample generator register functions
|
||||
|
||||
/*
|
||||
* CONSTANT DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Maximum number of supported antenna patterns
|
||||
#define DBG_IQGEN_MAX_ANTENNA (8)
|
||||
|
||||
/// bit defintitions for debug configuration
|
||||
#define DBG_IQGEN_PATTERN_MODE_BIT (1<<0)
|
||||
#define DBG_IQGEN_TIMING_MODE_BIT (1<<1)
|
||||
#define DBG_IQGEN_ANT_ID_MODE_BIT (2<<1)
|
||||
|
||||
|
||||
/// I&Q samples generation control
|
||||
enum dbg_iqgen_ctnl
|
||||
{
|
||||
/// I&Q samples up count
|
||||
DBG_IQGEN_UPCOUNT = 0,
|
||||
/// I&Q samples down count
|
||||
DBG_IQGEN_DOWNCOUNT = 1,
|
||||
/// I&Q samples fixed value
|
||||
DBG_IQGEN_FIXEDVAL = 2,
|
||||
/// I&Q samples PRBS
|
||||
DBG_IQGEN_PRBSPATTERN = 3,
|
||||
};
|
||||
|
||||
/// I&Q samples generation antenna sweep pattern
|
||||
enum dbg_iqgen_antenna_pattern
|
||||
{
|
||||
/// antenna up-sweep
|
||||
DBG_IQGEN_ANT_UPSWEEP = 0,
|
||||
/// antenna up-down sweep
|
||||
DBG_IQGEN_ANT_UPDNSWEEP = 1,
|
||||
};
|
||||
|
||||
/// I&Q samples generation timing mode
|
||||
enum dbg_iqgen_timing_mode
|
||||
{
|
||||
/// 1us switching/sampling interval
|
||||
DBG_IQGEN_1US_INTV = 0,
|
||||
/// 2us switching/sampling interval
|
||||
DBG_IQGEN_2US_INTV = 1,
|
||||
};
|
||||
|
||||
/// antenna switch enable mode
|
||||
enum dbg_iqgen_antenna_switch_mode
|
||||
{
|
||||
/// Accepts antenna ID switching inputs from baseband
|
||||
DBG_IQGEN_BASEBAND_SWITCHING = 0,
|
||||
/// Antenna switching is internally enabled
|
||||
DBG_IQGEN_INTERNAL_SWITCHING = 1,
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* VARIABLE DECLARATION
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Enable I&Q sample generator
|
||||
*
|
||||
* @param[in] nb_antenna Number of antenna (valid range 1-8)
|
||||
* @param[in] pattern_mode Antenna sweep pattern (@see enum dbg_iqgen_antenna_pattern)
|
||||
* @param[in] timing_mode Timing interval mode (@see enum dbg_iqgen_timing_mode)
|
||||
* @param[in] ant_switch_mode Antenna switching mode (@see enum dbg_iqgen_antenna_switch_mode)
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_iqgen_config_enable(uint8_t nb_antenna, uint8_t pattern_mode, uint8_t timing_mode, uint8_t ant_switch_mode);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Disable I&Q sample generator
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_iqgen_disable();
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Configure I&Q samples for a specific antenna
|
||||
*
|
||||
* @param[in] antenna ID antenna id (valid range 0-7)
|
||||
* @param[in] i_cntl configuration mode for I-samples (@see enum dbg_iqgen_cntl)
|
||||
* @param[in] q_cntl configuration mode for Q-samples (@see enum dbg_iqgen_cntl)
|
||||
* @param[in] i_val I-samples initial value
|
||||
* @param[in] q_val Q-samples initial value
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_iqgen_antenna_config(uint8_t antenna_id, uint8_t i_cntl, uint8_t q_cntl, uint8_t i_val, uint8_t q_val);
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief I&Q Generator configure
|
||||
*
|
||||
* @param[in] param configuration structure (@see hci_dbg_iqgen_cfg_cmd)
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t dbg_iqgen_config(struct hci_dbg_iqgen_cfg_cmd const *cfg);
|
||||
|
||||
#endif //BLE_IQ_GEN
|
||||
|
||||
/// @} DBGIQGEN
|
||||
|
||||
#endif // DBG_IQGEN_H_
|
||||
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file dbg_mwsgen.h
|
||||
*
|
||||
* @brief MWS/WLAN Generator API.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef DBG_MWSGEN_H_
|
||||
#define DBG_MWSGEN_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup DBGMWSGEN
|
||||
* @ingroup DBG
|
||||
* @brief Debug SW - MWS/WLAN Generator.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include "rwip_config.h"
|
||||
|
||||
#if (RW_WLAN_COEX_TEST) || (RW_MWS_COEX_TEST)
|
||||
|
||||
#include "reg_mwsgen.h" // MWS Event Generator register functions
|
||||
|
||||
/*
|
||||
* CONSTANT DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#if (RW_WLAN_COEX)
|
||||
/// WLAN coexistence disabled
|
||||
#define DBG_COEX_WLAN_DISABLED 0
|
||||
/// WLAN coexistence enabled
|
||||
#define DBG_COEX_WLAN_ENABLED 1
|
||||
#endif
|
||||
|
||||
#if (RW_MWS_COEX)
|
||||
/// MWS coexistence disabled
|
||||
#define DBG_COEX_MWS_DISABLED 0
|
||||
/// MWS coexistence enabled
|
||||
#define DBG_COEX_MWS_ENABLED 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* VARIABLE DECLARATION
|
||||
****************************************************************************************
|
||||
*/
|
||||
#if (RW_WLAN_COEX_TEST)
|
||||
extern uint32_t dbg_coex_scenario;
|
||||
#endif // RW_WLAN_COEX_TEST
|
||||
|
||||
#if (RW_MWS_COEX_TEST)
|
||||
extern uint32_t dbg_coex_scenario;
|
||||
#endif // RW_MWS_COEX_TEST
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#if (RW_MWS_COEX_TEST)
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Set the scenario for the unitary testing.
|
||||
*
|
||||
* @param[in] scenario Scenario type
|
||||
*
|
||||
* @return none
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t dbg_mwscoex_scen_set(uint32_t scenario);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize and configure MWS event generator registers to be in MWS mode.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_mwsgen_init(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Configure MWS generator
|
||||
*
|
||||
* @param[in] period Period of the mws signal (us)
|
||||
* @param[in] duty_cycle Duration of the high level (us)
|
||||
* @param[in] tx_act Duration of the tx activity (us)
|
||||
* @param[in] rx_act Duration of the rx activity (us)
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_mwsgen_config(uint32_t period, uint32_t duty_cycle, uint32_t tx_act, uint32_t rx_act);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Configure the WLAN COEX mode for BT.
|
||||
*
|
||||
* @param[in] txmode
|
||||
* @param[in] rxmode
|
||||
* @param[in] txmsk
|
||||
* @param[in] rxmsk
|
||||
* @param[in] txfmsk
|
||||
* @param[in] rxfmsk
|
||||
* @param[in] scanfmsk
|
||||
* @param[in] knudge
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_mws_config(uint8_t txmode, uint8_t rxmode, uint8_t txmsk, uint8_t rxmsk, uint8_t txfms, uint8_t rxfmsk, uint8_t scanfmsk, uint8_t knudge);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Start the MWS signal generator.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_mwsgen_start(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Stop the MWS signal generator.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_mwsgen_stop(void);
|
||||
#endif // RW_MWS_COEX_TEST
|
||||
|
||||
#if (RW_WLAN_COEX_TEST)
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Set the scenario for the unitary testing.
|
||||
*
|
||||
* @param[in] scenario Scenario type
|
||||
*
|
||||
* @return none
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
uint8_t dbg_wlcoex_scen_set(uint32_t scenario);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize and configure MWS event generator registers to be in WLAN mode.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_wlangen_init(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Set the period and duty cycle for the wlrxbsy signal.
|
||||
*
|
||||
* @param[in] period Period of the wlrxbsy signal (us)
|
||||
* @param[in] duty_cycle Duration of the high level (us)
|
||||
* @param[in] tx_act Duration of the tx activity (us)
|
||||
* @param[in] rx_act Duration of the rx activity (us)
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_wlangen_config(uint32_t period, uint32_t duty_cycle, uint32_t tx_act, uint32_t rx_act);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Configure the WLAN COEX mode for BT.
|
||||
*
|
||||
* @param[in] txmode
|
||||
* @param[in] rxmode
|
||||
* @param[in] txmsk
|
||||
* @param[in] rxmsk
|
||||
* @param[in] txthr
|
||||
* @param[in] rxthr
|
||||
* @param[in] pduration
|
||||
* @param[in] pdelay
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_wlan_config(uint8_t txmode, uint8_t rxmode, uint8_t txmsk, uint8_t rxmsk, uint8_t txthr, uint8_t rxthr, uint8_t pduration, uint8_t pdelay);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Start the wlrxbs signal generator.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_wlangen_start(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Stop the wlrxbs signal generator.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_wlangen_stop(void);
|
||||
#endif // RW_WLAN_COEX_TEST
|
||||
|
||||
#endif // (RW_WLAN_COEX_TEST) || (RW_MWS_COEX_TEST)
|
||||
|
||||
/// @} DBGMWSGEN
|
||||
|
||||
#endif // DBG_MWSGEN_H_
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file dbg_trc_config.h
|
||||
*
|
||||
* @brief Configuration of the Tracer module
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2016
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef DBG_TRC_CONFIG_H_
|
||||
#define DBG_TRC_CONFIG_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup TRACER
|
||||
* @{
|
||||
* @name Tracer module configuration
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#if defined CFG_TRC_ALL
|
||||
#define TRC_KE_MSG 1
|
||||
#define TRC_KE_TMR 1
|
||||
#define TRC_KE_EVT 1
|
||||
#define TRC_MEM 1
|
||||
#define TRC_SW_ASS 1
|
||||
#define TRC_CUSTOM 1
|
||||
|
||||
#if (BLE_EMB_PRESENT || BT_EMB_PRESENT)
|
||||
#define TRC_ARB 1
|
||||
#define TRC_PROG 1
|
||||
#define TRC_SLEEP 1
|
||||
#else // (BLE_EMB_PRESENT || BT_EMB_PRESENT)
|
||||
#define TRC_ARB 0
|
||||
#define TRC_PROG 0
|
||||
#define TRC_SLEEP 0
|
||||
#endif // (BLE_EMB_PRESENT || BT_EMB_PRESENT)
|
||||
|
||||
#if (BLE_EMB_PRESENT)
|
||||
#define TRC_CS_BLE 1
|
||||
#define TRC_LLCP 1
|
||||
#define TRC_LLC_STATE_TRANS 1
|
||||
#define TRC_RX_DESC 1
|
||||
#define TRC_ADV 1
|
||||
#define TRC_ACL 1
|
||||
#else /*(BLE_EMB_PRESENT)*/
|
||||
#define TRC_CS_BLE 0
|
||||
#define TRC_LLCP 0
|
||||
#define TRC_LLC_STATE_TRANS 0
|
||||
#define TRC_RX_DESC 0
|
||||
#define TRC_ADV 0
|
||||
#define TRC_ACL 0
|
||||
#endif /*(BLE_EMB_PRESENT)*/
|
||||
|
||||
#if (BLE_EMB_PRESENT && BLE_HOST_PRESENT)
|
||||
#define TRC_HCI 1
|
||||
#else /*(BLE_EMB_PRESENT && BLE_HOST_PRESENT)*/
|
||||
#define TRC_HCI 0
|
||||
#endif /*(BLE_EMB_PRESENT && BLE_HOST_PRESENT)*/
|
||||
|
||||
#if (BLE_HOST_PRESENT)
|
||||
#define TRC_L2CAP 1
|
||||
#else
|
||||
#define TRC_L2CAP 0
|
||||
#endif /*(BLE_HOST_PRESENT)*/
|
||||
|
||||
#if (BT_EMB_PRESENT)
|
||||
#define TRC_CS_BT 1
|
||||
#define TRC_LMP 1
|
||||
#define TRC_LC_STATE_TRANS 1
|
||||
#else
|
||||
#define TRC_CS_BT 0
|
||||
#define TRC_LMP 0
|
||||
#define TRC_LC_STATE_TRANS 0
|
||||
#endif /*(BT_EMB_PRESENT)*/
|
||||
|
||||
#else /*(CFG_TRC_ALL)*/
|
||||
|
||||
#if defined CFG_TRC_KE_MSG
|
||||
#define TRC_KE_MSG 1
|
||||
#else
|
||||
#define TRC_KE_MSG 0
|
||||
#endif /*(CFG_TRC_KE_MSG)*/
|
||||
|
||||
#if defined CFG_TRC_KE_TMR
|
||||
#define TRC_KE_TMR 1
|
||||
#else
|
||||
#define TRC_KE_TMR 0
|
||||
#endif /*CFG_TRC_KE_TMR*/
|
||||
|
||||
#if defined CFG_TRC_KE_EVT
|
||||
#define TRC_KE_EVT 1
|
||||
#else
|
||||
#define TRC_KE_EVT 0
|
||||
#endif /*CFG_TRC_KE_EVT*/
|
||||
|
||||
#if defined CFG_TRC_MEM
|
||||
#define TRC_MEM 1
|
||||
#else
|
||||
#define TRC_MEM 0
|
||||
#endif /*CFG_TRC_MEM*/
|
||||
|
||||
|
||||
#if defined CFG_TRC_SW_ASS
|
||||
#define TRC_SW_ASS 1
|
||||
#else
|
||||
#define TRC_SW_ASS 0
|
||||
#endif /*CFG_TRC_SW_ASS*/
|
||||
|
||||
#if defined CFG_TRC_CUSTOM
|
||||
#define TRC_CUSTOM 1
|
||||
#else
|
||||
#define TRC_CUSTOM 0
|
||||
#endif /*CFG_TRC_CUSTOM*/
|
||||
|
||||
#if (BLE_EMB_PRESENT)
|
||||
#if defined CFG_TRC_CS_BLE
|
||||
#define TRC_CS_BLE 1
|
||||
#else
|
||||
#define TRC_CS_BLE 0
|
||||
#endif /*(CFG_TRC_CS_BLE)*/
|
||||
|
||||
#if defined CFG_TRC_LLCP
|
||||
#define TRC_LLCP 1
|
||||
#else
|
||||
#define TRC_LLCP 0
|
||||
#endif /*(CFG_TRC_LLCP)*/
|
||||
|
||||
#if defined CFG_TRC_LLC_STATE_TRANS
|
||||
#define TRC_LLC_STATE_TRANS 1
|
||||
#else
|
||||
#define TRC_LLC_STATE_TRANS 0
|
||||
#endif /*(CFG_TRC_LLC_STATE_TRANS)*/
|
||||
|
||||
#if defined CFG_TRC_ARB
|
||||
#define TRC_ARB 1
|
||||
#else
|
||||
#define TRC_ARB 0
|
||||
#endif /*CFG_TRC_ARB*/
|
||||
|
||||
#if defined CFG_TRC_RX_DESC
|
||||
#define TRC_RX_DESC 1
|
||||
#else
|
||||
#define TRC_RX_DESC 0
|
||||
#endif /*CFG_TRC_RX_DESC*/
|
||||
|
||||
#if defined CFG_TRC_PROG
|
||||
#define TRC_PROG 1
|
||||
#else
|
||||
#define TRC_PROG 0
|
||||
#endif /*CFG_TRC_PROG*/
|
||||
|
||||
#if defined CFG_TRC_SLEEP
|
||||
#define TRC_SLEEP 1
|
||||
#else
|
||||
#define TRC_SLEEP 0
|
||||
#endif /*CFG_TRC_SLEEP*/
|
||||
|
||||
#if defined CFG_TRC_ADV
|
||||
#define TRC_ADV 1
|
||||
#else
|
||||
#define TRC_ADV 0
|
||||
#endif /*(CFG_TRC_ADV)*/
|
||||
|
||||
#if defined CFG_TRC_ACL
|
||||
#define TRC_ACL 1
|
||||
#else
|
||||
#define TRC_ACL 0
|
||||
#endif /*(CFG_TRC_ACL)*/
|
||||
|
||||
#else /*(BLE_EMB_PRESENT)*/
|
||||
|
||||
#define TRC_CS_BLE 0
|
||||
#define TRC_LLCP 0
|
||||
#define TRC_LLC_STATE_TRANS 0
|
||||
#define TRC_ARB 0
|
||||
#define TRC_RX_DESC 0
|
||||
#define TRC_PROG 0
|
||||
#define TRC_SLEEP 0
|
||||
#define TRC_ADV 0
|
||||
#define TRC_ACL 0
|
||||
#endif /*(BLE_EMB_PRESENT)*/
|
||||
|
||||
#if (BLE_EMB_PRESENT && BLE_HOST_PRESENT)
|
||||
#if defined CFG_TRC_HCI
|
||||
#define TRC_HCI 1
|
||||
#else
|
||||
#define TRC_HCI 0
|
||||
#endif /*CFG_TRC_HCI*/
|
||||
#else /*(BLE_EMB_PRESENT && BLE_HOST_PRESENT)*/
|
||||
#define TRC_HCI 0
|
||||
#endif /*(BLE_EMB_PRESENT && BLE_HOST_PRESENT)*/
|
||||
|
||||
#if (BLE_HOST_PRESENT)
|
||||
#if defined CFG_TRC_L2CAP
|
||||
#define TRC_L2CAP 1
|
||||
#else
|
||||
#define TRC_L2CAP 0
|
||||
#endif /*CFG_TRC_L2CAP*/
|
||||
#else /*BLE_HOST_PRESENT*/
|
||||
#define TRC_L2CAP 0
|
||||
#endif /*BLE_HOST_PRESENT*/
|
||||
|
||||
#if (BT_EMB_PRESENT)
|
||||
#if defined CFG_TRC_CS_BT
|
||||
#define TRC_CS_BT 1
|
||||
#else
|
||||
#define TRC_CS_BT 0
|
||||
#endif /*CFG_TRC_CS_BT*/
|
||||
|
||||
#if defined CFG_TRC_LMP
|
||||
#define TRC_LMP 1
|
||||
#else
|
||||
#define TRC_LMP 0
|
||||
#endif /*CFG_TRC_LMP*/
|
||||
|
||||
#if defined CFG_TRC_LC_STATE_TRANS
|
||||
#define TRC_LC_STATE_TRANS 1
|
||||
#else
|
||||
#define TRC_LC_STATE_TRANS 0
|
||||
#endif /*CFG_TRC_LC_STATE_TRANS*/
|
||||
|
||||
#else /*BT_EMB_PRESENT*/
|
||||
|
||||
#define TRC_CS_BT 0
|
||||
#define TRC_LMP 0
|
||||
#define TRC_LC_STATE_TRANS 0
|
||||
|
||||
#endif /*BT_EMB_PRESENT*/
|
||||
|
||||
#endif /* CFG_TRC_ALL */
|
||||
/// @} TRACER
|
||||
#endif /* DBG_TRC_CONFIG_H_ */
|
||||
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file dbg_trc_int.h
|
||||
*
|
||||
* @brief This file contains definitions related to the Tracer module.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef DBG_TRC_INT_H_
|
||||
#define DBG_TRC_INT_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup TRACER
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include "rwip_config.h"
|
||||
|
||||
#if (TRACER_PRESENT)
|
||||
#include <stdint.h> // standard definitions
|
||||
#include <stdbool.h> // boolean
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
///Channel index length
|
||||
#define CHANNEL_ID_LEN 1
|
||||
|
||||
///lengths of trace packet fields
|
||||
#define SEQ_NUM_LEN 2
|
||||
#define TIMESTAMP_LEN 4
|
||||
#define TRC_CODE_LEN 1
|
||||
|
||||
#define TRC_FIX_LEN \
|
||||
CHANNEL_ID_LEN +\
|
||||
TRC_MSG_HDR_LEN +\
|
||||
SEQ_NUM_LEN +\
|
||||
TIMESTAMP_LEN +\
|
||||
TRC_CODE_LEN
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convenient wrapper to trc_mem_alloc()
|
||||
*
|
||||
* This macro calls trc_mem_alloc() passing as parameter the length of the trace packet
|
||||
*
|
||||
* @param[in] trace_pay Trace payload length
|
||||
*
|
||||
* @return Pointer to trace code field(or NULL if the trace cannot be written)
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define TRC_MEM_ALLOC(trace_pay) \
|
||||
dbg_trc_mem_alloc(TRC_FIX_LEN + trace_pay)
|
||||
|
||||
typedef uint8_t trc_id_t;
|
||||
typedef uint8_t trc_opcode_t;
|
||||
|
||||
/*
|
||||
* STRUCTURES DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
///Tracer Environment context structure
|
||||
struct dbg_trc_env_tag
|
||||
{
|
||||
/// Current tracer configuration word
|
||||
uint32_t curr_cw;
|
||||
|
||||
/// Compiled tracer configuration word
|
||||
uint32_t compiled_cw;
|
||||
};
|
||||
|
||||
/*
|
||||
* GLOBAL VARIABLE DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
///Tracer environment context
|
||||
extern struct dbg_trc_env_tag dbg_trc_env;
|
||||
|
||||
/*
|
||||
* TRANSPORT LAYER FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief initialize tracer TL
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_trc_tl_init();
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief trigger the transmission of tracer packets
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_trc_tx_trigger(void);
|
||||
|
||||
/*
|
||||
* MEMORY FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize tracer memory
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_trc_mem_init();
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Try to write a trace in memory.
|
||||
* @param[in] trace_len Trace packet length (expressed in bytes)
|
||||
*
|
||||
* @return Pointer to trace code field(or NULL if the trace cannot be written)
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t *dbg_trc_mem_alloc(uint16_t const trace_len);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Try to read a trace from the memory.
|
||||
*
|
||||
* @return Pointer to the total size of the trace (or NULL if the trace cannot be read)
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t *dbg_trc_mem_read();
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Deallocate a trace from the memory.
|
||||
*
|
||||
* This function marks the trace block pointed by the reading pointer as invalid and moves
|
||||
* it to the next trace block
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_trc_mem_dealloc();
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialization of the tracer
|
||||
*
|
||||
* This function initializes the tracer
|
||||
*
|
||||
* @param[in] init_type Type of initialization (@see enum rwip_init_type)
|
||||
****************************************************************************************
|
||||
*/
|
||||
void dbg_trc_init(uint8_t init_type);
|
||||
|
||||
#endif /* TRACER_PRESENT */
|
||||
/// @} TRACER
|
||||
#endif /* DBG_TRC_INT_H_ */
|
||||
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ecc_p256.h
|
||||
*
|
||||
* @brief ECC functions for P256
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ECC_P256_H_
|
||||
#define ECC_P256_H_
|
||||
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include "rwip_config.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "ke_task.h"
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#define ECC_PUBLICKEY_GENERATION 0x01
|
||||
#define ECC_DHKEY_GENERATION 0x02
|
||||
|
||||
|
||||
/*
|
||||
* STRUCTURE DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Multiplication result message structure
|
||||
/*@TRACE*/
|
||||
struct ecc_result_ind
|
||||
{
|
||||
uint8_t key_res_x[32];
|
||||
uint8_t key_res_y[32];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* VARIABLE DECLARATION
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Debug Private Key
|
||||
extern const uint8_t DebugE256SecretKey[32];
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize Elliptic Curve algorithm
|
||||
*
|
||||
* @param[in] init_type Type of initialization (@see enum rwip_init_type)
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ecc_init(uint8_t init_type);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Generate a Secret Key compliant with ECC P256 algorithm
|
||||
*
|
||||
* If key is forced, just check its validity
|
||||
*
|
||||
* @param[out] secret_key Private key - MSB First
|
||||
* @param[in] forced True if provided key is forced, else generate it.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ecc_gen_new_secret_key(uint8_t* secret_key, bool forced);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Generate a new Public key pair using ECC P256 algorithm
|
||||
*
|
||||
* @param[in] secret_key Private key - MSB First
|
||||
* @param[in] blocking Force to run full algorithm without continue mode
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ecc_gen_new_public_key(uint8_t* secret_key256, ke_msg_id_t msg_id, ke_task_id_t task_id);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Generate a new DHKey using ECC P256 algorithm
|
||||
*
|
||||
* @param[in] key_type Type of key to generate (1: public key | 2: DH key)
|
||||
* @param[in] secret_key Private key - MSB First
|
||||
* @param[in] public_key_x Peer public key x coordinate - LSB First
|
||||
* @param[in] public_key_y Peer public key y coordinate - LSB First
|
||||
* @param[in] msg_id Message task ID for the result indication
|
||||
* @param[in] task_id Client task ID (Task type + instance)
|
||||
* @param[in] public_key_valid True: public key is valid, False: public key uncertain
|
||||
*
|
||||
* @return status 0 if key generation is started, > 0 otherwise
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t ecc_generate_key256(uint8_t key_type, const uint8_t* secret_key, const uint8_t* public_key_x, const uint8_t* public_key_y, ke_msg_id_t msg_id, ke_task_id_t task_id, bool public_key_valid);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Abort a current DHKey generation procedure
|
||||
*
|
||||
* @param[in] task_id Client task ID (Task type + instance)
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ecc_abort_key256_generation(ke_task_id_t task_id);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve debug private and public keys
|
||||
*
|
||||
* @param[out] secret_key Private key - MSB First
|
||||
* @param[out] pub_key_x Public key x coordinate - LSB First
|
||||
* @param[out] pub_key_y Public key y coordinate - LSB First
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ecc_get_debug_Keys(uint8_t*secret_key, uint8_t* pub_key_x, uint8_t* pub_key_y);
|
||||
|
||||
|
||||
#endif /* ECC_P256_H_ */
|
||||
@@ -0,0 +1,593 @@
|
||||
/*!
|
||||
* \file xc6xxx_fmc_spi.c
|
||||
*
|
||||
* \brief Target xc6xxx hal fmc spi implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc6xxx_fmc_spi.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void *ram_memcpy_bytes(void *dst, const void *src, int size)
|
||||
{
|
||||
if(dst == NULL || src == NULL || size <= 0)
|
||||
return NULL;
|
||||
|
||||
char *pdst = (char *)dst;
|
||||
char *psrc = (char *)src;
|
||||
|
||||
if(pdst > psrc && pdst < psrc + size) {
|
||||
pdst = pdst + size - 1;
|
||||
psrc = psrc + size - 1;
|
||||
while(size--)
|
||||
*pdst-- = *psrc--;
|
||||
} else {
|
||||
while(size--)
|
||||
*pdst++ = *psrc++;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_Status_Wait_Idle(void)
|
||||
{
|
||||
uint32_t reg = 0;
|
||||
do {
|
||||
__READ_REG32(BLE_COMN_AGC_REG_OUT0, reg);
|
||||
} while(!(reg & FMC_IDLE_Msk));
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_WriteNByte(uint8_t* txdata, uint16_t len)
|
||||
{
|
||||
if(len == 0) return;
|
||||
|
||||
uint16_t n;
|
||||
uint8_t remain = len % 4;
|
||||
uint16_t cnt = len / 4;
|
||||
uint32_t mid_data[64+1] = { 0 };
|
||||
|
||||
if(cnt != 0) {
|
||||
for(n=0; n<cnt; n++) {
|
||||
mid_data[n] = ((txdata[n*4] << 24) | (txdata[n*4+1] << 16) |
|
||||
(txdata[n*4+2] << 8) | txdata[n*4+3]);
|
||||
}
|
||||
}
|
||||
|
||||
if(remain != 0) {
|
||||
for(n=0; n<remain; n++) {
|
||||
mid_data[cnt] |= (txdata[cnt*4+n] << (24-8*n));
|
||||
}
|
||||
}
|
||||
|
||||
if(cnt != 0) {
|
||||
if(remain != 0)
|
||||
cnt = cnt + 1;
|
||||
for(n=0; n<cnt; n++)
|
||||
__FMC_SPI_SendByte(mid_data[n]);
|
||||
} else {
|
||||
__FMC_SPI_SendByte(mid_data[0]);
|
||||
}
|
||||
|
||||
while(!(*FMC_SSI_STS & FMC_SPI_STS_REG_FLAG_TFE) ||
|
||||
(*FMC_SSI_STS & FMC_SSI_STS_BUSY));
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_ReadNByte(uint8_t* rxdata, uint16_t len)
|
||||
{
|
||||
if(len == 0) return;
|
||||
|
||||
uint16_t n;
|
||||
uint8_t remain = len % 4;
|
||||
uint16_t cnt = len / 4;
|
||||
uint32_t mid_data = 0;
|
||||
|
||||
if(cnt != 0) {
|
||||
for(n=0; n<cnt; n++) {
|
||||
mid_data = __FMC_SPI_RecvByte( );
|
||||
// printf("0_rcv: 0x%08x\n", mid_data);
|
||||
rxdata[n*4] = mid_data >> 24;
|
||||
rxdata[n*4+1] = mid_data >> 16;
|
||||
rxdata[n*4+2] = mid_data >> 8;
|
||||
rxdata[n*4+3] = mid_data;
|
||||
}
|
||||
}
|
||||
|
||||
if(remain != 0) {
|
||||
mid_data = __FMC_SPI_RecvByte( );
|
||||
// printf("1_rcv: 0x%08x\n", mid_data);
|
||||
for(n=0; n<remain; n++) {
|
||||
rxdata[cnt*4+n] = mid_data >> 24;
|
||||
rxdata[cnt*4+1+n] = mid_data >> 16;
|
||||
rxdata[cnt*4+2+n] = mid_data >> 8;
|
||||
rxdata[cnt*4+3+n] = mid_data;
|
||||
}
|
||||
}
|
||||
|
||||
while(*FMC_SSI_STS & FMC_SPI_STS_REG_FLAG_RFNE) {
|
||||
mid_data = __FMC_SPI_RecvByte( );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Enable(uint8_t dfs)
|
||||
{
|
||||
__WRITE_REG32(FMC_SSI_EN, 0);
|
||||
if(dfs != 0x1f) {
|
||||
uint32_t reg= *FMC_SSI_CTRL0;
|
||||
__CLEAR_BIT(reg, (uint32_t)0x1f);
|
||||
__SET_BIT(reg, (uint32_t)dfs);
|
||||
__WRITE_REG32(FMC_SSI_CTRL0, reg);
|
||||
}
|
||||
__WRITE_REG32(FMC_SSI_EN, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Disable(void)
|
||||
{
|
||||
__WRITE_REG32(FMC_SSI_EN, 0);
|
||||
uint32_t reg= *FMC_SSI_CTRL0;
|
||||
__CLEAR_BIT(reg, (uint32_t)0x1f);
|
||||
__SET_BIT(reg, (uint32_t)0x1f);
|
||||
__WRITE_REG32(FMC_SSI_CTRL0, reg);
|
||||
__WRITE_REG32(FMC_SSI_EN, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Init_Oprt(void)
|
||||
{
|
||||
/* BT_CLK 时钟控制寄存器 */
|
||||
__WRITE_REG32(CPR_BT_CLK_CTL, ((1<<4) | ((1<<4)<<16)));
|
||||
/* BT_MODEM_CLK 时钟控制寄存器 */
|
||||
__WRITE_REG32(CPR_BT_MODEM_CTL, ((1<<4) | ((1<<4)<<16)));
|
||||
/* 配置 BT_PCLK_EN 使能 */
|
||||
__SET_BIT(*CPR_CTLAPBCLKEN_GRCTL, ((1<<10) | ((1<<10)<<16)));
|
||||
__WRITE_REG32(CPR_SSI0_MCLK_CTL, ((1<<16) | ((0<<4) | ((1<<16)<<4))));
|
||||
__WRITE_REG32(CPR_RSTCTL_SUBRST_SW, ((0<<2) | ((1<<2)<<16)));
|
||||
__WRITE_REG32(CPR_RSTCTL_SUBRST_SW, ((1<<2) | ((1<<2)<<16)));
|
||||
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
__WRITE_REG32(FMC_SSI_EN, 0);
|
||||
uint32_t reg= *FMC_SSI_CTRL0;
|
||||
__CLEAR_BIT(reg, (uint32_t)0x1f);
|
||||
__SET_BIT(reg, (uint32_t)0x1f);
|
||||
__WRITE_REG32(FMC_SSI_CTRL0, reg);
|
||||
*FMC_SSI_CTRL0 &= ~((uint32_t)0x01 << 14);
|
||||
|
||||
__WRITE_REG32(FMC_SSI_SE, 1);
|
||||
__WRITE_REG32(FMC_SSI_IE, 0);
|
||||
__WRITE_REG32(FMC_SSI_BAUD, 2);
|
||||
__WRITE_REG32(FMC_SSI_TXFTL, 0);
|
||||
__WRITE_REG32(FMC_SSI_RXFTL, 0);
|
||||
__WRITE_REG32(FMC_SSI_EN, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_PowerDown(void)
|
||||
{
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
uint8_t cmd[4];
|
||||
|
||||
cmd[0] = 0;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 0;
|
||||
cmd[3] = CMD_PWRDWN;
|
||||
|
||||
FMC_SPI_Enable(0x07);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
FMC_SPI_Disable( );
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_WakeUp(void)
|
||||
{
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
uint8_t cmd[4];
|
||||
|
||||
cmd[0] = 0;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 0;
|
||||
cmd[3] = CMD_RELEASE_PWRDWN;
|
||||
|
||||
FMC_SPI_Enable(0x07);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
FMC_SPI_Disable( );
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE uint8_t FMC_SPI_Flash_Status(void)
|
||||
{
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
uint8_t cmd[2] = { 0 };
|
||||
uint8_t sta[4] = { 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
cmd[0] = CMD_READ_STATUS;
|
||||
cmd[1] = 0xff;
|
||||
|
||||
FMC_SPI_Enable(0x1f);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
FMC_SPI_ReadNByte(sta, sizeof(sta));
|
||||
FMC_SPI_Disable( );
|
||||
|
||||
return sta[1];
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_Wait_Busy(void)
|
||||
{
|
||||
while(( FMC_SPI_Flash_Status( ) & 0x01 ));
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_Write_Enable(void)
|
||||
{
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
uint8_t cmd[4] = { 0 };
|
||||
|
||||
cmd[0] = 0;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 0;
|
||||
cmd[3] = CMD_WRITE_ENABLE;
|
||||
|
||||
FMC_SPI_Enable(0x07);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
FMC_SPI_Disable( );
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_Erase_Sector(uint32_t Dst_Addr)
|
||||
{
|
||||
// FMC_Status_Wait_Idle( );
|
||||
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
FMC_SPI_Flash_Write_Enable( );
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
|
||||
uint8_t cmd[4] = { 0 };
|
||||
|
||||
cmd[0] = CMD_SECTOR_ERASE;
|
||||
cmd[1] = Dst_Addr>>16;
|
||||
cmd[2] = Dst_Addr>>8;
|
||||
cmd[3] = Dst_Addr;
|
||||
|
||||
FMC_SPI_Enable(0x1f);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
FMC_SPI_Disable( );
|
||||
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_WritePage(uint32_t WriteAddr, uint8_t *data, uint16_t size)
|
||||
{
|
||||
if(size > FLASH_PAGE_SIZE)
|
||||
return;
|
||||
|
||||
uint32_t addr = WriteAddr;
|
||||
uint8_t cmd[16+4] = { 0 };
|
||||
|
||||
for(uint8_t i=0; i<16; i++) {
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
FMC_SPI_Flash_Write_Enable( );
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
|
||||
cmd[0] = CMD_PAGE_PROGRAM;
|
||||
cmd[1] = addr >> 16;
|
||||
cmd[2] = addr >> 8;
|
||||
cmd[3] = addr;
|
||||
|
||||
ram_memcpy_bytes(&cmd[4], data+i*16, 16);
|
||||
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
FMC_SPI_Enable(0x1f);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
|
||||
addr += 16;
|
||||
}
|
||||
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
FMC_SPI_Disable( );
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_ReadPage(uint32_t ReadAddr, uint8_t *data, uint16_t size)
|
||||
{
|
||||
if(size > FLASH_PAGE_SIZE)
|
||||
return;
|
||||
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
uint8_t cmd[16+4] = { 0 };
|
||||
uint8_t mid[16+4] = { 0 };
|
||||
uint16_t rx_idx = 0;
|
||||
uint32_t addr = ReadAddr;
|
||||
|
||||
for(uint8_t i=0; i<16; i++) {
|
||||
cmd[0] = CMD_READ_DATA;
|
||||
cmd[1] = addr >> 16;
|
||||
cmd[2] = addr >> 8;
|
||||
cmd[3] = addr;
|
||||
|
||||
FMC_SPI_Enable(0x1f);
|
||||
FMC_SPI_WriteNByte(cmd, 20); //sizeof(cmd)
|
||||
FMC_SPI_ReadNByte(mid, 20); //sizeof(mid)
|
||||
|
||||
ram_memcpy_bytes(&data[rx_idx], mid+4, 16);
|
||||
addr += 16;
|
||||
rx_idx += 16;
|
||||
}
|
||||
|
||||
FMC_SPI_Disable( );
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE uint8_t FMC_SPI_FlashWrite(uint32_t writeAddr, uint8_t *buff, uint16_t len)
|
||||
{
|
||||
uint32_t cur_addr = writeAddr;
|
||||
uint32_t end_addr = writeAddr + len;
|
||||
uint16_t wt_len = 0;
|
||||
uint16_t CurPageNum = 0; //本次数据存储所占用的当前页号
|
||||
uint32_t CurStartPsr = 0; //本次地址在 当前页所占的位置
|
||||
uint8_t temp_buff[FLASH_PAGE_SIZE] = { 0 };
|
||||
|
||||
while (cur_addr != end_addr) {
|
||||
/* code */
|
||||
CurPageNum = CUR_PAGE_NUM(cur_addr);
|
||||
CurStartPsr = CUR_START_PSR(cur_addr);
|
||||
FMC_SPI_Flash_ReadPage(CurPageNum*FLASH_PAGE_SIZE, temp_buff, FLASH_PAGE_SIZE);
|
||||
if(CurStartPsr) {
|
||||
ram_memcpy_bytes(&temp_buff[CurStartPsr], buff+wt_len, (256-CurStartPsr)>len-wt_len? len-wt_len:(256-CurStartPsr));
|
||||
wt_len += wt_len + ((256-CurStartPsr)>len-wt_len? len-wt_len:(256-CurStartPsr));
|
||||
cur_addr += wt_len;
|
||||
} else {
|
||||
ram_memcpy_bytes(temp_buff, buff+wt_len, len-wt_len>256? 256:len-wt_len);
|
||||
cur_addr += (len-wt_len>256? 256:len-wt_len);
|
||||
wt_len += (len-wt_len>256? 256:len-wt_len);
|
||||
}
|
||||
FMC_SPI_Flash_WritePage(CurPageNum*FLASH_PAGE_SIZE, temp_buff, FLASH_PAGE_SIZE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
|
||||
* @return[out]
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE uint8_t FMC_SPI_FlashRead(uint32_t readAddr, uint8_t *buff, uint16_t len)
|
||||
{
|
||||
uint32_t cur_addr = readAddr;
|
||||
uint32_t end_addr = readAddr + len;
|
||||
uint16_t rd_len = 0;
|
||||
uint16_t CurPageNum = 0; //本次数据存储所占用的当前页号
|
||||
uint32_t CurStartPsr = 0; //本次地址在 当前页所占的位置
|
||||
uint8_t temp_buff[FLASH_PAGE_SIZE] = { 0 };
|
||||
|
||||
while (cur_addr != end_addr) {
|
||||
CurPageNum = CUR_PAGE_NUM(cur_addr);
|
||||
CurStartPsr = CUR_START_PSR(cur_addr);
|
||||
FMC_SPI_Flash_ReadPage(CurPageNum*FLASH_PAGE_SIZE, temp_buff, FLASH_PAGE_SIZE);
|
||||
if(CurStartPsr) {
|
||||
ram_memcpy_bytes(buff, &temp_buff[CurStartPsr], (256-CurStartPsr)>len-rd_len? len-rd_len:(256-CurStartPsr));
|
||||
rd_len += rd_len + ((256-CurStartPsr)>len-rd_len? len-rd_len:(256-CurStartPsr));
|
||||
cur_addr += rd_len;
|
||||
} else {
|
||||
ram_memcpy_bytes(buff+rd_len, temp_buff, len-rd_len>256? 256:len-rd_len);
|
||||
cur_addr += (len-rd_len>256? 256:len-rd_len);
|
||||
rd_len += (len-rd_len>256? 256:len-rd_len);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_RUID(uint8_t *ruid)
|
||||
{
|
||||
FMC_Status_Wait_Idle( );
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
|
||||
uint8_t cmd[21] = { 0 };
|
||||
uint8_t id[21] = { 0 };
|
||||
|
||||
cmd[0] = CMD_RUID;
|
||||
cmd[1] = 0xff;
|
||||
cmd[2] = 0xff;
|
||||
cmd[3] = 0xff;
|
||||
cmd[4] = 0xff;
|
||||
|
||||
FMC_SPI_Enable(0x1f);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
|
||||
FMC_SPI_ReadNByte(id, sizeof(id));
|
||||
FMC_SPI_Disable( );
|
||||
|
||||
ram_memcpy_bytes(ruid, &id[5], 16);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_RDID(uint8_t *rdid)
|
||||
{
|
||||
FMC_Status_Wait_Idle( );
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
|
||||
uint8_t cmd[4] = { 0 };
|
||||
uint8_t id[4] = { 0 };
|
||||
|
||||
cmd[0] = CMD_RDID;
|
||||
cmd[1] = 0xff;
|
||||
cmd[2] = 0xff;
|
||||
cmd[3] = 0xff;
|
||||
|
||||
FMC_SPI_Enable(0x1f);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
|
||||
FMC_SPI_ReadNByte(id, sizeof(id));
|
||||
FMC_SPI_Disable( );
|
||||
|
||||
ram_memcpy_bytes(rdid, &id[1], 3);
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*!
|
||||
* \file xc6xxx_fmc_spi.h
|
||||
*
|
||||
* \brief The header of xc6xxx_fmc_spi.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __XC6xxx_FMC_SPI_H_
|
||||
#define __XC6xxx_FMC_SPI_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define __RAM_CODE __attribute__((section("ram_code")))
|
||||
|
||||
#define __WRITE_REG32(REG, VAL) ((*REG) = (VAL))
|
||||
#define __READ_REG32(REG, VAL) ((VAL) = (*REG))
|
||||
#define __SET_BIT(REG, BIT) ((REG) |= (BIT))
|
||||
#define __CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
|
||||
|
||||
// Register Address Definition
|
||||
#define CPR_BASE 0x40000000UL
|
||||
#define FMC_BASE 0x51000000UL
|
||||
#define BLE_COMMON_BASE 0x53022000UL
|
||||
|
||||
#define CPR_BT_CLK_CTL ((volatile uint32_t *)(CPR_BASE + 0x40))
|
||||
#define CPR_BT_MODEM_CTL ((volatile uint32_t *)(CPR_BASE + 0x48))
|
||||
#define CPR_SSI0_MCLK_CTL ((volatile uint32_t *)(CPR_BASE + 0x50))
|
||||
#define CPR_CTLAPBCLKEN_GRCTL ((volatile uint32_t *)(CPR_BASE + 0x70))
|
||||
#define CPR_RSTCTL_SUBRST_SW ((volatile uint32_t *)(CPR_BASE + 0x104))
|
||||
|
||||
#define FMC_SSI_CTRL0 ((volatile uint32_t *)(FMC_BASE + 0x00))
|
||||
#define FMC_SSI_CTRL1 ((volatile uint32_t *)(FMC_BASE + 0x04))
|
||||
#define FMC_SSI_EN ((volatile uint32_t *)(FMC_BASE + 0x08))
|
||||
#define FMC_SSI_SE ((volatile uint32_t *)(FMC_BASE + 0x10))
|
||||
#define FMC_SSI_BAUD ((volatile uint32_t *)(FMC_BASE + 0x14))
|
||||
#define FMC_SSI_TXFTL ((volatile uint32_t *)(FMC_BASE + 0x18))
|
||||
#define FMC_SSI_RXFTL ((volatile uint32_t *)(FMC_BASE + 0x1C))
|
||||
#define FMC_SSI_TXFL ((volatile uint32_t *)(FMC_BASE + 0x20))
|
||||
#define FMC_SSI_RXFL ((volatile uint32_t *)(FMC_BASE + 0x24))
|
||||
#define FMC_SSI_STS ((volatile uint32_t *)(FMC_BASE + 0x28))
|
||||
#define FMC_SSI_IE ((volatile uint32_t *)(FMC_BASE + 0x2C))
|
||||
#define FMC_SSI_DATA ((volatile uint32_t *)(FMC_BASE + 0x60))
|
||||
|
||||
|
||||
#define BLE_COMN_AGC_REG_OUT0 ((volatile uint32_t *)(BLE_COMMON_BASE + 0x28))
|
||||
|
||||
#define FMC_IDLE_Pos (31U)
|
||||
#define FMC_IDLE_Msk (1UL << FMC_IDLE_Pos)
|
||||
#define FMC_IDLE_STATUS FMC_IDLE_Msk
|
||||
|
||||
#define FMC_SSI_STS_BUSY (1UL)
|
||||
|
||||
#define FMC_SSI_STS_REG_TFE_Pos (2UL)
|
||||
#define FMC_SSI_STS_REG_TFE_EMPTY (1UL << FMC_SSI_STS_REG_TFE_Pos) /*!< 发送 FIFO 空. */
|
||||
#define FMC_SPI_STS_REG_FLAG_TFE ((uint16_t)FMC_SSI_STS_REG_TFE_EMPTY)
|
||||
|
||||
#define FMC_SSI_STS_REG_RFNE_Pos (3UL) /*!< Position of RFNE field. */
|
||||
#define FMC_SSI_STS_REG_RFNE_NOT_EMPTY (1UL << FMC_SSI_STS_REG_RFNE_Pos) /*!<接收 FIFO 非空 */
|
||||
#define FMC_SPI_STS_REG_FLAG_RFNE ((uint16_t)FMC_SSI_STS_REG_RFNE_NOT_EMPTY)
|
||||
|
||||
#define CMD_ERASE_SECURITY_REG (uint8_t)0x44
|
||||
#define CMD_READ_SECURITY_REG (uint8_t)0x48
|
||||
#define CMD_PROGRAM_SECURITY_REG (uint8_t)0x42
|
||||
|
||||
|
||||
#define OTP_PROGRAM_PAGE_1 (uint8_t)0x10
|
||||
#define OTP_PROGRAM_PAGE_2 (uint8_t)0x20
|
||||
#define OTP_PROGRAM_PAGE_3 (uint8_t)0x30
|
||||
|
||||
#define CMD_READ_DATA (uint8_t)0x03
|
||||
#define CMD_READ_STATUS (uint8_t)0x05
|
||||
#define CMD_CHIP_ERASE (uint8_t)0xc7
|
||||
#define CMD_WRITE_ENABLE (uint8_t)0x06
|
||||
#define CMD_WRITE_DISABLE (uint8_t)0x04
|
||||
#define CMD_PAGE_PROGRAM (uint8_t)0x02
|
||||
#define CMD_BLOCK_ERASE (uint8_t)0xD8
|
||||
#define CMD_SECTOR_ERASE (uint8_t)0x20
|
||||
#define CMD_PAGE_ERASE (uint8_t)0x81
|
||||
#define CMD_RELEASE_PWRDWN (uint8_t)0xAB
|
||||
#define CMD_PWRDWN (uint8_t)0xB9
|
||||
#define CMD_RUID (uint8_t)0x4B
|
||||
#define CMD_RDID (uint8_t)0x9F
|
||||
|
||||
#define FLASH_PAGE_SIZE 256
|
||||
|
||||
#define CUR_PAGE_NUM(addr) (addr/FLASH_PAGE_SIZE)
|
||||
#define CUR_START_PSR(addr) (addr%FLASH_PAGE_SIZE)
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Inline Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
__RAM_CODE static inline void __FMC_SPI_SendByte(uint32_t byte)
|
||||
{
|
||||
*FMC_SSI_DATA = byte;
|
||||
}
|
||||
|
||||
__RAM_CODE static inline uint32_t __FMC_SPI_RecvByte(void)
|
||||
{
|
||||
return (uint32_t)(*FMC_SSI_DATA);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
__RAM_CODE void FMC_SPI_Init_Oprt(void);
|
||||
__RAM_CODE void FMC_SPI_Flash_PowerDown(void);
|
||||
__RAM_CODE void FMC_SPI_Flash_WakeUp(void);
|
||||
__RAM_CODE void FMC_SPI_Flash_Wait_Busy(void);
|
||||
__RAM_CODE void FMC_SPI_Flash_Write_Enable(void);
|
||||
__RAM_CODE void FMC_SPI_Flash_Erase_Sector(uint32_t Dst_Addr);
|
||||
__RAM_CODE void FMC_SPI_Flash_Erase_Page(uint32_t Dst_Addr);
|
||||
__RAM_CODE void FMC_SPI_Flash_WritePage(uint32_t WriteAddr, uint8_t *data, uint16_t size);
|
||||
__RAM_CODE void FMC_SPI_Flash_ReadPage(uint32_t ReadAddr, uint8_t *data, uint16_t size);
|
||||
__RAM_CODE uint8_t FMC_SPI_FlashWrite(uint32_t writeAddr, uint8_t *buff, uint16_t len);
|
||||
__RAM_CODE uint8_t FMC_SPI_FlashRead(uint32_t readAddr, uint8_t *buff, uint16_t len);
|
||||
__RAM_CODE void FMC_SPI_Flash_RUID(uint8_t *ruid);
|
||||
__RAM_CODE void FMC_SPI_Flash_RDID(uint8_t *rdid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __XC6xxx_FMC_SPI_H_ */
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file h4tl.h
|
||||
*
|
||||
* @brief H4 UART Transport Layer header file.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef H4TL_H_
|
||||
#define H4TL_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup H4TL H4 UART Transport Layer
|
||||
* @ingroup H4TL
|
||||
* @brief H4 UART Transport Layer
|
||||
*
|
||||
* This module creates the abstraction between External UART driver and HCI generic functions
|
||||
* (designed for H4 UART transport layer).
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include "rwip_config.h" // stack configuration
|
||||
|
||||
#if (H4TL_SUPPORT)
|
||||
#include "rwip.h" // SW interface
|
||||
|
||||
#include <stdint.h> // standard integer definition
|
||||
#include <stdbool.h> // standard boolean definition
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Size of the logical channel identifier for H4 messages
|
||||
#define H4TL_LOGICAL_CHANNEL_LEN (1)
|
||||
|
||||
/**
|
||||
* Number of H4TL interfaces
|
||||
*
|
||||
* * NB=2: AHI and HCI: for Host-only stack with external app
|
||||
* - HCI has index 0
|
||||
* - AHI has index 1
|
||||
* * NB=1: AHI or HCI: for all other partitions
|
||||
*
|
||||
* Note: it is not possible to have no channel (H4TL must not be included in build in this case)
|
||||
*/
|
||||
#if (!BLE_EMB_PRESENT && HCI_TL_SUPPORT && AHI_TL_SUPPORT)
|
||||
#define H4TL_NB_CHANNEL 2
|
||||
#else // (!BLE_EMB_PRESENT && HCI_TL_SUPPORT && AHI_TL_SUPPORT)
|
||||
#define H4TL_NB_CHANNEL 1
|
||||
#endif // (!BLE_EMB_PRESENT && HCI_TL_SUPPORT && AHI_TL_SUPPORT)
|
||||
|
||||
|
||||
/*
|
||||
* GLOBAL VARIABLE DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief H4TL transport initialization.
|
||||
*
|
||||
* Puts the External Interface driver in reception, waiting for simple 1 byte message type. Space for
|
||||
* reception is allocated with ke_msg_alloc and the pointer is handed to env.rx. RX
|
||||
* interrupt is enabled.
|
||||
*
|
||||
* @param[in] tl_type Transport Layer Interface (@see enum h4tl_itf)
|
||||
* @param[in] eif External interface API
|
||||
*
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void h4tl_init(uint8_t tl_type, const struct rwip_eif_api* eif);
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief H4TL write function.
|
||||
*
|
||||
* @param[in] type Type of the buffer to be transmitted. It can take one of the following
|
||||
* values:
|
||||
* - @ref HCI_EVT_MSG_TYPE for event message
|
||||
* - @ref HCI_ACL_MSG_TYPE for ACL data
|
||||
* - @ref HCI_SYNC_MSG_TYPE for synchronous data
|
||||
*
|
||||
* @param[in] buf Pointer to the buffer to be transmitted. @note The buffer passed as
|
||||
* parameter must have one free byte before the first payload byte, so that the H4TL
|
||||
* module can put the type byte as first transmitted data.
|
||||
*
|
||||
* @param[in] len Length of the buffer to be transmitted.
|
||||
* @param[in] tx_callback Callback for indicating the end of transfer
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void h4tl_write(uint8_t type, uint8_t *buf, uint16_t len, void (*tx_callback)(void));
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Start External Interface input flow
|
||||
*
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void h4tl_start(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Stop External Interface input flow if possible
|
||||
*
|
||||
* @return true if External Interface flow was stopped, false otherwise
|
||||
*****************************************************************************************
|
||||
*/
|
||||
bool h4tl_stop(void);
|
||||
|
||||
#endif //H4TL_SUPPORT
|
||||
|
||||
/// @} H4TL
|
||||
|
||||
#endif // H4TL_H_
|
||||
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ke.h
|
||||
*
|
||||
* @brief This file contains the definition of the kernel environment.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _KE_H_
|
||||
#define _KE_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup ENV Environment
|
||||
* @ingroup KERNEL
|
||||
* @brief Kernel Environment
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include "rwip_config.h" // stack configuration
|
||||
|
||||
#include <stdbool.h> // standard boolean definitions
|
||||
#include <stdint.h> // standard integer definitions
|
||||
|
||||
/*
|
||||
* ENUMERATION
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Kernel Error Status
|
||||
enum KE_STATUS
|
||||
{
|
||||
KE_SUCCESS = 0,
|
||||
KE_FAIL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function performs all the initializations of the kernel.
|
||||
*
|
||||
* It initializes first the heap, then the message queues and the events. Then if required
|
||||
* it initializes the trace.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_init(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function flushes all messages currently pending in the kernel.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_flush(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function checks if sleep is possible or kernel is processing
|
||||
*
|
||||
* @return True if sleep is allowed, false otherwise
|
||||
****************************************************************************************
|
||||
*/
|
||||
bool ke_sleep_check(void);
|
||||
|
||||
#if (KE_PROFILING)
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function gets the statistics of the kernel usage.
|
||||
*
|
||||
* @param[out] max_msg_sent Max message sent
|
||||
* @param[out] max_msg_saved Max message saved
|
||||
* @param[out] max_timer_used Max timer used
|
||||
* @param[out] max_heap_used Max heap used
|
||||
****************************************************************************************
|
||||
*/
|
||||
enum KE_STATUS ke_stats_get(uint8_t* max_msg_sent,
|
||||
uint8_t* max_msg_saved,
|
||||
uint8_t* max_timer_used,
|
||||
uint16_t* max_heap_used);
|
||||
#endif //KE_PROFILING
|
||||
|
||||
/// @} KE
|
||||
|
||||
#endif // _KE_H_
|
||||
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ke_event.h
|
||||
*
|
||||
* @brief This file contains the definition related to kernel events.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _KE_EVENT_H_
|
||||
#define _KE_EVENT_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup EVT Events and Schedule
|
||||
* @ingroup KERNEL
|
||||
* @brief Event scheduling module.
|
||||
*
|
||||
* The KE_EVT module implements event scheduling functions. It can be used to
|
||||
* implement deferred actions.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include "rwip_config.h" // stack configuration
|
||||
|
||||
#include <stdint.h> // standard integer definition
|
||||
|
||||
|
||||
/*
|
||||
* CONSTANTS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/// Status of ke_task API functions
|
||||
enum KE_EVENT_STATUS
|
||||
{
|
||||
KE_EVENT_OK = 0,
|
||||
KE_EVENT_FAIL,
|
||||
KE_EVENT_UNKNOWN,
|
||||
KE_EVENT_CAPA_EXCEEDED,
|
||||
KE_EVENT_ALREADY_EXISTS,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* TYPE DEFINITION
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION PROTOTYPES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize Kernel event module.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_event_init(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Register an event callback.
|
||||
*
|
||||
* @param[in] event_type Event type.
|
||||
* @param[in] p_callback Pointer to callback function.
|
||||
*
|
||||
* @return Status
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t ke_event_callback_set(uint8_t event_type, void (*p_callback)(void));
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Set an event
|
||||
*
|
||||
* This primitive sets one event. It will trigger the call to the corresponding event
|
||||
* handler in the next scheduling call.
|
||||
*
|
||||
* @param[in] event_type Event to be set.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_event_set(uint8_t event_type);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Clear an event
|
||||
*
|
||||
* @param[in] event_type Event to be cleared.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_event_clear(uint8_t event_type);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Get the status of an event
|
||||
*
|
||||
* @param[in] event_type Event to get.
|
||||
*
|
||||
* @return Event status (0: not set / 1: set)
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t ke_event_get(uint8_t event_type);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Get all event status
|
||||
*
|
||||
* @return Events bit field
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint32_t ke_event_get_all(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Flush all pending events.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_event_flush(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Event scheduler entry point.
|
||||
*
|
||||
* This primitive is the entry point of Kernel event scheduling.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_event_schedule(void);
|
||||
|
||||
|
||||
|
||||
/// @} EVT
|
||||
|
||||
#endif //_KE_EVENT_H_
|
||||
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ke_mem.h
|
||||
*
|
||||
* @brief API for the heap management module.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _KE_MEM_H_
|
||||
#define _KE_MEM_H_
|
||||
|
||||
#include "rwip_config.h" // IP configuration
|
||||
#include <stdint.h> // standard integer
|
||||
#include <stdbool.h> // standard includes
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @defgroup MEM Memory
|
||||
* @ingroup KERNEL
|
||||
* @brief Heap management module.
|
||||
*
|
||||
* This module implements heap management functions that allow initializing heap,
|
||||
* allocating and freeing memory.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
// forward declarations
|
||||
struct mblock_free;
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Heap initialization.
|
||||
*
|
||||
* This function performs the following operations:
|
||||
* - sanity checks
|
||||
* - check memory allocated is at least large enough to hold two block descriptors to hold
|
||||
* start and end
|
||||
* - initialize the first and last descriptors
|
||||
* - save heap into kernel environment variable.
|
||||
*
|
||||
* @param[in] type Memory type.
|
||||
* @param[in|out] heap Heap pointer
|
||||
* @param[in] heap_size Size of the heap
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_mem_init(uint8_t type, uint8_t* heap, uint16_t heap_size);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Allocation of a block of memory.
|
||||
*
|
||||
* Allocates a memory block whose size is size; if no memory is available return NULL
|
||||
*
|
||||
* @param[in] size Size of the memory area that need to be allocated.
|
||||
* @param[in] type Type of memory block
|
||||
*
|
||||
* @return A pointer to the allocated memory area.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void *ke_malloc(uint32_t size, uint8_t type);
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Check if it's possible to allocate a block of memory with a specific size.
|
||||
*
|
||||
* @param[in] size Size of the memory area that need to be allocated.
|
||||
* @param[in] type Type of memory block
|
||||
*
|
||||
* @return True if memory block can be allocated, False else.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
bool ke_check_malloc(uint32_t size, uint8_t type);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Freeing of a block of memory.
|
||||
*
|
||||
* Free the memory area pointed by mem_ptr : mark the block as free and insert it in
|
||||
* the pool of free block.
|
||||
*
|
||||
* @param[in] mem_ptr Pointer to the memory area that need to be freed.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_free(void *mem_ptr);
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Check if current heap is empty or not (not used)
|
||||
*
|
||||
* @param[in] type Type of memory heap block
|
||||
*
|
||||
* @return true if heap not used, false else.
|
||||
****************************************************************************************
|
||||
*/
|
||||
bool ke_mem_is_empty(uint8_t type);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Check if current pointer is free or not
|
||||
*
|
||||
* @param[in] mem_ptr pointer to a memory block
|
||||
*
|
||||
* @return true if already free, false else.
|
||||
****************************************************************************************
|
||||
*/
|
||||
bool ke_is_free(void* mem_ptr);
|
||||
|
||||
#if (KE_PROFILING)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve memory usage of selected heap.
|
||||
*
|
||||
* @param[in] type Type of memory heap block
|
||||
*
|
||||
* @return current memory usage of current heap.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint16_t ke_get_mem_usage(uint8_t type);
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve max memory usage of all heap.
|
||||
* This command also resets max measured value.
|
||||
*
|
||||
* @return max memory usage of all heap.
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint32_t ke_get_max_mem_usage(void);
|
||||
|
||||
#endif // (KE_PROFILING)
|
||||
|
||||
///@} MEM
|
||||
|
||||
#endif // _KE_MEM_H_
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ke_msg.h
|
||||
*
|
||||
* @brief This file contains the definition related to message scheduling.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _KE_MSG_H_
|
||||
#define _KE_MSG_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @defgroup MSG Message Exchange
|
||||
* @ingroup KERNEL
|
||||
* @brief Message scheduling module.
|
||||
*
|
||||
* The MSG module implements message scheduling functions.
|
||||
|
||||
* A kernel message has an ID, a receiver task ID and a source task ID.
|
||||
* In most cases, it also has parameters which are defined in
|
||||
* a structure dynamically embedded in the message structure,
|
||||
* so the whole message will be managed internally as one block.
|
||||
*
|
||||
* A message can also have one extra parameter which is referenced
|
||||
* in the normal parameter structure. This extra block is assumed
|
||||
* to be large by the kernel and will be moved by DMA if needed.
|
||||
* This feature allows moving MMPDU from LMAC to UMAC.
|
||||
*
|
||||
* In order to send a message, a function first have to allocate
|
||||
* the memory for this message. It can be done with the wrapper
|
||||
* macro KE_MSG_ALLOC() (which will call ke_msg_alloc()).
|
||||
|
||||
* The message can then be sent with ke_msg_send(). The kernel
|
||||
* will take care of freeing the allocated memory.
|
||||
|
||||
* If the message has no parameters, the ke_msg_send_basic() function
|
||||
* can be used.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stddef.h> // standard definition
|
||||
#include <stdint.h> // standard integer
|
||||
#include <stdbool.h> // standard boolean
|
||||
#include "arch.h" // architectural definition
|
||||
#include "compiler.h" // compiler definition
|
||||
#include "co_list.h" // list definition
|
||||
|
||||
/// Task Identifier. Composed by the task type and the task index.
|
||||
typedef uint16_t ke_task_id_t;
|
||||
|
||||
/// Builds the task identifier from the type and the index of that task.
|
||||
#define KE_BUILD_ID(type, index) ( (ke_task_id_t)(((index) << 8)|(type)) )
|
||||
|
||||
/// Retrieves task type from task id.
|
||||
#define KE_TYPE_GET(ke_task_id) ((ke_task_id) & 0xFF)
|
||||
|
||||
/// Retrieves task index number from task id.
|
||||
#define KE_IDX_GET(ke_task_id) (((ke_task_id) >> 8) & 0xFF)
|
||||
|
||||
/// Task State
|
||||
typedef uint8_t ke_state_t;
|
||||
|
||||
/// Message Identifier. The number of messages is limited to 0xFFFF.
|
||||
/// The message ID is divided in two parts:
|
||||
/// bits[15~8]: task index (no more than 255 tasks support)
|
||||
/// bits[7~0]: message index(no more than 255 messages per task)
|
||||
/*@TRACE*/
|
||||
typedef uint16_t ke_msg_id_t;
|
||||
|
||||
/// Message structure.
|
||||
typedef struct ke_msg
|
||||
{
|
||||
struct co_list_hdr hdr; ///< List header for chaining
|
||||
|
||||
ke_msg_id_t id; ///< Message id.
|
||||
ke_task_id_t dest_id; ///< Destination kernel identifier.
|
||||
ke_task_id_t src_id; ///< Source kernel identifier.
|
||||
uint16_t param_len; ///< Parameter embedded struct length.
|
||||
uint32_t param[__ARRAY_EMPTY]; ///< Parameter embedded struct. Must be word-aligned.
|
||||
} ke_msg_t;
|
||||
|
||||
|
||||
/// Status returned by a task when handling a message
|
||||
/*@TRACE*/
|
||||
enum ke_msg_status_tag
|
||||
{
|
||||
KE_MSG_CONSUMED = 0, ///< consumed, msg and ext are freed by the kernel
|
||||
KE_MSG_NO_FREE, ///< consumed, nothing is freed by the kernel
|
||||
KE_MSG_SAVED, ///< not consumed, will be pushed in the saved queue
|
||||
};
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert a parameter pointer to a message pointer
|
||||
*
|
||||
* @param[in] param_ptr Pointer to the parameter member of a ke_msg
|
||||
* Usually retrieved by a ke_msg_alloc()
|
||||
*
|
||||
* @return The pointer to the ke_msg
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE struct ke_msg * ke_param2msg(void const *param_ptr)
|
||||
{
|
||||
return (struct ke_msg*) (((uint8_t*)param_ptr) - offsetof(struct ke_msg, param));
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convert a message pointer to a parameter pointer
|
||||
*
|
||||
* @param[in] msg Pointer to the ke_msg.
|
||||
*
|
||||
* @return The pointer to the param member
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE void * ke_msg2param(struct ke_msg const *msg)
|
||||
{
|
||||
return (void*) (((uint8_t*) msg) + offsetof(struct ke_msg, param));
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convenient wrapper to ke_msg_alloc()
|
||||
*
|
||||
* This macro calls ke_msg_alloc() and cast the returned pointer to the
|
||||
* appropriate structure. Can only be used if a parameter structure exists
|
||||
* for this message (otherwise, use ke_msg_send_basic()).
|
||||
*
|
||||
* @param[in] id Message identifier
|
||||
* @param[in] dest Destination Identifier
|
||||
* @param[in] src Source Identifier
|
||||
* @param[in] param_str parameter structure tag
|
||||
*
|
||||
* @return Pointer to the parameter member of the ke_msg.
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define KE_MSG_ALLOC(id, dest, src, param_str) \
|
||||
(struct param_str*) ke_msg_alloc(id, dest, src, sizeof(struct param_str))
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convenient wrapper to ke_msg_free()
|
||||
*
|
||||
* This macro calls ke_msg_free() with the appropriate msg pointer as parameter, according
|
||||
* to the message parameter pointer passed.
|
||||
*
|
||||
* @param[in] param_ptr parameter structure pointer
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define KE_MSG_FREE(param_ptr) ke_msg_free(ke_param2msg((param_ptr)))
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Convenient wrapper to ke_msg_alloc()
|
||||
*
|
||||
* This macro calls ke_msg_alloc() and cast the returned pointer to the
|
||||
* appropriate structure with a variable length. Can only be used if a parameter structure exists
|
||||
* for this message (otherwise, use ke_msg_send_basic()).Can only be used if the data array is
|
||||
* located at the end of the structure.
|
||||
*
|
||||
* @param[in] id Message identifier
|
||||
* @param[in] dest Destination Identifier
|
||||
* @param[in] src Source Identifier
|
||||
* @param[in] param_str parameter structure tag
|
||||
* @param[in] length length for the data
|
||||
*
|
||||
* @return Pointer to the parameter member of the ke_msg.
|
||||
****************************************************************************************
|
||||
*/
|
||||
#define KE_MSG_ALLOC_DYN(id, dest, src, param_str,length) (struct param_str*)ke_msg_alloc(id, dest, src, \
|
||||
(sizeof(struct param_str) + (length)));
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Allocate memory for a message
|
||||
*
|
||||
* This primitive allocates memory for a message that has to be sent. The memory
|
||||
* is allocated dynamically on the heap and the length of the variable parameter
|
||||
* structure has to be provided in order to allocate the correct size.
|
||||
*
|
||||
* Several additional parameters are provided which will be preset in the message
|
||||
* and which may be used internally to choose the kind of memory to allocate.
|
||||
*
|
||||
* The memory allocated will be automatically freed by the kernel, after the
|
||||
* pointer has been sent to ke_msg_send(). If the message is not sent, it must
|
||||
* be freed explicitly with ke_msg_free().
|
||||
*
|
||||
* Allocation failure is considered critical and should not happen.
|
||||
*
|
||||
* @param[in] id Message identifier
|
||||
* @param[in] dest_id Destination Task Identifier
|
||||
* @param[in] src_id Source Task Identifier
|
||||
* @param[in] param_len Size of the message parameters to be allocated
|
||||
*
|
||||
* @return Pointer to the parameter member of the ke_msg. If the parameter
|
||||
* structure is empty, the pointer will point to the end of the message
|
||||
* and should not be used (except to retrieve the message pointer or to
|
||||
* send the message)
|
||||
****************************************************************************************
|
||||
*/
|
||||
void *ke_msg_alloc(ke_msg_id_t const id, ke_task_id_t const dest_id,
|
||||
ke_task_id_t const src_id, uint16_t const param_len);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Message sending.
|
||||
*
|
||||
* Send a message previously allocated with any ke_msg_alloc()-like functions.
|
||||
*
|
||||
* The kernel will take care of freeing the message memory.
|
||||
*
|
||||
* Once the function have been called, it is not possible to access its data
|
||||
* anymore as the kernel may have copied the message and freed the original
|
||||
* memory.
|
||||
*
|
||||
* @param[in] param_ptr Pointer to the parameter member of the message that
|
||||
* should be sent.
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
void ke_msg_send(void const *param_ptr);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Basic message sending.
|
||||
*
|
||||
* Send a message that has a zero length parameter member. No allocation is
|
||||
* required as it will be done internally.
|
||||
*
|
||||
* @param[in] id Message identifier
|
||||
* @param[in] dest_id Destination Identifier
|
||||
* @param[in] src_id Source Identifier
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_msg_send_basic(ke_msg_id_t const id, ke_task_id_t const dest_id, ke_task_id_t const src_id);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Message forwarding.
|
||||
*
|
||||
* Forward a message to another task by changing its destination and source tasks IDs.
|
||||
*
|
||||
* @param[in] param_ptr Pointer to the parameter member of the message that
|
||||
* should be sent.
|
||||
* @param[in] dest_id New destination task of the message.
|
||||
* @param[in] src_id New source task of the message.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_msg_forward(void const *param_ptr, ke_task_id_t const dest_id, ke_task_id_t const src_id);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Message forwarding.
|
||||
*
|
||||
* Forward a message to another task by changing its message ID and its destination and source tasks IDs.
|
||||
*
|
||||
* @param[in] param_ptr Pointer to the parameter member of the message that
|
||||
* should be sent.
|
||||
* @param[in] msg_id New ID of the message.
|
||||
* @param[in] dest_id New destination task of the message.
|
||||
* @param[in] src_id New source task of the message.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_msg_forward_new_id(void const *param_ptr,
|
||||
ke_msg_id_t const msg_id, ke_task_id_t const dest_id, ke_task_id_t const src_id);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Free allocated message
|
||||
*
|
||||
* @param[in] msg Pointer to the message to be freed (not the parameter member!)
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_msg_free(struct ke_msg const *param);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve destination task identifier of a kernel message
|
||||
*
|
||||
* @param[in] param_ptr Pointer to the parameter member of the message.
|
||||
*
|
||||
* @return message destination task
|
||||
****************************************************************************************
|
||||
*/
|
||||
ke_msg_id_t ke_msg_dest_id_get(void const *param_ptr);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve source task identifier of a kernel message
|
||||
*
|
||||
* @param[in] param_ptr Pointer to the parameter member of the message.
|
||||
*
|
||||
* @return message source task
|
||||
****************************************************************************************
|
||||
*/
|
||||
ke_msg_id_t ke_msg_src_id_get(void const *param_ptr);
|
||||
|
||||
/**
|
||||
* Used to know if message is present in kernel queue or not.
|
||||
*
|
||||
* @param[in] param_ptr Pointer to the parameter member of the message.
|
||||
*
|
||||
* @return True if message is present in Kernel Queue, False else.
|
||||
*/
|
||||
bool ke_msg_in_queue(void const *param_ptr);
|
||||
/// @} MSG
|
||||
|
||||
#endif // _KE_MSG_H_
|
||||
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ke_task.h
|
||||
*
|
||||
* @brief This file contains the definition related to kernel task management.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _KE_TASK_H_
|
||||
#define _KE_TASK_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @defgroup TASK Task and Process
|
||||
* @ingroup KERNEL
|
||||
* @brief Task management module.
|
||||
*
|
||||
* This module implements the functions used for managing tasks.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include <stdint.h> // standard integer
|
||||
#include <stdbool.h> // standard boolean
|
||||
|
||||
#include "rwip_config.h" // stack configuration
|
||||
#include "compiler.h" // compiler defines, INLINE
|
||||
#include "ke_msg.h" // kernel message defines
|
||||
|
||||
/* Default Message handler code to handle several message type in same handler. */
|
||||
#define KE_MSG_DEFAULT_HANDLER (0xFFFF)
|
||||
/* Invalid task */
|
||||
#define KE_TASK_INVALID (0xFFFF)
|
||||
/* Used to know if a message is not present in kernel queue */
|
||||
#define KE_MSG_NOT_IN_QUEUE ((struct co_list_hdr *) 0xFFFFFFFF)
|
||||
|
||||
/// Status of ke_task API functions
|
||||
enum KE_TASK_STATUS
|
||||
{
|
||||
KE_TASK_OK = 0,
|
||||
KE_TASK_FAIL,
|
||||
KE_TASK_UNKNOWN,
|
||||
KE_TASK_CAPA_EXCEEDED,
|
||||
KE_TASK_ALREADY_EXISTS,
|
||||
};
|
||||
|
||||
|
||||
#define MSG_T(msg) ((ke_task_id_t)((msg) >> 8))
|
||||
#define MSG_I(msg) ((msg) & ((1<<8)-1))
|
||||
|
||||
/// Format of a task message handler function
|
||||
typedef int (*ke_msg_func_t)(ke_msg_id_t const msgid, void const *param,
|
||||
ke_task_id_t const dest_id, ke_task_id_t const src_id);
|
||||
|
||||
/// Macro for message handler function declaration or definition
|
||||
#define KE_MSG_HANDLER(msg_name, param_struct) int msg_name##_handler(ke_msg_id_t const msgid, \
|
||||
param_struct const *param, \
|
||||
ke_task_id_t const dest_id, \
|
||||
ke_task_id_t const src_id)
|
||||
|
||||
#define KE_MSG_HANDLER_NO_STATIC(msg_name, param_struct) int msg_name##_handler(ke_msg_id_t const msgid, \
|
||||
param_struct const *param, \
|
||||
ke_task_id_t const dest_id, \
|
||||
ke_task_id_t const src_id)
|
||||
|
||||
/// Macro for message handlers table declaration or definition
|
||||
#define KE_MSG_HANDLER_TAB(task) const struct ke_msg_handler task##_msg_handler_tab[] =
|
||||
|
||||
/// Element of a message handler table.
|
||||
struct ke_msg_handler
|
||||
{
|
||||
/// Id of the handled message.
|
||||
ke_msg_id_t id;
|
||||
/// Pointer to the handler function for the msgid above.
|
||||
ke_msg_func_t func;
|
||||
};
|
||||
|
||||
/// Task descriptor grouping all information required by the kernel for the scheduling.
|
||||
typedef struct ke_task_desc
|
||||
{
|
||||
/// Pointer to the message handler table
|
||||
const struct ke_msg_handler* msg_handler_tab;
|
||||
/// Pointer to the state table (one element for each instance).
|
||||
ke_state_t* state;
|
||||
/// Maximum index of supported instances of the task.
|
||||
uint16_t idx_max;
|
||||
/// Number of messages handled
|
||||
uint16_t msg_cnt;
|
||||
} ke_task_desc_t;
|
||||
|
||||
/*
|
||||
* FUNCTION PROTOTYPES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize Kernel task module.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_task_init(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Create a task.
|
||||
*
|
||||
* @param[in] task_type Task type.
|
||||
* @param[in] p_task_desc Pointer to task descriptor.
|
||||
*
|
||||
* @return Status
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t ke_task_create(uint8_t task_type, struct ke_task_desc const * p_task_desc);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Delete a task.
|
||||
*
|
||||
* @param[in] task_type Task type.
|
||||
*
|
||||
* @return Status
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t ke_task_delete(uint8_t task_type);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Retrieve the state of a task.
|
||||
*
|
||||
* @param[in] id Task id.
|
||||
*
|
||||
* @return Current state of the task
|
||||
****************************************************************************************
|
||||
*/
|
||||
ke_state_t ke_state_get(ke_task_id_t const id);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Set the state of the task identified by its Task Id.
|
||||
*
|
||||
* In this function we also handle the SAVE service: when a task state changes we
|
||||
* try to activate all the messages currently saved in the save queue for the given
|
||||
* task identifier.
|
||||
*
|
||||
* @param[in] id Identifier of the task instance whose state is going to be modified
|
||||
* @param[in] state_id New State
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_state_set(ke_task_id_t const id, ke_state_t const state_id);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Generic message handler to consume message without handling it in the task.
|
||||
*
|
||||
* @param[in] msgid Id of the message received (probably unused)
|
||||
* @param[in] param Pointer to the parameters of the message.
|
||||
* @param[in] dest_id TaskId of the receiving task.
|
||||
* @param[in] src_id TaskId of the sending task.
|
||||
*
|
||||
* @return KE_MSG_CONSUMED
|
||||
****************************************************************************************
|
||||
*/
|
||||
int ke_msg_discard(ke_msg_id_t const msgid, void const *param,
|
||||
ke_task_id_t const dest_id, ke_task_id_t const src_id);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Generic message handler to consume message without handling it in the task.
|
||||
*
|
||||
* @param[in] msgid Id of the message received (probably unused)
|
||||
* @param[in] param Pointer to the parameters of the message.
|
||||
* @param[in] dest_id TaskId of the receiving task.
|
||||
* @param[in] src_id TaskId of the sending task.
|
||||
*
|
||||
* @return KE_MSG_CONSUMED
|
||||
****************************************************************************************
|
||||
*/
|
||||
int ke_msg_save(ke_msg_id_t const msgid, void const *param,
|
||||
ke_task_id_t const dest_id, ke_task_id_t const src_id);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function flushes all messages, currently pending in the kernel for a
|
||||
* specific task.
|
||||
*
|
||||
* @param[in] task The Task Identifier that shall be flushed.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_task_msg_flush(ke_task_id_t task);
|
||||
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Check validity of a task. If task type or task instance does not exist,
|
||||
* return invalid task
|
||||
*
|
||||
* @param[in] task Task Identifier to check.
|
||||
*
|
||||
* @return Task identifier if valid, invalid identifier else.
|
||||
****************************************************************************************
|
||||
*/
|
||||
ke_task_id_t ke_task_check(ke_task_id_t task);
|
||||
|
||||
/// @} TASK
|
||||
|
||||
#endif // _KE_TASK_H_
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ke_timer.h
|
||||
*
|
||||
* @brief This file contains the definitions used for timer management
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _KE_TIMER_H_
|
||||
#define _KE_TIMER_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @defgroup TIMER BT Time
|
||||
* @ingroup KERNEL
|
||||
* @brief Timer management module.
|
||||
*
|
||||
* This module implements the functions used for managing kernel timers.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include "rwip.h" // RW definitions
|
||||
#include "rwip_config.h" // stack configuration
|
||||
#include "ke_msg.h" // messaging definition
|
||||
|
||||
|
||||
/*
|
||||
* DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* TYPE DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION PROTOTYPES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function flushes all timers pending in the kernel.
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_timer_flush(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Set a timer.
|
||||
*
|
||||
* The function first cancel the timer if it is already existing, then
|
||||
* it creates a new one. The timer can be one-shot or periodic, i.e. it
|
||||
* will be automatically set again after each trigger.
|
||||
*
|
||||
* When the timer expires, a message is sent to the task provided as
|
||||
* argument, with the timer id as message id.
|
||||
*
|
||||
*
|
||||
* @param[in] timer_id Timer identifier (message identifier type).
|
||||
* @param[in] task_id Task identifier which will be notified
|
||||
* @param[in] delay Delay in time milliseconds.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_timer_set(ke_msg_id_t const timer_id, ke_task_id_t const task, uint32_t delay_ms);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Remove an registered timer.
|
||||
*
|
||||
* This function search for the timer identified by its id and its task id.
|
||||
* If found it is stopped and freed, otherwise an error message is returned.
|
||||
*
|
||||
* @param[in] timer_id Timer identifier.
|
||||
* @param[in] task Task identifier.
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_timer_clear(ke_msg_id_t const timerid, ke_task_id_t const task);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Checks if a requested timer is active.
|
||||
*
|
||||
* This function pops the first timer from the timer queue and notifies the appropriate
|
||||
* task by sending a kernel message. If the timer is periodic, it is set again;
|
||||
* if it is one-shot, the timer is freed. The function checks also the next timers
|
||||
* and process them if they have expired or are about to expire.
|
||||
****************************************************************************************
|
||||
*/
|
||||
bool ke_timer_active(ke_msg_id_t const timer_id, ke_task_id_t const task_id);
|
||||
|
||||
|
||||
/// @} TIMER
|
||||
|
||||
#endif // _KE_TIMER_H_
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ke_env.h
|
||||
*
|
||||
* @brief This file contains the definition of the kernel.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _KE_ENV_H_
|
||||
#define _KE_ENV_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup ENV Environment
|
||||
* @ingroup KERNEL
|
||||
* @brief Kernel Environment
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include "rwip_config.h" // stack configuration
|
||||
#include "ke_event.h" // kernel event
|
||||
#include "co_list.h" // kernel queue definition
|
||||
|
||||
// forward declaration
|
||||
struct mblock_free;
|
||||
|
||||
/// Kernel environment definition
|
||||
struct ke_env_tag
|
||||
{
|
||||
/// Queue of sent messages but not yet delivered to receiver
|
||||
struct co_list queue_sent;
|
||||
/// Queue of messages delivered but not consumed by receiver
|
||||
struct co_list queue_saved;
|
||||
/// Queue of timers
|
||||
struct co_list queue_timer;
|
||||
/// Root pointer = pointer to first element of heap linked lists
|
||||
struct mblock_free * heap[KE_MEM_BLOCK_MAX];
|
||||
/// Size of heaps
|
||||
uint16_t heap_size[KE_MEM_BLOCK_MAX];
|
||||
|
||||
#if (KE_PROFILING)
|
||||
/// Size of heap used
|
||||
uint16_t heap_used[KE_MEM_BLOCK_MAX];
|
||||
/// Maximum heap memory used
|
||||
uint32_t max_heap_used;
|
||||
#endif //KE_PROFILING
|
||||
};
|
||||
|
||||
/// Kernel environment
|
||||
extern struct ke_env_tag ke_env;
|
||||
|
||||
/// @} ENV
|
||||
|
||||
#endif // _KE_ENV_H_
|
||||
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file ke_queue.h
|
||||
*
|
||||
* @brief This file contains the definition of the message object, queue element
|
||||
* object and queue object
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _KE_QUEUE_H_
|
||||
#define _KE_QUEUE_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup QUEUE Queues and Lists
|
||||
* @ingroup KERNEL
|
||||
* @brief Queue management module
|
||||
*
|
||||
* This module implements the functions used for managing message queues.
|
||||
* These functions must not be called under IRQ!
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include <stdint.h> // standard integer
|
||||
#include <stdbool.h> // standard boolean
|
||||
#include "compiler.h" // compiler definitions
|
||||
#include "co_list.h" // list definition
|
||||
|
||||
/*
|
||||
* FUNCTION PROTOTYPES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Pop entry to the queue
|
||||
*
|
||||
* @param[in] queue Pointer to the queue.
|
||||
* @param[in] element Pointer to the element.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE void ke_queue_push(struct co_list *const queue, struct co_list_hdr *const element)
|
||||
{
|
||||
co_list_push_back(queue, element);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Pop entry from the queue
|
||||
*
|
||||
* @param[in] queue Pointer to the queue.
|
||||
*
|
||||
* @return Pointer to the element.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__INLINE struct co_list_hdr *ke_queue_pop(struct co_list *const queue)
|
||||
{
|
||||
return co_list_pop_front(queue);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Extracts an element matching a given algorithm.
|
||||
*
|
||||
* @param[in] queue Pointer to the queue.
|
||||
* @param[in] func Matching function.
|
||||
* @param[in] arg Match argument.
|
||||
*
|
||||
* @return Pointer to the element found and removed (NULL otherwise).
|
||||
****************************************************************************************
|
||||
*/
|
||||
struct co_list_hdr *ke_queue_extract(struct co_list * const queue,
|
||||
bool (*func)(struct co_list_hdr const * elmt, uint32_t arg),
|
||||
uint32_t arg);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Insert an element in a sorted queue.
|
||||
*
|
||||
* This primitive use a comparison function from the parameter list to select where the
|
||||
* element must be inserted.
|
||||
*
|
||||
* @param[in] queue Pointer to the queue.
|
||||
* @param[in] element Pointer to the element to insert.
|
||||
* @param[in] cmp Comparison function (return true if first element has to be inserted
|
||||
* before the second one).
|
||||
*
|
||||
* @return Pointer to the element found and removed (NULL otherwise).
|
||||
****************************************************************************************
|
||||
*/
|
||||
void ke_queue_insert(struct co_list * const queue, struct co_list_hdr * const element,
|
||||
bool (*cmp)(struct co_list_hdr const *elementA,
|
||||
struct co_list_hdr const *elementB));
|
||||
|
||||
/// @} QUEUE
|
||||
|
||||
#endif // _KE_QUEUE_H_
|
||||
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file nvds.h
|
||||
*
|
||||
* @brief Non Volatile Data Storage (NVDS) driver
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
#ifndef _NVDS_H_
|
||||
#define _NVDS_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup NVDS
|
||||
* @ingroup COMMON
|
||||
* @brief Non Volatile Data Storage (NVDS)
|
||||
*
|
||||
* Parameters management
|
||||
* there are two compilation options:
|
||||
* + NVDS_8BIT_TAGLENGTH :
|
||||
* if set, each TAG has a maximum length of 256 bytes
|
||||
* if not set, each TAG has a maximum length of 65536 bytes
|
||||
* + NVDS_PACKED :
|
||||
* if not set, all the TAG header structures and TAG data contents are stored with an
|
||||
* alignment on 32 bit boundary
|
||||
* if set, all the TAG header structures and TAG data contents are stored
|
||||
* consecutively without gaps (as would be a structure with pragma packed)
|
||||
* + NVDS_READ_WRITE :
|
||||
* if not set, only GET action on TAGs is provided.
|
||||
* if set, PUT/DEL/LOCK actions are provided in addition of GET action.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include <stdbool.h> // boolean definition
|
||||
#include <stdint.h> // integer definition
|
||||
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// NVDS is defined as read-write
|
||||
#define NVDS_READ_WRITE 1
|
||||
|
||||
/// NVDS is defined as packed
|
||||
#define NVDS_PACKED 1
|
||||
|
||||
/// NVDS has 8-bit length tags
|
||||
#define NVDS_8BIT_TAGLENGTH 1
|
||||
|
||||
#define FLASH_BASE (252*1024)
|
||||
#define FLASH_SECTOR_SIZE (4*1024)
|
||||
|
||||
/// Type of the tag length (8 or 16 bits)
|
||||
#if (NVDS_8BIT_TAGLENGTH)
|
||||
typedef uint8_t nvds_tag_len_t;
|
||||
#else
|
||||
typedef uint16_t nvds_tag_len_t;
|
||||
#endif // NVDS_8BIT_TAGLENGTH
|
||||
|
||||
|
||||
/*
|
||||
* ENUMERATION DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Possible Returned Status
|
||||
enum NVDS_STATUS
|
||||
{
|
||||
/// NVDS status OK
|
||||
NVDS_OK,
|
||||
/// generic NVDS status KO
|
||||
NVDS_FAIL,
|
||||
/// NVDS TAG unrecognized
|
||||
NVDS_TAG_NOT_DEFINED,
|
||||
/// No space for NVDS
|
||||
NVDS_NO_SPACE_AVAILABLE,
|
||||
/// Length violation
|
||||
NVDS_LENGTH_OUT_OF_RANGE,
|
||||
/// NVDS parameter locked
|
||||
NVDS_PARAM_LOCKED,
|
||||
/// NVDS corrupted
|
||||
NVDS_CORRUPT
|
||||
};
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* used init nvds flash base addr
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t nvds_space_init(uint32_t flash_size);
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize NVDS.
|
||||
* @return NVDS_OK
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t nvds_init(uint32_t len);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Look for a specific tag and return, if found and matching (in length), the
|
||||
* DATA part of the TAG.
|
||||
*
|
||||
* If the length does not match, the TAG header structure is still filled, in order for
|
||||
* the caller to be able to check the actual length of the TAG.
|
||||
*
|
||||
* @param[in] tag TAG to look for whose DATA is to be retrieved
|
||||
* @param[in] length Expected length of the TAG
|
||||
* @param[out] buf A pointer to the buffer allocated by the caller to be filled with
|
||||
* the DATA part of the TAG
|
||||
*
|
||||
* @return NVDS_OK The read operation was performed
|
||||
* NVDS_LENGTH_OUT_OF_RANGE The length passed in parameter is different than the TAG's
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t nvds_get(uint8_t tag, nvds_tag_len_t * lengthPtr, uint8_t *buf);
|
||||
|
||||
#if (NVDS_READ_WRITE == 1)
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Look for a specific tag and delete it (Status set to invalid)
|
||||
*
|
||||
* Implementation notes
|
||||
* 1. The write function call return status is not handled
|
||||
*
|
||||
* @param[in] tag TAG to mark as deleted
|
||||
*
|
||||
* @return NVDS_OK TAG found and deleted
|
||||
* NVDS_PARAM_LOCKED TAG found but can not be deleted because it is locked
|
||||
* (others) return values from function call @ref nvds_browse_tag
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t nvds_del(uint8_t tag);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Look for a specific tag and lock it (Status lock bit set to LOCK).
|
||||
*
|
||||
* The write function call return status is not handled
|
||||
*
|
||||
* @param[in] tag TAG to mark as locked
|
||||
*
|
||||
* @return NVDS_OK TAG found and locked
|
||||
* (others) return values from function call @ref nvds_browse_tag
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t nvds_lock(uint8_t tag);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief This function adds a specific TAG to the NVDS.
|
||||
*
|
||||
* Steps:
|
||||
* 1) parse all the TAGs to:
|
||||
* 1.1) calculate the total size of all the valid TAGs
|
||||
* 1.2) erase the existing TAGs that have the same ID
|
||||
* 1.3) check if we can use the same TAG area in case of an EEPROM
|
||||
* 1.4) check that the TAG is not locked
|
||||
* 2) if we have to add the new TAG at the end fo the NVDS (cant use same area):
|
||||
* 2.1) allocate the appropriate amount of memory
|
||||
* 2.2) purge the NVDS
|
||||
* 2.3) free the memory allocated
|
||||
* 2.4) check that there is now enough room for the new TAG or return
|
||||
* NO_SPACE_AVAILABLE
|
||||
* 3) add the new TAG
|
||||
*
|
||||
* @param[in] tag TAG to look for whose DATA is to be retrieved
|
||||
* @param[in] length Expected length of the TAG
|
||||
* @param[in] buf Pointer to the buffer containing the DATA part of the TAG to add to
|
||||
* the NVDS
|
||||
*
|
||||
* @return NVDS_OK New TAG correctly written to the NVDS
|
||||
* NVDS_PARAM_LOCKED New TAG is trying to overwrite a TAG that is locked
|
||||
* NO_SPACE_AVAILABLE New TAG can not fit in the available space in the NVDS
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t nvds_put(uint8_t tag, nvds_tag_len_t length, uint8_t *buf);
|
||||
|
||||
#endif //(NVDS_READ_WRITE == 1)
|
||||
|
||||
/// @} NVDS
|
||||
|
||||
#endif // _NVDS_H_
|
||||
@@ -0,0 +1,941 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file nvds.c
|
||||
*
|
||||
* @brief Non Volatile Data Storage (NVDS) driver
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup NVDS
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include "rwip_config.h" // RW SW configuration
|
||||
#if (NVDS_SUPPORT)
|
||||
|
||||
#include "arch.h" // main
|
||||
#include "co_math.h" // math operations
|
||||
#include "nvds.h" // nvds definitions
|
||||
#include <limits.h> // limits definitions
|
||||
#include <stddef.h> // standard definitions
|
||||
#include <string.h> // string definitions
|
||||
#if (USE_ROM_FLASH)
|
||||
#include "xc6xxx_fmc_spi.h"
|
||||
#endif // (USE_ROM_FLASH)
|
||||
|
||||
#define NVDS_RAM_SUPPORT defined(CFG_GAIA)
|
||||
#if (NVDS_RAM_SUPPORT)
|
||||
#include "mailbox.h"
|
||||
#endif // NVDS_RAM_SUPPORT
|
||||
#include "dbg.h"
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// NVDS parameter data maximum length
|
||||
#if NVDS_8BIT_TAGLENGTH
|
||||
#define NVDS_PARAMETER_MAX_LENGTH UCHAR_MAX
|
||||
#else // NVDS_8BIT_TAGLENGTH
|
||||
#define NVDS_PARAMETER_MAX_LENGTH USHRT_MAX
|
||||
#endif // NVDS_8BIT_TAGLENGTH
|
||||
|
||||
/// TAG STATUS bit assignment
|
||||
#define NVDS_STATUS_VALID_MASK 0x01
|
||||
#define NVDS_STATUS_VALID 0x00
|
||||
#define NVDS_STATUS_NOT_VALID 0x01
|
||||
#define NVDS_STATUS_LOCKED_MASK 0x02
|
||||
#define NVDS_STATUS_LOCKED 0x00
|
||||
#define NVDS_STATUS_NOT_LOCKED 0x02
|
||||
#define NVDS_STATUS_ERASED_MASK 0x04
|
||||
#define NVDS_STATUS_ERASED 0x00
|
||||
#define NVDS_STATUS_NOT_ERASED 0x04
|
||||
|
||||
#if (NVDS_READ_WRITE == 1)
|
||||
/// Max storage for the NVDS device which can be used for tags
|
||||
#define NVDS_MAX_STORAGE_SIZE 0x0800 // 2KB
|
||||
#endif //(NVDS_READ_WRITE == 1)
|
||||
|
||||
// NVDS Mapping
|
||||
|
||||
/// Magic number offset
|
||||
#define NVDS_MAGIC_NUMBER_ADDRESS 0x0000
|
||||
/// Size of magic number
|
||||
#define NVDS_MAGIC_NUMBER_LENGTH 4
|
||||
|
||||
/// Start of NVDS data
|
||||
#if (NVDS_PACKED == 1)
|
||||
#define NVDS_START_STORAGE_AREA_ADDRESS \
|
||||
NVDS_MAGIC_NUMBER_ADDRESS + NVDS_MAGIC_NUMBER_LENGTH
|
||||
#else //(NVDS_PACKED == 0)
|
||||
#define NVDS_START_STORAGE_AREA_ADDRESS \
|
||||
CO_ALIGN4_HI(NVDS_MAGIC_NUMBER_ADDRESS) + \
|
||||
CO_ALIGN4_HI(NVDS_MAGIC_NUMBER_LENGTH)
|
||||
#endif //(NVDS_PACKED == 1)
|
||||
|
||||
/// Value found in flash when nothing has been written
|
||||
#define NVDS_NO_TAG 0xFF
|
||||
|
||||
/*
|
||||
* MACROS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Check is tag is the last one
|
||||
#define NVDS_IS_TAG_LAST(h) ((h).tag == NVDS_NO_TAG)
|
||||
/// Check is tag is valid
|
||||
#define NVDS_IS_TAG_OK(h) \
|
||||
((((h).status) & (NVDS_STATUS_VALID_MASK | NVDS_STATUS_ERASED_MASK)) == \
|
||||
(NVDS_STATUS_VALID | NVDS_STATUS_NOT_ERASED))
|
||||
/// Check is tag is locked
|
||||
#define NVDS_IS_TAG_LOCKED(h) \
|
||||
((((h).status) & NVDS_STATUS_LOCKED_MASK) == NVDS_STATUS_LOCKED)
|
||||
/// Set tag as erased
|
||||
#define NVDS_SET_TAG_ERASED(h) \
|
||||
((((h).status) & (~NVDS_STATUS_ERASED_MASK)) | NVDS_STATUS_ERASED)
|
||||
/// Set tag as locked
|
||||
#define NVDS_SET_TAG_LOCKED(h) \
|
||||
((((h).status) & (~NVDS_STATUS_LOCKED_MASK)) | NVDS_STATUS_LOCKED)
|
||||
/// Set tag as valid
|
||||
#define NVDS_SET_TAG_OK(h) \
|
||||
(NVDS_STATUS_VALID | NVDS_STATUS_NOT_LOCKED | NVDS_STATUS_NOT_ERASED)
|
||||
|
||||
/// Macro for alignment
|
||||
#if (NVDS_PACKED == 1)
|
||||
#define NVDS_ALIGNMENT(p) (p)
|
||||
#else //(NVDS_PACKED == 0)
|
||||
#define NVDS_ALIGNMENT(p) CO_ALIGN4_HI(p)
|
||||
#endif //(NVDS_PACKED == 1)
|
||||
|
||||
/// Length of tag header
|
||||
#define NVDS_TAG_HEADER_LENGTH NVDS_ALIGNMENT(sizeof(struct nvds_tag_header))
|
||||
/// Length of tag data
|
||||
#define NVDS_TAG_CONTENT_LENGTH(h) NVDS_ALIGNMENT((h).length)
|
||||
/// Full length of tag (header+data)
|
||||
#define NVDS_TAG_FULL_LENGTH(h) \
|
||||
NVDS_TAG_HEADER_LENGTH + NVDS_TAG_CONTENT_LENGTH(h)
|
||||
|
||||
/*
|
||||
* STRUCT DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// Structure defining the header of a TAG. It is very important that the TAG
|
||||
/// remains the first element of the structure because it defines the LAST TAG
|
||||
/// of the NVDS when set the oxFF.
|
||||
struct nvds_tag_header
|
||||
{
|
||||
/// current TAG identifier
|
||||
uint8_t tag;
|
||||
/// status of the TAG (erased, locked ...)
|
||||
uint8_t status;
|
||||
/// length of the TAG
|
||||
nvds_tag_len_t length;
|
||||
};
|
||||
|
||||
/// Environment structure of the NVDS module
|
||||
struct nvds_env_tag
|
||||
{
|
||||
/// Function to read the device Address being in the NVDS memory space
|
||||
void (*read)(uint32_t const address, uint32_t const length,
|
||||
uint8_t *const buf);
|
||||
/// Function to write the device Address being in the NVDS memory space
|
||||
void (*write)(uint32_t const address, uint32_t const length,
|
||||
uint8_t *const buf);
|
||||
/// Function to erase the entire NVDS memory space
|
||||
void (*erase)(uint32_t const address, uint32_t const length);
|
||||
|
||||
/// NVDS base pointer
|
||||
uint8_t *nvds_space;
|
||||
|
||||
/// Total size of the NVDS area
|
||||
uint32_t total_size;
|
||||
|
||||
/// Flash ID
|
||||
uint8_t flash_id;
|
||||
};
|
||||
|
||||
/*
|
||||
* GLOBAL VARIABLE DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#if (NVDS_READ_WRITE == 1)
|
||||
/// temporary buffer used for purging
|
||||
__STATIC uint8_t *nvds_temp_buf;
|
||||
#endif //(NVDS_READ_WRITE == 1)
|
||||
|
||||
/// NVDS magic number keyword
|
||||
// __STATIC const uint8_t nvds_magic_number[NVDS_MAGIC_NUMBER_LENGTH] = {'N',
|
||||
// 'V', 'D', 'S'};
|
||||
__STATIC const uint8_t nvds_magic_number[NVDS_MAGIC_NUMBER_LENGTH] = {'N', 'V',
|
||||
'D', 'S'};
|
||||
|
||||
/// NVDS environment
|
||||
__STATIC struct nvds_env_tag nvds_env;
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DECLARATION
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Check if the current NVDS has the correct magic number set.
|
||||
*
|
||||
* Implementation notes:we do not put an assert on the read access because we
|
||||
*could be in the situation of a dummy read (returns always NVDS_FAIL) and we
|
||||
*want to return correctly the FALSE.
|
||||
*
|
||||
* @return True if the NVDS has the Magic Number set, false otherwise.
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC bool nvds_is_magic_number_ok(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Look for a specific TAG.
|
||||
*
|
||||
* If found, it returns the address and the header, otherwise the TAG address
|
||||
*returned points to a location where it is possible to store a new TAG. The TAG
|
||||
*is returned only if it is valid (not erased). This function is useful to find
|
||||
* a single valid TAG element or find the next available space for a new TAG.
|
||||
*
|
||||
* @param[in] tag TAG to look for
|
||||
* @param[out] nvds_tag_header_ptr Pointer to the TAG header structure allocated
|
||||
*by the caller to contain the searched TAG header
|
||||
* @param[out] tag_address_ptr Pointer to the NVDS address at which TAG was
|
||||
*found (returned) or if the TAG was not found, first address free for storing
|
||||
*new TAG in NVDS
|
||||
*
|
||||
* @return Return codes from the @ref nvds_walk_tag function call
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC uint8_t nvds_browse_tag(uint8_t tag,
|
||||
struct nvds_tag_header *nvds_tag_header_ptr,
|
||||
uint32_t *tag_address_ptr);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Read the TAG header that MUST be present at NVDS address cur_tag_addr
|
||||
*and fill the TAG header structure that is allocated by the caller and
|
||||
*referenced by nvds_tag_header_ptr.
|
||||
*
|
||||
* Upon completion of the read, the next TAG address is computed and returned to
|
||||
*the caller through nxt_tag_addr_ptr (except if the current TAG is the LAST
|
||||
*one). If the caller wishes to read the first TAG of the NVDS, the value
|
||||
* NVDS_START_STORAGE_AREA_ADDRESS can be used as the cur_tag_addr.
|
||||
* If the current Address specified is pointing at the position of the last
|
||||
*element of the NVDS the function returns NVDS_TAG_NOT_DEFINED. In this case,
|
||||
*there is NO VALUE returned through nxt_tag_addr_ptr. The cur_tag_addr is
|
||||
*already pointing to an empty TAG. The TAG read is not check for validity, this
|
||||
*information should be handled by the caller if he wishes to use the TAG
|
||||
*information correctly.
|
||||
*
|
||||
* @param[in] cur_tag_addr Address of the current TAG in NVDS memory
|
||||
*space
|
||||
* @param[out] nvds_tag_header_ptr A pointer to an allocated space for the
|
||||
*parameter header
|
||||
* @param[out] nxt_tag_addr_ptr A pointer to the next TAG address in the NVDS
|
||||
*memory space
|
||||
*
|
||||
* @return NVDS_OK TAG read, header filled and next TAG address
|
||||
*filled NVDS_TAG_NOT_DEFINED Last TAG reached, header filled with garbage
|
||||
* NVDS_CORRUPT Current TAG is overcoming the NVDS size
|
||||
*limit
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC uint8_t nvds_walk_tag(uint32_t cur_tag_addr,
|
||||
struct nvds_tag_header *nvds_tag_header_ptr,
|
||||
uint32_t *nxt_tag_addr_ptr);
|
||||
|
||||
#if (NVDS_RAM_SUPPORT)
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Hook a RAM driver to the NVDS.
|
||||
* If NVDS media is stored in RAM,
|
||||
*
|
||||
* @return NVDS_OK
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC uint8_t nvds_ram_init(uint8_t *base, uint32_t len);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief RAM Read function
|
||||
*
|
||||
* @param[in] address Start address of the data to read from NVDS
|
||||
* @param[in] length Length of the data to read from NVDS
|
||||
* @param[in] buf Pointer to the buffer containing the DATA to read from
|
||||
*the NVDS
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC void nvds_ram_read(uint32_t address, uint32_t length, uint8_t *buf);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief RAM Write function
|
||||
*
|
||||
* @param[in] address NVDS address at which the write operation must be
|
||||
*performed
|
||||
* @param[in] length Length of the write operation to perform
|
||||
* @param[in] buf Pointer to a buffer containing the data to write
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC void nvds_ram_write(uint32_t address, uint32_t length, uint8_t *buf);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief RAM Erase function
|
||||
* @param[in] address NVDS address at which the erase operation must be
|
||||
*performed
|
||||
* @param[in] length Length of the erase operation to perform
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC void nvds_ram_erase(uint32_t address, uint32_t length);
|
||||
|
||||
#else // !(NVDS_RAM_SUPPORT)
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Hook a dummy driver to the NVDS.
|
||||
* If no valid NVDS media was found, to avoid incorrect behavior a dummy driver
|
||||
*should be hooked to the NVDS.
|
||||
*
|
||||
* @return NVDS_OK
|
||||
****************************************************************************************
|
||||
*/
|
||||
#if (NVDS_READ_WRITE == 0)
|
||||
__STATIC uint8_t nvds_null_init(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Dummy function to safely replace Read function
|
||||
*
|
||||
* @param[in] address Start address of the data to read from NVDS
|
||||
* @param[in] length Length of the data to read from NVDS
|
||||
* @param[in] buf Pointer to the buffer containing the DATA to read from
|
||||
*the NVDS
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC void nvds_null_read(uint32_t address, uint32_t length, uint8_t *buf);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Dummy function to safely replace Write function
|
||||
*
|
||||
* @param[in] address NVDS address at which the write operation must be
|
||||
*performed
|
||||
* @param[in] length Length of the write operation to perform
|
||||
* @param[in] buf Pointer to a buffer containing the data to write
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC void nvds_null_write(uint32_t address, uint32_t length, uint8_t *buf);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Dummy function to safely replace Erase function
|
||||
* @param[in] address NVDS address at which the erase operation must be
|
||||
*performed
|
||||
* @param[in] length Length of the erase operation to perform
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC void nvds_null_erase(uint32_t address, uint32_t length);
|
||||
#endif // (NVDS_READ_WRITE == 0)
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Read data from NVDS.
|
||||
*
|
||||
* @param[in] address Start address of the data to read from NVDS
|
||||
* @param[in] length Length of the data to read from NVDS
|
||||
* @param[in] buf Pointer to the buffer containing the DATA to read from
|
||||
*the NVDS
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC void nvds_read(uint32_t address, uint32_t length, uint8_t *buf);
|
||||
|
||||
#if (NVDS_READ_WRITE == 1)
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Write data into NVDS
|
||||
*
|
||||
* @param[in] address Start address of the data to write to NVDS
|
||||
* @param[in] length Length of the data to write to NVDS
|
||||
* @param[in] buf Pointer to the buffer containing the DATA to write to
|
||||
*the NVDS
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC void nvds_write(uint32_t address, uint32_t length, uint8_t *buf);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Erase data in NVDS
|
||||
*
|
||||
* @param[in] address Start address of the data to read from NVDS
|
||||
* @param[in] length Length of the data to read from NVDS
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC void nvds_erase(uint32_t address, uint32_t length);
|
||||
#endif // (NVDS_READ_WRITE == 1)
|
||||
|
||||
#endif //!(NVDS_RAM_SUPPORT)
|
||||
|
||||
#if (NVDS_READ_WRITE == 1)
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Initialize the NVDS memory.
|
||||
*
|
||||
* This function clears the entire memory content and writes the MagicNumber
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC void nvds_init_memory(void);
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Purge NVDS memory
|
||||
*
|
||||
* This function performs a read of all the valid TAGs of the NVDS, stores them
|
||||
*in the temporary buffer allocated by the caller, flushes the NVDS and then
|
||||
*rewrites all the valid TAGs.
|
||||
*
|
||||
* It is used to purge the NVDS when there is no more space to store a new TAG
|
||||
*for example or regularly to save TAG browse time.
|
||||
*
|
||||
* @param[in] length Length of the buffer allocated to perform the temporary
|
||||
*storage of the NVDS while purging (erase and compress)
|
||||
* @param[in] buf A pointer to the buffer allocated by the caller for the
|
||||
*temporary storage of the NVDS while purging
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC void nvds_purge(uint32_t length, uint8_t *buf);
|
||||
#endif //(NVDS_READ_WRITE == 1)
|
||||
|
||||
/*
|
||||
* LOCAL FUNCTION DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
//extern uint8_t *get_fota_env_addr(uint16_t len);
|
||||
|
||||
__STATIC bool nvds_is_magic_number_ok(void)
|
||||
{
|
||||
bool is_magic_number_ok = false;
|
||||
uint8_t read_magic_number[NVDS_MAGIC_NUMBER_LENGTH];
|
||||
|
||||
// Look for the magic number
|
||||
nvds_env.read(NVDS_MAGIC_NUMBER_ADDRESS, sizeof(read_magic_number),
|
||||
read_magic_number);
|
||||
|
||||
// Compare the read magic number with the correct value
|
||||
if (memcmp(read_magic_number, nvds_magic_number,
|
||||
NVDS_MAGIC_NUMBER_LENGTH) == 0) {
|
||||
is_magic_number_ok = true;
|
||||
}
|
||||
return is_magic_number_ok;
|
||||
}
|
||||
|
||||
__STATIC uint8_t nvds_walk_tag(uint32_t cur_tag_addr,
|
||||
struct nvds_tag_header *nvds_tag_header_ptr,
|
||||
uint32_t *nxt_tag_addr_ptr)
|
||||
{
|
||||
uint8_t status = NVDS_OK;
|
||||
|
||||
// Read the current parameter header
|
||||
nvds_env.read((uint32_t)cur_tag_addr,
|
||||
(uint32_t)sizeof(struct nvds_tag_header),
|
||||
(uint8_t *)nvds_tag_header_ptr);
|
||||
|
||||
// Check if the read operation completed successfully
|
||||
if (!NVDS_IS_TAG_LAST(*nvds_tag_header_ptr)) {
|
||||
// Calculate the address of the next tag
|
||||
*nxt_tag_addr_ptr =
|
||||
cur_tag_addr + NVDS_TAG_FULL_LENGTH(*nvds_tag_header_ptr);
|
||||
|
||||
// Check if there is enough space to read next header
|
||||
// the limit is set minus 1 because we need to leave at least an end
|
||||
// marker
|
||||
if (*nxt_tag_addr_ptr > (nvds_env.total_size - 1)) {
|
||||
// Going above NVDS limit, probably an error occurred
|
||||
ASSERT_ERR(0);
|
||||
status = NVDS_CORRUPT;
|
||||
}
|
||||
} else {
|
||||
// this is beyond the last TAG
|
||||
status = NVDS_TAG_NOT_DEFINED;
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
__STATIC uint8_t nvds_browse_tag(uint8_t tag,
|
||||
struct nvds_tag_header *nvds_tag_header_ptr,
|
||||
uint32_t *tag_address_ptr)
|
||||
{
|
||||
uint8_t status;
|
||||
uint32_t cur_tag_addr, nxt_tag_addr;
|
||||
|
||||
// set the address to the first data byte of the NVDS
|
||||
nxt_tag_addr = NVDS_START_STORAGE_AREA_ADDRESS;
|
||||
|
||||
do {
|
||||
// go to the next tag
|
||||
cur_tag_addr = nxt_tag_addr;
|
||||
|
||||
// retrieve the parameter header
|
||||
status =
|
||||
nvds_walk_tag(cur_tag_addr, nvds_tag_header_ptr, &nxt_tag_addr);
|
||||
|
||||
} while ((status == NVDS_OK) && !((nvds_tag_header_ptr->tag == tag) &&
|
||||
NVDS_IS_TAG_OK(*nvds_tag_header_ptr)));
|
||||
|
||||
// the returned address is the last address found
|
||||
*tag_address_ptr = cur_tag_addr;
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
#if (NVDS_RAM_SUPPORT)
|
||||
__STATIC void nvds_ram_read(uint32_t address, uint32_t length, uint8_t *buf)
|
||||
{
|
||||
// Test the validity of address + length
|
||||
ASSERT_ERR(((address + length) <= nvds_env.total_size));
|
||||
|
||||
// Read the RAM memory
|
||||
memcpy(buf, (void *)(nvds_env.nvds_space + address), length);
|
||||
}
|
||||
|
||||
#if (NVDS_READ_WRITE == 1)
|
||||
__STATIC void nvds_ram_write(uint32_t address, uint32_t length, uint8_t *buf)
|
||||
{
|
||||
// Test the validity of address + length
|
||||
ASSERT_ERR(((address + length) <= nvds_env.total_size));
|
||||
|
||||
// Write the RAM memory
|
||||
memcpy((void *)(nvds_env.nvds_space + address), buf, length);
|
||||
}
|
||||
|
||||
__STATIC void nvds_ram_erase(uint32_t address, uint32_t length)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
uint32_t incr;
|
||||
|
||||
// Write 0 the RAM memory
|
||||
buf[0] = 255;
|
||||
buf[1] = 255;
|
||||
buf[2] = 255;
|
||||
buf[3] = 255;
|
||||
|
||||
for (incr = 0; incr < length; incr = incr + 4) {
|
||||
memcpy((void *)nvds_env.nvds_space + address + incr, buf, 4);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
__STATIC uint8_t nvds_ram_init(uint8_t *base, uint32_t len)
|
||||
{
|
||||
uint8_t status = NVDS_OK;
|
||||
|
||||
// Initialize the pointer to the NVDS
|
||||
nvds_env.nvds_space = base;
|
||||
|
||||
// initialize the access functions
|
||||
nvds_env.read = &nvds_ram_read;
|
||||
|
||||
#if (NVDS_READ_WRITE == 1)
|
||||
nvds_env.write = &nvds_ram_write;
|
||||
nvds_env.erase = &nvds_ram_erase;
|
||||
#else //(NVDS_READ_WRITE == 0)
|
||||
nvds_env.write = &nvds_null_write;
|
||||
nvds_env.erase = &nvds_null_erase;
|
||||
#endif //(NVDS_READ_WRITE == 1)
|
||||
|
||||
nvds_env.total_size = len;
|
||||
|
||||
// Check if NVDS is correctly initialized
|
||||
if (!nvds_is_magic_number_ok()) {
|
||||
#if (NVDS_READ_WRITE == 1)
|
||||
// Initialize the memory
|
||||
nvds_init_memory();
|
||||
#else //(NVDS_READ_WRITE == 0)
|
||||
// No NVDS, so select the NULL NVDS
|
||||
nvds_null_init();
|
||||
// Return bad status
|
||||
status = NVDS_FAIL;
|
||||
#endif //(NVDS_READ_WRITE == 1)
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
#else // !(NVDS_RAM_SUPPORT)
|
||||
|
||||
#if (NVDS_READ_WRITE == 0)
|
||||
__STATIC void nvds_null_read(uint32_t address, uint32_t length, uint8_t *buf) {}
|
||||
|
||||
__STATIC void nvds_null_write(uint32_t address, uint32_t length, uint8_t *buf)
|
||||
{
|
||||
}
|
||||
|
||||
__STATIC void nvds_null_erase(uint32_t address, uint32_t length) {}
|
||||
|
||||
__STATIC uint8_t nvds_null_init(void)
|
||||
{
|
||||
// init all the structure
|
||||
memset(&nvds_env, 0, sizeof(nvds_env));
|
||||
nvds_env.read = nvds_null_read;
|
||||
nvds_env.write = nvds_null_write;
|
||||
nvds_env.erase = nvds_null_erase;
|
||||
|
||||
return NVDS_OK;
|
||||
}
|
||||
#endif // (NVDS_READ_WRITE == 0)
|
||||
|
||||
__STATIC void nvds_read(uint32_t address, uint32_t length, uint8_t *buf)
|
||||
{
|
||||
// Test the validity of address + length
|
||||
ASSERT_ERR(((address + length) <= nvds_env.total_size));
|
||||
|
||||
// Read the memory
|
||||
#if (USE_XIP)
|
||||
GLOBAL_INT_DISABLE();
|
||||
FMC_SPI_FlashRead((uint32_t)nvds_env.nvds_space + address, buf, length);
|
||||
GLOBAL_INT_RESTORE();
|
||||
#endif // (USE_XIP)
|
||||
// rom_env.stack_printf("nvds_read address=%x length=%x\n", address,
|
||||
// length); DUMP_DATA_PRINTF(buf, length);
|
||||
}
|
||||
|
||||
#if (NVDS_READ_WRITE == 1)
|
||||
__STATIC void nvds_write(uint32_t address, uint32_t length, uint8_t *buf)
|
||||
{
|
||||
// Test the validity of address + length
|
||||
ASSERT_ERR(((address + length) <= nvds_env.total_size));
|
||||
|
||||
// Read the memory
|
||||
#if (USE_XIP)
|
||||
GLOBAL_INT_DISABLE();
|
||||
FMC_SPI_FlashWrite((uint32_t)nvds_env.nvds_space + address, buf, length);
|
||||
GLOBAL_INT_RESTORE();
|
||||
#endif // (USE_XIP)
|
||||
// rom_env.stack_printf("nvds_write address=%x length=%x\n", address,
|
||||
// length); DUMP_DATA_PRINTF(buf, length);
|
||||
}
|
||||
|
||||
__STATIC void nvds_erase(uint32_t address, uint32_t length)
|
||||
{
|
||||
|
||||
uint8_t sector_cnt = length / FLASH_SECTOR_SIZE;
|
||||
uint32_t erase_base = (uint32_t)nvds_env.nvds_space + address;
|
||||
uint32_t erase_address = 0;
|
||||
if (length % FLASH_SECTOR_SIZE) {
|
||||
sector_cnt = sector_cnt + 1;
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < sector_cnt; i++) {
|
||||
// flash_erase(nvds_env.flash_id, (uint32_t)nvds_env.nvds_space +
|
||||
// address, length, NULL);
|
||||
erase_address = erase_base + i * FLASH_SECTOR_SIZE;
|
||||
#if (USE_XIP)
|
||||
GLOBAL_INT_DISABLE();
|
||||
FMC_SPI_Flash_Erase_Sector(erase_address);
|
||||
GLOBAL_INT_RESTORE();
|
||||
#endif // (USE_XIP)
|
||||
}
|
||||
}
|
||||
#endif // (NVDS_READ_WRITE == 1)
|
||||
|
||||
#endif // !(NVDS_RAM_SUPPORT)
|
||||
|
||||
#if (NVDS_READ_WRITE == 1)
|
||||
__STATIC void nvds_init_memory(void)
|
||||
{
|
||||
// clear the device
|
||||
nvds_env.erase((uint32_t)NVDS_MAGIC_NUMBER_ADDRESS, nvds_env.total_size);
|
||||
|
||||
// Write the magic number at address 0
|
||||
nvds_env.write((uint32_t)NVDS_MAGIC_NUMBER_ADDRESS,
|
||||
(uint32_t)NVDS_MAGIC_NUMBER_LENGTH,
|
||||
(uint8_t *)nvds_magic_number);
|
||||
}
|
||||
|
||||
__STATIC void nvds_purge(uint32_t length, uint8_t *buf)
|
||||
{
|
||||
uint8_t status;
|
||||
struct nvds_tag_header tag_hdr;
|
||||
uint32_t nxt_tag_addr;
|
||||
uint32_t total_length;
|
||||
uint8_t *walk_ptr;
|
||||
|
||||
// store all the valid TAG elements in the locally allocated buffer
|
||||
total_length = 0;
|
||||
nxt_tag_addr = NVDS_START_STORAGE_AREA_ADDRESS;
|
||||
walk_ptr = buf;
|
||||
do {
|
||||
// go to the next tag
|
||||
uint32_t cur_tag_addr = nxt_tag_addr;
|
||||
|
||||
status = nvds_walk_tag(cur_tag_addr, (struct nvds_tag_header *)&tag_hdr,
|
||||
&nxt_tag_addr);
|
||||
|
||||
if ((status == NVDS_OK) && NVDS_IS_TAG_OK(tag_hdr)) {
|
||||
// check that the current size is not overcoming the buffer
|
||||
total_length += NVDS_TAG_FULL_LENGTH(tag_hdr);
|
||||
ASSERT_ERR(total_length <= length);
|
||||
|
||||
// copy the header content
|
||||
*((struct nvds_tag_header *)walk_ptr) = tag_hdr;
|
||||
|
||||
// increment the pointer to the data part
|
||||
walk_ptr += NVDS_TAG_HEADER_LENGTH;
|
||||
cur_tag_addr += NVDS_TAG_HEADER_LENGTH;
|
||||
|
||||
// retrieve all the data part
|
||||
nvds_env.read((uint32_t)cur_tag_addr, (uint32_t)tag_hdr.length,
|
||||
walk_ptr);
|
||||
|
||||
// increment the walking pointer
|
||||
walk_ptr += NVDS_TAG_CONTENT_LENGTH(tag_hdr);
|
||||
}
|
||||
|
||||
} while (status == NVDS_OK);
|
||||
|
||||
// reinitialize the flash
|
||||
nvds_init_memory();
|
||||
|
||||
// rewrite the NVDS once cleaned
|
||||
nvds_env.write((uint32_t)NVDS_START_STORAGE_AREA_ADDRESS,
|
||||
(uint32_t)total_length, buf);
|
||||
}
|
||||
#endif //(NVDS_READ_WRITE == 1)
|
||||
|
||||
/*
|
||||
* used init nvds flash base addr
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t nvds_space_init(uint32_t flash_size)
|
||||
{
|
||||
nvds_env.nvds_space = flash_size - FLASH_PAGE_SIZE * 4 * 6; // the last 6K
|
||||
}
|
||||
|
||||
/*
|
||||
* EXPORTED FUNCTION DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
uint8_t nvds_init(uint32_t len)
|
||||
{
|
||||
LOGI("nvds_init base=%x len=%d\n", nvds_env.nvds_space, len);
|
||||
uint8_t status = NVDS_OK;
|
||||
|
||||
// Initialize the pointer to the NVDS
|
||||
// nvds_env.nvds_space = base;
|
||||
// initialize the access functions
|
||||
nvds_env.read = &nvds_read;
|
||||
nvds_env.write = &nvds_write;
|
||||
nvds_env.erase = &nvds_erase;
|
||||
nvds_env.total_size = len;
|
||||
//nvds_temp_buf = get_fota_env_addr(2048);
|
||||
// Check if NVDS is correctly initialized
|
||||
if (!nvds_is_magic_number_ok()) {
|
||||
nvds_init_memory();
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
uint8_t nvds_get(uint8_t tag, nvds_tag_len_t *lengthPtr, uint8_t *buf)
|
||||
{
|
||||
uint8_t status;
|
||||
uint32_t tag_addr;
|
||||
struct nvds_tag_header tag_hdr;
|
||||
|
||||
// try to find the TAG in the NVDS
|
||||
status = nvds_browse_tag(tag, &tag_hdr, &tag_addr);
|
||||
|
||||
// if the TAG was found
|
||||
if (status == NVDS_OK) {
|
||||
// The parameter is valid, verify that buffer is large enough to store
|
||||
// it
|
||||
if (*lengthPtr < tag_hdr.length) {
|
||||
status = NVDS_LENGTH_OUT_OF_RANGE;
|
||||
} else // All is OK, proceed to the read operation
|
||||
{
|
||||
// Copy data to output buffer
|
||||
nvds_env.read((uint32_t)(tag_addr + NVDS_TAG_HEADER_LENGTH),
|
||||
(uint32_t)tag_hdr.length, buf);
|
||||
// Return tag address
|
||||
*lengthPtr = tag_hdr.length;
|
||||
}
|
||||
} else {
|
||||
// Nothing to return, set length to 0
|
||||
*lengthPtr = 0;
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
#if (NVDS_READ_WRITE == 1)
|
||||
|
||||
uint8_t nvds_del(uint8_t tag)
|
||||
{
|
||||
uint8_t status;
|
||||
struct nvds_tag_header tag_hdr;
|
||||
uint32_t tag_addr;
|
||||
uint8_t status_to_write;
|
||||
|
||||
// look for the TAG
|
||||
status = nvds_browse_tag(tag, &tag_hdr, &tag_addr);
|
||||
|
||||
// Verify whether the parameter is locked or not
|
||||
if ((status == NVDS_OK) && NVDS_IS_TAG_LOCKED(tag_hdr)) {
|
||||
status = NVDS_PARAM_LOCKED;
|
||||
}
|
||||
|
||||
// Proceed to the delete operation
|
||||
if (status == NVDS_OK) {
|
||||
// then we set parameter to erased
|
||||
status_to_write = NVDS_SET_TAG_ERASED(tag_hdr);
|
||||
nvds_env.write(
|
||||
(uint32_t)(tag_addr + offsetof(struct nvds_tag_header, status)),
|
||||
(uint32_t)sizeof(status_to_write), (uint8_t *)&status_to_write);
|
||||
|
||||
#if (NVDS_RAM_SUPPORT)
|
||||
mailbox_send(E_NVDS_SAVE_REQ, NULL, 0); // request NVDS saved
|
||||
#endif //(NVDS_RAM_SUPPORT)
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
uint8_t nvds_lock(uint8_t tag)
|
||||
{
|
||||
uint8_t status;
|
||||
struct nvds_tag_header tag_hdr;
|
||||
uint32_t tag_addr;
|
||||
uint8_t status_to_write;
|
||||
|
||||
// look for the TAG
|
||||
status = nvds_browse_tag(tag, &tag_hdr, &tag_addr);
|
||||
|
||||
// Proceed to the lock operation
|
||||
if (status == NVDS_OK) {
|
||||
// The tag has been found, set the parameter to locked
|
||||
status_to_write = NVDS_SET_TAG_LOCKED(tag_hdr);
|
||||
nvds_env.write(
|
||||
(uint32_t)(tag_addr + offsetof(struct nvds_tag_header, status)),
|
||||
(uint32_t)sizeof(status_to_write), &status_to_write);
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
uint8_t nvds_put(uint8_t tag, nvds_tag_len_t length, uint8_t *buf)
|
||||
{
|
||||
uint8_t status;
|
||||
struct nvds_tag_header tag_hdr;
|
||||
uint8_t tag_buffer[NVDS_PARAMETER_MAX_LENGTH];
|
||||
uint32_t cur_tag_addr, nxt_tag_addr;
|
||||
uint8_t status_to_write;
|
||||
uint32_t total_length;
|
||||
|
||||
/* parse once all the TAG elements of the NVDS to:
|
||||
* 1) find same tag
|
||||
* 2) erase and invalidate the former tag
|
||||
* 3) compute the total length needed by the all valid tags
|
||||
* 4) retrieve the first address where new data can be stored */
|
||||
total_length = 0;
|
||||
nxt_tag_addr = NVDS_START_STORAGE_AREA_ADDRESS;
|
||||
do {
|
||||
// Go to the next tag
|
||||
cur_tag_addr = nxt_tag_addr;
|
||||
|
||||
// Read the next TAG header structure
|
||||
status = nvds_walk_tag(cur_tag_addr, &tag_hdr, &nxt_tag_addr);
|
||||
|
||||
// check TAG is valid
|
||||
if ((status == NVDS_OK) && NVDS_IS_TAG_OK(tag_hdr)) {
|
||||
// check TAG is identical to the new one
|
||||
if (tag_hdr.tag == tag) {
|
||||
// check TAG is not locked
|
||||
if (NVDS_IS_TAG_LOCKED(tag_hdr)) {
|
||||
return NVDS_PARAM_LOCKED;
|
||||
}
|
||||
|
||||
// Read parameter data
|
||||
nvds_env.read((uint32_t)(cur_tag_addr + NVDS_TAG_HEADER_LENGTH),
|
||||
(uint32_t)tag_hdr.length, tag_buffer);
|
||||
|
||||
// Compare data with new parameter
|
||||
if ((tag_hdr.length == length) &&
|
||||
!memcmp(buf, tag_buffer, tag_hdr.length)) {
|
||||
return NVDS_OK;
|
||||
}
|
||||
|
||||
// then we set parameter to erased
|
||||
status_to_write = NVDS_SET_TAG_ERASED(tag_hdr);
|
||||
nvds_env.write(
|
||||
(uint32_t)(cur_tag_addr +
|
||||
offsetof(struct nvds_tag_header, status)),
|
||||
(uint32_t)sizeof(status_to_write),
|
||||
(uint8_t *)&status_to_write);
|
||||
} else {
|
||||
// add the current tag length to the total length (used for
|
||||
// purge)
|
||||
total_length += NVDS_TAG_FULL_LENGTH(tag_hdr);
|
||||
}
|
||||
}
|
||||
} while (status == NVDS_OK);
|
||||
|
||||
// check that we've reached the last TAG of the NVDS
|
||||
if (status != NVDS_OK) {
|
||||
/* check if there is enough space to write next tag
|
||||
the limit is calculated including 2 TAG headers (the current and the
|
||||
next that is used to leave at least an end marker) */
|
||||
if ((cur_tag_addr + (NVDS_TAG_HEADER_LENGTH * 2) +
|
||||
NVDS_ALIGNMENT(length)) > (nvds_env.total_size)) {
|
||||
ASSERT_ERR(nvds_temp_buf != NULL);
|
||||
|
||||
// purge the NVDS using the current buffer
|
||||
nvds_purge(total_length, nvds_temp_buf);
|
||||
|
||||
// compute the next tag address in the NVDS memory space
|
||||
cur_tag_addr =
|
||||
NVDS_START_STORAGE_AREA_ADDRESS + NVDS_ALIGNMENT(total_length);
|
||||
|
||||
// if there is still not enough space, return an error
|
||||
if ((cur_tag_addr + NVDS_TAG_HEADER_LENGTH +
|
||||
NVDS_ALIGNMENT(length)) > (nvds_env.total_size - 1)) {
|
||||
return NVDS_NO_SPACE_AVAILABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// First of all, write the data of the parameter
|
||||
nvds_env.write((uint32_t)(cur_tag_addr + NVDS_TAG_HEADER_LENGTH),
|
||||
(uint32_t)length, buf);
|
||||
|
||||
// Second of all, configure the new value of the TAG HEADER
|
||||
tag_hdr.tag = tag;
|
||||
tag_hdr.status = NVDS_SET_TAG_OK(tag_hdr);
|
||||
tag_hdr.length = length;
|
||||
|
||||
// Third of all, write the new TAG HEADER
|
||||
nvds_env.write((uint32_t)(cur_tag_addr), (uint32_t)sizeof(tag_hdr),
|
||||
(uint8_t *)&tag_hdr);
|
||||
|
||||
#if (NVDS_RAM_SUPPORT)
|
||||
mailbox_send(E_NVDS_SAVE_REQ, NULL, 0); // request NVDS saved
|
||||
#endif //(NVDS_RAM_SUPPORT)
|
||||
|
||||
return (NVDS_OK);
|
||||
}
|
||||
#endif // NVDS_RAM_SUPPORT
|
||||
|
||||
#endif //(NVDS_SUPPORT)
|
||||
|
||||
/// @} NVDS
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file rf.h
|
||||
*
|
||||
* @brief Common header file for all radios.
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef RF_H_
|
||||
#define RF_H_
|
||||
#define TRANS_POWER_NEGTIVE_8_9_DBM 0x6065 //-9.90,line loss 1DBM
|
||||
#define TRANS_POWER_NEGTIVE_2_7_DBM 0x6125 //-3.70,line loss 1DBM
|
||||
#define TRANS_POWER_0_5DBM 0x6165 //-0.50,line loss 1DBM
|
||||
#define TRANS_POWER_0_6DBM 0x61a5 //-0.4,line loss 1DBM
|
||||
#define TRANS_POWER_2_85DBM 0x61e5 //1.85,line loss 1DBM
|
||||
#define TRANS_POWER_2_9DBM 0x6225 //1.90,line loss 1DBM
|
||||
#define TRANS_POWER_4_68DBM 0x6265 //3.68,line loss 1DBM
|
||||
#define TRANS_POWER_4_6DBM 0x62a5 //3.60,line loss 1DBM
|
||||
#define TRANS_POWER_6_1DBM 0x62e5 //5.10,line loss 1DBM
|
||||
#define TRANS_POWER_7_3DBM 0x6365 //6.30,line loss 1DBM
|
||||
#define TRANS_POWER_8_3DBM 0x6425 //7.30,line loss 1DBM
|
||||
#define TRANS_POWER_9_2DBM 0x6465 //8.20,line loss 1DBM
|
||||
#define TRANS_POWER_13_06DBM 0x67e5 //12.06,line loss 1DBM
|
||||
#define TRANS_POWER_13_05DBM 0x6825 //12.05,line loss 1DBM
|
||||
#define TRANS_POWER_13_35DBM 0x6865 //12.35,line loss 1DBM
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup RF
|
||||
* @ingroup DRIVERS
|
||||
* @brief Common definitions for radio modules.
|
||||
*
|
||||
* This module declares the functions and constants that have to be defined for all RF.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* FUNCTION DECLARATIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
struct rwip_rf_api; // forward declaration to avoid including rw.h
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Initialization of RF.
|
||||
*
|
||||
* This function initializes the RF and fills the structure containing the function
|
||||
* pointers and parameters required by the RW BT stack.
|
||||
*
|
||||
* @param[out] api Pointer to the BT RF API structure
|
||||
*
|
||||
*****************************************************************************************
|
||||
*/
|
||||
void rf_init(struct rwip_rf_api *api);
|
||||
|
||||
//modem init
|
||||
void modem_init(void);
|
||||
|
||||
|
||||
/// @} RF
|
||||
|
||||
#endif // RF_H_
|
||||
@@ -0,0 +1,903 @@
|
||||
/*****************************************************************************************
|
||||
*
|
||||
* @file rf_extrc.c
|
||||
*
|
||||
* @brief External Radio Controller initialization and specific functions
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2017
|
||||
*
|
||||
*
|
||||
*****************************************************************************************/
|
||||
|
||||
/*****************************************************************************************
|
||||
* @addtogroup RF_EXTRC
|
||||
* @ingroup RF
|
||||
* @brief External Radio Controller Driver
|
||||
*
|
||||
* This is the driver block for external radio controller
|
||||
* @{
|
||||
*****************************************************************************************/
|
||||
|
||||
/*****************************************************************************************
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************/
|
||||
|
||||
#include "rwip_config.h" // RW SW configuration
|
||||
|
||||
#include "co_math.h" // common math functions
|
||||
#include "co_utils.h" // common utility definition
|
||||
#include "em_map.h" // exchange table
|
||||
#include "plf.h" // Platform functions
|
||||
#include "rf.h" // RF interface
|
||||
#include "rwip.h" // for RF API structure definition
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
#include "reg_ipcore.h" // DM core registers
|
||||
#include "xc_drv_gpio.h"
|
||||
|
||||
#if (BLE_EMB_PRESENT)
|
||||
#include "reg_blecore.h" // ble core registers
|
||||
#include "reg_em_ble_cs.h" // control structure definitions
|
||||
#endif //(BLE_EMB_PRESENT)
|
||||
|
||||
#if (BT_EMB_PRESENT)
|
||||
#include "reg_btcore.h" // bt core registers
|
||||
#include "reg_em_bt_cs.h" // control structure definitions
|
||||
#endif //(BT_EMB_PRESENT)
|
||||
/*****************************************************************************************
|
||||
* DEFINES
|
||||
****************************************************************************************/
|
||||
|
||||
#define RF_GAIN_TBL_SIZE (8)
|
||||
#define RF_PWR_TBL_SIZE (8)
|
||||
|
||||
#define RF_RSSI_20dB_THRHLD -20
|
||||
#define RF_RSSI_40dB_THRHLD -40
|
||||
#define RF_RSSI_45dB_THRHLD -45
|
||||
#define RF_RSSI_48dB_THRHLD -48
|
||||
#define RF_RSSI_55dB_THRHLD -55
|
||||
#define RF_RSSI_60dB_THRHLD -60
|
||||
#define RF_RSSI_70dB_THRHLD -70
|
||||
|
||||
// TX max power
|
||||
#define RF_POWER_MAX 7
|
||||
#define RF_POWER_MIN 1
|
||||
#define RF_POWER_MSK 0x07
|
||||
|
||||
/*****************************************************************************************
|
||||
* GLOBAL VARIABLE DEFINITIONS
|
||||
****************************************************************************************/
|
||||
// Power table
|
||||
__STATIC const int8_t RF_TX_PW_CONV_TBL[RF_PWR_TBL_SIZE] = {
|
||||
[0] = -23, [1] = -20, [2] = -17, [3] = -14,
|
||||
[4] = -11, [5] = -8, [6] = -5, [7] = -2};
|
||||
|
||||
/*****************************************************************************************
|
||||
* FUNCTION DEFINITIONS
|
||||
****************************************************************************************/
|
||||
|
||||
/*****************************************************************************************
|
||||
* @brief Read access
|
||||
*
|
||||
* @param[in] addr register address
|
||||
*
|
||||
* @return uint32_t value
|
||||
****************************************************************************************/
|
||||
__STATIC uint32_t rf_reg_rd(uint32_t addr) { return 0; }
|
||||
|
||||
/*****************************************************************************************
|
||||
* @brief Write access
|
||||
*
|
||||
* @param[in] addr register address
|
||||
* @param[in] value value to write
|
||||
****************************************************************************************/
|
||||
__STATIC void rf_reg_wr(uint32_t addr, uint32_t value) { return; }
|
||||
|
||||
/*****************************************************************************************
|
||||
* @brief Initialize frequency table in the exchange memory
|
||||
****************************************************************************************/
|
||||
__STATIC void rf_em_init(void)
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
uint8_t temp_freq_tbl[EM_RF_FREQ_TABLE_LEN];
|
||||
|
||||
#if (BT_EMB_PRESENT)
|
||||
// First half part of frequency table is for the even frequencies
|
||||
while (idx < (EM_RF_FREQ_TABLE_LEN / 2)) {
|
||||
temp_freq_tbl[idx] = 2 * idx;
|
||||
idx++;
|
||||
}
|
||||
|
||||
while (idx < EM_RF_FREQ_TABLE_LEN) {
|
||||
temp_freq_tbl[idx] = 2 * (idx - (EM_RF_FREQ_TABLE_LEN / 2)) + 1;
|
||||
idx++;
|
||||
}
|
||||
|
||||
em_wr(&temp_freq_tbl[0], EM_FT_OFFSET, EM_RF_FREQ_TABLE_LEN);
|
||||
#elif (BLE_EMB_PRESENT)
|
||||
while (idx < EM_RF_FREQ_TABLE_LEN) {
|
||||
temp_freq_tbl[idx] = 2 * idx;
|
||||
idx++;
|
||||
}
|
||||
|
||||
em_wr(&temp_freq_tbl[0], EM_FT_OFFSET, EM_RF_FREQ_TABLE_LEN);
|
||||
#endif //(BT_EMB_PRESENT/BLE_EMB_PRESENT)
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Convert RSSI to dBm
|
||||
*
|
||||
* @param[in] rssi_reg RSSI read from the HW registers
|
||||
*
|
||||
* @return The converted RSSI
|
||||
*****************************************************************************************
|
||||
*/
|
||||
extern volatile uint8_t evt_start;
|
||||
__RAM_CODE __STATIC int8_t rf_rssi_convert(uint8_t rssi_reg)
|
||||
{
|
||||
int8_t rssi_dbm;
|
||||
// uint16_t power_modem;
|
||||
|
||||
if (rssi_reg < 128) {
|
||||
rssi_dbm = rssi_reg - 50;
|
||||
} else {
|
||||
rssi_dbm = rssi_reg - 256 - 50;
|
||||
}
|
||||
#if (CONN_RSSI_DEBUG)
|
||||
if(evt_start){
|
||||
printf("con rssi %d\n", rssi_dbm);
|
||||
}
|
||||
#endif
|
||||
return (rssi_dbm);
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get the TX power as control structure TX power field from a value in
|
||||
*dBm.
|
||||
*
|
||||
* @param[in] txpwr_dbm TX power in dBm
|
||||
* @param[in] option If TXPWR_CS_LOWER, return index equal to or lower than
|
||||
*requested If TXPWR_CS_HIGHER, return index equal to or higher than requested
|
||||
* If TXPWR_CS_NEAREST, return index nearest to the
|
||||
*desired value
|
||||
*
|
||||
* @return The index of the TX power
|
||||
*
|
||||
*****************************************************************************************
|
||||
*/
|
||||
__STATIC uint8_t rf_txpwr_cs_get(int8_t txpwr_dbm, uint8_t option)
|
||||
{
|
||||
ASSERT_ERR(option <= TXPWR_CS_NEAREST);
|
||||
|
||||
uint8_t i;
|
||||
|
||||
for (i = RF_POWER_MIN; i < RF_POWER_MAX; i++) {
|
||||
// Loop until we find a power higher than or equal to the requested one
|
||||
if (RF_TX_PW_CONV_TBL[i] >= txpwr_dbm)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((RF_TX_PW_CONV_TBL[i] > txpwr_dbm) && (i > RF_POWER_MIN)) {
|
||||
if ((option == TXPWR_CS_LOWER) ||
|
||||
((option == TXPWR_CS_NEAREST) &&
|
||||
(co_abs(txpwr_dbm - RF_TX_PW_CONV_TBL[i - 1]) <
|
||||
co_abs(txpwr_dbm - RF_TX_PW_CONV_TBL[i])))) {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Init RF sequence after reset.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
__STATIC void rf_reset(void) { return; }
|
||||
|
||||
#if (BT_EMB_PRESENT)
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Decrease the TX power by one step
|
||||
*
|
||||
* @param[in] link_id Link ID for which the TX power has to be decreased
|
||||
*
|
||||
* @return true when minimum power is reached, false otherwise
|
||||
*****************************************************************************************
|
||||
*/
|
||||
__STATIC bool rf_txpwr_dec(uint8_t link_id)
|
||||
{
|
||||
// Get current TX power value
|
||||
uint8_t tx_pwr =
|
||||
em_bt_pwrcntl_txpwr_getf(EM_BT_CS_ACL_INDEX(link_id)) & RF_POWER_MSK;
|
||||
|
||||
// Check if value can be decreased
|
||||
if (tx_pwr > RF_POWER_MIN) {
|
||||
// Decrease the TX power value
|
||||
em_bt_pwrcntl_txpwr_setf(EM_BT_CS_ACL_INDEX(link_id), tx_pwr - 1);
|
||||
}
|
||||
|
||||
return (tx_pwr > RF_POWER_MIN);
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Increase the TX power by one step
|
||||
*
|
||||
* @param[in] link_id Link ID for which the TX power has to be increased
|
||||
*
|
||||
* @return true when maximum power is reached, false otherwise
|
||||
*****************************************************************************************
|
||||
*/
|
||||
__STATIC bool rf_txpwr_inc(uint8_t link_id)
|
||||
{
|
||||
// Get current TX power value
|
||||
uint8_t tx_pwr =
|
||||
em_bt_pwrcntl_txpwr_getf(EM_BT_CS_ACL_INDEX(link_id)) & RF_POWER_MSK;
|
||||
|
||||
// Check if value can be increased
|
||||
if (tx_pwr < RF_POWER_MAX) {
|
||||
// Increase the TX power value
|
||||
em_bt_pwrcntl_txpwr_setf(EM_BT_CS_ACL_INDEX(link_id), tx_pwr + 1);
|
||||
}
|
||||
|
||||
return (tx_pwr < RF_POWER_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Set the TX power to max
|
||||
*
|
||||
* @param[in] link_id Link Identifier
|
||||
****************************************************************************************
|
||||
*/
|
||||
__STATIC void rf_txpwr_max_set(uint8_t link_id)
|
||||
{
|
||||
// Set max TX power value
|
||||
em_bt_pwrcntl_txpwr_setf(EM_BT_CS_ACL_INDEX(link_id), RF_POWER_MAX);
|
||||
}
|
||||
#endif //(BT_EMB_PRESENT)
|
||||
|
||||
#if (BLE_EMB_PRESENT)
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Enable/disable force AGC mechanism
|
||||
*
|
||||
* @param[in] True: Enable / False: disable
|
||||
*****************************************************************************************
|
||||
*/
|
||||
__STATIC void rf_force_agc_enable(bool en) { return; }
|
||||
#endif //(BLE_EMB_PRESENT)
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Get TX power in dBm from the index in the control structure
|
||||
*
|
||||
* @param[in] txpwr_idx Index of the TX power in the control structure
|
||||
* @param[in] modulation Modulation: 1 or 2 or 3 MBPS
|
||||
*
|
||||
* @return The TX power in dBm
|
||||
*****************************************************************************************
|
||||
*/
|
||||
__STATIC int8_t rf_txpwr_dbm_get(uint8_t txpwr_idx, uint8_t modulation)
|
||||
{
|
||||
// power table is the same for BR and EDR
|
||||
return (RF_TX_PW_CONV_TBL[txpwr_idx]);
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************************
|
||||
* @brief Sleep function for the RF.
|
||||
*****************************************************************************************
|
||||
*/
|
||||
__STATIC void rf_sleep(void)
|
||||
{
|
||||
ip_deepslcntl_set((ip_deepslcntl_get() & (~IP_EXTWKUPDSB_BIT)) |
|
||||
IP_DEEP_SLEEP_ON_BIT | // RW BT Core sleep
|
||||
IP_RADIO_SLEEP_EN_BIT | // Radio sleep
|
||||
IP_OSC_SLEEP_EN_BIT); // Oscillator sleep
|
||||
}
|
||||
|
||||
#if 0
|
||||
void rf_test_pin_init(void)
|
||||
{
|
||||
// writel(0x53022040, 6<<4| 6);
|
||||
writel(0x53022040, 6<<4| 0);
|
||||
// writel(0x53022040, 0);
|
||||
xc_gpio_fun_sel(3,0);
|
||||
xc_gpio_mux_ctl(3,3); // en test_pin[0]
|
||||
*((uint32_t volatile*)0x40000170) = 0;
|
||||
|
||||
xc_gpio_fun_sel(4,0);
|
||||
xc_gpio_mux_ctl(4,3); // en test_pin[1]
|
||||
*((uint32_t volatile*)0x40000174) = 1;
|
||||
|
||||
// xc_gpio_fun_sel(5,0);
|
||||
// xc_gpio_mux_ctl(5,3); // en test_pin[2]
|
||||
// *((uint32_t volatile*)0x40000178) = 2;
|
||||
|
||||
xc_gpio_fun_sel(6,0);
|
||||
xc_gpio_mux_ctl(6,3); // en test_pin[3]
|
||||
*((uint32_t volatile*)0x4000017c) = 2;
|
||||
|
||||
// xc_gpio_fun_sel(7,0);
|
||||
// xc_gpio_mux_ctl(7,3); // en test_pin[4]
|
||||
// *((uint32_t volatile*)0x40000180) = 3;
|
||||
|
||||
xc_gpio_fun_sel(8,0);
|
||||
xc_gpio_mux_ctl(8,3); // en test_pin[5]
|
||||
*((uint32_t volatile*)0x40000184) = 3;
|
||||
|
||||
// xc_gpio_fun_sel(9,0);
|
||||
// xc_gpio_mux_ctl(9,3); // en test_pin[6]
|
||||
// *((uint32_t volatile*)0x40000188) = 5;
|
||||
|
||||
xc_gpio_fun_sel(23, GPIO_Dx);
|
||||
xc_gpio_mux_ctl(23, GPIO_Mux3); // en test_pin[7]
|
||||
*((uint32_t volatile*)0x4000018c) = 4;
|
||||
|
||||
xc_gpio_fun_sel(24, GPIO_Dx);
|
||||
xc_gpio_mux_ctl(24, GPIO_Mux3); // en test_pin[8]
|
||||
*((uint32_t volatile*)0x40000190) = 5;
|
||||
xc_gpio_fun_sel(22,0);
|
||||
xc_gpio_mux_ctl(22,3); // en test_pin[6]
|
||||
*((uint32_t volatile*)0x40000188) = 6;
|
||||
|
||||
uint32_t val = (*(volatile unsigned *)(0x40000000 + 0x134));
|
||||
(*(volatile unsigned *)(0x40000000 + 0x134)) = val | (0x1<<28);
|
||||
|
||||
xc_gpio_fun_sel(15,0);
|
||||
xc_gpio_mux_ctl(15,3); // en test_pin[0]
|
||||
|
||||
xc_gpio_fun_sel(16,0);
|
||||
xc_gpio_mux_ctl(16,3); // en test_pin[1]
|
||||
|
||||
xc_gpio_fun_sel(5,0);
|
||||
xc_gpio_mux_ctl(5,3); // en test_pin[3]
|
||||
|
||||
xc_gpio_fun_sel(26,0);
|
||||
xc_gpio_mux_ctl(26,3); // en test_pin[4]
|
||||
|
||||
xc_gpio_fun_sel(27,0);
|
||||
xc_gpio_mux_ctl(27,3); // en test_pin[5]
|
||||
|
||||
xc_gpio_fun_sel(28,0);
|
||||
xc_gpio_mux_ctl(28,3); // en test_pin[6]
|
||||
|
||||
// xc_gpio_fun_sel(29,0);
|
||||
// xc_gpio_mux_ctl(29,3); // en test_pin[7]
|
||||
|
||||
// xc_gpio_fun_sel(30,0);
|
||||
// xc_gpio_mux_ctl(30,3); // en test_pin[8]
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************************
|
||||
* MODEM FUNCTION INTERFACE
|
||||
***************************************************************************************/
|
||||
void delay_ms_test()
|
||||
{
|
||||
for (volatile int i = 0; i < 1000; i++) {
|
||||
}
|
||||
}
|
||||
|
||||
#define RF_BASE (0x53021000)
|
||||
#define rf_ana0 (RF_BASE + 0 * 0x4) // 0x53021000
|
||||
#define rf_ana1 (RF_BASE + 1 * 0x4) // 0x53021004
|
||||
#define rf_ana2 (RF_BASE + 2 * 0x4) // 0x53021008
|
||||
#define rf_ana3 (RF_BASE + 3 * 0x4) // 0x5302100c
|
||||
#define rf_ana4 (RF_BASE + 4 * 0x4) // 0x53021010
|
||||
#define rf_ana5 (RF_BASE + 5 * 0x4) // 0x53021014
|
||||
#define rf_ana6 (RF_BASE + 6 * 0x4) // 0x53021018
|
||||
#define rf_ana7 (RF_BASE + 7 * 0x4) // 0x5302101C
|
||||
#define rf_ana8 (RF_BASE + 8 * 0x4) // 0x53021020
|
||||
#define rf_ana9 (RF_BASE + 9 * 0x4) // 0x53021024
|
||||
#define rf_ana10 (RF_BASE + 10 * 0x4) // 0x53021028
|
||||
#define rf_ana11 (RF_BASE + 11 * 0x4) // 0x5302102c
|
||||
#define rf_ana12 (RF_BASE + 12 * 0x4) // 0x53021030
|
||||
#define rf_ana13 (RF_BASE + 13 * 0x4) // 0x53021034
|
||||
#define rf_ana14 (RF_BASE + 14 * 0x4) // 0x53021038
|
||||
#define rf_ana15 (RF_BASE + 15 * 0x4) // 0x5302103c
|
||||
#define rf_ana16 (RF_BASE + 16 * 0x4) // 0x53021040
|
||||
#define rf_ana17 (RF_BASE + 17 * 0x4) // 0x53021044
|
||||
#define rf_ana18 (RF_BASE + 18 * 0x4) // 0x53021048
|
||||
#define rf_ana19 (RF_BASE + 19 * 0x4) // 0x5302104c
|
||||
#define rf_ana20 (RF_BASE + 20 * 0x4) // 0x53021050
|
||||
#define rf_ana21 (RF_BASE + 21 * 0x4) // 0x53021054
|
||||
#define rf_ana22 (RF_BASE + 22 * 0x4) // 0x53021058
|
||||
#define rf_ana23 (RF_BASE + 23 * 0x4) // 0x5302105c
|
||||
#define rf_ana24 (RF_BASE + 24 * 0x4) // 0x53021060
|
||||
#define rf_ana25 (RF_BASE + 25 * 0x4) // 0x53021064
|
||||
#define rf_ana26 (RF_BASE + 26 * 0x4) // 0x53021068
|
||||
#define rf_ana27 (RF_BASE + 27 * 0x4) // 0x5302106c
|
||||
#define rf_ana28 (RF_BASE + 28 * 0x4) // 0x53021070
|
||||
#define rf_ana29 (RF_BASE + 29 * 0x4) // 0x53021074
|
||||
#define rf_ana30 (RF_BASE + 30 * 0x4) // 0x53021078
|
||||
#define rf_ana31 (RF_BASE + 31 * 0x4) // 0x5302107c
|
||||
|
||||
//--- chip realated setting
|
||||
// Rx Parameter Configuration
|
||||
#define EXTRC_RXPWRUP (87)
|
||||
// #define RF_RX_ON_DELAY (70)
|
||||
// #define MODEM_RXON_DELAY (75)
|
||||
#define RF_RX_ON_DELAY (64)
|
||||
#define MODEM_RXON_DELAY (68)
|
||||
#define SYNC_ERR_BIT (7)
|
||||
|
||||
////Tx Parameter Configuration
|
||||
// #define EXTRC_TXPWRUP (80)
|
||||
// #define RF_TX_ON_DELAY (70)
|
||||
// #define MODEM_TXON_DELAY (10)
|
||||
|
||||
// //2M test
|
||||
// #define EXTRC_RXPWRUP (80)
|
||||
// #define RF_RX_ON_DELAY (10)
|
||||
// #define MODEM_RXON_DELAY (15)
|
||||
// #define SYNC_ERR_BIT (6)
|
||||
|
||||
// Tx Parameter Configuration
|
||||
#define EXTRC_TXPWRUP (87)
|
||||
#define RF_TX_ON_DELAY (75)
|
||||
#define MODEM_TXON_DELAY (32)
|
||||
|
||||
// //ble1m
|
||||
// #define EXTRC_RFRXTMDA0 8
|
||||
#define EXTRC_RFRXTMDA0 16
|
||||
// #define EXTRC_RXPATHDLY0 6
|
||||
#define EXTRC_RXPATHDLY0 4
|
||||
// ble2m
|
||||
#define EXTRC_RFRXTMDA1 8
|
||||
#define EXTRC_RXPATHDLY1 5
|
||||
// bles8
|
||||
#define EXTRC_RXFLUSHPATHDLY2 0
|
||||
#define EXTRC_RFRXTMDA2 136
|
||||
#define EXTRC_RXPATHDLY2 45
|
||||
// bles2
|
||||
#define EXTRC_RXFLUSHPATHDLY3 0
|
||||
#define EXTRC_RFRXTMDA3 40
|
||||
|
||||
#define setbit(x, y) ((x) |= (1 << (y)))
|
||||
#define clrbit(x, y) ((x) &= ~(1 << (y)))
|
||||
|
||||
static void wbit(uint16_t reg_addr, int end, int start, char *bit_str)
|
||||
{
|
||||
uint16_t reg_val = 0;
|
||||
char ch = 0;
|
||||
uint16_t i = 0;
|
||||
uint16_t s_len = 0;
|
||||
while (*(bit_str + s_len))
|
||||
s_len++;
|
||||
if (s_len != (end - start + 1))
|
||||
while (1)
|
||||
;
|
||||
reg_val = *(uint16_t *)(0x53021000 + reg_addr); // 0X4002F000
|
||||
for (i = start; i <= end; i++) {
|
||||
int bit_idx = i - start;
|
||||
ch = bit_str[(end - start) - bit_idx] - '0';
|
||||
if (ch == 1)
|
||||
setbit(reg_val, i);
|
||||
else if (ch == 0)
|
||||
clrbit(reg_val, i);
|
||||
}
|
||||
*(uint16_t *)(0x53021000 + reg_addr) = reg_val;
|
||||
}
|
||||
/*! ********************************************************
|
||||
* @name wbit
|
||||
* @desc wbit
|
||||
* *********************************************************/
|
||||
static uint16_t rbit(uint16_t reg_addr)
|
||||
{
|
||||
return *(uint16_t *)(0x53021000 + reg_addr);
|
||||
}
|
||||
|
||||
void rf_rccalib(void)
|
||||
{
|
||||
static uint8_t rccalib_flag = 0;
|
||||
if (rccalib_flag)
|
||||
return;
|
||||
uint32_t timeout = 0;
|
||||
uint16_t val = 0;
|
||||
wbit(0x0080, 10, 8, "111"); // RG_RCCAL_CTRL(Rccal �����ֵ����) def"100"
|
||||
delay_ms_test();
|
||||
wbit(0x0080, 5, 5, "1"); // RG_RCCAL_RESETN=1
|
||||
delay_ms_test();
|
||||
wbit(0x0080, 3, 3, "0"); // RG_RCCAL_SEL =0
|
||||
delay_ms_test();
|
||||
wbit(0x0080, 2, 2, "1"); // RG_RCCAL_EN=1
|
||||
delay_ms_test();
|
||||
wbit(0x0080, 4, 4, "1"); // RG_RCCAL_START=1
|
||||
delay_ms_test();
|
||||
while (!(rbit(0x0084) & 0x8000)) { // �ȴ�AD_RCCAL_FINISH���� �ó�Уֵ
|
||||
// AD_RCCAL_CTRIM
|
||||
if ((timeout++) > 0x10000)
|
||||
break;
|
||||
}
|
||||
val = rbit(0x0084);
|
||||
val = (val & 0x7FFF) >> 10; // ��УֵAD_RCCAL_CTRIM����
|
||||
wbit(0x0080, 3, 3, "1"); // RG_RCCAL_SEL =1
|
||||
wbit(0x0080, 2, 2, "0"); // RG_RCCAL_EN=0
|
||||
wbit(0x0080, 4, 4, "0"); // RG_RCCAL_START=0
|
||||
char tb[6] = {0}; // �������Уֵת�����ַ���
|
||||
tb[4] = ((val & 0x01) ? '1' : '0');
|
||||
tb[3] = ((val & 0x02) ? '1' : '0');
|
||||
tb[2] = ((val & 0x04) ? '1' : '0');
|
||||
tb[1] = ((val & 0x08) ? '1' : '0');
|
||||
tb[0] = ((val & 0x10) ? '1' : '0');
|
||||
wbit(0x0080, 15, 11, tb);
|
||||
rccalib_flag = 1;
|
||||
printf("\nRG_RCCAL_CC:%X \n", rbit(0x80));
|
||||
}
|
||||
|
||||
#if 0
|
||||
void send_Tone(void)
|
||||
{
|
||||
printf("send_Tone \n");
|
||||
uint32_t value = 0;
|
||||
|
||||
//ana30<13> 默认0改成1;shdn_tx mux
|
||||
writel(rf_ana30, readl(rf_ana30) | (0x1 << 13));
|
||||
//ana30<7:0> 默认00000000改成11111111;shdn
|
||||
writel(rf_ana30, readl(rf_ana30) | (0xff ));
|
||||
// ana29<5:4>默认11改成00;sxrstn mux
|
||||
value = readl(rf_ana29) & ~(0x3 << 4);
|
||||
writel(rf_ana29, value);
|
||||
// ana29<2>默认0改成1;dsmrstnspi
|
||||
writel(rf_ana29, readl(rf_ana29) | (0x01 << 2));
|
||||
// ana27<0>默认0改成1;afcrstnspi
|
||||
writel(rf_ana27, readl(rf_ana27) | (0x01));
|
||||
|
||||
//手动开tx_en(5A,5B共用):
|
||||
//ana29<3>默认0改成1;dacrstnspi
|
||||
writel(rf_ana29, readl(rf_ana29) | (0x01 << 3));
|
||||
//ana30<14> 默认0改成1;en_tx mux
|
||||
writel(rf_ana30, readl(rf_ana30) | (0x01 << 14));
|
||||
//ana31<7:2>默认000000改成111111;tx_en
|
||||
writel(rf_ana31, readl(rf_ana31) | (0x3f << 2));
|
||||
|
||||
// 发送单载波
|
||||
writel(rf_ana29, readl(rf_ana29) | (0x01 << 1)); // 手动afc mux开关ana29<1>默认0改成1,
|
||||
writel(rf_ana28, readl(rf_ana28) | (0x01)); // ana28<0> 拉高
|
||||
delay_ms_test();
|
||||
value = readl(0x53022064) & ~(0x1FFFFFFF << 4);writel(0x53022064, value | 0x896A << 16); // 2410
|
||||
|
||||
writel(rf_ana28, readl(rf_ana28) & ~(0x01)); // ana28<0> 默认0
|
||||
//value = readl(0x53022064) & ~(0x1FFFFFFF << 4);writel(0x53022064, value | 0x8962 << 16| 0xa4000); // 2402
|
||||
delay_ms_test();
|
||||
writel(rf_ana28, readl(rf_ana28) | (0x01)); // ana28<0> 拉高
|
||||
|
||||
while (1){
|
||||
// value = readl(0x53022064) & ~(0x1FFFFFFF<<4); writel(0x53022064, value | 0x8970<<16|0x28f); //2416 tone +10k
|
||||
// delay_ms_test();
|
||||
// value = readl(0x53022064) & ~(0x1FFFFFFF<<4); writel(0x53022064, value | 0x8960<<16|0xffd70); //2416 tone -10k
|
||||
// delay_ms_test();
|
||||
value = readl(0x53022064) & ~(0x1FFFFFFF<<4); writel(0x53022064, value | 0x8960<<16|0xe028f); //2416 tone +10k
|
||||
delay_ms_test();
|
||||
value = readl(0x53022064) & ~(0x1FFFFFFF<<4); writel(0x53022064, value | 0x8960<<16|0xdfd70); //2416 tone -10k
|
||||
delay_ms_test();
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
void auto_agc_init()
|
||||
{
|
||||
*((uint32_t volatile *)0x5302109c) =
|
||||
((0x0) << 10 | (0x0) << 4); // bt_rx_vga_map6/7
|
||||
*((uint32_t volatile *)0x530210A0) =
|
||||
((0x0) << 10 | (0x4) << 4); // bt_rx_vga_map8/9
|
||||
*((uint32_t volatile *)0x530210A4) =
|
||||
((0x8) << 10 | (0xc) << 4); // bt_rx_vga_map10/11
|
||||
*((uint32_t volatile *)0x530210A8) =
|
||||
((0x10) << 10 | (0x14) << 4); // bt_rx_vga_map12/13
|
||||
*((uint32_t volatile *)0x530210Ac) =
|
||||
((0x18) << 10 | (0x1c) << 4); // bt_rx_vga_map14/15
|
||||
// w4 0x53022000 0x97a0
|
||||
|
||||
*((uint32_t volatile *)0x53022018) =
|
||||
(0x0 << 24) | (0x0 << 16) | (0x0 << 8) | (0x0); // hw_cfg_rf_abb_gain0-3
|
||||
*((uint32_t volatile *)0x5302201c) =
|
||||
(0x0 << 24) | (0x0 << 16) | (0x0 << 8) | (0x0);
|
||||
*((uint32_t volatile *)0x53022020) =
|
||||
(0x8 << 24) | (0x4 << 16) | (0x2 << 8) | (0x0);
|
||||
*((uint32_t volatile *)0x53022024) =
|
||||
(0xe << 24) | (0xc << 16) | (0xa << 8) | (0x8);
|
||||
// *((uint32_t volatile*)0x530210A0) = ((8<<2)<<10 | (9<<2)<<4);
|
||||
// //bt_rx_vga_map8/9
|
||||
// *((uint32_t volatile*)0x530210A4) = ((9<<2)<<10 | (9<<2)<<4);
|
||||
// //bt_rx_vga_map10/11
|
||||
// *((uint32_t volatile*)0x530210A8) = ((9<<2)<<10 | (9<<2)<<4);
|
||||
// //bt_rx_vga_map12/13
|
||||
// *((uint32_t volatile*)0x530210Ac) = ((9<<2)<<10 | (9<<2)<<4);
|
||||
// //bt_rx_vga_map14/15
|
||||
|
||||
*((uint32_t volatile *)0x53022000) = (
|
||||
// 0<<0 | //0 enable
|
||||
// 1<<1 | //1 hw_agc_sel
|
||||
0 << 1 | // agc_en_mode
|
||||
0 << 4 | // 16 agc_adc_en_sw
|
||||
1 << 5 | // 17 hw_agc_ctrl_enable
|
||||
0 << 6 | // 18 cfg_cci_gain_mode
|
||||
1 << 7 | // rw rssi sel
|
||||
7 << 8 | // 23:20 cfg_LNA_init
|
||||
9 << 12); // 27:24 cfg_ABB_init
|
||||
*((uint32_t volatile *)0x5302200c) = 25; // cfg_turner_gain
|
||||
}
|
||||
|
||||
void rf_xtal_cal_set(uint8_t set_value)
|
||||
{
|
||||
uint32_t value;
|
||||
value = readl(CPRAO_AON_RF_AONREG_ADDR) & ~(0x3F << 20);
|
||||
writel(CPRAO_AON_RF_AONREG_ADDR, value | (set_value << 20));
|
||||
}
|
||||
|
||||
void modem_init(void)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
// open bt clock
|
||||
writel(0x40000040,
|
||||
readl(0x40000040) | (0x01 << 4) | 0xFFFF0000); // 0x40[4] bt_clk_en
|
||||
writel(0x40000048, readl(0x40000048) | (0x01 << 4) |
|
||||
0xFFFF0000); // 0x48[4] bt_modem_clk_en
|
||||
writel(0x40000070,
|
||||
readl(0x40000070) | (0x01 << 10) | 0xFFFF0000); // 0x70[10]bt_pclk_en
|
||||
writel(0x40000074, readl(0x40000074) | (0x01 << 2) |
|
||||
0xFFFF0000); // 0x74[2] bt32k_clk_en
|
||||
writel(0x4000247c, 0x200020); // bt32k_clk_ao_en
|
||||
writel(0x53022048, ((MODEM_TXON_DELAY << 8) | MODEM_RXON_DELAY));
|
||||
writel(0x53020368, readl(0x53020368) | (0x01 << 31)); // EXT_CORRCODE_EN[31]
|
||||
writel(0x53020204, readl(0x53020204) | (0x01 << 2)); // int_rx_cfg_sel = 1
|
||||
|
||||
writel(0x53022044, readl(0x53022044) & ~(0x1 << 13)); // neg sample adc
|
||||
writel(0x530210B0, readl(0x530210B0) & 0xFFFF | (1 << 14)); // bt_en_pm = 1
|
||||
writel(0x40002450, 1); // CPR_AO BB_CORELDORF_EN
|
||||
|
||||
writel(0x53020244, readl(0x53020244) & 0xFFFF |
|
||||
(0x1e00 << 16)); // int_fe_ifshift1[12:0] 512->1M IF
|
||||
|
||||
writel(0x5302204C, RF_TX_ON_DELAY << 8 | RF_RX_ON_DELAY); // rf_delay_ctrl
|
||||
writel(0x530210B8, (0x1 << 0x1) | (0x1 << 0x2)); // 正常工作
|
||||
|
||||
writel(0x53020214, 0x1);
|
||||
|
||||
// SYNC_ERR_BLE
|
||||
value = readl(0x53020368) & ~(0x7 << 8);
|
||||
writel(0x53020368, value | (SYNC_ERR_BIT << 8));
|
||||
|
||||
writel(rf_ana29, readl(rf_ana29) & ~(0x01 << 1));
|
||||
|
||||
writel(rf_ana2, 0x615f);
|
||||
|
||||
rf_rccalib();
|
||||
#if CFG_RSSI_ENABLE //auto_agc
|
||||
auto_agc_init();
|
||||
#else
|
||||
////ana0<7>默认0改成1,进入手动agc模式。用ana0<6:0>配置增益
|
||||
value = readl(rf_ana0);
|
||||
writel(rf_ana0, value | (0x1 << 7));
|
||||
// value = readl(rf_ana0) & (~0x7f) ; writel(rf_ana0, value | (0x7A));
|
||||
value = readl(rf_ana0) & (~0x7f);
|
||||
writel(rf_ana0, value | (0x77));
|
||||
#endif
|
||||
|
||||
#ifdef USED_DCDC
|
||||
writel(rf_ana21, TRANS_POWER_9_2DBM);
|
||||
#error
|
||||
#else
|
||||
writel(rf_ana21, TRANS_POWER_NEGTIVE_8_9_DBM);
|
||||
#endif // USED_DCDC
|
||||
|
||||
// 配置 VCO 电流ana18<2:0> --000, ana18<5:3> --001
|
||||
value = readl(rf_ana18) & ~(0x7);
|
||||
writel(rf_ana18, value);
|
||||
value = readl(rf_ana18) & ~(0x7 << 3);
|
||||
writel(rf_ana18, (value | (0x1 << 3)));
|
||||
value = readl(rf_ana2) & ~(0xf << 5);
|
||||
writel(rf_ana2, value | (0x8 << 5));
|
||||
value = readl(rf_ana24);
|
||||
|
||||
value=0x952c;
|
||||
|
||||
writel(rf_ana24, value);
|
||||
#ifdef VCO_POWER
|
||||
// ana4<15:12>默认1001(量产版默认值1000)改成0000
|
||||
value = readl(rf_ana4) & ~(0xf << 12);
|
||||
writel(rf_ana4, value);
|
||||
|
||||
// ana18<5:3>默认000改成001;
|
||||
value = readl(rf_ana18) | (0x001 << 3);
|
||||
writel(rf_ana18, value);
|
||||
// ana18<2:0>默认101改成000;
|
||||
value = readl(rf_ana18) & ~(0x7 << 0);
|
||||
writel(rf_ana18, value);
|
||||
|
||||
// ana28<4:2>默认100改成000.
|
||||
value = readl(rf_ana28) & ~(0x7 << 2);
|
||||
writel(rf_ana28, value);
|
||||
#endif // VCO_POWER
|
||||
|
||||
// rf_test_pin_init();
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* RADIO FUNCTION INTERFACE
|
||||
***************************************************************************************/
|
||||
void rf_init(struct rwip_rf_api *api)
|
||||
{
|
||||
// ********************************************************
|
||||
// * Initialize the RF driver API structure *
|
||||
// ********************************************************
|
||||
|
||||
api->reg_rd = rf_reg_rd;
|
||||
api->reg_wr = rf_reg_wr;
|
||||
api->txpwr_dbm_get = rf_txpwr_dbm_get;
|
||||
api->txpwr_min = RF_POWER_MIN;
|
||||
api->txpwr_max = RF_POWER_MAX;
|
||||
api->sleep = rf_sleep;
|
||||
api->reset = rf_reset;
|
||||
api->rssi_convert = rf_rssi_convert;
|
||||
api->txpwr_cs_get = rf_txpwr_cs_get;
|
||||
|
||||
#if (BLE_EMB_PRESENT)
|
||||
api->force_agc_enable = rf_force_agc_enable;
|
||||
#endif //(BLE_EMB_PRESENT)
|
||||
|
||||
#if (BT_EMB_PRESENT)
|
||||
api->txpwr_dec = rf_txpwr_dec;
|
||||
api->txpwr_inc = rf_txpwr_inc;
|
||||
api->txpwr_max_set = rf_txpwr_max_set;
|
||||
#endif //(BT_EMB_PRESENT)
|
||||
api->rssi_interf_thr = RF_RSSI_70dB_THRHLD;
|
||||
api->rssi_high_thr = RF_RSSI_40dB_THRHLD;
|
||||
api->rssi_low_thr = RF_RSSI_60dB_THRHLD;
|
||||
|
||||
#if (HCI_TEST_NO_IP)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// ********************************************************
|
||||
// * Initialize Exchange Memory *
|
||||
// ********************************************************
|
||||
|
||||
rf_em_init();
|
||||
|
||||
// ********************************************************
|
||||
// * Initialize BLE/BT Core Registers *
|
||||
// ********************************************************
|
||||
|
||||
/* BLE RADIOCNTL0 */
|
||||
ip_radiocntl0_pack(/*uint16_t spiptr*/ 0,
|
||||
/*uint8_t spicfg*/ 0,
|
||||
/*uint8_t spifreq*/ 0,
|
||||
/*uint8_t spigo*/ 0);
|
||||
|
||||
/* BLE RADIOCNTL1 */
|
||||
ip_radiocntl1_pack(/*uint8_t forceagcen*/ 0,
|
||||
/*uint8_t forceiq*/ 0,
|
||||
/*uint8_t rxdnsl*/ 0,
|
||||
/*uint8_t txdnsl*/ 0,
|
||||
/*uint16_t forceagclength*/ 0,
|
||||
/*uint8_t syncpulsemode*/ 0,
|
||||
/*uint8_t syncpulsesrc*/ 0,
|
||||
/*uint8_t dpcorren*/ 0,
|
||||
/*uint8_t jefselect*/ 1,
|
||||
/*uint8_t xrfsel*/ 2,
|
||||
/*uint8_t subversion*/ 0);
|
||||
|
||||
#if (BLE_EMB_PRESENT)
|
||||
|
||||
uint8_t dely1, dely2, dely3, dely4;
|
||||
ble_radiocntl2_phymsk_setf(
|
||||
0x3); // mark that 2mbps and Coded phy are supported for TLM
|
||||
|
||||
/* BLE RADIOPWRUPDN0 */
|
||||
ble_radiopwrupdn0_pack(/*uint8_t syncposition0*/ 0,
|
||||
/*uint8_t rxpwrup0*/ EXTRC_RXPWRUP,
|
||||
/*uint8_t txpwrdn0*/ 07,
|
||||
/*uint8_t txpwrup0*/ EXTRC_TXPWRUP);
|
||||
ble_radiopwrupdn0_unpack(&dely1, &dely2, &dely3, &dely4);
|
||||
|
||||
/* BLE RADIOPWRUPDN1 */
|
||||
ble_radiopwrupdn1_pack(/*uint8_t syncposition1*/ 0,
|
||||
/*uint8_t rxpwrup1*/ EXTRC_RXPWRUP,
|
||||
/*uint8_t txpwrdn1*/ 07,
|
||||
/*uint8_t txpwrup1*/ EXTRC_TXPWRUP);
|
||||
|
||||
ble_radiopwrupdn1_unpack(&dely1, &dely2, &dely3, &dely4);
|
||||
|
||||
/* BLE RADIOPWRUPDN2 */
|
||||
ble_radiopwrupdn2_pack(/*uint8_t syncposition2*/ 0,
|
||||
/*uint8_t rxpwrup2*/ EXTRC_RXPWRUP,
|
||||
/*uint8_t txpwrdn2*/ 07,
|
||||
/*uint8_t txpwrup2*/ EXTRC_TXPWRUP);
|
||||
|
||||
ble_radiopwrupdn2_unpack(&dely1, &dely2, &dely3, &dely4);
|
||||
|
||||
/* BLE RADIOPWRUPDN3 */
|
||||
ble_radiopwrupdn3_pack(/*uint8_t txpwrdn3*/ 07,
|
||||
/*uint8_t txpwrup3*/ EXTRC_TXPWRUP);
|
||||
|
||||
ble_radiopwrupdn3_unpack(&dely1, &dely2);
|
||||
|
||||
/* BLE RADIOTXRXTIM0 */
|
||||
ble_radiotxrxtim0_pack(/*uint8_t rfrxtmda0*/ EXTRC_RFRXTMDA0,
|
||||
/*uint8_t rxpathdly0*/ EXTRC_RXPATHDLY0,
|
||||
/*uint8_t txpathdly0*/ 4);
|
||||
|
||||
ble_radiotxrxtim0_unpack(&dely1, &dely2, &dely3);
|
||||
|
||||
/* BLE RADIOTXRXTIM1 */
|
||||
ble_radiotxrxtim1_pack(/*uint8_t rfrxtmda1*/ EXTRC_RFRXTMDA1,
|
||||
/*uint8_t rxpathdly1*/ EXTRC_RXPATHDLY1,
|
||||
/*uint8_t txpathdly1*/ 3);
|
||||
|
||||
ble_radiotxrxtim1_unpack(&dely1, &dely2, &dely3);
|
||||
|
||||
/* BLE RADIOTXRXTIM2 */
|
||||
ble_radiotxrxtim2_pack(/*uint8_t rxflushpathdly2*/ EXTRC_RXFLUSHPATHDLY2,
|
||||
/*uint8_t rfrxtmda2*/ EXTRC_RFRXTMDA2,
|
||||
/*uint8_t rxpathdly2*/ EXTRC_RXPATHDLY2,
|
||||
/*uint8_t txpathdly2*/ 4);
|
||||
|
||||
ble_radiotxrxtim2_unpack(&dely1, &dely2, &dely3, &dely4);
|
||||
|
||||
/* BLE RADIOTXRXTIM3 */
|
||||
ble_radiotxrxtim3_pack(/*uint8_t rxflushpathdly3*/ EXTRC_RXFLUSHPATHDLY3,
|
||||
/*uint8_t rfrxtmda3*/ EXTRC_RFRXTMDA3,
|
||||
/*uint8_t txpathdly3*/ 4);
|
||||
|
||||
ble_radiotxrxtim3_unpack(&dely1, &dely2, &dely3);
|
||||
|
||||
#endif //(BLE_EMB_PRESENT)
|
||||
|
||||
#if (BT_EMB_PRESENT)
|
||||
/* EDRCNTL */
|
||||
bt_rwbtcntl_nwinsize_setf(NORMAL_WIN_SIZE / 2);
|
||||
bt_edrcntl_rxgrd_timeout_setf(0x12);
|
||||
bt_edrcntl_rx_swap_setf(1);
|
||||
bt_edrcntl_tx_swap_setf(1);
|
||||
/* BT RADIOPWRUPDN */
|
||||
bt_radiopwrupdn_rxpwrupct_setf(EXTRC_RXPWRUP);
|
||||
bt_radiopwrupdn_txpwrdnct_setf(7);
|
||||
bt_radiopwrupdn_txpwrupct_setf(EXTRC_TXPWRUP);
|
||||
|
||||
/* IP RADIOCNTL */
|
||||
ip_radiocntl0_spifreq_setf(0);
|
||||
ip_radiocntl0_spigo_setf(0);
|
||||
ip_radiocntl0_spiptr_setf(0);
|
||||
ip_radiocntl1_forceagc_length_setf(0);
|
||||
ip_radiocntl1_sync_pulse_mode_setf(1); // SYNC_PULSE_SRC
|
||||
ip_radiocntl1_dpcorr_en_setf(0);
|
||||
ip_radiocntl1_xrfsel_setf(2); // xrfsel is 2 in our platform
|
||||
ip_radiocntl1_forceagc_en_setf(0);
|
||||
|
||||
/* BT RADIOTXRXTIM */
|
||||
bt_radiotxrxtim_rxpathdly_setf(24); // 21->24 2022/4/13
|
||||
bt_radiotxrxtim_txpathdly_setf(1);
|
||||
bt_radiotxrxtim_sync_position_setf(0);
|
||||
|
||||
/* BT RADIOCNTL 2 */
|
||||
bt_radiocntl2_freqtable_ptr_setf((EM_FT_OFFSET >> 2));
|
||||
bt_radiocntl2_syncerr_setf(0x7);
|
||||
|
||||
/* BT RADIOCNTL3 */
|
||||
bt_radiocntl3_rxrate0cfg_setf(1);
|
||||
bt_radiocntl3_txrate0cfg_setf(1);
|
||||
bt_radiocntl3_pack(/*uint8_t rxrate2cfg*/ 3,
|
||||
/*uint8_t rxrate1cfg*/ 2,
|
||||
/*uint8_t rxrate0cfg*/ 1,
|
||||
/*uint8_t getrssidelay*/ 0,
|
||||
/*uint8_t rxserparif*/ 0,
|
||||
/*uint8_t rxsyncrouting*/ 0,
|
||||
/*uint8_t rxvalidbeh*/ 0,
|
||||
/*uint8_t txrate2cfg*/ 3,
|
||||
/*uint8_t txrate1cfg*/ 2,
|
||||
/*uint8_t txrate0cfg*/ 1,
|
||||
/*uint8_t txserparif*/ 0,
|
||||
/*uint8_t txvalidbeh*/ 0);
|
||||
|
||||
#endif //(BT_EMB_PRESENT)
|
||||
}
|
||||
|
||||
///@} RF_EXTRC
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file rwip_task.h
|
||||
*
|
||||
* @brief Task Identifier description for the RW IP
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2016
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef RWIP_TASK_H_
|
||||
#define RWIP_TASK_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup ROOT
|
||||
* @{
|
||||
*
|
||||
* Information about RW SW TASK
|
||||
*
|
||||
* @name RW TASK Configuration
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/// Build the first message ID of a task. (in fact a ke_msg_id_t)
|
||||
#define TASK_FIRST_MSG(task) ((uint16_t)((task) << 8))
|
||||
|
||||
/// Builds the task identifier from the type and the index of that task.
|
||||
#define TASK_BUILD(type, index) ((uint16_t)(((index) << 8)|(type)) )
|
||||
|
||||
/// Retrieves task type from task id.
|
||||
#define TASK_TYPE_GET(ke_task_id) (((uint16_t)ke_task_id) & 0xFF)
|
||||
|
||||
/// Retrieves task index number from task id.
|
||||
#define TASK_IDX_GET(ke_task_id) ((((uint16_t)ke_task_id) >> 8) & 0xFF)
|
||||
|
||||
/// Message identifier index
|
||||
#define MSG_ID(task, idx) (TASK_FIRST_MSG((TASK_ID_ ## task)) + idx)
|
||||
|
||||
/// Tasks types definition, this value shall be in [0-254] range
|
||||
/*@TRACE*/
|
||||
enum TASK_API_ID
|
||||
{
|
||||
// -----------------------------------------------------------------------------------
|
||||
// ---------------------- Controller Task identifer ----------------------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
// Link Layer Tasks
|
||||
TASK_ID_LLM = 0, // BLE Link manager
|
||||
TASK_ID_LLC = 1, // BLE Link controller
|
||||
TASK_ID_LLD = 2, // BLE Link driver
|
||||
TASK_ID_LLI = 3, // BLE Link ISO
|
||||
|
||||
TASK_ID_DBG = 4, // Debug task
|
||||
|
||||
// BT Controller Tasks
|
||||
TASK_ID_LM = 5, // BT Link manager
|
||||
TASK_ID_LC = 6, // BT Link controller
|
||||
TASK_ID_LB = 7, // BT Broadcast
|
||||
TASK_ID_LD = 8, // BT Link driver
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// --------------------- BLE HL TASK API Identifiers ---------------------------------
|
||||
// --------------------- SHALL NOT BE CHANGED ---------------------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
|
||||
TASK_ID_L2CAP = 10, // L2CAP Task
|
||||
TASK_ID_GATT = 11, // Generic Attribute Profile Task
|
||||
TASK_ID_GAPM = 13, // Generic Access Profile Manager
|
||||
TASK_ID_GAPC = 14, // Generic Access Profile Controller
|
||||
TASK_ID_APP = 15, // Application API
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// --------------------- TRANSPORT AND PLATFORM TASKS --------------------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
TASK_ID_AHI = 16, // Application Host Interface
|
||||
TASK_ID_HCI = 17, // Host to Control Interface
|
||||
TASK_ID_DISPLAY = 19, // LCD/Display task
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// --------------------- BLE Profile TASK API Identifiers ----------------------------
|
||||
// --------------------- SHALL NOT BE CHANGED ---------------------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
TASK_ID_DISS = 20, // Device Information Service Server Task
|
||||
TASK_ID_DISC = 21, // Device Information Service Client Task
|
||||
|
||||
TASK_ID_PROXM = 22, // Proximity Monitor Task
|
||||
TASK_ID_PROXR = 23, // Proximity Reporter Task
|
||||
|
||||
TASK_ID_FINDL = 24, // Find Me Locator Task
|
||||
TASK_ID_FINDT = 25, // Find Me Target Task
|
||||
|
||||
TASK_ID_HTPC = 26, // Health Thermometer Collector Task
|
||||
TASK_ID_HTPT = 27, // Health Thermometer Sensor Task
|
||||
|
||||
TASK_ID_BLPS = 28, // Blood Pressure Sensor Task
|
||||
TASK_ID_BLPC = 29, // Blood Pressure Collector Task
|
||||
|
||||
TASK_ID_HRPS = 30, // Heart Rate Sensor Task
|
||||
TASK_ID_HRPC = 31, // Heart Rate Collector Task
|
||||
|
||||
TASK_ID_TIPS = 32, // Time Server Task
|
||||
TASK_ID_TIPC = 33, // Time Client Task
|
||||
|
||||
TASK_ID_SCPPS = 34, // Scan Parameter Profile Server Task
|
||||
TASK_ID_SCPPC = 35, // Scan Parameter Profile Client Task
|
||||
|
||||
TASK_ID_BASS = 36, // Battery Service Server Task
|
||||
TASK_ID_BASC = 37, // Battery Service Client Task
|
||||
|
||||
TASK_ID_HOGPD = 38, // HID Device Task
|
||||
TASK_ID_HOGPBH = 39, // HID Boot Host Task
|
||||
TASK_ID_HOGPRH = 40, // HID Report Host Task
|
||||
|
||||
TASK_ID_GLPS = 41, // Glucose Profile Sensor Task
|
||||
TASK_ID_GLPC = 42, // Glucose Profile Collector Task
|
||||
|
||||
TASK_ID_RSCPS = 43, // Running Speed and Cadence Profile Server Task
|
||||
TASK_ID_RSCPC = 44, // Running Speed and Cadence Profile Collector Task
|
||||
|
||||
TASK_ID_CSCPS = 45, // Cycling Speed and Cadence Profile Server Task
|
||||
TASK_ID_CSCPC = 46, // Cycling Speed and Cadence Profile Client Task
|
||||
|
||||
TASK_ID_ANPS = 47, // Alert Notification Profile Server Task
|
||||
TASK_ID_ANPC = 48, // Alert Notification Profile Client Task
|
||||
|
||||
TASK_ID_PASPS = 49, // Phone Alert Status Profile Server Task
|
||||
TASK_ID_PASPC = 50, // Phone Alert Status Profile Client Task
|
||||
|
||||
TASK_ID_CPPS = 51, // Cycling Power Profile Server Task
|
||||
TASK_ID_CPPC = 52, // Cycling Power Profile Client Task
|
||||
|
||||
TASK_ID_LANS = 53, // Location and Navigation Profile Server Task
|
||||
TASK_ID_LANC = 54, // Location and Navigation Profile Client Task
|
||||
|
||||
TASK_ID_IPSS = 55, // Internet Protocol Support Profile Server Task
|
||||
TASK_ID_IPSC = 56, // Internet Protocol Support Profile Client Task
|
||||
|
||||
TASK_ID_ENVS = 57, // Environmental Sensing Profile Server Task
|
||||
TASK_ID_ENVC = 58, // Environmental Sensing Profile Client Task
|
||||
|
||||
TASK_ID_WSCS = 59, // Weight Scale Profile Server Task
|
||||
TASK_ID_WSCC = 60, // Weight Scale Profile Client Task
|
||||
|
||||
TASK_ID_UDSS = 61, // User Data Service Server Task
|
||||
TASK_ID_UDSC = 62, // User Data Service Client Task
|
||||
|
||||
TASK_ID_BCSS = 63, // Body Composition Server Task
|
||||
TASK_ID_BCSC = 64, // Body Composition Client Task
|
||||
|
||||
TASK_ID_WPTS = 65, // Wireless Power Transfer Profile Server Task
|
||||
TASK_ID_WPTC = 66, // Wireless Power Transfer Profile Client Task
|
||||
|
||||
TASK_ID_PLXS = 67, // Pulse Oximeter Profile Server Task
|
||||
TASK_ID_PLXC = 68, // Pulse Oximeter Profile Client Task
|
||||
|
||||
TASK_ID_CGMS = 69, // Continuous Glucose Monitoring Server Task
|
||||
TASK_ID_CGMC = 70, // Continuous Glucose Monitoring Client Task
|
||||
|
||||
TASK_ID_CSISM = 71, // Coordinated Set Identification Profile Set Member Task
|
||||
TASK_ID_CSISC = 72, // Coordinated Set Identification Profile Set Coordinator Task
|
||||
|
||||
TASK_ID_OTS = 73, // Object Transfer Profile Server Task
|
||||
TASK_ID_OTC = 74, // Object Transfer Profile Client Task
|
||||
|
||||
TASK_ID_MESH = 200, // Mesh Task
|
||||
|
||||
TASK_ID_GAF = 210, // Generic Audio Framework
|
||||
|
||||
TASK_ID_AM0 = 240, // BLE Audio Mode 0
|
||||
|
||||
TASK_ID_THPP = 242, // Throughput profile tester used for debugging
|
||||
|
||||
TASK_ID_INVALID = 0xFF, // Invalid Task Identifier
|
||||
};
|
||||
|
||||
/// @} BT Stack Configuration
|
||||
/// @} ROOT
|
||||
|
||||
#endif //RWIP_CONFIG_H_
|
||||
Binary file not shown.
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
****************************************************************************************
|
||||
*
|
||||
* @file rwip_int.h
|
||||
*
|
||||
* @brief RW IP internal SW main module
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2009-2015
|
||||
*
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
#ifndef _RWIP_INT_H_
|
||||
#define _RWIP_INT_H_
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @addtogroup ROOT
|
||||
* @brief Entry points of the RW IP stacks/modules
|
||||
*
|
||||
* This module contains the primitives that allow an application accessing and running the
|
||||
* RW IP protocol stacks / modules.
|
||||
*
|
||||
* @{
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* INCLUDE FILES
|
||||
****************************************************************************************
|
||||
*/
|
||||
#include "rwip_config.h" // stack configuration
|
||||
|
||||
#include <stdint.h> // standard integer definitions
|
||||
#include <stdbool.h> // standard boolean definitions
|
||||
|
||||
|
||||
/*
|
||||
* DEFINES
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* STRUCTURE DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
#if (BLE_EMB_PRESENT && BLE_ISO_PRESENT)
|
||||
/// structure that represents ISO timer
|
||||
typedef struct rwip_iso_timer_
|
||||
{
|
||||
/// Target BTS time (in us)
|
||||
uint32_t tgt_bts[RWIP_ISO_TIMER_FIFO_DEPTH];
|
||||
/// Current ISO timer index
|
||||
uint8_t curr_idx;
|
||||
/// Next ISO timer index
|
||||
uint8_t next_idx;
|
||||
/// Number of ISO timers programmed
|
||||
uint8_t prog_nb;
|
||||
} rwip_iso_timer_t;
|
||||
#endif // (BLE_EMB_PRESENT && BLE_ISO_PRESENT)
|
||||
|
||||
/// RWIP Environment structure
|
||||
struct rwip_env_tag
|
||||
{
|
||||
#if (BLE_EMB_PRESENT && BLE_ISO_PRESENT)
|
||||
rwip_iso_timer_t iso_timer;
|
||||
#endif // (BLE_EMB_PRESENT && BLE_ISO_PRESENT)
|
||||
|
||||
#if (BLE_EMB_PRESENT || BT_EMB_PRESENT)
|
||||
/// Arbiter target timer (integer part, in half slots)
|
||||
uint32_t timer_arb_target;
|
||||
/// Alarm target timer (integer part, in half slots)
|
||||
uint32_t timer_alarm_target;
|
||||
#endif // (BLE_EMB_PRESENT || BT_EMB_PRESENT)
|
||||
/// Common target timer (in half slots)
|
||||
uint32_t timer_co_target;
|
||||
/// Last Sampled time (used for time conversion)
|
||||
rwip_time_t last_samp_time;
|
||||
|
||||
#if (BLE_EMB_PRESENT || BT_EMB_PRESENT)
|
||||
/// Contains sleep duration accumulated timing error (32kHz: 1/2 half us | 32.768kHz: 1/256 half-us)
|
||||
uint32_t sleep_acc_error;
|
||||
/// Power_up delay (in LP clock cycle unit, depends on Low power clock frequency)
|
||||
uint32_t lp_cycle_wakeup_delay;
|
||||
/// Duration of sleep and wake-up algorithm (depends on CPU speed) expressed in half us.
|
||||
uint16_t sleep_algo_dur;
|
||||
#endif // (BLE_EMB_PRESENT || BT_EMB_PRESENT)
|
||||
/// Prevent sleep bit field
|
||||
uint16_t prevent_sleep;
|
||||
#if (BLE_EMB_PRESENT || BT_EMB_PRESENT)
|
||||
/// External wake-up support
|
||||
bool ext_wakeup_enable;
|
||||
#if (!BLE_EMB_PRESENT)
|
||||
/// BTS sampling clock half microseconds residual (0 or 1)
|
||||
uint8_t samp_hus_residual;
|
||||
#endif // (!BLE_EMB_PRESENT)
|
||||
#endif // (BLE_EMB_PRESENT || BT_EMB_PRESENT)
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* GLOBAL DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/// RW SW environment
|
||||
extern struct rwip_env_tag rwip_env;
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION DEFINITIONS
|
||||
****************************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialization of the RW IP Common core driver
|
||||
*
|
||||
* @param[in] init_type Type of initialization (@see enum rwip_init_type)
|
||||
*/
|
||||
void rwip_driver_init(uint8_t init_type);
|
||||
|
||||
|
||||
///@} ROOT
|
||||
|
||||
#endif // _RWIP_INT_H_
|
||||
@@ -0,0 +1,72 @@
|
||||
/*!
|
||||
* \file shell.h
|
||||
*
|
||||
* \brief The head file of shell.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __SHELL_H__
|
||||
#define __SHELL_H__
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
#include "shell_handler.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define XC_DATA_LEN 64U
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
XC_SHELL_CMD_RECV = 0,
|
||||
XC_SHELL_CMD_PROC
|
||||
} eXC_Shell_Proc_state;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *cmd;
|
||||
eXC_Cmd_State (*fn)(eCMD_Type opt, int srgc, char *srgv[]);
|
||||
} XC_Cmd_Table_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_shell_test_case(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SHELL_H__ */
|
||||
@@ -0,0 +1,93 @@
|
||||
/*!
|
||||
* \file shell.h
|
||||
*
|
||||
* \brief The head file of shell_handler.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __SHELL_HANDLER_H__
|
||||
#define __SHELL_HANDLER_H__
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define XC_CMD_SIZE 255U
|
||||
|
||||
// XC Command
|
||||
#define XC_OK "OK"
|
||||
#define XC_ERROR "+CME ERROR:"
|
||||
|
||||
#define XC_CMD_TEST "+TEST"
|
||||
#define XC_CMD_BLE_MAC "+BMACADDR"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
XC_CMD_ERROR = -1,
|
||||
XC_CMD_SUCCESS = 0
|
||||
} eXC_Cmd_State;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
QUERY_CMD = 0x00,
|
||||
SET_CMD
|
||||
} eCMD_Type;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t byte0;
|
||||
uint8_t byte1;
|
||||
uint8_t byte2;
|
||||
uint8_t byte3;
|
||||
uint8_t byte4;
|
||||
uint8_t byte5;
|
||||
} BLE_Mac_Addr_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
extern uint8_t XC_Cmd[XC_CMD_SIZE];
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
eXC_Cmd_State xc_test_handler(eCMD_Type opt, int srgc, char *srgv[]);
|
||||
eXC_Cmd_State xc_ble_mac_addr_handler(eCMD_Type opt, int srgc, char *srgv[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SHELL_HANDLER_H__ */
|
||||
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/*!
|
||||
* \file shell.c
|
||||
*
|
||||
* \brief Target shell implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "shell.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
static XC_Cmd_Table_t XC_CMD_Table[] = {
|
||||
{ XC_CMD_TEST, xc_test_handler },
|
||||
{ XC_CMD_BLE_MAC, xc_ble_mac_addr_handler },
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define XC_CMD_TABLE_SIZE (sizeof(XC_CMD_Table) / sizeof(XC_Cmd_Table_t))
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
*
|
||||
* @return[out]
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_shell_init(void)
|
||||
{
|
||||
UART_InitTypeDef UART_InitStruct={0};
|
||||
|
||||
UART_InitStruct.Parity = UART_PARITY_DISABLE;
|
||||
UART_InitStruct.StopBits = UART_STOP_1_BITS;
|
||||
UART_InitStruct.WordLength = UART_UARTx_TCR_CLS_8BITS;
|
||||
UART_InitStruct.BaudRate = UART_BAUDRATE_115200;
|
||||
UART_InitStruct.HardwareFlowControl = UART_UARTx_MCR_AFCE_DISABLE;
|
||||
|
||||
UART_Init(XC_UART0, &UART_InitStruct);
|
||||
UART_Enable_RxIT(XC_UART0);
|
||||
NVIC_EnableIRQ(UART0_IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
*
|
||||
* @return[out]
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
eXC_Cmd_State xc_shell_proc(uint8_t *data, uint16_t data_len)
|
||||
{
|
||||
int srgc = 0;
|
||||
int index = 0;
|
||||
char *ptr = NULL;
|
||||
char *srgv[XC_DATA_LEN];
|
||||
eXC_Cmd_State ret = XC_CMD_ERROR;
|
||||
uint8_t *rx_cmd = data + 2;
|
||||
int16_t rx_cmd_idx = data_len - 2;
|
||||
|
||||
if(data_len <=2 && data[data_len] == '\0') {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(rx_cmd_idx <= 0 || rx_cmd[rx_cmd_idx] != '\0') {
|
||||
return ret;
|
||||
}
|
||||
// 注意这里 XC指令 只判定大写
|
||||
if(data[0] != 'X' || data[1] != 'C') {
|
||||
goto xc_end;
|
||||
}
|
||||
|
||||
for(index = 0; index < XC_CMD_TABLE_SIZE; index++) {
|
||||
int cmd_len = strlen(XC_CMD_Table[index].cmd);
|
||||
if(!strncmp((const char *)rx_cmd, XC_CMD_Table[index].cmd, cmd_len)) {
|
||||
ptr = (char *)rx_cmd + cmd_len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= XC_CMD_TABLE_SIZE || !XC_CMD_Table[index].fn) {
|
||||
goto xc_end;
|
||||
}
|
||||
|
||||
if(ptr[0] == '?') {
|
||||
ret = XC_CMD_Table[index].fn(QUERY_CMD, srgc, srgv);
|
||||
} else if(ptr[0] == '=' ) {
|
||||
ptr += 1;
|
||||
char *str = strtok((char *)ptr, " ");
|
||||
|
||||
while(str) {
|
||||
srgv[srgc++] = str;
|
||||
str = strtok((char *)NULL, " ");
|
||||
}
|
||||
|
||||
ret = XC_CMD_Table[index].fn(SET_CMD, srgc, srgv);
|
||||
} else {
|
||||
ret = XC_CMD_ERROR;
|
||||
}
|
||||
|
||||
xc_end:
|
||||
if(ret == XC_CMD_ERROR) {
|
||||
snprintf((char *)XC_Cmd, XC_CMD_SIZE, "\r\n%s %x\r\n", XC_ERROR, 1);
|
||||
UART_SendData(XC_UART0, XC_Cmd, strlen((const char *)XC_Cmd));
|
||||
} else {
|
||||
UART_SendData(XC_UART0, XC_Cmd, strlen((const char *)XC_Cmd));
|
||||
}
|
||||
memset(XC_Cmd, 0, XC_CMD_SIZE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
*
|
||||
* @return[out]
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_shell_test_case(void)
|
||||
{
|
||||
eXC_Shell_Proc_state sh_sta = XC_SHELL_CMD_RECV;
|
||||
uint8_t recv_buff[XC_CMD_SIZE] = { 0 };
|
||||
uint16_t recv_len = 0;
|
||||
|
||||
xc_shell_init( );
|
||||
|
||||
while(1) {
|
||||
/* main loop */
|
||||
switch(sh_sta) {
|
||||
case XC_SHELL_CMD_RECV: {
|
||||
recv_len += UART_ReceiveData(XC_UART0, recv_buff+recv_len);
|
||||
if(recv_len) {
|
||||
if((recv_buff[recv_len-2] == '\r') &&
|
||||
(recv_buff[recv_len-1] == '\n'))
|
||||
sh_sta = XC_SHELL_CMD_PROC;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case XC_SHELL_CMD_PROC: {
|
||||
// UART_SendData(XC_UART0, recv_buff, recv_len);
|
||||
(void)xc_shell_proc(recv_buff, recv_len);
|
||||
recv_len = 0;
|
||||
sh_sta = XC_SHELL_CMD_RECV;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/*!
|
||||
* \file shell_handler.c
|
||||
*
|
||||
* \brief Target shell handler implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "shell_handler.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
uint8_t XC_Cmd[XC_CMD_SIZE] = { 0 };
|
||||
|
||||
BLE_Mac_Addr_t Mac_Addr;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
*
|
||||
* @return[out]
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
eXC_Cmd_State xc_test_handler(eCMD_Type opt, int srgc, char *srgv[])
|
||||
{
|
||||
eXC_Cmd_State ret = XC_CMD_ERROR;
|
||||
|
||||
switch(opt) {
|
||||
case QUERY_CMD: {
|
||||
ret = XC_CMD_SUCCESS;
|
||||
snprintf((char *)XC_Cmd, XC_CMD_SIZE, "\r\n%s\r\n", XC_OK);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
*
|
||||
* @return[out]
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
eXC_Cmd_State xc_ble_mac_addr_handler(eCMD_Type opt, int srgc, char *srgv[])
|
||||
{
|
||||
eXC_Cmd_State ret = XC_CMD_ERROR;
|
||||
|
||||
switch(opt) {
|
||||
case QUERY_CMD: {
|
||||
ret = XC_CMD_SUCCESS;
|
||||
snprintf((char *)XC_Cmd, XC_CMD_SIZE, "\r\n%s: %02x:%02x:%02x:%02x:%02x:%02x\r\nOK\r\n",
|
||||
XC_CMD_BLE_MAC, Mac_Addr.byte0, Mac_Addr.byte1, Mac_Addr.byte2,
|
||||
Mac_Addr.byte3, Mac_Addr.byte4, Mac_Addr.byte5);
|
||||
}
|
||||
break;
|
||||
|
||||
case SET_CMD: {
|
||||
if(srgc < 1) break;
|
||||
Mac_Addr.byte0 = atoi(srgv[0]);
|
||||
Mac_Addr.byte1 = atoi(srgv[1]);
|
||||
Mac_Addr.byte2 = atoi(srgv[2]);
|
||||
Mac_Addr.byte3 = atoi(srgv[3]);
|
||||
Mac_Addr.byte4 = atoi(srgv[4]);
|
||||
Mac_Addr.byte5 = atoi(srgv[5]);
|
||||
|
||||
ret = XC_CMD_SUCCESS;
|
||||
snprintf((char *)XC_Cmd, XC_CMD_SIZE, "\r\n%s: %02x:%02x:%02x:%02x:%02x:%02x\r\nOK\r\n",
|
||||
XC_CMD_BLE_MAC, Mac_Addr.byte0, Mac_Addr.byte1, Mac_Addr.byte2,
|
||||
Mac_Addr.byte3, Mac_Addr.byte4, Mac_Addr.byte5);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user