forked from micropython/micropython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmachine_can_port.h
More file actions
188 lines (151 loc) · 6.82 KB
/
machine_can_port.h
File metadata and controls
188 lines (151 loc) · 6.82 KB
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
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024-2026 Angus Gratton
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_EXTMOD_MACHINE_CAN_PORT_H
#define MICROPY_INCLUDED_EXTMOD_MACHINE_CAN_PORT_H
#include "py/obj.h"
#include "py/objarray.h"
#include "py/runtime.h"
#include "shared/runtime/mpirq.h"
// This header is included into both extmod/machine_can.c and port-specific
// machine_can.c implementations and provides shared (static) function
// declarations to both.
//
// In a MicroPython build including this header from port-specific machine_can.c
// include is a no-op (as the file is included directly into
// extmod/machine_can.c). However, including it anyway means that Language
// Servers and IDEs can correctly analyse the machine_can.c file while the
// developer is writing it.
typedef enum {
MP_CAN_STATE_STOPPED,
MP_CAN_STATE_ACTIVE,
MP_CAN_STATE_WARNING,
MP_CAN_STATE_PASSIVE,
MP_CAN_STATE_BUS_OFF,
} machine_can_state_t;
typedef enum {
MP_CAN_MODE_NORMAL,
MP_CAN_MODE_SLEEP,
MP_CAN_MODE_LOOPBACK,
MP_CAN_MODE_SILENT,
MP_CAN_MODE_SILENT_LOOPBACK,
MP_CAN_MODE_MAX,
} machine_can_mode_t;
// CAN IRQ Flags
// (currently the same for all ports)
#define MP_CAN_IRQ_TX (1 << 0)
#define MP_CAN_IRQ_RX (1 << 1)
#define MP_CAN_IRQ_TX_FAILED (1 << 2)
#define MP_CAN_IRQ_STATE (1 << 3)
// Transmit buffer index is encoded into the irq().flags() response for MP_CAN_IRQ_TX
#define MP_CAN_IRQ_IDX_SHIFT 16
#define MP_CAN_IRQ_IDX_MASK 0xFF
#if MICROPY_HW_ENABLE_FDCAN
#define MP_CAN_MAX_LEN 64
#else
#define MP_CAN_MAX_LEN 8
#endif
struct machine_can_port;
// These values appear in the same order as the result of CAN.get_counters()
typedef struct {
mp_uint_t tec;
mp_uint_t rec;
mp_uint_t num_warning; // Number of "Error Warning" transitions
mp_uint_t num_passive; // Number of "Error Passive" transitions
mp_uint_t num_bus_off; // Number of "Bus-Off" transitions
mp_uint_t tx_pending;
mp_uint_t rx_pending;
mp_uint_t rx_overruns;
} machine_can_counters_t;
typedef struct _machine_can_obj_t {
mp_obj_base_t base;
mp_uint_t can_idx;
// Timing register settings
byte tseg1;
byte tseg2;
byte brp;
byte sjw;
machine_can_mode_t mode;
mp_irq_obj_t *mp_irq_obj;
uint16_t mp_irq_trigger;
mp_uint_t rx_error_flags;
// Assumed some of these counters are updated from different port ISRs, etc. and some
// are updated by calling machine_can_port_update_counters()
machine_can_counters_t counters;
struct machine_can_port *port;
} machine_can_obj_t;
// Indexes for recv result list
typedef enum {
RECV_ARG_ID,
RECV_ARG_DATA,
RECV_ARG_FLAGS,
RECV_ARG_ERRORS,
RECV_ARG_LEN, // Overall length, not an index
} recv_arg_idx_t;
#define CAN_STD_ID_MASK 0x7FF
#define CAN_EXT_ID_MASK 0x1fffffff
// CAN Message Flags
#define CAN_MSG_FLAG_RTR (1 << 0)
#define CAN_MSG_FLAG_EXT_ID (1 << 1)
#define CAN_MSG_FLAG_FD_F (1 << 2)
#define CAN_MSG_FLAG_BRS (1 << 3)
#define CAN_MSG_FLAG_UNORDERED (1 << 4)
// CAN recv() Error Flags
#define CAN_RECV_ERR_FULL (1 << 0)
#define CAN_RECV_ERR_OVERRUN (1 << 1)
#define CAN_RECV_ERR_ESI (1 << 2)
// The port must provide implementations of these low-level CAN functions
static int machine_can_port_f_clock(const machine_can_obj_t *self);
static bool machine_can_port_supports_mode(const machine_can_obj_t *self, machine_can_mode_t mode);
static void machine_can_port_clear_filters(machine_can_obj_t *self);
static mp_uint_t machine_can_port_max_data_len(mp_uint_t flags);
// The extmod layer calls this function in a loop with incrementing filter_idx
// values. It's up to the port how to apply the filters from here, and to raise
// an exception if there are too many.
//
// If the CAN_FILTERS_STD_EXT_SEPARATE flag is set to 1, filter_idx will
// enumerate standard id filters separately to extended id filters (the
// CAN_MSG_FLAG_EXT_ID bit in 'flags' differentiates the type).
static void machine_can_port_set_filter(machine_can_obj_t *self, int filter_idx, mp_uint_t can_id, mp_uint_t mask, mp_uint_t flags);
// Update interrupt configuration based on the new contents of 'self'
static void machine_can_update_irqs(machine_can_obj_t *self);
// Return the irq().flags() result. Calling this function may also update the hardware state machine.
static mp_uint_t machine_can_port_irq_flags(machine_can_obj_t *self);
static void machine_can_port_init(machine_can_obj_t *self);
static void machine_can_port_deinit(machine_can_obj_t *self);
static mp_int_t machine_can_port_send(machine_can_obj_t *self, mp_uint_t id, const byte *data, size_t data_len, mp_uint_t flags);
static bool machine_can_port_cancel_send(machine_can_obj_t *self, mp_uint_t idx);
static bool machine_can_port_recv(machine_can_obj_t *self, void *data, size_t *dlen, mp_uint_t *id, mp_uint_t *flags, mp_uint_t *errors);
static machine_can_state_t machine_can_port_get_state(machine_can_obj_t *self);
static void machine_can_port_restart(machine_can_obj_t *self);
// Updates values in self->counters (which counters are updated by this function versus from ISRs and the like
// is port specific
static void machine_can_port_update_counters(machine_can_obj_t *self);
// Hook for port to fill in the final item of the get_timings() result list with controller-specific values
static mp_obj_t machine_can_port_get_additional_timings(machine_can_obj_t *self, mp_obj_t optional_arg);
// This function is only optionally defined by the port. If macro CAN_PORT_PRINT_FUNCTION is not set
// then a default machine_can_print function will be used.
static void machine_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind);
#endif // MICROPY_INCLUDED_EXTMOD_MACHINE_CAN_PORT_H