Rework state transition logic to be more complete

This commit is contained in:
Erki 2022-07-14 18:01:52 +03:00
parent e86a5a1cbe
commit 671abd2f7f
2 changed files with 42 additions and 73 deletions

View File

@ -21,17 +21,18 @@ struct HwInstance
enum class States : std::uint8_t
{
P_ON = 0,
BUSY_RX,
BUSY_TX,
RX_ON,
TRX_OFF,
PLL_ON,
SLEEP,
PREP_DEEP_SLEEP,
BUSY_RX_AACK,
BUSY_TX_ARET,
RX_AACK_ON,
TX_ARET_ON
BUSY_RX = 0x1,
BUSY_TX = 0x2,
RX_ON = 0x06,
TRX_OFF = 0x08,
PLL_ON = 0x09,
SLEEP = 0x0F,
PREP_DEEP_SLEEP = 0x10,
BUSY_RX_AACK = 0x11,
BUSY_TX_ARET = 0x12,
RX_AACK_ON = 0x16,
TX_ARET_ON = 0x19,
TRANSITION_IN_PROGRESS = 0x1F
};
static HwInstance* instance();
@ -79,7 +80,7 @@ private:
io_descriptor* m_spi_io = nullptr;
States m_current_state = States::P_ON;
void m_wait_transition_complete();
void m_wait_can_transition();
};
}

View File

@ -124,65 +124,29 @@ bool HwInstance::set_current_state(const States& new_state)
if (new_state == m_current_state)
return true;
m_wait_transition_complete();
bool can_transition = false;
std::optional<std::uint8_t> trx_state_value = std::nullopt;
m_wait_can_transition();
switch (m_current_state)
auto is_rx_state = [](const States& s) -> bool
{
case States::P_ON:
if (new_state == States::TRX_OFF)
return s == States::RX_ON || s == States::RX_AACK_ON;
};
auto is_tx_state = [](const States& s) -> bool
{
trx_state_value = 0x08;
}
break;
case States::TRX_OFF:
if (new_state == States::RX_ON)
return s == States::TX_ARET_ON;
};
if ((is_rx_state(m_current_state) && is_tx_state(new_state))
|| (is_tx_state(m_current_state) && is_rx_state(new_state)))
{
trx_state_value = 0x06;
}
else if (new_state == States::PLL_ON)
{
trx_state_value = 0x09;
}
break;
case States::RX_ON:
if (new_state == States::PLL_ON)
{
trx_state_value = 0x09;
}
else if (new_state == States::TRX_OFF)
{
trx_state_value = 0x08;
}
break;
case States::PLL_ON:
if (new_state == States::RX_ON)
{
trx_state_value = 0x06;
}
else if (new_state == States::TRX_OFF)
{
trx_state_value = 0x08;
}
break;
default:
SKULLC_ASSERT_DEBUG(false);
return false;
set_current_state(States::PLL_ON);
}
if (trx_state_value)
{
register_write(Registers::TRX_STATE, *trx_state_value);
m_wait_transition_complete();
register_write(Registers::TRX_STATE, std::uint8_t(new_state));
m_wait_can_transition();
m_current_state = new_state;
return true;
}
else
{
return false;
}
}
void HwInstance::set_address_short(const std::uint16_t address)
{
@ -280,16 +244,20 @@ void HwInstance::set_csma_seed(const std::uint16_t entropy)
register_write(Registers::CSMA_SEED_1, reg_value);
}
void HwInstance::m_wait_transition_complete()
/**
* @brief Blocks until a state transition can be initiated.
*/
void HwInstance::m_wait_can_transition()
{
while (true)
{
int16_t radio_status = register_read(radio::Registers::TRX_STATUS);
radio_status &= 0x1F;
States radio_status = States::TRANSITION_IN_PROGRESS;
if (radio_status != 0x1F)
return;
}
do
{
radio_status = States(register_read(Registers::TRX_STATUS) & 0x1F);
} while (radio_status == States::BUSY_RX || radio_status == States::BUSY_TX ||
radio_status == States::BUSY_RX_AACK || radio_status == States::BUSY_TX_ARET ||
radio_status == States::TRANSITION_IN_PROGRESS);
}
}