Skip to content

v1.3.0-rc.1

Pre-release
Pre-release
Compare
Choose a tag to compare
@skuep skuep released this 01 Jan 16:23
· 26 commits to master since this release

This is a quite extensive pre-release delivering a firmware implementation of the promised

  • HID configuration system as discussed in PR #37 and
  • virtual PTT as discussed in PR #25 and issue #19.

Configurability

This enables the user to configure all kinds of functionality within the AIOC. Currently this is

  • USB VID:PID (although not recommended, but can be helpful in a pinch)
  • PTT1/PTT2 signal source (CM108 GPIOs 1-4, serial DTR/RTS or the new virtual PTT which serves as a high-performance VOX)
  • Configure CM108 buttons (Volume Up/Down, Playback/Record Mute) and serial inputs to PTT1/PTT2 inputs (supported with next hardware revision) or virtual COS)
  • Configure UART lockout on PTT activity, which is enabled by default but can be disabled. This is required to be able to use the AIOC as both a programming cable (UART) and soundcard.
  • Configure Virtual PTT and Virtual COS settings such as threshold value and timeout (tail) time
  • A whole slew of debug register showing whats going on inside the AIOC

Although all these things are now configurable, the default configuration is kept such that people that don't want to use this system, won't even notice it's there. E.g. default for PTT1 is still CM108 GPIO3 or DTR & !NRTS. CM108 Volume Down has the virtual COS.

The configuration can be stored in flash and is thus kept across power cycles. If you flash a new firmware in the future however, the settings will be lost. This is a bit inconvenient, but required to avoid having to be backwards compatible with the binary settings inside the flash across firmware versions.

How to configure

This part of the release is still a bit lacking. I plan there to be a very extensive python command line application that can be used to programm all the new configuration values of the AIOC. However currently, I only have this debug script, that I use for my purposes, that I can show you.
Please have a look in the stm32/aioc-fw/Src/settings.hfile on the details of the contents in those registers.

import sys
import hid
from struct import Struct
from enum import IntEnum, IntFlag

class Register(IntEnum):
    MAGIC = 0x00
    USBID = 0x08
    AIOC_IOMUX0 = 0x24
    AIOC_IOMUX1 = 0x25
    CM108_IOMUX0 = 0x44
    CM108_IOMUX1 = 0x45
    CM108_IOMUX2 = 0x46
    CM108_IOMUX3 = 0x47
    SERIAL_CTRL = 0x60
    SERIAL_IOMUX0 = 0x64
    SERIAL_IOMUX1 = 0x65
    SERIAL_IOMUX2 = 0x66
    SERIAL_IOMUX3 = 0x67
    VPTT_LVLCTRL = 0x82
    VPTT_TIMCTRL = 0x84
    VCOS_LVLCTRL = 0x92
    VCOS_TIMCTRL = 0x94

    
class Command(IntFlag):
    DEFAULTS = 0x10
    RECALL = 0x40
    STORE = 0x80

class PTTSource(IntFlag):
    NONE = 0x00000000
    CM108GPIO1 = 0x00000001
    CM108GPIO2 = 0x00000002
    CM108GPIO3 = 0x00000004
    CM108GPIO4 = 0x00000008
    SERIALDTR = 0x00000100
    SERIALRTS = 0x00000200
    SERIALDTRNRTS = 0x00000400
    SERIALNDTRRTS = 0x00000800
    VPTT = 0x00001000


def read(device, address):
    data = device.get_feature_report(int(address), 5)
    address, value = Struct('<BL').unpack(data)
    return value

def write(device, address, value):
    data = Struct('<BL').pack(address, value)
    device.send_feature_report(data)

def dump(device):
    for r in Register:
        print(f'Reg. {r.value:02x}: {read(device, r.value):08x}')

aioc = hid.Device(vid=0x1209, pid=0x7388)

magic = Struct("<L").pack(read(aioc, Register.MAGIC))

if (magic != b'AIOC'):
    sys.exit(-1)

print(f'Manufacturer: {aioc.manufacturer}')
print(f'Product: {aioc.product}')
print(f'Serial No: {aioc.serial}')
print(f'Magic: {magic}')

if True:
    # Load the hardware defaults
    print(f'Loading Defaults...')
    write(aioc, 0, Command.DEFAULTS)

if True:
    # Dump all known registers
    dump(aioc)

ptt1_source = PTTSource(read(aioc, Register.AIOC_IOMUX0))
ptt2_source = PTTSource(read(aioc, Register.AIOC_IOMUX1))

print(f'Current PTT1 Source: {str(ptt1_source)}')
print(f'Current PTT2 Source: {str(ptt2_source)}')

if False:
    # Swap PTT1/PTT2
    ptt1_source, ptt2_source = ptt2_source, ptt1_source
    print(f'Setting PTT1 Source to {str(ptt1_source)}')
    write(aioc, Register.AIOC_IOMUX0, ptt1_source)
    print(f'Setting PTT2 Source to {str(ptt2_source)}')
    write(aioc, Register.AIOC_IOMUX1, ptt2_source)

    print(f'Now PTT1 Source: {str(PTTSource(read(aioc, Register.AIOC_IOMUX0)))}')
    print(f'Now PTT2 Source: {str(PTTSource(read(aioc, Register.AIOC_IOMUX1)))}')

if False:
    # Set to AutoPTT on PTT1
    write(aioc, Register.AIOC_IOMUX0, PTTSource.VPTT)


if False:
    # Set USB VID and PID (use with caution. Will need changes above to be able to re-configure the AIOC)
    write(aioc, Register.USBID, (0x1209 << 0) | (0x7388 << 16))
    print(f'Now USBID: {read(aioc, Register.USBID):08x}')

if False:
    # Store settings into flash
    print(f'Storing...')
    write(aioc, 0, Command.STORE)

Should you have any issues or questions, feel free to open an issue.