SILABS AN452 Wireless m-bus stack programmers guide Datasheet

AN452
W I R E L E S S M-B US S TACK P ROGRAMMER ’ S G UIDE
1. Overview
This specification describes in detail the Application Programmer Interface (API) for the Silicon Labs Wireless
M-Bus stack. The Silicon Labs Wireless M-Bus stack uses a Silicon Labs C8051 MCU and EZRadioPRO®.
Wireless M-Bus is a European standard for meter reading applications using the 868 MHz frequency band.
1.1. Stack Layers
Wireless M-Bus uses the 3-layer IEC model, which is a subset of the 7-layer OSI model. See Figure 1.
Application
EN 13757-3
MCU
app
Data Link
EN 60870-5-2
M-Bus
phy
PHY
EN 13757-4
Si443x
Figure 1. Stack Layers
The Physical Layer (PHY) is defined in EN 13757-4. The Physical Layer defines how the bits are encoded and
transmitted, the RF modem characteristics (chip rate, preamble, and synchronization word), and RF parameters
(modulation, center frequency, and frequency deviation).
The PHY layer is implemented using a combination of hardware and firmware. The EZRadioPRO® performs all of
the RF and modem functions. The EZRadioPRO is used in FIFO mode with the packet handler disabled. The
MbusPhy.c module provides SPI interface, encoding/decoding, block read/write, and packet handling and
manages the transceiver states.
The M-Bus Data Link Layer is implemented in the MbusLink.c module. The M-Bus Application Programming
interface consists of public functions that may be called from the Application Layer in the main thread. The
MbusLink module also implements the Data Link Layer. The Data Link Layer will format and copy data from the
application TX buffer to the MbusPhy TX buffer, adding the required headers and CRCs.
The Application layer itself is not part of the M-Bus firmware. The Application Layer defines how a wide variety of
data is to be formatted for transmission. Most meters only need to transmit one or two types of data. Adding a large
amount of code to accommodate any kind of data to the meter would add unnecessary code and cost to the meter.
If might be feasible to implement a library or a header file with an exhaustive list of data types. However, most
metering customers know exactly what kind of data they need to transmit and can refer to the standard for
formatting details. A universal reader or sniffer might implement a complete set of application data types on the PC
GUI. For these reasons, the Application Layer is implemented using example applications for a meter and reader.
Rev. 0.1 2/10
Copyright © 2010 by Silicon Laboratories
AN452
AN452
1.2. Required Standards
1.2.1. EN 13757-4
EN 13757-4
Communication system for meters and remote reading of meters
Part 4: Wireless meter readout
Radio meter reading for operation in the 868 MHz to 870 MHz SRD band
1.2.2. EN 13757-3
Communication system for meters and remote reading of meters
Part 3: Dedicated Application Layer
1.2.3. IEC 60870-2-1:1992
Telecontrol equipment and systems
Part 5: Transmission protocols
Section 1:Link transmission procedure
1.2.4. IEC 60870-1-1:1990
Telecontrol equipment and systems
Part 5: Transmission protocols
Section 1: Transmission frame formats
1.3. Definitions









M-Bus—M-Bus is a wired standard for meter reading in Europe.
Wireless M-Bus—Wireless M-Bus for meter reading applications in Europe.
PHY—Physical Layer defines how data bits and bytes are encoded and transmitted.
API—Application Programmer interface.
LINK—Data Link Layer- defines how blocks and frames are transmitted.
CRC—Cyclic Redundancy Check.
FSK—Frequency Shift Keying.
Chip—Smallest unit of transmitted data. One data bit is encoded as multiple chips.
Module—A C code source .c file.
1.4. Coding Conventions
The following conventions were adopted for this project:

The compiler_defs.h file is used for cross compiler support.
Memory specific pointers are used for buffers and module registers.
 Each module has a short descriptive file name.

MbusLink.c
MbusPhy.c

Public functions include a short module prefix:
MbusLink—mbus
MbusPhy—PHY

API
module
Public variables also include the same module prefix, starting with a capital letter, since they are globals.
MbusLink—mbus
MbusPhy—PHY
2
API
module
Rev. 0.1
AN452

Each module includes an API header file with public function prototypes.
MbusLink.h
MbusPhy.h








Module public bits and variables are declared external in the module header file.
Public variables are bit or byte only, or qualified using a binary semaphore.
Public variables are used sparingly.
No module includes external variables from another module
Public variable declarations and internal prototypes are located in the module source file.
Hardware-specific macros and bit definitions are located in a hardware_defs.h header file.
Compile time build options, memory specifiers macros, and buffer size macros are located in the
module _defs.h files.
Function parameters passed as inputs may be indicated using __in, and parameters passed as outputs may be
indicated using __out.
Rev. 0.1
3
AN452
2. PHY API
2.1. PHY Layer Modules and File Organization
Table 1. PHY Layer Modules and File Organization
File Name
Description
Comments
MbusPhy.h
Physical Layer header file
MbusPhy.c
Physical Layer c file
MbusPhy_const.h
Physical Layer constants header file
MbusPhy_const.c
Physical Layer constants c file
Code constants used for Radio configuration
hardware_defs.h
Hardware definitions file
hardware specific macros
MbusPhy_def.h
M-Bus definitions file
M-Bus build and configuration
options
si443x_B1.h
Si4432 header file
compiler_defs.h
Compiler definitions file
C8051F930_defs.h
F930 header file
cross compiler macros
2.2. Functions
2.2.1. MbusPhyInitRegisters
Prototype:
PHY_STATUS MbusPhyInitRegisters(void);
Parameters:
none
Returns:
PHY_STATUS (U8) status:
PHY_STATUS_SUCCESS
PHY_STATUS_ERROR_INVALID_STATE
Description:
The PhyInitRegisters() function should be called after resetting the MCU, from the main() function, before using
any other PHY functions. This function will initialize the internal PHY registers in the MCU memory to their default
values. This function does not use the SPI or radio hardware.
It must be called while the radio is in shutdown mode. If the PHY is not in the shutdown state, this function will
return the error code PHY_STATUS_ERROR_INVALID_STATE.
4
Rev. 0.1
AN452
2.2.2. MbusPhyPowerUp
Prototype:
PHY_STATUS MbusPhyPowerUp (void);
Parameters:
none
Returns:
PHY_STATUS (U8) status:
PHY_STATUS_SUCCESS
PHY_STATUS_ERROR_INVALID_STATE
Description:
This function will power up the radio from the shutdown state.
Note that the time to go into IDLE state depends on the current PHY state.
Shutdown  Idle (17 ms)
Standby  Idle (1 ms)
While it is possible to call the MBusPhyIdle() function directly from shutdown, the MCU will be waiting a long time
for the radio to complete the power on reset sequence. The MCU can perform tasks while the Radio is powering up
by using the MbusPhyPowerUp() function first. The MBusPhyIdle() function should be called before using any PHY
functions that require the PHY to be in the Idle or standby state.
This can be used to perform tasks while waiting for Idle mode.
MbusPhyPowerUp ();
// This code is performed while the crystal is starting.
MbusPhyRadioIdle ();
2.2.3. MbusPhyIdle
Prototype:
PHY_STATUS MbusPhyIdle (void);
Parameters:
none
Returns:
PHY_STATUS (U8) status:
PHY_STATUS_SUCCESS
PHY_STATUS_ERROR_POR_TIMEOUT
PHY_STATUS_ERROR_XTAL_TIMEOUT
PHY_STATUS_ERROR_INVALID_STATE
Description:
This function will put the PHY into IDLE state from any other state.
Note that the time to go into IDLE state depends on the current radio state.
Shutdown  Idle (17 ms)
Standby  Idle (1 ms)
RX  Idle (does not wait)
The MbusPhyPowerUp function may be used to perform tasks while waiting for the radio to power up.
MbusPhyPowerUp ();
// This code is performed while the crystal is starting.
MbusPhyRadioIdle ();
Rev. 0.1
5
AN452
The next higher layer does not need to know the current state of the Radio, but the execution time of this function
will vary greatly depending on the current radio mode.
2.2.4. MbusPhyStandby
Prototype:
PHY_STATUS MbusPhyStandby (void);
Parameters:
Returns:
PHY_STATUS (U8) status:
PHY_STATUS_SUCCESS
PHY_STATUS_ERROR_POR_TIMEOUT
Description:
This function will put the PHY (Radio) into Standby mode from any other mode.
Note that the time to go into Standby mode depends on the current radio mode.
Shutdown  Standby (16 ms)
RX  Standby – 0 (does not wait)
Idle  Standby – 0 (does not wait)
Normally, this function should not be used from ShutDown mode. The radio automatically goes from ShutDown to
Idle mode following a POR. If this function is called when the Radio is in Shutdown mode, the MCU will wait until
the POR is complete.
2.2.5. MbusPhyInit
Prototype:
PHY_STATUS MbusPhyInit(void);
Parameters:
none
Returns:
PHY_STATUS (U8) status:
PHY_STATUS_SUCCESS
PHY_STATUS_ERROR_INVALID_STATE
PHY_STATUS_ERROR_UNSUPPORTED_RADIO
Description:
The MBusPhyInit() function will initialize the Si443x internal registers.
The PHY must be in the IDLE state before calling MBusPhyInit(). This may be accomplished by calling
MbusPhyIdle () before MBusPhyInit().
The PHY_METER and PHY_MODE registers should be set using the MbusPhySet() command before calling the
MbusPhyInit() function. Otherwise the default values will be used.
Since the Si4431 register values are lost, the PHY must be initialized every time after it is powered down.
When using the asymmetric T2 transfer mode, this function will not initialize the radio registers since the radio
registers are initialized upon each MbusPhyTx() or MbusPhyRx() function.
The status return code need not be used. In most cases, the next higher layer should know not to call this function
from an invalid state.
6
Rev. 0.1
AN452
2.2.6. MbusPhyRadioShutDown
Prototype:
PHY_STATUS MbusPhyRadioShutDown (void);
Parameters:
none
Returns:
PHY_STATUS (U8) status
PHY_STATUS_SUCCESS
This function will put the Radio into shutdown mode from any other mode.
The radio crystal is turned off manually before shutting down the chip.
This function does not use any timeouts.
All radio register values will be lost in shutdown mode.
2.2.7. MbusPhyGet
Prototype:
PHY_STATUS MbusPhyGet(U8 addr, U8 *value);
Parameters:
U8 addr – The PHY variable address (enumeration)
U8 *value – generic byte pointer to data
Returns:
PHY_STATUS (U8) status:
PHY_STATUS _SUCCESS
PHY_STATUS_ERROR_INVALID_ADDRESS
Description:
The MbusPhyGet function can be used to read the PHY registers or Si4431 registers.
0x00-0x7F—Si443x registers (SPI read transfer)
0x80-0x84—MbusPhy module registers
0x85-0xFF—returns invalid address
The SPI transfers are blocking, and this function will block until two bytes are transferred. This will take at least
1.6 µs using a 10 MHz SPI clock.
The status return code will return an error if the address is invalid. The status return code need not be used. In
most cases, the next higher layer should know not to pass an invalid address.
2.2.8. MbusPhySet
Prototype:
U8 MbusPhySet(U8 addr, U8 value);
Parameters:
U8 addr—The PHY variable address (enumeration)
U8 value
Returns:
PHY_STATUS (U8) status:
PHY_STATUS_SUCCESS
PHY_STATUS_ERROR_INVALID_VALUE
PHY_STATUS_ERROR_READ_ONLY_ADDRESS
PHY_STATUS_ERROR_INVALID_ADDRESS
Rev. 0.1
7
AN452
Description:
The MbusPhySet function can be used to set the PHY module registers or Si4431 registers.
0x00-0x7F – Si443x registers (SPI write transfer)
0x80-0x84 – MbusPhy module registers
0x85-0xFF – returns invalid address
The status return code will return an error if the value is out of range or read only. The status return code need not
be used. In most cases, the next higher layer should know not to write an invalid value, read only address, or
invalid address.
The SPI transfers are blocking, and this function will block until two bytes are transferred. This will take at least
1.6 µs using a 10 MHz SPI clock.
2.2.9. MbusPhyTx
Prototype:
PHY_STATUS MbusPhyTX(VARIABLE_SEGMENT_POINTER(, U8, BUFFER_MSPACE));
Parameters:
VARIABLE_SEGMENT_POINTER(buffer, U8, BUFFER_MSPACE));
pointer to TX buffer in BUFFER_MSPACE (typically xdata)
Returns:
PHY_STATUS (U8) status:
PHY_STATUS_SUCCESS
PHY_STATUS_ERROR_INVALID_STATE—not in IDLE state
PHY_STATUS_ERROR_INVALID_LENGTH—invalid L field
PHY_STATUS_ERROR_TX_TIMEOUT—Radio failed to send message before timeout
Description:
This function will transmit the data in the transmit buffer. This function is blocking and will not return until
transmission is complete.
If the asymmetric Mode T2 is being used, the radio will be initialized for TX.
The L field is read from the first byte of the buffer and need not be passed as a parameter. The packet length,
number of blocks, and the number of encoded bytes is calculated from the L field. The number of encoded bytes is
written to the radio TX packet length.
The packet in the TX buffer should be properly formatted (by the Data Link Layer) into blocks with CRCs between
blocks.
The next higher layer should supply a buffer large enough to accommodate the entire packet as indicated by the L
field. The TX function may send garbage data in the case of a buffer overrun. The TX function does not write to the
TX buffer.
This function will copy the first 64 bytes into the radio FIFO. Each byte of data is encoded before writing to the SPI.
If additional bytes are to be sent, the FIFO almost empty threshold will be set to 16 bytes and the FIFO almost
empty interrupt will be enabled. If there are not additional bytes to be written, the FIFO almost empty will be cleared
to 0, and the Packet Sent interrupt will be enabled.
Once the FIFO has been initialized and interrupts have been enabled, the transmitter will be started by writing to
the Function control 1 register. The MCU will then go to sleep until the next IRQ wakeup or timeout.
If the PHY is not in the IDLE state, the function will immediately return a PHY_STATUS_ERROR_INVALID_STATE
error code.
If the first byte in the buffer is an invalid length for the L field, the function will immediately return a
PHY_STATUS_ERROR_INVALID_LENGTH error code.
If for any reason the Radio does not successfully transmit all of the data in the TX buffer, the radio will be manually
set into the IDLE mode, and this function will return the PHY_STATUS_ERROR_TX_TIMEOUT error code. This
generally indicates a problem with the hardware.
8
Rev. 0.1
AN452
2.2.10. MbusPhyRx
Prototype:
PHY_STATUS MbusPhyRX(U32, VARIABLE_SEGMENT_POINTER(, U8, BUFFER_MSPACE));
Parameters:
U32 timeout—ticks of 32.768 kHz clock.
VARIABLE_SEGMENT_POINTER(buffer, U8, BUFFER_MSPACE));
pointer to RX buffer in BUFFER_MSPACE (typically xdata)
Returns:
U8 status
PHY_STATUS_SUCCESS
PHY_STATUS_ERROR_NOTHING_RECEIVED—nothing receive in RX time
PHY_STATUS_ERROR_INVALID_STATE—not in IDLE state
PHY_STATUS_ERROR_INVALID_LENGTH—invalid received L field
PHY_STATUS_ERROR_DECODING—error decoding Manchester or 3 out of 6
PHY_STATUS_ERROR_RX_INCOMPLETE—incomplete message received
Description:
The MbusPhyRx() function is a blocking RX function with a timeouts. The receiver will remain on for the specified
amount of time with the MCU in low-power sleep mode. The timeout or receiver interrupt will wake up the MCU.
The next higher layer should supply a buffer large enough to accommodate the entire packet for the largest
possible L-field of interest.
The largest L-field of interest should be defined in Mbus_defs.h
#define USER_RX_MAX_L_FIELD 148
An example buffer declaration is shown below:
SEGMENT_VARIABLE( userBuffer[USER_RX_BUFFER_SIZE], U8, BUFFER_MSPACE)
The return status of this function will indicate if a packet has been successfully received. If a packet has been
successfully received, this function will return a status of PHY_STATUS_SUCCESS. The PHY does not validate
the CRCs; so, the packet still might contain a CRC error.
If
the
receiver
timeout
has
expired,
the
function
will
return
a
PHY_STATUS_ERROR_NOTHING_RECEIVED. This may not be an error in many circumstances.
status
of
A decoding error at any point after the SYNC word results in the Receiver immediately returning a status of
PHY_STATUS_ERROR_DECODING.
If the correct number of bytes is not received completely, a status of PHY_STATUS_ERROR_RX_INCOMPLETE
will be returned.
2.3. PHY Module Registers
This it the structure typedef for the Mbus PHY
typedef struct MbusPhyRegisters
{
U8 meter;
U8 mode;
U8 channel;
U8 state;
U8 RxPacketLength;
U8 RxRSSI;
} MbusPhyRegisters;
All PHY module registers can be read using the MbusPhySet() function.
Rev. 0.1
9
AN452
3. Data Link Layer API
The Data Link Layer module implements a 13757-4:2005 compliant link layer. The Data Link Layer (LINK) provides
an interface between the Physical Layer (PHY) and the Application Layer (AL).
Data Link Layer:







Provides functions that transfer data between PHY and AL
Generate CRCs for outgoing messages
Detect CRC errors in incoming messages
Provide physical addressing
Acknowledge transfers for bidirectional communication modes
Frame data bits
Detect framing errors in incoming messages
3.1. Definitions

AL—Application Layer
 LINK—Data Link Layer
 NHL—Next Higher Layer
 PHY—Physical Layer
3.2. Module and File Organization
Table 2. File Descriptions and Comments
File Name
Description
Common.h
Common typedefs and macros
Comments
Crc.h
CRC-16-DNP header file
Crc.c
CRC-16-DNP source file
MbusLink.h
Data Link Layer header file
MbusLink.c
Data Link Layer source file
MbusLinkServices.h
Data Link Layer Services primitives header file
MbusLinkServices.c
Data Link Layer Services primitives source file Optional request, confirmation, indication, and response service primitives.
MbusLink_defs.h
Data Link Layer compile-time build options
MbusLinkServices_defs.h
Data Link Layer Services compile-time build
options
10
Rev. 0.1
AN452
3.3. Functions
3.3.1. MbusLinkInit
Prototype:
LINK_STATUS MbusLinkInit(void);
Parameters:
none
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR_INVALID_STATE
Description:
This function initializes the Data Link Layer module attributes to their default values, initializes the RTC at
32.768 kHz, and initializes the PHY registers. This function only needs to be called once at the beginning of code
after an MCU reset.
3.3.2. MbusLinkRadioPowerOn
Prototype:
LINK_STATUS MbusLinkRadioPowerOn(void);
Parameters:
none
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR_INVALID_STATE
Description:
This function turns on the EZRadioPRO® but does not wait for the radio to enter IDLE mode. The NHL/AL can
perform work while waiting for the radio oscillator to stabilize. Next, call MbusLinkRadioConfig() to wait for the radio
to enter IDLE mode and configure the radio modes and channel.
3.3.3. MbusLinkRadioConfig
Prototype:
LINK_STATUS MbusLinkRadioConfig(void);
Parameters:
none
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR_INVALID_VALUE
LINK_STATUS_PHY_ERROR_INVALID_STATE
LINK_STATUS_PHY_ERROR_POR_TIMEOUT
LINK_STATUS_PHY_ERROR_XTAL_TIMEOUT
LINK_STATUS_PHY_ERROR_UNSUPPORTED_RADIO
Description:
This function waits for the EZRadioPRO to enter IDLE mode and stores the radio modes and channel settings
before configuring the radio over SPI. Users must call this function after changing radio settings before the new
settings will apply.
Rev. 0.1
11
AN452
3.3.4. MbusLinkRadioPowerOff
Prototype:
LINK_STATUS MbusLinkRadioPowerOff(void);
Parameters:
none
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR_INVALID_STATE
Description:
Turns the EZRadioPRO off. All radio settings are lost when the radio is shut down. Call MbusLinkRadioPowerOn()
and MbusLinkRadioConfig() before using the radio again.
3.3.5. MbusLinkRadioStandby
Prototype:
LINK_STATUS MbusLinkRadioStandby(void);
Parameters:
none
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR_POR_TIMEOUT
LINK_STATUS_PHY_ERROR_INVALID_STATE
Description:
Puts the EZRadioPRO into a low power standby mode. Radio settings are preserved in standby mode.
Call MbusLinkRadioResume() to resume from standby mode.
3.3.6. MbusLinkRadioResume
Prototype:
LINK_STATUS MbusLinkRadioResume(void);
Parameters:
none
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR_INVALID_STATE
LINK_STATUS_PHY_ERROR_POR_TIMEOUT
LINK_STATUS_PHY_ERROR_XTAL_TIMEOUT
Description:
Resumes the EZRadioPRO from standby mode and places the radio into IDLE mode.
3.3.7. MbusLinkMcuSleep
Prototype:
LINK_STATUS MbusLinkMcuSleep(__in U32 duration);
Parameters:
duration—The amount of time for the MCU to sleep in RTC (32.768 kHz) ticks.
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR
12
Rev. 0.1
AN452
Description:
This function places the MCU into a low power sleep mode and prepares the RTC to wake the device up after the
specified duration. If MAINS_POWERED is defined in MbusPhy_defs.h, then the MCU will enter IDLE mode,
allowing interrupts to occur.
3.3.8. MbusLinkSetAttribute
Prototype:
LINK_STATUS MbusLinkSetAttributes(__in LINK_ATTR_ID attr, __in U8 value);
Parameters:
attr—The attribute identifier for the attribute to modify
value—Sets the attribute value
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR_READ_ONLY_ADDRESS
LINK_STATUS_PHY_ERROR_INVALID_ADDRESS
LINK_STATUS_PHY_ERROR_INVALID_VALUE
LINK_STATUS_INVALID_ATTR
LINK_STATUS_NOT_PERMITTED
Description:
This function sets the specified attribute to the specified value.
Attribute IDs:
0x00–0x7F: Si443x registers (SPI write transfer)
0x80–0x8F: PHY variables
0x90–0xFF: LINK attributes (see "3.5. Data Link Layer Attributes" on page 20)
3.3.9. MbusLinkGetAttribute
Prototype:
LINK_STATUS MbusLinkGetAttributes(__in LINK_ATTR_ID attr, __out U8* value);
Parameters:
attr—The attribute identifier for the attribute value to return
value—Returns the attribute value
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR_INVALID_ADDRESS
LINK_STATUS_INVALID_ATTR
LINK_STATUS_NOT_PERMITTED
Description:
This function returns the attribute value for the attribute specified.
Attribute IDs:
0x00–0x7F: Si443x registers (SPI write transfer)
0x8–0x8F: PHY variables
0x90–0xFF: LINK attributes
Rev. 0.1
13
AN452
3.3.10. MbusLinkTransmitFrame
Prototype:
LINK_STATUS MbusLinkTransmitFrame(__in Frame* frame);
Parameters:
frame—A pointer to a LINK frame specifying the C, M, A, CI, and Data fields
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR_INVALID_VALUE
LINK_STATUS_PHY_ERROR_INVALID_STATE
LINK_STATUS_PHY_ERROR_INVALID_LENGTH
LINK_STATUS_PHY_ERROR_POR_TIMEOUT
LINK_STATUS_PHY_ERROR_XTAL_TIMEOUT
LINK_STATUS_PHY_ERROR_UNSUPPORTED_RADIO
LINK_STATUS_PHY_ERROR_TX_TIMEOUT
LINK_STATUS_INVALID_SIZE
Description:
This function takes a frame input and generates a frame buffer consisting of L, C, M, A, CI, Data, and CRC fields
(stored in an internal TX frame buffer). The L and CRC fields are automatically calculated and added to the frame
buffer. If the EZRadioPRO is not already in IDLE mode, this function will call MbusLinkRadioConfig(). This allows
users to optimize power usage by generating a transmit frame while initializing the EZRadioPRO. Next, the
function transmits the frame buffer via the PHY.
3.3.11. MbusLinkTransmitFrameAtTime
Prototype:
LINK_STATUS MbusLinkTransmitFrameAtTime(__in U32 txRtcTime, __in Frame* frame);
Parameters:
txRtcTime—The time in RTC (32.768 kHz) ticks at which to transmit the frame
frame—A pointer to a LINK frame specifying the C, M, A, CI, and Data fields
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR_INVALID_VALUE
LINK_STATUS_PHY_ERROR_INVALID_STATE
LINK_STATUS_PHY_ERROR_INVALID_LENGTH
LINK_STATUS_PHY_ERROR_POR_TIMEOUT
LINK_STATUS_PHY_ERROR_XTAL_TIMEOUT
LINK_STATUS_PHY_ERROR_UNSUPPORTED_RADIO
LINK_STATUS_PHY_ERROR_TX_TIMEOUT
LINK_STATUS_INVALID_SIZE
Description:
This function takes a frame input and generates a frame buffer consisting of L, C, M, A, CI, Data, and CRC fields
(stored in an internal TX frame buffer). The L and CRC fields are automatically calculated and added to the frame
buffer. If the EZRadioPRO® is not already in idle mode, then this function will call MbusLinkRadioConfig(). This
allows users to optimize power usage by generating a transmit frame while initializing the EZRadioPRO®. Next,
the function transmits the frame buffer via the PHY at the specified RTC time.
14
Rev. 0.1
AN452
3.3.12. MbusLinkReceiveFrame
Prototype:
LINK_STATUS MbusLinkReceiveFrame(__in U32 timeout, __out Frame* frame);
Parameters:
timeout—The maximum number of RTC (32.768 kHz) ticks to wait to receive a valid preamble and sync word
frame—A pointer to a LINK frame that will return the C, M, A, CI, and Data fields
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR_INVALID_VALUE
LINK_STATUS_PHY_ERROR_INVALID_STATE
LINK_STATUS_PHY_ERROR_INVALID_LENGTH
LINK_STATUS_PHY_ERROR_NOTHING_RECEIVED
LINK_STATUS_PHY_ERROR_DECODING
LINK_STATUS_PHY_ERROR_POR_TIMEOUT
LINK_STATUS_PHY_ERROR_XTAL_TIMEOUT
LINK_STATUS_PHY_ERROR_UNSUPPORTED_RADIO
LINK_STATUS_PHY_ERROR_RX_PACKET_INCOMPLETE
Description:
This function first makes sure that the EZRadioPRO is in IDLE mode by calling MbusLinkRadioConfig() and then
attempts to receive a frame using the PHY. If reception was successful, the function parses the received frame
buffer by checking for valid data lengths and CRC and copies the data to a frame structure.
3.4. Service Primitive Functions
The Data Link Layer implements the service primitives defined in IEC 60870-5-2:1992. To include the service
primitives module in a project, the user must include MbusLinkService.h and MbusLinkService.c in the project file
and call MbusLinkServicesInit().
3.4.1. MbusLinkServicesInit
Prototype:
void MbusLinkServicesInit(void);
Parameters:
none
Returns:
none
Description:
This function initializes the Mbus Link Services module.
3.4.2. MbusLinkServicesRequest
Prototype:
void MbusLinkServicesRequest(__in Request* request, __out Confirmation* confirmation);
Parameters:
request—A pointer to a Data Link Layer request primitive. Contains the frame to transmit and the number of retry
attempts (for Send/Confirm and Request/Respond)
confirmation—A pointer to a Data Link Layer confirmation service primitive. Returns the status of the request,
positive/negative acknowledge, the request service type, link state, and response frame (Request/Respond).
Rev. 0.1
15
AN452
Returns:
none
Description:
This function processes a request service primitive, generates a valid C-field by setting the FCV, FCB, and PRM
bits, transmits the request frame, checks for confirm/response if applicable, and retries data transmission when
appropriate (Send/Confirm, Request/Respond when valid ack/nack is not received).
Flow Chart:
Prepare Frame
(FCV, FCB, PRM)
Wait min response
delay
Transmit Frame
Transmit
Successful ?
No
Status = (Error)
Positive = FALSE
No
Status = LINK_STATUS_SUCCESS
Positive = TRUE
Yes
Status = LINK_STATUS_SUCCESS
Positive = TRUE
Yes
Status = LINK_STATUS_SUCCESS
Positive = FALSE
Yes
Status = LINK_STATUS_INVALID_SIZE
Positive = FALSE
Yes
Ack/Nack
Requested?
Yes
Wait min response
delay
Receive Frame
(max – min
response delay)
Yes
Valid Ack /
Response?
No
Valid Nack?
No
Insufficient
Buffer Size?
No
Attempt <=
MaxRetries?
No
Status = LINK_STATUS_TX_RETRY_ERROR
Positive = FALSE
Figure 2. MbusLinkServicesRequest Flowchart
16
Rev. 0.1
AN452
3.4.3. MbusLinkServicesIndication
Prototype:
void MbusLinkServicesIndication(__out Indication* indication);
Parameters:
indication—A pointer to a Data Link Layer indication service primitive. Specifies the read timeout and returns the
status of the read operation, the received frame service type, and the received frame.
Returns:
none
Description:
This function attempts to receive a frame via the PHY within the timeout duration specified. Upon receipt of a
frame, the indication service primitive returns the frame and service type.
Flow Chart:
Receive Frame
(timeout)
Receive
Successful ?
No
Status = (Error)
Yes
No
Duplicate
Frame?
Yes
Wait min response
delay
Send/Confirm?
Yes
No
Wait min response
delay
Transmit Ack
Retransmit
Confirm/Respond
Status = LINK_STATUS_NO_DATA
Status = LINK_STATUS_SUCCESS
Figure 3. MbusLinkServicesIndication Flowchart
Rev. 0.1
17
AN452
3.4.4. MbusLinkServicesResponse
Prototype:
LINK_STATUS MbusLinkServicesResponse(__in Indication* indication, __in Response* response);
Parameters:
indication—Indication returned from MbusLinkServicesIndication().
response—A pointer to a Data Link Layer response service primitive that specifies the response frame or a
negative response.
Returns:
LINK_STATUS_SUCCESS
LINK_STATUS_PHY_ERROR_INVALID_VALUE
LINK_STATUS_PHY_ERROR_INVALID_STATE
LINK_STATUS_PHY_ERROR_INVALID_LENGTH
LINK_STATUS_PHY_ERROR_NOTHING_RECEIVED
LINK_STATUS_PHY_ERROR_DECODING
LINK_STATUS_PHY_ERROR_POR_TIMEOUT
LINK_STATUS_PHY_ERROR_XTAL_TIMEOUT
LINK_STATUS_PHY_ERROR_UNSUPPORTED_RADIO
LINK_STATUS_PHY_ERROR_RX_PACKET_INCOMPLETE
LINK_STATUS_INVALID_SIZE
Description:
This function attempts to receive a frame via the PHY within the timeout duration specified. Upon receipt of a
frame, the indication service primitive returns the frame and service type.
18
Rev. 0.1
AN452
Flow Chart:
Request/
Respond?
No
Status = LINK_STATUS_NO_DATA
No
Status = LINK_STATUS_INVALID_SIZE
Yes
Valid Frame
Size?
Yes
Wait min response
delay
Positive
Response?
No
Yes
Transmit Positive
Response
(w/Data)
Transmit Negative
Response
Transmit
Successful ?
No
Status = (Error)
Yes
Status = LINK_STATUS_SUCCESS
Figure 4. MbusLinkServicesResponse Flowchart
Rev. 0.1
19
AN452
3.5. Data Link Layer Attributes
Table 3. Data Link Layer Attributes
Attribute
LINK_ATTR_ID Enumerations
ID
Description
LinkAttrMeterMode
LINK_ATTR_ID_METER_MODE
0x90
Meter/Other Mode:
0—LINK_MODE_OTHER
1—LINK_MODE_METER
LinkAttrRadioMode
LINK_ATTR_ID_RADIO_MODE
0x91
Wireless M-Bus radio mode:
0—LINK_MODE_S
1—LINK_MODE_SL
2—LINK_MODE_T
3—LINK_MODE_R
LinkAttrRadioChannel
LINK_ATTR_ID_RADIO_CHANNEL
0x92
R Mode Channel (0–9)
LinkAttrTxFcb
LINK_ATTR_ID_TX_FCB
0x93
unused
LinkAttrRxFcb
LINK_ATTR_ID_RX_FCB
0x94
FCB value from last frame received
LinkAttrModeSTroMin
LINK_ATTR_ID_MODE_S_TRO_MIN
0x95
Mode S: Minimum response delay (ms)
LinkAttrModeSTroMax
LINK_ATTR_ID_MODE_S_TRO_MAX
0x96
Mode S: Maximum response delay (ms)
LinkAttrModeTTackMin
LINK_ATTR_ID_MODE_T_TACK_MIN
0x97
Mode T: Minimum acknowledge delay (ms)
LinkAttrModeTTackMax
LINK_ATTR_ID_MODE_T_TACK_MAX
0x98
Mode T: Maximum acknowledge delay (ms)
LinkAttrModeRTroMin
LINK_ATTR_ID_MODE_R_TRO_MIN
0x99
Mode R: Minimum response delay (ms)
(CI = 0x81)
LinkAttrModeRTroMax
LINK_ATTR_ID_MODE_R_TRO_MAX
0x9A
Mode R: Maximum response delay (ms)
(CI = 0x81)
LinkAttrModeRTrmMin
LINK_ATTR_ID_MODE_R_TRM_MIN
0x9B
Mode R: Minimum response delay (ms)
LinkAttrModeRTrmMax
LINK_ATTR_ID_MODE_R_TRM_MAX
0x9C
Mode R: Maximum response delay (s)
20
Rev. 0.1
AN452
3.5.1. Data Link Layer User-Modifiable Definitions
Table 4. User-Modifiable Definitions
Definition
Min
Default
LINK_USER_MAX_TX_DATA_FIELD_SIZE
0
138
Specifies the max data-field size in bytes to be
transmitted and is used to determine the size of
the TX frame buffer
LINK_USER_MAX_RX_DATA_FIELD_SIZE
0
138
Specifies the max data-field size in bytes to be
received and is used to determine the size of the
RX frame buffer
LINK_USER_MSPACE
Description
SEG_XDATA
The memory space used for all spaced pointers for
frame data and service primitives
3.5.2. Data Link Layer Service Primitive User-Modifiable Definitions
Table 5. Service Primitive User-Modifiable Definitions
Definition
Min
Default
LINK_AUTO_RESP_DATA_MAX
0
138
The size of the data-field buffer used for automatic
responses to duplicate requests
LINK_TX_FCB_TABLE_ENTRIES_MAX
1
2
The number of destination addresses to record the
frame control bit used for transmission
LINK_SYSCLK
20000UL
Rev. 0.1
Description
The system clock speed in kHz used to determine processing delays
21
AN452
3.6. Data Link Layer Structures
3.6.1. Frame
Typedef:
typedef U8 LINK_ATTR_MFR[LINK_ATTR_SIZE_MFR];
typedef U8 LINK_ATTR_ADDR[LINK_ATTR_SIZE_ADDR];
typedef struct DataField
{
U8 size;
U8 capacity;
U8* payload;
} DataField;
Members:
size - The number of valid bytes in the data-field
capacity - The size of the buffer pointed to by payload
payload - A pointer to a user space byte array
typedef struct Frame
{
U8 c_field;
LINK_ATTR_MFR m_field;
LINK_ATTR_ADDR a_field;
U8 ci_field;
DataField data_field;
} Frame;
Members:
c_field - The Control-field
m_field - The manufacturer ID
a_field - The Address-field
ci_field - The Control Information-field
data_field - The Data-field
3.7. Data Link Layer Service Primitive Structures
3.7.1. Request
Typedef:
typedef struct Request
{
U8 retries;
Frame frame;
} Request;
Members:
retries - The number of times to retry an acknowledged transmission if a confirm/respond is not received.
frame - The frame to transmit. The C-field is used to determine the transmission procedure
(Send/No Reply, Send/Confirm, Request/Respond). All fields must be specified when calling
MbusLinkServicesRequest().
22
Rev. 0.1
AN452
3.7.2. Confirmation
Typedef:
typedef struct Confirmation
{
LINK_STATUS status;
BOOL positive;
LINK_SERVICE_TYPE serviceType;
LINK_STATE link;
Frame frame;
}; Confirmation;
Members:
status - returns the status of the MbusLinkServicesRequest().
positive - returns TRUE if the MbusLinkServicesRequest() was successful.
Send/NoReply: returns TRUE if the transmission was successful.
Send/Confirm: returns TRUE if a positive ack/confirm was received.
Request/Respond: returns TRUE if a response was received.; Returns FALSE if a respond nack is
received.
serviceType - returns the service type of the request (Send/No Reply, Send/Confirm, Request/Respond).
link - returns the status of the Data Link Layer (operational/non operational)
frame - returns the frame received for Send/Confirm or Request/Respond.
3.7.2.1. Indication
Typedef:
typedef struct Indication
{
U32 timeout;
LINK_STATUS status;
LINK_SERVICE_TYPE serviceType;
Frame frame;
} Indication;
Members:
timeout - The number of milliseconds to wait to receive data for MbusLinkServicesIndication().
status - The status of MbusLinkServicesIndication().
serviceType - The service type of the received frame (Send/No Reply, Send/Confirm, Request/Respond).
frame - The received frame.
3.7.2.2. Response
Typedef:
typedef struct Response
{
BOOL positive;
Frame frame;
} Response;
Members:
positive - Set to TRUE if sending a response to a Send/Respond with data.
Set to FALSE if sending a respond nack.
frame - The frame response to send.
Rev. 0.1
23
AN452
3.8. LINK_STATUS
// LINK_STATUS
typedef enum LINK_STATUS
{
// PHY layer status codes
LINK_STATUS_SUCCESS = 0x00,
LINK_STATUS_PHY_ERROR,
// unspecified
LINK_STATUS_PHY_ERROR_TIMEOUT,
// unspecified timeout
LINK_STATUS_PHY_ERROR_READ_ONLY_ADDRESS,
LINK_STATUS_PHY_ERROR_INVALID_ADDRESS,
LINK_STATUS_PHY_ERROR_INVALID_VALUE,
LINK_STATUS_PHY_ERROR_INVALID_STATE,
LINK_STATUS_PHY_ERROR_INVALID_LENGTH,
LINK_STATUS_PHY_ERROR_NOTHING_RECEIVED,
LINK_STATUS_PHY_ERROR_DECODING,
LINK_STATUS_PHY_ERROR_POR_TIMEOUT,
LINK_STATUS_PHY_ERROR_XTAL_TIMEOUT,
LINK_STATUS_PHY_ERROR_UNSUPPORTED_RADIO,
LINK_STATUS_PHY_ERROR_TX_TIMEOUT,
LINK_STATUS_PHY_ERROR_RX_INVALID_LENGTH,
LINK_STATUS_PHY_ERROR_RX_PACKET_INCOMPLETE,
// LINK layer status codes
LINK_STATUS_INVALID_SIZE = 0x40,
LINK_STATUS_INVALID_ATTR,
LINK_STATUS_NOT_PERMITTED,
LINK_STATUS_CRC_ERROR,
LINK_STATUS_FRAME_ERROR,
LINK_STATUS_TX_RETRY_ERROR,
LINK_STATUS_UNKNOWN_ERROR = 0xFF
} LINK_STATUS;
24
Rev. 0.1
AN452
Table 6. LINK_STATUS Enumeration Descriptions
Enumeration
Value
LINK_STATUS_SUCCESS
0x00
Success
LINK_STATUS_PHY_ERROR
0x01
PHY_STATUS_ERROR
LINK_STATUS_PHY_ERROR_TIMEOUT
0x02
PHY_STATUS_ERROR_TIMEOUT
LINK_STATUS_PHY_ERROR_READ_ONLY_ADDRESS
0x03
PHY_STATUS_ERROR_READ_ONLY_ADDRESS
LINK_STATUS_PHY_ERROR_INVALID_ADDRESS
0x04
PHY_STATUS_ERROR_INVALID_ADDRESS
LINK_STATUS_PHY_ERROR_INVALID_VALUE
0x05
PHY_STATUS_ERROR_INVALID_VALUE
LINK_STATUS_PHY_ERROR_INVALID_STATE
0x06
PHY_STATUS_ERROR_INVALID_STATE
LINK_STATUS_PHY_ERROR_INVALID_LENGTH
0x07
PHY_STATUS_ERROR_INVALID_LENGTH
LINK_STATUS_PHY_ERROR_NOTHING_RECEIVED
0x08
PHY_STATUS_ERROR_NOTHING_RECEIVED
LINK_STATUS_PHY_ERROR_DECODING
0x09
PHY_STATUS_ERROR_DECODING
LINK_STATUS_PHY_ERROR_POR_TIMEOUT
0x0A
PHY_STATUS_ERROR_POR_TIMEOUT
LINK_STATUS_PHY_ERROR_XTAL_TIMEOUT,
0x0B
PHY_STATUS_ERROR_XTAL_TIMEOUT
LINK_STATUS_PHY_ERROR_UNSUPPORTED_RADIO
0x0C
PHY_STATUS_ERROR_UNSUPPORTED_RADIO
LINK_STATUS_PHY_ERROR_TX_TIMEOUT,
0x0D
PHY_STATUS_ERROR_TX_TIMEOUT
LINK_STATUS_PHY_ERROR_RX_INVALID_LENGTH
0x0E
PHY_STATUS_ERROR_RX_INVALID_LENGTH
LINK_STATUS_PHY_ERROR_RX_PACKET_INCOMPLETE
0x0F
PHY_STATUS_ERROR_RX_PACKET_INCOMPLETE
LINK_STATUS_INVALID_SIZE
0x40
Buffer is not large enough
LINK_STATUS_INVALID_ATTR
0x41
Invalid attribute ID
LINK_STATUS_NOT_PERMITTED
0x42
Attribute is read only or write only
LINK_STATUS_CRC_ERROR
0x43
Frame is invalid due to CRC mismatches
LINK_STATUS_FRAME_ERROR
0x44
Frame is invalid due to incorrect block format
LINK_STATUS_TX_RETRY_ERROR
0x45
Could not transmit service request (retries failed)
LINK_STATUS_UNKNOWN_ERROR
0xFF
Unspecified error
Rev. 0.1
Description
25
AN452
CONTACT INFORMATION
Silicon Laboratories Inc.
400 West Cesar Chavez
Austin, TX 78701
Tel: 1+(512) 416-8500
Fax: 1+(512) 416-9669
Toll Free: 1+(877) 444-3032
Please visit the Silicon Labs Technical Support web page:
https://www.silabs.com/support/pages/contacttechnicalsupport.aspx
and register to submit a technical support request.
The information in this document is believed to be accurate in all respects at the time of publication but is subject to change without notice.
Silicon Laboratories assumes no responsibility for errors and omissions, and disclaims responsibility for any consequences resulting from
the use of information included herein. Additionally, Silicon Laboratories assumes no responsibility for the functioning of undescribed features
or parameters. Silicon Laboratories reserves the right to make changes without further notice. Silicon Laboratories makes no warranty, representation or guarantee regarding the suitability of its products for any particular purpose, nor does Silicon Laboratories assume any liability
arising out of the application or use of any product or circuit, and specifically disclaims any and all liability, including without limitation consequential or incidental damages. Silicon Laboratories products are not designed, intended, or authorized for use in applications intended to
support or sustain life, or for any other application in which the failure of the Silicon Laboratories product could create a situation where personal injury or death may occur. Should Buyer purchase or use Silicon Laboratories products for any such unintended or unauthorized application, Buyer shall indemnify and hold Silicon Laboratories harmless against all claims and damages.
Silicon Laboratories and Silicon Labs are trademarks of Silicon Laboratories Inc.
Other products or brandnames mentioned herein are trademarks or registered trademarks of their respective holders.
26
Rev. 0.1
Similar pages