can: can_check_bittiming_failed(): introduce function to check bittiming

This commit is contained in:
Marc Kleine-Budde 2023-01-28 16:15:20 +01:00 committed by Marc Kleine-Budde
parent 5fb636c4bc
commit b62d47dff2
6 changed files with 50 additions and 43 deletions

View File

@ -49,7 +49,7 @@ typedef struct {
extern const struct gs_device_bt_const CAN_btconst;
void can_init(can_data_t *channel, CAN_TypeDef *instance);
bool can_set_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing);
void can_set_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing);
void can_enable(can_data_t *channel, uint32_t mode);
void can_disable(can_data_t *channel);
bool can_is_enabled(can_data_t *channel);

View File

@ -31,6 +31,7 @@ THE SOFTWARE.
#include "can.h"
#include "usbd_gs_can.h"
bool can_check_bittiming_ok(const struct can_bittiming_const *btc, const struct gs_device_bittiming *timing);
void CAN_SendFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel);
void CAN_ReceiveFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel);
void CAN_HandleError(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel);

View File

@ -247,9 +247,7 @@ struct gs_device_bittiming {
u32 brp;
} __packed __aligned(4);
struct gs_device_bt_const {
u32 feature;
u32 fclk_can;
struct can_bittiming_const {
u32 tseg1_min;
u32 tseg1_max;
u32 tseg2_min;
@ -260,26 +258,17 @@ struct gs_device_bt_const {
u32 brp_inc;
} __packed __aligned(4);
struct gs_device_bt_const {
u32 feature;
u32 fclk_can;
struct can_bittiming_const btc;
} __packed __aligned(4);
struct gs_device_bt_const_extended {
u32 feature;
u32 fclk_can;
u32 tseg1_min;
u32 tseg1_max;
u32 tseg2_min;
u32 tseg2_max;
u32 sjw_max;
u32 brp_min;
u32 brp_max;
u32 brp_inc;
u32 dtseg1_min;
u32 dtseg1_max;
u32 dtseg2_min;
u32 dtseg2_max;
u32 dsjw_max;
u32 dbrp_min;
u32 dbrp_max;
u32 dbrp_inc;
struct can_bittiming_const btc;
struct can_bittiming_const dbtc;
} __packed __aligned(4);
struct gs_identify_mode {

View File

@ -45,14 +45,16 @@ const struct gs_device_bt_const CAN_btconst = {
#endif
,
.fclk_can = CAN_CLOCK_SPEED,
.tseg1_min = 1,
.tseg1_max = 16,
.tseg2_min = 1,
.tseg2_max = 8,
.sjw_max = 4,
.brp_min = 1,
.brp_max = 1024,
.brp_inc = 1,
.btc = {
.tseg1_min = 1,
.tseg1_max = 16,
.tseg2_min = 1,
.tseg2_max = 8,
.sjw_max = 4,
.brp_min = 1,
.brp_max = 1024,
.brp_inc = 1,
},
};
// The STM32F0 only has one CAN interface, define it as CAN1 as
@ -84,23 +86,14 @@ void can_init(can_data_t *channel, CAN_TypeDef *instance)
device_can_init(channel, instance);
}
bool can_set_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing)
void can_set_bittiming(can_data_t *channel, const struct gs_device_bittiming *timing)
{
const uint8_t tseg1 = timing->prop_seg + timing->phase_seg1;
if ( (timing->brp>0) && (timing->brp<=1024)
&& (tseg1>0) && (tseg1<=16)
&& (timing->phase_seg2>0) && (timing->phase_seg2<=8)
&& (timing->sjw>0) && (timing->sjw<=4)
) {
channel->brp = timing->brp & 0x3FF;
channel->phase_seg1 = tseg1;
channel->phase_seg2 = timing->phase_seg2;
channel->sjw = timing->sjw;
return true;
} else {
return false;
}
channel->brp = timing->brp;
channel->phase_seg1 = tseg1;
channel->phase_seg2 = timing->phase_seg2;
channel->sjw = timing->sjw;
}
void can_enable(can_data_t *channel, uint32_t mode)

View File

@ -29,6 +29,23 @@ THE SOFTWARE.
#include "timer.h"
#include "usbd_gs_can.h"
bool can_check_bittiming_ok(const struct can_bittiming_const *btc,
const struct gs_device_bittiming *timing)
{
const uint32_t tseg1 = timing->prop_seg + timing->phase_seg1;
if (tseg1 < btc->tseg1_min ||
tseg1 > btc->tseg1_max ||
timing->phase_seg2 < btc->tseg2_min ||
timing->phase_seg2 > btc->tseg2_max ||
timing->sjw > btc->sjw_max ||
timing->brp < btc->brp_min ||
timing->brp > btc->brp_max)
return false;
return true;
}
void CAN_SendFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel)
{
struct gs_host_frame_object *frame_object;

View File

@ -28,6 +28,7 @@ THE SOFTWARE.
#include <string.h>
#include "can.h"
#include "can_common.h"
#include "compiler.h"
#include "config.h"
#include "gpio.h"
@ -490,6 +491,9 @@ static uint8_t USBD_GS_CAN_EP0_RxReady(USBD_HandleTypeDef *pdev) {
case GS_USB_BREQ_BITTIMING: {
const struct gs_device_bittiming *timing = (struct gs_device_bittiming *)hcan->ep0_buf;
if (!can_check_bittiming_ok(&CAN_btconst.btc, timing))
goto out_fail;
can_set_bittiming(channel, timing);
break;
}
@ -540,6 +544,9 @@ static uint8_t USBD_GS_CAN_EP0_RxReady(USBD_HandleTypeDef *pdev) {
req->bRequest = 0xFF;
return USBD_OK;
out_fail:
return USBD_FAIL;
}
static uint8_t USBD_GS_CAN_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) {