Added MS/TP automatic baudrate detection option into the core MS/TP state machine. (#900)
This commit is contained in:
+109
-7
@@ -648,7 +648,9 @@ bool MSTP_Master_Node_FSM(struct mstp_port_struct_t *mstp_port)
|
||||
}
|
||||
switch (mstp_port->master_state) {
|
||||
case MSTP_MASTER_STATE_INITIALIZE:
|
||||
if (mstp_port->ZeroConfigEnabled) {
|
||||
if (mstp_port->CheckAutoBaud) {
|
||||
MSTP_Auto_Baud_FSM(mstp_port);
|
||||
} else if (mstp_port->ZeroConfigEnabled) {
|
||||
MSTP_Zero_Config_FSM(mstp_port);
|
||||
if (mstp_port->This_Station != 255) {
|
||||
/* indicate that the next station is unknown */
|
||||
@@ -1430,8 +1432,8 @@ static void MSTP_Zero_Config_State_Idle(struct mstp_port_struct_t *mstp_port)
|
||||
return;
|
||||
}
|
||||
if (mstp_port->ReceivedValidFrame) {
|
||||
/* IdleValidFrame */
|
||||
/* next state will clear the frame flags */
|
||||
/* MonitorPFM */
|
||||
mstp_port->Poll_Count = 0;
|
||||
mstp_port->Zero_Config_State = MSTP_ZERO_CONFIG_STATE_LURK;
|
||||
} else if (mstp_port->ReceivedInvalidFrame) {
|
||||
@@ -1482,7 +1484,7 @@ static void MSTP_Zero_Config_State_Lurk(struct mstp_port_struct_t *mstp_port)
|
||||
}
|
||||
}
|
||||
if (src == mstp_port->Zero_Config_Station) {
|
||||
/* AddressInUse */
|
||||
/* LurkAddressInUse */
|
||||
/* monitor PFM from the next address */
|
||||
mstp_port->Zero_Config_Station = MSTP_Zero_Config_Station_Increment(
|
||||
mstp_port->Zero_Config_Station);
|
||||
@@ -1493,23 +1495,23 @@ static void MSTP_Zero_Config_State_Lurk(struct mstp_port_struct_t *mstp_port)
|
||||
/* calculate this node poll count priority number */
|
||||
count = Nmin_poll + mstp_port->Npoll_slot;
|
||||
if (mstp_port->Poll_Count == count) {
|
||||
/* PollResponse */
|
||||
/* LurkPollResponse */
|
||||
MSTP_Create_And_Send_Frame(
|
||||
mstp_port, FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, src,
|
||||
mstp_port->Zero_Config_Station, NULL, 0);
|
||||
mstp_port->Zero_Config_State = MSTP_ZERO_CONFIG_STATE_CLAIM;
|
||||
} else {
|
||||
/* CountFrame */
|
||||
/* LurkCountFrame */
|
||||
mstp_port->Poll_Count++;
|
||||
}
|
||||
}
|
||||
} else if (mstp_port->ReceivedInvalidFrame) {
|
||||
/* InvalidFrame */
|
||||
/* LurkInvalidFrame */
|
||||
mstp_port->ReceivedInvalidFrame = false;
|
||||
} else if (mstp_port->Zero_Config_Silence > 0) {
|
||||
if (mstp_port->SilenceTimer((void *)mstp_port) >
|
||||
mstp_port->Zero_Config_Silence) {
|
||||
/* LurkingTimeout */
|
||||
/* LurkTimeout */
|
||||
mstp_port->Zero_Config_State = MSTP_ZERO_CONFIG_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
@@ -1660,6 +1662,106 @@ void MSTP_Zero_Config_FSM(struct mstp_port_struct_t *mstp_port)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the baud rate for auto-baud at a given index
|
||||
* @param baud_rate_index the index of the baud rate
|
||||
* @return the baud rate at the index
|
||||
* @note A modulo operation keeps the index within the bounds of the array of
|
||||
* baud rates.
|
||||
*/
|
||||
uint32_t MSTP_Auto_Baud_Rate(unsigned baud_rate_index)
|
||||
{
|
||||
const uint32_t TestBaudrates[6] = {
|
||||
115200, 76800, 57600, 38400, 19200, 9600
|
||||
};
|
||||
unsigned index;
|
||||
|
||||
index = baud_rate_index % ARRAY_SIZE(TestBaudrates);
|
||||
|
||||
return TestBaudrates[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The MSTP_AUTO_BAUD_STATE_INIT state is entered when
|
||||
* CheckAutoBaud is TRUE
|
||||
* @param mstp_port the context of the MSTP port
|
||||
*/
|
||||
static void MSTP_Auto_Baud_State_Init(struct mstp_port_struct_t *mstp_port)
|
||||
{
|
||||
uint32_t baud;
|
||||
|
||||
if (!mstp_port) {
|
||||
return;
|
||||
}
|
||||
mstp_port->ValidFrames = 0;
|
||||
mstp_port->BaudRateIndex = 0;
|
||||
mstp_port->ValidFrameTimerReset((void *)mstp_port);
|
||||
baud = MSTP_Auto_Baud_Rate(mstp_port->BaudRateIndex);
|
||||
mstp_port->BaudRateSet(baud);
|
||||
mstp_port->Auto_Baud_State = MSTP_AUTO_BAUD_STATE_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The MSTP_AUTO_BAUD_STATE_IDLE state is entered when
|
||||
* CheckAutoBaud is TRUE and waits for good frames or timeout
|
||||
* @param mstp_port the context of the MSTP port
|
||||
*/
|
||||
static void MSTP_Auto_Baud_State_Idle(struct mstp_port_struct_t *mstp_port)
|
||||
{
|
||||
uint32_t baud;
|
||||
|
||||
if (!mstp_port) {
|
||||
return;
|
||||
}
|
||||
if (mstp_port->ReceivedValidFrame) {
|
||||
/* IdleValidFrame */
|
||||
mstp_port->ValidFrames++;
|
||||
if (mstp_port->ValidFrames >= 4) {
|
||||
/* GoodBaudRate */
|
||||
mstp_port->CheckAutoBaud = false;
|
||||
mstp_port->Auto_Baud_State = MSTP_AUTO_BAUD_STATE_USE;
|
||||
}
|
||||
mstp_port->ReceivedValidFrame = false;
|
||||
} else if (mstp_port->ReceivedInvalidFrame) {
|
||||
/* IdleInvalidFrame */
|
||||
mstp_port->ValidFrames = 0;
|
||||
mstp_port->ReceivedInvalidFrame = false;
|
||||
} else if (mstp_port->ValidFrameTimer((void *)mstp_port) >= 5000UL) {
|
||||
/* IdleTimeout */
|
||||
mstp_port->BaudRateIndex++;
|
||||
baud = MSTP_Auto_Baud_Rate(mstp_port->BaudRateIndex);
|
||||
mstp_port->BaudRateSet(baud);
|
||||
mstp_port->ValidFrames = 0;
|
||||
mstp_port->ValidFrameTimerReset((void *)mstp_port);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Finite State Machine for the Auto Baud Rate process
|
||||
* @param mstp_port the context of the MSTP port
|
||||
*/
|
||||
void MSTP_Auto_Baud_FSM(struct mstp_port_struct_t *mstp_port)
|
||||
{
|
||||
if (!mstp_port) {
|
||||
return;
|
||||
}
|
||||
if (!mstp_port->CheckAutoBaud) {
|
||||
return;
|
||||
}
|
||||
switch (mstp_port->Auto_Baud_State) {
|
||||
case MSTP_AUTO_BAUD_STATE_INIT:
|
||||
MSTP_Auto_Baud_State_Init(mstp_port);
|
||||
break;
|
||||
case MSTP_AUTO_BAUD_STATE_IDLE:
|
||||
MSTP_Auto_Baud_State_Idle(mstp_port);
|
||||
break;
|
||||
case MSTP_AUTO_BAUD_STATE_USE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* note: This_Station assumed to be set with the MAC address */
|
||||
/* note: Nmax_info_frames assumed to be set (default=1) */
|
||||
/* note: Nmax_master assumed to be set (default=127) */
|
||||
|
||||
Reference in New Issue
Block a user