summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-16 00:18:16 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-16 00:18:16 +0000
commit029f65b7a25c5fa6a4d6162d6fdbc2d7e6dd3400 (patch)
tree47d8373b2cb580503c7e6f2debca10947baea75e
parentc695bddb45904343b658fc72a16ac8d681346a63 (diff)
parentce3a405dee2a9f25489e4b20c7ec1f517b1a9ee7 (diff)
downloaduwb-029f65b7a25c5fa6a4d6162d6fdbc2d7e6dd3400.tar.gz
Snap for 11104212 from ce3a405dee2a9f25489e4b20c7ec1f517b1a9ee7 to 24Q1-release
Change-Id: I8618b20b439ef23138e84a89fa948f7a9d8d06b7
-rw-r--r--extns/inc/uci_defs.h8
-rw-r--r--halimpl/config/README.md97
-rw-r--r--halimpl/fwd/sr1xx/phNxpUciHal_fwd.cc116
-rw-r--r--halimpl/fwd/sr1xx/phNxpUciHal_fwd.h3
-rw-r--r--halimpl/hal/phNxpUciHal.cc276
-rw-r--r--halimpl/hal/phNxpUciHal.h18
-rw-r--r--halimpl/hal/phNxpUciHal_ext.cc849
-rw-r--r--halimpl/hal/phNxpUciHal_ext.h10
-rw-r--r--halimpl/tml/phTmlUwb.h2
-rw-r--r--halimpl/tml/phTmlUwb_spi.cc2
-rw-r--r--halimpl/utils/phNxpConfig.cc18
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(&gtx_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], &gtx_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)