libdrmconf 0.12.1
A library to program DMR radios.
Loading...
Searching...
No Matches
OpenGD77Interface Class Reference

Implements the interfact to a radio running the Open GD77 firmware. More...

#include <opengd77_interface.hh>

Inheritance diagram for OpenGD77Interface:
Collaboration diagram for OpenGD77Interface:

Classes

struct  CommandRequest
 Represents a command message. More...
 
struct  FirmwareInfo
 Radio inforation struct. More...
 
struct  ReadRequest
 Represents a read message. More...
 
struct  ReadResponse
 Represents a read response message. More...
 
struct  WriteRequest
 Represents a write message. More...
 
struct  WriteResponse
 Represents a write-response message. More...
 

Public Types

enum class  Variant { GD77 , UV380 }
 

Public Member Functions

 OpenGD77Interface (const USBDeviceDescriptor &descr, const ErrorStack &err=ErrorStack(), QObject *parent=nullptr)
 Constructs a new interface to a specific OpenGD77 device.
 
virtual ~OpenGD77Interface ()
 Destructor.
 
void close ()
 Closes the interface to the device.
 
RadioInfo identifier (const ErrorStack &err=ErrorStack())
 Returns an identifier of the radio.
 
bool read_start (uint32_t bank, uint32_t addr, const ErrorStack &err=ErrorStack())
 Starts the read process from the specified bank and at the given address.
 
bool read (uint32_t bank, uint32_t addr, uint8_t *data, int nbytes, const ErrorStack &err=ErrorStack())
 Reads a chunk of data from the block-address bno (block number).
 
bool read_finish (const ErrorStack &err=ErrorStack())
 This function ends a series of read operations.
 
bool write_start (uint32_t bank, uint32_t addr, const ErrorStack &err=ErrorStack())
 Starts the write process into the specified bank and at the given address.
 
bool write (uint32_t bank, uint32_t addr, uint8_t *data, int nbytes, const ErrorStack &err=ErrorStack())
 Writes a chunk of data at the address addr.
 
bool write_finish (const ErrorStack &err=ErrorStack())
 This function ends a series of write operations.
 
bool reboot (const ErrorStack &err=ErrorStack())
 Some radios need to be rebooted after being read or programmed.
 
- Public Member Functions inherited from USBSerial
virtual ~USBSerial ()
 Destructor.
 
bool isOpen () const
 If true, the device has been found and is open.
 
void close ()
 Closes the interface to the device.
 
- Public Member Functions inherited from RadioInterface
virtual ~RadioInterface ()
 Destructor.
 

Static Public Member Functions

static USBDeviceInfo interfaceInfo ()
 Returns some information about this interface.
 
static QList< USBDeviceDescriptordetect (bool saveOnly=true)
 Tries to find all interfaces connected AnyTone radios.
 
- Static Public Member Functions inherited from USBSerial
static QList< USBDeviceDescriptordetect (uint16_t vid, uint16_t pid, bool isSave=true)
 Searches for all USB serial ports with the specified VID/PID.
 
static QList< USBDeviceDescriptordetect ()
 Searches for all USB serial ports.
 

Static Public Attributes

static const uint32_t EEPROM = 0
 The EEPROM memory bank.
 
static const uint32_t FLASH = 1
 The Flash memory bank.
 

Protected Member Functions

bool readEEPROM (uint32_t addr, uint8_t *data, uint16_t len, const ErrorStack &err=ErrorStack())
 Read some data from EEPROM at the given address.
 
bool writeEEPROM (uint32_t addr, const uint8_t *data, uint16_t len, const ErrorStack &err=ErrorStack())
 Write some data to EEPROM at the given address.
 
bool readFlash (uint32_t addr, uint8_t *data, uint16_t len, const ErrorStack &err=ErrorStack())
 Read some data from Flash at the given address.
 
bool setFlashSector (uint32_t addr, const ErrorStack &err=ErrorStack())
 Select the correct Flash sector for the given address.
 
bool writeFlash (uint32_t addr, const uint8_t *data, uint16_t len, const ErrorStack &err=ErrorStack())
 Write some data to the given Flash memory.
 
bool finishWriteFlash (const ErrorStack &err=ErrorStack())
 Finalize writing to the Flash memory.
 
bool readFirmwareInfo (FirmwareInfo &radioInfo, const ErrorStack &err=ErrorStack())
 Read radio info struct.
 
bool sendShowCPSScreen (const ErrorStack &err=ErrorStack())
 Send a "show CPS screen" message.
 
bool sendClearScreen (const ErrorStack &err=ErrorStack())
 Send a "clear screen" message.
 
bool sendDisplay (uint8_t 1, uint8_t y, const char *message, uint8_t iSize, uint8_t alignment, uint8_t inverted, const ErrorStack &err=ErrorStack())
 Send a "display some text" message.
 
bool sendRenderCPS (const ErrorStack &err=ErrorStack())
 Send a "render CPS screen" message.
 
bool sendCloseScreen (const ErrorStack &err=ErrorStack())
 Send a "close screen" message.
 
bool sendCommand (CommandRequest::Option option, const ErrorStack &err=ErrorStack())
 Sends some command message with the given options.
 
- Protected Member Functions inherited from USBSerial
 USBSerial (const USBDeviceDescriptor &descriptor, QSerialPort::BaudRate rate=QSerialPort::Baud115200, const ErrorStack &err=ErrorStack(), QObject *parent=nullptr)
 Constructs an opens new serial interface to the devices identified by the given vendor and product IDs.
 
QString formatPinoutSignals ()
 Serializes the pinout singals.
 
- Protected Member Functions inherited from RadioInterface
 RadioInterface ()
 Hidden constructor.
 

Protected Attributes

Variant _protocolVariant
 The protocol variant determined by the device type obtained by the firmware info.
 
int32_t _sector
 The current Flash sector, set to -1 if none is currently selected.
 

Additional Inherited Members

- Protected Slots inherited from USBSerial
void onError (QSerialPort::SerialPortError error_t)
 Callback for serial interface errors.
 
void onClose ()
 Callback when closing interface.
 
void signalingChanged ()
 Signaling callback.
 

Detailed Description

Implements the interfact to a radio running the Open GD77 firmware.

This interface uses a USB serial-port to communicate with the device. To find the corresponding port, the device-specific VID 0x1fc9 and PID 0x0094 are used. Hence no udev rules are needed to access these devices. The user, however, should be a member of the dialout group to get access to the serial interfaces.

Command requests

The overall command requets structure is

     7   6   5   4   3   2   1   0   7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+...+---+
00 | Fixed prefix 'C' (43h)        | Command flag                  | Payload   |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+...+---+

where the optional and variable length payload field is determined by the command flag. The request starts with the command prefix 'C' (43h) followed by the command flag. Following command flags are known.

FlagCommand
00h Show CPS screen.
01h Clear screen.
02h Display text.
03h Render screen.
05h Close CPS screen.
06h Control radio.
07h Start GPS logging.
feh Ping request.

Show CPS Screen (00h)

Reserves the screen for the CPS. The content is not cleared.

The command is quiet simple

     7   6   5   4   3   2   1   0   7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
00 | Fixed prefix 'C' (43h)        | 00h                           |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

as is the response

     7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+
00 | '-' (2dh)                     |
   +---+---+---+---+---+---+---+---+

Clear Screen (01h)

Once the screen has been reserved, this command clears it.

Also this command is quiet simple

     7   6   5   4   3   2   1   0   7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
00 | Fixed prefix 'C' (43h)        | 01h                           |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

as is the response

     7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+
00 | '-' (2dh)                     |
   +---+---+---+---+---+---+---+---+

Set text (02h)

This command has a variable payload size.

     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
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
00 | Fixed prefix 'C' (43h)        | 03h                           | Column address (usually 0)    | Row address (00h, 10h, ..)    |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
04 | Size (bug? always 3)          | Alignment                     | Inverted                      | Payload max. 16x ASCII     ...
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
    ...                                                                                                                            |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
FieldMeaning
Column Address Specifies the column index.
Row Address Specifies the row index as multiple of 10h.
Size Text size (?). Actually, always observed 3.
Alignment Specifies text alignment on row. 0=left, 1=center, 2=right(?)
Inverted Inverts text, 0=off, 1=inverted (?).
Payload Variable size, up to 16bytes ASCII text.

If there are no errors, the radio responds with

     7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+
00 | '-' (2dh)                     |
   +---+---+---+---+---+---+---+---+

Render Screen (03h)

Randers the transmitted screen. This command is quiet simple again, with no payload.

     7   6   5   4   3   2   1   0   7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
00 | Fixed prefix 'C' (43h)        | 03h                           |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

as is the response:

     7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+
00 | '-' (2dh)                     |
   +---+---+---+---+---+---+---+---+

Control Radio (06h)

This command request is used to control the radio. The specific action is transmitted as a single payload byte.

     7   6   5   4   3   2   1   0   7   6   5   4   3   2   1   0   7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
00 | Fixed prefix 'C' (43h)        | 06h                           | Action                        |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Action CodeMeaning
00h Save settings and rebbot.
01h Reboot
02h Save settings and VFOs, no reboot.
03h Flash LED green.
04h Flash LED red.
05h Re-init internal buffers.
06h Re-init sound buffers.
07h Update date-time from GPS.

If there are no errors, the radio responds with

     7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+
00 | '-' (2dh)                     |
   +---+---+---+---+---+---+---+---+

Start GPS Logging (07h)

A simple request without any payload.

     7   6   5   4   3   2   1   0   7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
00 | Fixed prefix 'C' (43h)        | 7h                           |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

If there is no error, the response should be.

     7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+
00 | '-' (2dh)                     |
   +---+---+---+---+---+---+---+---+

After that, the radio will send GPS information via the serial port until any other command is send to the radio.

Ping Request (06h)

A simple request without any payload

     7   6   5   4   3   2   1   0   7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
00 | Fixed prefix 'C' (43h)        | feh                           |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

and the radio should respond with

     7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+
00 | '-' (2dh)                     |
   +---+---+---+---+---+---+---+---+

Read requests

The read command is used to obtain different stuff. Not only the code plug. In general, all read share the same form

     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
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
00 | Fixed prefix 'R' (52h)        | Memory                        | Address 32bit unsigned int, big endian                     ...
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
04  ...                                                            | Length, 16bit unsigned int, big endian                        |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Code Memory region
01h Flash
02h EEPROM
05h MCU ROM
06h Display buffer
07h WAV buffer
08h AMBE buffer
09h Radio info
0ah FLASH security registers

Whenever the read request returns some data, it is tranmitted with the read response

     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
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
00 | Fixed prefix 'R' (52h)        | Length, 16bit unsigned int, big endian                        | Data, length bytes         ...
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
nn  ...                                                                                                                            |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

If not, a simple ACK response is send

     7   6   5   4   3   2   1   0
   +---+---+---+---+---+---+---+---+
00 | '-' (2dh)                     |
   +---+---+---+---+---+---+---+---+

Radio info struct

When reading the radio inforamtion, the information is returned in a binary struct:

       0                               8                               16                              24
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0000 | Struct version number, 32bit unsigned int, little-endian, default 0x0003                                                      |
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0004 | Radio type, 32bit unsigned int, little endian                                                                                 |
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0008 | Git version string, 16x ASCII                                                                                                 |
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
      ...                                                                                                                         ...
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0014  ...                                                                                                                            |
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0018 | Build date-time string, 16x ASCII                                                                                          ...
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
      ...                                                                                                                         ...
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0024  ...                                                                                                                            |
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0028 | Flash chip part number, 32 bit unsigned int, little endian                                                                    |
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
002c | Features, 16bit unsigned int, little endian                   |
     +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Code Radio Variant
00h Radioddity GD-77
01h Radioddity GD-77S
02h Baofeng DM-1801
03h Radioddity RD-5R
04h Baofeng DM-1801A
05h TyT MD-9600
06h TyT MD-UV390
07h TyT MD-380
08h Baofeng DM-1701
09h TyT MD-2017
0ah Baofeng DM-1701 RGB

Write requests

Constructor & Destructor Documentation

◆ OpenGD77Interface()

OpenGD77Interface::OpenGD77Interface ( const USBDeviceDescriptor & descr,
const ErrorStack & err = ErrorStack(),
QObject * parent = nullptr )
explicit

Constructs a new interface to a specific OpenGD77 device.


Member Function Documentation

◆ close()

void OpenGD77Interface::close ( )
virtual

Closes the interface to the device.

Implements RadioInterface.

◆ finishWriteFlash()

bool OpenGD77Interface::finishWriteFlash ( const ErrorStack & err = ErrorStack())
protected

Finalize writing to the Flash memory.

If not send after writing to a sector, the changes are lost.

◆ identifier()

RadioInfo OpenGD77Interface::identifier ( const ErrorStack & err = ErrorStack())
virtual

Returns an identifier of the radio.

Implements RadioInterface.

◆ read()

bool OpenGD77Interface::read ( uint32_t bank,
uint32_t addr,
uint8_t * data,
int nbytes,
const ErrorStack & err = ErrorStack() )
virtual

Reads a chunk of data from the block-address bno (block number).

Parameters
bankSpecifies the memory bank to read from. Usually there is only one bank. Some radios, however, to have several memory banks to hold the codeplug. For example the Open GD77 has EEPROM and Flash memory banks with independent addresses.
addrSpecifies the address to read from.
dataPointer where to store the read data.
nbytesSpecifies the number of bytes to read.
errPasses an error stack to put error messages on.
Returns
true on success.

Implements RadioInterface.

◆ read_finish()

bool OpenGD77Interface::read_finish ( const ErrorStack & err = ErrorStack())
virtual

This function ends a series of read operations.

This function will be re-implemented by certain interfaces that need completion of read operations (e.g., HID).

Parameters
errPasses an error stack to put error messages on.

Implements RadioInterface.

◆ read_start()

bool OpenGD77Interface::read_start ( uint32_t bank,
uint32_t addr,
const ErrorStack & err = ErrorStack() )
virtual

Starts the read process from the specified bank and at the given address.

Parameters
bankSpecifies the memory bank to read from. Usually there is only one bank. Some radios, however, to have several memory banks to hold the codeplug. For example the Open GD77 has EEPROM and Flash memory banks with independent addresses.
addrSpecifies the address to read from.
errPasses an error stack to put error messages on.

Implements RadioInterface.

◆ reboot()

bool OpenGD77Interface::reboot ( const ErrorStack & err = ErrorStack())
virtual

Some radios need to be rebooted after being read or programmed.

This function will be re-implemented by some interfaces (e.g., DFUDevice) to reboot the radio. By default this function does nothing.

Parameters
errPasses an error stack to put error messages on.

Reimplemented from RadioInterface.

◆ setFlashSector()

bool OpenGD77Interface::setFlashSector ( uint32_t addr,
const ErrorStack & err = ErrorStack() )
protected

Select the correct Flash sector for the given address.

This command must be sent before writing to the flash memory.

◆ write()

bool OpenGD77Interface::write ( uint32_t bank,
uint32_t addr,
uint8_t * data,
int nbytes,
const ErrorStack & err = ErrorStack() )
virtual

Writes a chunk of data at the address addr.

Parameters
bankSpecifies the memory bank to write to. Usually there is only one bank. Some radios, however, to have several memory banks to hold the codeplug. For example the Open GD77 has EEPROM and Flash memory banks with independent addresses.
addrSpecifies the address to write to.
dataPointer to the actual data to be written.
nbytesSpecifies the number of bytes to write.
errPasses an error stack to put error messages on.
Returns
true on success.

Implements RadioInterface.

◆ write_finish()

bool OpenGD77Interface::write_finish ( const ErrorStack & err = ErrorStack())
virtual

This function ends a series of write operations.

This function will be implemented by certain interfaces that need completion of write operations (e.g., HID).

Parameters
errPasses an error stack to put error messages on.

Implements RadioInterface.

◆ write_start()

bool OpenGD77Interface::write_start ( uint32_t bank,
uint32_t addr,
const ErrorStack & err = ErrorStack() )
virtual

Starts the write process into the specified bank and at the given address.

Parameters
bankSpecifies the memory bank to write to. Usually there is only one bank. Some radios, however, to have several memory banks to hold the codeplug. For example the Open GD77 has EEPROM and Flash memory banks with independent addresses.
addrSpecifies the address to write to.
errPasses an error stack to put error messages on.

Implements RadioInterface.


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