= Digital Voice Modem

== Technical Note
=== Modem Protocol

Document Identifier: TN.1001

Author: Bryan Biedenkapp, N2PLL

Editors: Bryan Biedenkapp, N2PLL

Contributors: N/A

Abstract: Describes high-level concepts and procedures for the Modem Protocol.

Status: Draft

== 1. Introduction
This document describes, in high-level, the general concepts and procedures for the Modem Protocol used by DVM projects.

== 2. Technical Note

=== 2.1 Definitions
* DVM: Digital Voice Modem

=== 2.2 General Concept
The DVM Modem Protocol defines a common and standard communications protocol between a host application and a dedicated modem hardware device (usually based around a STM32F446 or similar).

The core purpose of the protocol is to provide a common serial communications between the host application and the dedicated modem hardware.

=== 2.3 Modem Packet Framing
The modem protocol implements a very simplistic framing mechanism for transmitting data between the host and modem (and vice versa).

[cols="2,1,3"]
|===
|Frame Type |Opcode |Description

|Short
|$FE
|This frame type is used for transporting packets of 254 bytes or less in length.

|Long
|$FD
|This frame type is used for transporting packets greater than 254 bytes in length.
|=== 

[discrete]
==== Modem Packet - Short Frame
[listing]
    Byte 0               1               2               3
    Bit  7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        | Frame Type  | Length          | Opcode        | ...           |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        | <Variable Length Data>                                        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    2 bytes (not including data length)

[discrete]
==== Modem Packet - Long Frame
[listing]
    Byte 0               1               2               3
    Bit  7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        | Frame Type  | Length                          | Opcode        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        | <Variable Length Data>                                        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    3 bytes (not including data length)

It is important to note the Length parameter of the packet buffer should be the length of the *entire* packet not just the payload.

==== 2.3.1 Modem Opcodes
The opcode defines which operation/command being transmitted.

[cols="2,1,3"]
|===
|Function Name |Opcode |Description

|Get Version
|$00
|This function is used for retrieving the firmware version from the modem.

|Get Status
|$01
|This function is used for retrieving the current status from the modem.

|Set Configuration
|$02
|This function is used for setting configuration parameters to the modem.

|Set Mode
|$03
|This function is used for setting the operational mode parameter to the modem.

|Set Symbol Level Adjustment
|$04
|This function is used for setting the symbol level adjustment parameters to the modem.

|Set Rx Level Adjustment
|$05
|This function is used for setting the receive level adjustment parameter to the modem.

|Set RF Parameters
|$06
|This function is used for setting the RF parameters to the modem. (Hotspot Only)

|Calibration Data
|$08
|This function is used for setting calibration data to the modem when operating in a calibration mode.

|RSSI Data
|$08
|This function is used for receiving RSSI data from the modem.

|Send CW ID
|$0A
|This function is used to cause the modem to emit a CWID burst of morse code.

|Set FIFO Buffers
|$0F
|This function is used for setting the internal FIFO ringbuffer sizes on the modem.

|DMR Slot 1 Data
|$18
|This function is used for sending/receiving DMR Slot 1 protocol data to/from the modem.

|DMR Slot 1 Lost
|$19
|This function is used for signalling loss of synchronization for DMR Slot 1 protocol data.

|DMR Slot 2 Data
|$1A
|This function is used for sending/receiving DMR Slot 2 protocol data to/from the modem.

|DMR Slot 2 Lost
|$1B
|This function is used for signalling loss of synchronization for DMR Slot 2 protocol data.

|DMR Short LC
|$1C
|This function is used for sending/receiving DMR Short LC protocol data to/from the modem.

|DMR Start
|$1D
|This function is used for providing transmitter control and starting the DMR data stream.

|DMR Abort
|$1E
|

|DMR CACH AT Control
|$1F
|This function is used for setting the DMR CACH AT bit on or off.

|DMR Slot 1 Clear
|$20
|This function is used for commanding the modem to clear the DMR Slot 1 FIFO buffers.

|DMR Slot 2 Clear
|$21
|This function is used for commanding the modem to clear the DMR Slot 2 FIFO buffers.

|Project 25 Data
|$31
|This function is used for sending/receiving Project 25 protocol data to/from the modem.

|Project 25 Lost
|$32
|This function is used for signalling loss of synchronization for Project 25 protocol data.

|Project 25 Clear
|$33
|This function is used for commanding the modem to clear the Project 25 FIFO buffers.

|NXDN Data
|$41
|This function is used for sending/receiving NXDN protocol data to/from the modem.

|NXDN Lost
|$42
|This function is used for signalling loss of synchronization for NXDN protocol data.

|NXDN Clear
|$43
|This function is used for commanding the modem to clear the NXDN FIFO buffers.

|Ack
|$70
|This function is used for acknowledging a command.

|Nack
|$7F
|This function is used for negative acknowledgment of a command.

|Flash Read
|$E0
|This function is used for reading 256 bytes of data from the flash storage partition of the modem. (Only on supported hardware.)

|Flash Write
|$E1
|This function is used for writing 256 bytes of data to the flash storage partition of the modem. (Only on supported hardware.)

|Reboot MCU
|$EA
|This function is used for triggering a reboot of the modem MCU.

|Debug 1
|$F1
|This function is used for receiving debug data from the modem. (1 byte)

|Debug 2
|$F2
|This function is used for receiving debug data from the modem. (2 byte)

|Debug 3
|$F3
|This function is used for receiving debug data from the modem. (3 byte)

|Debug 4
|$F4
|This function is used for receiving debug data from the modem. (4 byte)

|Debug 5
|$F5
|This function is used for receiving debug data from the modem. (5 byte)

|=== 

==== 2.3.2 Modem Operational States
The operational state defines which mode/state the modem is currently in.

[cols="2,1,3"]
|===
|State Name |State |Description

|IDLE
|0
|This is the default state for a modem, the modem is not in any active mode in this state.

|DMR
|1
|When in this mode the modem is actively Rx/Tx DMR protocol data.

|Project 25
|2
|When in this mode the modem is actively Rx/Tx Project 25 protocol data.

|NXDN
|3
|When in this mode the modem is actively Rx/Tx NXDN protocol data.

|CW
|10
|When in this mode the modem is actively Tx CWID morse data.

|Project 25 Calibration 1K
|92
|

|DMR DMO Calibration 1K
|93
|

|DMR Calibration 1K
|94
|

|DMR Low Frequency Calibration
|95
|

|RSSI Calibration
|96
|

|Project 25 Calibration
|97
|

|DMR Calibration
|98
|

|NXDN Calibration
|99
|
|=== 

==== 2.3.3 Negative Acknowledgement Reasons
This table defines the reasons a negative acknowledgement may be sent.

[cols="2,1,3"]
|===
|Reason Name |Reason Code |Description

|OK
|0
|

|NAK
|1
|General Failure.

|Illegal Length
|2
|Packet received was of an illegal length, and was discarded by the modem.

|Invalid Request
|4
|Packet received was an invalid request, and was discarded by the modem.

|Ringbuffer Full
|8
|Sent when a command attempts to write to a FIFO buffer that is full.

|Invalid FDMA Preamble
|10
|Sent by the Set Configuration command typically, to indicate the FDMA preamble value was out of range.

|Invalid Mode
|11
|Sent by either Set Configuration or Set Mode command to indicate a mode was specified that is invalid.

|Invalid DMR Color Code
|12
|Sent by the Set Configuration command typically, if the DMR color code is out of range.

|Invalid DMR Slot
|13
|Sent by the modem to indicate the DMR slot value was out of range.

|Invalid DMR Start
|14
|

|Invalid DMR Rx Delay
|15
|Sent by the modem to indicate the DMR Rx Delay value was out of range.

|Invalid P25 Correlation Count
|16
|Sent by the modem to indicate the P25 Correlation Count value was out of range.

|No Internal Flash
|20
|Sent by the modem when the hardware does not support the Flash Read or Flash Write operations.

|Flash Erase Failed
|21
|Sent by the modem when the configuration partition of the flash was unable to be erased.

|Flash Write Failed
|22
|Sent by the modem when the configuration partition of the flash was unable to be written.

|Flash Write Too Big
|23
|Sent by the modem when the data sent to be written to the configuration partition of the flash was too large to be written.

|DMR Disabled
|63
|Sent by the modem to indicate DMR operations are disabled.

|P25 Disabled
|64
|Sent by the modem to indicate P25 operations are disabled.

|NXDN Disabled
|65
|Sent by the modem to indicate NXDN operations are disabled.

|=== 

=== 2.4 General Opcode Specifications

==== 2.4.1 Get Version
This opcode is utilized to retreive the hardcoded (at compile time) version string from the firmware.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|Get Version Opcode
|1
|
|=== 

Upon reception, the modem shall transmit in response:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|Get Version Opcode
|1
|$00

|Protocol Version
|1
|

|CPU Type
|1
|

|CPU UDID
|16
|Universal Device Identifier

|Baked Firmware Version String
|83
|
|=== 

==== 2.4.2 Get Status
This opcode is utilized to retreive the various interesting operational runtime values from the modem.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|Get Status Opcode
|1
|$01
|=== 

Upon reception, the modem shall transmit in response:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|Get Status Opcode
|1
|$01

|Protocol Enablement Flags
|1
|This byte contains flags that indicate which digital protocol is enabled on the modem.

|Modem State
|1
|Current operational state.

|Operation Flags
|1
|This byte contains various operation flags.

|Reserved
|1
|

|DMR Slot 1 FIFO Space
|1
|This byte contains the FIFO space available in DMR frames.

|DMR Slot 2 FIFO Space
|1
|This byte contains the FIFO space available in DMR frames.

|Reserved
|1
|

|Project 25 FIFO Space
|1
|This byte contains the FIFO space available in P25 LDU frames.

|NXDN FIFO Space
|1
|This byte contains the FIFO space available in NXDN frames.

|=== 

==== 2.4.3 Set Configuration
This opcode is utilized to set the general configuration of the modem.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|24
|Length

|Set Configuration Opcode
|1
|$02

|Flags 1 Byte
|1
|This flags byte represents various states (see below).

|Flags 2 Byte
|1
|This flags byte represents various states (see below).

|FDMA Preamble Length
|1
|

|Initial Mode
|1
|This sets the initial mode of the modem, the mode can be changed with Set Mode at any time.

|Rx Level
|1
|

|CW ID Tx Level
|1
|

|DMR Color Code
|1
|

|DMR Rx Delay
|1
|

|P25 NAC
|2
|

|DMR Tx Level
|1
|

|P25 Correlation Count
|1
|

|P25 Tx Level
|1
|

|Tx DC Offset
|1
|

|Rx DC Offset
|1
|

|NXDN Tx Level
|1
|

|Rx Coarse Softpot Setting
|1
|This currently only applies to DVMV1 modems.

|Rx Fine Softpot Setting
|1
|This currently only applies to DVMV1 modems.

|Tx Coarse Softpot Setting
|1
|This currently only applies to DVMV1 modems.

|Tx Fine Softpot Setting
|1
|This currently only applies to DVMV1 modems.

|RSSI Coarse Softpot Setting
|1
|This currently only applies to DVMV1 modems.

|RSSI Fine Softpot Setting
|1
|This currently only applies to DVMV1 modems.
|=== 

[discrete]
==== Flags 1 Byte
[cols="2,1,2"]
|===
|Name |Flag Bit |Description

|Rx Invert
|$01
|

|Tx Invert
|$02
|

|PTT Invert
|$04
|

|Modem Debug
|$10
|

|Simplex Operation
|$80
|
|=== 

[discrete]
==== Flags 2 Byte
[cols="2,1,2"]
|===
|Name |Flag Bit |Description

|DC Blocker
|$01
|

|COS Lockout
|$04
|

|DMR Enabled
|$02
|

|P25 Enabled
|$08
|

|NXDN Enabled
|$10
|
|=== 

Upon reception, the modem shall perform whatever operations necessary to transition to the requested mode and transmit a ACK or NACK in response.

If the operation fails the modem shall:

* Respond with a NACK and the "Illegal Length" if packet from the host is improperly sized.
* Respond with a NACK and the "Invalid FDMA Preamble" if the FDMA preamble parameter is out of range.
* Respond with a NACK and the "Invalid DMR Color Code" if the DMR color code is out of range.
* Respond with a NACK and the "Invalid DMR Rx Delay" if the DMR receive delay is out of range.
* Respond with a NACK and the "Invalid P25 Correlation Count" if the P25 correlation count is out of range.

==== 2.4.4 Set Mode
This opcode is utilized to set the operational mode of the modem.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|4
|Length

|Set Mode Opcode
|1
|$03

|Operational Mode
|1
|$00
|=== 

Upon reception, the modem shall perform whatever operations necessary to transition to the requested mode and transmit a ACK or NACK in response.

==== 2.4.5 Set Symbol Level Adjustment
This opcode is utilized to set the symbol level adjustments on the modem.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|9
|Length

|Set Symbol Level Adjustment Opcode
|1
|$04

|DMR +3/-3 Symbol Level Adjustment
|1
|This is a unsigned value of 0 to 255 representing an adjustment of -128 to 128.

|DMR +1/-1 Symbol Level Adjustment
|1
|This is a unsigned value of 0 to 255 representing an adjustment of -128 to 128.

|P25 +3/-3 Symbol Level Adjustment
|1
|This is a unsigned value of 0 to 255 representing an adjustment of -128 to 128.

|P25 +1/-1 Symbol Level Adjustment
|1
|This is a unsigned value of 0 to 255 representing an adjustment of -128 to 128.

|NXDN +3/-3 Symbol Level Adjustment
|1
|This is a unsigned value of 0 to 255 representing an adjustment of -128 to 128.

|NXDN +1/-1 Symbol Level Adjustment
|1
|This is a unsigned value of 0 to 255 representing an adjustment of -128 to 128.
|=== 

Upon reception, the modem shall perform whatever operations necessary to set the Rx level and transmit a ACK or NACK in response.

If the operation fails the modem shall:

* Respond with a NACK and the "Illegal Length" if packet from the host is improperly sized.
* Respond with a NACK and the "Invalid Request" if parameters are out of range.

==== 2.4.6 Set Rx Level Adjustment
This opcode is utilized to set the Rx level on the modem.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|4
|Length

|Set Rx Level Opcode
|1
|$05

|Rx Level
|1
|
|=== 

Upon reception, the modem shall perform whatever operations necessary to set the Rx level and transmit a ACK or NACK in response.

If the operation fails the modem shall:

* Respond with a NACK and the "Illegal Length" if packet from the host is improperly sized.

==== 2.4.7 Set RF Parameters (Hotspot Only)
This opcode is utilized to set the RF parameters for a hotspot modem.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|18 or 22
|Length of 18 does not set AFC parameters, length of 22 sets AFC parameters.

|Set RF Parameters Opcode
|1
|$06

|Rx Frequency (in Hz)
|4
|

|Tx Frequency (in Hz)
|4
|

|Tx Power (value from 0 to 255)
|1
|

|DMR Discriminator Bandwidth Adjustment
|1
|This is a unsigned value of 0 to 255 representing an adjustment of -128 to 128.

|P25 Discriminator Bandwidth Adjustment
|1
|This is a unsigned value of 0 to 255 representing an adjustment of -128 to 128.

|DMR Post Demodulation Bandwidth Adjustment
|1
|This is a unsigned value of 0 to 255 representing an adjustment of -128 to 128.

|P25 Post Demodulation Bandwidth Adjustment
|1
|This is a unsigned value of 0 to 255 representing an adjustment of -128 to 128.

|AFC Gain Mode
|1
|This represents the AFC gain mode: 0 = Auto, 1 = Auto (Linear), 2 = Low, 3 = High.

|NXDN Discriminator Bandwidth Adjustment
|1
|This is a unsigned value of 0 to 255 representing an adjustment of -128 to 128.

|NXDN Post Demodulation Bandwidth Adjustment
|1
|This is a unsigned value of 0 to 255 representing an adjustment of -128 to 128.

|AFC Enable, KI and KP
|1
|This value represents whether or not AFC is enabled ($80 bit), the AFC KI (lower 4 bits), the AFC KP (upper 4 bits).

|AFC Range
|1
|

|=== 

Upon reception, the modem shall perform whatever operations necessary to set the RF parameters and transmit a ACK or NACK in response.

If the operation fails the modem shall:

* Respond with a NACK and the "Illegal Length" if packet from the host is improperly sized.
* Respond with a NACK and the "Invalid Request" if parameters are out of range.

==== 2.4.8 Calibration Data
*TODO TODO TODO*

==== 2.4.9 RSSI Data
*TODO TODO TODO*

==== 2.4.10 Send CWID
This opcode is utilized to transmit a CW ID morse message from the modem.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|4 or More
|Length, the length is typically 3 + the length of the CWID to send.

|Send CWID Opcode
|1
|$0A

|...
|...
|...

|CWID Letters
|1
|

|...
|...
|...
|=== 

Upon reception, the modem shall perform whatever operations necessary to transmit a CWID with the given letters and transmit a ACK or NACK in response.

If the operation fails the modem shall:

* Respond with a NACK and the "Illegal Length" if packet from the host is improperly sized.

==== 2.4.11 Set FIFO Buffers
This opcode is utilized to set the size of the FIFO buffers on the modem.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|6
|Length

|Set FIFO Buffers Opcode
|1
|$0F

|DMR Buffer Size
|2
|This is a unsigned 16-bit value representing the FIFO buffer size.

|P25 Buffer Size
|2
|This is a unsigned 16-bit value representing the FIFO buffer size.

|NXDN Buffer Size
|2
|This is a unsigned 16-bit value representing the FIFO buffer size.
|=== 

Upon reception, the modem shall perform whatever operations necessary to resize the FIFO buffers and transmit a ACK or NACK in response.

If the operation fails the modem shall:

* Respond with a NACK and the "Illegal Length" if packet from the host is improperly sized.
* Respond with a NACK and the "Invalid Mode" if buffers are attempted to be resized while not in an IDLE state.

==== 2.4.12 Acknowledgement
This opcode is utilized by the modem to notify the host of a positive acknowledgement of a command.

The modem shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|4
|Length

|Ack Opcode
|1
|$70

|Opcode Being Acknowledged
|1
|$00
|=== 

==== 2.4.13 Negative Acknowledgement
This opcode is utilized by the modem to notify the host of a negative acknowledgement of a command.

The modem shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|5
|Length

|Nack Opcode
|1
|$7F

|Opcode Being Acknowledged
|1
|$00

|NACK Reason Code
|1
|$00
|=== 

==== 2.4.14 Flash Read
This opcode is utilized to read data from the modem's configuration partition on the flash.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|Flash Read Opcode
|1
|$E0
|=== 

The modem shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|249
|Length

|Flash Read Opcode
|1
|$E0

|Variable Length Data
|249
|...
|=== 

==== 2.4.15 Flash Write
This opcode is utilized to write data from the modem's configuration partition on the flash.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|254
|Length

|Flash Write Opcode
|1
|$E1

|Flash Data
|<Variable>
|...
|=== 

Upon reception, the modem shall perform whatever operations necessary to write data to the flash and transmit a ACK or NACK in response.

If the flash operation fails the modem shall:

* Respond with a NACK and the "Flash Write Too Big" if more then 254 bytes are attempted to be written.
* Respond with a NACK and the "Flash Write Failed" if a write error occurs.

==== 2.4.16 Reset MCU
This opcode is utilized to reboot the MCU of the modem.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|Reset MCU Opcode
|1
|$EA
|=== 

Upon reception of this opcode the modem should immediately issue a MCU restart. No response back from the modem shall be expected.

=== 2.5 DMR Opcode Specifications

==== 2.5.1 Slot 1 Data
This opcode is utilized by both the host and modem to transmit DMR Slot 1 frame data.

The host or modem shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|36
|Length

|DMR Slot 1 Data Opcode
|1
|$18

|...
|...
|...

|Frame Data
|<Variable>
|

|...
|...
|...
|=== 

Upon reception, the host or modem shall perform whatever operations necessary to handle frame data.

If data is being transmitted to the modem, upon reception, the modem shall perform whatever operations necessary to handle the frame data for transmission and transmit a ACK or NACK in response.

If the write data operation fails the modem shall:

* Respond with a NACK and the "Illegal Length" if the frame data is not the standard DMR frame length 33 bytes.
* Respond with a NACK and the "Ringbuffer Full" if the DMR FIFO buffer is full.

==== 2.5.2 Slot 1 Lost
This opcode is utilized to notify the host the current transmission synchronization was lost.

The modem shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|DMR Sot 1 Lost Opcode
|1
|$19
|=== 

Upon reception, the host shall perform whatever operations necessary to handle a transmission loss event.

==== 2.5.3 Slot 2 Data
This opcode is utilized by both the host and modem to transmit DMR Slot 2 or DMR DMO frame data.

The host or modem shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|36
|Length

|DMR Slot 2 Data Opcode
|1
|$1A

|...
|...
|...

|Frame Data
|<Variable>
|

|...
|...
|...
|=== 

Upon reception, the host or modem shall perform whatever operations necessary to handle frame data.

If data is being transmitted to the modem, upon reception, the modem shall perform whatever operations necessary to handle the frame data for transmission and transmit a ACK or NACK in response.

If the write data operation fails the modem shall:

* Respond with a NACK and the "Illegal Length" if the frame data is not the standard DMR frame length 33 bytes.
* Respond with a NACK and the "Ringbuffer Full" if the DMR FIFO buffer is full.

==== 2.5.4 Slot 2 Lost
This opcode is utilized to notify the host the current transmission synchronization was lost.

The modem shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|DMR Sot 1 Lost Opcode
|1
|$1B
|=== 

Upon reception, the host shall perform whatever operations necessary to handle a transmission loss event.

==== 2.5.5 Short LC
*TODO TODO TODO*

==== 2.5.6 Start
*TODO TODO TODO*

==== 2.5.7 Abort
*TODO TODO TODO*

==== 2.5.8 CACH AT Control
This opcode is utilized to set the CACH AT bit for the specified slot.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|4
|Length

|DMR CACH AT Control Opcode
|1
|$1F

|DMR Slot
|1
|DMR Slot to set the CACH AT bit for.
|=== 

Upon reception, the modem shall perform whatever operations necessary to set the CACH AT bit for the specified slot.

==== 2.5.9 Slot 1 Clear
This opcode is utilized to clear the FIFO buffer for DMR Slot 1.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|DMR Slot 2 Clear Opcode
|1
|$20
|=== 

Upon reception, the modem shall perform whatever operations necessary to clear the FIFO buffers.

==== 2.5.10 Slot 2 Clear
This opcode is utilized to clear the FIFO buffer for DMR Slot 2.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|DMR Slot 2 Clear Opcode
|1
|$21
|=== 

Upon reception, the modem shall perform whatever operations necessary to clear the FIFO buffers.

=== 2.6 P25 Opcode Specifications

==== 2.6.1 Data
This opcode is utilized by both the host and modem to transmit P25 frame data.

The host or modem shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|21 or greater
|Length, P25 data frames are variable length, the minimum data frame is a TDU data frame which has a modem packet length of 21 bytes.

|P25 Data Opcode
|1
|$31

|...
|...
|...

|Frame Data
|<Variable>
|

|...
|...
|...
|=== 

Upon reception, the host or modem shall perform whatever operations necessary to handle frame data.

If data is being transmitted to the modem, upon reception, the modem shall perform whatever operations necessary to handle the frame data for transmission and transmit a ACK or NACK in response.

If the write data operation fails the modem shall:

* Respond with a NACK and the "Illegal Length" if the frame data is less then a standard P25 TDU frame length 18 bytes.
* Respond with a NACK and the "Ringbuffer Full" if the P25 FIFO buffer is full.

==== 2.6.2 Lost
This opcode is utilized to notify the host the current transmission synchronization was lost.

The modem shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|P25 Lost Opcode
|1
|$32
|=== 

Upon reception, the host shall perform whatever operations necessary to handle a transmission loss event.

==== 2.6.3 Clear
This opcode is utilized to clear the FIFO buffer for P25.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|P25 Clear Opcode
|1
|$33
|=== 

Upon reception, the modem shall perform whatever operations necessary to clear the FIFO buffers.

=== 2.7 NXDN Opcode Specifications

==== 2.7.1 Data
This opcode is utilized by both the host and modem to transmit NXDN frame data.

The host or modem shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|51
|Length

|NXDN Data Opcode
|1
|$41

|...
|...
|...

|Frame Data
|<Variable>
|

|...
|...
|...
|=== 

Upon reception, the host or modem shall perform whatever operations necessary to handle frame data.

If data is being transmitted to the modem, upon reception, the modem shall perform whatever operations necessary to handle the frame data for transmission and transmit a ACK or NACK in response.

If the write data operation fails the modem shall:

* Respond with a NACK and the "Illegal Length" if the frame data is not the standard NXDN frame length 48 bytes.
* Respond with a NACK and the "Ringbuffer Full" if the NXDN FIFO buffer is full.

==== 2.7.2 Lost
This opcode is utilized to notify the host the current transmission synchronization was lost.

The modem shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|NXDN Lost Opcode
|1
|$42
|=== 

Upon reception, the host shall perform whatever operations necessary to handle a transmission loss event.

==== 2.7.3 Clear
This opcode is utilized to clear the FIFO buffer for NXDN.

The host shall transmit:
[cols="2,1,2"]
|===
|Name |Length (bytes) |Description

|Short Frame Start
|1
|Short Frame Start

|Length
|3
|Length

|NXDN Clear Opcode
|1
|$43
|=== 

Upon reception, the modem shall perform whatever operations necessary to clear the FIFO buffers.
