DCH Details#
Data Channel Packet Format#
All DCH messages have the same general composition: a header followed by the payload. The payload format depends on the message type. Two versions of the DCH packet format are currently supported: versions 2 and 3. Some kits use version 2 by default, while others use version 3.
Note: The selected version does not persist through reboots. You can change it using the Admin Console.
The difference between the two versions is the header content and the supported message types. A DCH message begins with an opening bracket and ends with a closing bracket. The DCH header includes the opening bracket.


Default DCH Version | Kit Type |
|---|---|
2 |
|
3 |
|
The following applies to both versions of the DCH packet format:
length: The total length of the header and payload elements between the opening and closing brackets.
timestamp: Time when the data was collected. If multiple data elements are sent in a single packet, the timestamp denotes when the first element was collected.
type: Message type, identified by an ID as listed below:
Message Type | ID |
|---|---|
PTI | 0x20 |
AEM | 0x63 |
PC Samples | 0x64 |
Exceptions | 0x65 |
Logic Analyzer | 0x66 |
Version 2#
Header contents for DCH version 2 are as follows:


typedef __packed struct __DCH_DataMessageHeader {
char frame;
uint16_t length;
uint16_t version;
uint8_t timeStamp[6];
uint16_t type;
uint8_t sequenceNumber;
} DCH_DataMessageHeader;The size of the header is 13 bytes plus 1 byte for the opening bracket.
Supported packets:
PTI
Version 3#
Header contents for DCH version 3 are as follows:


typedef __packed struct __DCH_DataMessageHeader_v3 {
char frame;
uint16_t length;
uint16_t version;
int64_t timeStamp;
uint16_t type;
uint32_t flags;
uint16_t sequenceNumber;
} DCH_DataMessageHeader_v3;The size of the header is 20 bytes plus 1 byte for the opening bracket.
Supported packets:
PTI
AEM
PC Samples
Exceptions
Logic Analyzer
PTI Packet#
The payload for the DCH PTI packet is a single PTI packet received from the target. A PTI packet already contains metadata, so no additional header is added.
AEM Packet#
The payload for the AEM packet consists of a header and an array of floats. Each float value is a single current measurement. The header is defined as follows:
typedef __packed struct __DCH_AEMCurrentPacketHeader{
uint16_t version;
/* Configuration info */
uint32_t sampleRate; /* In Hz */
uint16_t sampleBufferSize; /* Samples */
uint16_t sampleBufferSequenceNumber; /* 16 bit packet sequence #*/
uint32_t reservedConfig[2]; /* Reserved */
/* Data packet info */
float voltage; /* VMCU voltage at start of data frame */
uint32_t reservedData[2]; /* Reserved */
uint32_t status;
} DCH_AEMCurrentPacketHeader;PC Sample Packet#
The payload for the PC sample packet consists of a header and an array of DCH PC samples. The PC samples are acquired from the target through SWO. The timestamp offset field in the DCH PC sample describes the offset from the timestamp in the DCH header to the PC sample. The header and the DCH PC sample are defined as follows:
typedef __packed struct __DCH_PCSamplePacketHeader {
uint16_t version;
uint16_t count; /* Item count */
} DCH_PCSamplePacketHeader;
typedef __packed struct __DCH_PCSample {
uint32_t timestampOffset;
uint32_t pcsample;
} DCH_PCSample;Exception Packet#
The payload for the exception packet consists of a header and an array of DCH exceptions. The exceptions are acquired from the target through SWO. The timestamp offset field in the DCH exception describes the offset from the timestamp in the DCH header to the exception. The header and the DCH exception are defined as follows:
typedef __packed struct __DCH_ExceptionPacketHeader {
uint16_t version;
uint16_t count; /* Item count */
} DCH_ExceptionPacketHeader;
typedef __packed struct __DCH_Exception {
uint32_t timestampOffset;
uint16_t exception;
} DCH_Exception;Logic Analyzer Packet#
The adapter will send a logic analyzer packet if at least one of the channels has changed. It also sends a packet every second if there is no change. Therefore, a packet will be sent when a connection to the DCH is established if the last connection occurred more than a second ago.
The payload for the logic analyzer packet consists of a header and an array of bytes. In this byte array, each bit represents one channel of the logic analyzer. Channel zero is represented by the least significant bit, and channel seven by the most significant bit. The header is defined as follows:
typedef __packed struct __DCH_LogicPacketHeader {
uint16_t version; /* Current version is 1 */
uint16_t count; /* Sample count */
uint32_t sampleRate; /* In Hz */
} DCH_LogicPacketHeader;Custom DCH Packets#
The adapter supports sending custom DCH packets. In order to do this, the target must communicate with the host using the SWO pin of the debug interface through the ITM debug peripheral. The SWO data baud rate must be fixed at 875 kHz. The data must then be transmitted using ITM stimulus port 8 and has to be framed in a specific way:
typedef __packed struct __DCH_CustomPacket {
char startFrame;
uint8_t length;
uint8_t version;
uint16_t type;
uint8_t sequenceNumber;
uint8_t *data;
uint16_t crc;
char endFrame;
} DCH_CustomPacket;Field | Length | Purpose |
|---|---|---|
Start frame | 1 | Open bracket |
Length | 1 | The length from version to end of data. |
Version | 1 | Always |
Type | 2 | Message type. Little-endian. |
Sequence number | 1 | Sequence number. |
Data | 1 - 255 | Data. |
CRC | 2 | CRC CCITT-16 from version to end of data. |
End frame | 1 | Close bracket |
If both of the CRC bytes are set to 0x5A the CRC check will be skipped. For a list of currently used type codes see DCH message type list. This custom packet will be unwrapped by the adapter and then wrapped in the DCH header of the currently selected DCH version. The type field of the DCH header will then be populated with the type field that the packet was wrapped in.
Configuration over SWO packet format#
The configuration over SWO (CoS) packet is an example of a custom DCH packet. The CoS packet is created by the target and follows the specification listed below.
typedef __packed struct __COS_ConfigOption {
uint8_t optionType; /* Can be UART (1) or PTI (2) */
uint8_t reserved1;
uint16_t reserved2;
uint32_t optionValue;
} COS_ConfigOption_t;Option type | Option value bit field | Purpose | Comment |
|---|---|---|---|
UART | 0:23 | Baudrate | Baudrate |
24:27 | Reserved | Reserved | |
28:31 | Mode | Can be aux (3), cts (4) or rts (8). | |
PTI | 0:23 | Baudrate | Reserved |
24:26 | Reserved | Reserved | |
27:29 | Mode | Can be onewire (0), twowire (1) or efruart (2). | |
30:31 | Interface | Can be 0 or 1. |
The following example code shows how the CoS packet can be packaged to be sent as a custom DCH packet.
COS_ConfigOption_t config;
uint16_t packetLength;
uint16_t type;
uint8_t bufferLength;
uint8_t *buffer;
uint8_t outputByte;
config.optionType = COS_CONFIG_OPTION_TYPE_UART;
config.optionValue = baudrate;
config.optionValue |= mode << COS_CONFIG_UART_MODE_POS;
type = 0x80;
buffer = (uint8_t *)&config;
bufferLength = sizeof(config);
/* Full length is data + frame (2), length (1), version (1), type (2), sequence (1) and crc (2) */
packetLength = ( (uint16_t)bufferLength ) + 9;
for ( i = 0; i < packetLength; ++i ) {
if ( i == 0 ) {
/* Frame start */
outputByte = '[';
}
else if ( i == 1 ) {
/* Packet length */
/* Including version byte, type and sequence number */
outputByte = bufferLength + 4;
}
else if ( i == 2 ) {
/* Version byte */
outputByte = 0xD1;
}
else if ( i == 3 ) {
/* First 8 bits of message type */
outputByte = type & 0xFF;
}
else if ( i == 4 ) {
/* Last 8 bits of message type */
outputByte = (type >> 8) & 0xFF;
}
else if ( i == 5 ) {
/* Sequence number */
outputByte = sequenceNumber++;
}
else if ( i == packetLength - 3 ) {
/* CRC first byte */
outputByte = 0x5A;
}
else if ( i == packetLength - 2 ) {
/* CRC second byte */
outputByte = 0x5A;
}
else if ( i == packetLength - 1 ) {
/* Frame end */
outputByte = ']';
}
else {
/* Data */
outputByte = buffer[i - 6];
}
SWOITMSendByte( ITM_CHANNEL_8, outputByte );
}


