Skip to content

Commit 8c3087a

Browse files
Merge pull request #318 from marckleinebudde/add-tdc-support
add TDC support
2 parents 4037812 + e7ce91e commit 8c3087a

8 files changed

Lines changed: 306 additions & 71 deletions

File tree

include/can.h

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,38 @@
3434
#include "led.h"
3535
#include "list.h"
3636

37+
struct can_drv_reg_status {
38+
#if defined (CONFIG_BXCAN)
39+
uint32_t esr;
40+
#endif
41+
};
42+
43+
enum can_channel_flag {
44+
CAN_CHANNEL_FLAG_BITTIMING_SET = BIT(0),
45+
CAN_CHANNEL_FLAG_DATA_BITTIMING_SET = BIT(1),
46+
CAN_CHANNEL_FLAG_TDC_SET = BIT(2),
47+
};
48+
3749
#define CAN_CHANNEL_BUS_OFF_RESTART_DISABLED 0
3850

3951
typedef struct can_channel {
4052
#if defined (CONFIG_BXCAN)
4153
CAN_TypeDef *instance;
4254
#endif
55+
struct can_drv_reg_status reg_status;
4356
struct list_head list_from_host;
4457
led_data_t leds;
4558
uint32_t feature;
59+
enum can_channel_flag flags;
4660
enum gs_can_state state;
4761
uint32_t bus_off_restart;
62+
struct gs_device_bittiming bittiming;
63+
#ifdef CONFIG_CANFD
64+
struct gs_device_bittiming data_bittiming;
65+
struct gs_device_tdc tdc;
66+
#endif
4867
#if defined (CONFIG_BXCAN)
4968
struct gs_device_filter filter;
50-
uint32_t btr;
5169
#endif
5270
#if (NUM_CAN_CHANNEL > 1)
5371
uint8_t nr;
@@ -57,21 +75,11 @@ typedef struct can_channel {
5775
extern const struct gs_device_bt_const CAN_btconst;
5876
extern const struct gs_device_bt_const_extended CAN_btconst_ext;
5977
extern const struct gs_device_filter_info CAN_filter_info;
78+
extern const struct gs_device_tdc_const CAN_tdc_const;
6079

6180
struct board_channel_config;
6281

6382
void can_init(can_data_t *channel, const struct board_channel_config *config);
64-
void can_set_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing);
65-
66-
#ifdef CONFIG_CANFD
67-
void can_set_data_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing);
68-
#else
69-
static inline bool can_set_data_bittiming(can_data_t __maybe_unused *channel,
70-
const struct gs_device_bittiming __maybe_unused *timing)
71-
{
72-
return false;
73-
}
74-
#endif
7583

7684
#ifdef CONFIG_CAN_FILTER
7785
void can_set_filter(can_data_t *channel, const struct gs_device_filter *filter);

include/can_common.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,37 @@
4040
#define CAN_LEC_CRC_ERROR 6
4141
#define CAN_LEC_SOFTWARE 7
4242

43+
bool can_check_feature_ok(const can_data_t *channel, const uint32_t feature);
4344
bool can_check_bittiming_ok(const struct can_bittiming_const *btc, const struct gs_device_bittiming *timing);
45+
void can_set_bittiming(struct can_channel *channel, const struct gs_device_bittiming *bt);
46+
47+
#ifdef CONFIG_CANFD
48+
void can_set_data_bittiming(struct can_channel *channel, const struct gs_device_bittiming *timing);
49+
bool can_check_tdc_ok(const struct gs_device_tdc_const *tdc_const, const struct gs_device_tdc *tdc);
50+
void can_set_tdc(struct can_channel *channel, const struct gs_device_tdc *tdc);
51+
void can_get_device_tdc(const struct can_channel *channel, struct gs_device_tdc *tdc);
52+
#else
53+
static inline void can_set_data_bittiming(struct can_channel __maybe_unused *channel,
54+
const struct gs_device_bittiming __maybe_unused *timing)
55+
{
56+
}
57+
58+
static inline bool can_check_tdc_ok(const struct gs_device_tdc_const __maybe_unused *tdc_const,
59+
const struct gs_device_tdc __maybe_unused *tdc)
60+
{
61+
return false;
62+
}
63+
64+
static inline void can_set_tdc(struct can_channel __maybe_unused *channel,
65+
const struct gs_device_tdc __maybe_unused *tdc)
66+
{
67+
}
68+
69+
static inline void can_get_device_tdc(const struct can_channel __maybe_unused *channel,
70+
struct gs_device_tdc __maybe_unused *tdc)
71+
{
72+
}
73+
#endif
4474

4575
#ifdef CONFIG_CAN_FILTER
4676
bool can_check_filter_ok(const struct gs_device_filter *filter);

include/can_drv.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,23 @@
2929
#include <stdint.h>
3030

3131
struct can_channel;
32+
struct can_drv_reg_status;
3233
struct gs_device_state;
34+
struct gs_device_tdc;
3335
struct gs_host_frame;
3436

3537
void can_drv_enable(struct can_channel *channel);
3638
void can_drv_disable(struct can_channel *channel);
3739

38-
uint32_t can_drv_read_reg_status(const struct can_channel *channel);
40+
void can_drv_get_device_tdc(const struct can_channel *channel, struct gs_device_tdc *tdc);
3941

40-
bool can_drv_bus_error_pending(const uint32_t reg);
41-
bool can_drv_handle_bus_error(const struct can_channel *channel, struct gs_host_frame *frame, const uint32_t reg);
42+
void can_drv_read_reg_status(struct can_channel *channel);
4243

43-
enum gs_can_state can_drv_get_state(const uint32_t reg);
44-
void can_drv_get_device_state(const struct can_channel *channel, struct gs_device_state *state, const uint32_t reg);
45-
void can_drv_handle_state_change(const struct can_channel *channel, struct gs_host_frame *frame, const uint32_t reg);
44+
bool can_drv_bus_error_pending(const struct can_channel *channel);
45+
bool can_drv_handle_bus_error(const struct can_channel *channel, struct gs_host_frame *frame);
46+
47+
enum gs_can_state can_drv_get_state(const struct can_channel *channel);
48+
void can_drv_get_device_state(const struct can_channel *channel, struct gs_device_state *state);
49+
void can_drv_handle_state_change(const struct can_channel *channel, struct gs_host_frame *frame);
4650

4751
void can_drv_handle_bus_off_recovery(struct can_channel *channel);

include/gs_usb.h

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@
7575
* - struct gs_device_filter
7676
*/
7777
#define GS_CAN_FEATURE_FILTER (1<<16)
78+
/* device supports TDC configuration, see:
79+
* - GS_USB_BREQ_GET_TDC_CONST
80+
* - GS_USB_BREQ_SET_TDC
81+
* - GS_USB_BREQ_GET_TDC
82+
* - struct gs_device_tdc_const
83+
* - struct gs_device_tdc
84+
*/
85+
#define GS_CAN_FEATURE_TDC (1<<17)
7886
/* device support CAN bus off recovery
7987
* - GS_USB_BREQ_BUS_OFF_RECOVERY
8088
* - struct gs_device_bus_off_recovery
@@ -186,9 +194,9 @@ enum gs_usb_breq {
186194
GS_USB_BREQ_GET_STATE,
187195
GS_USB_BREQ_SET_FILTER,
188196
GS_USB_BREQ_GET_FILTER,
189-
__GS_USB_BREQ_PLACEHOLDER_17,
190-
__GS_USB_BREQ_PLACEHOLDER_18,
191-
__GS_USB_BREQ_PLACEHOLDER_19,
197+
GS_USB_BREQ_GET_TDC_CONST,
198+
GS_USB_BREQ_SET_TDC,
199+
GS_USB_BREQ_GET_TDC,
192200
GS_USB_BREQ_ELM_GET_BOARDINFO = 20,
193201
GS_USB_BREQ_ELM_SET_FILTER,
194202
GS_USB_BREQ_ELM_GET_LASTERROR,
@@ -325,6 +333,29 @@ struct gs_device_filter {
325333
};
326334
} __packed __aligned(4);
327335

336+
enum gs_device_tdc_mode {
337+
GS_CAN_TDC_MODE_OFF = BIT(0),
338+
GS_CAN_TDC_MODE_AUTO = BIT(1),
339+
GS_CAN_TDC_MODE_MANUAL = BIT(2),
340+
};
341+
342+
struct gs_device_tdc_const {
343+
u32 tdcv_min;
344+
u32 tdcv_max;
345+
u32 tdco_min;
346+
u32 tdco_max;
347+
u32 tdcf_min;
348+
u32 tdcf_max;
349+
u32 mode;
350+
} __packed __aligned(4);
351+
352+
struct gs_device_tdc {
353+
u32 tdcv;
354+
u32 tdco;
355+
u32 tdcf;
356+
enum gs_device_tdc_mode mode;
357+
} __packed __aligned(4);
358+
328359
struct gs_device_bus_off_recovery {
329360
u32 unused;
330361
} __packed __aligned(4);

include/usbd_gs_can.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ typedef struct {
8989

9090
// Device <-> Host
9191
struct gs_device_termination_state term_state;
92+
struct gs_device_tdc tdc;
9293
}; );
9394
uint8_t __aligned(4) buf[sizeof(struct ep0_data)];
9495
} ep0;

src/can/bxcan.c

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,6 @@ void can_init(can_data_t *channel, const struct board_channel_config *channel_co
103103
filter->fa1r = 0x1; // Enable filter bank 0
104104
}
105105

106-
void can_set_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing)
107-
{
108-
channel->btr = FIELD_PREP(CAN_BTR_SJW, timing->sjw - 1) |
109-
FIELD_PREP(CAN_BTR_TS2, timing->phase_seg2 - 1) |
110-
FIELD_PREP(CAN_BTR_TS1, timing->prop_seg + timing->phase_seg1 - 1) |
111-
FIELD_PREP(CAN_BTR_BRP, timing->brp - 1);
112-
}
113-
114106
#ifdef CONFIG_CAN_FILTER
115107
void can_set_filter(can_data_t *channel, const struct gs_device_filter *filter)
116108
{
@@ -160,7 +152,10 @@ void can_drv_enable(struct can_channel *channel)
160152
mcr |= CAN_MCR_NART;
161153
}
162154

163-
uint32_t btr = channel->btr;
155+
uint32_t btr = FIELD_PREP(CAN_BTR_SJW, channel->bittiming.sjw - 1) |
156+
FIELD_PREP(CAN_BTR_TS2, channel->bittiming.phase_seg2 - 1) |
157+
FIELD_PREP(CAN_BTR_TS1, channel->bittiming.prop_seg + channel->bittiming.phase_seg1 - 1) |
158+
FIELD_PREP(CAN_BTR_BRP, channel->bittiming.brp - 1);
164159

165160
if (feature & GS_CAN_FEATURE_LISTEN_ONLY) {
166161
btr |= CAN_MODE_SILENT;
@@ -302,28 +297,28 @@ bool can_send(can_data_t *channel, struct gs_host_frame *frame)
302297
}
303298
}
304299

305-
bool can_drv_bus_error_pending(const uint32_t reg_esr)
300+
bool can_drv_bus_error_pending(const struct can_channel *channel)
306301
{
302+
const uint32_t reg_esr = channel->reg_status.esr;
307303
const uint8_t lec = FIELD_GET(CAN_ESR_LEC, reg_esr);
308304

309305
return can_is_lec_error(lec);
310306
}
311307

312-
uint32_t can_drv_read_reg_status(const struct can_channel *channel)
308+
void can_drv_read_reg_status(struct can_channel *channel)
313309
{
314-
const uint32_t reg_esr = channel->instance->ESR;
310+
channel->reg_status.esr = channel->instance->ESR;
315311

316-
if (can_drv_bus_error_pending(reg_esr)) {
312+
if (can_drv_bus_error_pending(channel)) {
317313
/* mark as handled by software */
318314
channel->instance->ESR |= FIELD_PREP(CAN_ESR_LEC, CAN_LEC_SOFTWARE);
319315
}
320-
321-
return reg_esr;
322316
}
323317

324-
bool can_drv_handle_bus_error(const struct can_channel __maybe_unused *channel, struct gs_host_frame *frame,
325-
const uint32_t reg_esr)
318+
bool can_drv_handle_bus_error(const struct can_channel *channel, struct gs_host_frame *frame)
326319
{
320+
const uint32_t reg_esr = channel->reg_status.esr;
321+
327322
const uint8_t tx_err = FIELD_GET(CAN_ESR_TEC, reg_esr);
328323
const uint8_t rx_err = FIELD_GET(CAN_ESR_REC, reg_esr);
329324

@@ -341,8 +336,10 @@ bool can_drv_handle_bus_error(const struct can_channel __maybe_unused *channel,
341336
return true;
342337
}
343338

344-
enum gs_can_state can_drv_get_state(const uint32_t reg_esr)
339+
enum gs_can_state can_drv_get_state(const struct can_channel *channel)
345340
{
341+
const uint32_t reg_esr = channel->reg_status.esr;
342+
346343
if (!(reg_esr & (CAN_ESR_BOFF | CAN_ESR_EPVF | CAN_ESR_EWGF))) {
347344
return GS_CAN_STATE_ERROR_ACTIVE;
348345
}
@@ -358,25 +355,24 @@ enum gs_can_state can_drv_get_state(const uint32_t reg_esr)
358355
return GS_CAN_STATE_ERROR_WARNING;
359356
}
360357

361-
void can_drv_get_device_state(const struct can_channel __maybe_unused *channel, struct gs_device_state *state,
362-
const uint32_t reg_esr)
358+
void can_drv_get_device_state(const struct can_channel *channel, struct gs_device_state *state)
363359
{
364-
state->state = can_drv_get_state(reg_esr);
360+
const uint32_t reg_esr = channel->reg_status.esr;
361+
362+
state->state = can_drv_get_state(channel);
365363
state->rxerr = FIELD_GET(CAN_ESR_REC, reg_esr);
366364
state->txerr = FIELD_GET(CAN_ESR_TEC, reg_esr);
367365
}
368366

369-
void can_drv_handle_state_change(const struct can_channel __maybe_unused *channel, struct gs_host_frame *frame,
370-
const uint32_t reg_esr)
367+
void can_drv_handle_state_change(const struct can_channel *channel, struct gs_host_frame *frame)
371368
{
372-
enum gs_can_state tx_state, rx_state;
373-
uint8_t tx_err, rx_err;
369+
const uint32_t reg_esr = channel->reg_status.esr;
374370

375-
tx_err = FIELD_GET(CAN_ESR_TEC, reg_esr);
376-
rx_err = FIELD_GET(CAN_ESR_REC, reg_esr);
371+
const uint8_t tx_err = FIELD_GET(CAN_ESR_TEC, reg_esr);
372+
const uint8_t rx_err = FIELD_GET(CAN_ESR_REC, reg_esr);
377373

378-
tx_state = can_err_to_state(tx_err);
379-
rx_state = can_err_to_state(rx_err);
374+
const enum gs_can_state tx_state = can_err_to_state(tx_err);
375+
const enum gs_can_state rx_state = can_err_to_state(rx_err);
380376

381377
if (tx_state >= rx_state) {
382378
frame->classic_can->data[1] |= gs_can_tx_state_to_frame(tx_state);

0 commit comments

Comments
 (0)