diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-11-16 00:18:16 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-11-16 00:18:16 +0000 |
commit | 029f65b7a25c5fa6a4d6162d6fdbc2d7e6dd3400 (patch) | |
tree | 47d8373b2cb580503c7e6f2debca10947baea75e | |
parent | c695bddb45904343b658fc72a16ac8d681346a63 (diff) | |
parent | ce3a405dee2a9f25489e4b20c7ec1f517b1a9ee7 (diff) | |
download | uwb-029f65b7a25c5fa6a4d6162d6fdbc2d7e6dd3400.tar.gz |
Snap for 11104212 from ce3a405dee2a9f25489e4b20c7ec1f517b1a9ee7 to 24Q1-release
Change-Id: I8618b20b439ef23138e84a89fa948f7a9d8d06b7
-rw-r--r-- | extns/inc/uci_defs.h | 8 | ||||
-rw-r--r-- | halimpl/config/README.md | 97 | ||||
-rw-r--r-- | halimpl/fwd/sr1xx/phNxpUciHal_fwd.cc | 116 | ||||
-rw-r--r-- | halimpl/fwd/sr1xx/phNxpUciHal_fwd.h | 3 | ||||
-rw-r--r-- | halimpl/hal/phNxpUciHal.cc | 276 | ||||
-rw-r--r-- | halimpl/hal/phNxpUciHal.h | 18 | ||||
-rw-r--r-- | halimpl/hal/phNxpUciHal_ext.cc | 849 | ||||
-rw-r--r-- | halimpl/hal/phNxpUciHal_ext.h | 10 | ||||
-rw-r--r-- | halimpl/tml/phTmlUwb.h | 2 | ||||
-rw-r--r-- | halimpl/tml/phTmlUwb_spi.cc | 2 | ||||
-rw-r--r-- | halimpl/utils/phNxpConfig.cc | 18 |
11 files changed, 854 insertions, 545 deletions
diff --git a/extns/inc/uci_defs.h b/extns/inc/uci_defs.h index 4b2316c..bb7a3f4 100644 --- a/extns/inc/uci_defs.h +++ b/extns/inc/uci_defs.h @@ -163,20 +163,16 @@ #define UCI_PARAM_ID_AOA_ELEVATION_MEASUREMENTS 0xE4 #define UCI_PARAM_ID_RANGE_MEASUREMENTS 0xE5 -/********************************************** - * UCI Parameter IDs : Calibration Parameters - **********************************************/ -#define UCI_PARAM_ID_RF_CLK_ACCURACY_CALIB 0x01 -#define UCI_PARAM_ID_RX_ANT_DELAY_CALIB 0x02 - /************************************************* * Status codes ************************************************/ /* Generic Status Codes */ #define UCI_STATUS_OK 0x00 +#define UCI_STATUS_FAILED 0x02 #define UCI_STATUS_INVALID_PARAM 0x04 #define UCI_STATUS_INVALID_MSG_SIZE 0x06 #define UCI_STATUS_COMMAND_RETRY 0x0A +#define UCI_STATUS_UNKNOWN 0x0B #define UCI_STATUS_THERMAL_RUNAWAY 0x54 #define UCI_STATUS_HW_RESET 0xFE diff --git a/halimpl/config/README.md b/halimpl/config/README.md index 41d41ed..678a00a 100644 --- a/halimpl/config/README.md +++ b/halimpl/config/README.md @@ -87,26 +87,10 @@ Example: ``` # /vendor/etc/libuwb-nxp.conf: - REGION_MAP_PATH="/vendor/etc/uwb/regions.conf" -``` -``` # /vendor/etc/uwb/regions.conf: - -CE="AT BE BG CH CY CZ DE DK EE ES FI FR GB GR HR HU IE IS IT LI LV LT LU MT NI NL NO PL PT RO SE SK SI" - -# North America FCC="US CA" - -# Restricted -RESTRICTED="AR AM AZ BY ID KZ KG NP PK PY RU SB TJ TM UA UZ" - -# Japan -JP="JP" - -# Taiwan -TW="TW" ``` In the above example, 'US' and 'CA' country codes are grouped into 'FCC' region string. @@ -114,44 +98,97 @@ In the above example, 'US' and 'CA' country codes are grouped into 'FCC' region When the system provides country code with 'US', `EXTRA_CONF_PATH_2=/vendor/etc/uwb/cal-<country>.conf*` will be evaluated as `/vendor/etc/uwb/cal-FCC.conf` instead of `/vendor/etc/uwb/cal-US.conf` and `cal-FCC.conf` will be loaded. #### Parameters -* *cal.rx_antenna_mask*`=<8bit unsigned>` - 1 octect, Antenna IDs defined by the device. b0=Antenna-ID 1, b1=Antenna-ID 2, ... +##### *cal.uwb_disable`=<1|0>`* + +Per-country, Disable UWB RF when it's set to 1. Default is 0. + +##### *cal.rx_antenna_mask*`=<8bit unsigned>`, *cal.tx_antenna_mask*`=<8bit unsigned>` + +1 octect, Antenna IDs defined by the device. b0=Antenna-ID 1, b1=Antenna-ID 2, ... + +e.g. `cal.rx_antenna_mask=0x3` means this paltform has two RX antennas with ID 1 and 2. + +##### *cal.restricted_channels*`=<16bit unsigned>` + +Per country, Restricted channel mask, b0=Channel0, b1=Channel1, ... b15=Channel15. +e.g. `cal.restricted_channels=0x20` to deactivate channel 5. + +##### *cal.otp.xtal*`=<1|0>` + +Load the Crystal calibration value from OTP when it's 1. *cal.xtal* will be ignored. - For example, `cal.rx_antenna_mask=0x3` means this paltform has two RX antennas with ID 1 and 2. +##### *cal.xtal*`=<byte array>` -* *cal.restricted_channels*`=<16bit unsigned>` +6 bytes Crystal calibration values (little endian) - Restrict channel mask, b0=Channel0, b1=Channel1, ... b15=Channel15. e.g. `cal.restricted_channels=0x20` to deactivate channel 5. +- [5:4] : CAP1 +- [3:2] : CAP2 +- [1:0] : GM CURRENT CONTROL -* *cal.otp.xtal*`=<1|0>` +e.g. `cal.xtal={11 00 11 00 3f 00}` - Load the XTAL_CAP_GM_CTRL calibration value from OTP when it's 1. *cal.xtal* will be ignored. +##### *cal.ant`<antenna-id>`.ch`<channel-number>`.ant_delay*`=<16bit unsigned>` -* *cal.xtal*`=<byte array>` +Per-country, RX antenna delay value in Q14.2. e.g. `cal.ant1.ch5.ant_delay=2000` - XTAL_CAP_GM_CTRL value. e.g. `cal.xtal={11 11 3f}` +##### *cal.ant`<antenna-id>`.ch`<channel-number>`.tx_power*`=<byte array>` -* *cal.ant`<antenna-id>`.ch`<channel-number>`.ant_delay*`=<16bit unsigned>` +Per-country, 4 bytes TX Power value. - RX antenna delay value. e.g. `cal.ant1.ch5.ant_delay=2000` +- [3:2] : Delta peak +- [1:0] : ID RMS -* *cal.ant`<antenna-id>`.ch`<channel-number>`.tx_power*`=<byte array>` + e.g. `cal.ant1.ch5.tx_power={01 00 00 00}` - TX Power value. e.g. `cal.ant1.ch5.tx_power={01 00}` +##### *cal.tx_pulse_shape* + +Per-country, Byte array for TX pulse shape data + +##### *cal.ddfs_enable`=<1|0>`* + +Per-country, Enable DDFS tone generation. Default is 0. + +##### *cal.dc_suppress`=<1|0>`* + +Per-country, Enable DC supression. Default is 0. #### Example configuration files ``` # /vendor/etc/libuwb-nxp.conf: +... +REGION_MAP_PATH="/vendor/etc/uwb/regions.conf" + EXTRA_CONF_PATH_1="/vendor/etc/uwb/cal-base.conf" EXTRA_CONF_PATH_2="/vendor/etc/uwb/cal-<country>.conf" EXTRA_CONF_PATH_3="/mnt/vendor/persist/uwb/cal-factory.conf" # /vendor/etc/uwb/cal-base.conf: -cal.rx_antenna_mask=0x01 +cal.rx_antenna_mask=0x03 +cal.tx_antenna_mask=0x01 cal.otp.xtal=1 cal.restricted_channels=0 +# /vendor/etc/uwb/cal-FCC.conf: +cal.restricted_channel=0x0 + # /vendor/etc/uwb/cal-JP.conf: cal.restricted_channel=0x20 +cal.ddfs_enable=1 +cal.ddfs_tone_config={...} + +# /vendor/etc/uwb/cal-KR.conf: +cal.restricted_channel=0x20 + +# /vendor/etc/uwb/cal-TW.conf: +cal.restricted_channel=0x20 + +# /vendor/etc/uwb/cal-RESTRICTED.conf: +cal.uwb_disable=1 +cal.restricted_channels=0xffff + +# /vendor/etc/uwb/regions.conf: +CE="AT BE BG CH CY CZ DE DK EE ES FI FR GB GR HR HU IE IS IT LI LV LT LU MT NI NL NO PL PT RO SE SK SI" +FCC="US CA" +RESTRICTED="AR AM AZ BY ID KZ KG NP PK PY RU SB TJ TM UA UZ" ``` diff --git a/halimpl/fwd/sr1xx/phNxpUciHal_fwd.cc b/halimpl/fwd/sr1xx/phNxpUciHal_fwd.cc index 11d12b7..b955a44 100644 --- a/halimpl/fwd/sr1xx/phNxpUciHal_fwd.cc +++ b/halimpl/fwd/sr1xx/phNxpUciHal_fwd.cc @@ -18,35 +18,30 @@ /*************************************************************************************/ /* INCLUDES */ /*************************************************************************************/ +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> -#include <unistd.h> -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> #include <sys/ioctl.h> -#include <unistd.h> -#include <string.h> + #include <string> -#include "phNxpLog.h" -#include <cstring> -#include <iostream> -#include <sstream> -#include <phTmlUwb_spi.h> + +#include "phNxpConfig.h" +#include "phNxpLog.h" #include "phNxpUciHal_fwd.h" #include <phNxpUciHal_utils.h> -#include "phNxpConfig.h" +#include <phTmlUwb_spi.h> + using namespace std; #define FILEPATH_MAXLEN 500 static uint8_t chip_id = 0x00; static uint8_t deviceLcInfo = 0x00; static uint8_t is_fw_download_log_enabled = 0x00; -const char* default_prod_fw = "libsr100t_prod_fw.bin"; -const char* default_dev_fw = "libsr100t_dev_fw.bin"; +static const char* default_prod_fw = "libsr100t_prod_fw.bin"; +static const char* default_dev_fw = "libsr100t_dev_fw.bin"; +static const char* default_fw_dir = "/vendor/firmware/uwb/"; +static string default_fw_path; -char* configured_fw_name = NULL; -char default_fw_path[FILEPATH_MAXLEN] = "/vendor/firmware/uwb/"; /*************************************************************************************/ /* LOCAL FUNCTIONS */ /*************************************************************************************/ @@ -61,53 +56,40 @@ static void setOpts(void) gOpts.fMosi = NULL; gOpts.misoFile = (char*)"Miso.bin"; gOpts.fMiso = NULL; - - gPasswd = FALSE; - gImg = FALSE; } -static int init(void) { - const uint16_t fw_max_len = 260; - configured_fw_name = (char*)malloc(fw_max_len * sizeof(char)); +static int init(void) +{ const char *pDefaultFwFileName = NULL; - int maxSrcLen = (FILEPATH_MAXLEN-strlen(default_fw_path)) - 1; - if (configured_fw_name == NULL) { - ALOGD("malloc of configured_fw_name failed "); - return 1; - } + char configured_fw_name[FILEPATH_MAXLEN]; + default_fw_path = default_fw_dir; + if((deviceLcInfo == PHHBCI_HELIOS_PROD_KEY_1) || (deviceLcInfo == PHHBCI_HELIOS_PROD_KEY_2)) { pDefaultFwFileName = default_prod_fw; - if (!NxpConfig_GetStr(NAME_NXP_UWB_PROD_FW_FILENAME, configured_fw_name, fw_max_len)) { + if (!NxpConfig_GetStr(NAME_NXP_UWB_PROD_FW_FILENAME, configured_fw_name, sizeof(configured_fw_name))) { ALOGD("Invalid Prod Fw name keeping the default name: %s", pDefaultFwFileName); - strncat(default_fw_path, pDefaultFwFileName, maxSrcLen); + default_fw_path += pDefaultFwFileName; } else{ ALOGD("configured_fw_name : %s", configured_fw_name); - strncat(default_fw_path, configured_fw_name, maxSrcLen); + default_fw_path += configured_fw_name; } } else if (deviceLcInfo == PHHBCI_HELIOS_DEV_KEY) { pDefaultFwFileName = default_dev_fw; - if (!NxpConfig_GetStr(NAME_NXP_UWB_DEV_FW_FILENAME, configured_fw_name, fw_max_len)) { + if (!NxpConfig_GetStr(NAME_NXP_UWB_DEV_FW_FILENAME, configured_fw_name, sizeof(configured_fw_name))) { ALOGD("Invalid Dev Fw name keeping the default name: %s", pDefaultFwFileName); - strncat(default_fw_path, pDefaultFwFileName, maxSrcLen); + default_fw_path += pDefaultFwFileName; } else{ ALOGD("configured_fw_name : %s", configured_fw_name); - strncat(default_fw_path, configured_fw_name, maxSrcLen); + default_fw_path += configured_fw_name; } } else { ALOGD("Invalid DeviceLCInfo : 0x%x\n", deviceLcInfo); return 1; } - ALOGD("Referring FW path..........: %s", default_fw_path); - if (gImg && (NULL == (gOpts.fImg = fopen(default_fw_path, "rb")))) { - ALOGD("ERROR: Cannot open %s file for reading!\n", gOpts.imgFile); - return 1; - } else { - ALOGD("FW FILE OPEN SUCCESS....\n"); - gImg = true; - // gOpts.capture = Capture_Apdu_With_Dummy_Miso; - } + ALOGD("Referring FW path..........: %s", default_fw_path.c_str()); + // gOpts.capture = Capture_Apdu_With_Dummy_Miso; if (Capture_Off != gOpts.capture) { ALOGD("Not Capture_Off.....\n"); @@ -132,11 +114,7 @@ static int init(void) { static void cleanup(void) { ioctl((intptr_t)tPalConfig.pDevHandle, SRXXX_SET_FWD, 0); - if(configured_fw_name !=NULL){ - free(configured_fw_name); - memset(default_fw_path, '\0', sizeof(char)*256); - strcpy(default_fw_path, "/vendor/firmware/uwb/"); - } + if (NULL != gOpts.fImg) { fclose(gOpts.fImg); @@ -939,8 +917,9 @@ phHbci_Status_t phHbci_GetDeviceLcInfo(){ * update the acutual state of operation in arg pointer * ******************************************************************************/ -int phNxpUciHal_fw_download() { - uint8_t *pImg = gphHbci_ImgHelios; +int phNxpUciHal_fw_download() +{ + uint8_t pImg[256 * 1024] __attribute__((aligned(4))); uint32_t imgSz=0, maxSz, err = 0; unsigned long num = 0; phHbci_General_Command_t cmd; @@ -993,29 +972,27 @@ int phNxpUciHal_fw_download() { ALOGD("ERROR: Undefined Master Mode = %u\n", gOpts.mode); return 1; } - if (gImg) - { - if(gOpts.fImg == NULL) { - gOpts.fImg = fopen(default_fw_path, "rb"); - } - if(gOpts.fImg == NULL) { - ALOGD("Firmware file does not exist:"); - return phHbci_File_Not_found; - } - fseek(gOpts.fImg, 0, SEEK_END); - imgSz = (uint32_t)ftell(gOpts.fImg); - ALOGD("FWD file size ftell returns: %d\n",imgSz); - if (!imgSz || (maxSz < imgSz)) - { - ALOGD("ERROR: %s image size (%d) not supported!\n", gOpts.imgFile, imgSz); - cleanup(); - return 1; - } - rewind(gOpts.fImg); + if(gOpts.fImg == NULL) { + gOpts.fImg = fopen(default_fw_path.c_str(), "rb"); + } + if(gOpts.fImg == NULL) { + ALOGD("Firmware file does not exist:"); + return phHbci_File_Not_found; + } + fseek(gOpts.fImg, 0, SEEK_END); + imgSz = (uint32_t)ftell(gOpts.fImg); + ALOGD("FWD file size ftell returns: %d\n",imgSz); + if (!imgSz || (maxSz < imgSz) || (sizeof(pImg) < imgSz)) + { + ALOGD("ERROR: %s image size (%d) not supported!\n", gOpts.imgFile, imgSz); + cleanup(); + return 1; } + rewind(gOpts.fImg); + ALOGD("FWD file size: %d\n",imgSz); - if (!gImg || (imgSz == fread(pImg, sizeof(uint8_t), imgSz, gOpts.fImg))) + if (imgSz == fread(pImg, sizeof(uint8_t), imgSz, gOpts.fImg)) { if(cmd == phHbci_General_Cmd_Mode_HIF_Image) { ALOGD("HIF Image mode.\n"); @@ -1035,7 +1012,6 @@ int phNxpUciHal_fw_download() { cleanup(); return err; - } void setDeviceHandle(void* pDevHandle) diff --git a/halimpl/fwd/sr1xx/phNxpUciHal_fwd.h b/halimpl/fwd/sr1xx/phNxpUciHal_fwd.h index effdb04..fa2c25e 100644 --- a/halimpl/fwd/sr1xx/phNxpUciHal_fwd.h +++ b/halimpl/fwd/sr1xx/phNxpUciHal_fwd.h @@ -397,11 +397,8 @@ phHbci_MisoApdu_t gphHbci_MisoApdu; phPalSr100_Config_t tPalConfig; Options_t gOpts; -bool gPasswd, gImg; uint8_t gDummyMiso[PHHBCI_MAX_LEN_PAYLOAD_MISO]; -static uint8_t gphHbci_ImgHelios[256 * 1024] __attribute__((aligned(4))); - phHbci_Status_t phHbci_GetStatus(void); phHbci_Status_t phHbci_GeneralStatus(phHbci_General_Command_t mode); phHbci_Status_t phHbci_QueryInfo(uint8_t* pInfo, uint32_t* pInfoSz, diff --git a/halimpl/hal/phNxpUciHal.cc b/halimpl/hal/phNxpUciHal.cc index 438d893..428030f 100644 --- a/halimpl/hal/phNxpUciHal.cc +++ b/halimpl/hal/phNxpUciHal.cc @@ -54,10 +54,7 @@ bool uwb_get_platform_id = false; uint32_t timeoutTimerId = 0; char persistant_log_path[120]; static uint8_t Rx_data[UCI_MAX_DATA_LEN]; -uint8_t channel_5_support = 1; -uint8_t channel_9_support = 1; -short conf_tx_power = 0; -bool uwb_enable = true; + /* AOA support handling */ bool isAntennaRxPairDefined = false; int numberOfAntennaPairs = 0; @@ -71,8 +68,6 @@ static void phNxpUciHal_kill_client_thread( phNxpUciHal_Control_t* p_nxpucihal_ctrl); static void* phNxpUciHal_client_thread(void* arg); extern int phNxpUciHal_fw_download(); -static void phNxpUciHal_print_response_status(uint8_t *p_rx_data, - uint16_t p_len); static void phNxpUciHal_getVersionInfo(); /****************************************************************************** @@ -277,16 +272,14 @@ bool isCountryCodeMapCreated = false; * Returns It returns true if the incoming command to be skipped. * ******************************************************************************/ -bool phNxpUciHal_parse(uint16_t data_len, const uint8_t *p_data) { - uint8_t mt = 0, gid = 0, oid = 0; - uint16_t arrLen = 0, tag = 0, idx = 0; +bool phNxpUciHal_parse(uint16_t data_len, const uint8_t *p_data) +{ bool ret = false; + const phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings; - map<uint16_t, vector<uint16_t>>::iterator itr; - vector<uint16_t>::iterator v_itr; - mt = (*(p_data)&UCI_MT_MASK) >> UCI_MT_SHIFT; - gid = p_data[0] & UCI_GID_MASK; - oid = p_data[1] & UCI_OID_MASK; + const uint8_t mt = (p_data[0] &UCI_MT_MASK) >> UCI_MT_SHIFT; + const uint8_t gid = p_data[0] & UCI_GID_MASK; + const uint8_t oid = p_data[1] & UCI_OID_MASK; if (mt == UCI_MT_CMD) { if ((gid == UCI_GID_ANDROID) && (oid == UCI_MSG_ANDROID_SET_COUNTRY_CODE)) { @@ -300,68 +293,49 @@ bool phNxpUciHal_parse(uint16_t data_len, const uint8_t *p_data) { if ((country_code[0] == '0') && (country_code[1] == '0')) { NXPLOG_UCIHAL_D("Country code %c%c is Invalid!", country_code[0], country_code[1]); } else { - NxpConfig_SetCountryCode(country_code); + phNxpUciHal_handle_set_country_code(country_code); } // send country code response to upper layer nxpucihal_ctrl.rx_data_len = 5; - static uint8_t rsp_data[5]; - rsp_data[0] = 0x4c; - rsp_data[1] = 0x01; - rsp_data[2] = 0x00; - rsp_data[3] = 0x01; - if (uwb_enable) { + static uint8_t rsp_data[5] = { 0x4c, 0x01, 0x00, 0x01 }; + if (rt_set->uwb_enable) { rsp_data[4] = 0x00; // Response Success } else { - NXPLOG_UCIHAL_D("Country code uwb disable " - "UCI_STATUS_CODE_ANDROID_REGULATION_UWB_OFF!"); + NXPLOG_UCIHAL_D("Country code uwb disable UCI_STATUS_CODE_ANDROID_REGULATION_UWB_OFF!"); rsp_data[4] = UCI_STATUS_CODE_ANDROID_REGULATION_UWB_OFF; } ret = true; (*nxpucihal_ctrl.p_uwb_stack_data_cback)(nxpucihal_ctrl.rx_data_len, rsp_data); - } else if ((gid == UCI_GID_PROPRIETARY_0x0F) && - (oid == SET_VENDOR_SET_CALIBRATION)) { + } else if ((gid == UCI_GID_PROPRIETARY_0x0F) && (oid == SET_VENDOR_SET_CALIBRATION)) { if (p_data[UCI_MSG_HDR_SIZE + 1] == VENDOR_CALIB_PARAM_TX_POWER_PER_ANTENNA) { - phNxpUciHal_processCalibParamTxPowerPerAntenna(conf_tx_power, p_data, - data_len); + phNxpUciHal_processCalibParamTxPowerPerAntenna(p_data, data_len); } - } else if ((gid == UCI_GID_SESSION_MANAGE) && - (oid == UCI_MSG_SESSION_SET_APP_CONFIG)) { - uint8_t index = - 4 /*UCI_MSG_HDR_SIZE*/ + 4 /*Session_Id*/ + 1 /*Num of configs*/; - uint8_t len = p_data[UCI_MSG_HDR_SIZE - 1]; - len = len + UCI_MSG_HDR_SIZE; // length should be size of payload + size - // of header - uint8_t tagId, length, channel_number, no_of_config; - no_of_config = p_data[8]; + } else if ((gid == UCI_GID_SESSION_MANAGE) && (oid == UCI_MSG_SESSION_SET_APP_CONFIG)) { + uint8_t len = p_data[UCI_MSG_HDR_SIZE - 1] + UCI_MSG_HDR_SIZE; + uint8_t index = 9; // Header 4 + SessionID 4 + NumOfConfigs 1 + uint8_t tagId, length, ch; while (index < len) { tagId = p_data[index++]; length = p_data[index++]; - if (tagId == UCI_PARAM_ID_CHANNEL_NUMBER) { - channel_number = p_data[index]; + if (tagId == UCI_PARAM_ID_CHANNEL_NUMBER) { + ch = p_data[index]; - if (((channel_number == CHANNEL_NUM_5) && !channel_5_support) || - ((channel_number == CHANNEL_NUM_9) && !channel_9_support)) { - NXPLOG_UCIHAL_D("Country code blocked channel"); + if (((ch == CHANNEL_NUM_5) && (rt_set->restricted_channel_mask & (1 << 5))) || + ((ch == CHANNEL_NUM_9) && (rt_set->restricted_channel_mask & (1 << 9)))) { + NXPLOG_UCIHAL_D("Country code blocked channel %u", ch); // send setAppConfig response with COUNTRY_CODE_BLOCKED response - nxpucihal_ctrl.rx_data_len = 8; - static uint8_t rsp_data[8]; - rsp_data[0] = 0x41; - rsp_data[1] = 0x03; - rsp_data[2] = 0x00; - rsp_data[3] = 0x04; // Length - rsp_data[4] = 0x02; - rsp_data[5] = 0x01; - rsp_data[6] = 0x04; - rsp_data[7] = UCI_STATUS_COUNTRY_CODE_BLOCKED_CHANNEL; + static uint8_t rsp_data[] = { 0x41, 0x03, 0x04, 0x04, + UCI_STATUS_FAILED, 0x01, UCI_STATUS_INVALID_PARAM, UCI_STATUS_COUNTRY_CODE_BLOCKED_CHANNEL + }; + nxpucihal_ctrl.rx_data_len = sizeof(rsp_data); ret = true; - (*nxpucihal_ctrl.p_uwb_stack_data_cback)( - nxpucihal_ctrl.rx_data_len, rsp_data); + (*nxpucihal_ctrl.p_uwb_stack_data_cback)(nxpucihal_ctrl.rx_data_len, rsp_data); break; } } @@ -370,6 +344,10 @@ bool phNxpUciHal_parse(uint16_t data_len, const uint8_t *p_data) { } } else if (mt == UCI_MT_RSP) { if ((gid == UCI_GID_CORE) && (oid == UCI_MSG_CORE_GET_CAPS_INFO)) { + map<uint16_t, vector<uint16_t>>::iterator itr; + vector<uint16_t>::iterator v_itr; + uint16_t arrLen, tag, idx; + // do not modify caps if the country code is not received from upper // layer. if (isCountryCodeMapCreated == false) { @@ -481,12 +459,11 @@ static void phNxpUciHal_kill_client_thread( * In case of failure returns other failure value. * ******************************************************************************/ -tHAL_UWB_STATUS phNxpUciHal_open(uwb_stack_callback_t* p_cback, - uwb_stack_data_callback_t* p_data_cback) { +tHAL_UWB_STATUS phNxpUciHal_open(uwb_stack_callback_t* p_cback, uwb_stack_data_callback_t* p_data_cback) +{ + static const char uwb_dev_node[256] = "/dev/srxxx"; phOsalUwb_Config_t tOsalConfig; phTmlUwb_Config_t tTmlConfig; - char* uwb_dev_node = NULL; - const uint16_t max_len = 260; tHAL_UWB_STATUS wConfigStatus = UWBSTATUS_SUCCESS; pthread_attr_t attr; @@ -512,14 +489,7 @@ tHAL_UWB_STATUS phNxpUciHal_open(uwb_stack_callback_t* p_cback, memset(&nxpucihal_ctrl, 0x00, sizeof(nxpucihal_ctrl)); memset(&tOsalConfig, 0x00, sizeof(tOsalConfig)); memset(&tTmlConfig, 0x00, sizeof(tTmlConfig)); - uwb_dev_node = (char*)nxp_malloc(max_len * sizeof(char)); - if (uwb_dev_node == NULL) { - NXPLOG_UCIHAL_E("malloc of uwb_dev_node failed "); - goto clean_and_return; - } else { - NXPLOG_UCIHAL_E("Assigning the default helios Node: dev/srxxx"); - strcpy(uwb_dev_node, "/dev/srxxx"); - } + NXPLOG_UCIHAL_E("Assigning the default helios Node: %s", uwb_dev_node); /* By default HAL status is HAL_STATUS_OPEN */ nxpucihal_ctrl.halStatus = HAL_STATUS_OPEN; @@ -530,7 +500,7 @@ tHAL_UWB_STATUS phNxpUciHal_open(uwb_stack_callback_t* p_cback, /* Configure hardware link */ nxpucihal_ctrl.gDrvCfg.nClientId = phDal4Uwb_msgget(0, 0600); nxpucihal_ctrl.gDrvCfg.nLinkType = ENUM_LINK_TYPE_SPI; - tTmlConfig.pDevName = (int8_t*)uwb_dev_node; + tTmlConfig.pDevName = uwb_dev_node; tOsalConfig.dwCallbackThreadId = (uintptr_t)nxpucihal_ctrl.gDrvCfg.nClientId; tOsalConfig.pLogFile = NULL; tTmlConfig.dwGetMsgThreadId = (uintptr_t)nxpucihal_ctrl.gDrvCfg.nClientId; @@ -540,11 +510,6 @@ tHAL_UWB_STATUS phNxpUciHal_open(uwb_stack_callback_t* p_cback, if (wConfigStatus != UWBSTATUS_SUCCESS) { NXPLOG_UCIHAL_E("phTmlUwb_Init Failed"); goto clean_and_return; - } else { - if (uwb_dev_node != NULL) { - free(uwb_dev_node); - uwb_dev_node = NULL; - } } /* Create the client thread */ @@ -578,10 +543,6 @@ tHAL_UWB_STATUS phNxpUciHal_open(uwb_stack_callback_t* p_cback, clean_and_return: CONCURRENCY_UNLOCK(); - if (uwb_dev_node != NULL) { - free(uwb_dev_node); - uwb_dev_node = NULL; - } /* Report error status */ (*nxpucihal_ctrl.p_uwb_stack_cback)(HAL_UWB_OPEN_CPLT_EVT, HAL_UWB_ERROR_EVT); @@ -886,9 +847,11 @@ void phNxpUciHal_read_complete(void* pContext, tHAL_UWB_STATUS status; uint8_t gid = 0, oid = 0, pbf = 0, mt = 0; UNUSED(pContext); + if (nxpucihal_ctrl.read_retry_cnt == 1) { nxpucihal_ctrl.read_retry_cnt = 0; } + if (pInfo->wStatus == UWBSTATUS_SUCCESS) { NXPLOG_UCIHAL_D("read successful status = 0x%x", pInfo->wStatus); nxpucihal_ctrl.p_rx_data = pInfo->pBuff; @@ -903,12 +866,18 @@ void phNxpUciHal_read_complete(void* pContext, phNxpUciHal_parse_get_capsInfo(nxpucihal_ctrl.rx_data_len, nxpucihal_ctrl.p_rx_data); } + nxpucihal_ctrl.isSkipPacket = 0; + phNxpUciHal_parse(nxpucihal_ctrl.rx_data_len, nxpucihal_ctrl.p_rx_data); phNxpUciHal_process_response(); if(!uwb_device_initialized) { + if (pbf) { + /* XXX: fix the whole logic if this really happens */ + NXPLOG_UCIHAL_E("FIXME: Fragmented packets received during device-init!"); + } if((gid == UCI_GID_CORE) && (oid == UCI_MSG_CORE_DEVICE_STATUS_NTF)) { nxpucihal_ctrl.uwbc_device_state = nxpucihal_ctrl.p_rx_data[UCI_RESPONSE_STATUS_OFFSET]; if(nxpucihal_ctrl.uwbc_device_state == UWB_DEVICE_INIT || nxpucihal_ctrl.uwbc_device_state == UWB_DEVICE_READY) { @@ -947,86 +916,95 @@ void phNxpUciHal_read_complete(void* pContext, } } - if (nxpucihal_ctrl.isSkipPacket == 0) { - if((nxpucihal_ctrl.p_rx_data[0x00] & 0xF0) == 0x40){ - if (nxpucihal_ctrl.hal_ext_enabled) { + // phNxpUciHal_process_ext_cmd_rsp() is waiting for the response packet + // set this true to wake it up for other reasons + bool bWakeupExtCmd = (mt == UCI_MT_RSP); + + /* DBG packets not yet supported, just ignore them silently */ + if (!nxpucihal_ctrl.isSkipPacket) { + if ((mt == UCI_MT_NTF) && (gid == UCI_GID_INTERNAL) && + (oid == UCI_EXT_PARAM_DBG_RFRAME_LOG_NTF)) { + nxpucihal_ctrl.isSkipPacket = 1; + } + } + + // Handle retransmissions + if (!nxpucihal_ctrl.isSkipPacket) { + if (!pbf && mt == UCI_MT_NTF && gid == UCI_GID_CORE && oid == UCI_MSG_CORE_GENERIC_ERROR_NTF) { + uint8_t status_code = nxpucihal_ctrl.p_rx_data[UCI_RESPONSE_STATUS_OFFSET]; + + if (status_code == UCI_STATUS_COMMAND_RETRY) { + nxpucihal_ctrl.ext_cb_data.status = UWBSTATUS_COMMAND_RETRANSMIT; + nxpucihal_ctrl.isSkipPacket = 1; + bWakeupExtCmd = true; + } else if (status_code == UCI_STATUS_INVALID_MSG_SIZE) { + nxpucihal_ctrl.ext_cb_data.status = UWBSTATUS_INVALID_COMMAND_LENGTH; nxpucihal_ctrl.isSkipPacket = 1; + bWakeupExtCmd = true; } - if(nxpucihal_ctrl.p_rx_data[UCI_RESPONSE_STATUS_OFFSET] == UCI_STATUS_OK){ - nxpucihal_ctrl.ext_cb_data.status = UWBSTATUS_SUCCESS; - } else if ((gid == UCI_GID_CORE) && (oid == UCI_MSG_CORE_SET_CONFIG)){ - NXPLOG_UCIHAL_E(" status = 0x%x",nxpucihal_ctrl.p_rx_data[UCI_RESPONSE_STATUS_OFFSET]); - /* check if any configurations are not supported then ignore the - * UWBSTATUS_FEATURE_NOT_SUPPORTED status code*/ - nxpucihal_ctrl.ext_cb_data.status = phNxpUciHal_process_ext_rsp(nxpucihal_ctrl.rx_data_len, nxpucihal_ctrl.p_rx_data); - } else { - if (gid == UCI_GID_SESSION_MANAGE && - oid == UCI_MSG_SESSION_QUERY_DATA_SIZE) { - nxpucihal_ctrl.ext_cb_data.status = - nxpucihal_ctrl - .p_rx_data[UCI_MSG_SESSION_QUERY_DATA_SIZE_STATUS_OFFSET]; + } + } + + // Check status code only for extension commands + if (!nxpucihal_ctrl.isSkipPacket) { + if (mt == UCI_MT_RSP) { + if (nxpucihal_ctrl.hal_ext_enabled) { + nxpucihal_ctrl.isSkipPacket = 1; + + if (pbf) { + /* XXX: fix the whole logic if this really happens */ + NXPLOG_UCIHAL_E("FIXME: Fragmented packets received while processing internal commands!"); + } + + uint8_t status_code = (nxpucihal_ctrl.rx_data_len > UCI_RESPONSE_STATUS_OFFSET) ? + nxpucihal_ctrl.p_rx_data[UCI_RESPONSE_STATUS_OFFSET] : UCI_STATUS_UNKNOWN; + + if (status_code == UCI_STATUS_OK) { + nxpucihal_ctrl.ext_cb_data.status = UWBSTATUS_SUCCESS; + } else if ((gid == UCI_GID_CORE) && (oid == UCI_MSG_CORE_SET_CONFIG)){ + /* check if any configurations are not supported then ignore the + * UWBSTATUS_FEATURE_NOT_SUPPORTED status code*/ + nxpucihal_ctrl.ext_cb_data.status = phNxpUciHal_process_ext_rsp(nxpucihal_ctrl.rx_data_len, nxpucihal_ctrl.p_rx_data); } else { nxpucihal_ctrl.ext_cb_data.status = UWBSTATUS_FAILED; - NXPLOG_UCIHAL_E( - "command failed! status = 0x%x", - nxpucihal_ctrl.p_rx_data[UCI_RESPONSE_STATUS_OFFSET]); + NXPLOG_UCIHAL_E("Got error status code(0x%x) from internal command.", status_code); + usleep(1); // XXX: not sure if it's really needed } } - usleep(1); - SEM_POST(&(nxpucihal_ctrl.ext_cb_data)); - } else if (gid == UCI_GID_CORE && oid == UCI_MSG_CORE_GENERIC_ERROR_NTF && - nxpucihal_ctrl.p_rx_data[4] == UCI_STATUS_COMMAND_RETRY) { - if (nxpucihal_ctrl.hal_ext_enabled) { - nxpucihal_ctrl.ext_cb_data.status = UWBSTATUS_COMMAND_RETRANSMIT; - } - SEM_POST(&(nxpucihal_ctrl.ext_cb_data)); - } else if (gid == UCI_GID_CORE && oid == UCI_MSG_CORE_GENERIC_ERROR_NTF && - nxpucihal_ctrl.p_rx_data[4] == UCI_STATUS_INVALID_MSG_SIZE) { - if (nxpucihal_ctrl.hal_ext_enabled) { - nxpucihal_ctrl.ext_cb_data.status = UWBSTATUS_INVALID_COMMAND_LENGTH; - nxpucihal_ctrl.isSkipPacket = 1; - } - SEM_POST(&(nxpucihal_ctrl.ext_cb_data)); } - } else if (nxpucihal_ctrl.hal_ext_enabled == 0) { - SEM_POST(&(nxpucihal_ctrl.ext_cb_data)); } - if ((mt == UCI_MT_NTF) && (gid == UCI_GID_INTERNAL) && - (oid == UCI_EXT_PARAM_DBG_RFRAME_LOG_NTF)) { - nxpucihal_ctrl.isSkipPacket = 1; + + if (bWakeupExtCmd && nxpucihal_ctrl.ext_cb_waiting) { + SEM_POST(&(nxpucihal_ctrl.ext_cb_data)); } - /* if Debug Notification, then skip sending to application */ - if(nxpucihal_ctrl.isSkipPacket == 0) { - phNxpUciHal_print_response_status(nxpucihal_ctrl.p_rx_data, nxpucihal_ctrl.rx_data_len); + if (!nxpucihal_ctrl.isSkipPacket) { /* Read successful, send the event to higher layer */ - if ((nxpucihal_ctrl.p_uwb_stack_data_cback != NULL) && (nxpucihal_ctrl.rx_data_len <= UCI_MAX_PAYLOAD_LEN)) { - (*nxpucihal_ctrl.p_uwb_stack_data_cback)(nxpucihal_ctrl.rx_data_len, - nxpucihal_ctrl.p_rx_data); - } + if ((nxpucihal_ctrl.p_uwb_stack_data_cback != NULL) && (nxpucihal_ctrl.rx_data_len <= UCI_MAX_PAYLOAD_LEN)) { + (*nxpucihal_ctrl.p_uwb_stack_data_cback)(nxpucihal_ctrl.rx_data_len, nxpucihal_ctrl.p_rx_data); + } } - } else { + } else { // pInfo->wStatus != UWBSTATUS_SUCCESS NXPLOG_UCIHAL_E("read error status = 0x%x", pInfo->wStatus); } - if (nxpucihal_ctrl.halStatus == HAL_STATUS_CLOSE) { - return; - } /* Disable junk data check for each UCI packet*/ if(nxpucihal_ctrl.fw_dwnld_mode) { if((gid == UCI_GID_CORE) && (oid == UCI_MSG_CORE_DEVICE_STATUS_NTF)){ nxpucihal_ctrl.fw_dwnld_mode = false; } } + /* Read again because read must be pending always.*/ - status = phTmlUwb_Read( - Rx_data, UCI_MAX_DATA_LEN, - (pphTmlUwb_TransactCompletionCb_t)&phNxpUciHal_read_complete, NULL); - if (status != UWBSTATUS_PENDING) { - NXPLOG_UCIHAL_E("read status error status = %x", status); - /* TODO: Not sure how to handle this ? */ + if (nxpucihal_ctrl.halStatus != HAL_STATUS_CLOSE) { + status = phTmlUwb_Read( + Rx_data, UCI_MAX_DATA_LEN, + (pphTmlUwb_TransactCompletionCb_t)&phNxpUciHal_read_complete, NULL); + if (status != UWBSTATUS_PENDING) { + NXPLOG_UCIHAL_E("read status error status = %x", status); + /* TODO: Not sure how to handle this ? */ + } } - return; } /****************************************************************************** @@ -1734,40 +1712,6 @@ tHAL_UWB_STATUS phNxpUciHal_sessionInitialization(uint32_t sessionId) { } /****************************************************************************** - * Function phNxpUciHal_print_response_status - * - * Description This function logs the response status - * - * Returns status - * - ******************************************************************************/ -static void phNxpUciHal_print_response_status(uint8_t* p_rx_data, uint16_t p_len) { - uint8_t mt; - int status_byte; - const uint8_t response_buf[][30] = {"STATUS_OK", - "STATUS_REJECTED", - "STATUS_FAILED", - "STATUS_SYNTAX_ERROR", - "STATUS_INVALID_PARAM", - "STATUS_INVALID_RANGE", - "STATUS_INAVALID_MSG_SIZE", - "STATUS_UNKNOWN_GID", - "STATUS_UNKNOWN_OID", - "STATUS_RFU", - "STATUS_READ_ONLY", - "STATUS_COMMAND_RETRY", - "STATUS_UNKNOWN"}; - if(p_len > UCI_PKT_HDR_LEN) { - mt = ((p_rx_data[0]) & UCI_MT_MASK) >> UCI_MT_SHIFT; - status_byte = p_rx_data[UCI_RESPONSE_STATUS_OFFSET]; - if((mt == UCI_MT_RSP) && (status_byte <= MAX_RESPONSE_STATUS)) { - NXPLOG_UCIHAL_D(" %s: Response Status = %s", __func__, - response_buf[status_byte]); - } - } -} - -/****************************************************************************** * Function phNxpUciHal_GetMwVersion * * Description This function gets the middleware version diff --git a/halimpl/hal/phNxpUciHal.h b/halimpl/hal/phNxpUciHal.h index 2ae77d0..7297032 100644 --- a/halimpl/hal/phNxpUciHal.h +++ b/halimpl/hal/phNxpUciHal.h @@ -155,6 +155,12 @@ typedef struct { uint8_t rc_version; /* patch */ } phNxpUciHal_FW_Version_t; +typedef struct { + uint16_t restricted_channel_mask; + bool uwb_enable; + short tx_power_offset; // From UWB_COUNTRY_CODE_CAPS +} phNxpUciHal_Runtime_Settings_t; + /* UCI Control structure */ typedef struct phNxpUciHal_Control { phNxpUci_HalStatus halStatus; /* Indicate if hal is open or closed */ @@ -180,6 +186,10 @@ typedef struct phNxpUciHal_Control { /* Waiting semaphore */ phNxpUciHal_Sem_t ext_cb_data; + // in case of fragmented response, + // ext_cb_data is flagged only from the 1st response packet + bool ext_cb_waiting; + phNxpUciHal_Sem_t dev_status_ntf_wait; phNxpUciHal_Sem_t uwb_binding_status_ntf_wait; phNxpUciHal_Sem_t uwb_get_binding_status_ntf_wait; @@ -211,6 +221,14 @@ typedef struct phNxpUciHal_Control { uint8_t uwb_binding_count; uint8_t uwbc_device_state; uint8_t dev_state_ntf_wait; + + // Per-country settings + phNxpUciHal_Runtime_Settings_t rt_settings; + + // Extra calibration + // Antenna Definitions for extra calibration, b0=Antenna1, b1=Antenna2, ... + uint8_t cal_rx_antenna_mask; + uint8_t cal_tx_antenna_mask; } phNxpUciHal_Control_t; /* Internal messages to handle callbacks */ diff --git a/halimpl/hal/phNxpUciHal_ext.cc b/halimpl/hal/phNxpUciHal_ext.cc index af82a9b..5a312b3 100644 --- a/halimpl/hal/phNxpUciHal_ext.cc +++ b/halimpl/hal/phNxpUciHal_ext.cc @@ -39,12 +39,11 @@ extern phNxpUciHal_Control_t nxpucihal_ctrl; extern uint32_t cleanup_timer; extern bool uwb_debug_enabled; extern uint32_t timeoutTimerId; -extern uint8_t channel_5_support; -extern uint8_t channel_9_support; extern short conf_tx_power; -extern bool uwb_enable; -uint8_t *gtx_power = NULL, *gRMS_tx_power = NULL; -uint8_t gtx_power_length = 0; + +static std::vector<uint8_t> gtx_power; +static std::vector<uint8_t> gRMS_tx_power; + phNxpUciHalProp_Control_t extNxpucihal_ctrl; uint32_t hwResetTimer; @@ -85,8 +84,12 @@ tHAL_UWB_STATUS phNxpUciHal_process_ext_cmd_rsp(uint16_t cmd_len, /* Send ext command */ do { NXPLOG_UCIHAL_D("Entered do while loop"); + nxpucihal_ctrl.ext_cb_data.status = UWBSTATUS_SUCCESS; + nxpucihal_ctrl.ext_cb_waiting = true; + *data_written = phNxpUciHal_write_unlocked(cmd_len, p_cmd); + if (*data_written != cmd_len) { NXPLOG_UCIHAL_D("phNxpUciHal_write failed for hal ext"); goto clean_and_return; @@ -120,6 +123,7 @@ tHAL_UWB_STATUS phNxpUciHal_process_ext_cmd_rsp(uint16_t cmd_len, NXPLOG_UCIHAL_E("p_hal_ext->ext_cb_data.sem semaphore error"); goto clean_and_return; } + nxpucihal_ctrl.ext_cb_waiting = false; switch (nxpucihal_ctrl.ext_cb_data.status) { case UWBSTATUS_RESPONSE_TIMEOUT: @@ -127,6 +131,7 @@ tHAL_UWB_STATUS phNxpUciHal_process_ext_cmd_rsp(uint16_t cmd_len, ext_cmd_retry_cnt++; break; case UWBSTATUS_INVALID_COMMAND_LENGTH: + // XXX: Why retrying here? invalid_len_retry_cnt++; break; default: @@ -323,23 +328,25 @@ tHAL_UWB_STATUS phNxpUciHal_process_ext_rsp(uint16_t rsp_len, uint8_t* p_buff){ return status; } +static bool phNxpUciHal_setCalibParamTxPower(void); + /******************************************************************************* - * Function phNxpUciHal_reset_country_code_config + * Function phNxpUciHal_resetRuntimeSettings * - * Description Reset the country code config - * - * Returns void + * Description reset per-country code settigs to default * *******************************************************************************/ -void phNxpUciHal_reset_country_code_config() { - uwb_enable = true; - channel_5_support = 1; - channel_9_support = 1; - conf_tx_power = 0; +static void phNxpUciHal_resetRuntimeSettings(void) +{ + phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings; + rt_set->uwb_enable = true; + rt_set->restricted_channel_mask = 0; + rt_set->tx_power_offset = 0; + } /******************************************************************************* - * Function phNxpUciHal_getCountryCaps + * Function phNxpUciHal_applyCountryCaps * * Description Creates supported channel's and Tx power TLV format for *specific country code and updates map. @@ -347,70 +354,85 @@ void phNxpUciHal_reset_country_code_config() { * Returns void * *******************************************************************************/ -void phNxpUciHal_getCountryCaps(const uint8_t *cc_resp, const char country_code[2], - uint8_t *cc_data, uint32_t *retlen) { - uint16_t idx = 0; - uint16_t index = 0; - bool country_code_found = false; - uint8_t tx_power_len = 0; - uint32_t cc_resp_len = *retlen; - phNxpUciHal_reset_country_code_config(); - while (idx < cc_resp_len) { - if (cc_resp[idx++] == COUNTRY_CODE_TAG) { // ISO country code TAG - uint16_t len_idx = idx++; - uint8_t len = cc_resp[len_idx]; - for (uint8_t index = 0; index < len; index++) { - if (cc_resp[idx] != country_code[index]) { - idx = len_idx + len + 1; - country_code_found = false; - break; - } else { - idx++; - country_code_found = true; - } +static void phNxpUciHal_applyCountryCaps(const char country_code[2], + const uint8_t *cc_resp, uint32_t cc_resp_len, + uint8_t *cc_data, uint32_t *cc_data_len) +{ + phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings; + + phNxpUciHal_resetRuntimeSettings(); + + uint16_t idx = 1; // first byte = number countries + bool country_code_found = false; + + while (idx < cc_resp_len) { + uint8_t tag = cc_resp[idx++]; + uint8_t len = cc_resp[idx++]; + + if (country_code_found) { + switch (tag) { + case UWB_ENABLE_TAG: + if (len == 1) { + rt_set->uwb_enable = cc_resp[idx]; + NXPLOG_UCIHAL_D("CountryCaps uwb_enable = %u", cc_resp[idx]); } - while (cc_resp[idx] != COUNTRY_CODE_TAG) { - uint8_t cc_tag = cc_resp[idx++]; - len = cc_resp[idx++]; - if (country_code_found) { - switch (cc_tag) { - case UWB_ENABLE_TAG: - uwb_enable = cc_resp[idx++]; - break; - case CHANNEL_5_TAG: - channel_5_support = cc_resp[idx++]; - break; - case CHANNEL_9_TAG: - channel_9_support = cc_resp[idx++]; - break; - case TX_POWER_TAG: - conf_tx_power = (cc_resp[idx++] << RMS_TX_POWER_SHIFT); - conf_tx_power |= (cc_resp[idx++]); - phNxpUciHal_setCalibParamTxPower(conf_tx_power); - tx_power_len = len; - break; - } - } else { - idx += len; - } + break; + case CHANNEL_5_TAG: + if (len == 1 && !cc_resp[idx]) { + rt_set->restricted_channel_mask |= 1<< 5; + NXPLOG_UCIHAL_D("CountryCaps channel 5 support = %u", cc_resp[idx]); } + break; + case CHANNEL_9_TAG: + if (len == 1 && !cc_resp[idx]) { + rt_set->restricted_channel_mask |= 1<< 9; + NXPLOG_UCIHAL_D("CountryCaps channel 9 support = %u", cc_resp[idx]); + } + break; + case TX_POWER_TAG: + if (len == 2) { + rt_set->tx_power_offset = (short)((cc_resp[idx + 0] << RMS_TX_POWER_SHIFT) | (cc_resp[idx + 1])); + NXPLOG_UCIHAL_D("CountryCaps tx_power_offset = %d", rt_set->tx_power_offset); + + phNxpUciHal_setCalibParamTxPower(); + } + break; + default: + break; } - } - NXPLOG_UCIHAL_D("channel_5_support = %d", channel_5_support); - NXPLOG_UCIHAL_D("channel_9_support = %d", channel_9_support); - - uint8_t channel_info = (channel_5_support | CHANNEL_5_MASK) & 0xFF & - ((channel_9_support << 3) | CHANNEL_9_MASK); - uint8_t ccc_channel_info = - (channel_5_support | (channel_9_support << 1)) & CCC_CHANNEL_INFO_BIT_MASK; - NXPLOG_UCIHAL_D("channel_info = %d", channel_info); - cc_data[index++] = UWB_CHANNELS; - cc_data[index++] = 0x01; - cc_data[index++] = channel_info; - cc_data[index++] = CCC_UWB_CHANNELS; - cc_data[index++] = 0x01; - cc_data[index++] = ccc_channel_info; - *retlen = index; + } + if (tag == COUNTRY_CODE_TAG) { + country_code_found = (cc_resp[idx + 0] == country_code[0]) && (cc_resp[idx + 1] == country_code[1]); + } + idx += len; + } + + // consist up 'cc_data' TLVs + uint8_t fira_channels = 0xff; + if (rt_set->restricted_channel_mask & (1 << 5)) + fira_channels &= CHANNEL_5_MASK; + if (rt_set->restricted_channel_mask & (1 << 9)) + fira_channels &= CHANNEL_9_MASK; + + uint8_t ccc_channels = 0; + if (!(rt_set->restricted_channel_mask & (1 << 5))) + ccc_channels |= 0x01; + if (!(rt_set->restricted_channel_mask & (1 << 9))) + ccc_channels |= 0x02; + + uint8_t index = 0; + if ((index + 3) <= *cc_data_len) { + cc_data[index++] = UWB_CHANNELS; + cc_data[index++] = 0x01; + cc_data[index++] = fira_channels; + } + + if ((index + 3) <= *cc_data_len) { + cc_data[index++] = CCC_UWB_CHANNELS; + cc_data[index++] = 0x01; + cc_data[index++] = ccc_channels; + } + *cc_data_len = index; } /******************************************************************************* @@ -445,38 +467,40 @@ static bool phNxpUciHal_is_retry_required(uint8_t uci_octet0) { } /****************************************************************************** - * Function phNxpUciHal_sendSetCalibration + * Function phNxpUciHal_updateTxPower * - * Description This function send set calibration command + * Description This function updates the tx antenna power * - * Returns void + * Returns true/false * ******************************************************************************/ -static void phNxpUciHal_sendSetCalibration(const uint8_t *setCalibData, - uint8_t length) { - // GID : 0xF / OID : 0x21 - const uint8_t setCalibHeader[] = {0x2F, 0x21, 0x00}; - uint8_t *setCalibCmd = NULL; - setCalibCmd = (uint8_t *)malloc(sizeof(uint8_t) * (length + UCI_MSG_HDR_SIZE)); - memcpy(&setCalibCmd[0], &setCalibHeader[0], 3); - setCalibCmd[UCI_MSG_HDR_SIZE - 1] = length; - memcpy(&setCalibCmd[UCI_MSG_HDR_SIZE], &setCalibData[0], length); - length += UCI_MSG_HDR_SIZE; - tHAL_UWB_STATUS status = phNxpUciHal_send_ext_cmd(length, setCalibCmd); - if (status != UWBSTATUS_SUCCESS) { - NXPLOG_UCIHAL_D("%s: send failed", __func__); - } - if (setCalibCmd != NULL) { - free(setCalibCmd); - } - if (gtx_power != NULL) { - free(gtx_power); - gtx_power = NULL; - } - if (gRMS_tx_power != NULL) { - free(gRMS_tx_power); - gRMS_tx_power = NULL; - } +static void phNxpUciHal_updateTxPower(void) +{ + phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings; + + if (rt_set->tx_power_offset == 0) + return; + + if (gtx_power.empty()) + return; + + uint8_t index = 2; // channel + param ID + + if (gtx_power[index++]) { // number of entries + uint8_t num_of_antennas = gtx_power[index++]; + while (num_of_antennas--) { + index += 3; // antenna Id(1) + Peak Tx(2) + long tx_power_long = (gtx_power[index] & 0xff) | (gtx_power[index + 1] << RMS_TX_POWER_SHIFT); + tx_power_long += rt_set->tx_power_offset; + + // long to 16bit little endian + if (tx_power_long < 0) + tx_power_long = 0; + uint16_t tx_power_u16 = (uint16_t)tx_power_long; + gtx_power[index++] = tx_power_u16 & 0xff; + gtx_power[index++] = tx_power_u16 >> RMS_TX_POWER_SHIFT; + } + } } /******************************************************************************* @@ -487,63 +511,18 @@ static void phNxpUciHal_sendSetCalibration(const uint8_t *setCalibData, * Returns void * *******************************************************************************/ -void phNxpUciHal_processCalibParamTxPowerPerAntenna(const short conf_tx_power, - const uint8_t *p_data, - uint16_t data_len) { - // RMS Tx power -> Octet [4, 5] in calib data - NXPLOG_UCIHAL_D("phNxpUciHal_processCalibParamTxPowerPerAntenna %d", - conf_tx_power); - - if (gtx_power != NULL) { - free(gtx_power); - gtx_power = NULL; - } - gtx_power = (uint8_t *)malloc(sizeof(uint8_t) * data_len); +void phNxpUciHal_processCalibParamTxPowerPerAntenna(const uint8_t *p_data, uint16_t data_len) +{ + phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings; - if (gtx_power != NULL) { - gtx_power_length = p_data[UCI_MSG_HDR_SIZE - 1]; - memcpy(>x_power[0], &p_data[UCI_MSG_HDR_SIZE], - data_len - UCI_MSG_HDR_SIZE); - } + // RMS Tx power -> Octet [4, 5] in calib data + NXPLOG_UCIHAL_D("phNxpUciHal_processCalibParamTxPowerPerAntenna %d", rt_set->tx_power_offset); - if (conf_tx_power != 0) { - phNxpUciHal_updateTxPower(conf_tx_power); - } + gtx_power = std::move(std::vector<uint8_t> {p_data + UCI_MSG_HDR_SIZE, p_data + data_len}); - if (gtx_power != NULL) { - memcpy(&nxpucihal_ctrl.p_cmd_data[UCI_MSG_HDR_SIZE], >x_power[0], - data_len - UCI_MSG_HDR_SIZE); - } -} + phNxpUciHal_updateTxPower(); -/****************************************************************************** - * Function phNxpUciHal_updateTxPower - * - * Description This function updates the tx antenna power - * - * Returns true/false - * - ******************************************************************************/ -bool phNxpUciHal_updateTxPower(short conf_tx_power) { - if (gtx_power != NULL) { - uint8_t index = 0; - index++; // channel num - index++; // param ID - if (gtx_power[index++]) { - uint8_t num_of_antennas = gtx_power[index++]; - while (num_of_antennas--) { - index++; // antenna Id - index += 2; // Peak Tx - short calib_tx_pow = - gtx_power[index] << RMS_TX_POWER_SHIFT | gtx_power[index + 1]; - gtx_power[index++] = - (conf_tx_power + calib_tx_pow) >> RMS_TX_POWER_SHIFT; - gtx_power[index++] = (conf_tx_power + calib_tx_pow); - } - return true; - } - } - return false; + memcpy(&nxpucihal_ctrl.p_cmd_data[UCI_MSG_HDR_SIZE], gtx_power.data(), gtx_power.size()); } /****************************************************************************** @@ -554,13 +533,24 @@ bool phNxpUciHal_updateTxPower(short conf_tx_power) { * Returns true/false * ******************************************************************************/ -bool phNxpUciHal_setCalibParamTxPower(short conf_tx_power) { +static bool phNxpUciHal_setCalibParamTxPower(void) +{ + phNxpUciHal_updateTxPower(); - phNxpUciHal_updateTxPower(conf_tx_power); - if (gtx_power != NULL) { - phNxpUciHal_sendSetCalibration(gtx_power, gtx_power_length); - } - return true; + // GID : 0xF / OID : 0x21 + std::vector<uint8_t> packet{0x2f, 0x21, 0x00, 0x00}; + packet.insert(packet.end(), gtx_power.begin(), gtx_power.end()); + packet[3] = gtx_power.size(); + + tHAL_UWB_STATUS status = phNxpUciHal_send_ext_cmd(packet.size(), packet.data()); + if (status != UWBSTATUS_SUCCESS) { + NXPLOG_UCIHAL_D("%s: send failed", __func__); + } + + gtx_power.clear(); + gRMS_tx_power.clear(); + + return true; } /****************************************************************************** @@ -739,7 +729,7 @@ static void phNxpUciHal_parseCoreDeviceInfoRsp(const uint8_t *p_rx_data, size_t while (index < len) { paramId = p_rx_data[index++]; length = p_rx_data[index++]; - if (paramId == DEVICE_NAME_PARAM_ID && length >= 5) { + if (paramId == DEVICE_NAME_PARAM_ID && length >= 6) { /* SR100T --> T */ switch(p_rx_data[index + 5]) { case DEVICE_TYPE_SR1xxS: @@ -842,91 +832,269 @@ void phNxpUciHal_process_response() { } } +// SW defined data structures +typedef enum { + // 6 bytes + // [1:0] cap1 [3:2] cap2 [5:4] gm current control + EXTCAL_PARAM_CLK_ACCURACY = 0x1, // xtal + + // 3n + 1 bytes + // [0] n, number of entries + n * { [0] antenna-id [1:0] RX delay(Q14.2) } + EXTCAL_PARAM_RX_ANT_DELAY = 0x2, // ant_delay + + // 5N + 1 bytes + // [0]: n, number of entries + n * { [0] antenna-id [2:1] delta-peak [4:3] id-rms } + EXTCAL_PARAM_TX_POWER = 0x3, // tx_power + + // channel independent + // 1 byte + // b0: enable/disable DDFS tone generation (default off) + // b1: enable/disable DC suppression (default off) + EXTCAL_PARAM_TX_BASE_BAND_CONTROL = 0x101, // ddfs_enable, dc_suppress + + // channel independent (raw data contains channel info) + // bytes array + EXTCAL_PARAM_DDFS_TONE_CONFIG = 0x102, // ddfs_tone_config + + // channel independent + // byte array + EXTCAL_PARAM_TX_PULSE_SHAPE = 0x103, // tx_pulse_shape +} extcal_param_id_t; + +// Based on NXP SR1xx UCI v2.0.5 +// current HAL impl only supports "xtal" read from otp +// others should be existed in .conf files + +static tHAL_UWB_STATUS sr1xx_set_calibration(uint8_t channel, const std::vector<uint8_t> &tlv) +{ + // SET_CALIBRATION_CMD header: GID=0xF OID=0x21 + std::vector<uint8_t> packet({ (0x20 | UCI_GID_PROPRIETARY_0X0F), UCI_MSG_SET_DEVICE_CALIBRATION, 0x00, 0x00}); + + // use 9 for channel-independent parameters + if (!channel) { + channel = 9; + } + packet.push_back(channel); + packet.insert(packet.end(), tlv.begin(), tlv.end()); + packet[3] = packet.size() - 4; + return phNxpUciHal_send_ext_cmd(packet.size(), packet.data()); +} + +static tHAL_UWB_STATUS sr1xx_set_conf(const std::vector<uint8_t> &tlv) +{ + // SET_CALIBRATION_CMD header: GID=0xF OID=0x21 + std::vector<uint8_t> packet({ (0x20 | UCI_GID_CORE), UCI_MSG_CORE_SET_CONFIG, 0x00, 0x00}); + packet.push_back(1); // number of parameters + packet.insert(packet.end(), tlv.begin(), tlv.end()); + packet[3] = packet.size() - 4; + return phNxpUciHal_send_ext_cmd(packet.size(), packet.data()); +} + /****************************************************************************** - * Function phNxpUciHal_extcal_handle_coreinit + * Function phNxpUciHal_apply_calibration * - * Description Apply additional core device settings + * Description Send calibration/dev-config command to UWBS * - * Returns void. + * Parameters id - parameter id + * channel - channel number. 0 if it's channel independentt + * data - parameter value + * data_len - length of data + * + * Returns 0 : success, <0 : errno * ******************************************************************************/ -void phNxpUciHal_extcal_handle_coreinit(void) +tHAL_UWB_STATUS sr1xx_apply_calibration(extcal_param_id_t id, const uint8_t ch, const uint8_t *data, size_t data_len) { - long retlen = 0; + // Device Calibration + const uint8_t UCI_PARAM_ID_RF_CLK_ACCURACY_CALIB = 0x01; + const uint8_t UCI_PARAM_ID_RX_ANT_DELAY_CALIB = 0x02; + const uint8_t UCI_PARAM_ID_TX_POWER_PER_ANTENNA = 0x04; + + // Device Configurations + const uint16_t UCI_PARAM_ID_TX_BASE_BAND_CONFIG = 0xe426; + const uint16_t UCI_PARAM_ID_DDFS_TONE_CONFIG = 0xe427; + const uint16_t UCI_PARAM_ID_TX_PULSE_SHAPE_CONFIG = 0xe428; + + switch (id) { + case EXTCAL_PARAM_CLK_ACCURACY: + { + if (data_len != 6) { + return UWBSTATUS_FAILED; + } - // Channels - const uint8_t cal_channels[] = {5, 6, 8, 9}; + std::vector<uint8_t> tlv; + // Tag + tlv.push_back(UCI_PARAM_ID_RF_CLK_ACCURACY_CALIB); + // Length + tlv.push_back((uint8_t)data_len + 1); + // Value + tlv.push_back(3); // number of register (must be 0x03) + tlv.insert(tlv.end(), data, data + data_len); - // Antenna Definitions: rx_antenna_mask(1), tx_antenna_mask(1) - uint8_t rx_antenna_mask_n = 0xff; - NxpConfig_GetNum("cal.rx_antenna_mask", &rx_antenna_mask_n, 1); - std::bitset<8> rx_antenna_mask(rx_antenna_mask_n); - const uint8_t n_rx_antennas = rx_antenna_mask.size(); + return sr1xx_set_calibration(ch, tlv); + } + case EXTCAL_PARAM_RX_ANT_DELAY: + { + if (!ch || data_len < 1 || !data[0] || (data[0] * 3) != (data_len - 1)) { + return UWBSTATUS_FAILED; + } - // SET_CALIBRATION_CMD header: GID=0xF OID=0x21 - const std::vector<uint8_t> packet_header({ (0x20 | UCI_GID_PROPRIETARY_0X0F), UCI_MSG_SET_DEVICE_CALIBRATION, 0x00, 0x00}); + std::vector<uint8_t> tlv; + // Tag + tlv.push_back(UCI_PARAM_ID_RX_ANT_DELAY_CALIB); + // Length + tlv.push_back((uint8_t)data_len); + // Value + tlv.insert(tlv.end(), data, data + data_len); - // Supported calibrations, - // current HAL impl only supports "xtal" read from otp - // others should be existed in .conf files - // - // | name |otp-id|cal-id| size |per- |per- | otp | - // | | | | |channel|antenna| | - // |---------------|------|------|------|-------|-------|-----| - // | xtal | 0x02 | 0x02 | 3 | n | n | y | - // | tx_power | 0x04 | 0x17 | 2 | y | y | | - // | ant_delay | 0x0b | 0x02 | 2 | y | y | | - - // XTAL_CAP_GM_CTRL - // Check otp.xtal + return sr1xx_set_calibration(ch, tlv); + } + case EXTCAL_PARAM_TX_POWER: + { + if (!ch || data_len < 1 || !data[0] || (data[0] * 5) != (data_len - 1)) { + return UWBSTATUS_FAILED; + } + + std::vector<uint8_t> tlv; + // Tag + tlv.push_back(UCI_PARAM_ID_TX_POWER_PER_ANTENNA); + // Length + tlv.push_back((uint8_t)data_len); + // Value + tlv.insert(tlv.end(), data, data + data_len); + + return sr1xx_set_calibration(ch, tlv); + } + case EXTCAL_PARAM_TX_BASE_BAND_CONTROL: + { + if (data_len != 1) { + return UWBSTATUS_FAILED; + } + + std::vector<uint8_t> tlv; + // Tag + tlv.push_back(UCI_PARAM_ID_TX_BASE_BAND_CONFIG >> 8); + tlv.push_back(UCI_PARAM_ID_TX_BASE_BAND_CONFIG & 0xff); + // Length + tlv.push_back(1); + // Value + tlv.push_back(data[0]); + + return sr1xx_set_conf(tlv); + } + case EXTCAL_PARAM_DDFS_TONE_CONFIG: + { + if (!data_len) { + return UWBSTATUS_FAILED; + } + + std::vector<uint8_t> tlv; + // Tag + tlv.push_back(UCI_PARAM_ID_DDFS_TONE_CONFIG >> 8); + tlv.push_back(UCI_PARAM_ID_DDFS_TONE_CONFIG & 0xff); + // Length + tlv.push_back(data_len); + // Value + tlv.insert(tlv.end(), data, data + data_len); + + return sr1xx_set_conf(tlv); + } + case EXTCAL_PARAM_TX_PULSE_SHAPE: + { + if (!data_len) { + return UWBSTATUS_FAILED; + } + + std::vector<uint8_t> tlv; + // Tag + tlv.push_back(UCI_PARAM_ID_TX_PULSE_SHAPE_CONFIG >> 8); + tlv.push_back(UCI_PARAM_ID_TX_PULSE_SHAPE_CONFIG & 0xff); + // Length + tlv.push_back(data_len); + // Value + tlv.insert(tlv.end(), data, data + data_len); + + return sr1xx_set_conf(tlv); + } + default: + NXPLOG_UCIHAL_E("Unsupported parameter: 0x%x", id); + return UWBSTATUS_FAILED; + } +} + +tHAL_UWB_STATUS sr1xx_read_otp(extcal_param_id_t id, uint8_t *data, size_t data_len, size_t *retlen) +{ + switch(id) { + case EXTCAL_PARAM_CLK_ACCURACY: + { + const size_t param_len = 6; + uint8_t otp_xtal_data[3]; + + if (data_len < param_len) { + NXPLOG_UCIHAL_E("Requested RF_CLK_ACCURACY_CALIB with %zu bytes (expected >= %zu)", data_len, param_len); + return UWBSTATUS_FAILED; + } + if (!otp_read_data(0x09, OTP_ID_XTAL_CAP_GM_CTRL, otp_xtal_data, sizeof(otp_xtal_data))) { + NXPLOG_UCIHAL_E("Failed to read OTP XTAL_CAP_GM_CTRL"); + return UWBSTATUS_FAILED; + } + memset(data, 0, param_len); + // convert OTP_ID_XTAL_CAP_GM_CTRL to EXTCAL_PARAM_RX_ANT_DELAY + data[0] = otp_xtal_data[0]; // cap1 + data[2] = otp_xtal_data[1]; // cap2 + data[4] = otp_xtal_data[2]; // gm_current_control (default: 0x30) + *retlen = param_len; + return UWBSTATUS_SUCCESS; + } + break; + default: + NXPLOG_UCIHAL_E("Unsupported otp parameter %d", id); + return UWBSTATUS_FAILED; + } +} + +// Channels +const static uint8_t cal_channels[] = {5, 6, 8, 9}; + +static void extcal_do_xtal(void) +{ + int ret; + + // RF_CLK_ACCURACY_CALIB (otp supported) + // parameters: cal.otp.xtal=0|1, cal.xtal=X uint8_t otp_xtal_flag = 0; - uint8_t otp_xtal_data[3]; - uint8_t xtal_data[6]; - bool need_xtal_calibration = false; + uint8_t xtal_data[32]; + size_t xtal_data_len = 0; if (NxpConfig_GetNum("cal.otp.xtal", &otp_xtal_flag, 1) && otp_xtal_flag) { - if (otp_read_data(0x09, OTP_ID_XTAL_CAP_GM_CTRL, otp_xtal_data, sizeof(otp_xtal_data))) { - // convert OTP_ID_XTAL_CAP_GM_CTRL to RF_CLK_ACCURACY_CALIB - memset(xtal_data, 0, sizeof(xtal_data)); - xtal_data[0] = otp_xtal_data[0]; - xtal_data[2] = otp_xtal_data[1]; - xtal_data[4] = otp_xtal_data[2]; - need_xtal_calibration = true; - } else { - NXPLOG_UCIHAL_E("Failed to read OTP XTAL_CAP_GM_CTRL"); + sr1xx_read_otp(EXTCAL_PARAM_CLK_ACCURACY, xtal_data, sizeof(xtal_data), &xtal_data_len); + } + if (!xtal_data_len) { + long retlen = 0; + if (NxpConfig_GetByteArray("cal.xtal", xtal_data, sizeof(xtal_data), &retlen)) { + xtal_data_len = retlen; } - } else if (NxpConfig_GetByteArray("cal.xtal", otp_xtal_data, sizeof(otp_xtal_data), &retlen) && - retlen == sizeof(otp_xtal_data)) { - need_xtal_calibration = true; - } - - if (need_xtal_calibration) { - std::vector<uint8_t> payload; - - // Channel, 9, don't care for RF_CLK_ACCURACY_CALIB - payload.push_back(9); - // Tag - payload.push_back(UCI_PARAM_ID_RF_CLK_ACCURACY_CALIB); - // Length = 7 - payload.push_back(1 + sizeof(xtal_data)); - // octet[0] = 3 - payload.push_back(3); - // octet[6:1] = cap1(2), cap2(2), gm_current_control(2) - payload.insert(payload.end(), &xtal_data[0], &xtal_data[6]); - - std::vector<uint8_t> packet(packet_header); - packet[3] = payload.size(); - packet.insert(packet.end(), payload.begin(), payload.end()); - - tHAL_UWB_STATUS status = phNxpUciHal_send_ext_cmd(packet.size(), packet.data()); - if (status != UWBSTATUS_SUCCESS) { - NXPLOG_UCIHAL_E("Failed to apply XTAL_CAP_GM_CTRL={%02x,%02x,%02x,%02x,%02x,%02x}", - xtal_data[0], xtal_data[1], xtal_data[2], xtal_data[3], xtal_data[4], xtal_data[5]); + } + + if (xtal_data_len) { + NXPLOG_UCIHAL_E("Apply CLK_ACCURARY (len=%zu, from-otp=%c)", xtal_data_len, otp_xtal_flag ? 'y' : 'n'); + + ret = sr1xx_apply_calibration(EXTCAL_PARAM_CLK_ACCURACY, 0, xtal_data, xtal_data_len); + + if (ret != UWBSTATUS_SUCCESS) { + NXPLOG_UCIHAL_E("Failed to apply CLK_ACCURACY (len=%zu, from-otp=%c)", + xtal_data_len, otp_xtal_flag ? 'y' : 'n'); } } +} - // RX_ANT_DELAY_CALIB(0x0F) - // Read configuration file ant1.ch5.ant_delay +static void extcal_do_ant_delay(void) +{ + std::bitset<8> rx_antenna_mask(nxpucihal_ctrl.cal_rx_antenna_mask); + const uint8_t n_rx_antennas = rx_antenna_mask.size(); + + // RX_ANT_DELAY_CALIB + // parameter: cal.ant<N>.ch<N>.ant_delay=X // N(1) + N * {AntennaID(1), Rxdelay(Q14.2)} if (n_rx_antennas) { for (auto ch : cal_channels) { @@ -945,10 +1113,11 @@ void phNxpUciHal_extcal_handle_coreinit(void) if (!NxpConfig_GetNum(key, &delay_value, 2)) continue; - NXPLOG_UCIHAL_D("RX_ANT_DELAY_CALIB: found %s = %u", key, delay_value); + NXPLOG_UCIHAL_D("Apply RX_ANT_DELAY_CALIB: %s = %u", key, delay_value); entries.push_back(ant_id); - entries.push_back(delay_value >> 8); + // Little Endian entries.push_back(delay_value & 0xff); + entries.push_back(delay_value >> 8); n_entries++; } @@ -956,23 +1125,209 @@ void phNxpUciHal_extcal_handle_coreinit(void) continue; entries.insert(entries.begin(), n_entries); + tHAL_UWB_STATUS ret = sr1xx_apply_calibration(EXTCAL_PARAM_RX_ANT_DELAY, ch, entries.data(), entries.size()); + if (ret != UWBSTATUS_SUCCESS) { + NXPLOG_UCIHAL_E("Failed to apply RX_ANT_DELAY for channel %u", ch); + } + } + } +} - std::vector<uint8_t> payload; - payload.push_back(ch); - payload.push_back(UCI_PARAM_ID_RX_ANT_DELAY_CALIB); - payload.push_back(entries.size()); - payload.insert(payload.end(), entries.begin(), entries.end()); +static void extcal_do_tx_power(void) +{ + std::bitset<8> tx_antenna_mask(nxpucihal_ctrl.cal_tx_antenna_mask); + const uint8_t n_tx_antennas = tx_antenna_mask.size(); - std::vector<uint8_t> packet(packet_header); - packet[3] = payload.size(); - packet.insert(packet.end(), payload.begin(), payload.end()); + // TX_POWER + // parameter: cal.ant<N>.ch<N>.tx_power={...} + if (n_tx_antennas) { + for (auto ch : cal_channels) { + std::vector<uint8_t> entries; + uint8_t n_entries = 0; - tHAL_UWB_STATUS status = phNxpUciHal_send_ext_cmd(packet.size(), packet.data()); - if (status != UWBSTATUS_SUCCESS) { - NXPLOG_UCIHAL_E("Failed to apply RX_ANT_DELAY_CALIB for channel %u", ch); - } else { - NXPLOG_UCIHAL_E("RX_ANT_DELAY_CALIB: applied for channel %u", ch); + for (auto i = 0; i < n_tx_antennas; i++) { + if (!tx_antenna_mask[i]) + continue; + + char key[32]; + const uint8_t ant_id = i + 1; + std::snprintf(key, sizeof(key), "cal.ant%u.ch%u.tx_power", ant_id, ch); + + uint8_t power_value[32]; + long retlen = 0; + if (!NxpConfig_GetByteArray(key, power_value, sizeof(power_value), &retlen)) { + continue; + } + + NXPLOG_UCIHAL_D("Apply TX_POWER: %s = { %lu bytes }", key, retlen); + entries.push_back(ant_id); + entries.insert(entries.end(), power_value, power_value + retlen); + n_entries++; + } + + if (!n_entries) + continue; + + entries.insert(entries.begin(), n_entries); + tHAL_UWB_STATUS ret = sr1xx_apply_calibration(EXTCAL_PARAM_TX_POWER, ch, entries.data(), entries.size()); + if (ret != UWBSTATUS_SUCCESS) { + NXPLOG_UCIHAL_E("Failed to apply TX_POWER for channel %u", ch); + } + } + } +} + +static void extcal_do_tx_pulse_shape(void) +{ + // parameters: cal.tx_pulse_shape={...} + long retlen = 0; + uint8_t data[64]; + + if (NxpConfig_GetByteArray("cal.tx_pulse_shape", data, sizeof(data), &retlen) && retlen) { + NXPLOG_UCIHAL_D("Apply TX_PULSE_SHAPE: data = { %lu bytes }", retlen); + + tHAL_UWB_STATUS ret = sr1xx_apply_calibration(EXTCAL_PARAM_TX_PULSE_SHAPE, 0, data, (size_t)retlen); + if (ret != UWBSTATUS_SUCCESS) { + NXPLOG_UCIHAL_E("Failed to apply TX_PULSE_SHAPE."); + } + } +} + +static void extcal_do_tx_base_band(void) +{ + // TX_BASE_BAND_CONTROL, DDFS_TONE_CONFIG + // parameters: cal.ddfs_enable=1|0, cal.dc_suppress=1|0, ddfs_tone_config={...} + uint8_t ddfs_enable = 0, dc_suppress = 0; + uint8_t ddfs_tone[256]; + long retlen = 0; + tHAL_UWB_STATUS ret; + + NxpConfig_GetNum("cal.ddfs_enable", &ddfs_enable, 1); + NxpConfig_GetNum("cal.dc_suppress", &dc_suppress, 1); + + // DDFS_TONE_CONFIG + if (ddfs_enable) { + if (!NxpConfig_GetByteArray("cal.ddfs_tone_config", ddfs_tone, sizeof(ddfs_tone), &retlen) || !retlen) { + NXPLOG_UCIHAL_E("cal.ddfs_tone_config is not supplied while cal.ddfs_enable=1, ddfs was not enabled."); + ddfs_enable = 0; + } else { + NXPLOG_UCIHAL_D("Apply DDFS_TONE_CONFIG: ddfs_tone_config = { %lu bytes }", retlen); + + ret = sr1xx_apply_calibration(EXTCAL_PARAM_DDFS_TONE_CONFIG, 0, ddfs_tone, (size_t)retlen); + if (ret != UWBSTATUS_SUCCESS) { + NXPLOG_UCIHAL_E("Failed to apply DDFS_TONE_CONFIG, ddfs was not enabled."); + ddfs_enable = 0; } } } + + // TX_BASE_BAND_CONTROL + { + NXPLOG_UCIHAL_E("Apply TX_BASE_BAND_CONTROL: ddfs_enable=%u, dc_suppress=%u", ddfs_enable, dc_suppress); + + uint8_t flag = 0; + if (ddfs_enable) + flag |= 0x01; + if (dc_suppress) + flag |= 0x02; + ret = sr1xx_apply_calibration(EXTCAL_PARAM_TX_BASE_BAND_CONTROL, 0, &flag, 1); + if (ret) { + NXPLOG_UCIHAL_E("Failed to apply TX_BASE_BAND_CONTROL"); + } + } +} + +static void extcal_do_restrictions(void) +{ + phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings; + + phNxpUciHal_resetRuntimeSettings(); + + uint16_t mask= 0; + if (NxpConfig_GetNum("cal.restricted_channels", &mask, sizeof(mask))) { + NXPLOG_UCIHAL_D("Restriction flag, restricted channel mask=0x%x", mask); + rt_set->restricted_channel_mask = mask; + } + + uint8_t uwb_disable = 0; + if (NxpConfig_GetNum("cal.uwb_disable", &uwb_disable, sizeof(uwb_disable))) { + NXPLOG_UCIHAL_D("Restriction flag, uwb_disable=%u", uwb_disable); + rt_set->uwb_enable = !uwb_disable; + } +} + +/****************************************************************************** + * Function phNxpUciHal_extcal_handle_coreinit + * + * Description Apply additional core device settings + * + * Returns void. + * + ******************************************************************************/ +void phNxpUciHal_extcal_handle_coreinit(void) +{ + // read rx_aantenna_mask, tx_antenna_mask + uint8_t rx_antenna_mask_n = 0x1; + uint8_t tx_antenna_mask_n = 0x1; + if (!NxpConfig_GetNum("cal.rx_antenna_mask", &rx_antenna_mask_n, 1)) { + NXPLOG_UCIHAL_E("cal.rx_antenna_mask is not specified, use default 0x%x", rx_antenna_mask_n); + } + if (!NxpConfig_GetNum("cal.tx_antenna_mask", &tx_antenna_mask_n, 1)) { + NXPLOG_UCIHAL_E("cal.tx_antenna_mask is not specified, use default 0x%x", tx_antenna_mask_n); + } + nxpucihal_ctrl.cal_rx_antenna_mask = rx_antenna_mask_n; + nxpucihal_ctrl.cal_tx_antenna_mask = tx_antenna_mask_n; + + extcal_do_xtal(); + extcal_do_ant_delay(); +} + +extern bool isCountryCodeMapCreated; + +/****************************************************************************** + * Function phNxpUciHal_handle_set_country_code + * + * Description Apply per-country settings + * + * Returns void. + * + ******************************************************************************/ +void phNxpUciHal_handle_set_country_code(const char country_code[2]) +{ + NXPLOG_UCIHAL_D("Apply country code %c%c", country_code[0], country_code[1]); + + NxpConfig_SetCountryCode(country_code); + + // Load 'COUNTRY_CODE_CAPS' and apply it to 'conf_map' + uint8_t cc_caps[UCI_MAX_DATA_LEN]; + long retlen = 0; + if (NxpConfig_GetByteArray(NAME_NXP_UWB_COUNTRY_CODE_CAPS, cc_caps, sizeof(cc_caps), &retlen) && retlen) { + NXPLOG_UCIHAL_D("COUNTRY_CODE_CAPS is provided."); + isCountryCodeMapCreated = false; + + uint32_t cc_caps_len = retlen; + uint8_t cc_data[UCI_MAX_DATA_LEN]; + uint32_t cc_data_len = sizeof(cc_data); + phNxpUciHal_applyCountryCaps(country_code, cc_caps, cc_caps_len, cc_data, &cc_data_len); + + if (get_conf_map(cc_data, cc_data_len)) { + isCountryCodeMapCreated = true; + NXPLOG_UCIHAL_D("Country code caps loaded"); + } + } else { + NXPLOG_UCIHAL_D("COUNTRY_CODE_CAPS was not provided."); + } + + // per-country extra calibrations are only triggered when 'COUNTRY_CODE_CAPS' is not provided + if (!isCountryCodeMapCreated) { + NXPLOG_UCIHAL_D("Apply per-country extra calibrations"); + extcal_do_restrictions(); + + phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings; + if (rt_set->uwb_enable) { + extcal_do_tx_power(); + extcal_do_tx_pulse_shape(); + extcal_do_tx_base_band(); + } + } } diff --git a/halimpl/hal/phNxpUciHal_ext.h b/halimpl/hal/phNxpUciHal_ext.h index 7a753ce..02c6d57 100644 --- a/halimpl/hal/phNxpUciHal_ext.h +++ b/halimpl/hal/phNxpUciHal_ext.h @@ -66,14 +66,8 @@ typedef struct { tHAL_UWB_STATUS phNxpUciHal_send_ext_cmd(uint16_t cmd_len, const uint8_t* p_cmd); tHAL_UWB_STATUS phNxpUciHal_process_ext_rsp(uint16_t cmd_len, uint8_t* p_buff); tHAL_UWB_STATUS phNxpUciHal_set_board_config(); -void phNxpUciHal_getCountryCaps(const uint8_t *cc_resp, const char country_code[2], - uint8_t *cc_data, uint32_t *retlen); -void phNxpUciHal_processCalibParamTxPowerPerAntenna(const short conf_tx_power, - const uint8_t *p_data, - uint16_t data_len); +void phNxpUciHal_processCalibParamTxPowerPerAntenna(const uint8_t *p_data, uint16_t data_len); void phNxpUciHal_extcal_handle_coreinit(void); -bool phNxpUciHal_updateTxPower(short conf_tx_power); -bool phNxpUciHal_setCalibParamTxPower(short conf_tx_power); void phNxpUciHal_process_response(); - +void phNxpUciHal_handle_set_country_code(const char country_code[2]); #endif /* _PHNXPNICHAL_EXT_H_ */ diff --git a/halimpl/tml/phTmlUwb.h b/halimpl/tml/phTmlUwb.h index 1b0bcb3..99ae934 100644 --- a/halimpl/tml/phTmlUwb.h +++ b/halimpl/tml/phTmlUwb.h @@ -152,7 +152,7 @@ typedef struct phTmlUwb_Config { * * e.g. On Linux based systems this would be /dev/SR100 */ - int8_t* pDevName; + const char* pDevName; /* Callback Thread ID * * This is the thread ID on which the Reader & Writer thread posts message. */ diff --git a/halimpl/tml/phTmlUwb_spi.cc b/halimpl/tml/phTmlUwb_spi.cc index e59d2a7..c5e8902 100644 --- a/halimpl/tml/phTmlUwb_spi.cc +++ b/halimpl/tml/phTmlUwb_spi.cc @@ -51,7 +51,7 @@ tHAL_UWB_STATUS phTmlUwb_spi_open_and_configure(pphTmlUwb_Config_t pConfig, NXPLOG_TML_D("Opening port=%s\n", pConfig->pDevName); /* open port */ - nHandle = open((const char*)pConfig->pDevName, O_RDWR); + nHandle = open(pConfig->pDevName, O_RDWR); if (nHandle < 0) { NXPLOG_TML_E("_spi_open() Failed: retval %x", nHandle); *pLinkHandle = NULL; diff --git a/halimpl/utils/phNxpConfig.cc b/halimpl/utils/phNxpConfig.cc index 9f32438..e1aa9a8 100644 --- a/halimpl/utils/phNxpConfig.cc +++ b/halimpl/utils/phNxpConfig.cc @@ -774,7 +774,6 @@ void CascadeConfig::init(const char *main_config) } } -extern bool isCountryCodeMapCreated; void CascadeConfig::setCountryCode(const char country_code[2]) { string strCountry = mRegionMap.xlateCountryCode(country_code); @@ -786,23 +785,16 @@ void CascadeConfig::setCountryCode(const char country_code[2]) x.dump(); } } - - // Load 'COUNTRY_CODE_CAPS' and apply it to 'conf_map' - auto cc_data = make_unique<uint8_t[]>(UCI_MAX_DATA_LEN); - const uwbParam *param = mCapsConfig.find(NAME_NXP_UWB_COUNTRY_CODE_CAPS); - if (param) { - uint32_t retlen = param->arr_len(); - phNxpUciHal_getCountryCaps(param->arr_value(), country_code, cc_data.get(), &retlen); - if (get_conf_map(cc_data.get(), retlen)) { - isCountryCodeMapCreated = true; - NXPLOG_UCIHAL_D("Country code caps loaded"); - } - } } const uwbParam* CascadeConfig::find(const char *name) const { const uwbParam* param = NULL; + + param = mCapsConfig.find(name); + if (param) + return param; + for (auto it = mExtraConfig.rbegin(); it != mExtraConfig.rend(); it++) { param = it->find(name); if (param) |