Skip to content

Commit

Permalink
Added support for STA5635 SPI command/response. (#341)
Browse files Browse the repository at this point in the history
# New Features
- Added message support for sending SPI commands over a UART to an
STA5635 L-band front end
  • Loading branch information
leskowicz authored Oct 29, 2024
2 parents 969cf8a + b7110c2 commit daf7ecd
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 1 deletion.
11 changes: 11 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ cc_library(
],
)

# STA5635 RF front-end message definitions.
cc_library(
name = "sta5635",
hdrs = [
"src/point_one/fusion_engine/messages/sta5635.h",
],
deps = [
":core_headers",
],
)

# ROS translation message definitions.
cc_library(
name = "ros_support",
Expand Down
1 change: 1 addition & 0 deletions python/fusion_engine_client/messages/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .core import *
from .fault_control import *
from . import ros
from . import sta5635

message_type_to_class = MessagePayload.message_type_to_class
message_type_by_name = MessagePayload.message_type_by_name
Expand Down
3 changes: 3 additions & 0 deletions python/fusion_engine_client/messages/defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ class MessageType(IntEnum):

LBAND_FRAME = 14000

STA5635_COMMAND = 14100
STA5635_COMMAND_RESPONSE = 14101

RESERVED = 20000

@classmethod
Expand Down
86 changes: 86 additions & 0 deletions python/fusion_engine_client/messages/sta5635.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from construct import (Struct, Int8ul, Int32ul, Int64sl, Bytes)

from ..utils.construct_utils import construct_message_to_string
from .defs import *


class STA5635Command(MessagePayload):
"""!
@brief A command to be sent to an attached STA5635 RF front-end.
"""
MESSAGE_TYPE = MessageType.STA5635_COMMAND
MESSAGE_VERSION = 0

Construct = Struct(
"command" / Int8ul,
"address" / Int8ul,
"data" / Bytes(2),
)

def __init__(self):
self.command = 0
self.address = 0
self.data = bytes()

def pack(self, buffer: Optional[bytes] = None, offset: int = 0, return_buffer: bool = True) -> (bytes, int):
values = vars(self)
packed_data = self.Construct.build(values)
return PackedDataToBuffer(packed_data, buffer, offset, return_buffer)

def unpack(self, buffer: bytes, offset: int = 0, message_version: int = MessagePayload._UNSPECIFIED_VERSION) -> int:
parsed = self.Construct.parse(buffer[offset:])
self.__dict__.update(parsed)
del self.__dict__['_io']
return parsed._io.tell()

def calcsize(self) -> int:
return self.Construct.sizeof()

def __repr__(self):
result = super().__repr__()[:-1]
result += f', command=0x{self.command:02X}, address=0x{self.address:02X}, data={self.data}]'
return result

def __str__(self):
return construct_message_to_string(message=self, value_to_string={
'command': lambda x: f'0x{x:02X}',
'address': lambda x: f'0x{x:02X}',
})


class STA5635CommandResponse(MessagePayload):
"""!
@brief Result from an STA5635 sent in response to an @ref STA5635Command.
"""
MESSAGE_TYPE = MessageType.STA5635_COMMAND_RESPONSE
MESSAGE_VERSION = 0

Construct = Struct(
"system_time_ns" / Int64sl,
"command_sequence_number" / Int32ul,
"data" / Bytes(4),
)

def __init__(self):
self.system_time_ns = 0
self.command_sequence_number = 0
self.data = bytes()

def pack(self, buffer: Optional[bytes] = None, offset: int = 0, return_buffer: bool = True) -> (bytes, int):
values = vars(self)
packed_data = self.Construct.build(values)
return PackedDataToBuffer(packed_data, buffer, offset, return_buffer)

def unpack(self, buffer: bytes, offset: int = 0, message_version: int = MessagePayload._UNSPECIFIED_VERSION) -> int:
parsed = self.Construct.parse(buffer[offset:])
self.__dict__.update(parsed)
del self.__dict__['_io']
return parsed._io.tell()

def calcsize(self) -> int:
return self.Construct.sizeof()

def __repr__(self):
result = super().__repr__()[:-1]
result += f', seq={self.command_sequence_number}, data={self.data}]'
return result
14 changes: 13 additions & 1 deletion src/point_one/fusion_engine/messages/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,11 @@ enum class MessageType : uint16_t {

LBAND_FRAME = 14000, ///< @ref LBandFrameMessage

STA5635_COMMAND = 14100, ///< @ref STA5635Command
STA5635_COMMAND_RESPONSE = 14101, ///< @ref STA5635CommandResponse

/// The maximum defined @ref MessageType enum value.
MAX_VALUE = LBAND_FRAME,
MAX_VALUE = STA5635_COMMAND_RESPONSE,
};

/**
Expand Down Expand Up @@ -272,6 +275,12 @@ P1_CONSTEXPR_FUNC const char* to_string(MessageType type) {

case MessageType::LBAND_FRAME:
return "L-band Frame Contents";

case MessageType::STA5635_COMMAND:
return "STA5635 Command";

case MessageType::STA5635_COMMAND_RESPONSE:
return "STA5635 Command Response";
}
return "Unrecognized Message";
}
Expand Down Expand Up @@ -309,6 +318,7 @@ P1_CONSTEXPR_FUNC bool IsCommand(MessageType message_type) {
case MessageType::EXPORT_DATA:
case MessageType::SET_MESSAGE_RATE:
case MessageType::GET_MESSAGE_RATE:
case MessageType::STA5635_COMMAND:
return true;
case MessageType::INVALID:
case MessageType::POSE:
Expand Down Expand Up @@ -348,6 +358,7 @@ P1_CONSTEXPR_FUNC bool IsCommand(MessageType message_type) {
case MessageType::MESSAGE_RATE_RESPONSE:
case MessageType::SUPPORTED_IO_INTERFACES:
case MessageType::LBAND_FRAME:
case MessageType::STA5635_COMMAND_RESPONSE:
return false;
}
return false;
Expand All @@ -368,6 +379,7 @@ P1_CONSTEXPR_FUNC bool IsResponse(MessageType message_type) {
case MessageType::COMMAND_RESPONSE:
case MessageType::CONFIG_RESPONSE:
case MessageType::MESSAGE_RATE_RESPONSE:
case MessageType::STA5635_COMMAND_RESPONSE:
return true;
default:
return false;
Expand Down
90 changes: 90 additions & 0 deletions src/point_one/fusion_engine/messages/sta5635.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**************************************************************************/ /**
* @brief Command/control support for an attached STA5635 RF front-end.
* @file
******************************************************************************/

#pragma once

#include "point_one/fusion_engine/common/portability.h"
#include "point_one/fusion_engine/messages/defs.h"

namespace point_one {
namespace fusion_engine {
namespace messages {

// Enforce 4-byte alignment and packing of all data structures and values.
// Floating point values are aligned on platforms that require it. This is done
// with a combination of setting struct attributes, and manual alignment
// within the definitions. See the "Message Packing" section of the README.
#pragma pack(push, 1)

/**************************************************************************/ /**
* @defgroup sta5635 STA5635 Command/Control Messages
* @brief Messages for interacting with an attached STA5635 RF front-end device.
* @ingroup device_control
*
* These messages are intended to be used only for devices with an
* STMicroelectronics STA5635 RF front-end where direct user control of the
* front-end is needed. This is not common and should not be used on most
* platforms.
*
* For platforms using an STA5635, the device will output @ref LBandFrameMessage
* containing I/Q samples from the RF front-end. The format and use of the I/Q
* samples is platform-specific.
*
* See also @ref messages.
******************************************************************************/

/**
* @brief A command to be sent to an attached STA5635 RF front-end. (@ref
* MessageType::STA5635_COMMAND, version 1.0).
* @ingroup sta5635
*
* See the STA5635 data sheet for the allowed command, address, and data values.
*/
struct P1_ALIGNAS(4) STA5635Command : public MessagePayload {
static constexpr MessageType MESSAGE_TYPE = MessageType::STA5635_COMMAND;
static constexpr uint8_t MESSAGE_VERSION = 0;

/** The STA5635 command code to be issued. */
uint8_t command = 0;
/** The address of the STA5635 register to be accessed. */
uint8_t address = 0;
/**
* The value to be sent to the device, where `data[0]` contains the MSB.
*/
uint8_t data[2] = {0};
};

/**
* @brief Result from an STA5635 sent in response to an @ref STA5635Command.
* (@ref MessageType::STA5635_COMMAND_RESPONSE, version 1.0).
* @ingroup sta5635
*/
struct P1_ALIGNAS(4) STA5635CommandResponse : public MessagePayload {
static constexpr MessageType MESSAGE_TYPE =
MessageType::STA5635_COMMAND_RESPONSE;
static constexpr uint8_t MESSAGE_VERSION = 0;

/**
* The system time when the response was received (in nanoseconds). Note that
* this is not synchronized to P1 or GNSS time.
*/
int64_t system_time_ns = 0;
/**
* The sequence number contained in the @ref STA5635Command to which this
* response belongs.
*/
uint32_t command_sequence_number = 0;
/**
* The response from the device, where `data[0]` contains the first byte in
* the response.
*/
uint8_t data[4] = {0};
};

#pragma pack(pop)

} // namespace messages
} // namespace fusion_engine
} // namespace point_one

0 comments on commit daf7ecd

Please sign in to comment.