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

View File

@ -124,64 +124,28 @@ bool HwInstance::set_current_state(const States& new_state)
if (new_state == m_current_state) if (new_state == m_current_state)
return true; return true;
m_wait_transition_complete(); m_wait_can_transition();
bool can_transition = false;
std::optional<std::uint8_t> trx_state_value = std::nullopt;
switch (m_current_state) auto is_rx_state = [](const States& s) -> bool
{
return s == States::RX_ON || s == States::RX_AACK_ON;
};
auto is_tx_state = [](const States& s) -> bool
{
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)))
{ {
case States::P_ON: set_current_state(States::PLL_ON);
if (new_state == States::TRX_OFF)
{
trx_state_value = 0x08;
}
break;
case States::TRX_OFF:
if (new_state == States::RX_ON)
{
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;
} }
if (trx_state_value) register_write(Registers::TRX_STATE, std::uint8_t(new_state));
{ m_wait_can_transition();
register_write(Registers::TRX_STATE, *trx_state_value); m_current_state = new_state;
m_wait_transition_complete(); return true;
m_current_state = new_state;
return true;
}
else
{
return false;
}
} }
void HwInstance::set_address_short(const std::uint16_t address) 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); 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) States radio_status = States::TRANSITION_IN_PROGRESS;
do
{ {
int16_t radio_status = register_read(radio::Registers::TRX_STATUS); radio_status = States(register_read(Registers::TRX_STATUS) & 0x1F);
radio_status &= 0x1F;
if (radio_status != 0x1F) } while (radio_status == States::BUSY_RX || radio_status == States::BUSY_TX ||
return; radio_status == States::BUSY_RX_AACK || radio_status == States::BUSY_TX_ARET ||
} radio_status == States::TRANSITION_IN_PROGRESS);
} }
} }