blob: 2b281277f8da642d9000298c95100cb57820d4a6 [file] [log] [blame]
#include "NxpUwbChip.h"
#include "phNxpConfig.h"
#include "phNxpUciHal.h"
#include "phNxpUciHal_ext.h"
#include "phUwbStatus.h"
#include "phUwbTypes.h"
#include "phNxpUwbCalib.h"
#include "uci_defs.h"
#define UCI_MSG_UWB_ESE_BINDING_LEN 11
#define UCI_MSG_UWB_ESE_BINDING_OFFSET_COUNT 5
#define UCI_MSG_UWB_ESE_BINDING_OFFSET_BINDING_STATE 6
extern phNxpUciHal_Control_t nxpucihal_ctrl;
extern int hdll_fw_download();
class NxpUwbChipSr200 final : public NxpUwbChip {
public:
NxpUwbChipSr200();
virtual ~NxpUwbChipSr200();
tHAL_UWB_STATUS chip_init();
tHAL_UWB_STATUS core_init();
device_type_t get_device_type(const uint8_t *param, size_t param_len);
tHAL_UWB_STATUS read_otp(extcal_param_id_t id, uint8_t *data, size_t data_len, size_t *retlen);
tHAL_UWB_STATUS apply_calibration(extcal_param_id_t id, const uint8_t ch, const uint8_t *data, size_t data_len);
tHAL_UWB_STATUS get_supported_channels(const uint8_t **cal_channels, uint8_t *nr);
private:
void on_binding_status_ntf(size_t packet_len, const uint8_t* packet);
tHAL_UWB_STATUS check_binding_done();
UciHalRxHandler bindingStatusNtfHandler_;
UciHalSemaphore bindingStatusNtfWait_;
uint8_t bindingStatus_;
};
NxpUwbChipSr200::NxpUwbChipSr200() :
bindingStatus_(UWB_DEVICE_UNKNOWN)
{
}
NxpUwbChipSr200::~NxpUwbChipSr200()
{
}
void NxpUwbChipSr200::on_binding_status_ntf(size_t packet_len, const uint8_t* packet)
{
if (packet_len >= UCI_RESPONSE_STATUS_OFFSET) {
bindingStatus_ = packet[UCI_RESPONSE_STATUS_OFFSET];
NXPLOG_UCIHAL_D("BINDING_STATUS_NTF: 0x%x", bindingStatus_);
bindingStatusNtfWait_.post(UWBSTATUS_SUCCESS);
}
}
tHAL_UWB_STATUS NxpUwbChipSr200::check_binding_done()
{
// Wait for Binding status notification
if (bindingStatusNtfWait_.getStatus() != UWBSTATUS_SUCCESS) {
bindingStatusNtfWait_.wait();
}
if (bindingStatusNtfWait_.getStatus() != UWBSTATUS_SUCCESS) {
NXPLOG_UCIHAL_E("Binding status notification timeout");
// Stop HAL init when it didn't receive the binding notification
if (nxpucihal_ctrl.fw_boot_mode == USER_FW_BOOT_MODE)
return UWBSTATUS_FAILED;
else
return UWBSTATUS_SUCCESS;
}
switch (bindingStatus_) {
case UWB_DEVICE_NOT_BOUND:
NXPLOG_UCIHAL_E("Binding status: Unbound.");
break;
case UWB_DEVICE_BOUND_UNLOCKED:
NXPLOG_UCIHAL_E("Binding status: bound & unlocked.");
break;
case UWB_DEVICE_BOUND_LOCKED:
NXPLOG_UCIHAL_D("Binding status: bound & locked.");
break;
case UWB_DEVICE_UNKNOWN:
NXPLOG_UCIHAL_D("Binding status: Unknown.");
break;
default:
NXPLOG_UCIHAL_E("Unknown binding status: 0x%x", bindingStatus_);
return UWBSTATUS_FAILED;
}
return UWBSTATUS_SUCCESS;
}
tHAL_UWB_STATUS NxpUwbChipSr200::chip_init()
{
tHAL_UWB_STATUS status;
// system in FW download mode
// This will be cleared on first Device Status NTF
nxpucihal_ctrl.fw_dwnld_mode = true;
NXPLOG_UCIHAL_D("Start SR200 FW download");
for (int i = 0; i < 5; i++) {
phTmlUwb_Chip_Reset();
status = hdll_fw_download();
if (status == UWBSTATUS_SUCCESS) {
NXPLOG_UCIHAL_D("Complete SR200 FW download");
break;
} else if(status == UWBSTATUS_FILE_NOT_FOUND) {
NXPLOG_UCIHAL_E("FW file Not found.");
break;
} else {
NXPLOG_UCIHAL_E("FW download failed, status= 0x%x, retry.", status);
}
}
// register binding status ntf handler
bindingStatusNtfHandler_ = UciHalRxHandler(
UCI_MT_NTF, UCI_GID_PROPRIETARY, UCI_MSG_BINDING_STATUS_NTF,
true,
std::bind(&NxpUwbChipSr200::on_binding_status_ntf, this, std::placeholders::_1, std::placeholders::_2));
return status;
}
tHAL_UWB_STATUS NxpUwbChipSr200::core_init()
{
return check_binding_done();
}
device_type_t NxpUwbChipSr200::get_device_type(const uint8_t *param, size_t param_len)
{
// should be 'SR200..'
const char marker[] = { 'S', 'R', '2', '0', '0' };
if (param_len >= sizeof(marker)) {
if (!memcmp(param, marker, sizeof(marker)))
return DEVICE_TYPE_SR200;
}
return DEVICE_TYPE_UNKNOWN;
}
tHAL_UWB_STATUS
NxpUwbChipSr200::read_otp(extcal_param_id_t id,
uint8_t *data, size_t data_len, size_t *retlen)
{
return UWBSTATUS_NOT_ALLOWED;
}
tHAL_UWB_STATUS
NxpUwbChipSr200::apply_calibration(extcal_param_id_t id, const uint8_t ch,
const uint8_t *data, size_t data_len)
{
switch (id) {
case EXTCAL_PARAM_TX_POWER:
case EXTCAL_PARAM_TX_BASE_BAND_CONTROL:
case EXTCAL_PARAM_DDFS_TONE_CONFIG:
case EXTCAL_PARAM_TX_PULSE_SHAPE:
return sr1xx_apply_calibration(id, ch, data, data_len);
case EXTCAL_PARAM_CLK_ACCURACY:
case EXTCAL_PARAM_RX_ANT_DELAY:
/* break through */
default:
NXPLOG_UCIHAL_E("Unsupported parameter: 0x%x", id);
return UWBSTATUS_FAILED;
}
}
tHAL_UWB_STATUS
NxpUwbChipSr200::get_supported_channels(const uint8_t **cal_channels, uint8_t *nr)
{
static const uint8_t sr200_cal_channels[] = {5, 9, 10};
*cal_channels = sr200_cal_channels;
*nr = std::size(sr200_cal_channels);
return UWBSTATUS_SUCCESS;
}
std::unique_ptr<NxpUwbChip> GetUwbChip()
{
return std::make_unique<NxpUwbChipSr200>();
}