Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | /** @file
* @brief IPv6 Networking over CAN definitions.
*
* Definitions for IPv6 Networking over CAN support.
*/
/*
* Copyright (c) 2019 Alexander Wachter
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_NET_CAN_H_
#define ZEPHYR_INCLUDE_NET_CAN_H_
#include <zephyr/types.h>
#include <net/net_ip.h>
#include <net/net_if.h>
#include <can.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief IPv6 over CAN library
* @defgroup net_can Network Core Library
* @ingroup networking
* @{
*/
/**
* CAN L2 driver API. Used by 6loCAN.
*/
/*
* Abbreviations
* BS Block Size
* CAN_DL CAN LL data size
* CF Consecutive Frame
* CTS Continue to send
* DLC Data length code
* FC Flow Control
* FF First Frame
* FS Flow Status
*/
/** @cond INTERNAL_HIDDEN */
#define NET_CAN_DL 8
#define NET_CAN_MTU 0x0FFF
/* 0x3DFF - bit 4 to 10 must not be zero. Also prevent stuffing bit*/
#define NET_CAN_MULTICAST_ADDR 0x3DFF
#define NET_CAN_DAD_ADDR 0x3DFE
#define NET_CAN_ETH_TRANSLATOR_ADDR 0x3DF0
#define NET_CAN_MAX_ADDR 0x3DEF
#define NET_CAN_MIN_ADDR 0x0100
#define CAN_NET_IF_ADDR_MASK 0x3FFF
#define CAN_NET_IF_ADDR_BYTE_LEN 2U
#define CAN_NET_IF_ADDR_DEST_POS 14U
#define CAN_NET_IF_ADDR_DEST_MASK (CAN_NET_IF_ADDR_MASK << CAN_NET_IF_ADDR_DEST_POS)
#define CAN_NET_IF_ADDR_SRC_POS 0U
#define CAN_NET_IF_ADDR_SRC_MASK (CAN_NET_IF_ADDR_MASK << CAN_NET_IF_ADDR_SRC_POS)
#define CAN_NET_IF_ADDR_MCAST_POS 28U
#define CAN_NET_IF_ADDR_MCAST_MASK (1UL << CAN_NET_IF_ADDR_MCAST_POS)
#define CAN_NET_IF_IS_MCAST_BIT (1U << 14)
#define CAN_NET_FILTER_NOT_SET -1
/** @endcond */
/*
* +-----------+ +-----------+
* | | | |
* | IPv6 | | IPv6 |
* | 6LoCAN | | 6LoCAN |
* | | | |
* +----+-+----+ +----+-+----+
* | | | | +---+
* +----+ | | | | / \ +-+
* | | | | | | +--+ / \_/ \
* +++ +---+ +--+----+ +-------+ +--+----+ +--/ \_/ \
* | | \ / | \ / \ / | \ / / |
* | | X | X CAN X | X | Internet |
* | | / \ | / \ / \ | / \ \ /
* +++ +---+ +----+--+ +-------+ +----+--+ +--+ /
* | | +-------------------+
* +----+
*/
struct net_can_api {
/**
* The net_if_api must be placed in first position in this
* struct so that we are compatible with network interface API.
*/
struct net_if_api iface_api;
/** Send a single CAN frame */
int (*send)(struct device *dev, const struct zcan_frame *frame,
can_tx_callback_t cb, void *cb_arg, s32_t timeout);
/** Attach a filter with it's callback */
int (*attach_filter)(struct device *dev, can_rx_callback_t cb,
void *cb_arg, const struct zcan_filter *filter);
/** Detach a filter */
void (*detach_filter)(struct device *dev, int filter_id);
/** Enable or disable the reception of frames for net CAN */
int (*enable)(struct device *dev, bool enable);
};
/** @cond INTERNAL_HIDDEN */
#define CANBUS_L2_CTX_TYPE struct net_canbus_context *
/**
* Context for canbus net device.
*/
struct canbus_net_ctx {
/** Filter ID for link layer duplicate address detection. */
int dad_filter_id;
/** Work item for responding to link layer DAD requests. */
struct k_work dad_work;
/** The interface associated with this device */
struct net_if *iface;
/** The link layer address chosen for this interface */
u16_t ll_addr;
};
/**
* Canbus link layer addresses have a length of 14 bit for source and destination.
* Both together are 28 bit to fit a CAN extended identifier with 29 bit length.
*/
struct net_canbus_lladdr {
u16_t addr : 14;
};
/**
* STmin is split in two valid ranges:
* 0-127: 0ms-127ms
* 128-240: Reserved
* 241-249: 100us-900us (multiples of 100us)
* 250- : Reserved
*/
struct canbus_fc_opts {
/** Block size. Number of CF PDUs before next CF is sent */
u8_t bs;
/**< Minimum separation time. Min time between frames */
u8_t stmin;
};
/**
* Context for a transmission of messages that didn't fit in a single frame.
* These messages Start with a FF (First Frame) that is in case of unicast
* acknowledged by a FC (Frame Control). After that, one or more CF
* (Consecutive frames) carry the rest of the message.
*/
struct canbus_isotp_tx_ctx {
/** Pkt containing the data to transmit */
struct net_pkt *pkt;
/** Timeout for TX Timeout and separation time */
struct _timeout timeout;
/** Frame Control options received from FC frame */
struct canbus_fc_opts opts;
/** CAN destination address */
struct net_canbus_lladdr dest_addr;
/** Remaining data to transmit in bytes */
u16_t rem_len;
/** Number of bytes in the tx queue */
s8_t tx_backlog;
/** State of the transmission */
u8_t state;
/** Actual block number that is transmitted. Counts from BS to 0 */
u8_t act_block_nr;
/** Number of WAIT frames received */
u8_t wft;
/** Sequence number that is added to CF */
u8_t sn : 4;
/** Transmission is multicast */
u8_t is_mcast : 1;
};
/**
* Context for reception of messages that are not single frames.
* This is the counterpart of the canbus_isotp_tx_ctx.
*/
struct canbus_isotp_rx_ctx {
/** Pkt that is large enough to hold the entire message */
struct net_pkt *pkt;
/** Timeout for RX timeout*/
struct _timeout timeout;
/** Remaining data to receive. Goes from message length to zero */
u16_t rem_len;
/** State of the reception */
u8_t state;
/** Number of frames received in this block. Counts from BS to 0 */
u8_t act_block_nr;
/** Number of WAIT frames transmitted */
u8_t wft;
/** Expected sequence number in CF */
u8_t sn : 4;
};
/**
* Initialization of the canbus L2.
*
* This function starts the TX workqueue and does some initialization.
*/
void net_6locan_init(struct net_if *iface);
/**
* Ethernet frame input function for Ethernet to 6LoCAN translation
*
* This function checks the destination link layer address for addresses
* that has to be forwarded. Frames that need to be forwarded are forwarded here.
*/
enum net_verdict net_canbus_translate_eth_frame(struct net_if *iface,
struct net_pkt *pkt);
/** @endcond */
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_NET_CAN_H_ */
|