MRBus Core Library Reference
Functions

void mrbusCRC16Initialize(void) (PIC)

The mrbusCRC16Initialize() only exists in the PIC version of the core library. For AVR implementations, a uint16_t type variable set to 0 will work. See mrbusCRC16Update() for details and examples.


uint16_t mrbusCRC16Update(uint16_t crc, uint8_t a) (AVR)

void mrbusCRC16Update(uint8_t a) (PIC)

The mrbusCRC16Update() function will update the current CRC16 with the next byte. The CRC is either stored in an application-level uint16_t in the AVR version or carried in the global uint8_t variables crc16_high and crc16_low in the PIC version.

AVR Example:

/* CRC16 Test for AVR*/
uint16_t crc16 = 0;
for(i=0; i<mrbus_rx_buffer[MRBUS_PKT_LEN]; i++)
{
   if ((i != MRBUS_PKT_CRC_H) && (i != MRBUS_PKT_CRC_L))
      crc16 = mrbusCRC16Update(crc16, mrbus_rx_buffer[i]);
}

if (mrbus_rx_buffer[MRBUS_PKT_CRC_H] == ((crc16>>8) & 0xff)
   && mrbus_rx_buffer[MRBUS_PKT_CRC_L] == (crc16 & 0xff))
   // Packet passes checksum
   pkt_good = 1;

PIC Example:

/* CRC16 Test for PIC */
mrbusCRC16Initialize();
for(i=0; i<mrbus_rx_buffer[MRBUS_PKT_LEN]; i++)
{
   if ((i != MRBUS_PKT_CRC_H) && (i != MRBUS_PKT_CRC_L))
      mrbusCRC16Update(mrbus_rx_buffer[i]);
}

if (mrbus_rx_buffer[MRBUS_PKT_CRC_H] == crc16_h && mrbus_rx_buffer[MRBUS_PKT_CRC_L] == crc16_l)
   // Packet passes checksum
   pkt_good = 1;

void mrbusInit(void)

mrbusInit should be called in the power up initialization section of your application, before interrupts get enabled. It will initialize MRBus-related variables and configure the UART and I/O line needed to use MRBus.


uint8_t mrbusPacketTransmit(void)

mrbusPacketTransmit will compute the checksum on whatever packet is in mrbus_tx_buffer and attempt go through the arbitration phase of transmission. If it is unsuccessful in arbitrating the bus for its node, it return a non-zero value. If it is successful, it will return 0 and set the MRBUS_TX_BUF_ACTIVE bit in mrbus_state.

Note: When mrbusPacketTransmit() returns zero, it does not mean that the entire packet has been sent - only that it has successfully arbitrated the bus and that transmission is guaranteed to complete. The MRBUS_TX_BUF_ACTIVE flag in mrbus_state must be checked to see if packet transmission has completed.


uint8_t mrbusPicRxISR(void)

mrbusPicRxISR() should be called from the PIC's interrupt handler. It provides the functionality needed to handle bytes coming in off the UART, including testing of whether the RCIF and RCIE bits are even set to generate an interrupt off reception.

Note: There is no AVR analog of this function. The AVR core library automatically connects the RX interrupt handler to the appropriate interrupt vector. Because PICs only have a single interrupt vector, it becomes necessary to implement a function to test and handle receive interrupts.


uint8_t mrbusPicTxISR(void)

mrbusPicTxISR() should be called from the PIC's interrupt handler. It provides the functionality needed to handle interrupt-driven transmission through UART, including testing of whether the TXIF and TXIE bits are even set to generate an interrupt off transmission.

Note: There is no AVR analog of this function. The AVR core library automatically connects the TX interrupt handler to the appropriate interrupt vector. Because PICs only have a single interrupt vector, it becomes necessary to implement a function to test and handle transmit interrupts.

Global Application Variables

These variables are used by the application and the core library to communicate with each other.


uint8_t mrbus_activity

mrbus_activity is used by the receive interrupt to communicate to the mrbusPacketTransmit() function that the bus is currently busy, or that a read has completed. It's used to speed up the transmit retry process. It's set to MRBUS_ACTIVITY_IDLE by calls to mrbusPacketTransmit(), and will be upgraded by the receive interrupt handler to MRBUS_ACTIVITY_RX or MRBUS_ACTIVITY_RX_COMPLETE depending on what happens. When it reaches MRBUS_ACTIVITY_RX_COMPLETE, it's safe to retry transmission.

Note: This is mainly for use within the interlocking loop between mrbusPacketTransmit() and waiting due to bus activity.


uint8_t mrbus_priority

mrbus_priority is used for prioritizing packet arbitration. mrbus_priority initializes to 6, and should be left there unless the packet is doing something unique. Lower numbers give greater priority, and higher numbers (up to 11) give lower priority.


uint8_t mrbus_state

mrbus_state is a bitmask that holds the current state of the MRBus-related activities.


uint8_t mrbus_rx_buffer[MRBUS_BUFFER_SIZE]

mrbus_rx_buffer holds the last packet received by the core library. This buffer is valid once the MRBUS_RX_PKT_READY flag in mrbus_state is set, and as long as that flag remains set it will not be overwritten. The packet in the buffer is not guaranteed uncorrupted, or addressed to this particular node. The application is responsible for CRC? checks and address filters. It is guaranteed to be at least the length sent in the packet's length byte.

The core library is double-buffered on receives (with the raw received data going into mrbus_rx_input_buffer). So, while it's important to handle and clear the MRBUS_RX_PKT_READY flag as quickly as is reasonable, another packet can be queuing up from the interrupt routine even while the mrbus_rx_buffer is left unaffected. If a second packet is completely received before the MRBUS_RX_PKT_READY flag is cleared, the new packet will be thrown away.


uint8_t mrbus_tx_buffer[MRBUS_BUFFER_SIZE]

mrbus_tx_buffer holds the packet to be transmitted by the node. The application must only write to this buffer when the MRBUS_TX_BUF_ACTIVE flag in mrbus_state is zero. Otherwise, the core library is still trying to transmit from the buffer and any changes will corrupt the transmission.

The application is responsible for filling in the entire packet except for the two CRC bytes. Those will be calculated by mrbusPacketTransmit() when it's called.

Constants

Packet Byte Offset Constants

These constants define the index in the mrbus_rx_buffer and mrbus_tx_buffer at which fixed data elements reside.

MRBUS_PKT_DEST  = 0
MRBUS_PKT_SRC   = 1 
MRBUS_PKT_LEN   = 2
MRBUS_PKT_CRC_L = 3
MRBUS_PKT_CRC_H = 4
MRBUS_PKT_TYPE  = 5

mrbus_activity States

MRBUS_ACTIVITY_IDLE - Indicates that the bus has been quiet since mrbus_activity was reset to MRBUS_ACTIVITY_IDLE. Numeric value is 0.

MRBUS_ACTIVITY_RX - Indicates that the bus has seen activity of some sort since mrbus_activity was reset to MRBUS_ACTIVITY_IDLE. Numeric value is 1.

MRBUS_ACTIVITY_RX_COMPLETE - Indicates that the bus has seen a successful packet reception since mrbus_activity was set to MRBUS_ACTIVITY_IDLE or to MRBUS_ACTIVITY_RX. Numeric value is 2.


mrbus_state Flags

These flags are binary masks, suitable for binary ands and ors directly with mrbus_state to determine the state of interactions between the core library and the application.

Setting Example: mrbus_state |= MRBUS_TX_PKT_READY

Clearing Example: mrbus_state &= ~MRBUS_RX_PKT_READY

Testing Example: if (mrbus_state & MRBUS_RX_PKT_READY) { /* do stuff */ }

MRBUS_RX_PKT_READY - Indicates that the mrbus_rx_buffer has a new packet in it and is ready for application processing. See the description of mrbus_rx_buffer for more details. Should never be set by the application, but should be cleared by the application as soon as the packet in mrbus_rx_buffer is handled.

MRBUS_TX_PKT_READY - A convenience provided to the application to indicate that the packet in mrbus_tx_buffer is ready to be transmitted. The core library will never set this flag, but will clear it as soon as mrbusPacketTransmit() has successfully arbitrated and packet transmission is assured (but will not yet be complete). The application can use this to communicate from one part of the main loop where transmissions are set up to the actual parts that call mrbusPacketTransmit() that a packet has been created and is in the buffer, ready to go.

MRBUS_TX_BUF_ACTIVE - Indicates that the transmit buffer is currently in use and a transmission is in progress. mrbusPacketTransmit() sets this bit after arbitration is successful and packet transmission assured. The bit is cleared once the entire packet has been transmitted and it is once again safe for the application to write to mrbus_tx_buffer. Thus, all application sections that write to mrbus_tx_buffer should first check if MRBUS_TX_BUF_ACTIVE is set, and if so, wait or skip accessing the transmit buffer.


Miscellaneous Constants

MRBUS_BUFFER_SIZE - The maximum size of a MRBus packet, and the size of the mrbus_rx_buffer, mrbus_tx_buffer, and mrbus_rx_input_buffer.

Compiler Defines

These items can be defined at preprocessing / compilation time to change the behaviour of the core library.


MRBUS_DISABLE_LOOPBACK

Define MRBUS_DISABLE_LOOPBACK at compilation time to prevent the MRBus core library from receiving its own transmissions. Normally, MRBus nodes see their own transmissions as received packets as well. In some places, such as access points or other bridge-type nodes, this is undesirable.

Global Private Variables

These variables are private elements used for the various core library functions to communicate and should never be accessed by the application directly. They're documented here for completeness and to positively indicate that they are private.


uint8_t mrbus_loneliness

Note: This variable is internal and application code should never set or read this variable.

mrbus_loneliness is an internal variable used for tracking of how "lonely" the node is - basically how many times it's tried to transmit and been thwarted by a failed arbitration. It's initialized to six and should be left to the MRBus core library to manage.


uint8_t mrbus_rx_index

Note: This variable is internal and application code should never set or read this variable.

mrbus_rx_index stores the index of the next byte to be received in mrbus_rx_input_buffer. It is reset as part of the receive interrupt upon receipt of a framing error (as would occur from the arbitration bytes) or upon receipt of a valid length packet.


uint8_t mrbus_rx_input_buffer[MRBUS_BUFFER_SIZE]

Note: This variable is internal and application code should never set or read this variable.

mrbus_rx_input_buffer is used to accumulate a packet being received off the MRBus. When the packet is done and it passes basic length checks, it will be copied over to mrbus_rx_buffer for application use if the MRBUS_RX_PKT_READY flag is clear in mrbus_state. Otherwise, the packet will be thrown away.


uint8_t mrbus_tx_index

Note: This variable is internal and application code should never set or read this variable.

mrbus_tx_index stores the index of the next byte to be transmitted in mrbus_tx_buffer. It is reset in mrbusPacketTransmit() and managed by the interrupt code as the packet is transmitted.

Copyright 2012 by the MRBus Group.
Licensed under a Creative Commons Attribution-ShareAlike 3.0 License.
Questions? Comments? Please email us at support@iascaled.com

Last modified on February 19, 2012, at 01:36 PM