Skip to content

SPI Interface

The SPI interface gives access to all features of the W-Modbus module. The interface consists of five digital signals (VDD max):

  • IRQ – Interrupt signal. Active low, configurable through the interrupt mask register

  • CS – SPI Chip select, active low

  • SCK – SPI clock input

  • MOSI – SPI data input

  • MISO – SPI data output

Interface description

Bit and byte order

The data on the SPI bus is clocked with most significant bit first. All multi-byte register data are sent in big-endian byte order.

Clock polarity

Data is valid in the low-to-high transition of SCK. This is also known as the clock being active high with valid data on the leading clock edge.

Maximum clock speed

The maximum clock speed supported by W-Modbus is 8 MHz. Clock speeds above this limit may result in unexpected behavior.

Setup time

The SPI slave unit has a setup time of 4 μs after the high-to-low transition of the CS signal.

SPI operation

SPI transactions

All SPI transactions start with a high-to-low transition on the CS pin. The CS pin must be held low during the entire SPI transaction.

The IRQ_FLAGS register is always shifted out as the first byte of each transaction.

Example SPI transaction

SPI commands

All SPI command sequences, except for the NOP command, consist of two SPI transactions. The first transaction shall be two bytes long, this is the command bytes. The second transaction is the payload. The second transaction must not be started until the W-Modbus module has confirmed the command by a high-to-low transition on the IRQ pin. The first byte being sent to W-Modbus in the second transaction will be ignored, however it is suggested this byte is being sent as 0xFF. See below for an example full SPI command sequence.

NOTE: Bit 7 in the IRQ flags register MUST be observed. A ‘1’ in this bit means that the SPI slave module is unable to process the current transaction, and the full command sequence MUST be restarted – this means sending the command transaction again.

Example SPI command sequence with a pending IRQ when sequence started

The available SPI commands are listed in the table below.

Command Hex value Comment
READ_REG 00 AA Read from a register. AA = 8 bit register address.
WRITE_REG 01 AA Write to a register. AA = 8 bit register address.
NOP FF XX No operation. Can be used as a shortcut to read the IRQ_FLAGS register. XX = Not used.

Register map

All undefined bits in the table below shall be considered reserved for future use - don't care when read, write as 0.

Do not read or write undefined registers – doing so could result in undefined behavior.

Address (hex) Mnemonic Bit no. Type Reset value Description
00 STATUS
NETWORK_STATUS 0-6 R - 0 = no network
1 = connected, good link
2 = connected, bad link
3 = connected, unreliable link
COMMISSIONING 7 R/W 0 0 = no commissioning data received
1 = valid commissioning data received
Write 1 here to decommission node
01 APP_MODE
MODE 0-6 R/W 0 0 = None
1 = Secure Gateway
2 = Commissioning Gateway
3 = Secure Mesh
4 = Commissioning Mesh
BOOTLOADER 7 W - Write 1 to reset to bootloader mode
02 IRQ_MASK IRQ Mask register
NETWORK_STATUS_EN 0 R/W 1 Enable network status IRQ
Reserved 1-7 R/W -
03 IRQ_FLAGS
NETWORK_STATUS 0 R 0 Network status changed. Only valid in Node mode.
Reserved 1-7
04 VERSION
FIRMWARE_VERSION_MAJOR 0-7 R - Major version number
FIRMWARE_VERSION_MINOR 8-15 R - Minor version number
FIRMWARE_VERSION_PATCH 16-23 R - Patch version number
06 UART_CONFIG
BAUDRATE 0-23 R/W 0 Any standard value up to 76800 bps has been tested and verified. Higher values, such as 115200 bps, are allowed but have not been tested.
PARITY 24 R/W 0 0 = None
1 = Even
STOP_BITS 25 R/W 0 0 = One stop bit
2 = Two stop bits
Reserved 26-31
10 MODBUS_STATUS
SERVER_ADDRESS 0-7 R 0 Address of detected modbus server.
0 = None detected

Interrupts

The IRQ pin is used to indicate that there is one (or more) pending interrupt that has been enabled through the IRQ_MASK register. The IRQ pin is also used to indicate that the SPI slave is ready to receive the second transaction of an ongoing SPI command sequence.

The IRQ pin will always go high (inactive) after a successful SPI transaction. If any interrupts are pending, or when the chip is ready for the second transaction in a SPI command sequence it will be indicated through a high-to-low transition on the IRQ pin.

NETWORK_STATUS

Asserted when the NETWORK_STATUS register has changed value

Usage example

A simple psuedo-code example for reading UART configuration. The SPI interface is assumed to be initialized.

/* Buffers must be large enough to accommodate register and commands */
uint8_t rx_buffer[BUF_SZ];
uint8_t tx_command[2];

tx_command[0] = 0x00; // Read command
tx_command[1] = 0x06; // Address of UART config

/* Transfer command bytes, read back IRQ flags in the first byte
spi_transfer(tx_command, 2, rx_buffer, 1);

/* Wait until the transfer completes */
WAIT_UNTIL(spi_transfer_complete());

 /* Wait for the IRQ indicating response is ready */
WAIT_UNTIL(gpio_value(SPI_IRQ) == 0);

/* Read the value. The UART config is 4 bytes long, plus one for IRQ flags */
spi_transfer(tx_command, 2, rx_buffer, 4 + 1);

/* Wait until the transfer completes */
WAIT_UNTIL(spi_transfer_complete());

/* IRQ flags are stored in rx_buf[0] */

/* Baudrate is multibyte, MSB first */
uint32_t baudrate = (rx_buf[1] << 16) |
                    (rx_buf[2] << 8) |
                    (rx_buf[3] << 0);

/* Parity is a simple boolean value in bit 24, i.e at position 0 in byte 4 */
uint8_t parity = (rx_buf[4] & 0x01);

/* Stop bits is a simple boolean value in bit 25, i.e at position 1 in byte 4 */
uint8_t stop_bits = (rx_buf[4] & 0x02) >> 1;