or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bit-timing.mdbus-operations.mdcli-tools.mdevent-system.mdfile-io.mdhardware-interfaces.mdindex.mdmessage-handling.mdperiodic-transmission.md

bit-timing.mddocs/

0

# Bit Timing Configuration

1

2

CAN bit timing calculation and configuration utilities for both CAN 2.0 and CAN FD, supporting various calculation methods including sample point-based timing, register-based configuration, and bitrate-based parameter calculation.

3

4

## Capabilities

5

6

### CAN 2.0 Bit Timing

7

8

Configure bit timing parameters for standard CAN 2.0 communication.

9

10

```python { .api }

11

class BitTiming:

12

def __init__(self, f_clock: int, brp: int, tseg1: int, tseg2: int, sjw: int,

13

nof_samples: int = 1, strict: bool = False):

14

"""

15

Create CAN 2.0 bit timing configuration.

16

17

Parameters:

18

- f_clock: CAN system clock frequency in Hz

19

- brp: Bit rate prescaler (1-1024)

20

- tseg1: Time segment 1 (number of quanta from sync to sampling point)

21

- tseg2: Time segment 2 (number of quanta from sampling point to end)

22

- sjw: Synchronization jump width (1 to min(4, tseg1, tseg2))

23

- nof_samples: Number of samples (1 or 3)

24

- strict: If True, raise exceptions for invalid parameters

25

"""

26

27

@classmethod

28

def from_bitrate_and_segments(cls, f_clock: int, bitrate: int, tseg1: int,

29

tseg2: int, sjw: int, nof_samples: int = 1):

30

"""

31

Create bit timing from bitrate and time segments.

32

33

Parameters:

34

- f_clock: CAN system clock frequency in Hz

35

- bitrate: Desired bit rate in bits per second

36

- tseg1: Time segment 1 in quanta

37

- tseg2: Time segment 2 in quanta

38

- sjw: Synchronization jump width in quanta

39

- nof_samples: Number of samples per bit

40

41

Returns:

42

BitTiming instance with calculated prescaler

43

"""

44

45

@classmethod

46

def from_registers(cls, f_clock: int, btr0: int, btr1: int):

47

"""

48

Create bit timing from BTR register values.

49

50

Parameters:

51

- f_clock: CAN system clock frequency in Hz

52

- btr0: Bus Timing Register 0 value

53

- btr1: Bus Timing Register 1 value

54

55

Returns:

56

BitTiming instance decoded from register values

57

"""

58

59

@classmethod

60

def from_sample_point(cls, f_clock: int, bitrate: int, sample_point: float):

61

"""

62

Calculate bit timing for desired sample point percentage.

63

64

Parameters:

65

- f_clock: CAN system clock frequency in Hz

66

- bitrate: Desired bit rate in bits per second

67

- sample_point: Desired sample point as percentage (e.g., 75.0 for 75%)

68

69

Returns:

70

BitTiming instance with calculated parameters

71

"""

72

```

73

74

### CAN FD Bit Timing

75

76

Configure bit timing for CAN FD with separate arbitration and data phase parameters.

77

78

```python { .api }

79

class BitTimingFd:

80

def __init__(self, f_clock: int, nom_brp: int, nom_tseg1: int, nom_tseg2: int,

81

nom_sjw: int, data_brp: int, data_tseg1: int, data_tseg2: int,

82

data_sjw: int, nom_sam: bool = False):

83

"""

84

Create CAN FD bit timing configuration.

85

86

Parameters:

87

- f_clock: CAN system clock frequency in Hz

88

- nom_brp: Nominal (arbitration) bit rate prescaler

89

- nom_tseg1: Nominal time segment 1

90

- nom_tseg2: Nominal time segment 2

91

- nom_sjw: Nominal synchronization jump width

92

- data_brp: Data phase bit rate prescaler

93

- data_tseg1: Data phase time segment 1

94

- data_tseg2: Data phase time segment 2

95

- data_sjw: Data phase synchronization jump width

96

- nom_sam: Nominal phase sampling (False=1 sample, True=3 samples)

97

"""

98

99

@classmethod

100

def from_bitrates_and_sample_points(cls, f_clock: int, nom_bitrate: int,

101

data_bitrate: int, nom_sample_point: float,

102

data_sample_point: float):

103

"""

104

Calculate CAN FD timing from bitrates and sample points.

105

106

Parameters:

107

- f_clock: System clock frequency in Hz

108

- nom_bitrate: Nominal (arbitration) phase bitrate

109

- data_bitrate: Data phase bitrate

110

- nom_sample_point: Nominal phase sample point percentage

111

- data_sample_point: Data phase sample point percentage

112

113

Returns:

114

BitTimingFd instance with calculated parameters

115

"""

116

```

117

118

### Bit Timing Properties

119

120

Access calculated timing properties and register values.

121

122

```python { .api }

123

# BitTiming properties

124

@property

125

def bitrate(self) -> int:

126

"""Calculated bitrate in bits per second."""

127

128

@property

129

def sample_point(self) -> float:

130

"""Sample point as percentage of bit time."""

131

132

@property

133

def btr0(self) -> int:

134

"""Bus Timing Register 0 value."""

135

136

@property

137

def btr1(self) -> int:

138

"""Bus Timing Register 1 value."""

139

140

@property

141

def tseg(self) -> int:

142

"""Total time segments (tseg1 + tseg2)."""

143

144

# Dictionary-like access

145

def __getitem__(self, key: str):

146

"""Access timing parameters as dictionary keys."""

147

148

def keys(self):

149

"""Get available parameter keys."""

150

151

def values(self):

152

"""Get parameter values."""

153

154

def items(self):

155

"""Get parameter key-value pairs."""

156

```

157

158

## Usage Examples

159

160

### Basic Bit Timing Configuration

161

162

```python

163

import can

164

165

# Create bit timing for 500 kbps with 8 MHz clock

166

timing = can.BitTiming(

167

f_clock=8_000_000, # 8 MHz clock

168

brp=1, # Prescaler = 1

169

tseg1=13, # Time segment 1 = 13 quanta

170

tseg2=2, # Time segment 2 = 2 quanta

171

sjw=1 # SJW = 1 quantum

172

)

173

174

print(f"Configured bitrate: {timing.bitrate} bps")

175

print(f"Sample point: {timing.sample_point:.1f}%")

176

print(f"BTR registers: BTR0=0x{timing.btr0:02X}, BTR1=0x{timing.btr1:02X}")

177

```

178

179

### Calculate from Bitrate and Sample Point

180

181

```python

182

import can

183

184

# Calculate timing for 1 Mbps with 87.5% sample point

185

timing = can.BitTiming.from_sample_point(

186

f_clock=16_000_000, # 16 MHz clock

187

bitrate=1_000_000, # 1 Mbps

188

sample_point=87.5 # 87.5% sample point

189

)

190

191

print(f"Calculated parameters:")

192

print(f" BRP: {timing['brp']}")

193

print(f" TSEG1: {timing['tseg1']}")

194

print(f" TSEG2: {timing['tseg2']}")

195

print(f" SJW: {timing['sjw']}")

196

print(f"Actual bitrate: {timing.bitrate} bps")

197

print(f"Actual sample point: {timing.sample_point:.1f}%")

198

```

199

200

### CAN FD Bit Timing

201

202

```python

203

import can

204

205

# CAN FD with 500 kbps arbitration, 2 Mbps data phase

206

fd_timing = can.BitTimingFd(

207

f_clock=40_000_000, # 40 MHz clock

208

# Nominal (arbitration) phase - 500 kbps

209

nom_brp=5,

210

nom_tseg1=13,

211

nom_tseg2=2,

212

nom_sjw=1,

213

# Data phase - 2 Mbps

214

data_brp=1,

215

data_tseg1=15,

216

data_tseg2=4,

217

data_sjw=1

218

)

219

220

print(f"Arbitration phase: {fd_timing.nom_bitrate} bps")

221

print(f"Data phase: {fd_timing.data_bitrate} bps")

222

print(f"Speed improvement: {fd_timing.data_bitrate / fd_timing.nom_bitrate:.1f}x")

223

```

224

225

### Multiple Standard Bitrates

226

227

```python

228

import can

229

230

# Common CAN bitrates with 8 MHz clock

231

standard_configs = {

232

'125k': can.BitTiming(f_clock=8_000_000, brp=4, tseg1=13, tseg2=2, sjw=1),

233

'250k': can.BitTiming(f_clock=8_000_000, brp=2, tseg1=13, tseg2=2, sjw=1),

234

'500k': can.BitTiming(f_clock=8_000_000, brp=1, tseg1=13, tseg2=2, sjw=1),

235

'1M': can.BitTiming(f_clock=8_000_000, brp=1, tseg1=5, tseg2=2, sjw=1)

236

}

237

238

print("Standard CAN bitrate configurations:")

239

for name, timing in standard_configs.items():

240

print(f"{name:>4}: {timing.bitrate:>7} bps, "

241

f"SP={timing.sample_point:4.1f}%, "

242

f"BTR0=0x{timing.btr0:02X}, BTR1=0x{timing.btr1:02X}")

243

```

244

245

### Bit Timing Validation

246

247

```python

248

import can

249

250

def validate_timing(timing, target_bitrate, tolerance=0.01):

251

"""Validate bit timing against target bitrate."""

252

actual_rate = timing.bitrate

253

error = abs(actual_rate - target_bitrate) / target_bitrate

254

255

print(f"Target: {target_bitrate} bps")

256

print(f"Actual: {actual_rate} bps")

257

print(f"Error: {error * 100:.3f}%")

258

259

if error <= tolerance:

260

print("✓ Timing within tolerance")

261

return True

262

else:

263

print("✗ Timing exceeds tolerance")

264

return False

265

266

# Test different configurations

267

configs_to_test = [

268

(8_000_000, 500_000, {'brp': 1, 'tseg1': 13, 'tseg2': 2, 'sjw': 1}),

269

(10_000_000, 250_000, {'brp': 5, 'tseg1': 6, 'tseg2': 1, 'sjw': 1}),

270

(16_000_000, 1_000_000, {'brp': 1, 'tseg1': 13, 'tseg2': 2, 'sjw': 1})

271

]

272

273

for f_clock, target_rate, params in configs_to_test:

274

print(f"\nTesting {f_clock/1e6:.0f} MHz clock, {target_rate/1000:.0f} kbps:")

275

timing = can.BitTiming(f_clock=f_clock, **params)

276

validate_timing(timing, target_rate)

277

```

278

279

### Using Bit Timing with Bus

280

281

```python

282

import can

283

284

# Calculate optimal timing for hardware

285

timing = can.BitTiming.from_sample_point(

286

f_clock=16_000_000,

287

bitrate=500_000,

288

sample_point=80.0

289

)

290

291

# Use timing parameters with bus (example for socketcan)

292

bus = can.Bus(

293

channel='can0',

294

interface='socketcan',

295

# Note: Most interfaces handle timing automatically

296

# This is conceptual - actual parameter names vary by interface

297

bitrate=timing.bitrate

298

)

299

300

print(f"Bus configured for {timing.bitrate} bps")

301

bus.shutdown()

302

```

303

304

### Register-Based Configuration

305

306

```python

307

import can

308

309

# Create timing from existing BTR register values

310

# (e.g., read from hardware or configuration file)

311

timing_from_regs = can.BitTiming.from_registers(

312

f_clock=8_000_000,

313

btr0=0x00, # BRP-1 in lower 6 bits, SJW-1 in upper 2 bits

314

btr1=0xDE # TSEG1-1 in lower 4 bits, TSEG2-1 in upper 3 bits, SAM in bit 7

315

)

316

317

print(f"Decoded from registers:")

318

print(f" Bitrate: {timing_from_regs.bitrate} bps")

319

print(f" BRP: {timing_from_regs['brp']}")

320

print(f" TSEG1: {timing_from_regs['tseg1']}")

321

print(f" TSEG2: {timing_from_regs['tseg2']}")

322

```

323

324

## Types

325

326

```python { .api }

327

from typing import Union, Dict, Any

328

from collections.abc import Mapping

329

330

class BitTiming(Mapping[str, int]):

331

"""CAN 2.0 bit timing configuration with dictionary-like access."""

332

333

def __init__(self, f_clock: int, brp: int, tseg1: int, tseg2: int,

334

sjw: int, nof_samples: int = 1, strict: bool = False): ...

335

336

# Properties

337

f_clock: int

338

brp: int

339

tseg1: int

340

tseg2: int

341

sjw: int

342

nof_samples: int

343

344

@property

345

def bitrate(self) -> int: ...

346

@property

347

def sample_point(self) -> float: ...

348

@property

349

def btr0(self) -> int: ...

350

@property

351

def btr1(self) -> int: ...

352

353

class BitTimingFd:

354

"""CAN FD bit timing configuration with dual-phase parameters."""

355

356

def __init__(self, f_clock: int, nom_brp: int, nom_tseg1: int,

357

nom_tseg2: int, nom_sjw: int, data_brp: int,

358

data_tseg1: int, data_tseg2: int, data_sjw: int,

359

nom_sam: bool = False): ...

360

361

# Properties for both phases

362

@property

363

def nom_bitrate(self) -> int: ...

364

@property

365

def data_bitrate(self) -> int: ...

366

@property

367

def nom_sample_point(self) -> float: ...

368

@property

369

def data_sample_point(self) -> float: ...

370

```