Loading...
Searching...
No Matches
Differentially Operated Serial Ethernet

Driver for connecting RIOT devices using a single bus wire. More...

Detailed Description

Driver for connecting RIOT devices using a single bus wire.

About

This driver enables RIOT nodes to communicate by Ethernet over a serial bus. This enables them to interact in an easy and cheap manner using a single bus wire with very low hardware requirements: The used microcontrollers just need to feature at least one UART and one optional GPIO that is able to raise interrupts.

Wiring

DOSE wiring

For bus access, you need a CAN transceiver, since the DOSE uses the PHY layer of CAN for the electrical connection of the nodes. Every transceiver IC operating with the right voltage levels should do. (If you are on a 3.3V MCU, you could use an IC such as the SN65HVD233.)

Basically, UART TX and RX are connected to respective pins of the transceiver. In addition, the RX pin can also be connected to the sense GPIO if the UART does not implement the periph_uart_rxstart_irq feature. In this case, the bus allocation can be detected more precisely and collisions are less likely.

How it works

Some technical details for those interested: The Ethernet frames are sent onto the bus using uart_write() while observing the received echo from the bus. This way collisions are detected (received echo != transmitted octet) and retransmissions are scheduled. The frames are appended with a CRC16 to protect the system from transmission errors.

A note on high data rates

When using high UART data rates (1 MBit/s and above) per-byte overhead becomes significant. A major factor here is setting (software) timers which are used to catch error conditions. To speed up the TX path it is therefore recommended to implement hardware collision detection (if available) to avoid the need for setting a timeout for each byte transmitted.

To speed up the more critical RX path, enable the dose_watchdog module. This requires a dedicated hardware timer DOSE_TIMER_DEV to be configured in e.g. board.h. The timer is shared between all DOSE interfaces and will periodically check if any interface does not make progress with receiving a frame (payload marker did not advance between two timer periods) and abort the RX process.

Modules

 Differentially Operated Serial Ethernet (DOSE) driver compile configuration
 

Files

file  dose_params.h
 Default configuration for the Differentially Operated Serial Ethernet driver.
 
file  dose.h
 Driver for the Differentially Operated Serial Ethernet module.
 

Data Structures

struct  dose_t
 DOSE netdev device. More...
 
struct  dose_params_t
 Struct containing the required configuration. More...
 

Macros

#define DOSE_FRAME_CRC_LEN   (2)
 CRC16 is used.
 
#define CONFIG_DOSE_RX_BUF_LEN   (ETHERNET_FRAME_LEN + DOSE_FRAME_CRC_LEN)
 DOSE RX buffer length Should be large enough to fit at least one Ethernet frame.
 
#define DOSE_TIMER_DEV   TIMER_DEV(…)
 Hardware timer to use with the dose_watchdog module.
 

Functions

void dose_setup (dose_t *dev, const dose_params_t *params, uint8_t index)
 Setup a DOSE based device state.
 

State definitions

The drivers internal state that is hold in dose_t.state

enum  dose_state_t {
  DOSE_STATE_INIT = 0x00 , DOSE_STATE_BLOCKED = 0x01 , DOSE_STATE_IDLE = 0x02 , DOSE_STATE_RECV = 0x03 ,
  DOSE_STATE_SEND = 0x04 , DOSE_STATE_STANDBY = 0x05 , DOSE_STATE_SLEEP = 0x06 , DOSE_STATE_ANY = 0x0F
}
 

Signal definitions

A signal controls the state machine and may cause a state transition

enum  dose_signal_t {
  DOSE_SIGNAL_NONE = 0x00 , DOSE_SIGNAL_INIT = 0x10 , DOSE_SIGNAL_GPIO = 0x20 , DOSE_SIGNAL_UART = 0x30 ,
  DOSE_SIGNAL_ZTIMER = 0x40 , DOSE_SIGNAL_SEND = 0x50 , DOSE_SIGNAL_END = 0x60
}
 

Escape octet definitions

#define DOSE_OCTET_END   (0xFF)
 Magic octet indicating the end of frame.
 
#define DOSE_OCTET_ESC   (0xFE)
 Magic octet escaping 0xFF in byte stream.
 

Flag definitions

Hold in dose_t.flags

#define DOSE_FLAG_RECV_BUF_DIRTY   (BIT0)
 Receive buffer contains a complete unhandled frame.
 
#define DOSE_FLAG_END_RECEIVED   (BIT1)
 END octet has been received.
 
#define DOSE_FLAG_ESC_RECEIVED   (BIT2)
 ESC octet has been received.
 
#define DOSE_FLAG_SEND_PENDING   (BIT3)
 A send operation is pending.
 

Opt definitions

Hold in dose_t.opts

#define DOSE_OPT_PROMISCUOUS   (BIT0)
 Don't check the destination MAC - pass every frame to upper layers.
 

Macro Definition Documentation

◆ CONFIG_DOSE_RX_BUF_LEN

#define CONFIG_DOSE_RX_BUF_LEN   (ETHERNET_FRAME_LEN + DOSE_FRAME_CRC_LEN)

DOSE RX buffer length Should be large enough to fit at least one Ethernet frame.

Definition at line 169 of file dose.h.

◆ DOSE_FLAG_END_RECEIVED

#define DOSE_FLAG_END_RECEIVED   (BIT1)

END octet has been received.

Definition at line 134 of file dose.h.

◆ DOSE_FLAG_ESC_RECEIVED

#define DOSE_FLAG_ESC_RECEIVED   (BIT2)

ESC octet has been received.

Definition at line 135 of file dose.h.

◆ DOSE_FLAG_RECV_BUF_DIRTY

#define DOSE_FLAG_RECV_BUF_DIRTY   (BIT0)

Receive buffer contains a complete unhandled frame.

Definition at line 133 of file dose.h.

◆ DOSE_FLAG_SEND_PENDING

#define DOSE_FLAG_SEND_PENDING   (BIT3)

A send operation is pending.

Definition at line 136 of file dose.h.

◆ DOSE_FRAME_CRC_LEN

#define DOSE_FRAME_CRC_LEN   (2)

CRC16 is used.

Definition at line 162 of file dose.h.

◆ DOSE_OCTET_END

#define DOSE_OCTET_END   (0xFF)

Magic octet indicating the end of frame.

Definition at line 95 of file dose.h.

◆ DOSE_OCTET_ESC

#define DOSE_OCTET_ESC   (0xFE)

Magic octet escaping 0xFF in byte stream.

Definition at line 96 of file dose.h.

◆ DOSE_OPT_PROMISCUOUS

#define DOSE_OPT_PROMISCUOUS   (BIT0)

Don't check the destination MAC - pass every frame to upper layers.

Definition at line 144 of file dose.h.

◆ DOSE_TIMER_DEV

#define DOSE_TIMER_DEV   TIMER_DEV(…)

Hardware timer to use with the dose_watchdog module.

     This will be used to detect RX timeout instead of ztimer to speed up
     the RX path when high data rates / less CPU overhead is required.

Definition at line 179 of file dose.h.

Enumeration Type Documentation

◆ dose_signal_t

Enumerator
DOSE_SIGNAL_NONE 

No signal ...

DOSE_SIGNAL_INIT 

Init the state machine.

DOSE_SIGNAL_GPIO 

Sense GPIO detected a falling edge.

DOSE_SIGNAL_UART 

Octet has been received.

DOSE_SIGNAL_ZTIMER 

Timer timed out.

DOSE_SIGNAL_SEND 

Enter send state.

DOSE_SIGNAL_END 

Leave send state.

Definition at line 118 of file dose.h.

◆ dose_state_t

Enumerator
DOSE_STATE_INIT 

Initial state that will never be reentered.

DOSE_STATE_BLOCKED 

The driver just listens to incoming frames and blocks outgress frames.

DOSE_STATE_IDLE 

Frames will be received or sent.

DOSE_STATE_RECV 

Currently receiving a frame.

DOSE_STATE_SEND 

Currently sending a frame.

DOSE_STATE_STANDBY 

Receiver is turned off, but send will wake it up.

DOSE_STATE_SLEEP 

Receiver is turned off and send will be discarded.

DOSE_STATE_ANY 

Special state filter used internally to observe any state transition.

Definition at line 103 of file dose.h.

Function Documentation

◆ dose_setup()

void dose_setup ( dose_t dev,
const dose_params_t params,
uint8_t  index 
)

Setup a DOSE based device state.

Parameters
[out]devHandle of the device to initialize
[in]paramsParameters for device initialization
[in]indexIndex of params in a global parameter struct array. If initialized manually, pass a unique identifier instead.