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.

DCH-packet-formatDCH-packet-format

Default DCH Version

Kit Type

2

wstk-tablewstk-tableek-dk-tableek-dk-table

3

wpk-tablewpk-table pk-tablepk-table

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:

DCH-packet-formatDCH-packet-format

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:

DCH-packet-formatDCH-packet-format

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 [ to delimit the message.

Length

1

The length from version to end of data.

Version

1

Always 0xD1

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 ] to delimit the message.

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 );
}