drivers/distance_sensor: New Broadcom AFBR-S50LV85D distance sensor driver

* Basic Broadcom AFBR-S50 driver using vendor API and binary blob https://github.com/Broadcom/AFBR-S50-API
* fix ARK Flow paw3902 rotation
This commit is contained in:
AlexKlimaj
2021-06-15 10:12:24 -06:00
committed by GitHub
parent e828ba4288
commit dddd2c3297
51 changed files with 7753 additions and 37 deletions
+2
View File
@@ -108,3 +108,5 @@ src/systemcmds/topic_listener/listener_generated.cpp
# SITL
dataman
eeprom/
!src/drivers/distance_sensor/broadcom/afbrs50/Lib/*
+3 -3
View File
@@ -12,6 +12,7 @@ px4_add_board(
UAVCAN_INTERFACES 1
DRIVERS
bootloaders
distance_sensor/broadcom/afbrs50
imu/bosch/bmi088
optical_flow/paw3902
uavcannode
@@ -20,14 +21,13 @@ px4_add_board(
load_mon
#sensors
SYSTEMCMDS
mft
mtd
param
perf
reboot
system_time
top
topic_listener
#topic_listener
uorb
ver
work_queue
)
+2 -2
View File
@@ -13,6 +13,7 @@ px4_add_board(
UAVCAN_INTERFACES 1
DRIVERS
bootloaders
distance_sensor/broadcom/afbrs50
imu/bosch/bmi088
optical_flow/paw3902
uavcannode
@@ -21,14 +22,13 @@ px4_add_board(
#load_mon
#sensors
SYSTEMCMDS
mft
mtd
param
#perf
#reboot
#system_time
#top
#topic_listener
#uorb
#ver
#work_queue
)
+3 -1
View File
@@ -4,6 +4,8 @@
#------------------------------------------------------------------------------
# Internal SPI
paw3902 -s start -Y 90
paw3902 -s start -Y 180
bmi088 -A -s -R 4 start
bmi088 -G -s -R 4 start
afbrs50 start
@@ -133,8 +133,8 @@
#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1
#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1
#define GPIO_SPI2_MISO GPIO_SPI2_MISO_1
#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_1
#define GPIO_SPI2_SCK GPIO_SPI2_SCK_1
#define GPIO_SPI2_MISO GPIO_SPI2_MISO_1 /* PB14 */
#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_1 /* PB15 */
#define GPIO_SPI2_SCK GPIO_SPI2_SCK_1 /* PB10 */
#endif /* __ARCH_BOARD_BOARD_H */
@@ -40,6 +40,4 @@
// DMA2 Channel/Stream Selections
//--------------------------------------------//---------------------------//----------------
#define DMACHAN_SPI1_RX DMAMAP_SPI1_RX_2 // DMA2, Stream 2, Channel 3
#define DMACHAN_SPI2_RX DMAMAP_SPI2_RX // DMA2, Stream 3, Channel 0
#define DMACHAN_SPI2_TX DMAMAP_SPI2_TX // DMA2, Stream 4, Channel 0
#define DMACHAN_SPI1_TX DMAMAP_SPI1_TX_1 // DMA2, Stream 5, Channel 3
@@ -144,8 +144,6 @@ CONFIG_STM32_SPI1=y
CONFIG_STM32_SPI1_DMA=y
CONFIG_STM32_SPI1_DMA_BUFFER=1024
CONFIG_STM32_SPI2=y
CONFIG_STM32_SPI2_DMA=y
CONFIG_STM32_SPI2_DMA_BUFFER=1024
CONFIG_STM32_SPI_DMA=y
CONFIG_STM32_TIM8=y
CONFIG_STM32_USART2=y
+7
View File
@@ -56,6 +56,13 @@
#define GPIO_nLED_RED /* PB3 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN3)
#define GPIO_nLED_BLUE /* PA8 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN8)
#define BROADCOM_AFBR_S50_S2PI_SPI_BUS 2
#define BROADCOM_AFBR_S50_S2PI_CS /* PB12 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN12)
#define BROADCOM_AFBR_S50_S2PI_IRQ /* PB4 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN4|GPIO_EXTI)
#define BROADCOM_AFBR_S50_S2PI_CLK /* PB10 */ GPIO_SPI2_SCK_1
#define BROADCOM_AFBR_S50_S2PI_MOSI /* PB15 */ GPIO_SPI2_MOSI_1
#define BROADCOM_AFBR_S50_S2PI_MISO /* PB14 */ GPIO_SPI2_MISO_1
#define BOARD_HAS_CONTROL_STATUS_LEDS 1
#define BOARD_OVERLOAD_LED LED_RED
#define BOARD_ARMED_STATE_LED LED_BLUE
@@ -160,7 +160,7 @@ static int read_id_dn(int *id, uint32_t gpio_drive, uint32_t gpio_sense, int adc
/* Turn the sense lines to digital outputs LOW */
imxrt_config_gpio(PX4_MAKE_GPIO_OUTPUT(gpio_sense));
imxrt_config_gpio(PX4_MAKE_GPIO_OUTPUT_CLEAR(gpio_sense));
up_udelay(100); /* About 10 TC assuming 485 K */
@@ -172,7 +172,7 @@ static int read_id_dn(int *id, uint32_t gpio_drive, uint32_t gpio_sense, int adc
/* Write the sense lines HIGH */
imxrt_gpio_write(PX4_MAKE_GPIO_OUTPUT(gpio_sense), 1);
imxrt_gpio_write(PX4_MAKE_GPIO_OUTPUT_CLEAR(gpio_sense), 1);
up_udelay(100); /* About 10 TC assuming 485 K */
@@ -113,6 +113,7 @@ int kinetis_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, boo
#define _PX4_MAKE_GPIO(pin_ftmx, io) ((((uint32_t)(pin_ftmx)) & ~(_PIN_MODE_MASK | _PIN_OPTIONS_MASK)) |(io))
#define PX4_MAKE_GPIO_INPUT(gpio) _PX4_MAKE_GPIO(gpio, GPIO_PULLUP)
#define PX4_MAKE_GPIO_OUTPUT(gpio) _PX4_MAKE_GPIO(gpio, GPIO_HIGHDRIVE)
#define PX4_MAKE_GPIO_OUTPUT_SET(gpio) _PX4_MAKE_GPIO(gpio, GPIO_HIGHDRIVE)
#define PX4_MAKE_GPIO_OUTPUT_CLEAR(gpio) _PX4_MAKE_GPIO(gpio, GPIO_LOWDRIVE)
__END_DECLS
@@ -105,6 +105,7 @@ int imxrt_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, bool
#define px4_arch_gpiosetevent(pinset,r,f,e,fp,a) imxrt_gpiosetevent(pinset,r,f,e,fp,a)
#define PX4_MAKE_GPIO_INPUT(gpio) (((gpio) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_INPUT | IOMUX_SCHMITT_TRIGGER | IOMUX_PULL_UP_47K | IOMUX_DRIVE_HIZ))
#define PX4_MAKE_GPIO_OUTPUT(gpio) (((gpio) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP | IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST))
#define PX4_MAKE_GPIO_OUTPUT_CLEAR(gpio) (((gpio) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP | IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST))
#define PX4_MAKE_GPIO_OUTPUT_SET(gpio) (((gpio) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_OUTPUT | GPIO_OUTPUT_ONE | IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP | IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST))
__END_DECLS
@@ -170,7 +170,7 @@ static int read_id_dn(int *id, uint32_t gpio_drive, uint32_t gpio_sense, int adc
/* Turn the sense lines to digital outputs LOW */
stm32_configgpio(PX4_MAKE_GPIO_OUTPUT(gpio_sense));
stm32_configgpio(PX4_MAKE_GPIO_OUTPUT_CLEAR(gpio_sense));
up_udelay(100); /* About 10 TC assuming 485 K */
@@ -182,7 +182,7 @@ static int read_id_dn(int *id, uint32_t gpio_drive, uint32_t gpio_sense, int adc
/* Write the sense lines HIGH */
stm32_gpiowrite(PX4_MAKE_GPIO_OUTPUT(gpio_sense), 1);
stm32_gpiowrite(PX4_MAKE_GPIO_OUTPUT_CLEAR(gpio_sense), 1);
up_udelay(100); /* About 10 TC assuming 485 K */
@@ -103,7 +103,8 @@ __BEGIN_DECLS
#define px4_arch_gpiosetevent(pinset,r,f,e,fp,a) stm32_gpiosetevent(pinset,r,f,e,fp,a)
#define PX4_MAKE_GPIO_INPUT(gpio) (((gpio) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_INPUT|GPIO_PULLUP))
#define PX4_MAKE_GPIO_OUTPUT(gpio) (((gpio) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR))
#define PX4_MAKE_GPIO_OUTPUT_CLEAR(gpio) (((gpio) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR))
#define PX4_MAKE_GPIO_OUTPUT_SET(gpio) (((gpio) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET))
#define PX4_GPIO_PIN_OFF(def) (((def) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_INPUT|GPIO_FLOAT|GPIO_SPEED_2MHz))
@@ -31,6 +31,7 @@
#
############################################################################
add_subdirectory(broadcom)
add_subdirectory(cm8jl65)
add_subdirectory(leddar_one)
add_subdirectory(ll40ls)
@@ -0,0 +1,34 @@
############################################################################
#
# Copyright (c) 2021 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
#add_subdirectory(afbrs50) # not suitable for general inclusion
@@ -0,0 +1,360 @@
/****************************************************************************
*
* Copyright (c) 2021 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/* Include Files */
#include "AFBRS50.hpp"
#include <lib/drivers/device/Device.hpp>
#include <px4_platform_common/getopt.h>
#include <px4_platform_common/module.h>
#define AFBRS50_MEASURE_INTERVAL (1000000 / 100) // 10Hz
/*! Define the SPI baud rate (to be used in the SPI module). */
#define SPI_BAUD_RATE 5000000
#include "s2pi.h"
#include "timer.h"
#include "argus_hal_test.h"
AFBRS50 *g_dev{nullptr};
AFBRS50::AFBRS50(uint8_t device_orientation):
ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::hp_default),
_px4_rangefinder(0, device_orientation)
{
device::Device::DeviceId device_id{};
device_id.devid_s.bus_type = device::Device::DeviceBusType::DeviceBusType_SPI;
device_id.devid_s.bus = BROADCOM_AFBR_S50_S2PI_SPI_BUS;
device_id.devid_s.devtype = DRV_DIST_DEVTYPE_AFBRS50;
_px4_rangefinder.set_device_id(device_id.devid);
}
AFBRS50::~AFBRS50()
{
stop();
perf_free(_sample_perf);
}
status_t AFBRS50::measurement_ready_callback(status_t status, void *data)
{
if (!up_interrupt_context()) {
if (status == STATUS_OK) {
if (g_dev) {
g_dev->ProcessMeasurement(data);
}
}
}
return status;
}
void AFBRS50::ProcessMeasurement(void *data)
{
if (data != nullptr) {
perf_count(_sample_perf);
argus_results_t res{};
status_t evaluate_status = Argus_EvaluateData(_hnd, &res, data);
if ((evaluate_status == STATUS_OK) && (res.Status == 0)) {
uint32_t result_mm = res.Bin.Range / (Q9_22_ONE / 1000);
float result_m = static_cast<float>(result_mm) / 1000.f;
_px4_rangefinder.update(((res.TimeStamp.sec * 1000000ULL) + res.TimeStamp.usec), result_m);
}
}
}
int AFBRS50::init()
{
if (_hnd != nullptr) {
// retry
Argus_Deinit(_hnd);
Argus_DestroyHandle(_hnd);
_hnd = nullptr;
}
_hnd = Argus_CreateHandle();
if (_hnd == nullptr) {
PX4_ERR("Handle not initialized");
return PX4_ERROR;
}
// Initialize the S2PI hardware required by the API.
S2PI_Init(BROADCOM_AFBR_S50_S2PI_SPI_BUS, SPI_BAUD_RATE);
status_t status = Argus_Init(_hnd, BROADCOM_AFBR_S50_S2PI_SPI_BUS);
if (status == STATUS_OK) {
uint32_t id = Argus_GetChipID(_hnd);
uint32_t value = Argus_GetAPIVersion();
uint8_t a = (value >> 24) & 0xFFU;
uint8_t b = (value >> 16) & 0xFFU;
uint8_t c = value & 0xFFFFU;
PX4_INFO_RAW("AFBR-S50 Chip ID: %d, API Version: %d v%d.%d.%d\n", id, value, a, b, c);
argus_module_version_t mv = Argus_GetModuleVersion(_hnd);
switch (mv) {
case AFBR_S50MV85G_V1:
// FALLTHROUGH
case AFBR_S50MV85G_V2:
// FALLTHROUGH
case AFBR_S50MV85G_V3:
_px4_rangefinder.set_min_distance(0.08f);
_px4_rangefinder.set_max_distance(10.f);
_px4_rangefinder.set_fov(math::radians(6.f));
PX4_INFO_RAW("AFBR-S50MV85G\n");
break;
case AFBR_S50LV85D_V1:
_px4_rangefinder.set_min_distance(0.08f);
_px4_rangefinder.set_max_distance(30.f);
_px4_rangefinder.set_fov(math::radians(6.f));
PX4_INFO_RAW("AFBR-S50LV85D (v1)\n");
break;
case AFBR_S50MV68B_V1:
_px4_rangefinder.set_min_distance(0.08f);
_px4_rangefinder.set_max_distance(10.f);
_px4_rangefinder.set_fov(math::radians(1.f));
PX4_INFO_RAW("AFBR-S50MV68B (v1)\n");
break;
case AFBR_S50MV85I_V1:
_px4_rangefinder.set_min_distance(0.08f);
_px4_rangefinder.set_max_distance(5.f);
_px4_rangefinder.set_fov(math::radians(6.f));
PX4_INFO_RAW("AFBR-S50MV85I (v1)\n");
break;
case AFBR_S50SV85K_V1:
_px4_rangefinder.set_min_distance(0.08f);
_px4_rangefinder.set_max_distance(10.f);
_px4_rangefinder.set_fov(math::radians(4.f));
PX4_INFO_RAW("AFBR-S50SV85K (v1)\n");
break;
default:
break;
}
_state = STATE::CONFIGURE;
ScheduleDelayed(AFBRS50_MEASURE_INTERVAL);
return PX4_OK;
}
return PX4_ERROR;
}
void AFBRS50::Run()
{
// backup schedule
ScheduleDelayed(100_ms);
switch (_state) {
case STATE::TEST: {
Argus_VerifyHALImplementation(Argus_GetSPISlave(_hnd));
_state = STATE::CONFIGURE;
ScheduleDelayed(100_ms);
}
break;
case STATE::CONFIGURE: {
Argus_SetConfigurationFrameTime(_hnd, AFBRS50_MEASURE_INTERVAL);
status_t status = Argus_StartMeasurementTimer(_hnd, measurement_ready_callback);
if (status != STATUS_OK) {
PX4_ERR("CONFIGURE status not okay: %i", status);
_state = STATE::STOP;
ScheduleNow();
} else {
_state = STATE::COLLECT;
ScheduleDelayed(AFBRS50_MEASURE_INTERVAL);
}
}
break;
case STATE::COLLECT: {
// currently handeled by measurement_ready_callback
}
break;
case STATE::STOP: {
Argus_StopMeasurementTimer(_hnd);
Argus_Deinit(_hnd);
Argus_DestroyHandle(_hnd);
}
break;
default:
break;
}
}
void AFBRS50::stop()
{
_state = STATE::STOP;
ScheduleNow();
}
void AFBRS50::print_info()
{
perf_print_counter(_sample_perf);
}
namespace afbrs50
{
static int start(const uint8_t rotation)
{
if (g_dev != nullptr) {
PX4_ERR("already started");
return PX4_ERROR;
}
g_dev = new AFBRS50(rotation);
if (g_dev == nullptr) {
PX4_ERR("object instantiate failed");
return PX4_ERROR;
}
// Initialize the sensor.
if (g_dev->init() != PX4_OK) {
PX4_ERR("driver start failed");
delete g_dev;
g_dev = nullptr;
return PX4_ERROR;
}
return PX4_OK;
}
static int status()
{
if (g_dev == nullptr) {
PX4_ERR("driver not running");
return PX4_ERROR;
}
g_dev->print_info();
return PX4_OK;
}
static int stop()
{
if (g_dev != nullptr) {
delete g_dev;
g_dev = nullptr;
}
PX4_INFO("driver stopped");
return PX4_OK;
}
static int usage()
{
PRINT_MODULE_DESCRIPTION(
R"DESCR_STR(
### Description
Driver for the Broadcom AFBRS50.
### Examples
Attempt to start driver on a specified serial device.
$ afbrs50 start
Stop driver
$ afbrs50 stop
)DESCR_STR");
PRINT_MODULE_USAGE_NAME("afbrs50", "driver");
PRINT_MODULE_USAGE_SUBCATEGORY("distance_sensor");
PRINT_MODULE_USAGE_COMMAND_DESCR("start", "Start driver");
PRINT_MODULE_USAGE_PARAM_STRING('d', nullptr, nullptr, "Serial device", false);
PRINT_MODULE_USAGE_PARAM_INT('r', 25, 0, 25, "Sensor rotation - downward facing by default", true);
PRINT_MODULE_USAGE_COMMAND_DESCR("stop", "Stop driver");
return PX4_OK;
}
} // namespace
extern "C" __EXPORT int afbrs50_main(int argc, char *argv[])
{
const char *myoptarg = nullptr;
int ch = 0;
int myoptind = 1;
uint8_t rotation = distance_sensor_s::ROTATION_DOWNWARD_FACING;
while ((ch = px4_getopt(argc, argv, "d:r", &myoptind, &myoptarg)) != EOF) {
switch (ch) {
case 'r':
rotation = (uint8_t)atoi(myoptarg);
break;
default:
PX4_WARN("Unknown option");
return afbrs50::usage();
}
}
if (myoptind >= argc) {
return afbrs50::usage();
}
if (!strcmp(argv[myoptind], "start")) {
return afbrs50::start(rotation);
} else if (!strcmp(argv[myoptind], "status")) {
return afbrs50::status();
} else if (!strcmp(argv[myoptind], "stop")) {
return afbrs50::stop();
}
return afbrs50::usage();
}
@@ -0,0 +1,92 @@
/****************************************************************************
*
* Copyright (c) 2021 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file AFBRS50.hpp
*
* Driver for the Broadcom AFBR-S50 connected via SPI.
*
*/
#pragma once
#include "argus.h"
#include <drivers/drv_hrt.h>
#include <lib/drivers/rangefinder/PX4Rangefinder.hpp>
#include <lib/perf/perf_counter.h>
#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/defines.h>
#include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
using namespace time_literals;
class AFBRS50 : public px4::ScheduledWorkItem
{
public:
AFBRS50(const uint8_t device_orientation = distance_sensor_s::ROTATION_DOWNWARD_FACING);
~AFBRS50() override;
int init();
/**
* Diagnostics - print some basic information about the driver.
*/
void print_info();
/**
* Stop the automatic measurement state machine.
*/
void stop();
private:
void Run() override;
void ProcessMeasurement(void *data);
static status_t measurement_ready_callback(status_t status, void *data);
argus_hnd_t *_hnd{nullptr};
enum class STATE : uint8_t {
TEST,
CONFIGURE,
COLLECT,
STOP
} _state{STATE::CONFIGURE};
PX4Rangefinder _px4_rangefinder;
hrt_abstime _measurement_time{0};
perf_counter_t _sample_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": sample interval")};
};
@@ -0,0 +1,35 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details This file provides functionality to globally turn IRQs on/off.
*
* @copyright Copyright c 2016-2019, Avago Technologies GmbH.
* All rights reserved.
*
*****************************************************************************/
#ifndef IRQ_H
#define IRQ_H
#ifdef __cplusplus
extern "C" {
#endif
/*!***************************************************************************
* @defgroup IRQ IRQ: Global Interrupt Control
* @ingroup driver
* @brief Global IRQ Module
* @details This module provides functionality to globally enable/disable
* interrupts by turning the I-bit in the CPSR on/off.
* @addtogroup IRQ
* @{
*****************************************************************************/
#include "platform/argus_irq.h"
#ifdef __cplusplus
}
#endif
/*! @} */
#endif /* IRQ_H */
@@ -0,0 +1,107 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details This file provides an interface for the required S2PI module.
*
* @copyright Copyright c 2016-2019, Avago Technologies GmbH.
* All rights reserved.
*
*****************************************************************************/
#ifndef S2PI_H
#define S2PI_H
#ifdef __cplusplus
extern "C" {
#endif
/*!***************************************************************************
* @defgroup SPI SPI: Serial Peripheral Interface
* @ingroup driver
* @brief S2PI: SPI incl. GPIO Hardware Layer Module
*
* @details Provides driver functionality for the S2PI interface module.
*
* The S2PI module consists of a standard SPI interface plus a
* single GPIO interrupt line. Furthermore, the SPI pins are
* accessible via GPIO control to allow a software emulation of
* additional protocols using the same pins.
*
* This module actually implements the #argus_s2pi interface that
* is required for the Argus API. Refer to the module for more
* information.
*
* @addtogroup SPI
* @{
*****************************************************************************/
#include "platform/argus_s2pi.h"
/*! Enables the SPI slaves that utilize a GPIO pin for chip select. */
#define S2PI_GPIO_SLAVES 0
/*! The S2PI slaves. */
enum S2PISlaves {
/*! No SPI slave selected (all pins are disabled w/ high z state). */
S2PI_NONE = 0,
/*! The S2PI slave 1 (connected via adapter board). */
S2PI_S1 = 1,
/*! The S2PI slave 2 (connected via cable). */
S2PI_S2 = 2,
#if S2PI_GPIO_SLAVES
/*! The S2PI slave 3. */
S2PI_S3 = 3,
/*! The S2PI slave 4. */
S2PI_S4 = 4,
/*! The experimental S2PI slave 1 w/ GPIO CS
* (connected via adapter board). */
S2PI_S1_GPIO = 5,
/*! The experimental S2PI slave 2 w/ GPIO CS
* (connected via cable). */
S2PI_S2_GPIO = 6,
#endif
/*! No SPI slave selected (all pins go to low state). */
S2PI_PINS_LOW = 0xFFU,
};
/*!***************************************************************************
* @brief Initializes the S2PI module.
*
* @details Setup the board as a S2PI master, this also sets up up the S2PI pins.
* The SPI interface is initialized with the corresponding default
* SPI slave (i.e. CS and IRQ lines) and the default baud rate.
*
* @param defaultSlave The default SPI slave to be addressed right after
* module initialization.
* @param baudRate_Bps The default SPI baud rate in bauds-per-second.
*
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_Init(s2pi_slave_t defaultSlave, uint32_t baudRate_Bps);
/*!***************************************************************************
* @brief Sets the SPI baud rate in bps.
* @param baudRate_Bps The default SPI baud rate in bauds-per-second.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
* - #STATUS_OK on success
* - #ERROR_S2PI_INVALID_BAUD_RATE on invalid baud rate value.
*****************************************************************************/
status_t S2PI_SetBaudRate(uint32_t baudRate_Bps);
#ifdef __cplusplus
}
#endif
/*! @} */
#endif // S2PI_H
@@ -0,0 +1,52 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details This file provides driver functionality for PIT (periodic interrupt timer).
*
* @copyright Copyright c 2016-2019, Avago Technologies GmbH.
* All rights reserved.
*
*****************************************************************************/
#ifndef TIMER_H
#define TIMER_H
#ifdef __cplusplus
extern "C" {
#endif
/*!***************************************************************************
* @defgroup timer Timer Module
* @ingroup driver
* @brief Timer Hardware Driver Module
* @details Provides driver functionality for the timer peripherals.
* This module actually implements the #argus_timer interface that
* is required for the Argus API. It contains two timing
* functionalities: A periodic interrupt/callback timer and
* an lifetime counter.
*
* Note that the current implementation only features a single
* callback timer interval and does not yet support the feature
* of multiple intervalls at a time.
*
* @addtogroup timer
* @{
*****************************************************************************/
/*******************************************************************************
* Include Files
******************************************************************************/
#include "platform/argus_timer.h"
/*!***************************************************************************
* @brief Initializes the timer hardware.
*****************************************************************************/
void Timer_Init(void);
#ifdef __cplusplus
}
#endif
/*! @} */
#endif /* TIMER_H */
@@ -0,0 +1,24 @@
#include <nuttx/irq.h>
static volatile irqstate_t irqstate_flags;
/*!***************************************************************************
* @brief Enable IRQ Interrupts
*
* @return -
*****************************************************************************/
void IRQ_UNLOCK(void)
{
leave_critical_section(irqstate_flags);
}
/*!***************************************************************************
* @brief Disable IRQ Interrupts
*
* @return -
*****************************************************************************/
void IRQ_LOCK(void)
{
irqstate_flags = enter_critical_section();
}
@@ -0,0 +1,431 @@
#include "irq.h"
#include "s2pi.h"
#include <stdio.h>
#include <board_config.h>
#include <nuttx/spi/spi.h>
#include <drivers/drv_hrt.h>
#include <px4_platform_common/workqueue.h>
#include <lib/perf/perf_counter.h>
/*! A structure to hold all internal data required by the S2PI module. */
typedef struct {
/*! Determines the current driver status. */
volatile status_t Status;
/*! Determines the current S2PI slave. */
volatile s2pi_slave_t Slave;
/*! A callback function to be called after transfer/run mode is completed. */
s2pi_callback_t Callback;
/*! A parameter to be passed to the callback function. */
void *CallbackData;
/*! A callback function to be called after external interrupt is triggered. */
s2pi_irq_callback_t IrqCallback;
/*! A parameter to be passed to the interrupt callback function. */
void *IrqCallbackData;
struct spi_dev_s *spidev;
uint8_t *spi_tx_data;
uint8_t *spi_rx_data;
size_t spi_frame_size;
/*! The mapping of the GPIO blocks and pins for this device. */
const uint32_t GPIOs[ S2PI_IRQ + 1 ];
}
s2pi_handle_t;
s2pi_handle_t s2pi_ = { .GPIOs = { [ S2PI_CLK ] = BROADCOM_AFBR_S50_S2PI_CLK,
[ S2PI_CS ] = BROADCOM_AFBR_S50_S2PI_CS,
[ S2PI_MOSI ] = BROADCOM_AFBR_S50_S2PI_MOSI,
[ S2PI_MISO ] = BROADCOM_AFBR_S50_S2PI_MISO,
[ S2PI_IRQ ] = BROADCOM_AFBR_S50_S2PI_IRQ
}
};
static struct work_s broadcom_s2pi_transfer_work = {};
static perf_counter_t s2pi_transfer_perf = NULL;
static perf_counter_t s2pi_transfer_callback_perf = NULL;
static perf_counter_t s2pi_irq_callback_perf = NULL;
/*!***************************************************************************
* @brief Initialize the S2PI module.
* @details Setup the board as a S2PI master, this also sets up up the S2PI
* pins.
* The SPI interface is initialized with the corresponding default
* SPI slave (i.e. CS and IRQ lines) and the default baud rate.
*
* @param defaultSlave The default SPI slave to be addressed right after
* module initialization.
* @param baudRate_Bps The default SPI baud rate in bauds-per-second.
*
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
static int gpio_falling_edge(int irq, void *context, void *arg)
{
if (s2pi_.IrqCallback != 0) {
perf_begin(s2pi_irq_callback_perf);
s2pi_.IrqCallback(s2pi_.IrqCallbackData);
perf_end(s2pi_irq_callback_perf);
}
return 0;
}
status_t S2PI_Init(s2pi_slave_t defaultSlave, uint32_t baudRate_Bps)
{
px4_arch_configgpio(BROADCOM_AFBR_S50_S2PI_CS);
s2pi_.spidev = px4_spibus_initialize(BROADCOM_AFBR_S50_S2PI_SPI_BUS);
px4_arch_configgpio(BROADCOM_AFBR_S50_S2PI_IRQ);
px4_arch_gpiosetevent(BROADCOM_AFBR_S50_S2PI_IRQ, false, true, false, &gpio_falling_edge, NULL);
s2pi_transfer_perf = perf_alloc(PC_ELAPSED, MODULE_NAME": transfer");
s2pi_transfer_callback_perf = perf_alloc(PC_ELAPSED, MODULE_NAME": transfer callback");
s2pi_irq_callback_perf = perf_alloc(PC_ELAPSED, MODULE_NAME": irq callback");
return S2PI_SetBaudRate(baudRate_Bps);
}
/*!***************************************************************************
* @brief Returns the status of the SPI module.
*
* @return Returns the \link #status_t status\endlink:
* - #STATUS_IDLE: No SPI transfer or GPIO access is ongoing.
* - #STATUS_BUSY: An SPI transfer is in progress.
* - #STATUS_S2PI_GPIO_MODE: The module is in GPIO mode.
*****************************************************************************/
status_t S2PI_GetStatus(void)
{
return s2pi_.Status;
}
/*!***************************************************************************
* @brief Sets the SPI baud rate in bps.
* @param baudRate_Bps The default SPI baud rate in bauds-per-second.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
* - #STATUS_OK on success
* - #ERROR_S2PI_INVALID_BAUD_RATE on invalid baud rate value.
*****************************************************************************/
status_t S2PI_SetBaudRate(uint32_t baudRate_Bps)
{
SPI_SETMODE(s2pi_.spidev, SPIDEV_MODE3);
SPI_SETBITS(s2pi_.spidev, 8);
SPI_SETFREQUENCY(s2pi_.spidev, baudRate_Bps);
return STATUS_OK;
}
/*!*****************************************************************************
* @brief Captures the S2PI pins for GPIO usage.
* @details The SPI is disabled (module status: #STATUS_S2PI_GPIO_MODE) and the
* pins are configured for GPIO operation. The GPIO control must be
* release with the #S2PI_ReleaseGpioControl function in order to
* switch back to ordinary SPI functionality.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_CaptureGpioControl(void)
{
/* Check if something is ongoing. */
IRQ_LOCK();
status_t status = s2pi_.Status;
if (status != STATUS_IDLE) {
IRQ_UNLOCK();
return status;
}
s2pi_.Status = STATUS_S2PI_GPIO_MODE;
IRQ_UNLOCK();
// GPIO mode (output push pull)
px4_arch_configgpio(PX4_MAKE_GPIO_OUTPUT_SET(s2pi_.GPIOs[S2PI_CLK]));
px4_arch_configgpio(PX4_MAKE_GPIO_OUTPUT_SET(s2pi_.GPIOs[S2PI_MISO]));
px4_arch_configgpio(PX4_MAKE_GPIO_OUTPUT_SET(s2pi_.GPIOs[S2PI_MOSI]));
return STATUS_OK;
}
/*!*****************************************************************************
* @brief Releases the S2PI pins from GPIO usage and switches back to SPI mode.
* @details The GPIO pins are configured for SPI operation and the GPIO mode is
* left. Must be called if the pins are captured for GPIO operation via
* the #S2PI_CaptureGpioControl function.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_ReleaseGpioControl(void)
{
/* Check if something is ongoing. */
IRQ_LOCK();
status_t status = s2pi_.Status;
if (status != STATUS_S2PI_GPIO_MODE) {
IRQ_UNLOCK();
return status;
}
s2pi_.Status = STATUS_IDLE;
IRQ_UNLOCK();
// SPI alternate
stm32_configgpio(s2pi_.GPIOs[S2PI_CLK]);
stm32_configgpio(s2pi_.GPIOs[S2PI_MISO]);
stm32_configgpio(s2pi_.GPIOs[S2PI_MOSI]);
// probably not necessary
stm32_spibus_initialize(BROADCOM_AFBR_S50_S2PI_SPI_BUS);
return STATUS_OK;
}
/*!*****************************************************************************
* @brief Writes the output for a specified SPI pin in GPIO mode.
* @details This function writes the value of an SPI pin if the SPI pins are
* captured for GPIO operation via the #S2PI_CaptureGpioControl previously.
* @param slave The specified S2PI slave.
* @param pin The specified S2PI pin.
* @param value The GPIO pin state to write (0 = low, 1 = high).
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_WriteGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t value)
{
/* Check if pin is valid. */
if (pin > S2PI_IRQ || value > 1) {
return ERROR_INVALID_ARGUMENT;
}
/* Check if in GPIO mode. */
if (s2pi_.Status != STATUS_S2PI_GPIO_MODE) {
return ERROR_S2PI_INVALID_STATE;
}
px4_arch_gpiowrite(s2pi_.GPIOs[pin], value);
return STATUS_OK;
}
/*!*****************************************************************************
* @brief Reads the input from a specified SPI pin in GPIO mode.
* @details This function reads the value of an SPI pin if the SPI pins are
* captured for GPIO operation via the #S2PI_CaptureGpioControl previously.
* @param slave The specified S2PI slave.
* @param pin The specified S2PI pin.
* @param value The GPIO pin state to read (0 = low, 1 = high).
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_ReadGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t *value)
{
/* Check if pin is valid. */
if (pin > S2PI_IRQ || !value) {
return ERROR_INVALID_ARGUMENT;
}
/* Check if in GPIO mode. */
if (s2pi_.Status != STATUS_S2PI_GPIO_MODE) {
return ERROR_S2PI_INVALID_STATE;
}
*value = px4_arch_gpioread(s2pi_.GPIOs[pin]);
return STATUS_OK;
}
/*!***************************************************************************
* @brief Cycles the chip select line.
* @details In order to cancel the integration on the ASIC, a fast toggling
* of the chip select pin of the corresponding SPI slave is required.
* Therefore, this function toggles the CS from high to low and back.
* The SPI instance for the specified S2PI slave must be idle,
* otherwise the status #STATUS_BUSY is returned.
* @param slave The specified S2PI slave.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_CycleCsPin(s2pi_slave_t slave)
{
/* Check the driver status. */
IRQ_LOCK();
status_t status = s2pi_.Status;
if (status != STATUS_IDLE) {
IRQ_UNLOCK();
return status;
}
s2pi_.Status = STATUS_BUSY;
IRQ_UNLOCK();
px4_arch_gpiowrite(s2pi_.GPIOs[S2PI_CS], 0);
px4_arch_gpiowrite(s2pi_.GPIOs[S2PI_CS], 1);
s2pi_.Status = STATUS_IDLE;
return STATUS_OK;
}
/*!***************************************************************************
* @brief Transfers a single SPI frame asynchronously.
* @details Transfers a single SPI frame in asynchronous manner. The Tx data
* buffer is written to the device via the MOSI line.
* Optionally the data on the MISO line is written to the provided
* Rx data buffer. If null, the read data is dismissed.
* The transfer of a single frame requires to not toggle the chip
* select line to high in between the data frame.
* An optional callback is invoked when the asynchronous transfer
* is finished. Note that the provided buffer must not change while
* the transfer is ongoing. Use the slave parameter to determine
* the corresponding slave via the given chip select line.
*
* @param slave The specified S2PI slave.
* @param txData The 8-bit values to write to the SPI bus MOSI line.
* @param rxData The 8-bit values received from the SPI bus MISO line
* (pass a null pointer if the data don't need to be read).
* @param frameSize The number of 8-bit values to be sent/received.
* @param callback A callback function to be invoked when the transfer is
* finished. Pass a null pointer if no callback is required.
* @param callbackData A pointer to a state that will be passed to the
* callback. Pass a null pointer if not used.
*
* @return Returns the \link #status_t status\endlink:
* - #STATUS_OK: Successfully invoked the transfer.
* - #ERROR_INVALID_ARGUMENT: An invalid parameter has been passed.
* - #ERROR_S2PI_INVALID_SLAVE: A wrong slave identifier is provided.
* - #STATUS_BUSY: An SPI transfer is already in progress. The
* transfer was not started.
* - #STATUS_S2PI_GPIO_MODE: The module is in GPIO mode. The transfer
* was not started.
*****************************************************************************/
static void broadcom_s2pi_transfer_callout(void *arg)
{
perf_begin(s2pi_transfer_perf);
px4_arch_gpiowrite(s2pi_.GPIOs[S2PI_CS], 0);
SPI_EXCHANGE(s2pi_.spidev, s2pi_.spi_tx_data, s2pi_.spi_rx_data, s2pi_.spi_frame_size);
s2pi_.Status = STATUS_IDLE;
px4_arch_gpiowrite(s2pi_.GPIOs[S2PI_CS], 1);
perf_end(s2pi_transfer_perf);
/* Invoke callback if there is one */
if (s2pi_.Callback != 0) {
perf_begin(s2pi_transfer_callback_perf);
s2pi_callback_t callback = s2pi_.Callback;
s2pi_.Callback = 0;
callback(STATUS_OK, s2pi_.CallbackData);
perf_end(s2pi_transfer_callback_perf);
}
}
status_t S2PI_TransferFrame(s2pi_slave_t spi_slave, uint8_t const *txData, uint8_t *rxData, size_t frameSize,
s2pi_callback_t callback, void *callbackData)
{
/* Verify arguments. */
if (!txData || frameSize == 0 || frameSize >= 0x10000) {
return ERROR_INVALID_ARGUMENT;
}
/* Check the spi slave.*/
if (spi_slave != S2PI_S2) {
return ERROR_S2PI_INVALID_SLAVE;
}
/* Check the driver status, lock if idle. */
IRQ_LOCK();
status_t status = s2pi_.Status;
if (status != STATUS_IDLE) {
IRQ_UNLOCK();
return status;
}
s2pi_.Status = STATUS_BUSY;
/* Set the callback information */
s2pi_.Callback = callback;
s2pi_.CallbackData = callbackData;
s2pi_.spi_tx_data = (uint8_t *)txData;
s2pi_.spi_rx_data = rxData;
s2pi_.spi_frame_size = frameSize;
work_queue(HPWORK, &broadcom_s2pi_transfer_work, broadcom_s2pi_transfer_callout, NULL, 0);
IRQ_UNLOCK();
return STATUS_OK;
}
/*!***************************************************************************
* @brief Terminates a currently ongoing asynchronous SPI transfer.
* @details When a callback is set for the current ongoing activity, it is
* invoked with the #ERROR_ABORTED error byte.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_Abort(void)
{
status_t status = s2pi_.Status;
/* Check if something is ongoing. */
if (status == STATUS_IDLE) {
return STATUS_OK;
}
/* Abort SPI transfer. */
if (status == STATUS_BUSY) {
work_cancel(HPWORK, &broadcom_s2pi_transfer_work);
}
return STATUS_OK;
}
/*!***************************************************************************
* @brief Set a callback for the GPIO IRQ for a specified S2PI slave.
*
* @param slave The specified S2PI slave.
* @param callback A callback function to be invoked when the specified
* S2PI slave IRQ occurs. Pass a null pointer to disable
* the callback.
* @param callbackData A pointer to a state that will be passed to the
* callback. Pass a null pointer if not used.
*
* @return Returns the \link #status_t status\endlink:
* - #STATUS_OK: Successfully installation of the callback.
* - #ERROR_S2PI_INVALID_SLAVE: A wrong slave identifier is provided.
*****************************************************************************/
status_t S2PI_SetIrqCallback(s2pi_slave_t slave, s2pi_irq_callback_t callback, void *callbackData)
{
s2pi_.IrqCallback = callback;
s2pi_.IrqCallbackData = callbackData;
return STATUS_OK;
}
/*!***************************************************************************
* @brief Reads the current status of the IRQ pin.
* @details In order to keep a low priority for GPIO IRQs, the state of the
* IRQ pin must be read in order to reliable check for chip timeouts.
*
* The execution of the interrupt service routine for the data-ready
* interrupt from the corresponding GPIO pin might be delayed due to
* priority issues. The delayed execution might disable the timeout
* for the eye-safety checker too late causing false error messages.
* In order to overcome the issue, the state of the IRQ GPIO input
* pin is read before raising a timeout error in order to check if
* the device has already finished but the IRQ is still pending to be
* executed!
* @param slave The specified S2PI slave.
* @return Returns 1U if the IRQ pin is high (IRQ not pending) and 0U if the
* devices pulls the pin to low state (IRQ pending).
*****************************************************************************/
uint32_t S2PI_ReadIrqPin(s2pi_slave_t slave)
{
return px4_arch_gpioread(s2pi_.GPIOs[S2PI_IRQ]);
}
@@ -0,0 +1,138 @@
#include "timer.h"
#include <drivers/drv_hrt.h>
#include <stdio.h>
#include <board_config.h>
static struct hrt_call broadcom_hrt_call = {};
static timer_cb_t timer_callback_; /*! Callback function for PIT timer */
static uint32_t period_us_;
/*! Storage for the callback parameter */
static void *callback_param_;
static void broadcom_hrt_callout(void *arg)
{
if (timer_callback_ != 0) {
//timer_callback_(arg);
timer_callback_(callback_param_);
hrt_call_after(&broadcom_hrt_call, period_us_, broadcom_hrt_callout, callback_param_);
}
}
void Timer_Init(void)
{
hrt_cancel(&broadcom_hrt_call);
}
/*!***************************************************************************
* @brief Obtains the lifetime counter value from the timers.
*
* @details The function is required to get the current time relative to any
* point in time, e.g. the startup time. The returned values \p hct and
* \p lct are given in seconds and microseconds respectively. The current
* elapsed time since the reference time is then calculated from:
*
* t_now [usec] = hct * 1000000 usec + lct * 1 usec
*
* @param hct A pointer to the high counter value bits representing current
* time in seconds.
* @param lct A pointer to the low counter value bits representing current
* time in microseconds. Range: 0, .., 999999 usec
* @return -
*****************************************************************************/
void Timer_GetCounterValue(uint32_t *hct, uint32_t *lct)
{
hrt_abstime time = hrt_absolute_time();
*hct = time / 1000000ULL;
*lct = time - (*hct * 1000000ULL);
}
/*!***************************************************************************
* @brief Starts the timer for a specified callback parameter.
* @details Sets the callback interval for the specified parameter and starts
* the timer with a new interval. If there is already an interval with
* the given parameter, the timer is restarted with the given interval.
* Passing a interval of 0 disables the timer.
* @param dt_microseconds The callback interval in microseconds.
* @param param An abstract parameter to be passed to the callback. This is
* also the identifier of the given interval.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Timer_Start(uint32_t period, void *param)
{
callback_param_ = param;
period_us_ = period;
if (period != 0) {
hrt_call_after(&broadcom_hrt_call, period, broadcom_hrt_callout, param);
} else {
hrt_cancel(&broadcom_hrt_call);
}
return STATUS_OK;
}
/*!***************************************************************************
* @brief Stops the timer for a specified callback parameter.
* @details Stops a callback interval for the specified parameter.
* @param param An abstract parameter that identifies the interval to be stopped.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Timer_Stop(void *param)
{
period_us_ = 0;
callback_param_ = 0;
hrt_cancel(&broadcom_hrt_call);
return STATUS_OK;
}
/*!***************************************************************************
* @brief Sets the timer interval for a specified callback parameter.
* @details Sets the callback interval for the specified parameter and starts
* the timer with a new interval. If there is already an interval with
* the given parameter, the timer is restarted with the given interval.
* If the same time interval as already set is passed, nothing happens.
* Passing a interval of 0 disables the timer.
* @param dt_microseconds The callback interval in microseconds.
* @param param An abstract parameter to be passed to the callback. This is
* also the identifier of the given interval.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Timer_SetInterval(uint32_t dt_microseconds, void *param)
{
if (dt_microseconds != 0) {
period_us_ = dt_microseconds;
hrt_call_after(&broadcom_hrt_call, dt_microseconds, broadcom_hrt_callout, param);
} else {
hrt_cancel(&broadcom_hrt_call);
}
return STATUS_OK;
}
/*!***************************************************************************
* @brief Installs an periodic timer callback function.
* @details Installs an periodic timer callback function that is invoked whenever
* an interval elapses. The callback is the same for any interval,
* however, the single intervals can be identified by the passed
* parameter.
* Passing a zero-pointer removes and disables the callback.
* @param f The timer callback function.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Timer_SetCallback(timer_cb_t f)
{
timer_callback_ = f;
return STATUS_OK;
}
@@ -0,0 +1,59 @@
############################################################################
#
# Copyright (c) 2021 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
add_library(afbrs50_m4_fpu STATIC IMPORTED GLOBAL)
set_property(TARGET afbrs50_m4_fpu PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/Lib/libafbrs50_m4_fpu.a)
px4_add_module(
MODULE drivers__distance_sensor__afbrs50
MAIN afbrs50
COMPILE_FLAGS
STACK_MAIN
4096
INCLUDES
API/Inc
Inc
SRCS
AFBRS50.cpp
AFBRS50.hpp
API/Src/irq.c
API/Src/s2pi.c
API/Src/timer.c
argus_hal_test.c
DEPENDS
px4_work_queue
drivers_rangefinder
afbrs50_m4_fpu
)
target_link_libraries(afbrs50_m4_fpu INTERFACE drivers__distance_sensor__afbrs50)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,489 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details Defines the dynamic configuration adaption (DCA) setup parameters
* and data structure.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_DCA_H
#define ARGUS_DCA_H
/*!***************************************************************************
* @defgroup argusdca Dynamic Configuration Adaption
* @ingroup argusapi
*
* @brief Dynamic Configuration Adaption (DCA) parameter definitions and API functions.
*
* @details The DCA contains an algorithms that detect ambient conditions
* and adopt the device configuration to the changing parameters
* dynamically while operating the sensor. This is achieved by
* rating the currently received signal quality and changing the
* device configuration accordingly to the gathered information
* from the current measurement frame results before the next
* integration cycle starts.
*
* The DCA consists of the following features:
* - Static or Dynamic mode. The first is utilizing the nominal
* values while the latter is dynamically adopting between min.
* and max. value and starting from the nominal values.
* - Analog Integration Depth Adaption (from multiple patterns down to single pulses)
* - Optical Output Power Adaption
* - Pixel Input Gain Adaption (w/ ambient light rejection)
* - ADC Sensitivity (i.e. ADC Range) Adaption
* - Power Saving Ratio (to decrease the average output power and thus the current consumption)
* - All that features are heeding the Laser Safety limits.
* .
*
* @addtogroup argusdca
* @{
*****************************************************************************/
#include "argus_def.h"
/*! The minimum amplitude threshold value. */
#define ARGUS_CFG_DCA_ATH_MIN (1U << 6U)
/*! The maximum amplitude threshold value. */
#define ARGUS_CFG_DCA_ATH_MAX (0xFFFFU)
/*! The minimum saturated pixel threshold value. */
#define ARGUS_CFG_DCA_PXTH_MIN (1U)
/*! The maximum saturated pixel threshold value. */
#define ARGUS_CFG_DCA_PXTH_MAX (33U)
/*! The maximum analog integration depth in UQ10.6 format,
* i.e. the maximum pattern count per sample. */
#define ARGUS_CFG_DCA_DEPTH_MAX ((uq10_6_t)(ADS_SEQCT_N_MASK << (6U - ADS_SEQCT_N_SHIFT)))
/*! The minimum analog integration depth in UQ10.6 format,
* i.e. the minimum pattern count per sample. */
#define ARGUS_CFG_DCA_DEPTH_MIN ((uq10_6_t)(1U)) // 1/64, i.e. 1/2 nibble
/*! The maximum optical output power, i.e. the maximum VCSEL 1 high current in LSB. */
#define ARGUS_CFG_DCA_POWER_MAX_LSB (ADS_LASET_VCSEL_HC1_MASK >> ADS_LASET_VCSEL_HC1_SHIFT)
/*! The minimum optical output power, i.e. the minimum VCSEL 1 high current in mA. */
#define ARGUS_CFG_DCA_POWER_MIN_LSB (1)
/*! The maximum optical output power, i.e. the maximum VCSEL 1 high current in LSB. */
#define ARGUS_CFG_DCA_POWER_MAX (ADS0032_HIGH_CURRENT_LSB2MA(ARGUS_CFG_DCA_POWER_MAX_LSB + 1))
/*! The minimum optical output power, i.e. the minimum VCSEL 1 high current in mA. */
#define ARGUS_CFG_DCA_POWER_MIN (1)
/*! The dynamic configuration algorithm Pixel Input Gain stage count. */
#define ARGUS_DCA_GAIN_STAGE_COUNT (4U)
/*! The dynamic configuration algorithm state mask for the Pixel Input Gain stage. */
#define ARGUS_STATE_DCA_GAIN_MASK (0x03U)
/*! The dynamic configuration algorithm state mask for the Pixel Input Gain stage. */
#define ARGUS_STATE_DCA_GAIN_SHIFT (14U)
/*! Getter for the dynamic configuration algorithm Pixel Input Gain stage. */
#define ARGUS_STATE_DCA_GAIN_GET(state) \
(((state) >> ARGUS_STATE_DCA_GAIN_SHIFT) & ARGUS_STATE_DCA_GAIN_MASK)
/*! The dynamic configuration algorithm Optical Output Power stage count. */
#define ARGUS_DCA_POWER_STAGE_COUNT (4U)
/*! The dynamic configuration algorithm state mask for the Optical Output Power stage. */
#define ARGUS_STATE_DCA_POWER_MASK (0x03U)
/*! The dynamic configuration algorithm state mask for the Optical Output Power stage. */
#define ARGUS_STATE_DCA_POWER_SHIFT (12U)
/*! Getter for the dynamic configuration algorithm Optical Output Power stage. */
#define ARGUS_STATE_DCA_POWER_GET(state) \
(((state) >> ARGUS_STATE_DCA_POWER_SHIFT) & ARGUS_STATE_DCA_POWER_MASK)
/*! The dynamic configuration algorithm state mask for the Max. Analog Integration Depth shift value. */
#define ARGUS_STATE_DCA_DEPTH_SHFT_MASK (0x0FU)
/*! The dynamic configuration algorithm state mask for the Max. Analog Integration Depth shift value. */
#define ARGUS_STATE_DCA_DEPTH_SHFT_SHIFT (8U)
/*! Getter for the dynamic configuration algorithm Max. Analog Integration Depth shift value. */
#define ARGUS_STATE_DCA_DEPTH_SHFT_GET(state) \
(((state) >> ARGUS_STATE_DCA_DEPTH_SHFT_SHIFT) & ARGUS_STATE_DCA_DEPTH_SHFT_MASK)
/*!***************************************************************************
* @brief The dynamic configuration algorithm enable flags.
*****************************************************************************/
typedef enum {
/*! DCA is disabled and will be completely skipped. */
DCA_ENABLE_OFF = 0,
/*! DCA is enabled and will dynamically adjust the device configuration. */
DCA_ENABLE_DYNAMIC = 1,
/*! DCA is enabled and will apply the static (nominal) values to the device. */
DCA_ENABLE_STATIC = -1,
} argus_dca_enable_t;
/*!***************************************************************************
* @brief The dynamic configuration algorithm Optical Output Power stages enumerator.
*****************************************************************************/
typedef enum {
/*! Low output power stage. */
DCA_POWER_LOW = 0,
/*! Medium low output power stage. */
DCA_POWER_MEDIUM_LOW = 1,
/*! Medium high output power stage. */
DCA_POWER_MEDIUM_HIGH = 2,
/*! High output power stage. */
DCA_POWER_HIGH = 3
} argus_dca_power_t;
/*!***************************************************************************
* @brief The dynamic configuration algorithm Pixel Input Gain stages enumerator.
*****************************************************************************/
typedef enum {
/*! Low gain stage. */
DCA_GAIN_LOW = 0,
/*! Medium low gain stage. */
DCA_GAIN_MEDIUM_LOW = 1,
/*! Medium high gain stage. */
DCA_GAIN_MEDIUM_HIGH = 2,
/*! High gain stage. */
DCA_GAIN_HIGH = 3
} argus_dca_gain_t;
/*!***************************************************************************
* @brief State flags for the current frame.
* @details State flags determine the current state of the measurement frame:
* - [0]: #ARGUS_STATE_MEASUREMENT_MODE: Measurement Mode:
* - 0: Mode A
* - 1: Mode B
* .
* - [1]: #ARGUS_STATE_DUAL_FREQ_MODE: Dual Frequency Mode Enabled Flag
* - 0: Disabled, measurements w/ base frequency only
* - 1: Enabled, measurements w/ detuned frequency
* .
* - [2]: #ARGUS_STATE_MEASUREMENT_FREQ: Measurement Frequency for
* Dual Frequency Mode, (only valid if #ARGUS_STATE_DUAL_FREQ_MODE
* flag is set)
* - 0: A-Frame w/ detuned frequency
* - 1: B-Frame w/ detuned frequency
* .
* - [3]: #ARGUS_STATE_DEBUG_MODE
* - [4]: #ARGUS_STATE_GOLDEN_PIXEL_MODE
* - [5]: #ARGUS_STATE_BGL_WARNING
* - [6]: #ARGUS_STATE_BGL_ERROR
* - [7]: #ARGUS_STATE_PLL_LOCKED
* - 0: PLL_LOCKED bit was not set at start of integration;
* - 0: PLL_LOCKED bit was set at start of integration;
* .
* - [8-11]: Max. Depth Shift Value
* - [12-13]: Power Stages
* - [14-15]: Gain Stages
* .
*****************************************************************************/
typedef enum {
/*! No state flag set. */
ARGUS_STATE_NONE = 0,
/*! 0x01: Measurement Mode.
* - 0: Mode A: Long Range / Medium Precision
* - 1: Mode B: Short Range / High Precision */
ARGUS_STATE_MEASUREMENT_MODE = 1U << 0U,
/*! 0x02: Dual Frequency Mode Enabled.
* - 0: Disabled: measurements with base frequency,
* - 1: Enabled: measurement with detuned frequency. */
ARGUS_STATE_DUAL_FREQ_MODE = 1U << 1U,
/*! 0x04: Measurement Frequency for Dual Frequency Mode
* (only if #ARGUS_STATE_DUAL_FREQ_MODE flag is set).
* - 0: A-Frame w/ detuned frequency,
* - 1: B-Frame w/ detuned frequency */
ARGUS_STATE_MEASUREMENT_FREQ = 1U << 2U,
/*! 0x08: Debug Mode. If set, the range value of erroneous pixels are not
* cleared or reset.
* - 0: Disabled (default).
* - 1: Enabled. */
ARGUS_STATE_DEBUG_MODE = 1U << 3U,
/*! 0x10: Golden Pixel Mode Flag.
* Set whenever the Pixel Binning Algorithm is operating in the
* Golden Pixel Mode.
* - 0: Normal Pixel Binning Mode.
* - 1: Golden Pixel Mode. */
ARGUS_STATE_GOLDEN_PIXEL_MODE = 1U << 4U,
/*! 0x20: Background Light Warning Flag.
* Set whenever the background light is very high and the
* measurement data might be unreliable.
* - 0: No Warning Background Light is within valid range.
* - 1: Warning: Background Light is very high. */
ARGUS_STATE_BGL_WARNING = 1U << 5U,
/*! 0x40: Background Light Error Flag.
* Set whenever the background light is too high and the
* measurement data is unreliable or invalid.
* - 0: No Error, Background Light is within valid range.
* - 1: Error: Background Light is too high. */
ARGUS_STATE_BGL_ERROR = 1U << 6U,
/*! 0x80: PLL_LOCKED bit.
* - 0: PLL not locked at start of integration.
* - 1: PLL locked at start of integration. */
ARGUS_STATE_PLL_LOCKED = 1U << 7U,
/*! DCA is in low Optical Output Power stage. */
ARGUS_STATE_DCA_POWER_LOW = DCA_GAIN_LOW << ARGUS_STATE_DCA_POWER_SHIFT,
/*! DCA is in medium-low Optical Output Power stage. */
ARGUS_STATE_DCA_POWER_MED_LOW = DCA_GAIN_MEDIUM_LOW << ARGUS_STATE_DCA_POWER_SHIFT,
/*! DCA is in medium-high Optical Output Power stage. */
ARGUS_STATE_DCA_POWER_MED_HIGH = DCA_GAIN_MEDIUM_HIGH << ARGUS_STATE_DCA_POWER_SHIFT,
/*! DCA is in high Optical Output Power stage. */
ARGUS_STATE_DCA_POWER_HIGH = DCA_GAIN_HIGH << ARGUS_STATE_DCA_POWER_SHIFT,
/*! DCA is in low Pixel Input Gain stage. */
ARGUS_STATE_DCA_GAIN_LOW = DCA_GAIN_LOW << ARGUS_STATE_DCA_GAIN_SHIFT,
/*! DCA is in medium-low Pixel Input Gain stage. */
ARGUS_STATE_DCA_GAIN_MED_LOW = DCA_GAIN_MEDIUM_LOW << ARGUS_STATE_DCA_GAIN_SHIFT,
/*! DCA is in medium-high Pixel Input Gain stage. */
ARGUS_STATE_DCA_GAIN_MED_HIGH = DCA_GAIN_MEDIUM_HIGH << ARGUS_STATE_DCA_GAIN_SHIFT,
/*! DCA is in high Pixel Input Gain stage. */
ARGUS_STATE_DCA_GAIN_HIGH = DCA_GAIN_HIGH << ARGUS_STATE_DCA_GAIN_SHIFT,
} argus_state_t;
/*!***************************************************************************
* @brief Dynamic Configuration Adaption (DCA) Parameters.
* @details DCA contains:
* - Static or dynamic mode. The first is utilizing the nominal values
* while the latter is dynamically adopting between min. and max.
* value and starting form the nominal values.
* - Analog Integration Depth Adaption down to single pulses.
* - Optical Output Power Adaption
* - Pixel Input Gain Adaption
* - Digital Integration Depth Adaption
* - Dynamic Global Phase Shift Injection.
* - All that features are heeding the Laser Safety limits.
* .
*****************************************************************************/
typedef struct {
/*! Enables the automatic configuration adaption features.
* Enables the dynamic part if #DCA_ENABLE_DYNAMIC and the static only if
* #DCA_ENABLE_STATIC. If set to DCA_ENABLE_OFF, the DCA is completely
* skipped and the static register values are considered which is
* recommended for advanced debugging only. */
argus_dca_enable_t Enabled;
/*! The threshold value of saturated pixels that causes a linear reduction
* of the integration energy, i.e. if the number of saturated pixels are
* larger or equal to this value, the integration energy will be reduced
* by a single step (one pattern if the current integration depth is > 1,
* one pulse if the current integration depth is <= 1 or one power LSB for
* the optical power range).
*
* Valid values: 1, ..., 33; (use 33 to disable the linear decrease)
* Note that the linear value must be smaller or equal to the exponential
* value. To sum up, it must hold:
* 1 <= SatPxThLin <= SatPxThExp <= SatPxThRst <= 33 */
uint8_t SatPxThLin;
/*! The threshold number of saturated pixels that causes a exponential
* reduction of the integration energy, i.e. if the number of saturated
* pixels is larger or equal to this value, the integration energy will be
* halved.
*
* Valid values: 1, ..., 33; (use 33 to disable the exponential decrease)
* Note that the exponential value must be between the linear and reset
* values. To sum up, it must hold:
* 1 <= SatPxThLin <= SatPxThExp <= SatPxThRst <= 33 */
uint8_t SatPxThExp;
/*! The threshold number of saturated pixels that causes a sudden reset of
* the integration energy to the minimal value, i.e. if the number of
* saturated pixels are larger or equal to this value, the integration
* energy will suddenly be reset to the minimum values. The gain setting
* will stay at the mid value and a decrease happens after the next step
* if still required.
*
* Valid values: 1, ..., 33; (use 33 to disable the sudden reset)
* Note that the reset value must be larger or equal to the exponential
* value. To sum up, it must hold:
* 1 <= SatPxThLin <= SatPxThExp <= SatPxThRst <= 33 */
uint8_t SatPxThRst;
/*! The amplitude to be targeted from the lower regime. If the amplitude
* lower than the target value, a linear increase of integration energy
* will happen in order to optimize for best performance.
*
* Valid values: #ARGUS_CFG_DCA_ATH_MIN, ... #ARGUS_CFG_DCA_ATH_MAX or 0
* Set 0 to disable optimization toward the target amplitude.
* Note further that the following condition must hold:
* 'MIN' <= AthLow <= Atarget <= AthHigh <= 'MAX' */
uq12_4_t Atarget;
/*! The low threshold value for the max. amplitude. If the max. amplitude
* falls below this value, the integration depth will be increases.
*
* Valid values: #ARGUS_CFG_DCA_ATH_MIN, ... #ARGUS_CFG_DCA_ATH_MAX
* Note further that the following condition must hold:
* 'MIN' <= AthLow <= Atarget <= AthHigh <= 'MAX' */
uq12_4_t AthLow;
/*! The high threshold value for the max. amplitude. If the max. amplitude
* exceeds this value, the integration depth will be decreases. Note that
* also saturated pixels will cause a decrease of the integration depth.
*
* Valid values: #ARGUS_CFG_DCA_ATH_MIN, ... #ARGUS_CFG_DCA_ATH_MAX
* Note further that the following condition must hold:
* 'MIN' <= AthLow <= Atarget <= AthHigh <= 'MAX' */
uq12_4_t AthHigh;
/*! The nominal analog integration depth in UQ10.6 format,
* i.e. the nominal pattern count per sample.
*
* Valid values: #ARGUS_CFG_DCA_DEPTH_MIN, ... #ARGUS_CFG_DCA_DEPTH_MAX
* Note further that the following condition must hold:
* 'MIN' <= DepthLow <= DepthNom <= DepthHigh <= 'MAX' */
uq10_6_t DepthNom;
/*! The minimum analog integration depth in UQ10.6 format,
* i.e. the minimum pattern count per sample.
*
* Valid values: #ARGUS_CFG_DCA_DEPTH_MIN, ... #ARGUS_CFG_DCA_DEPTH_MAX
* Note further that the following condition must hold:
* 'MIN' <= DepthLow <= DepthNom <= DepthHigh <= 'MAX' */
uq10_6_t DepthMin;
/*! The maximum analog integration depth in UQ10.6 format,
* i.e. the maximum pattern count per sample.
*
* Valid values: #ARGUS_CFG_DCA_DEPTH_MIN, ... #ARGUS_CFG_DCA_DEPTH_MAX
* Note further that the following condition must hold:
* 'MIN' <= DepthMin <= DepthNom <= DepthMax <= 'MAX' */
uq10_6_t DepthMax;
/*! The nominal optical output power in mA,
* i.e. the nominal VCSEL_HC1 setting.
*
* Valid values: #ARGUS_CFG_DCA_POWER_MIN, ... #ARGUS_CFG_DCA_POWER_MAX
* Note further that the following condition must hold:
* 'MIN' <= PowerMin <= PowerNom <= 'MAX' */
uq12_4_t PowerNom;
/*! The minimum optical output power in mA,
* i.e. the minimum VCSEL_HC1 setting.
*
* Valid values: #ARGUS_CFG_DCA_POWER_MIN, ... #ARGUS_CFG_DCA_POWER_MAX
* Note further that the following condition must hold:
* 'MIN' <= PowerMin <= PowerNom <= 'MAX' */
uq12_4_t PowerMin;
/*! The nominal pixel gain setting, i.e. the setting for
* nominal/default gain stage.
*
* Valid values: 0,..,3: #DCA_GAIN_LOW, ... #DCA_GAIN_HIGH
* Note further that the following condition must hold:
* 'MIN' <= GainMin <= GainNom <= GainMax <= 'MAX' */
argus_dca_gain_t GainNom;
/*! The minimal pixel gain setting, i.e. the setting for
* minimum gain stage.
*
* Valid values: 0,..,3: #DCA_GAIN_LOW, ... #DCA_GAIN_HIGH
* Note further that the following condition must hold:
* 'MIN' <= GainMin <= GainNom <= GainMax <= 'MAX' */
argus_dca_gain_t GainMin;
/*! The maximum pixel gain setting, i.e. the setting for
* maximum gain stage.
*
* Valid values: 0,..,3: #DCA_GAIN_LOW, ... #DCA_GAIN_HIGH
* Note further that the following condition must hold:
* 'MIN' <= GainMin <= GainNom <= GainMax <= 'MAX' */
argus_dca_gain_t GainMax;
/*! Power Saving Ratio value.
*
* Determines the percentage of the full available frame time that is not
* exploited for digital integration. Thus the device is idle within the
* specified portion of the frame time and does consume less energy.
*
* Note that the laser safety might already limit the maximum integration
* depth and the power saving ratio might not take effect for all ambient
* situations. Thus the Power Saving Ratio is to be understood as a minimum
* percentage where the device is idle per frame.
*
* The value is a UQ0.8 format that ranges from 0.0 (=0x00) to 0.996 (=0xFF),
* where 0 means no power saving (i.e. feature disabled) and 0xFF determines
* maximum power saving, i.e. the digital integration depth is limited to a
* single sample.
*
* Range: 0x00, .., 0xFF; set 0 to disable. */
uq0_8_t PowerSavingRatio;
} argus_cfg_dca_t;
/*! @} */
#endif /* ARGUS_DCA_H */
@@ -0,0 +1,205 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 hardware API.
* @details This file provides generic definitions belonging to all
* devices from the AFBR-S50 product family.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_DEF_H
#define ARGUS_DEF_H
/*!***************************************************************************
* Include files
*****************************************************************************/
#include "argus_status.h"
#include "argus_version.h"
#include "utility/fp_def.h"
#include "utility/time.h"
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
/*!***************************************************************************
* @addtogroup argusapi
* @{
*****************************************************************************/
/*!***************************************************************************
* @brief Maximum number of phases per measurement cycle.
* @details The actual phase number is defined in the register configuration.
* However the software does only support a fixed value of 4 yet.
*****************************************************************************/
#define ARGUS_PHASECOUNT 4U
/*!***************************************************************************
* @brief The device pixel field size in x direction (long edge).
*****************************************************************************/
#define ARGUS_PIXELS_X 8U
/*!***************************************************************************
* @brief The device pixel field size in y direction (short edge).
*****************************************************************************/
#define ARGUS_PIXELS_Y 4U
/*!***************************************************************************
* @brief The total device pixel count.
*****************************************************************************/
#define ARGUS_PIXELS ((ARGUS_PIXELS_X)*(ARGUS_PIXELS_Y))
/*!***************************************************************************
* @brief The AFBR-S50 module types.
*****************************************************************************/
typedef enum {
/*! No device connected or not recognized. */
MODULE_NONE = 0,
/*! AFBR-S50MV85G: an ADS0032 based multi-pixel range finder device
* w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
* medium range 3D applications.
* Version 1 - legacy version! */
AFBR_S50MV85G_V1 = 1,
/*! AFBR-S50MV85G: an ADS0032 based multi-pixel range finder device
* w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
* medium range 3D applications.
* Version 2 - legacy version! */
AFBR_S50MV85G_V2 = 2,
/*! AFBR-S50MV85G: an ADS0032 based multi-pixel range finder device
* w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
* medium range 3D applications.
* Version 7 - current version! */
AFBR_S50MV85G_V3 = 7,
/*! AFBR-S50LV85D: an ADS0032 based multi-pixel range finder device
* w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
* long range 1D applications.
* Version 1 - current version! */
AFBR_S50LV85D_V1 = 3,
/*! AFBR-S50MV68B: an ADS0032 based multi-pixel range finder device
* w/ 4x8 pixel matrix and red, 680 nm, laser source for
* medium range 1D applications.
* Version 1 - current version! */
AFBR_S50MV68B_V1 = 4,
/*! AFBR-S50MV85I: an ADS0032 based multi-pixel range finder device
* w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
* medium range 3D applications.
* Version 1 - current version! */
AFBR_S50MV85I_V1 = 5,
/*! AFBR-S50MV85G: an ADS0032 based multi-pixel range finder device
* w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
* short range 3D applications.
* Version 1 - current version! */
AFBR_S50SV85K_V1 = 6,
/*! Reserved for future extensions. */
Reserved = 0b111111
} argus_module_version_t;
/*!***************************************************************************
* @brief The AFBR-S50 laser configurations.
*****************************************************************************/
typedef enum {
/*! No laser connected. */
LASER_NONE = 0,
/*! 850nm Infra-Red VCSEL v1 */
LASER_H_V1 = 1,
/*! 850nm Infra-Red VCSEL v2 */
LASER_H_V2 = 2,
/*! 680nm Red VCSEL v1 */
LASER_R_V1 = 3,
} argus_laser_type_t;
/*!***************************************************************************
* @brief The AFBR-S50 chip versions.
*****************************************************************************/
typedef enum {
/*! No device connected or not recognized. */
ADS0032_NONE = 0,
/*! ADS0032 v1.0 */
ADS0032_V1_0 = 1,
/*! ADS0032 v1.1 */
ADS0032_V1_1 = 2,
/*! ADS0032 v1.2 */
ADS0032_V1_2 = 3,
} argus_chip_version_t;
/*!***************************************************************************
* @brief The number of measurement modes with distinct configuration and
* calibration records.
*****************************************************************************/
#define ARGUS_MODE_COUNT (2)
/*!***************************************************************************
* @brief The measurement modes.
*****************************************************************************/
typedef enum {
/*! Measurement Mode A: Long Range Mode. */
ARGUS_MODE_A = 1,
/*! Measurement Mode B: Short Range Mode. */
ARGUS_MODE_B = 2,
} argus_mode_t;
/*!***************************************************************************
* @brief Generic API callback function.
* @details Invoked by the API. The content of the abstract data pointer
* depends upon the context.
* @param status The module status that caused the callback. #STATUS_OK if
* everything was as expected.
* @param data An abstract pointer to an user defined data. This will
* usually be passed to the function that also takes the
* callback as an parameter. Otherwise it has a special
* meaning such as configuration or calibration data.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
typedef status_t (*argus_callback_t)(status_t status, void *data);
/*! @} */
#endif /* ARGUS_DEF_H */
@@ -0,0 +1,81 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details Defines the dual frequency mode (DFM) setup parameters.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_DFM_H
#define ARGUS_DFM_H
/*!***************************************************************************
* @defgroup argusdfm Dual Frequency Mode
* @ingroup argusdev
*
* @brief Dual Frequency Mode (DFM) parameter definitions and API functions.
*
* @details The DFM is an algorithm to extend the unambiguous range of the
* sensor by utilizing two detuned measurement frequencies.
*
* The AFBR-S50 API provides three measurement modes:
* - 1X: Single Frequency Measurement
* - 4X: Dual Frequency Measurement w/ 4 times the unambiguous
* range of the Single Frequency Measurement
* - 8X: Dual Frequency Measurement w/ 8 times the unambiguous
* range of the Single Frequency Measurement
*
* @addtogroup argusdfm
* @{
*****************************************************************************/
/*! The Dual Frequency Mode frequency count. */
#define ARGUS_DFM_FRAME_COUNT (2U)
/*! The Dual Frequency Mode measurement modes count. Excluding the disabled mode. */
#define ARGUS_DFM_MODE_COUNT (2U) // expect off-mode!
/*! The Dual Frequency Mode measurement modes enumeration. */
typedef enum {
/*! Single Frequency Measurement Mode (w/ 1x Unambiguous Range). */
DFM_MODE_OFF = 0U,
/*! 4X Dual Frequency Measurement Mode (w/ 4x Unambiguous Range). */
DFM_MODE_4X = 1U,
/*! 8X Dual Frequency Measurement Mode (w/ 8x Unambiguous Range). */
DFM_MODE_8X = 2U,
} argus_dfm_mode_t;
/*! @} */
#endif /* ARGUS_DFM_H */
@@ -0,0 +1,118 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 hardware API.
* @details Defines the generic measurement parameters and data structures.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_MEAS_H
#define ARGUS_MEAS_H
/*!***************************************************************************
* @defgroup argusmeas Measurement/Device Control
* @ingroup argusapi
*
* @brief Measurement/Device control module
*
* @details This module contains measurement and device control specific
* definitions and methods.
*
* @addtogroup argusmeas
* @{
*****************************************************************************/
#include "argus_dca.h"
#include "argus_def.h"
/*! Number of raw data values. */
#define ARGUS_RAW_DATA_VALUES 132U // 33 channels * 4 phases
/*! Size of the raw data in bytes. */
#define ARGUS_RAW_DATA_SIZE (3U * ARGUS_RAW_DATA_VALUES) // 3 bytes * 33 channels * 4 phases
/*! The number channels for auxiliary measurements readout. */
#define ARGUS_AUX_CHANNEL_COUNT (5U)
/*! Size of the auxiliary data in bytes. */
#define ARGUS_AUX_DATA_SIZE (3U * ARGUS_AUX_CHANNEL_COUNT) // 3 bytes * x channels * 1 phase
/*!***************************************************************************
* @brief The device measurement configuration structure.
* @details The portion of the configuration data that belongs to the
* measurement cycle. I.e. the data that defines a measurement frame.
*****************************************************************************/
typedef struct {
/*! ADC channel enabled mask for the first
* channels 0 .. 31 (active pixels channels).
* See [pixel mapping](@ref argusmap) for more
* details on the pixel mask. */
uint32_t PxEnMask;
/*! ADS channel enabled mask for the remaining
* channels 31 .. 63 (miscellaneous values).
* See [pixel mapping](@ref argusmap) for more
* details on the channel mask. */
uint32_t ChEnMask;
/*! Pattern count per sample in uq10.6 format.
* Determines the analog integration depth. */
uq10_6_t AnalogIntegrationDepth;
/*! Sample count per phase/frame.
* Determines the digital integration depth. */
uint16_t DigitalIntegrationDepth;
/*! Laser current per sample in mA.
* Determines the optical output power. */
uq12_4_t OutputPower;
/*! Charge pump voltage per sample in LSB.
* Determines the pixel gain. */
uint8_t PixelGain;
/*! PLL Frequency Offset, caused by temperature
* compensation, in PLL_INT_PRD LSBs. */
int8_t PllOffset;
/*! The current state of the measurement frame:
* - Measurement Mode,
* - A/B Frame,
* - PLL_Locked Bit,
* - BGL Warning/Error,
* - DCA State,
* - ... */
argus_state_t State;
} argus_meas_frame_t;
/*! @} */
#endif /* ARGUS_MEAS_H */
@@ -0,0 +1,170 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details Defines macros to work with pixel and ADC channel masks.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_MSK_H
#define ARGUS_MSK_H
/*!***************************************************************************
* @defgroup argusmap ADC Channel Mapping
* @ingroup argusres
*
* @brief Pixel ADC Channel (n) to x-y-Index Mapping
*
* @details The ADC Channels of each pixel or auxiliary channel on the device
* is numbered in a way that is convenient on the chip. The macros
* in this module are defined in order to obtain the x-y-indices of
* each channel and vice versa.
*
* @addtogroup argusmap
* @{
*****************************************************************************/
#include "api/argus_def.h"
#include "utility/int_math.h"
/*!*****************************************************************************
* @brief Macro to determine the channel number of an specified Pixel.
* @param x The x index of the pixel.
* @param y The y index of the pixel.
* @return The channel number n of the pixel.
******************************************************************************/
#define PIXEL_XY2N(x, y) ((((x) ^ 7) << 1) | ((y) & 2) << 3 | ((y) & 1))
/*!*****************************************************************************
* @brief Macro to determine the x index of an specified Pixel channel.
* @param n The channel number of the pixel.
* @return The x index number of the pixel.
******************************************************************************/
#define PIXEL_N2X(n) ((((n) >> 1U) & 7) ^ 7)
/*!*****************************************************************************
* @brief Macro to determine the y index of an specified Pixel channel.
* @param n The channel number of the pixel.
* @return The y index number of the pixel.
******************************************************************************/
#define PIXEL_N2Y(n) (((n) & 1U) | (((n) >> 3) & 2U))
/*!*****************************************************************************
* @brief Macro to determine if a ADC Pixel channel was enabled from a pixel mask.
* @param msk The 32-bit pixel mask
* @param ch The channel number of the pixel.
* @return True if the pixel channel n was enabled, false elsewise.
******************************************************************************/
#define PIXELN_ISENABLED(msk, ch) (((msk) >> (ch)) & 0x01U)
/*!*****************************************************************************
* @brief Macro enables an ADC Pixel channel in a pixel mask.
* @param msk The 32-bit pixel mask
* @param ch The channel number of the pixel.
******************************************************************************/
#define PIXELN_ENABLE(msk, ch) ((msk) |= (0x01U << (ch)))
/*!*****************************************************************************
* @brief Macro disables an ADC Pixel channel in a pixel mask.
* @param msk The 32-bit pixel mask
* @param ch The channel number of the pixel.
******************************************************************************/
#define PIXELN_DISABLE(msk, ch) ((msk) &= (~(0x01U << (ch))))
/*!*****************************************************************************
* @brief Macro to determine if an ADC Pixel channel was enabled from a pixel mask.
* @param msk 32-bit pixel mask
* @param x x index of the pixel.
* @param y y index of the pixel.
* @return True if the pixel (x,y) was enabled, false elsewise.
******************************************************************************/
#define PIXELXY_ISENABLED(msk, x, y) (PIXELN_ISENABLED(msk, PIXEL_XY2N(x, y)))
/*!*****************************************************************************
* @brief Macro enables an ADC Pixel channel in a pixel mask.
* @param msk 32-bit pixel mask
* @param x x index of the pixel.
* @param y y index of the pixel.
******************************************************************************/
#define PIXELXY_ENABLE(msk, x, y) (PIXELN_ENABLE(msk, PIXEL_XY2N(x, y)))
/*!*****************************************************************************
* @brief Macro disables an ADC Pixel channel in a pixel mask.
* @param msk 32-bit pixel mask
* @param x x index of the pixel.
* @param y y index of the pixel.
******************************************************************************/
#define PIXELXY_DISABLE(msk, x, y) (PIXELN_DISABLE(msk, PIXEL_XY2N(x, y)))
/*!*****************************************************************************
* @brief Macro to determine if a ADC channel was enabled from a channel mask.
* @param msk 32-bit channel mask
* @param ch channel number of the ADC channel.
* @return True if the ADC channel n was enabled, false elsewise.
******************************************************************************/
#define CHANNELN_ISENABLED(msk, ch) (((msk) >> ((ch) - 32U)) & 0x01U)
/*!*****************************************************************************
* @brief Macro to determine if a ADC channel was enabled from a channel mask.
* @param msk 32-bit channel mask
* @param ch channel number of the ADC channel.
* @return True if the ADC channel n was enabled, false elsewise.
******************************************************************************/
#define CHANNELN_ENABLE(msk, ch) ((msk) |= (0x01U << ((ch) - 32U)))
/*!*****************************************************************************
* @brief Macro to determine if a ADC channel was enabled from a channel mask.
* @param msk 32-bit channel mask
* @param ch channel number of the ADC channel.
* @return True if the ADC channel n was enabled, false elsewise.
******************************************************************************/
#define CHANNELN_DISABLE(msk, ch) ((msk) &= (~(0x01U << ((ch) - 32U))))
/*!*****************************************************************************
* @brief Macro to determine the number of enabled pixel channels via a popcount
* algorithm.
* @param pxmsk 32-bit pixel mask
* @return The count of enabled pixel channels.
******************************************************************************/
#define PIXEL_COUNT(pxmsk) popcount(pxmsk)
/*!*****************************************************************************
* @brief Macro to determine the number of enabled channels via a popcount
* algorithm.
* @param pxmsk 32-bit pixel mask
* @param chmsk 32-bit channel mask
* @return The count of enabled ADC channels.
******************************************************************************/
#define CHANNEL_COUNT(pxmsk, chmsk) (popcount(pxmsk) + popcount(chmsk))
/*! @} */
#endif /* ARGUS_MSK_H */
@@ -0,0 +1,221 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details Defines the pixel binning algorithm (PBA) setup parameters and
* data structure.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_PBA_H
#define ARGUS_PBA_H
/*!***************************************************************************
* @defgroup arguspba Pixel Binning Algorithm
* @ingroup argusapi
*
* @brief Pixel Binning Algorithm (PBA) parameter definitions and API functions.
*
* @details Defines the generic pixel binning algorithm (PBA) setup parameters
* and data structure.
*
* The PBA module contains filter algorithms that determine the
* pixels with the best signal quality and extract an 1d distance
* information from the filtered pixels.
*
* The pixel filter algorithm is a three-stage filter with a
* fallback value:
*
* -# A fixed pre-filter mask is applied to statically disable
* specified pixels.
* -# A relative and absolute amplitude filter is applied in the
* second stage. The relative filter is determined by a ratio
* of the maximum amplitude off all available (i.e. not filtered
* in stage 1) pixels. Pixels that have an amplitude below the
* relative threshold are dismissed. The same holds true for
* the absolute amplitude threshold. All pixel with smaller
* amplitude are dismissed.\n
* The relative threshold is useful to setup a distance
* measurement scenario. All well illuminated pixels are
* selected and considered for the final 1d distance. The
* absolute threshold is used to dismiss pixels that are below
* the noise level. The latter would be considered for the 1d
* result if the maximum amplitude is already very low.
* -# A distance filter is used to distinguish pixels that target
* the actual object from pixels that see the brighter background,
* e.g. white walls. Thus, the pixel with the minimum distance
* is referenced and all pixel that have a distance between
* the minimum and the given minimum distance scope are selected
* for the 1d distance result. The minimum distance scope is
* determined by an relative (to the current minimum distance)
* and an absolute value. The larger scope value is the
* relevant one, i.e. the relative distance scope can be used
* to heed the increasing noise at larger distances.
* -# If all of the above filters fail to determine a single valid
* pixel, the golden pixel is used as a fallback value. The
* golden pixel is the pixel that sits right at the focus point
* of the optics at large distances.
* .
*
* After filtering is done, there may be more than a single pixel
* left to determine the 1d signal. Therefore several averaging
* methods are implemented to obtain the best 1d result from many
* pixels. See #argus_pba_averaging_mode_t for details.
*
*
* @addtogroup arguspba
* @{
*****************************************************************************/
#include "argus_def.h"
/*!***************************************************************************
* @brief Enable flags for the pixel binning algorithm.
*
* @details Determines the pixel binning algorithm feature enable status.
* - [0]: #PBA_ENABLE: Enables the pixel binning feature.
* - [1]: reserved
* - [2]: reserved
* - [3]: reserved
* - [4]: reserved
* - [5]: #PBA_ENABLE_GOLDPX: Enables the golden pixel feature.
* - [6]: #PBA_ENABLE_MIN_DIST_SCOPE: Enables the minimum distance scope
* feature.
* - [7]: reserved
* .
*****************************************************************************/
typedef enum {
/*! Enables the pixel binning feature. */
PBA_ENABLE = 1U << 0U,
/*! Enables the golden pixel. */
PBA_ENABLE_GOLDPX = 1U << 5U,
/*! Enables the minimum distance scope filter. */
PBA_ENABLE_MIN_DIST_SCOPE = 1U << 6U,
} argus_pba_flags_t;
/*!***************************************************************************
* @brief The averaging modes for the pixel binning algorithm.
*****************************************************************************/
typedef enum {
/*! Evaluate the 1D range from all available pixels using
* a simple average. */
PBA_SIMPLE_AVG = 1U,
/*! Evaluate the 1D range from all available pixels using
* a linear amplitude weighted averaging method.
* Formula: x_mean = sum(x_i * A_i) / sum(A_i) */
PBA_LINEAR_AMPLITUDE_WEIGHTED_AVG = 2U,
} argus_pba_averaging_mode_t;
/*!***************************************************************************
* @brief The pixel binning algorithm settings data structure.
* @details Describes the pixel binning algorithm settings.
*****************************************************************************/
typedef struct {
/*! Enables the pixel binning features.
* Each bit may enable a different feature. See #argus_pba_flags_t
* for details about the enabled flags. */
argus_pba_flags_t Enabled;
/*! Determines the PBA averaging mode which is used to obtain the
* final range value from the algorithm, for example, the average
* of all pixels. See #argus_pba_averaging_mode_t for more details
* about the individual evaluation modes. */
argus_pba_averaging_mode_t Mode;
/*! The Relative amplitude threshold value (in %) of the max. amplitude.
* Pixels with amplitude below this threshold value are dismissed.
*
* All available values from the 8-bit representation are valid.
* The actual percentage value is determined by 100%/256*x.
*
* Use 0 to disable the relative amplitude threshold. */
uq0_8_t RelAmplThreshold;
/*! The relative minimum distance scope value in %.
* Pixels that have a range value within [x0, x0 + dx] are considered
* for the pixel binning, where x0 is the minimum distance of all
* amplitude picked pixels and dx is the minimum distance scope value.
* The minimum distance scope value will be the maximum of relative
* and absolute value.
*
* All available values from the 8-bit representation are valid.
* The actual percentage value is determined by 100%/256*x.
*
* Special values:
* - 0: Use 0 for absolute value only or to choose the pixel with the
* minimum distance only (of also the absolute value is 0)! */
uq0_8_t RelMinDistanceScope;
/*! The Absolute amplitude threshold value in LSB.
* Pixels with amplitude below this threshold value are dismissed.
*
* All available values from the 16-bit representation are valid.
* The actual LSB value is determined by x/16.
*
* Use 0 to disable the absolute amplitude threshold. */
uq12_4_t AbsAmplThreshold;
/*! The absolute minimum distance scope value in m.
* Pixels that have a range value within [x0, x0 + dx] are considered
* for the pixel binning, where x0 is the minimum distance of all
* amplitude picked pixels and dx is the minimum distance scope value.
* The minimum distance scope value will be the maximum of relative
* and absolute value.
*
* All available values from the 16-bit representation are valid.
* The actual LSB value is determined by x/2^15.
*
* Special values:
* - 0: Use 0 for relative value only or to choose the pixel with the
* minimum distance only (of also the relative value is 0)! */
uq1_15_t AbsMinDistanceScope;
/*! The pre-filter pixel mask determines the pixel channels that are
* statically excluded from the pixel binning (i.e. 1D distance) result.
*
* The pixel enabled mask is an 32-bit mask that determines the
* device internal channel number. It is recommended to use the
* - #PIXELXY_ISENABLED(msk, x, y)
* - #PIXELXY_ENABLE(msk, x, y)
* - #PIXELXY_DISABLE(msk, x, y)
* .
* macros to work with the pixel enable masks. */
uint32_t PrefilterMask;
} argus_cfg_pba_t;
/*! @} */
#endif /* ARGUS_PBA_H */
@@ -0,0 +1,143 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details Defines the device pixel measurement results data structure.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_PX_H
#define ARGUS_PX_H
/*!***************************************************************************
* @addtogroup argusres
* @{
*****************************************************************************/
/*! Maximum amplitude value in UQ12.4 format. */
#define ARGUS_AMPLITUDE_MAX (0xFFF0U)
/*! Maximum range value in Q9.22 format.
* Also used as a special value to determine no object detected or infinity range. */
#define ARGUS_RANGE_MAX (Q9_22_MAX)
/*!***************************************************************************
* @brief Status flags for the evaluated pixel structure.
*
* @details Determines the pixel status. 0 means OK (#PIXEL_OK).
* - [0]: #PIXEL_OFF: Pixel was disabled and not read from the device.
* - [1]: #PIXEL_SAT: The pixel was saturated.
* - [2]: #PIXEL_BIN_EXCL: The pixel was excluded from the 1D result.
* - [3]: #PIXEL_AMPL_MIN: The pixel amplitude has evaluated to 0.
* - [4]: #PIXEL_PREFILTERED: The was pre-filtered by static mask.
* - [5]: #PIXEL_NO_SIGNAL: The pixel has no valid signal.
* - [6]: #PIXEL_OUT_OF_SYNC: The pixel has lost signal trace.
* - [7]: #PIXEL_STALLED: The pixel value is stalled due to errors.
* .
*****************************************************************************/
typedef enum {
/*! 0x00: Pixel status OK. */
PIXEL_OK = 0,
/*! 0x01: Pixel is disabled (in hardware) and no data has been read from the device. */
PIXEL_OFF = 1U << 0U,
/*! 0x02: Pixel is saturated (i.e. at least one saturation bit for any
* sample is set or the sample is in the invalidity area). */
PIXEL_SAT = 1U << 1U,
/*! 0x04: Pixel is excluded from the pixel binning (1d) result. */
PIXEL_BIN_EXCL = 1U << 2U,
/*! 0x08: Pixel amplitude minimum underrun
* (i.e. the amplitude calculation yields 0). */
PIXEL_AMPL_MIN = 1U << 3U,
/*! 0x10: Pixel is pre-filtered by the static pixel binning pre-filter mask,
* i.e. the pixel is disabled by software. */
PIXEL_PREFILTERED = 1U << 4U,
/*! 0x20: Pixel amplitude is below its threshold value. The received signal
* strength is too low to evaluate a valid signal. The range value is
* set to the maximum possible value (approx. 512 m). */
PIXEL_NO_SIGNAL = 1U << 5U,
/*! 0x40: Pixel is not in sync with respect to the dual frequency algorithm.
* I.e. the pixel may have a correct value but is estimated into the
* wrong unambiguous window. */
PIXEL_OUT_OF_SYNC = 1U << 6U,
/*! 0x80: Pixel is stalled due to one of the following reasons:
* - #PIXEL_SAT
* - #PIXEL_AMPL_MIN
* - #PIXEL_OUT_OF_SYNC
* - Global Measurement Error
* .
* A stalled pixel does not update its measurement data and keeps the
* previous values. If the issue is resolved, the stall disappears and
* the pixel is updating again. */
PIXEL_STALLED = 1U << 7U
} argus_px_status_t;
/*!***************************************************************************
* @brief The evaluated measurement results per pixel.
* @details This structure contains the evaluated data for a single pixel.\n
* If the amplitude is 0, the pixel is turned off or has invalid data.
*****************************************************************************/
typedef struct {
/*! Range Values from the device in meter. It is the actual distance before
* software adjustments/calibrations. */
q9_22_t Range;
/*! Phase Values from the device in units of PI, i.e. 0 ... 2. */
uq1_15_t Phase;
/*! Amplitudes of measured signals in LSB.
* Special values: 0 == Pixel Off, 0xFFFF == Overflow/Error */
uq12_4_t Amplitude;
/*! Pixel status; determines if the pixel is disabled, saturated, ..
* See the \link #argus_px_status_t pixel status flags\endlink for more
* information. */
argus_px_status_t Status;
/*! The unambiguous window determined by the dual frequency feature. */
int8_t RangeWindow;
/*! The raw amplitudes of measured signals in LSB. */
uq12_4_t AmplitudeRaw;
} argus_pixel_t;
/*! @} */
#endif /* ARGUS_PX_H */
@@ -0,0 +1,173 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details Defines the generic measurement results data structure.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_RES_H
#define ARGUS_RES_H
/*!***************************************************************************
* @defgroup argusres Measurement Data
* @ingroup argusapi
*
* @brief Measurement results data structures.
*
* @details The interface defines all data structures that correspond to
* the AFBR-S50 measurement results, e.g.
* - 1D distance and amplitude values,
* - 3D distance and amplitude values (i.e. per pixel),
* - Auxiliary channel measurement results (VDD, IAPD, temperature, ...)
* - Device and result status
* - ...
* .
*
* @addtogroup argusres
* @{
*****************************************************************************/
#include "argus_def.h"
#include "argus_px.h"
#include "argus_meas.h"
/*!***************************************************************************
* @brief The 1d measurement results data structure.
* @details The 1d measurement results obtained by the pixel binning algorithm.
*****************************************************************************/
typedef struct {
/*! Raw 1D range value in meter (Q9.22 format). The distance obtained by
* the pixel binning algorithm from the current measurement frame. */
q9_22_t Range;
/*! The 1D amplitude in LSB (Q12.4 format). The (maximum) amplitude obtained
* by the pixel binning algorithm from the current measurement frame.
* Special value: 0 == No/Invalid Result. */
uq12_4_t Amplitude;
} argus_results_bin_t;
/*!***************************************************************************
* @brief The auxiliary measurement results data structure.
* @details The auxiliary measurement results obtained by the auxiliary task.
* Special values, i.e. 0xFFFFU, indicate no readout value available.
*****************************************************************************/
typedef struct {
/*! VDD ADC channel readout value.
* Special Value if no value has been measured:
* Invalid/NotAvailable = 0xFFFFU (UQ12_4_MAX) */
uq12_4_t VDD;
/*! Temperature sensor ADC channel readout value.
* Special Value if no value has been measured:
* Invalid/NotAvailable = 0x7FFFU (Q11_4_MAX) */
q11_4_t TEMP;
/*! Substrate Voltage ADC Channel readout value.
* Special Value if no value has been measured:
* Invalid/NotAvailable = 0xFFFFU (UQ12_4_MAX) */
uq12_4_t VSUB;
/*! VDD VCSEL ADC channel readout value.
* Special Value if no value has been measured:
* Invalid/NotAvailable = 0xFFFFU (UQ12_4_MAX) */
uq12_4_t VDDL;
/*! APD current ADC Channel readout value.
* Special Value if no value has been measured:
* Invalid/NotAvailable = 0xFFFFU (UQ12_4_MAX) */
uq12_4_t IAPD;
/*! Background Light Value in arbitrary. units,
* estimated by the substrate voltage control task.
* Special Value if no value is available:
* Invalid/NotAvailable = 0xFFFFU (UQ12_4_MAX) */
uq12_4_t BGL;
/*! Shot Noise Amplitude in LSB units,
* estimated by the shot noise monitor task from
* the average amplitude of the passive pixels.
* Special Value if no value is available:
* Invalid/NotAvailable = 0xFFFFU (UQ12_4_MAX) */
uq12_4_t SNA;
} argus_results_aux_t;
/*!***************************************************************************
* @brief The measurement results data structure.
* @details Measurement data from the device.
* @code
* // Pixel Field: Pixel[x][y]
* //
* // 0 -----------> x
* // | O O O O O O O O
* // | O O O O O O O O
* // | O O O O O O O O O (ref. Px)
* // y O O O O O O O O
* @endcode
*****************************************************************************/
typedef struct {
/*! The \link #status_t status\endlink of the current measurement frame.
* - 0 (i.e. #STATUS_OK) for a good measurement signal.
* - > 0 for warnings and weak measurement signal.
* - < 0 for errors and invalid measurement signal. */
status_t Status;
/*! Time in milliseconds (measured since the last MCU startup/reset)
* when the measurement was triggered. */
ltc_t TimeStamp;
/*! The configuration for the current measurement frame. */
argus_meas_frame_t Frame;
/*! Raw unmapped ADC results from the device. */
uint32_t Data[ARGUS_RAW_DATA_VALUES];
/*! Raw Range Values from the device in meter.
* It is the actual distance before software adjustments/calibrations. */
argus_pixel_t PixelRef;
/*! Raw Range Values from the device in meter.
* It is the actual distance before software adjustments/calibrations. */
argus_pixel_t Pixel[ARGUS_PIXELS_X][ARGUS_PIXELS_Y];
/*! Pixel binned results. */
argus_results_bin_t Bin;
/*! The auxiliary ADC channel data. */
argus_results_aux_t Auxiliary;
} argus_results_t;
/*! @} */
#endif /* ARGUS_RES_H */
@@ -0,0 +1,82 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details Defines the Shot Noise Monitor (SNM) setup parameters.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_SNM_H
#define ARGUS_SNM_H
/*!***************************************************************************
* @defgroup argussnm Shot Noise Monitor
* @ingroup argusdev
*
* @brief Shot Noise Monitor (SNM) parameter definitions and API functions.
*
* @details The SNM is an algorithm to monitor and react on shot noise
* induced by harsh environment conditions like high ambient
* light.
*
* The AFBR-S50 API provides three modes:
* - Dynamic: Automatic mode, automatically adopts to current
* ambient conditions.
* - Static (Outdoor): Static mode, optimized for outdoor applications.
* - Static (Indoor): Static mode, optimized for indoor applications.
* .
*
* @addtogroup argussnm
* @{
*****************************************************************************/
/*! The Shot Noise Monitor modes enumeration. */
typedef enum {
/*! Static Shot Noise Monitoring Mode, optimized for indoor applications.
* Assumes the best case scenario, i.e. no bad influence from ambient conditions.
* Thus it uses a fixed setting that will result in the best performance.
* Equivalent to Shot Noise Monitoring disabled. */
SNM_MODE_STATIC_INDOOR = 0U,
/*! Static Shot Noise Monitoring Mode, optimized for outdoor applications.
* Assumes the worst case scenario, i.e. it uses a fixed setting that will
* work under all ambient conditions. */
SNM_MODE_STATIC_OUTDOOR = 1U,
/*! Dynamic Shot Noise Monitoring Mode.
* Adopts the system performance dynamically to the current ambient conditions. */
SNM_MODE_DYNAMIC = 2U,
} argus_snm_mode_t;
/*! @} */
#endif /* ARGUS_SNM_H */
@@ -0,0 +1,271 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details Provides status codes for the AFBR-S50 API.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_STATUS_H
#define ARGUS_STATUS_H
#include <stdint.h>
/*!***************************************************************************
* @defgroup status Status Codes
* @brief Status and Error Code Definitions
* @details Defines status and error codes for function return values.
* Basic status number structure:
* - 0 is OK or no error.
* - negative values determine errors.
* - positive values determine warnings or status information.
* .
* @addtogroup status
* @{
*****************************************************************************/
/*!***************************************************************************
* @brief Type used for all status and error return values.
* @details Basic status number structure:
* - 0 is OK or no error.
* - negative values determine errors.
* - positive values determine warnings or status information.
* .
*****************************************************************************/
typedef int32_t status_t;
/*! AFBR-S50 API status and error return codes. */
enum Status {
/**********************************************************************************************
********** Generic Status ********************************************************************
*********************************************************************************************/
/*! 0: Status for success/no error. */
STATUS_OK = 0,
/*! 0: Status for device/module/hardware idle. Implies #STATUS_OK. */
STATUS_IDLE = 0,
/*! 1: Status to be ignored. */
STATUS_IGNORE = 1,
/*! 2: Status for device/module/hardware busy. */
STATUS_BUSY = 2,
/*! 3: Status for device/module/hardware is currently initializing. */
STATUS_INITIALIZING = 3,
/*! -1: Error for generic fail/error. */
ERROR_FAIL = -1,
/*! -2: Error for process aborted by user/external. */
ERROR_ABORTED = -2,
/*! -3: Error for invalid read only operations. */
ERROR_READ_ONLY = -3,
/*! -4: Error for out of range parameters. */
ERROR_OUT_OF_RANGE = -4,
/*! -5: Error for invalid argument passed to an function. */
ERROR_INVALID_ARGUMENT = -5,
/*! -6: Error for timeout occurred. */
ERROR_TIMEOUT = -6,
/*! -7: Error for not initialized modules. */
ERROR_NOT_INITIALIZED = -7,
/*! -8: Error for not supported. */
ERROR_NOT_SUPPORTED = -8,
/*! -9: Error for yet not implemented functions. */
ERROR_NOT_IMPLEMENTED = -9,
/**********************************************************************************************
********** S2PI Layer Status *****************************************************************
*********************************************************************************************/
/*! 51: SPI is disabled and pins are used in GPIO mode. */
STATUS_S2PI_GPIO_MODE = 51,
/*! -51: Error occurred on the Rx line. */
ERROR_S2PI_RX_ERROR = -51,
/*! -52: Error occurred on the Tx line. */
ERROR_S2PI_TX_ERROR = -52,
/*! -53: Called a function at a wrong driver state. */
ERROR_S2PI_INVALID_STATE = -53,
/*! -54: The specified baud rate is not valid. */
ERROR_S2PI_INVALID_BAUD_RATE = -54,
/*! -55: The specified slave identifier is not valid. */
ERROR_S2PI_INVALID_SLAVE = -55,
/**********************************************************************************************
********** NVM / Flash Layer Status *********************************************************
*********************************************************************************************/
/*! -98: Flash Error: The version of the settings in the flash memory is not compatible. */
ERROR_NVM_INVALID_FILE_VERSION = -98,
/*! -99: Flash Error: The memory is out of range. */
ERROR_NVM_OUT_OF_RANGE = -99,
/**********************************************************************************************
********** AFBR-S50 Specific Status **********************************************************
*********************************************************************************************/
/*! 104: AFBR-S50 Status: All (internal) raw data buffers are currently in use.
* The measurement was not executed due to lack of available raw data buffers.
* Please call #Argus_EvaluateData to free the buffers. */
STATUS_ARGUS_BUFFER_BUSY = 104,
/*! 105: AFBR-S50 Status: The measurement was not executed/started due to output power
* limitations. */
STATUS_ARGUS_POWERLIMIT = 105,
/*! 107: AFBR-S50 Status: No valid signal was detected at any active pixel
* via the Pixel Binning Algorithm. The Golden Pixel was Choosen as a
* fallback value that is consider to be the last pixel that has a valid
* signal for low reflective (or far away) objects.
* The current results should be considered carefully. */
STATUS_ARGUS_UNDERFLOW = 107,
/*! 108: AFBR-S50 Status: No object was detected within the field-of-view
* and measurement range of the device. */
STATUS_ARGUS_NO_OBJECT = 108,
/*! 109: AFBR-S50 Status: The readout algorithm for the EEPROM has detected a bit
* error which has been corrected. However, if more than a single bit error
* has occurred, the corrected value is invalid! This cannot be distinguished
* from the valid case. Thus, if the error starts to occur, the sensor
* should be replaced soon! */
STATUS_ARGUS_EEPROM_BIT_ERROR = 109,
/*! 110: AFBR-S50 Status: Inconsistent EEPROM readout data. No calibration
* trimming values are applied. The calibration remains invalid. */
STATUS_ARGUS_INVALID_EEPROM = 110,
/*! -101: AFBR-S50 Error: No device connected. Initial SPI tests failed. */
ERROR_ARGUS_NOT_CONNECTED = -101,
/*! -102: AFBR-S50 Error: Inconsistent configuration parameters. */
ERROR_ARGUS_INVALID_CFG = -102,
/*! -105: AFBR-S50 Error: Invalid measurement mode configuration parameter. */
ERROR_ARGUS_INVALID_MODE = -105,
/*! -107: AFBR-S50 Error: The APD bias voltage is reinitializing due to a dropout.
* The current measurement data set is invalid! */
ERROR_ARGUS_BIAS_VOLTAGE_REINIT = -107,
/*! -109: AFBR-S50 Error: The EEPROM readout has failed. The failure is detected
* by three distinct read attempts, each resulting in invalid data.
* Note: this state differs from that #STATUS_ARGUS_EEPROM_BIT_ERROR
* such that it is usually temporarily and due to harsh ambient conditions. */
ERROR_ARGUS_EEPROM_FAILURE = -109,
/*! -110: AFBR-S50 Error: The measurement signals of all active pixels are invalid
* and thus the 1D range is also invalid and stalled.
* This means the range value is not updated and kept at the previous valid value. */
ERROR_ARGUS_STALLED = -110,
/*! -111: AFBR-S50 Error: The background light is too bright. */
ERROR_ARGUS_BGL_EXCEEDANCE = -111,
/*! -112: AFBR-S50 Error: The crosstalk vector amplitude is too high. */
ERROR_ARGUS_XTALK_AMPLITUDE_EXCEEDANCE = -112,
/*! -113: AFBR-S50 Error: Laser malfunction! Laser Safety may not be given! */
ERROR_ARGUS_LASER_FAILURE = -113,
/*! -114: AFBR-S50 Error: Register data integrity is lost (e.g. due to unexpected
* power-on-reset cycle or invalid write cycle of SPI. System tries to
* reset the values. */
ERROR_ARGUS_DATA_INTEGRITY_LOST = -114,
/*! -115: AFBR-S50 Error: The range offsets calibration failed! */
ERROR_ARGUS_RANGE_OFFSET_CALIBRATION_FAILED = -115,
/*! -191: AFBR-S50 Error: The device is currently busy and cannot execute the
* requested command. */
ERROR_ARGUS_BUSY = -191,
/*! -199: AFBR-S50 Error: Unknown module number. */
ERROR_ARGUS_UNKNOWN_MODULE = -199,
/*! -198: AFBR-S50 Error: Unknown chip version number. */
ERROR_ARGUS_UNKNOWN_CHIP = -198,
/*! -197: AFBR-S50 Error: Unknown laser type number. */
ERROR_ARGUS_UNKNOWN_LASER = -197,
/*! 193: AFBR-S50 Status (internal): The device is currently busy with updating the
* configuration (i.e. with writing register values). */
STATUS_ARGUS_BUSY_CFG_UPDATE = 193,
/*! 194: AFBR-S50 Status (internal): The device is currently busy with updating the
* calibration data (i.e. writing to register values). */
STATUS_ARGUS_BUSY_CAL_UPDATE = 194,
/*! 195: AFBR-S50 Status (internal): The device is currently executing a calibration
* sequence. */
STATUS_ARGUS_BUSY_CAL_SEQ = 195,
/*! 196: AFBR-S50 Status (internal): The device is currently executing a measurement
* cycle. */
STATUS_ARGUS_BUSY_MEAS = 196,
/*! 100: AFBR-S50 Status (internal): The ASIC is initializing a new measurement, i.e.
* a register value is written that starts an integration cycle on the ASIC. */
STATUS_ARGUS_STARTING = 100,
/*! 103: AFBR-S50 Status (internal): The ASIC is performing an integration cycle. */
STATUS_ARGUS_ACTIVE = 103,
};
/*! @} */
#endif /* ARGUS_STATUS_H */
@@ -0,0 +1,76 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details This file contains the current API version number.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_VERSION_H
#define ARGUS_VERSION_H
/*!***************************************************************************
* @defgroup version API Version
* @ingroup argusapi
*
* @brief API and library core version number
*
* @details Contains the AFBR-S50 API and Library Core Version Number.
*
* @addtogroup version
* @{
*****************************************************************************/
/*! Major version number of the AFBR-S50 API. */
#define ARGUS_API_VERSION_MAJOR 1
/*! Minor version number of the AFBR-S50 API. */
#define ARGUS_API_VERSION_MINOR 2
/*! Bugfix version number of the AFBR-S50 API. */
#define ARGUS_API_VERSION_BUGFIX 3
/*! Build version nunber of the AFBR-S50 API. */
#define ARGUS_API_VERSION_BUILD "20201120091253"
/*****************************************************************************/
/*! Construct the version number for drivers. */
#define MAKE_VERSION(major, minor, bugfix) \
(((major) << 24) | ((minor) << 16) | (bugfix))
/*! Version number of the AFBR-S50 API. */
#define ARGUS_API_VERSION MAKE_VERSION((ARGUS_API_VERSION_MAJOR), \
(ARGUS_API_VERSION_MINOR), \
(ARGUS_API_VERSION_BUGFIX))
/*! @} */
#endif /* ARGUS_VERSION_H */
@@ -0,0 +1,114 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 hardware API.
* @details Defines the generic device calibration API.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_XTALK_H
#define ARGUS_XTALK_H
/*!***************************************************************************
* @addtogroup arguscal
* @{
*****************************************************************************/
#include "api/argus_def.h"
/*!***************************************************************************
* @brief Pixel Crosstalk Compensation Vector.
* @details Contains calibration data (per pixel) that belongs to the
* RX-TX-Crosstalk compensation feature.
*****************************************************************************/
/*! Pixel Crosstalk Vector */
typedef struct {
/*! Crosstalk Vector - Sine component.
* Special Value: Q11_4_MIN == not available */
q11_4_t dS;
/*! Crosstalk Vector - Cosine component.
* Special Value: Q11_4_MIN == not available */
q11_4_t dC;
} xtalk_t;
/*!***************************************************************************
* @brief Pixel-To-Pixel Crosstalk Compensation Parameters.
* @details Contains calibration data that belongs to the pixel-to-pixel
* crosstalk compensation feature.
*****************************************************************************/
typedef struct {
/*! Pixel-To-Pixel Compensation on/off. */
bool Enabled;
/*! The relative threshold determines when the compensation is active for
* each individual pixel. The value determines the ratio of the individual
* pixel signal is with respect to the overall average signal. If the
* ratio is smaller than the value, the compensation is active. Absolute
* and relative conditions are connected with AND logic. */
uq0_8_t RelativeThreshold;
/*! The absolute threshold determines the minimum total crosstalk
* amplitude (i.e. the average amplitude of all pixels weighted by
* the Kc factor) that is required for the compensation to become
* active. Set to 0 to always enable. Absolute and relative
* conditions are connected with AND logic. */
uq12_4_t AbsoluteTreshold;
/*! The sine component of the Kc factor that determines the amount of the total
* signal of all pixels that influences the individual signal of each pixel.
* Higher values determine more influence on the individual pixel signal. */
q3_12_t KcFactorS;
/*! The cosine component of the Kc factor that determines the amount of the total
* signal of all pixels that influences the individual signal of each pixel.
* Higher values determine more influence on the individual pixel signal. */
q3_12_t KcFactorC;
/*! The sine component of the reference pixel Kc factor that determines the
* amount of the total signal on all pixels that influences the individual
* signal of the reference pixel.
* Higher values determine more influence on the reference pixel signal. */
q3_12_t KcFactorSRefPx;
/*! The cosine component of the reference pixel Kc factor that determines the
* amount of the total signal on all pixels that influences the individual
* signal of the reference pixel.
* Higher values determine more influence on the reference pixel signal. */
q3_12_t KcFactorCRefPx;
} argus_cal_p2pxtalk_t;
/*! @} */
#endif /* ARGUS_XTALK_H */
@@ -0,0 +1,50 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details This file the main header of the AFBR-S50 API.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_H
#define ARGUS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "api/argus_api.h"
#ifdef __cplusplus
}
#endif
#endif /* ARGUS_H */
@@ -0,0 +1,121 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details This file provides an interface for enabling/disabling interrupts.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_IRQ_H
#define ARGUS_IRQ_H
#ifdef __cplusplus
extern "C" {
#endif
/*!***************************************************************************
* @defgroup argus_irq IRQ: Global Interrupt Control Layer
* @ingroup argus_platform
*
* @brief Global Interrupt Control Layer
*
* @details This module provides functionality to globally enable/disable
* interrupts by turning the I-bit in the CPSR on/off.
*
* Here is a simple example implementation using the CMSIS functions
* "__enable_irq()" and "__disable_irq()". An integer counter is
* used to achieve nested interrupt disabling:
*
* @code
*
* // Global lock level counter value.
* static volatile int g_irq_lock_ct;
*
* // Global unlock all interrupts using CMSIS function "__enable_irq()".
* void IRQ_UNLOCK(void)
* {
* assert(g_irq_lock_ct > 0);
* if (--g_irq_lock_ct <= 0)
* {
* g_irq_lock_ct = 0;
* __enable_irq();
* }
* }
*
* // Global lock all interrupts using CMSIS function "__disable_irq()".
* void IRQ_LOCK(void)
* {
* __disable_irq();
* g_irq_lock_ct++;
* }
*
* @endcode
*
* @note The IRQ locking mechanism is used to create atomic sections
* (within the scope of the AFBR-S50 API) that are very few processor
* instruction only. It does NOT lock interrupts for considerable
* amounts of time.
*
* @note The interrupts utilized by the AFBR-S50 API can be interrupted
* by other, higher prioritized interrupts, e.g. some system
* critical interrupts. In this case, the IRQ_LOCK/IRQ_UNLOCK
* mechanism can be implemented such that only the interrupts
* required for the AFBR-S50 API are locked. The above example is
* dedicated to a ARM Corex-M0 architecture, where interrupts
* can only disabled at a global scope. Other architectures like
* ARM Cortex-M4 allow selective disabling of interrupts.
*
* @addtogroup argus_irq
* @{
*****************************************************************************/
/*!***************************************************************************
* @brief Enable IRQ Interrupts
*
* @details Enables IRQ interrupts by clearing the I-bit in the CPSR.
* Can only be executed in Privileged modes.
*****************************************************************************/
void IRQ_UNLOCK(void);
/*!***************************************************************************
* @brief Disable IRQ Interrupts
*
* @details Disables IRQ interrupts by setting the I-bit in the CPSR.
* Can only be executed in Privileged modes.
*****************************************************************************/
void IRQ_LOCK(void);
#ifdef __cplusplus
}
#endif
/*! @} */
#endif // ARGUS_IRQ_H
@@ -0,0 +1,135 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details This file provides an interface for the optional non-volatile memory.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_NVM_H
#define ARGUS_NVM_H
#ifdef __cplusplus
extern "C" {
#endif
/*!***************************************************************************
* @defgroup argus_nvm NVM: Non-Volatile Memory Layer
* @ingroup argus_platform
*
* @brief Non-Volatile Memory Layer
*
* @details This module provides functionality to access the non-volatile
* memory (e.g. flash) on the underlying platform.
*
* This module is optional and only required if calibration data
* needs to be stored within the API.
*
* @note The implementation of this module is optional for the correct
* execution of the API. If not implemented, a weak implementation
* within the API will be used that disables the NVM feature.
*
* @addtogroup argus_nvm
* @{
*****************************************************************************/
#include "argus.h"
/*!***************************************************************************
* @brief Initializes the non-volatile memory unit and reserves a chunk of memory.
*
* @details The function is called upon API initialization sequence. If available,
* the non-volatile memory module reserves a chunk of memory with the
* provides number of bytes (size) and returns with #STATUS_OK.
*
* If not implemented, the function should return #ERROR_NOT_IMPLEMENTED
* in oder to inform the API to not use the NVM module.
*
* After initialization, the API calls the #NVM_Write and #NVM_Read
* methods to write within the reserved chunk of memory.
*
* @note The implementation of this function is optional for the correct
* execution of the API. If not implemented, a weak implementation
* within the API will be used that disables the NVM feature.
*
* @param size The required size of NVM to store all parameters.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t NVM_Init(uint32_t size);
/*!***************************************************************************
* @brief Write a block of data to the non-volatile memory.
*
* @details The function is called whenever the API wants to write data into
* the previously reserved (#NVM_Init) memory block. The data shall
* be written at a given offset and with a given size.
*
* If no NVM module is available, the function can return with error
* #ERROR_NOT_IMPLEMENTED.
*
* @note The implementation of this function is optional for the correct
* execution of the API. If not implemented, a weak implementation
* within the API will be used that disables the NVM feature.
*
* @param offset The index offset where the first byte needs to be written.
* @param size The number of bytes to be written.
* @param buf The pointer to the data buffer with the data to be written.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t NVM_Write(uint32_t offset, uint32_t size, uint8_t const *buf);
/*!***************************************************************************
* @brief Reads a block of data from the non-volatile memory.
*
* @details The function is called whenever the API wants to read data from
* the previously reserved (#NVM_Init) memory block. The data shall
* be read at a given offset and with a given size.
*
* If no NVM module is available, the function can return with error
* #ERROR_NOT_IMPLEMENTED.
*
* @note The implementation of this function is optional for the correct
* execution of the API. If not implemented, a weak implementation
* within the API will be used that disables the NVM feature.
*
* @param offset The index offset where the first byte needs to be read.
* @param size The number of bytes to be read.
* @param buf The pointer to the data buffer to copy the data to.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t NVM_Read(uint32_t offset, uint32_t size, uint8_t *buf);
#ifdef __cplusplus
}
#endif
/*! @} */
#endif // ARGUS_NVM_H
@@ -0,0 +1,83 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details This file provides an interface for the optional debug module.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_PRINT_H
#define ARGUS_PRINT_H
/*!***************************************************************************
* @defgroup argus_log Debug: Logging Interface
* @ingroup argus_platform
*
* @brief Logging interface for the AFBR-S50 API.
*
* @details This interface provides logging utility functions.
* Defines a printf-like function that is used to print error and
* log messages.
*
* @addtogroup argus_log
* @{
*****************************************************************************/
#include "api/argus_def.h"
/*!***************************************************************************
* @brief A printf-like function to print formated data to an debugging interface.
*
* @details Writes the C string pointed by fmt_t to an output. If format
* includes format specifiers (subsequences beginning with %), the
* additional arguments following fmt_t are formatted and inserted in
* the resulting string replacing their respective specifiers.
*
* To enable the print functionality, an implementation of the function
* must be provided that maps the output to an interface like UART or
* a debugging console, e.g. by forwarding to standard printf() method.
*
* @note The implementation of this function is optional for the correct
* execution of the API. If not implemented, a weak implementation
* within the API will be used that does nothing. This will improve
* the performance but no error messages are logged.
*
* @note The naming is different from the standard printf() on purpose to
* prevent builtin compiler optimizations.
*
* @param fmt_s The usual print() format string.
* @param ... The usual print() parameters. *
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t print(const char *fmt_s, ...);
/*! @} */
#endif /* ARGUS_PRINT_H */
@@ -0,0 +1,352 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details This file provides an interface for the required S2PI module.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_S2PI_H
#define ARGUS_S2PI_H
#ifdef __cplusplus
extern "C" {
#endif
/*!***************************************************************************
* @defgroup argus_s2pi S2PI: Serial Peripheral Interface
* @ingroup argus_platform
*
* @brief S2PI: SPI incl. GPIO Hardware Layer Module
*
* @details The S2PI module consists of a standard SPI interface plus a
* single GPIO interrupt line. Furthermore, the SPI pins are
* accessible via GPIO control to allow a software emulation of
* additional protocols using the same pins.
*
* **SPI interface:**
*
* The SPI interface is based on a single function:
*
* #S2PI_TransferFrame. This function transfers a specified number
* of bytes via the interfaces MOSI line and simultaneously reads
* the incoming data on the MOSI line. The read can also be skipped.
* The transfer happen asynchronously, e.g. via a DMA request. After
* finishing the transfer, the provided callback is invoked with
* the status of the transfer and the provided abstract parameter.
* Furthermore, the functions receives a slave parameter that can
* be used to connect multiple slaves, each with its individual
* chip select line.
*
* The interface also provides functionality to change the SPI
* baud rate. An additional abort method is used to cancel the
* ongoing transfer.
*
* **GPIO interface:**
*
* The GPIO interface handles the measurement finished interrupt
* from the device. When the device invokes the interrupt, it pulls
* the interrupt line to low. Thus the interrupt must trigger when
* a transition from high to low occurs on the interrupt line.
*
* The module simply invokes a callback when this interrupt the
* pending. The #S2PI_SetIrqCallback method is used to install the
* callback for a specified slave. Each slave will have its own
* interrupt line. An additional callback parameter can be set that
* would be passed to the callback function.
*
* In addition to the interrupt, all SPI pins need to be accessible
* as GPIO pins through the interface. One basic operation would
* be to cycle the chip select pin which resets the device.
* Additional, the device contains an EEPROM that is connected to
* the SPI pins but requires a different protocol that is not
* compatible to any standard SPI interface. Therefore, the
* interface provides the possibility to switch to GPIO control
* that allows to emulate the EEPROM protocol via software bit
* banging. Two methods are provided to switch forth and back
* between SPI and GPIO control. In GPIO mode, several functions
* are used to read and write the individual GPIO pins.
*
* Note that the GPIO mode is only required to readout the EEPROM
* at initialization of the device, i.e. during execution of the
* #Argus_Init or #Argus_Reinit method. The GPIO mode is not used
* during measurements.
*
*
* @addtogroup argus_s2pi
* @{
*****************************************************************************/
#include "api/argus_def.h"
/*!***************************************************************************
* @brief S2PI layer callback function type for the SPI transfer completed event.
*
* @param status The \link #status_t status\endlink of the completed
* transfer (#STATUS_OK on success).
*
* @param param The provided (optional, can be null) callback parameter.
*
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
typedef status_t (*s2pi_callback_t)(status_t status, void *param);
/*!***************************************************************************
* @brief S2PI layer callback function type for the GPIO interrupt event.
*
* @param param The provided (optional, can be null) callback parameter.
*****************************************************************************/
typedef void (*s2pi_irq_callback_t)(void *param);
/*! The S2PI slave identifier. Basically an user defined enumerable type that
* can be used to identify the slave within the SPI module. */
typedef int32_t s2pi_slave_t;
/*! The enumeration of S2PI pins. */
typedef enum {
/*! The SPI clock pin. */
S2PI_CLK,
/*! The SPI chip select pin. */
S2PI_CS,
/*! The SPI MOSI pin. */
S2PI_MOSI,
/*! The SPI MISO pin. */
S2PI_MISO,
/*! The IRQ pin. */
S2PI_IRQ
} s2pi_pin_t;
/*!***************************************************************************
* @brief Returns the status of the SPI module.
*
* @return Returns the \link #status_t status\endlink:
* - #STATUS_IDLE: No SPI transfer or GPIO access is ongoing.
* - #STATUS_BUSY: An SPI transfer is in progress.
* - #STATUS_S2PI_GPIO_MODE: The module is in GPIO mode.
*****************************************************************************/
status_t S2PI_GetStatus(void);
/*!***************************************************************************
* @brief Transfers a single SPI frame asynchronously.
*
* @details Transfers a single SPI frame in asynchronous manner. The Tx data
* buffer is written to the device via the MOSI line.
* Optionally, the data on the MISO line is written to the provided
* Rx data buffer. If null, the read data is dismissed. Note that
* Rx and Tx buffer can be identical. I.e. the same buffer is used
* for writing and reading data. First, a byte is transmitted and
* the received byte overwrites the previously send value.
*
* The transfer of a single frame requires to not toggle the chip
* select line to high in between the data frame. The maximum
* number of bytes transfered in a single SPI transfer is given by
* the data value register of the device, which is 396 data bytes
* plus a single address byte: 397 bytes.
*
* An optional callback is invoked when the asynchronous transfer
* is finished. If the \p callback parameter is a null pointer,
* no callback is provided. Note that the provided buffer must not
* change while the transfer is ongoing.
*
* Use the slave parameter to determine the corresponding slave via the
* given chip select line.
*
* Usually, two distinct interrupts are required to handle the RX and
* TX ready events. The callback must be invoked from whichever
* interrupt comes after the SPI transfer has been finished. Note
* that new SPI transfers are invoked from within the callback function
* (i.e. from within the interrupt service routine of same priority).
*
* @param slave The specified S2PI slave.
* @param txData The 8-bit values to write to the SPI bus MOSI line.
* @param rxData The 8-bit values received from the SPI bus MISO line
* (pass a null pointer if the data don't need to be read).
* @param frameSize The number of 8-bit values to be sent/received.
* @param callback A callback function to be invoked when the transfer is
* finished. Pass a null pointer if no callback is required.
* @param callbackData A pointer to a state that will be passed to the
* callback. Pass a null pointer if not used.
*
* @return Returns the \link #status_t status\endlink:
* - #STATUS_OK: Successfully invoked the transfer.
* - #ERROR_INVALID_ARGUMENT: An invalid parameter has been passed.
* - #ERROR_S2PI_INVALID_SLAVE: A wrong slave identifier is provided.
* - #STATUS_BUSY: An SPI transfer is already in progress. The
* transfer was not started.
* - #STATUS_S2PI_GPIO_MODE: The module is in GPIO mode. The transfer
* was not started.
*****************************************************************************/
status_t S2PI_TransferFrame(s2pi_slave_t slave,
uint8_t const *txData,
uint8_t *rxData,
size_t frameSize,
s2pi_callback_t callback,
void *callbackData);
/*!***************************************************************************
* @brief Terminates a currently ongoing asynchronous SPI transfer.
*
* @details When a callback is set for the current ongoing activity, it is
* invoked with the #ERROR_ABORTED error byte.
*
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_Abort(void);
/*!***************************************************************************
* @brief Set a callback for the GPIO IRQ for a specified S2PI slave.
*
* @param slave The specified S2PI slave.
* @param callback A callback function to be invoked when the specified
* S2PI slave IRQ occurs. Pass a null pointer to disable
* the callback.
* @param callbackData A pointer to a state that will be passed to the
* callback. Pass a null pointer if not used.
*
* @return Returns the \link #status_t status\endlink:
* - #STATUS_OK: Successfully installation of the callback.
* - #ERROR_S2PI_INVALID_SLAVE: A wrong slave identifier is provided.
*****************************************************************************/
status_t S2PI_SetIrqCallback(s2pi_slave_t slave, s2pi_irq_callback_t callback, void *callbackData);
/*!***************************************************************************
* @brief Reads the current status of the IRQ pin.
*
* @details In order to keep a low priority for GPIO IRQs, the state of the
* IRQ pin must be read in order to reliable check for chip timeouts.
*
* The execution of the interrupt service routine for the data-ready
* interrupt from the corresponding GPIO pin might be delayed due to
* priority issues. The delayed execution might disable the timeout
* for the eye-safety checker too late causing false error messages.
* In order to overcome the issue, the state of the IRQ GPIO input
* pin is read before raising a timeout error in order to check if
* the device has already finished but the IRQ is still pending to be
* executed!
* @param slave The specified S2PI slave.
* @return Returns 1U if the IRQ pin is high (IRQ not pending) and 0U if the
* devices pulls the pin to low state (IRQ pending).
*****************************************************************************/
uint32_t S2PI_ReadIrqPin(s2pi_slave_t slave);
/*!***************************************************************************
* @brief Cycles the chip select line.
*
* @details In order to cancel the integration on the ASIC, a fast toggling
* of the chip select pin of the corresponding SPI slave is required.
* Therefore, this function toggles the CS from high to low and back.
* The SPI instance for the specified S2PI slave must be idle,
* otherwise the status #STATUS_BUSY is returned.
*
* @param slave The specified S2PI slave.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_CycleCsPin(s2pi_slave_t slave);
/*!*****************************************************************************
* @brief Captures the S2PI pins for GPIO usage.
*
* @details The SPI is disabled (module status: #STATUS_S2PI_GPIO_MODE) and the
* pins are configured for GPIO operation. The GPIO control must be
* release with the #S2PI_ReleaseGpioControl function in order to
* switch back to ordinary SPI functionality.
*
* @note This function is only called during device initialization!
*
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_CaptureGpioControl(void);
/*!*****************************************************************************
* @brief Releases the S2PI pins from GPIO usage and switches back to SPI mode.
*
* @details The GPIO pins are configured for SPI operation and the GPIO mode is
* left. Must be called if the pins are captured for GPIO operation via
* the #S2PI_CaptureGpioControl function.
*
* @note This function is only called during device initialization!
*
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_ReleaseGpioControl(void);
/*!*****************************************************************************
* @brief Writes the output for a specified SPI pin in GPIO mode.
*
* @details This function writes the value of an SPI pin if the SPI pins are
* captured for GPIO operation via the #S2PI_CaptureGpioControl previously.
*
* @note Since some GPIO peripherals switch the GPIO pins very fast a delay
* must be added after each GBIO access (i.e. right before returning
* from the #S2PI_WriteGpioPin method) in order to decrease the baud
* rate of the software EEPROM protocol. Increase the delay if timing
* issues occur while reading the EERPOM. For example:
* Delay = 10 µsec => Baud Rate < 100 kHz
*
* @note This function is only called during device initialization!
*
* @param slave The specified S2PI slave.
* @param pin The specified S2PI pin.
* @param value The GPIO pin state to write (0 = low, 1 = high).
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_WriteGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t value);
/*!*****************************************************************************
* @brief Reads the input from a specified SPI pin in GPIO mode.
*
* @details This function reads the value of an SPI pin if the SPI pins are
* captured for GPIO operation via the #S2PI_CaptureGpioControl previously.
*
* @note This function is only called during device initialization!
*
* @param slave The specified S2PI slave.
* @param pin The specified S2PI pin.
* @param value The GPIO pin state to read (0 = low, 1 = high).
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_ReadGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t *value);
#ifdef __cplusplus
}
#endif
/*! @} */
#endif // ARGUS_S2PI_H
@@ -0,0 +1,267 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details This file provides an interface for the required timer modules.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_TIMER_H
#define ARGUS_TIMER_H
#ifdef __cplusplus
extern "C" {
#endif
/*!***************************************************************************
* @defgroup argus_timer Timer: Hardware Timer Interface
* @ingroup argus_platform
*
* @brief Timer implementations for lifetime counting as well as periodic
* callback.
*
* @details The module provides an interface to the timing utilities that
* are required by the AFBR-S50 time-of-flight sensor API.
*
* Two essential features have to be provided by the user code:
* 1. Time Measurement Capability: In order to keep track of outgoing
* signals, the API needs to measure elapsed time. In order to
* provide optimum device performance, the granularity should be
* around 10 to 100 microseconds.
* 2. Periodic Callback: The API provides an automatic starting of
* measurement cycles at a fixed frame rate via a periodic
* interrupt timer. If this feature is not used, implementation
* of the periodic interrupts can be skipped. An weak default
* implementation is provide in the API.
* .
*
* The time measurement feature is simply implemented by the function
* #Timer_GetCounterValue. Whenever the function is called, the
* provided counter values must be written with the values obtained
* by the current time.
*
* The periodic interrupt timer is a simple callback interface.
* After installing the callback function pointer via #Timer_SetCallback,
* the timer can be started by setting interval via #Timer_SetInterval
* or #Timer_Start. From then, the callback is invoked periodically as
* the corresponding interval may specify. The timer is stopped via
* #Timer_Stop or by setting the interval to 0. The interval can be
* updated at any time by updating the interval via the #Timer_SetInterval
* function. To any of these functions, an abstract parameter pointer
* must be passed. This parameter is passed back to the callback any
* time it is invoked.
*
* In order to provide the usage of multiple devices, an mechanism is
* introduced to allow the installation of multiple callback interval
* at the same time. Therefore, the abstract parameter pointer is used
* to identify the corresponding callback interval. For example, there
* are two callbacks for two intervals, t1 and t2, required. The user
* can start two timers by calling the #Timer_Start method twice, but
* with an individual parameter pointer, ptr1 and ptr2, each:
* \code
* Timer_Start(100000, ptr1); // 10 ms callback w/ parameter ptr1
* Timer_Start(200000, ptr2); // 20 ms callback w/ parameter ptr1
* \endcode
*
* Note that the implemented timer module must therefore support
* as many different intervals as instances of the AFBR-S50 device are
* used.
*
* @addtogroup argus_timer
* @{
*****************************************************************************/
#include "api/argus_def.h"
/*******************************************************************************
* Lifetime Counter Timer Interface
******************************************************************************/
/*!***************************************************************************
* @brief Obtains the lifetime counter value from the timers.
*
* @details The function is required to get the current time relative to any
* point in time, e.g. the startup time. The returned values \p hct and
* \p lct are given in seconds and microseconds respectively. The current
* elapsed time since the reference time is then calculated from:
*
* t_now [µsec] = hct * 1000000 µsec + lct * 1 µsec
*
* Note that the accuracy/granularity of the lifetime counter does
* not need to be 1 µsec. Usually, a granularity of approximately
* 100 µsec is sufficient. However, in case of very high frame rates
* (above 1000 frames per second), it is recommended to implement
* an even lower granularity (somewhere in the 10 µsec regime).
*
* It must be guaranteed, that each call of the #Timer_GetCounterValue
* function must provide a value that is greater or equal, but never lower,
* than the value returned from the previous call.
*
* A hardware based implementation of the lifetime counter functionality
* would be to chain two distinct timers such that counter 2 increases
* its value when counter 1 wraps to 0. The easiest way is to setup
* counter 1 to wrap exactly every second. Counter 1 would than count
* the sub-seconds (i.e. µsec) value (\p lct) and counter 2 the seconds
* (\p hct) value. A 16-bit counter is sufficient in case of counter 1
* while counter 2 must be a 32-bit version.
*
* In case of a lack of available hardware timers, a software solution
* can be used that requires only a 16-bit timer. In a simple scenario,
* the timer is configured to wrap around every second and increase
* a software counter value in its interrupt service routine (triggered
* with the wrap around event) every time the wrap around occurs.
*
*
* @note The implementation of this function is mandatory for the correct
* execution of the API.
*
* @param hct A pointer to the high counter value bits representing current
* time in seconds.
*
* @param lct A pointer to the low counter value bits representing current
* time in microseconds. Range: 0, .., 999999 µsec
*****************************************************************************/
void Timer_GetCounterValue(uint32_t *hct, uint32_t *lct);
/*******************************************************************************
* Periodic Interrupt Timer Interface
******************************************************************************/
/*!***************************************************************************
* @brief The callback function type for periodic interrupt timer.
*
* @details The function that is invoked every time a specified interval elapses.
* An abstract parameter is passed to the function whenever it is called.
*
* @param param An abstract parameter to be passed to the callback. This is
* also the identifier of the given interval.
*****************************************************************************/
typedef void (*timer_cb_t)(void *param);
/*!***************************************************************************
* @brief Installs an periodic timer callback function.
*
* @details Installs an periodic timer callback function that is invoked whenever
* an interval elapses. The callback is the same for any interval,
* however, the single intervals can be identified by the passed
* parameter.
* Passing a zero-pointer removes and disables the callback.
*
* @note The implementation of this function is optional for the correct
* execution of the API. If not implemented, a weak implementation
* within the API will be used that disable the periodic timer callback
* and thus the automatic starting of measurements from the background.
*
* @param f The timer callback function.
*
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Timer_SetCallback(timer_cb_t f);
/*!***************************************************************************
* @brief Sets the timer interval for a specified callback parameter.
*
* @details Sets the callback interval for the specified parameter and starts
* the timer with a new interval. If there is already an interval with
* the given parameter, the timer is restarted with the given interval.
* If the same time interval as already set is passed, nothing happens.
* Passing a interval of 0 disables the timer.
*
* Note that a microsecond granularity for the timer interrupt period is
* not required. Usually a microseconds granularity is sufficient.
* The required granularity depends on the targeted frame rate, e.g. in
* case of more than 1 kHz measurement rate, a granularity of less than
* a microsecond is required to achieve the given frame rate.
*
* @note The implementation of this function is optional for the correct
* execution of the API. If not implemented, a weak implementation
* within the API will be used that disable the periodic timer callback
* and thus the automatic starting of measurements from the background.
*
* @param dt_microseconds The callback interval in microseconds.
*
* @param param An abstract parameter to be passed to the callback. This is
* also the identifier of the given interval.
*
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Timer_SetInterval(uint32_t dt_microseconds, void *param);
/*!***************************************************************************
* @brief Starts the timer for a specified callback parameter.
*
* @details Sets the callback interval for the specified parameter and starts
* the timer with a new interval. If there is already an interval with
* the given parameter, the timer is restarted with the given interval.
* Passing a interval of 0 disables the timer.
*
* Note that a microsecond granularity for the timer interrupt period is
* not required. Usually a microseconds granularity is sufficient.
* The required granularity depends on the targeted frame rate, e.g. in
* case of more than 1 kHz measurement rate, a granularity of less than
* a microsecond is required to achieve the given frame rate.
*
* @note The implementation of this function is optional for the correct
* execution of the API. If not implemented, a weak implementation
* within the API will be used that disable the periodic timer callback
* and thus the automatic starting of measurements from the background.
*
* @param dt_microseconds The callback interval in microseconds.
*
* @param param An abstract parameter to be passed to the callback. This is
* also the identifier of the given interval.
*
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Timer_Start(uint32_t dt_microseconds, void *param);
/*!***************************************************************************
* @brief Stops the timer for a specified callback parameter.
*
* @details Stops a callback interval for the specified parameter.
*
* @note The implementation of this function is optional for the correct
* execution of the API. If not implemented, a weak implementation
* within the API will be used that disable the periodic timer callback
* and thus the automatic starting of measurements from the background.
*
* @param param An abstract parameter that identifies the interval to be stopped.
*
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Timer_Stop(void *param);
#ifdef __cplusplus
}
#endif
/*! @} */
#endif /* ARGUS_TIMER_H */
@@ -0,0 +1,407 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details Provides definitions and basic macros for fixed point data types.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef FP_DEF_H
#define FP_DEF_H
/*!***************************************************************************
* @defgroup fixedpoint Fixed Point Math
* @ingroup argusutil
* @brief A basic math library for fixed point number in the Qx.y fomat.
* @details This module contains common fixed point type definitions as
* well as some basic math algorithms. All types are based on
* integer types. The number are defined with the Q number format.
*
* - For a description of the Q number format refer to:
* https://en.wikipedia.org/wiki/Q_(number_format)
* - Another resource for fixed point math in C might be found at
* http://www.eetimes.com/author.asp?section_id=36&doc_id=1287491
* .
* @warning This definitions are not portable and work only with
* little-endian systems!
* @addtogroup fixedpoint
* @{
*****************************************************************************/
#include <stdint.h>
/*******************************************************************************
* UQ6.2
******************************************************************************/
/*!***************************************************************************
* @brief Unsigned fixed point number: UQ6.2
* @details An unsigned fixed point number format based on the 8-bit unsigned
* integer type with 6 integer and 2 fractional bits.
* - Range: 0 .. 63.75
* - Granularity: 0.25
*****************************************************************************/
typedef uint8_t uq6_2_t;
/*******************************************************************************
* UQ4.4
******************************************************************************/
/*!***************************************************************************
* @brief Unsigned fixed point number: UQ4.4
* @details An unsigned fixed point number format based on the 8-bit unsigned
* integer type with 4 integer and 4 fractional bits.
* - Range: 0 .. 15.9375
* - Granularity: 0.0625
*****************************************************************************/
typedef uint8_t uq4_4_t;
/*! Maximum value of UQ4.4 number format. */
#define UQ4_4_MAX ((uq4_4_t)UINT8_MAX)
/*! The 1/one/unity in UQ4.4 number format. */
#define UQ4_4_ONE ((uq4_4_t)(1U<<4U))
/*******************************************************************************
* UQ2.6
******************************************************************************/
/*!***************************************************************************
* @brief Unsigned fixed point number: UQ2.6
* @details An unsigned fixed point number format based on the 8-bit unsigned
* integer type with 2 integer and 6 fractional bits.
* - Range: 0 .. 3.984375
* - Granularity: 0.015625
*****************************************************************************/
typedef uint8_t uq2_6_t;
/*! The 1/one/unity in UQ2.6 number format. */
#define UQ2_6_ONE ((uq2_6_t)(1U<<6U))
/*******************************************************************************
* UQ1.7
******************************************************************************/
/*!***************************************************************************
* @brief Unsigned fixed point number: UQ1.7
* @details An unsigned fixed point number format based on the 8-bit unsigned
* integer type with 1 integer and 7 fractional bits.
* - Range: 0 .. 1.9921875
* - Granularity: 0.0078125
*****************************************************************************/
typedef uint8_t uq1_7_t;
/*******************************************************************************
* Q0.7
******************************************************************************/
/*!***************************************************************************
* @brief Signed fixed point number: Q0.7
* @details An signed fixed point number format based on the 8-bit integer
* type with 0 integer and 7 fractional bits.
* - Range: -1 .. 0.9921875
* - Granularity: 0.0078125
*****************************************************************************/
//typedef int8_t q0_7_t;
/*******************************************************************************
* UQ0.8
******************************************************************************/
/*!***************************************************************************
* @brief Unsigned fixed point number: UQ0.8
* @details An unsigned fixed point number format based on the 8-bit unsigned
* integer type with 1 integer and 7 fractional bits.
* - Range: 0 .. 0.99609375
* - Granularity: 0.00390625
*****************************************************************************/
typedef uint8_t uq0_8_t;
/*! Maximum value of UQ0.8 number format. */
#define UQ0_8_MAX ((uq0_8_t)UINT8_MAX)
/*******************************************************************************
* UQ12.4
******************************************************************************/
/*!***************************************************************************
* @brief Unsigned fixed point number: UQ12.4
* @details An unsigned fixed point number format based on the 16-bit unsigned
* integer type with 12 integer and 4 fractional bits.
* - Range: 0 ... 4095.9375
* - Granularity: 0.0625
*****************************************************************************/
typedef uint16_t uq12_4_t;
/*! Maximum value of UQ12.4 number format. */
#define UQ12_4_MAX ((uq12_4_t)UINT16_MAX)
/*! The 1/one/unity in UQ12.4 number format. */
#define UQ12_4_ONE ((uq12_4_t)(1U<<4U))
/*******************************************************************************
* Q11.4
******************************************************************************/
/*!***************************************************************************
* @brief Signed fixed point number: Q11.4
* @details An signed fixed point number format based on the 16-bit signed
* integer type with 11 integer and 4 fractional bits.
* - Range: -2048 ... 2047.9375
* - Granularity: 0.0625
*****************************************************************************/
typedef int16_t q11_4_t;
/*! The 1/one/unity in UQ11.4 number format. */
#define UQ11_4_ONE ((q11_4_t)(1 << 4))
/*! Maximum value of Q11.4 number format. */
#define Q11_4_MAX ((q11_4_t)INT16_MAX)
/*! Minimum value of Q11.4 number format. */
#define Q11_4_MIN ((q11_4_t)INT16_MIN)
/*******************************************************************************
* UQ10.6
******************************************************************************/
/*!***************************************************************************
* @brief Unsigned fixed point number: UQ10.6
* @details An unsigned fixed point number format based on the 16-bit unsigned
* integer type with 10 integer and 6 fractional bits.
* - Range: 0 ... 1023.984375
* - Granularity: 0.015625
*****************************************************************************/
typedef uint16_t uq10_6_t;
/*! Maximum value of UQ10.6 number format. */
#define UQ10_6_MAX ((uq10_6_t)UINT16_MAX)
/*! The 1/one/unity in UQ10.6 number format. */
#define UQ10_6_ONE ((uq10_6_t)(1U << 6U))
/*******************************************************************************
* UQ1.15
******************************************************************************/
/*!***************************************************************************
* @brief Unsigned fixed point number: UQ1.15
* @details An unsigned fixed point number format based on the 16-bit unsigned
* integer type with 1 integer and 15 fractional bits.
* - Range: 0 .. 1.999969
* - Granularity: 0.000031
*****************************************************************************/
typedef uint16_t uq1_15_t;
/*! Maximum value of UQ1.15 number format. */
#define UQ1_15_MAX ((uq1_15_t)UINT16_MAX)
/*! The 1/one/unity in UQ1.15 number format. */
#define UQ1_15_ONE ((uq1_15_t)(1U << 15U))
/*******************************************************************************
* Q0.15
******************************************************************************/
/*!***************************************************************************
* @brief Signed fixed point number: Q0.15
* @details An signed fixed point number format based on the 16-bit integer
* type with 0 integer and 15 fractional bits.
* - Range: -1 .. 0.999969482
* - Granularity: 0.000030518
*****************************************************************************/
typedef int16_t q0_15_t;
/*******************************************************************************
* Q2.13
******************************************************************************/
/*!***************************************************************************
* @brief Signed fixed point number: Q2.13
* @details An signed fixed point number format based on the 16-bit integer
* type with 2 integer and 13 fractional bits.
* - Range: -4 .. 3.99987793
* - Granularity: 0.00012207
*****************************************************************************/
//typedef int16_t q2_13_t;
/*******************************************************************************
* Q13.2
******************************************************************************/
/*!***************************************************************************
* @brief Signed fixed point number: Q13.2
* @details An signed fixed point number format based on the 16-bit integer
* type with 13 integer and 2 fractional bits.
* - Range: -8192 .. 8191.75
* - Granularity: 0.25
*****************************************************************************/
//typedef int16_t q13_2_t;
/*******************************************************************************
* Q3.12
******************************************************************************/
/*!***************************************************************************
* @brief Signed fixed point number: Q3.12
* @details An signed fixed point number format based on the 16-bit integer
* type with 3 integer and 12 fractional bits.
* - Range: -8 .. 7.99975586
* - Granularity: 0.00024414
*****************************************************************************/
typedef int16_t q3_12_t;
/*******************************************************************************
* UQ0.16
******************************************************************************/
/*!***************************************************************************
* @brief Unsigned fixed point number: UQ0.16
* @details An unsigned fixed point number format based on the 16-bit unsigned
* integer type with 0 integer and 16 fractional bits.
* - Range: 0 .. 0.9999847412109375
* - Granularity: 1.52587890625e-5
*****************************************************************************/
typedef uint16_t uq0_16_t;
/*! Maximum value of UQ0.16 number format. */
#define UQ0_16_MAX ((uq0_16_t)UINT16_MAX)
/*! The 1/one/unity in UQ0.16 number format. */
#define UQ0_16_ONE ((uq0_16_t)(1U<<16U))
/*******************************************************************************
* UQ28.4
******************************************************************************/
/*!***************************************************************************
* @brief Unsigned fixed point number: UQ28.4
* @details An unsigned fixed point number format based on the 32-bit unsigned
* integer type with 28 integer and 4 fractional bits.
* - Range: 0 ... 268435455.9375
* - Granularity: 0.0625
*****************************************************************************/
typedef uint32_t uq28_4_t;
/*! Maximum value of UQ28.4 number format. */
#define UQ28_4_MAX ((uq28_4_t)UINT32_MAX)
/*! The 1/one/unity in UQ28.4 number format. */
#define UQ28_4_ONE ((uq28_4_t)(1U<<4U))
/*******************************************************************************
* Q27.4
******************************************************************************/
/*!***************************************************************************
* @brief Signed fixed point number: Q27.4
* @details An signed fixed point number format based on the 32-bit signed
* integer type with 27 integer and 4 fractional bits.
* - Range: -134217728 ... 134217727.9375
* - Granularity: 0.0625
*****************************************************************************/
typedef int32_t q27_4_t;
/*! The 1/one/unity in UQ27.4 number format. */
#define UQ27_4_ONE ((q27_4_t)(1 << 4))
/*! Maximum value of Q27.4 number format. */
#define Q27_4_MAX ((q27_4_t)INT32_MAX)
/*! Minimum value of Q27.4 number format. */
#define Q27_4_MIN ((q27_4_t)INT32_MIN)
/*******************************************************************************
* UQ16.16
******************************************************************************/
/*!***************************************************************************
* @brief Unsigned fixed point number: UQ16.16
* @details An unsigned fixed point number format based on the 32-bit unsigned
* integer type with 16 integer and 16 fractional bits.
* - Range: 0 ... 65535.999984741
* - Granularity: 0.000015259
*****************************************************************************/
typedef uint32_t uq16_16_t;
/*! The 1/one/unity in UQ16.16 number format. */
#define UQ16_16_ONE ((uq16_16_t)(1U << 16U))
/*! Maximum value of UQ16.16 number format. */
#define UQ16_16_MAX ((uq16_16_t)UINT32_MAX)
/*! Euler's number, e, in UQ16.16 format. */
#define UQ16_16_E (0x2B7E1U)
/*******************************************************************************
* Q15.16
******************************************************************************/
/*!***************************************************************************
* @brief Signed fixed point number: Q15.16
* @details An signed fixed point number format based on the 32-bit integer
* type with 15 integer and 16 fractional bits.
* - Range: -32768 .. 32767.99998
* - Granularity: 1.52588E-05
*****************************************************************************/
typedef int32_t q15_16_t;
/*! The 1/one/unity in Q15.16 number format. */
#define Q15_16_ONE ((q15_16_t)(1 << 16))
/*! Maximum value of Q15.16 number format. */
#define Q15_16_MAX ((q15_16_t)INT32_MAX)
/*! Minimum value of Q15.16 number format. */
#define Q15_16_MIN ((q15_16_t)INT32_MIN)
/*******************************************************************************
* UQ10.22
******************************************************************************/
/*!***************************************************************************
* @brief Unsigned fixed point number: UQ10.22
* @details An unsigned fixed point number format based on the 32-bit unsigned
* integer type with 10 integer and 22 fractional bits.
* - Range: 0 ... 1023.99999976158
* - Granularity: 2.38418579101562E-07
*****************************************************************************/
typedef uint32_t uq10_22_t;
/*******************************************************************************
* Q9.22
******************************************************************************/
/*!***************************************************************************
* @brief Signed fixed point number: Q9.22
* @details An signed fixed point number format based on the 32-bit integer
* type with 9 integer and 22 fractional bits.
* - Range: -512 ... 511.9999998
* - Granularity: 2.38418579101562E-07
*****************************************************************************/
typedef int32_t q9_22_t;
/*! The 1/one/unity in Q9.22 number format. */
#define Q9_22_ONE ((q9_22_t)(1 << 22))
/*! Maximum value of Q9.22 number format. */
#define Q9_22_MAX ((q9_22_t)INT32_MAX)
/*! Minimum value of Q9.22 number format. */
#define Q9_22_MIN ((q9_22_t)INT32_MIN)
/*! @} */
#endif /* FP_DEF_H */
@@ -0,0 +1,290 @@
/*************************************************************************//**
* @file
* @brief This file is part of the AFBR-S50 API.
* @details This file provides utility functions for timing necessities.
*
* @copyright
*
* Copyright (c) 2021, Broadcom Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef TIME_H
#define TIME_H
/*!***************************************************************************
* @defgroup time Time Utility
* @ingroup argusutil
* @brief Timer utilities for time measurement duties.
* @details This module provides time measurement utility functions like
* delay or time measurement methods, or time math functions.
* @addtogroup time
* @{
*****************************************************************************/
#include <stdint.h>
#include <stdbool.h>
/*!***************************************************************************
* @brief A data structure to represent current time.
*
* @details Value is obtained from the PIT time which must be configured as
* lifetime counter.
*****************************************************************************/
typedef struct {
/*! Seconds. */
uint32_t sec;
/*! Microseconds. */
uint32_t usec;
} ltc_t;
/*!***************************************************************************
* @brief Obtains the elapsed time since MCU startup.
* @param t_now returned current time
*****************************************************************************/
void Time_GetNow(ltc_t *t_now);
/*!***************************************************************************
* @brief Obtains the elapsed microseconds since MCU startup.
* @details Wrap around effect due to uint32_t result format!!
* @param -
* @return Elapsed microseconds since MCU startup as uint32_t.
*****************************************************************************/
uint32_t Time_GetNowUSec(void);
/*!***************************************************************************
* @brief Obtains the elapsed milliseconds since MCU startup.
* @details Wrap around effect due to uint32_t result format!!
* @param -
* @return Elapsed milliseconds since MCU startup as uint32_t.
*****************************************************************************/
uint32_t Time_GetNowMSec(void);
/*!***************************************************************************
* @brief Obtains the elapsed seconds since MCU startup.
* @param -
* @return Elapsed seconds since MCU startup as uint32_t.
*****************************************************************************/
uint32_t Time_GetNowSec(void);
/*!***************************************************************************
* @brief Obtains the elapsed time since a given time point.
* @param t_elapsed Returns the elapsed time since t_start.
* @param t_start Start time point.
*****************************************************************************/
void Time_GetElapsed(ltc_t *t_elapsed, ltc_t *const t_start);
/*!***************************************************************************
* @brief Obtains the elapsed microseconds since a given time point.
* @details Wrap around effect due to uint32_t result format!!
* @param t_start Start time point.
* @return Elapsed microseconds since t_start as uint32_t.
*****************************************************************************/
uint32_t Time_GetElapsedUSec(ltc_t *const t_start);
/*!***************************************************************************
* @brief Obtains the elapsed milliseconds since a given time point.
* @details Wrap around effect due to uint32_t result format!!
* @param t_start Start time point.
* @return Elapsed milliseconds since t_start as uint32_t.
*****************************************************************************/
uint32_t Time_GetElapsedMSec(ltc_t *const t_start);
/*!***************************************************************************
* @brief Obtains the elapsed seconds since a given time point.
* @param t_start Start time point.
* @return Elapsed seconds since t_start as uint32_t.
*****************************************************************************/
uint32_t Time_GetElapsedSec(ltc_t *const t_start);
/*!***************************************************************************
* @brief Obtains the time difference between two given time points.
* @details Result is defined as t_diff = t_end - t_start.
* Note: since no negative time differences are supported, t_end has
* to be later/larger than t_start. Otherwise, the result won't be
* a negative time span but given by max value.
* @param t_diff Returned time difference.
* @param t_start Start time point.
* @param t_end End time point.
*****************************************************************************/
void Time_Diff(ltc_t *t_diff, ltc_t const *t_start, ltc_t const *t_end);
/*!***************************************************************************
* @brief Obtains the time difference between two given time points in
* microseconds.
* @details Result is defined as t_diff = t_end - t_start.
* Refers to Time_Diff() and handles overflow such that to large
* values are limited by 0xFFFFFFFF µs.
* @param t_start Start time point.
* @param t_end End time point.
* @return Time difference in microseconds.
*****************************************************************************/
uint32_t Time_DiffUSec(ltc_t const *t_start, ltc_t const *t_end);
/*!***************************************************************************
* @brief Obtains the time difference between two given time points in
* milliseconds.
* @details Result is defined as t_diff = t_end - t_start.
* Refers to Time_Diff() and handles overflow.
* Wrap around effect due to uint32_t result format!!
* @param t_start Start time point.
* @param t_end End time point.
* @return Time difference in milliseconds.
*****************************************************************************/
uint32_t Time_DiffMSec(ltc_t const *t_start, ltc_t const *t_end);
/*!***************************************************************************
* @brief Obtains the time difference between two given time points in
* seconds.
* @details Result is defined as t_diff = t_end - t_start.
* Refers to Time_Diff() and handles overflow.
* @param t_start Start time point.
* @param t_end End time point.
* @return Time difference in seconds.
*****************************************************************************/
uint32_t Time_DiffSec(ltc_t const *t_start, ltc_t const *t_end);
/*!***************************************************************************
* @brief Time delay for a given time period.
* @param dt Delay time.
*****************************************************************************/
void Time_Delay(ltc_t const *dt);
/*!***************************************************************************
* @brief Time delay for a given time period in microseconds.
* @param dt_usec Delay time in microseconds.
*****************************************************************************/
void Time_DelayUSec(uint32_t dt_usec);
/*!***************************************************************************
* @brief Time delay for a given time period in milliseconds.
* @param dt_msec Delay time in milliseconds.
*****************************************************************************/
void Time_DelayMSec(uint32_t dt_msec);
/*!***************************************************************************
* @brief Time delay for a given time period in seconds.
* @param dt_sec Delay time in seconds.
*****************************************************************************/
void Time_DelaySec(uint32_t dt_sec);
/*!***************************************************************************
* @brief Checks if timeout is reached from a given starting time.
* @details Handles overflow.
* @param t_start Start time.
* @param t_timeout Timeout period.
* @return Timeout elapsed? True/False (boolean value)
*****************************************************************************/
bool Time_CheckTimeout(ltc_t const *t_start, ltc_t const *t_timeout);
/*!***************************************************************************
* @brief Checks if timeout is reached from a given starting time.
* @details Handles overflow.
* @param t_start Start time.
* @param t_timeout_usec Timeout period in microseconds.
* @return Timeout elapsed? True/False (boolean value)
*****************************************************************************/
bool Time_CheckTimeoutUSec(ltc_t const *t_start, uint32_t const t_timeout_usec);
/*!***************************************************************************
* @brief Checks if timeout is reached from a given starting time.
* @details Handles overflow.
* @param t_start Start time.
* @param t_timeout_msec Timeout period in milliseconds.
* @return Timeout elapsed? True/False (boolean value)
*****************************************************************************/
bool Time_CheckTimeoutMSec(ltc_t const *t_start, uint32_t const t_timeout_msec);
/*!***************************************************************************
* @brief Checks if timeout is reached from a given starting time.
* @details Handles overflow.
* @param t_start Start time.
* @param t_timeout_sec Timeout period in seconds.
* @return Timeout elapsed? True/False (boolean value)
*****************************************************************************/
bool Time_CheckTimeoutSec(ltc_t const *t_start, uint32_t const t_timeout_sec);
/*!***************************************************************************
* @brief Adds two ltc_t values.
* @details Result is defined as t = t1 + t2. Results are wrapped around at
* maximum values just like integers.
* @param t Return value: t = t1 + t2.
* @param t1 1st operand.
* @param t2 2nd operand.
*****************************************************************************/
void Time_Add(ltc_t *t, ltc_t const *t1, ltc_t const *t2);
/*!***************************************************************************
* @brief Adds a given time in microseconds to an ltc_t value.
* @param t Return value: t = t1 + t2.
* @param t1 1st operand.
* @param t2_usec 2nd operand in microseconds.
*****************************************************************************/
void Time_AddUSec(ltc_t *t, ltc_t const *t1, uint32_t t2_usec);
/*!***************************************************************************
* @brief Adds a given time in milliseconds to an ltc_t value.
* @param t Return value: t = t1 + t2.
* @param t1 1st operand.
* @param t2_msec 2nd operand in milliseconds.
*****************************************************************************/
void Time_AddMSec(ltc_t *t, ltc_t const *t1, uint32_t t2_msec);
/*!***************************************************************************
* @brief Adds a given time in seconds to an ltc_t value.
* @param t Return value: t = t1 + t2.
* @param t1 1st operand.
* @param t2_sec 2nd operand in seconds.
*****************************************************************************/
void Time_AddSec(ltc_t *t, ltc_t const *t1, uint32_t t2_sec);
/*!***************************************************************************
* @brief Converts ltc_t to microseconds (uint32_t).
* @param t Input ltc_t struct.
* @return Time value in microseconds.
*****************************************************************************/
uint32_t Time_ToUSec(ltc_t const *t);
/*!***************************************************************************
* @brief Converts ltc_t to milliseconds (uint32_t).
* @param t Input ltc_t struct.
* @return Time value in milliseconds.
*****************************************************************************/
uint32_t Time_ToMSec(ltc_t const *t);
/*!***************************************************************************
* @brief Converts ltc_t to seconds (uint32_t).
* @param t Input ltc_t struct.
* @return Time value in seconds.
*****************************************************************************/
uint32_t Time_ToSec(ltc_t const *t);
/*! @} */
#endif /* TIME_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,166 @@
/*************************************************************************//**
* @file argus_hal_test.c
* @brief Tests for the AFBR-S50 API hardware abstraction layer.
*
* @copyright
*
* Copyright (c) 2021, Broadcom, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef ARGUS_HAL_TEST_H
#define ARGUS_HAL_TEST_H
__BEGIN_DECLS
/*!***************************************************************************
* @addtogroup argustest
* @{
*****************************************************************************/
#include "argus.h"
/*!***************************************************************************
* @brief Version number of the HAL Self Test.
*
* @details Changes:
*
* - v1.0:
* - Initial release.
* .
* - v1.1:
* - Added additional print output.
* - Increased tolerance for timer test to 3%.
* - Fixed callback issue by disabling it after IRQ test.
* .
*****************************************************************************/
#define HAL_TEST_VERSION "v1.1"
/*!***************************************************************************
* @brief Executes a series of tests in order to verify the HAL implementation.
*
* @details A series of automated tests are executed in order to verify the
* implementation of the HAL required by the API.
*
* The following tests are executed:
*
* 1) Timer Plausibility Test:
*
* Rudimentary tests of the lifetime counter (LTC) implementation.
* This verifies that the LTC is running by checking if the returned
* values of two consecutive calls to the #Timer_GetCounterValue
* function are ascending. An artificial delay using the NOP operation
* is induced such that the timer is not read to fast.
*
* 2) Timer Wraparound Test:
*
* The LTC values must wrap from 999999 μs to 0 μs and increase the
* seconds counter accordingly. This test verifies the correct wrapping
* by consecutively calling the #Timer_GetCounterValue function until
* at least 2 wraparound events have been occurred.
*
* 3) SPI Connection Test:
*
* This test verifies the basic functionality of the SPI interface.
* The test utilizes the devices laser pattern register, which can
* be freely programmed by any 128-bit pattern. Thus, it writes a byte
* sequence and reads back the written values on the consecutive SPI
* access.
*
* 4) SPI Interrupt Test:
*
* This test verifies the correct implementation of the device
* integration finished interrupt callback. Therefore it configures
* the device with a minimal setup to run a pseudo measurement that
* does not emit any laser light.
*
* Note that this test does verify the GPIO interrupt that occurs
* whenever the device has finished the integration/measurement and
* new data is waiting to be read from the device. This does not test
* the interrupt that is triggered when the SPI transfer has finished.
*
* The data ready interrupt implies two S2PI layer functions that
* are tested in this test: The #S2PI_SetIrqCallback function installs
* a callback function that is invoked whenever the IRQ occurs.
* The IRQ can be delayed due to higher priority task, e.g. from the
* user code. It is essential for the laser safety timeout algorithm
* to determine the device ready signal as fast as possible, another
* method is implemented to read if the IRQ is pending but the
* callback has not been reset yet. This is what the #S2PI_ReadIrqPin
* function is for.
*
* 5) GPIO Mode Test:
*
* This test verifies the GPIO mode of the S2PI HAL module. This is
* done by leveraging the EEPROM readout sequence that accesses the
* devices EEPROM via a software protocol that depends on the GPIO
* mode.
*
* This the requires several steps, most of them are already verified
* in previous tests:
* - Basic device configuration and enable EEPROM.
* - Read EERPOM via GPIO mode and apply Hamming weight
* - Repeat several times (to eliminate random readout issues).
* - Decode the EEPROM (using EEPROM_Decode in argus_cal_eeprom.c)
* - Check if Module Number and Chip ID is not 0
*
* 6) Timer Test:
*
* The test verifies the timer HAL implementation by comparing the
* timings to the AFBR-S50 device as a reference.
* Therefore several measurement are executed on the device, each with
* a different averaging sample count. The elapsed time increases
* linearly with the number of averaging samples. In order to remove
* the time for software/setup, a linear regression fit is applied to
* the measurement results and only the slope is considered for the
* result. A delta of 102.4 microseconds per sample is expected.
* If the measured delta per sample is within an specified error range,
* the timer implementation is considered correct.
*
* -------------------------------------------------------------------
*
* Each test will write an error description via the print (i.e. UART)
* function that shows what went wrong. Also an corresponding status is
* returned in case no print functionality is available.
*
*
* @param spi_slave The SPI hardware slave, i.e. the specified CS and IRQ
* lines. This is actually just a number that is passed
* to the SPI interface to distinct for multiple SPI slave
* devices. Note that the slave must be not equal to 0,
* since is reserved for error handling.
*
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_VerifyHALImplementation(s2pi_slave_t spi_slave);
__END_DECLS
/*! @} */
#endif /* ARGUS_CAL_API_H */
+16 -16
View File
@@ -1,6 +1,6 @@
/****************************************************************************
*
* Copyright (c) 2012-2020 PX4 Development Team. All rights reserved.
* Copyright (c) 2012-2021 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -163,23 +163,23 @@
#define DRV_MAG_DEVTYPE_UAVCAN 0x88
#define DRV_DIST_DEVTYPE_UAVCAN 0x89
#define DRV_ADC_DEVTYPE_ADS1115 0x90
#define DRV_DIST_DEVTYPE_VL53L1X 0x91
#define DRV_DIST_DEVTYPE_CM8JL65 0x92
#define DRV_DIST_DEVTYPE_LEDDARONE 0x93
#define DRV_DIST_DEVTYPE_MAVLINK 0x94
#define DRV_DIST_DEVTYPE_PGA460 0x95
#define DRV_DIST_DEVTYPE_PX4FLOW 0x96
#define DRV_DIST_DEVTYPE_TFMINI 0x97
#define DRV_DIST_DEVTYPE_ULANDING 0x98
#define DRV_ADC_DEVTYPE_ADS1115 0x90
#define DRV_GPIO_DEVTYPE_MCP23009 0x99
#define DRV_DIST_DEVTYPE_SIM 0x9a
#define DRV_DIST_DEVTYPE_SRF05 0x9b
#define DRV_DIST_DEVTYPE_GY_US42 0x9c
#define DRV_BAT_DEVTYPE_BATMON_SMBUS 0x9d
#define DRV_DIST_DEVTYPE_VL53L1X 0x91
#define DRV_DIST_DEVTYPE_CM8JL65 0x92
#define DRV_DIST_DEVTYPE_LEDDARONE 0x93
#define DRV_DIST_DEVTYPE_MAVLINK 0x94
#define DRV_DIST_DEVTYPE_PGA460 0x95
#define DRV_DIST_DEVTYPE_PX4FLOW 0x96
#define DRV_DIST_DEVTYPE_TFMINI 0x97
#define DRV_DIST_DEVTYPE_ULANDING 0x98
#define DRV_DIST_DEVTYPE_AFBRS50 0x99
#define DRV_DIST_DEVTYPE_SIM 0x9A
#define DRV_DIST_DEVTYPE_SRF05 0x9B
#define DRV_DIST_DEVTYPE_GY_US42 0x9C
#define DRV_BAT_DEVTYPE_BATMON_SMBUS 0x9d
#define DRV_GPIO_DEVTYPE_MCP23009 0x9F
#define DRV_GPS_DEVTYPE_ASHTECH 0xA0
#define DRV_GPS_DEVTYPE_EMLID_REACH 0xA1
@@ -48,7 +48,7 @@ public:
// Set the MAV_DISTANCE_SENSOR type (LASER, ULTRASOUND, INFRARED, RADAR)
void set_rangefinder_type(uint8_t rangefinder_type) { _distance_sensor_pub.get().type = rangefinder_type; };
void set_device_id(const uint8_t device_id) { _distance_sensor_pub.get().device_id = device_id; };
void set_device_id(const uint32_t device_id) { _distance_sensor_pub.get().device_id = device_id; };
void set_device_type(const uint8_t device_type);
void set_fov(const float fov) { set_hfov(fov); set_vfov(fov); }