LAST UPDATED June 9, 2026
v1
v1

Functional Description

A Dual-Mode Bluetooth Module geared for audio.

The Violet C Module (hereby referred to as Violet C or Violet, if unspecified) is a Bluetooth SoM supporting Bluetooth BR/EDR + LE, geared for audio over Bluetooth. There are 2 relevant versions of Violet, versions B and C.

Violet C Module

Violet B utilizes an older chipset(ATS2853X), whereas Violet C uses a newer chipset(ATS2835X) and supports newer features. The primary difference is that Violet C contains support for LE Audio, as opposed to Violet B, which only support Classic Audio. A summary of the functions and peripherals can be seen below.

Violet B Violet C
Features
Bluetooth BR/EDR
BLE
LE Audio
USB
I2S
TWI / I2C
UART 0 / 1
SPI
Note

A number of other functions, such as GPIO, timers, IR Rx, etc, can be accessed by multiplexing certain peripherals. See the datasheet for further information.

v1

Pinout

The pinout is as follows.

Pin NumberPin NameDescription
1GND Ground
2GND Ground
3AOR DAC Analog Out Right
4GPIO9 / SPI1 CLK GPIO 9 | SPI Clock
5AOL DAC Analog Out Left
6GPIO10 / SPI1 MISO GPIO 10 | SPI MISO
7GPIO11 / SPI1 MOSI GPIO 11 | SPI MOSI
8GPIO12 / SPI1 SS GPIO 12 | SPI Chip Select
9GND Ground
105V 5V power supply [in]
11BAT 4.1V power supply [out]
12GND Ground
13AIR Analog Input Right
14AIL Analog Input Left
15AUX DET AUX detect
16GPIO0 GPIO 0
17GND Ground
18I2S MCLK I2S Master Clock
19I2S BCLK I2S Bit Clock
20I2S LRCLK I2S L/R Clock
21I2S SDO I2S Serial Data Out
22I2S SDI I2S Serial Data In
23GND Ground
24GPIO1 / UART1 Rx GPIO 1 | UART 1 Receive
25GPIO2 / UART1 Tx GPIO 2 | UART 1 Transmit
26PROG USB Program select [active low]
27GPIO3 / WAKE GPIO 3 | WAKE function
28RST Reset board [active low]
29GPIO4 / UART1 RTS GPIO 4 | UART 1 Clear To Send
30GPIO5 / UART1 CTS GPIO 5 | UART 1 Ready To Send
31GND Ground
32VCC 3.3V power supply [out]
33LED1 LED 1 drive pin
34LED2 LED 2 drive pin
35GND Ground
36USB DP USB Data Plus
37USB DM USB Data Minus
38ADC2 Low Resolution ADC 2
39ADC1 Low Resolution ADC 1[1]
40VCC 3.3V power supply [out]
41GPIO6 / PWM GPIO 6 | PWM output
42GPIO7 / TWI SCL I2C Clock
43GPIO8 / TWI SDA I2C Data
44GND Ground
45GND Ground
[1]

If USB ADFU mode cannot be reached by normal means (holding PROG low during a reset), ADC1 can be pulled to ground to forcefully enter this mode. Additionally, R6 on Violet C can be populated to short ADC1 to GND.

Violet C Pin Number Diagram

Violet C Pinout Numbers
v1

State Machine

The Violet State Machine is as follows.

Violet C State Machine With Button Violet C State Machine Without Button

For the most part, the State Machine should be self sufficient. APIs can be used to request information about the Bluetooth connection, without affecting the state machine directly. There are only 3 ways the state machine should be manually changed.

  • Entering the Discoverable state
  • Clearing the pair list (wiping reconnection information)
  • Smartphone connections, disconnections, media changes, etc

Deprecated APIs will remain, but may break the state machine behavior.

API Structure

Violet APIs are to follow the following packet structure when sent over UART1.

Packet Structure

Byte 0
0xAA
Byte 1
n
Byte 2
t
Byte 3
0xYY
Byte m
0xYY
Byte M
0xYY
Magic Number
Payload Length
API Type
Data 1
Data m
Data M
Note

For the time being, the Magic value shall remain as 0xAA. Any packets not containing the same value shall be discarded.

Packet lengths are API dependent. The least amount of data a packet can contain is 3 bytes, where the Payload Length shall be set to 1. Note that all packets sent from an MCU to Violet will be responded to, but Violet may send APIs without request.

API Type

Value Hex Description
ACK 0x01 Acknowledge. Indicates that the API has been successfully received.
STATUS 0x02 Status. Indicates a given state, given the context of the API in question.
VOLUME 0x03 Volume. Special status used to indicate a change in volume level.
SKAA_API 0x04 APIs marked with the SKAA_API type are intended to be forwarded from MCU to BLE, or vice versa.
NACK 0xFF Bad API received, API context dependent.

API - Power On

Active

Description

This API is emitted during boot of Violet C. It can be used to notify that the Violet C is active, or that a reboot has occurred. A reboot may be unintentional, or via an OTA upgrade.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x01
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x01
Magic
Payload Length
Type
API Code

API - Power Off

Deprecated

Description

This API was relevant in Violet A, as it had to be externally powered on and off(seperate chipset). This API will still respond, but it will have no effect on Violet C.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x02
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x02
Magic
Payload Length
Type
API Code

API - Enter Standby

Deprecated

Description

This API will disconnect any connected devices, stop reconnection, and enter non-discoverable.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x03
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x03
Magic
Payload Length
Type
API Code

API - Exit Standby

Deprecated

Description

This API reallows connections to Violet.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 4
0x04
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 4
0x04
Magic
Payload Length
Type
API Code

API - Enter Linkback

Deprecated

Description

This API will start the reconnection process for any devices stored on the pair list.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x05
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x05
Magic
Payload Length
Type
API Code

API - Enter Discoverable

Active

Description

This API will force Violet into a discoverable state, and allows new connections to the module. This API will return an ACK.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x06
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x06
Magic
Payload Length
Type
API Code

API - Exit Discoverable

Deprecated

Description

This API cause Violet to enter a non-discoverable state, and will try to reconnect to a device on the pair list, if any. This API will return an ACK.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x07
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x07
Magic
Payload Length
Type
API Code

API - Clear Pair List

Active

Description

This API will disconnect any connected devices, and wipe all reconnection information from NVRAM (effectively clearing the pair list). This API will return an ACK.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x08
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x08
Magic
Payload Length
Type
API Code

API - Play

Active

Description

This API will attempt to stop any media over AVRCP. If the command fails, a NACK will be returned, otherwise, ACK.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x09
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x09
Magic
Payload Length
Type
API Code

Violet MCU
Not Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0xFF
Byte 3
0x09
Magic
Payload Length
Type
API Code

API - Play

Active

Description

This API will attempt to toggle between pause and play over AVRCP. This behaviour is carried over from Violet B. If the command fails, a NACK will be returned, otherwise, ACK.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x0A
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x0A
Magic
Payload Length
Type
API Code

Violet MCU
Not Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0xFF
Byte 3
0x0A
Magic
Payload Length
Type
API Code

API - Volume Up

Active

Description

This API will increment the relative system volume. This API will return an ACK.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x0B
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x0B
Magic
Payload Length
Type
API Code

API - Volume Down

Active

Description

This API will decrement the relative system volume. This API will return an ACK.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x0C
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x0C
Magic
Payload Length
Type
API Code

API - Volume Set

Active

Description

This API will set the absolute system volume. This API will return an ACK.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x03
Byte 2
0x01
Byte 3
0x0D
Byte 4
0x0N
Magic
Payload Length
Type
API Code
Volume[0,31]

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x0D
Magic
Payload Length
Type
API Code

API - Track Forward

Active

Description

This API will attempt to go to the next track over AVRCP. This behaviour is carried over from Violet B. If the command fails, a NACK will be returned, otherwise, ACK.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x0E
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x0E
Magic
Payload Length
Type
API Code

Violet MCU
Not Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0xFF
Byte 3
0x0E
Magic
Payload Length
Type
API Code

API - Track Back

Active

Description

This API will attempt to go to the previous track over AVRCP. This behaviour is carried over from Violet B. If the command fails, a NACK will be returned, otherwise, ACK.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x0F
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x0F
Magic
Payload Length
Type
API Code

Violet MCU
Not Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0xFF
Byte 3
0x0F
Magic
Payload Length
Type
API Code

API - Request Volume

Active

Description

This API will return an ACK containing the volume.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x10
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x03
Byte 2
0x01
Byte 3
0x10
Byte 4
0xYY
Magic
Payload Length
Type
API Code
Volume[0,31]

API - Request Pair List

Active

Description

This API will return an ACK containing the Bluetooth Addresses of all devices on the pair list. The Payload Length can be used to return the number of paired devices, and each Bluetooth Address is emitted consecutively. If there are no paired devices, the Payload Length shall be set to 2.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x11
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0xNN
Byte 2
0x01
Byte 3
0x11
Byte 4
0xUU
Byte 5 + n
0xVV
Byte 6 + n
0xWW
Byte 7 + n
0xXX
Byte 8 + n
0xYY
Byte 9 + n
0xZZ
Magic
Payload Length
Type
API Code
BT Addr Byte 0
BT Addr Byte 1
BT Addr Byte 2
BT Addr Byte 3
BT Addr Byte 4
BT Addr Byte 5

API - Request State

Active

Description

This API will return an ACK containing the system connection state.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x12
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x03
Byte 2
0x01
Byte 3
0x12
Byte 4
0xYY
Magic
Payload Length
Type
API Code
State

API - OTA UART Upgrade

Active

Description

This API will begin the OTA upgrade process over UART, using the generated ota.bin file. This API returns an ACK. See the programming section for further information.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x13
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x13
Magic
Payload Length
Type
API Code

API - Disconnect

Active

Description

This API disconnects any/all currently connected devices, and returns an ACK.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x14
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x14
Magic
Payload Length
Type
API Code

API - Update Bluetooth Name

Active

Description

This API writes a new Bluetooth BR/EDR name to NVRAM, and returns an ACK. The Payload Length should be equal to the name length in characters + 3. The name should end in a null terminator \0.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0xNN
Byte 2
0x01
Byte 3
0x15
Byte 4+
0xYY
Magic
Payload Length
Type
API Code
BT Name Byte

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x15
Magic
Payload Length
Type
API Code

API - Update MAC Address

Active

Description

This API writes a new device MAC Address to NVRAM, and returns an ACK. The Payload Length should be equal to 8.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x08
Byte 2
0x01
Byte 3
0x16
Byte 4+
0xYY
Magic
Payload Length
Type
API Code
MAC Byte X

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x16
Magic
Payload Length
Type
API Code

API - SKAA API To Violet

Active

Description

This API acts as a passthrough for SKAA APIs, forwarding APIs from the MCU to a BLE connection (if available). This API returns an ACK.

MCU Violet
SKAA API

Byte 0
0xAA
Byte 1
0x0D
Byte 2
0x04
Byte 3
0x17
Byte 4
0xWW
Byte 5
0xXX
Byte 6
0xYY
Byte 7+
0xZZ
Magic
Payload Length
Type
API Code
SKAA Type
SKAA Index
SKAA Dest
SKAA Data[8]

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x17
Magic
Payload Length
Type
API Code

API - SKAA API To MCU

Active

Description

This API acts as a passthrough for SKAA APIs, forwarding APIs from a BLE connection (if available) to the MCU. This API is one way only.

Violet MCU
SKAA API

Byte 0
0xAA
Byte 1
0x0D
Byte 2
0x04
Byte 3
0x18
Byte 4
0xWW
Byte 5
0xXX
Byte 6
0xYY
Byte 7+
0xZZ
Magic
Payload Length
Type
API Code
SKAA Type
SKAA Index
SKAA Dest
SKAA Data[8]

API - Set Local Volume Scaling

Active

Description

This API sets the local DAC volume, and returns an ACK.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x03
Byte 2
0x01
Byte 3
0x19
Byte 4
0xYY
Magic
Payload Length
Type
API Code
Local Volume

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x19
Magic
Payload Length
Type
API Code

API - Update Bluetooth LE Name

Active

Description

This API writes a new Bluetooth LE Name to NVRAM, and returns an ACK. The Payload Length should be equal to the name length in characters + 3.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0xNN
Byte 2
0x01
Byte 3
0x1A
Byte 4+
0xYY
Magic
Payload Length
Type
API Code
BLE Name Byte

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x1A
Magic
Payload Length
Type
API Code

API - Update Nadja LS Version

Active

Description

This API writes the current Nadja LS version to NVRAM, and returns an ACK. The Payload Length should be equal to the version length in characters + 3.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0xNN
Byte 2
0x01
Byte 3
0x1B
Byte 4+
0xYY
Magic
Payload Length
Type
API Code
Version Byte

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x1B
Magic
Payload Length
Type
API Code

API - Update Hardware ID

Active

Description

This API writes the Hardware ID to NVRAM, and returns an ACK. The Payload Length should be equal to the hardware ID length in characters + 3.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0xNN
Byte 2
0x01
Byte 3
0x1C
Byte 4+
0xYY
Magic
Payload Length
Type
API Code
HWID Byte

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x1C
Magic
Payload Length
Type
API Code

API - Update UUID

Active

Description

This API writes the UUID to NVRAM, and returns an ACK. The Payload Length should be equal to the UUID length in characters + 3.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0xNN
Byte 2
0x01
Byte 3
0x1D
Byte 4+
0xYY
Magic
Payload Length
Type
API Code
UUID Byte

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x1D
Magic
Payload Length
Type
API Code

API - Update Serial Number

Active

Description

This API writes the Serial Number to NVRAM, and returns an ACK. The Payload Length should be equal to the Serial Number length in characters + 3. The serial number must be 7–32 printable ASCII characters.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0xNN
Byte 2
0x01
Byte 3
0x1E
Byte 4+
0xYY
Magic
Payload Length
Type
API Code
SN Byte

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x1E
Magic
Payload Length
Type
API Code

API - OTA UART Fast Upgrade

Active

Description

This API initiates the OTA Upgrade process over UART, and returns an ACK. The MCU must support switching baud rates, as the fast upgrade runs at 3 MBaud, while the command is sent at 115200. See the programming section for further details.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x3F
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x3F
Magic
Payload Length
Type
API Code

API - OTA UART Very Fast Upgrade

Active

Description

This API initiates the OTA Upgrade process over UART, and returns an ACK. The MCU must support switching baud rates, as the very fast upgrade runs at 6 MBaud, while the command is sent at 115200. This API has not been tested, but should theoretically work. See the programming section for further details.

MCU Violet
Command

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x40
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0x40
Magic
Payload Length
Type
API Code

API - Command Unknown

Incomplete

Description

This API ACKs any non-supported APIs.

Violet MCU
Not Acknowledge

Byte 0
0xAA
Byte 1
0x02
Byte 2
0x01
Byte 3
0xFF
Magic
Payload Length
Type
NACK Code

API - Request Metadata Title

Active

Description

This API returns the current title metadata, retrieved via AVRCP. If no data is valid, the payload shall be set to 2.

MCU Violet
Command

Byte 0
0xCC
Byte 1
0x02
Byte 2
0x01
Byte 3
0x20
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xCC
Byte 1
0xNN
Byte 2
0x01
Byte 3
0x20
Byte 4+
0xYY
Magic
Payload Length
Type
API Code
Title Byte

API - Request Metadata Artist

Active

Description

This API returns the current artist metadata, retrieved via AVRCP. If no data is valid, the payload shall be set to 2.

MCU Violet
Command

Byte 0
0xCC
Byte 1
0x02
Byte 2
0x01
Byte 3
0x21
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xCC
Byte 1
0xNN
Byte 2
0x01
Byte 3
0x21
Byte 4+
0xYY
Magic
Payload Length
Type
API Code
Artist Byte

API - Request Metadata Album

Active

Description

This API returns the current album metadata, retrieved via AVRCP. If no data is valid, the payload shall be set to 2.

MCU Violet
Command

Byte 0
0xCC
Byte 1
0x02
Byte 2
0x01
Byte 3
0x22
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xCC
Byte 1
0xNN
Byte 2
0x01
Byte 3
0x22
Byte 4+
0xYY
Magic
Payload Length
Type
API Code
Album Byte

API - Request Metadata Duration

Active

Description

This API returns the current track duration metadata as a decimal millisecond string, retrieved via AVRCP. If no data is valid, the payload shall be set to 2.

MCU Violet
Command

Byte 0
0xCC
Byte 1
0x02
Byte 2
0x01
Byte 3
0x23
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xCC
Byte 1
0xNN
Byte 2
0x01
Byte 3
0x23
Byte 4+
0xYY
Magic
Payload Length
Type
API Code
Duration Byte

API - Request Play Status

Active

Description

This API returns the current media play status as a 3-byte response. The play status byte is the value returned by the BT manager's media status query.

MCU Violet
Command

Byte 0
0xCC
Byte 1
0x02
Byte 2
0x01
Byte 3
0x24
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge

Byte 0
0xCC
Byte 1
0x03
Byte 2
0x01
Byte 3
0x24
Byte 4
0xYY
Magic
Payload Length
Type
API Code
Play Status

API - Request Remote Bluetooth Name

Active

Description

This API returns the Bluetooth device name of the active A2DP peer (up to 30 characters). If no A2DP device is active, the response payload length is set to 2 (type + API code only).

MCU Violet
Command

Byte 0
0xCC
Byte 1
0x02
Byte 2
0x01
Byte 3
0x25
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge (device connected)

Byte 0
0xCC
Byte 1
0xNN
Byte 2
0x01
Byte 3
0x25
Byte 4+
0xYY
Magic
Payload Length
Type
API Code
BT Name Byte

Violet MCU
Acknowledge (no device)

Byte 0
0xCC
Byte 1
0x02
Byte 2
0x01
Byte 3
0x25
Magic
Payload Length
Type
API Code

API - Request Remote Bluetooth Address

Active

Description

This API returns the 6-byte BD_ADDR of the active A2DP peer. If no A2DP device is active, the response payload length is set to 2 (type + API code only).

MCU Violet
Command

Byte 0
0xCC
Byte 1
0x02
Byte 2
0x01
Byte 3
0x26
Magic
Payload Length
Type
API Code

Violet MCU
Acknowledge (device connected)

Byte 0
0xCC
Byte 1
0x08
Byte 2
0x01
Byte 3
0x26
Byte 4
0xUU
Byte 5
0xVV
Byte 6
0xWW
Byte 7
0xXX
Byte 8
0xYY
Byte 9
0xZZ
Magic
Payload Length
Type
API Code
BT Addr Byte 0
BT Addr Byte 1
BT Addr Byte 2
BT Addr Byte 3
BT Addr Byte 4
BT Addr Byte 5

Violet MCU
Acknowledge (no device)

Byte 0
0xCC
Byte 1
0x02
Byte 2
0x01
Byte 3
0x26
Magic
Payload Length
Type
API Code
v1

Programming

There are 2 primary ways to program Violet C.

  • Via ADFU over USB
  • Via OTA over UART

USB

The only 2 requirements to program violet is the 5V power supply, and USB data lines (DP, DM).

If the Violet C has not been programmed before, ADFU(Actions Device Firmware Upgrade) will be entered automatically. While in this mode, the MultiMedia Product Tool by Actions can be used to flash a .fw file.

If the Violet has been programmed prior, there are 2 ways to intentionally enter ADFU. First, holding the PROG pin active low while resetting the board (via RST) will initiate ADFU. The second way to intentionally enter ADFU is to shortADC1 to Ground. This can be manually achevied by populating R6 on Violet C, and removing after flashing.

Multi Media Tool
Actions Multimedia Product Tool.

Once in ADFU mode, the number of USB devices will increase on the MultiMedia Product Tool, and it will classify as ADFU, not UDISK.

Multi Media Tool
USB ADFU connected.

When the Violet is "Ready", you can select the desired .fw file, and hit the large download arrow.

Multi Media Tool
Select .fw file.
Multi Media Tool
Successful download.

When the download has completed successfully, the connected device will show "Successful(offline)". From this point, resetting the Violet will cause it to enter normal operation. Other programming options can be selected on the right side of the tool, and hovering over will provide descriptions hints.


UART

Programming via UART effectively transfers a firmware binary (.bin) to Violet, which flashes itself once the transfer is complete. The exchange consists of three main phases: Initialization, Handshake, and Data Transfer. Only the host may begin the transfer via the OTA UART Upgrade API (API Code 0x13 or 0x3F). Note that the "Very Fast" requires a baude rate of 600000, and has not been tested due to hardware limitiations.


1. UART API Update Trigger

The default baud rate is determined by the API in question. If a higher baud rate is selected, both sides must do a switch in conjunction with eachother. A buad rate of 3 MBaud is suggested, as it reduces flashing time from 3 minutes to 30 seconds. No other APIs should be sent after this API is transferred, otherwise the process may freeze, and reset is required. This applies to Bluetooth events as well, so ensure that no devices are connected during this process.

sequenceDiagram participant H as Host (loader) participant D as Device (Violet) H->>D: [Init] AA 02 01 <cmd> Note over H,D: cmd = 0x13 or 0x3F opt H->>H: Drain TX H->>H: Switch baud rate H->>H: Wait 50 ms, flush RX end

If a higher baud is selected, the baud rate switch must be complete immediately after the API transfer.


2. Handshake

sequenceDiagram participant H as Host participant D as Violet D->>H: "OK?" (3 bytes) H->>D: "YES,YOU?" (8 bytes) D->>H: "METOO" (5 bytes)

The purpose of the handshake is to begin the data transfer.


3. Data Transfer

sequenceDiagram participant H as Host participant D as Violet loop Until all chunks delivered D->>H: PULLDATA cmd packet [seq, offset, len] (20 bytes) H->>D: CRC32(chunk) + seq + firmware[offset..offset+len-1] end D->>H: REPORT01 cmd packet [seq, 0, 0] (20 bytes) H->>D: CRC32("REPORT01") + seq + "REPORT01" (16 bytes) Note over H,D: OTA upgrade complete

PULLDATA Command Packet

Once the handshake is complete, Violet will begin to emit commands for data.

Bytes Type Field
0 – 7 char[8] Command name (ASCII, zero-padded)
8 – 11 uint32_t little-endian Sequence number
12 – 15 uint32_t little-endian Byte offset in firmware image
16 – 19 uint32_t little-endian Number of Bytes requested

PULLDATA Response

The host shall respond to the PULLDATA request with the requested data, and a CRC-32 check.

Bytes Field
0 – 3 CRC-32 of firmware[offset : offset+len−1]
4 – 7 Echo of the request sequence number (little-endian)
8 – 8+len−1 Raw firmware data (len bytes)

REPORT01 Command Packet

After all chunks have been pulled successfully, the device sends a REPORT01 command to signal it has received the entire image.

Bytes Type Field
0 – 7 char[8] Command name (ASCII, zero-padded)
8 – 11 uint32_t little-endian Sequence number
12 – 15 uint32_t little-endian 0x0000
16 – 19 uint32_t little-endian 0x0000

REPORT01 Response

Once the response is received, the OTA update is considered complete on the Host side.

Bytes Field
0 – 3 CRC-32 of the ASCII string "REPORT01"
4 – 7 Echo of the sequence number (little-endian)
8 – 15 ASCII string "REPORT01"

After the data transfer is complete, allow up to a minute for the Violet to complete firmware upgrades. Interrupting this process may cause the Violet to enter an un-recoverable state, except via ADFU. A Power On API can be used to indicate when the process is complete.

CRC-32 Algorithm

cpp

static const uint32_t s_crc32[16] = {
  0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
  0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
  0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
  0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};

uint32_t VioletProgrammer::Crc32(uint32_t crc, const uint8_t* ptr, uint32_t buf_len) {
  uint32_t crcu32 = ~crc;
  while (buf_len--) {
    uint8_t b = *ptr++;
    crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
    crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
  }
  return ~crcu32;
}
        

Miscellaneous

Useful Structures

cpp

typedef struct {
  uint8_t magic;
  uint8_t length;
  std::array payload; // Type (1 byte) + API (1 byte) + up to 253 bytes of data
} violet_uart_api_t;

enum class VioletMagic : uint16_t {
  VioletB = 0xAA,
  VioletC = 0xCC,
  NotApplicable = 0xFF
};

/* VIOLET C TYPE */
enum class VioletAPIType : uint8_t {
  Event = 0x00,
  Ack = 0x01,
  Status = 0x02,
  Volume = 0x03,
  SkaaAPI = 0x04,
  Nack = 0xFF
};

/* VIOLET CONNECTION STATE */
enum class ConnState {
  Off = 0x00,       // Radio is considered off.
  PowerOn = 0x01,   // Radio has turned on. This is more so an event, as the state will change almost immediately after.
  Reconnecting = 0x02,  // Radio is attempting to connect to a device found on the pair list, based on reconnect policy.
  Discoverable = 0x03,  // Radio is discoverable, AND other states are invalid.
  Connected = 0x04,     // Radio has an active connection to another device.
  Standby = 0x06,        // Radio is on, but not discoverable or connectable.
  Pairing,       // Another device has initiated pairing.
  Connecting,    // Radio is in the process of connecting to another device.
  Disconnecting, // Radio is in process of disconnecting from another device (intentional).
};

/* VIOLET EVENTS */
enum class VioletEvent : uint8_t {
  PowerOn = 0x00,
  DeviceConnected = 0x01,
  DeviceDisconnected = 0x02,
  TrackChanged = 0x03,
  MetadataUpdated = 0x04,
  TransportBr = 0x05,
  TransportLe = 0x06,
  MediaConnected = 0x07
};


/* VIOLET B APIs */

enum class VioletAPI : uint8_t {
  PowerOn                 = 0x01,
  PowerOff                = 0x02,
  EnterStandby            = 0x03,
  ExitStandby             = 0x04,
  EnterLinkback           = 0x05,
  EnterDiscoverable       = 0x06,
  ExitDiscoverable        = 0x07,
  ClearPairedList         = 0x08,
  Play                    = 0x09,
  Pause                   = 0x0A,
  VolumeUp                = 0x0B,
  VolumeDown              = 0x0C,
  VolumeSet               = 0x0D,
  NextTrack               = 0x0E,
  PrevTrack               = 0x0F,
  RequestVolume           = 0x10,
  RequestPairedList       = 0x11,
  RequestState            = 0x12,
  OtaUartUpgrade          = 0x13,
  Disconnect              = 0x14,
  UpdateBtName            = 0x15,
  UpdateMac               = 0x16,
  SkaaApiToViolet         = 0x17,
  SkaaApiToNls            = 0x18,
  SetLocalVolumeScaling   = 0x19,
  UpdateBleName           = 0x1A,
  UpdateNlsVersion        = 0x1B,
  UpdateHwid              = 0x1C,
  UpdateUuid              = 0x1D,
  UpdateSerialNumber      = 0x1E,
  RequestMetadataTitle    = 0x20,
  RequestMetadataArtist   = 0x21,
  RequestMetadataAlbum    = 0x22,
  RequestMetadataDuration = 0x23,
  RequestPlayStatus       = 0x24,
  RequestRemoteBtName     = 0x25,
  RequestRemoteBtAddr     = 0x26,
  OtaUartFastUpgrade      = 0x3F,
  OtaUartVeryFastUpgrade  = 0x40,
  CommandUnknown          = 0xFF
};

enum class PlayStatus : uint8_t {
  Inactive = 0,
  Paused,
  Playing
};
        

Changelog

What's new in each release

v1 2026-05-29

  • Create online documentation

v1 2026-05-29

  • Complete online documentation