The DMX512 / RDM Transceiver.
This module handles communications on the RS485 line.
The general model is that a client initiates a transceiver operation, passing in a token (cookie) to identify the operation. When the transceiver operation completes, the appropriate TransceiverEventCallback is run, which receives the same token and any operation-specific data. This allows the client to associate the callback with the original request that generated the event.
If a TRANSCEIVER_NO_NOTIFICATION is used for the token, the callback will not be run.
The transceiver can operate in various modes:
Since we may be in the middle of performing an operation when the mode change request occurs, the Transceiver_SetMode() function takes a token argument. When the mode change completes, a T_OP_MODE_CHANGE event will occur.
In controller mode, clients can send E1.11 frames by calling one of:
In responder mode, the TransceiverEventCallback will be run when a frame is received. The handler should call Transceiver_QueueRDMResponse() to send a response frame. See Responder State Machine.
This puts the E1.11 driver circuit into loopback mode and allows the client to call Transceiver_QueueSelfTest(). The self test operation will send a single byte which can be used to confirm the driver circuit is working correctly.
Files | |
file | transceiver.h |
The DMX512 / RDM Transceiver. | |
file | transceiver_timing.h |
The timing constants for the 485 Transceiver. | |
Data Structures | |
union | TransceiverTiming |
The timing measurements for an operation. More... | |
struct | TransceiverEvent |
Information about a transceiver event. More... | |
struct | TransceiverHardwareSettings |
The hardware settings to use for the Transceiver. More... | |
Macros | |
#define | MINIMUM_TX_BREAK_TIME 44u |
The minimum break time the user can configure, in microseconds. More... | |
#define | MAXIMUM_TX_BREAK_TIME 800u |
The maximum break time the user can configure, in microseconds. More... | |
#define | MINIMUM_TX_MARK_TIME 4u |
The minimum mark time the user can configure, in microseconds. More... | |
#define | MAXIMUM_TX_MARK_TIME 800u |
The maximum mark time the user can configure, in microseconds. More... | |
#define | CONTROLLER_RX_BREAK_TIME_MIN 880u |
The minimum break time for controllers to receive. More... | |
#define | CONTROLLER_RX_BREAK_TIME_MAX 3520u |
The maximum break time for controllers to receive. More... | |
#define | CONTROLLER_RX_MARK_TIME_MAX 880u |
The maximum mark time for controllers to receive. More... | |
#define | CONTROLLER_MIN_BREAK_TO_BREAK 13u |
The minimum break-to-break time at a controller. More... | |
#define | CONTROLLER_DUB_BACKOFF 58u |
The back off time for a DUB command. More... | |
#define | CONTROLLER_BROADCAST_BACKOFF 2u |
The back off time for a broadcast command. More... | |
#define | CONTROLLER_MISSING_RESPONSE_BACKOFF 30u |
The back off time for a missing response. More... | |
#define | CONTROLLER_NON_RDM_BACKOFF 2u |
The back off time for a non-RDM command. More... | |
#define | RESPONDER_RX_BREAK_TIME_MIN 880u |
The minimum break time for responders to receive. More... | |
#define | RESPONDER_RX_BREAK_TIME_MAX 10000u |
The maximum break time for responders to receive. More... | |
#define | MINIMUM_RESPONDER_DELAY 1760u |
The minimum RDM responder delay in 10ths of a microsecond, Table 3-4, E1.20. | |
#define | MAXIMUM_RESPONDER_DELAY 20000u |
The maximum RDM responder delay in 10ths of a microsecond. Table 3-4, E1.20. | |
#define | RESPONDER_RX_MARK_TIME_MIN 80u |
The minimum mark time for responders to receive. More... | |
#define | RESPONDER_RX_MARK_TIME_MAX 10000u |
The maximum mark time for responders to receive. More... | |
#define | RESPONDER_RDM_INTERSLOT_TIMEOUT 21u |
The inter-slot timeout for RDM frames. More... | |
#define | RESPONDER_DMX_INTERSLOT_TIMEOUT 10000u |
The inter-slot timeout for DMX and other ASC frames. More... | |
#define | CONTROLLER_RECEIVE_RDM_INTERSLOT_TIMEOUT 21u |
The inter-slot timeout for RDM frames. More... | |
Typedefs | |
typedef bool(* | TransceiverEventCallback )(const TransceiverEvent *event) |
The callback run when a transceiver event occurs. More... | |
Enumerations | |
enum | TransceiverMode { T_MODE_CONTROLLER, T_MODE_RESPONDER, T_MODE_SELF_TEST, T_MODE_LAST } |
The operating modes of the transceiver. More... | |
enum | TransceiverOperation { T_OP_TX_ONLY, T_OP_RDM_DUB, T_OP_RDM_BROADCAST, T_OP_RDM_WITH_RESPONSE, T_OP_RX, T_OP_MODE_CHANGE, T_OP_SELF_TEST } |
Identifies the various types of transceiver operation. More... | |
enum | TransceiverOperationResult { T_RESULT_OK, T_RESULT_TX_ERROR, T_RESULT_RX_DATA, T_RESULT_RX_TIMEOUT, T_RESULT_RX_INVALID, T_RESULT_RX_START_FRAME, T_RESULT_RX_CONTINUE_FRAME, T_RESULT_RX_FRAME_TIMEOUT, T_RESULT_CANCELLED, T_RESULT_SELF_TEST_FAILED } |
The result of an operation. More... | |
Functions | |
void | Transceiver_Initialize (const TransceiverHardwareSettings *settings, TransceiverEventCallback tx_callback, TransceiverEventCallback rx_callback) |
Initialize the transceiver. More... | |
bool | Transceiver_SetMode (TransceiverMode mode, int16_t token) |
Change the operating mode of the transceiver. More... | |
TransceiverMode | Transceiver_GetMode () |
The operating mode of the transceiver. More... | |
void | Transceiver_Tasks () |
Perform the periodic transceiver tasks. More... | |
bool | Transceiver_QueueDMX (int16_t token, const uint8_t *data, unsigned int size) |
Queue a DMX frame for transmission. More... | |
bool | Transceiver_QueueASC (int16_t token, uint8_t start_code, const uint8_t *data, unsigned int size) |
Queue an alternate start code (ASC) frame for transmission. More... | |
bool | Transceiver_QueueRDMDUB (int16_t token, const uint8_t *data, unsigned int size) |
Queue an RDM DUB operation. More... | |
bool | Transceiver_QueueRDMRequest (int16_t token, const uint8_t *data, unsigned int size, bool is_broadcast) |
Queue an RDM Get / Set operation. More... | |
bool | Transceiver_QueueRDMResponse (bool include_break, const IOVec *iov, unsigned int iov_count) |
Queue an RDM Response. More... | |
bool | Transceiver_QueueSelfTest (int16_t token) |
Schedule a loopback self test. | |
void | Transceiver_Reset () |
Reset the transceiver state. More... | |
bool | Transceiver_SetBreakTime (uint16_t break_time_us) |
Set the break (space) time. More... | |
uint16_t | Transceiver_GetBreakTime () |
Return the current configured break time. More... | |
bool | Transceiver_SetMarkTime (uint16_t mark_time_us) |
Set the mark-after-break (MAB) time. More... | |
uint16_t | Transceiver_GetMarkTime () |
Return the current configured mark-after-break (MAB) time. More... | |
bool | Transceiver_SetRDMBroadcastTimeout (uint16_t delay) |
Set the controller timeout for broadcast RDM commands. More... | |
uint16_t | Transceiver_GetRDMBroadcastTimeout () |
Return the current controller timeout for broadcast RDM commands. More... | |
bool | Transceiver_SetRDMResponseTimeout (uint16_t delay) |
Set the controller's RDM response timeout. More... | |
uint16_t | Transceiver_GetRDMResponseTimeout () |
Return the controller's RDM response timeout. More... | |
bool | Transceiver_SetRDMDUBResponseLimit (uint16_t limit) |
Set the maximum time allowed for a DUB response. More... | |
uint16_t | Transceiver_GetRDMDUBResponseLimit () |
Return the Controller DUB response timeout. More... | |
bool | Transceiver_SetRDMResponderDelay (uint16_t delay) |
Configure the delay after the end of the controller's packet before the responder will transmit the reply. More... | |
uint16_t | Transceiver_GetRDMResponderDelay () |
Return the RDM responder delay. More... | |
bool | Transceiver_SetRDMResponderJitter (uint16_t max_jitter) |
Configure the jitter added to the responder delay. More... | |
uint16_t | Transceiver_GetRDMResponderJitter () |
Return the RDM responder jitter. More... | |
Variables | |
const int16_t | TRANSCEIVER_NO_NOTIFICATION |
Suppress event notifications. More... | |
#define CONTROLLER_BROADCAST_BACKOFF 2u |
The back off time for a broadcast command.
Measured in 10ths of a millisecond. The value is from line 6 of Table 3-2 in E1.20. In this case we round 176us to 0.2 ms.
#define CONTROLLER_DUB_BACKOFF 58u |
The back off time for a DUB command.
Measured in 10ths of a millisecond. The value is from line 2 of Table 3-2 in E1.20.
#define CONTROLLER_MIN_BREAK_TO_BREAK 13u |
The minimum break-to-break time at a controller.
Measured in 10ths of a millisecond. The value is from Table 6 in E1.11 (2008). In this case we round 1.204ms to 1.3 ms.
#define CONTROLLER_MISSING_RESPONSE_BACKOFF 30u |
The back off time for a missing response.
Measured in 10ths of a millisecond. The value is from line 5 of Table 3-2 in E1.20.
#define CONTROLLER_NON_RDM_BACKOFF 2u |
The back off time for a non-RDM command.
Measured in 10ths of a millisecond. The value is from line 7 of Table 3-2 in E1.20. In this case we round 176us to 0.2 ms.
#define CONTROLLER_RECEIVE_RDM_INTERSLOT_TIMEOUT 21u |
The inter-slot timeout for RDM frames.
Measured in 10ths of a millisecond. The value is from line 2 of Table 3-1 in E1.20.
#define CONTROLLER_RX_BREAK_TIME_MAX 3520u |
The maximum break time for controllers to receive.
Measured in 10ths of a microsecond. The value is from line 2 of Table 3-1 in E1.20.
#define CONTROLLER_RX_BREAK_TIME_MIN 880u |
The minimum break time for controllers to receive.
Measured in 10ths of a microsecond. The value is from line 2 of Table 3-1 in E1.20.
Note that some responders, like say the Robin 600 Spot, have a very short low before the actual break. This is probably the transceiver turning around and lasts on the order of 200nS.
#define CONTROLLER_RX_MARK_TIME_MAX 880u |
The maximum mark time for controllers to receive.
Measured in 10ths of a microsecond. The value is from line 2 of Table 3-1 in E1.20.
#define MAXIMUM_TX_BREAK_TIME 800u |
The maximum break time the user can configure, in microseconds.
This needs to be kept within what a 16-bit timer can support. We'll probably need to change this if the clock speed increases.
#define MAXIMUM_TX_MARK_TIME 800u |
The maximum mark time the user can configure, in microseconds.
This needs to be kept within what a 16-bit timer can support. We'll probably need to change this if the clock speed increases.
#define MINIMUM_TX_BREAK_TIME 44u |
The minimum break time the user can configure, in microseconds.
DMX1990 was 88us and later versions raised this to 92us. We allow down to 44us because Sean says it's useful for testing.
#define MINIMUM_TX_MARK_TIME 4u |
The minimum mark time the user can configure, in microseconds.
DMX1986 apparently allows a 4us mark time.
#define RESPONDER_DMX_INTERSLOT_TIMEOUT 10000u |
The inter-slot timeout for DMX and other ASC frames.
Measured in 10ths of a millisecond. The value is from Table 6 of E1.11-2008
#define RESPONDER_RDM_INTERSLOT_TIMEOUT 21u |
The inter-slot timeout for RDM frames.
Measured in 10ths of a millisecond. The value is from line 1 of Table 3-3 in E1.20.
#define RESPONDER_RX_BREAK_TIME_MAX 10000u |
The maximum break time for responders to receive.
Measured in 10ths of a millisecond. The value is from line 1 of Table 3-3 in E1.20.
#define RESPONDER_RX_BREAK_TIME_MIN 880u |
The minimum break time for responders to receive.
Measured in 10ths of a microsecond. The value is from line 1 of Table 3-3 in E1.20.
#define RESPONDER_RX_MARK_TIME_MAX 10000u |
The maximum mark time for responders to receive.
Measured in 10ths of a millisecond. The value is from line 1 of Table 3-3 in E1.20.
#define RESPONDER_RX_MARK_TIME_MIN 80u |
The minimum mark time for responders to receive.
Measured in 10ths of a microsecond. The value is from line 1 of Table 3-3 in E1.20.
typedef bool(* TransceiverEventCallback)(const TransceiverEvent *event) |
The callback run when a transceiver event occurs.
The pointer is valid for the lifetime of the function call.
enum TransceiverMode |
enum TransceiverOperation |
Identifies the various types of transceiver operation.
The result of an operation.
uint16_t Transceiver_GetBreakTime | ( | ) |
Return the current configured break time.
uint16_t Transceiver_GetMarkTime | ( | ) |
Return the current configured mark-after-break (MAB) time.
TransceiverMode Transceiver_GetMode | ( | ) |
The operating mode of the transceiver.
uint16_t Transceiver_GetRDMBroadcastTimeout | ( | ) |
Return the current controller timeout for broadcast RDM commands.
uint16_t Transceiver_GetRDMDUBResponseLimit | ( | ) |
Return the Controller DUB response timeout.
uint16_t Transceiver_GetRDMResponderDelay | ( | ) |
Return the RDM responder delay.
uint16_t Transceiver_GetRDMResponderJitter | ( | ) |
Return the RDM responder jitter.
uint16_t Transceiver_GetRDMResponseTimeout | ( | ) |
Return the controller's RDM response timeout.
void Transceiver_Initialize | ( | const TransceiverHardwareSettings * | settings, |
TransceiverEventCallback | tx_callback, | ||
TransceiverEventCallback | rx_callback | ||
) |
Initialize the transceiver.
settings | The settings to use for the transceiver. |
tx_callback | The callback to run when a transceiver TX event occurs. |
rx_callback | The callback to run when a transceiver RX event occurs. |
If PIPELINE_TRANSCEIVER_TX_EVENT is defined in app_pipeline.h, the macro will override the value of tx_callback. If PIPELINE_TRANSCEIVER_RX_EVENT is defined in app_pipeline.h, the macro will override the value of rx_callback.
bool Transceiver_QueueASC | ( | int16_t | token, |
uint8_t | start_code, | ||
const uint8_t * | data, | ||
unsigned int | size | ||
) |
Queue an alternate start code (ASC) frame for transmission.
token | The token for this operation. |
start_code | the alternate start code. |
data | The ASC data, excluding the start code. |
size | The size of the data, excluding the start code. |
bool Transceiver_QueueDMX | ( | int16_t | token, |
const uint8_t * | data, | ||
unsigned int | size | ||
) |
Queue a DMX frame for transmission.
token | The token for this operation. |
data | The DMX data, excluding the start code. |
size | The size of the DMX data, excluding the start code. |
bool Transceiver_QueueRDMDUB | ( | int16_t | token, |
const uint8_t * | data, | ||
unsigned int | size | ||
) |
Queue an RDM DUB operation.
token | The token for this operation. |
data | The RDM DUB data, excluding the start code. |
size | The size of the RDM DUB data, excluding the start code. |
bool Transceiver_QueueRDMRequest | ( | int16_t | token, |
const uint8_t * | data, | ||
unsigned int | size, | ||
bool | is_broadcast | ||
) |
Queue an RDM Get / Set operation.
token | The token for this operation. |
data | The RDM data, excluding the start code. |
size | The size of the RDM data, excluding the start code. |
is_broadcast | True if this is a broadcast request. |
bool Transceiver_QueueRDMResponse | ( | bool | include_break, |
const IOVec * | iov, | ||
unsigned int | iov_count | ||
) |
Queue an RDM Response.
include_break | true if this response requires a break |
iov | The data to send in the response |
iov_count | The number of IOVecs. |
void Transceiver_Reset | ( | ) |
Reset the transceiver state.
This can be used to recover from an error. The line will be placed back into a MARK state.
bool Transceiver_SetBreakTime | ( | uint16_t | break_time_us | ) |
Set the break (space) time.
break_time_us | the break time in microseconds, values are 44 to 800 inclusive. |
The default time is 176 uS. Table 6 in E1.11 lists the minimum break time as 92uS but the 1990 standard allows 88uS. We go down to 44 uS for testing purposes. Table 3-1 in E1.20 lists the minimum break as 176uS and the maximum as 352uS.
bool Transceiver_SetMarkTime | ( | uint16_t | mark_time_us | ) |
Set the mark-after-break (MAB) time.
mark_time_us | the mark time in microseconds, values are 4 to 800 inclusive. |
The default is 12uS. Table 6 in E1.11 allows 12uS to 1s. Table 3-1 in E1.20 allows 12 to 88uS. We go down to 4 uS for testing purposes.
bool Transceiver_SetMode | ( | TransceiverMode | mode, |
int16_t | token | ||
) |
Change the operating mode of the transceiver.
mode | the new operating mode. |
token | The token passed to the TransceiverEventCallback when the mode change completes. |
After any in-progress operation completes, then next call to Transceiver_Tasks() will result in the mode change.
bool Transceiver_SetRDMBroadcastTimeout | ( | uint16_t | delay | ) |
Set the controller timeout for broadcast RDM commands.
delay | the time to wait for a broadcast response, in 10ths of a millisecond. Valid values are 0 to 50 (0 to 5ms). |
With the exception of a DUB, an RDM controller usually doesn't listen for responses after sending a broadcast command. However for testing purposes we want to be able to listen for responders that incorrectly reply to non-DUB broadcasts.
bool Transceiver_SetRDMDUBResponseLimit | ( | uint16_t | limit | ) |
Set the maximum time allowed for a DUB response.
limit | the maximum time to wait from the start of the DUB response until the end, in 10ths of a microseconds. Valid values are 10000 - 35000 (1 - 3.5ms). Values < 28000 are outside the specification but may be used for testing. |
The default value is 29000 (2.9mS), see Line 3, Table 3-3, E1.20.
By setting the value less than 29000, we can cause responders that are at the limits of the specification to fail. By setting the value to more than 29000, we can support responders that are out-of-spec.
bool Transceiver_SetRDMResponderDelay | ( | uint16_t | delay | ) |
Configure the delay after the end of the controller's packet before the responder will transmit the reply.
delay | the delay between the end-of-packet and transmitting the responder, in 10ths of a microseconds. Valid values are 1760 - 20000 (0.176 - 2ms). |
The default value is 1760 (176uS), see Table 3-4, E1.20.
bool Transceiver_SetRDMResponderJitter | ( | uint16_t | max_jitter | ) |
Configure the jitter added to the responder delay.
max_jitter | the maximum jitter in 10ths of a microsecond. Set to 0 to disable jitter. Valid values are 0 to (20000 - Responder Delay). |
The default value is 0.
bool Transceiver_SetRDMResponseTimeout | ( | uint16_t | delay | ) |
Set the controller's RDM response timeout.
delay | the time to wait in 10ths of a millisecond. Valid values are 10 - 50 (1 - 5ms). Values < 28 are outside the specification but may be used for testing. |
This response timeout is the time the controller waits for an RDM response before considering the response missing. This is used for both DISCOVERY and GET/SET commands. The limits for broadcast commands is controlled with Transceiver_SetRDMBroadcastTimeout().
The default value is 28 (2.8mS), see Lines 1 & 3, Table 3-2, E1.20.
By setting the value less than 28, we can cause responders that are at the limits of the specification to fail. By setting the value more than 28, we can accommodate responders that are out-of-spec.
void Transceiver_Tasks | ( | ) |
Perform the periodic transceiver tasks.
This should be called in the main event loop.
const int16_t TRANSCEIVER_NO_NOTIFICATION |
Suppress event notifications.
This value can be used as a token to avoid the event handler notification.