Ke Ao Teensy Flight Software
The software on the Teensy in the Ke Ao cubesat.
Loading...
Searching...
No Matches
Artemis::Devices::Astrodev Class Reference

The satellite's Astrodev (Li-3) radio. More...

#include <astrodev.h>

Classes

struct  beacon_config
 Structure for beacon configuration. More...
 
struct  firmware
 Structure for radio firmware version communication. More...
 
struct  frame
 Structure of Astrodev Command and Data Interface (CDI) frame. More...
 
struct  function_config1
 Structure for configuring discrete Astrodev radio functions. More...
 
struct  function_config2
 Structure for configuring more discrete Astrodev radio functions. More...
 
struct  realtimeclock
 Structure for radio Real-Time Clock (RTC) communication. More...
 
struct  response
 The structure for a response from the Astrodev radio. More...
 
struct  rf_config
 Structure for configuring the RF functions of the Astrodev radio. More...
 
struct  tcv_config
 Structure for configuring the Astrodev radio. More...
 
struct  telemetry
 Structure for configuring telemetry data for the Astrodev radio. More...
 

Public Types

enum class  Command : uint8_t {
  NAK = 0x00 , NOOP = 0x01 , RESET = 0x02 , TRANSMIT = 0x03 ,
  RECEIVE = 0x04 , GETTCVCONFIG = 0x05 , SETTCVCONFIG = 0x06 , TELEMETRY = 0x07 ,
  FLASH = 0x08 , RFCONFIG = 0x09 , BEACONDATA = 0x10 , BEACONCONFIG = 0x11 ,
  FIRMWAREREV = 0x12 , DIOKEY = 0x13 , FIRMWAREUPDATE = 0x14 , FIRMWAREPACKET = 0x15 ,
  WRITE_KEY_A_128 = 0x16 , WRITE_KEY_B_128 = 0x17 , WRITE_KEY_A_256 = 0x18 , WRITE_KEY_B_256 = 0x19 ,
  FASTSETPA = 0x20 , GET_RTC = 0x41 , SET_RTC = 0x42 , ALARM_RTC = 0x43
}
 Enumeration of Astrodev commands. More...
 
enum class  Modulation : uint8_t { ASTRODEV_MODULATION_GFSK , ASTRODEV_MODULATION_AFSK , ASTRODEV_MODULATION_BPSK , ASTRODEV_MODULATION_NONE }
 Enumeration of Astrodev modulation types. More...
 
enum class  OACommand {
  TELEMETRY_DUMP = 0x30 , PING_RETURN = 0x31 , CODE_UPLOAD = 0x32 , RADIO_RESET = 0x33 ,
  PIN_TOGGLE = 0x34
}
 Enumeration of Over-the-Air (OA) Astrodev commands. More...
 

Public Member Functions

 Astrodev ()
 Construct a new Astrodev:: Astrodev object.
 
 Astrodev (HardwareSerial *hw_serial)
 Construct a new Astrodev:: Astrodev object.
 
int32_t InitializeSerial (HardwareSerial *hw_serial, uint32_t baud_rate=38400)
 Initialization of the serial connection to the Astrodev radio.
 
int32_t VerifyConnection ()
 Verify serial connection to the Astrodev radio.
 
int32_t SendAstrodevFrame (frame &message)
 Send an Astrodev frame to the radio.
 
int32_t SendHeaderOnlyFrame (Command command)
 Helper function to construct and send header-only command frames to the Astrodev radio.
 
int32_t NoOp ()
 Send a no-operation (no-op) command to the Astrodev radio.
 
int32_t Reset ()
 Send a soft reset command to the Astrodev radio.
 
int32_t GetTCVConfig ()
 Send a get transceiver configuration command to the Astrodev radio.
 
int32_t GetTelemetry ()
 Sends a get telemetry command to the Astrodev radio.
 
int32_t TransmitPacketFromRadio (Cosmos::Support::PacketComm &packet)
 Command the Astrodev radio to transmit a PacketComm packet.
 
int32_t SetTCVConfig ()
 Set transceiver configuration settings on the radio.
 
int32_t SetRFConfig (rf_config config)
 Sets the RF configuration settings on the radio.
 
int32_t ReceiveAstrodevFrame (frame &message)
 Receive an Astrodev frame from the radio.
 
uint16_t CalcCS (uint8_t *data, uint16_t size)
 Calculate a checksum.
 
void setSerial (HardwareSerial *new_serial)
 Sets the serial connection used to communicate with the radio.
 

Public Attributes

std::map< uint8_t, uint16_t > RF_BAUD
 Mapping of integer configuration values to RF baud rate.
 
std::map< uint16_t, uint8_t > RF_INDEX
 Mapping of RF baud rate to integer configuration values.
 
std::map< uint8_t, uint16_t > UART_BAUD
 Mapping of integer configuration values to serial baud rate.
 
std::map< uint16_t, uint8_t > UART_INDEX
 Mapping of serial baud rate to integer configuration values.
 
telemetry last_telem
 
int32_t last_error = 0
 
std::atomic< bool > buffer_full
 
Command last_command = Command::NAK
 
tcv_config tcv_configuration
 
std::atomic< bool > ack_noop
 
std::atomic< bool > ack_reset
 
std::atomic< bool > ack_transmit
 
std::atomic< bool > ack_setTCVConfig
 

Static Public Attributes

static constexpr uint8_t SYNC0 = 'H'
 The first synchronization byte.
 
static constexpr uint8_t SYNC1 = 'e'
 The second synchronization byte.
 
static constexpr uint8_t TORADIO = 0x10
 A command being sent from the Teensy.
 
static constexpr uint8_t TOTEENSY = 0x20
 A response being sent from the radio.
 
static constexpr uint8_t MTU = 254
 The Maximum Transmission Units (MTU).
 
static constexpr uint16_t PACKETCOMM_DATA_SIZE
 The maximum size of a PacketComm payload.
 

Detailed Description

The satellite's Astrodev (Li-3) radio.

Member Enumeration Documentation

◆ Command

enum class Artemis::Devices::Astrodev::Command : uint8_t
strong

Enumeration of Astrodev commands.

This enum represents the type of command in the packets used to communicate between the Teensy and Astrodev radio.

Enumerator
NAK 

No-op Acknowledge.

NOOP 

No-op command.

RESET 

Reset Astrodev radio processors and systems.

TRANSMIT 

Send bytes to Astrodev radio.

RECEIVE 

Receive bytes from Astrodev radio.

GETTCVCONFIG 

Get Astrodev radio configuration.

SETTCVCONFIG 

Set Astrodev radio configuration.

TELEMETRY 

A telemetry packet, either sent from or to the Astrodev radio.

FLASH 

Write to the Astrodev radio's flash memory.

RFCONFIG 

Low level RF configuration.

BEACONDATA 

Set beacon contents.

BEACONCONFIG 

Set beacon configuration.

FIRMWAREREV 

Firmware number, a 4-byte float.

DIOKEY 

Digital I/O (DIO) key write.

FIRMWAREUPDATE 

Firmware update command.

FIRMWAREPACKET 

Firmware packet write.

WRITE_KEY_A_128 

Used to write to the firmware.

WRITE_KEY_B_128 

Used to write to the firmware.

WRITE_KEY_A_256 

Used to write to the firmware.

WRITE_KEY_B_256 

Used to write to the firmware.

FASTSETPA 

Set power amplifier level (high speed)

GET_RTC 

Get Real-Time Clock (RTC) values.

SET_RTC 

Set Real-Time Clock (RTC).

ALARM_RTC 

An alarm on the Real-Time Clock (RTC).

◆ Modulation

enum class Artemis::Devices::Astrodev::Modulation : uint8_t
strong

Enumeration of Astrodev modulation types.

This enum represents the types of modulation that can be configured on the Astrodev radio.

Enumerator
ASTRODEV_MODULATION_GFSK 

Gaussian Frequency Shift Keying (GFSK) modulation.

ASTRODEV_MODULATION_AFSK 

Audio Frequency Shift Keying (AFSK) modulation.

ASTRODEV_MODULATION_BPSK 

Binary Phase Shift Keying (BPSK) modulation.

ASTRODEV_MODULATION_NONE 

No modulation.

◆ OACommand

Enumeration of Over-the-Air (OA) Astrodev commands.

This enum represents the commands that can be sent to the Astrodev radio from a ground station. Note that sending these commands requires configuring an OA key and transmitting that key along with the command.

Enumerator
TELEMETRY_DUMP 

Send a telemetry packet. Currently reserved (unavailable).

PING_RETURN 

Responds with telemetry structure.

CODE_UPLOAD 

Upload code to the radio. Currently reserved (unavailable).

RADIO_RESET 

Soft reset the radio.

PIN_TOGGLE 

Directly toggle over-the-air pin.

Constructor & Destructor Documentation

◆ Astrodev() [1/2]

Artemis::Devices::Astrodev::Astrodev ( )

Construct a new Astrodev:: Astrodev object.

This constructor can be used to create an instance of the Astrodev class without providing any specific HardwareSerial object.

◆ Astrodev() [2/2]

Artemis::Devices::Astrodev::Astrodev ( HardwareSerial *  hw_serial)

Construct a new Astrodev:: Astrodev object.

This constructor is used to create an instance of the Astrodev class specifying the HardwareSerial object that connects the Teensy and radio.

Parameters
hw_serialA pointer to a HardwareSerial object representing the serial port connecting the radio and the Teensy.

Member Function Documentation

◆ CalcCS()

uint16_t Artemis::Devices::Astrodev::CalcCS ( uint8_t *  data,
uint16_t  size 
)

Calculate a checksum.

Parameters
dataA pointer to the data to be calculated over.
sizeThe size of the data to be calculated over.
Returns
uint16_t A two-byte checksum of the data.

The checksum consists of two bytes, ck_a and ck_b. Combined, they form the two-byte checksum cs.

The checksum algorithm is relatively simple. For each byte in the data, it is added to ck_a. ck_a is then added to ck_b. This repeats for every byte in the data to be summed over.

The resulting two-byte checksum consists of ck_a in the low byte position and ck_b in the high byte position.

◆ GetTCVConfig()

int32_t Artemis::Devices::Astrodev::GetTCVConfig ( )

Send a get transceiver configuration command to the Astrodev radio.

Returns
int32_t Returns 0 if command is successfully sent, negative value if unsuccessful.

The Astrodev radio is sent a header-only command frame with the command Command::GETTCVCONFIG, which queries the radio for its transceiver configuration.

◆ GetTelemetry()

int32_t Artemis::Devices::Astrodev::GetTelemetry ( )

Sends a get telemetry command to the Astrodev radio.

Returns
int32_t Returns 0 if command is successfully sent, negative value if unsuccessful.

The Astrodev radio is sent a header-only command frame with the command Command::TELEMETRY, which queries the radio for its telemetry data.

◆ InitializeSerial()

int32_t Artemis::Devices::Astrodev::InitializeSerial ( HardwareSerial *  hw_serial,
uint32_t  baud_rate = 38400 
)

Initialization of the serial connection to the Astrodev radio.

Parameters
hw_serialA pointer to a HardwareSerial object representing the serial port on the Teensy connecting it to the Astrodev radio.
baud_rateThe baud rate of that serial connection. Defaults to 38400.
Returns
int32_t Always returns 0.

The passed in HardwareSerial parameter is copied over to the internal private variable in the Astrodev class. This internal serial connection is then begun using the passed-in baud rate parameter.

◆ NoOp()

int32_t Artemis::Devices::Astrodev::NoOp ( )

Send a no-operation (no-op) command to the Astrodev radio.

Returns
int32_t Returns 0 if command is successfully sent, negative value if unsuccessful.

The Astrodev radio is sent a header-only command frame with the command Command::NOOP, which is a no-operation (no-op) command. This has no effect on the radio, other than generating an acknowledge frame in reply.

This command can be used to query if the Astrodev radio's buffer is full, as the ack reply frame contains radio status flags in the high byte of the payload size field.

◆ ReceiveAstrodevFrame()

int32_t Artemis::Devices::Astrodev::ReceiveAstrodevFrame ( frame incoming_frame)

Receive an Astrodev frame from the radio.

Parameters
incoming_frameA pointer to an Astrodev frame struct to hold the recieved data from the radio.
Returns
int32_t Returns the Astrodev command type from the packet header if successful, negative value if unsuccessful.

The internal incoming queue mutex is locked.

The synchronization characters are awaited. The serial interface is read from, one character at a time, twice. The first synchronization character is optional, but if both synchronization characters are not read, return with an error value. This error is also returned if nothing is received within a one-second timeout period. The synchronization characters are then placed in the frame's header.

The remaining six bytes of the header are read in from the serial interface and stored in the frame's header. In the event that the serial interface does not yet have six bytes available, read all the bytes available, then read the remaining bytes to form a full header. If no more bytes are available, return with an error value.

Calculate the header checksum and compare it to the received header's checksum. If they do not match, return with an error value.

The ack and sizelo bytes in the frame header are checked to determine what type of frame is incoming from the radio. The internal buffer full status flag is set to the value received in the top four bits of the ack byte in the reply from the radio.

ack and sizelo are appended together and masked to determine the value of the bottom three bytes. If the value is 0x0A0A, then the incoming frame is an acknowledge response from the radio. The function returns here with the command type of the incoming frame.

If the appended and masked value is 0x0FFF, then the incoming packet is a no-acknowledge response from the radio. This function returns with an error value.

Otherwise, the frame is a reponse that should have a payload. Determine the size of the payload by checking the header. If there is no payload, then return the type of command from the frame's header.

Using this size, read that number of bytes (plus two more bytes for the checksum) from the serial interface. Store those read-in bytes in the payload of the Astrodev frame. If all the bytes in the frame's payload are not immediately available, keep trying to read in the remaining bytes from the serial interface. Try no more than five times to read as much of the frame's payload as possible.

Extract the frame checksum from the end of the frame, after the payload. If it does not match the checksum generated by the received frame's payload and header, return with an error value.

Finally, if all aspects of the frame's header have been verified, return the type of command from the frame's header.

◆ Reset()

int32_t Artemis::Devices::Astrodev::Reset ( )

Send a soft reset command to the Astrodev radio.

Returns
int32_t Returns 0 if command is successfully sent, negative value if unsuccessful.

The Astrodev radio is sent a header-only command frame with the command Command::RESET, which is a soft reset command.

◆ SendAstrodevFrame()

int32_t Artemis::Devices::Astrodev::SendAstrodevFrame ( frame outgoing_frame)

Send an Astrodev frame to the radio.

Parameters
outgoing_frameA pointer to an Astrodev frame struct to be sent to the radio.
Returns
int32_t Returns size of transmitted frame's payload in bytes if successful, negative value if unsuccessful. If successful, this return value only indicates that the Astrodev frame was sucessfully sent to the radio. It gives no indication on whether that command was successfully executed.

The internal outgoing queue mutex is locked.

The size of the payload is checked. If it is too large to be sent, return an error value.

Fill in the header data with the synchronization bytes. Additionally specify that this frame is being sent from the Teensy to the radio, empty the high byte of the payload size field (only the low byte is used), and calculate the header checksum bytes over the fields representing the frame's direction of travel, command type, and payload size.

Send the header data over the serial connection. If the entire frame consists of just the header, then skip the payload processing and return the size of the frame's payload (which is 0 for header-only frames going from the Teensy to the Astrodev radio).

Calculate the two-byte payload checksum. The checksum is calculated over all bytes in the frame including the header with the exception of the two synchronization bytes. The checksum is then appended to the end of the frame, after the payload.

The remainder of the frame (payload and payload checksum) are then sent over the serial connection.

The total size of the frame is returned as the sum of the size of the payload, the header (8 bytes) and the payload checksum (2 bytes).

◆ SendHeaderOnlyFrame()

int32_t Artemis::Devices::Astrodev::SendHeaderOnlyFrame ( Command  command)

Helper function to construct and send header-only command frames to the Astrodev radio.

Parameters
commandThe command to be sent to the Astrodev radio, defined as the Astrodev::Command enum.
Returns
int32_t Returns the size of the frame's payload (which is 0) if the frame was sucessfully sent to the radio, negative value if unsuccessful. This return value does not indicate whether the command has been executed; it only indicates that the command has been sent.

The frame's header data is filled in. The frame is designated with the passed in command, with an empty payload.

The command frame is sent to the radio. If unsuccessful, return the error code.

A short delay is given for the Astrodev radio to acknowledge the command.

◆ SetRFConfig()

int32_t Artemis::Devices::Astrodev::SetRFConfig ( rf_config  config)

Sets the RF configuration settings on the radio.

Parameters
configThe RF configuration settings struct containing the settings to be written to the radio.
Returns
int32_t Returns 0 if successful, negative value if unsuccessful.

An Astrodev packet is created to communicate with the radio.

This packet's header data is filled in. The packet is designated as a RFCONFIG command, with the RF configuration struct as the payload. The size of the payload is the size of that struct.

The packet is transmitted to the radio. Delay for a short time (at least 250 ms) to apply the settings. If unsuccessful, return the error code.

◆ setSerial()

void Artemis::Devices::Astrodev::setSerial ( HardwareSerial *  new_serial)

Sets the serial connection used to communicate with the radio.

Parameters
new_serialA pointer to a HardwareSerial object representing the serial port to be used to communicate with the radio.

The passed-in serial port object is copied over to the internal serial port object.

◆ SetTCVConfig()

int32_t Artemis::Devices::Astrodev::SetTCVConfig ( )

Set transceiver configuration settings on the radio.

Returns
int32_t Returns size of configuration struct if successful, negative value if unsuccessful.

An Astrodev packet is created to communicate with the radio.

This packet's header data is filled in. The packet is designated as a SETTCVCONFIG command, with the current internal transceiver configuration struct as the payload. The size of the payload is the size of that struct.

The packet is transmitted to the radio. If unsuccessful, return the error code.

After a short delay, receive the response from the radio. If unsucccessful, return the error code.

Todo:
Wait at least 250 ms for settings to be applied, but seemsto require about 10x as long

◆ TransmitPacketFromRadio()

int32_t Artemis::Devices::Astrodev::TransmitPacketFromRadio ( Cosmos::Support::PacketComm &  transmission_packet)

Command the Astrodev radio to transmit a PacketComm packet.

Parameters
transmission_packetA pointer to a PacketComm packet struct to be transmitted by the Astrodev radio.
Returns
int32_t Returns size of Astrodev frame sent to radio if successfully sent to radio, negative value if unsuccessful. This return value does not indicate that the packet was sucessfully transmitted over RF; it indicates that the Astrodev frame containing the data and command to the radio to transmit was sucessfully sent.

The header and payload of the packet are merged into one.

The internal transmission Astrodev frame is used to hold the PacketComm packet. This frame's header data is written to with the TRANSMIT command, indicating data to be transmitted by the Astrodev radio's transceiver, and the size of the payload, which is the PacketComm packet. If the packet's size is greater than the MTU, then return an error value.

The PacketComm packet is copied to the Astrodev frame as its payload.

The Astrodev transmission frame, containing the PacketComm packet as its payload, is sent to the radio using the SendAstrodevFrame() function. This commands the radio to transmit the PacketComm packet using its transceiver.

A short delay is given for the radio to execute the transmission.

◆ VerifyConnection()

int32_t Artemis::Devices::Astrodev::VerifyConnection ( )

Verify serial connection to the Astrodev radio.

Returns
int32_t Returns 0 if successful, negative value if unsuccessful.

The Astrodev radio is sent a command to reset. If this command cannot be sent to the radio, the reset command frame is resent four more times after a two-second delay. If the reset command frame still cannot be sent, return with an error code.

The Astrodev radio is sent a no-op command frame. If this frame cannot be sent to the radio, a reset command frame is sent followed by another no-op command frame. If the no-op frame still cannot be sent to the radio, return with an error code.

Member Data Documentation

◆ MTU

constexpr uint8_t Artemis::Devices::Astrodev::MTU = 254
staticconstexpr

The Maximum Transmission Units (MTU).

This defines the largest payload that can be carried by a single Astrodev radio data frame.

◆ PACKETCOMM_DATA_SIZE

constexpr uint16_t Artemis::Devices::Astrodev::PACKETCOMM_DATA_SIZE
staticconstexpr
Initial value:
=
MTU - (COSMOS_SIZEOF(PacketComm::Header) + 2)
static constexpr uint8_t MTU
The Maximum Transmission Units (MTU).
Definition astrodev.h:48

The maximum size of a PacketComm payload.

This calculates the maximum size of a PacketComm payload after taking into account the size of a PacketComm header and the checksum.

Todo:
The checksum from PacketComm or Astrodev? Astrodev payload checksum does not add to MTU length.

◆ RF_BAUD

std::map<uint8_t, uint16_t> Artemis::Devices::Astrodev::RF_BAUD
Initial value:
= {
{0, 1200},
{1, 9600},
{2, 19200},
{3, 38400},
{4, 57600},
{5, 115200}
}

Mapping of integer configuration values to RF baud rate.

This map associates integer values, stored in the tcv_config struct, to baud rates used by the Astrodev radio to transmit to and receive from a ground station.

◆ RF_INDEX

std::map<uint16_t, uint8_t> Artemis::Devices::Astrodev::RF_INDEX
Initial value:
= {
{ 1200, 0},
{ 9600, 1},
{ 19200, 2},
{ 38400, 3},
{ 57600, 4},
{115200, 5}
}

Mapping of RF baud rate to integer configuration values.

This map associates baud rates used by the Astrodev radio to transmit to and receive from a ground station to integer values, stored in the tcv_config struct.

◆ TORADIO

constexpr uint8_t Artemis::Devices::Astrodev::TORADIO = 0x10
staticconstexpr

A command being sent from the Teensy.

This corresponds to the high byte of a command's opcode. This describes a Astrodev radio data frame being delivered from the Teensy to the radio.

◆ TOTEENSY

constexpr uint8_t Artemis::Devices::Astrodev::TOTEENSY = 0x20
staticconstexpr

A response being sent from the radio.

This corresponds to the high byte of a command's opcode. This describes a Astrodev radio data frame being delivered from the radio to the Teensy.

◆ UART_BAUD

std::map<uint8_t, uint16_t> Artemis::Devices::Astrodev::UART_BAUD
Initial value:
= {
{0, 9600},
{1, 19200},
{2, 38400},
{3, 57600},
{4, 115200}
}

Mapping of integer configuration values to serial baud rate.

This map associates integer values, stored in the tcv_config struct, to baud rates used by the serial connectiom between the Teensy and Astrodev radio.

◆ UART_INDEX

std::map<uint16_t, uint8_t> Artemis::Devices::Astrodev::UART_INDEX
Initial value:
= {
{ 9600, 0},
{ 19200, 1},
{ 38400, 2},
{ 57600, 3},
{115200, 4}
}

Mapping of serial baud rate to integer configuration values.

This map associates baud rates used by the serial connectiom between the Teensy and Astrodev radio to integer values, stored in the tcv_config struct.


The documentation for this class was generated from the following files: