stateDiagram

state CALIBRATION_STATES {

        CALIBRATE_FREQUENCY

        CALIBRATE_FREQUENCY : CALIBRATE_FREQUENCY

        CALIBRATE_FREQUENCY : enter / #123; UpdateHardwareState()#59; #125;

        CALIBRATE_RX_IQ

        CALIBRATE_RX_IQ : CALIBRATE_RX_IQ

        CALIBRATE_RX_IQ : enter / #123; UpdateHardwareState()#59; #125;

        CALIBRATE_RX_IQ : do / #123; UpdateRXDeltaVal()#59; #125;

        CALIBRATE_TX_IQ_SPACE

        CALIBRATE_TX_IQ_SPACE : CALIBRATE_TX_IQ_SPACE

        CALIBRATE_TX_IQ_SPACE : enter / #123; UpdateHardwareState()#59; #125;

        state "$exit_pt.done" as CALIBRATION_STATES.(ExitPoint)(done)

        CALIBRATE_TX_IQ_MARK

        CALIBRATE_TX_IQ_MARK : CALIBRATE_TX_IQ_MARK

        CALIBRATE_TX_IQ_MARK : enter / #123; UpdateHardwareState()#59; #125;

        CALIBRATE_TX_IQ_MARK : do / #123; UpdateTXDeltaVal()#59; #125;

        CALIBRATE_POWER_SPACE

        CALIBRATE_POWER_SPACE : CALIBRATE_POWER_SPACE

        CALIBRATE_POWER_SPACE : enter / #123; UpdateHardwareState()#59; #125;

        CALIBRATE_POWER_MARK

        CALIBRATE_POWER_MARK : CALIBRATE_POWER_MARK

        CALIBRATE_POWER_MARK : enter / #123; UpdateHardwareState()#59; #125;

        CALIBRATE_OFFSET_MARK

        CALIBRATE_OFFSET_MARK : CALIBRATE_OFFSET_MARK

        CALIBRATE_OFFSET_MARK : enter / #123; UpdateHardwareState()#59; #125;

        CALIBRATE_OFFSET_SPACE

        CALIBRATE_OFFSET_SPACE : CALIBRATE_OFFSET_SPACE

        CALIBRATE_OFFSET_SPACE : enter / #123; UpdateHardwareState()#59; #125;

}

state NORMAL_STATES {

        CW_RECEIVE

        CW_RECEIVE : CW_RECEIVE

        CW_RECEIVE : enter / #123; UpdateHardwareState()#59; #125;

        CW_RECEIVE : 1. do / #123; markCount_ms = 0#59; #125;

        SSB_TRANSMIT

        SSB_TRANSMIT : SSB_TRANSMIT

        SSB_TRANSMIT : enter / #123; UpdateHardwareState()#59; #125;

        CW_TRANSMIT_MARK

        CW_TRANSMIT_MARK : CW_TRANSMIT_MARK

        CW_TRANSMIT_MARK : enter / #123; UpdateHardwareState()#59; #125;

        CW_TRANSMIT_SPACE

        CW_TRANSMIT_SPACE : CW_TRANSMIT_SPACE

        CW_TRANSMIT_SPACE : enter / #123; ModeCWTransmitSpaceEnter()#59; #125;

        CW_TRANSMIT_SPACE : enter / #123; spaceCount_ms = 0#59; #125;

        CW_TRANSMIT_SPACE : 1. do / #123; spaceCount_ms++#59; #125;

        CW_TRANSMIT_DIT_MARK

        CW_TRANSMIT_DIT_MARK : CW_TRANSMIT_DIT_MARK

        CW_TRANSMIT_DIT_MARK : enter / #123; UpdateHardwareState()#59; #125;

        CW_TRANSMIT_DIT_MARK : enter / #123; markCount_ms = 0#59; #125;

        CW_TRANSMIT_DIT_MARK : 1. do / #123; markCount_ms++#59;\nspaceCount_ms = 0#59; #125;

        CW_TRANSMIT_KEYER_SPACE

        CW_TRANSMIT_KEYER_SPACE : CW_TRANSMIT_KEYER_SPACE

        CW_TRANSMIT_KEYER_SPACE : enter / #123; ModeCWTransmitSpaceEnter()#59; #125;

        CW_TRANSMIT_KEYER_SPACE : enter / #123; spaceCount_ms = 0#59; #125;

        CW_TRANSMIT_KEYER_SPACE : 1. do / #123; spaceCount_ms++#59;\nmarkCount_ms = 0#59; #125;

        CW_TRANSMIT_KEYER_WAIT

        CW_TRANSMIT_KEYER_WAIT : CW_TRANSMIT_KEYER_WAIT

        CW_TRANSMIT_KEYER_WAIT : enter / #123; spaceCount_ms = 0#59; #125;

        CW_TRANSMIT_KEYER_WAIT : 1. do / #123; spaceCount_ms++#59;\nmarkCount_ms = 0#59; #125;

        CW_TRANSMIT_DAH_MARK

        CW_TRANSMIT_DAH_MARK : CW_TRANSMIT_DAH_MARK

        CW_TRANSMIT_DAH_MARK : enter / #123; UpdateHardwareState()#59; #125;

        CW_TRANSMIT_DAH_MARK : enter / #123; markCount_ms = 0#59; #125;

        CW_TRANSMIT_DAH_MARK : 1. do / #123; markCount_ms++#59;\nspaceCount_ms = 0#59; #125;

        %% Initial state name as "." so that it fits in black circle shape.
        %% See https://github.com/StateSmith/StateSmith/issues/404
        state "." as NORMAL_STATES.(InitialState)

        state DIGITAL_STATES {

                %% Initial state name as "." so that it fits in black circle shape.
                %% See https://github.com/StateSmith/StateSmith/issues/404
                state "." as DIGITAL_STATES.(InitialState)

                DIGITAL_RECEIVE

                DIGITAL_RECEIVE : DIGITAL_RECEIVE

                DIGITAL_RECEIVE : enter / #123; UpdateHardwareState()#59; #125;

                DIGITAL_TRANSMIT

                DIGITAL_TRANSMIT : DIGITAL_TRANSMIT

                DIGITAL_TRANSMIT : enter / #123; UpdateHardwareState()#59; #125;

        }

        SSB_RECEIVE

        SSB_RECEIVE : SSB_RECEIVE

        SSB_RECEIVE : enter / #123; UpdateHardwareState()#59; #125;

}

%% Initial state name as "." so that it fits in black circle shape.
%% See https://github.com/StateSmith/StateSmith/issues/404
state "." as ROOT.(InitialState)

CALIBRATE_FREQUENCY --> CALIBRATION_STATES.(ExitPoint)(done) : CALIBRATE_EXIT

CALIBRATE_RX_IQ --> CALIBRATION_STATES.(ExitPoint)(done) : CALIBRATE_EXIT

CALIBRATE_TX_IQ_SPACE --> CALIBRATION_STATES.(ExitPoint)(done) : CALIBRATE_EXIT

CALIBRATE_TX_IQ_SPACE --> CALIBRATE_TX_IQ_MARK : PTT_PRESSED

CALIBRATION_STATES.(ExitPoint)(done) --> NORMAL_STATES

CALIBRATE_TX_IQ_MARK --> CALIBRATE_TX_IQ_SPACE : PTT_RELEASED

CALIBRATE_POWER_SPACE --> CALIBRATE_POWER_MARK : PTT_PRESSED

CALIBRATE_POWER_SPACE --> CALIBRATE_OFFSET_SPACE : OFFSET_START

CALIBRATE_POWER_SPACE --> CALIBRATION_STATES.(ExitPoint)(done) : CALIBRATE_EXIT

CALIBRATE_POWER_MARK --> CALIBRATE_POWER_SPACE : PTT_RELEASED

CALIBRATE_POWER_MARK --> CALIBRATE_POWER_SPACE : OFFSET_END

CALIBRATE_OFFSET_MARK --> CALIBRATE_OFFSET_SPACE : PTT_RELEASED

CALIBRATE_OFFSET_MARK --> CALIBRATE_POWER_SPACE : OFFSET_END

CALIBRATE_OFFSET_SPACE --> CALIBRATION_STATES.(ExitPoint)(done) : CALIBRATE_EXIT

CALIBRATE_OFFSET_SPACE --> CALIBRATE_OFFSET_MARK : PTT_PRESSED

CALIBRATE_OFFSET_SPACE --> CALIBRATE_POWER_SPACE : OFFSET_END

NORMAL_STATES --> CALIBRATE_FREQUENCY : CALIBRATE_FREQUENCY

NORMAL_STATES --> CALIBRATE_RX_IQ : CALIBRATE_RX_IQ

NORMAL_STATES --> CALIBRATE_TX_IQ_SPACE : CALIBRATE_TX_IQ

NORMAL_STATES --> CALIBRATE_POWER_SPACE : CALIBRATE_POWER

CW_RECEIVE --> SSB_RECEIVE : TO_SSB_MODE

CW_RECEIVE --> CW_TRANSMIT_MARK : KEY_PRESSED [IsTxAllowed()]

CW_RECEIVE --> CW_TRANSMIT_DAH_MARK : DAH_PRESSED [IsTxAllowed()]

CW_RECEIVE --> CW_TRANSMIT_DIT_MARK : DIT_PRESSED [IsTxAllowed()]

CW_RECEIVE --> DIGITAL_STATES : TO_DIGITAL_MODE

SSB_TRANSMIT --> SSB_RECEIVE : PTT_RELEASED

CW_TRANSMIT_MARK --> CW_TRANSMIT_SPACE : KEY_RELEASED

CW_TRANSMIT_SPACE --> CW_TRANSMIT_MARK : KEY_PRESSED

CW_TRANSMIT_SPACE --> CW_RECEIVE : do [spaceCount_ms >= waitDuration_ms]

CW_TRANSMIT_DIT_MARK --> CW_TRANSMIT_KEYER_SPACE : do [markCount_ms >= ditDuration_ms]

CW_TRANSMIT_KEYER_SPACE --> CW_TRANSMIT_KEYER_WAIT : do [spaceCount_ms >= ditDuration_ms]

CW_TRANSMIT_KEYER_WAIT --> CW_RECEIVE : do [spaceCount_ms >= waitDuration_ms]

CW_TRANSMIT_KEYER_WAIT --> CW_TRANSMIT_DIT_MARK : DIT_PRESSED

CW_TRANSMIT_KEYER_WAIT --> CW_TRANSMIT_DAH_MARK : DAH_PRESSED

CW_TRANSMIT_DAH_MARK --> CW_TRANSMIT_KEYER_SPACE : do [markCount_ms >= 3*ditDuration_ms]

NORMAL_STATES.(InitialState) --> SSB_RECEIVE

DIGITAL_STATES.(InitialState) --> DIGITAL_RECEIVE

DIGITAL_RECEIVE --> DIGITAL_TRANSMIT : PTT_PRESSED [IsTxAllowed()]

DIGITAL_RECEIVE --> SSB_RECEIVE : TO_SSB_MODE

DIGITAL_RECEIVE --> CW_RECEIVE : TO_CW_MODE

DIGITAL_TRANSMIT --> DIGITAL_RECEIVE : PTT_RELEASED

SSB_RECEIVE --> SSB_TRANSMIT : PTT_PRESSED [IsTxAllowed()]

SSB_RECEIVE --> DIGITAL_STATES : TO_DIGITAL_MODE

SSB_RECEIVE --> CW_RECEIVE : TO_CW_MODE

ROOT.(InitialState) --> NORMAL_STATES