blob: 2b1bdf5c36e370367eb386c0e530631af78f2064 [file] [edit]
/*
* Copyright 2021-2023 NXP
* Copyright 2024 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "phNxpUciHal_ext.h"
#include "phNxpUwbCalib.h"
#include "phUwbStatus.h"
//
// SR1XX Device Calibrations:
//
// 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());
}
tHAL_UWB_STATUS sr1xx_apply_calibration(extcal_param_id_t id, const uint8_t ch, const uint8_t *data, size_t data_len)
{
// 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;
}
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);
return sr1xx_set_calibration(ch, tlv);
}
case EXTCAL_PARAM_RX_ANT_DELAY:
{
// [0] = number of entries
// {
// [0] = rx antenna id
// [1,2] = rx delay
// }
if (!ch || data_len < 1 || !data[0] || (data[0] * 3) != (data_len - 1)) {
return UWBSTATUS_FAILED;
}
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);
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;
}
}