diff --git a/ports/stm32f4xx/dlmstp.c b/ports/stm32f4xx/dlmstp.c index 8472bf37..7703649c 100644 --- a/ports/stm32f4xx/dlmstp.c +++ b/ports/stm32f4xx/dlmstp.c @@ -175,6 +175,12 @@ static unsigned ReceivePDUCount; static volatile struct dlmstp_packet PDU_Buffer[MSTP_PDU_PACKET_COUNT]; static RING_BUFFER PDU_Queue; +/* Callback function to be called every time we receive a preamble */ +static dlmstp_hook_frame_rx_start_cb Preamble_Callback = NULL; + +/* Callback function to be called every time we receive a frame */ +static dlmstp_hook_frame_rx_complete_cb Frame_Rx_Callback = NULL; + bool dlmstp_init(char *ifname) { ifname = ifname; @@ -442,6 +448,11 @@ static void MSTP_Receive_Frame_FSM(void) /* Preamble1 */ /* receive the remainder of the frame. */ Receive_State = MSTP_RECEIVE_STATE_PREAMBLE; + + /* if a frame-start callback was provided, call it */ + if (Preamble_Callback != NULL) { + Preamble_Callback(); + } } } break; @@ -552,6 +563,13 @@ static void MSTP_Receive_Frame_FSM(void) /* NotForUs */ MSTP_Flag.ReceivedValidFrameNotForUs = true; } + /* if a frame-receipt callback was provided, call */ + /* it for this frame */ + if (Frame_Rx_Callback != NULL) { + Frame_Rx_Callback(SourceAddress, + DestinationAddress, FrameType, InputBuffer, + DataLength); + } /* wait for the start of the next frame. */ Receive_State = MSTP_RECEIVE_STATE_IDLE; } else { @@ -630,6 +648,12 @@ static void MSTP_Receive_Frame_FSM(void) /* NotForUs */ MSTP_Flag.ReceivedValidFrameNotForUs = true; } + /* if a frame-receipt callback was provided, call it */ + /* for this frame */ + if (Frame_Rx_Callback != NULL) { + Frame_Rx_Callback(SourceAddress, DestinationAddress, + FrameType, InputBuffer, DataLength); + } } else { MSTP_Flag.ReceivedInvalidFrame = true; @@ -1364,9 +1388,6 @@ uint16_t dlmstp_receive( MSTP_Flag.ReceivedValidFrameNotForUs = false; ReceiveFrameCount++; } - if (MSTP_Flag.ReceivedValidFrame) { - ReceiveFrameCount++; - } if (MSTP_Flag.ReceivedInvalidFrame) { ReceiveFrameCount++; } @@ -1376,6 +1397,7 @@ uint16_t dlmstp_receive( MSTP_Flag.ReceivedValidFrameNotForUs = false; } else if (MSTP_Flag.ReceivedValidFrame) { if (rs485_turnaround_elapsed()) { + ReceiveFrameCount++; if ((This_Station > 127) && (This_Station < 255)) { MSTP_Slave_Node_FSM(); } else if (This_Station <= 127) { @@ -1513,3 +1535,14 @@ uint8_t dlmstp_max_master_limit(void) { return 127; } + +void dlmstp_set_frame_rx_complete_callback( + dlmstp_hook_frame_rx_complete_cb cb_func) +{ + Frame_Rx_Callback = cb_func; +} + +void dlmstp_set_frame_rx_start_callback(dlmstp_hook_frame_rx_start_cb cb_func) +{ + Preamble_Callback = cb_func; +} diff --git a/src/bacnet/datalink/dlmstp.h b/src/bacnet/datalink/dlmstp.h index db97d1d0..1807eb5f 100644 --- a/src/bacnet/datalink/dlmstp.h +++ b/src/bacnet/datalink/dlmstp.h @@ -44,6 +44,17 @@ typedef struct dlmstp_packet { uint8_t pdu[DLMSTP_MPDU_MAX]; /* packet */ } DLMSTP_PACKET; +/* callback to signify the receipt of a preamble */ +typedef void (*dlmstp_hook_frame_rx_start_cb)(); + +/* callback on for receiving every valid frame */ +typedef void (*dlmstp_hook_frame_rx_complete_cb)( + uint8_t src, + uint8_t dest, + uint8_t mstp_msg_type, + uint8_t * pdu, + uint16_t pdu_len); + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -141,6 +152,25 @@ extern "C" { BACNET_STACK_EXPORT uint8_t dlmstp_max_master_limit(void); + /* Set the callback function to be called on every valid received frame */ + /* This is not necessary for normal usage, but is helpful if the caller */ + /* needs to monitor traffic on the MS/TP bus */ + /* The specified callback function should execute quickly so as to avoid */ + /* interfering with bus timing */ + BACNET_STACK_EXPORT + void dlmstp_set_frame_rx_complete_callback( + dlmstp_hook_frame_rx_complete_cb cb_func); + + /* Set the callback function to be called every time the start of a */ + /* frame is detected. This is not necessary for normal usage, but is */ + /* helpful if the caller needs to know when a frame begins for timing */ + /* (timing is heavily dependent upon baud rate and the period with */ + /* which dlmstp_receive is called) */ + /* The specified callback function should execute quickly so as to avoid */ + /* interfering with bus timing */ + BACNET_STACK_EXPORT + void dlmstp_set_frame_rx_start_callback( + dlmstp_hook_frame_rx_start_cb cb_func); #ifdef __cplusplus }