fcan.h 8.0 KB
Newer Older
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 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
/*
 * Copyright : (C) 2022 Phytium Information Technology, Inc.
 * All Rights Reserved.
 *
 * This program is OPEN SOURCE software: you can redistribute it and/or modify it
 * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
 * either version 1.0 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the Phytium Public License for more details.
 *
 *
 * FilePath: fcan.h
 * Date: 2021-04-27 15:08:44
 * LastEditTime: 2022-02-18 08:29:25
 * Description:  This files is for
 *
 * Modify History:
 *  Ver   Who        Date         Changes
 * ----- ------     --------    --------------------------------------
 */


#ifndef FT_CAN_H
#define FT_CAN_H

#include "ftypes.h"
#include "ferror_code.h"
#include "fparameters.h"
#include "fkernel.h"
#include "fcan_hw.h"

typedef enum
{
    FCAN_INTR_EVENT_SEND = 0,    /* Handler type for frame sending interrupt */
    FCAN_INTR_EVENT_RECV = 1,    /* Handler type for frame reception interrupt */
    FCAN_INTR_EVENT_ERROR,       /* Handler type for error interrupt */
    FCAN_INTR_EVENT_NUM
} FCanIntrEventType;

#define FCAN_SUCCESS        FT_SUCCESS /* SUCCESS */
#define FCAN_NOT_READY      FT_MAKE_ERRCODE(ErrModBsp, ErrBspCan, 1)
#define FCAN_FAILURE        FT_MAKE_ERRCODE(ErrModBsp, ErrBspCan, 2)   /* failed */
#define FCAN_INVAL_PARAM    FT_MAKE_ERRCODE(ErrModBsp, ErrBspCan, 3)  /* invalid parameters */

#if defined(CONFIG_FCAN_USE_CANFD)
    #define FCAN_DATA_LENGTH 64U
#else
    #define FCAN_DATA_LENGTH 8U
#endif

/* CAN payload length and DLC definitions according to ISO 11898-1 */
#define CAN_MAX_DLC     8
#define CAN_MAX_DLEN    8
#define CAN_MAX_CTL     3
#define CAN_SFF_ID_BITS 11
#define CAN_EFF_ID_BITS 29

/* special address description flags for the CAN_ID */
#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
#define CAN_ERR_FLAG 0x20000000U /* error message frame */

/* valid bits in CAN ID for frame formats */
#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
#define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */

/* Frame type */
#define STANDARD_FRAME  0   /* standard frame */
#define EXTEND_FRAME    1   /* extended frame */

/* Bit timing calculate */
#define CAN_CALC_MAX_ERROR  50 /* in one-tenth of a percent */
#define CAN_CALC_SYNC_SEG   1

/* can segment type */
typedef enum
{
    FCAN_ARB_SEGMENT = 0, /* Arbitration segment */
    FCAN_DATA_SEGMENT = 1, /* Data segment */
    FCAN_SEGMENT_TYPE_NUM
} FCanSegmentType;

/* Can error status bit mask */
#define FCAN_BUS_ERROR_MASK         1
#define FCAN_PASSIVE_ERROR_MASK     2
#define FCAN_PASSIVE_WARNING_MASK   4
#define FCAN_FIFO_RX_OVERFLOW_MASK  8

/* Can frame select */
#define FCAN_STANDARD_FRAME     0
#define FCAN_EXTENDARD_FRAME    1

/* can baudrate */
#define FCAN_BAUDRATE_10K    10000
#define FCAN_BAUDRATE_50K    50000
#define FCAN_BAUDRATE_100K   100000
#define FCAN_BAUDRATE_200K   200000
#define FCAN_BAUDRATE_250K   250000
#define FCAN_BAUDRATE_500K   500000
#define FCAN_BAUDRATE_1000K  1000000
#define FCAN_BAUDRATE_2000K  2000000
#define FCAN_BAUDRATE_3000K  3000000
#define FCAN_BAUDRATE_4000K  4000000
#define FCAN_BAUDRATE_5000K  5000000

/*
 * defined bits for FCanFrame.flags
 *
 * The use of struct FCanFrame implies the Extended Data Length (EDL) bit to
 * be set in the CAN frame bitstream on the wire. The EDL bit switch turns
 * the CAN controllers bitstream processor into the CAN FD mode which creates
 * two new options within the CAN FD frame specification:
 *
 * Bit Rate Switch - to indicate a second baudrate is/was used for the payload
 * Error State Indicator - represents the error state of the transmitting node
 *
 * As the CANFD_ESI bit is internally generated by the transmitting CAN
 * controller only the CANFD_BRS bit is relevant for real CAN controllers when
 * building a CAN FD frame for transmission. Setting the CANFD_ESI bit can make
 * sense for virtual CAN interfaces to test applications with echoed frames.
 */
#define CANFD_BRS 0x02 /* bit rate switch (second baudrate for payload data) */
#define CANFD_ESI 0x04 /* error state indicator of the transmitting node */

typedef void (*FCanIntrEventHandler)(void *param);

typedef struct
{
    FCanIntrEventType type;
    FCanIntrEventHandler handler;
    void *param;
} FCanIntrEventConfig;

typedef struct
{
    u32 filter_index;/* filter register index*/
    u32 id; /* id bit to receive */
    u32 mask;/* id mask bit to receive */
    u32 type;/* frame type, standard or extended*/
} FCanIdMaskConfig;

typedef struct
{
    u32 canid;/* can frame id */
    u8 candlc;/* can frame length */
    u8 flags; /* additional flags for CAN FD */
    u8 data[FCAN_DATA_LENGTH] __attribute__((aligned(8)));
} FCanFrame;

typedef struct
{
    u32 instance_id;   /* Id of device */
    uintptr base_address; /* Can base Address */
    u32 irq_num;    /* interrupt number */
    u32 irq_prority;/* interrupt priority*/
} FCanConfig;

typedef struct
{
    FCanSegmentType segment;
    boolean auto_calc; /* if auto calculate baudrate parameters */
    u32 baudrate;     /* baudrate */
    u32 sample_point; /* sample point */
    u32 prop_seg;     /* Propagation segment in TQs */
    u32 phase_seg1;   /* Phase buffer segment 1 in TQs */
    u32 phase_seg2;   /* Phase buffer segment 2 in TQs */
    u32 sjw;          /* Synchronisation jump width in TQs */
    u32 brp;          /* Baudrate prescaler */
} FCanBaudrateConfig;

typedef struct
{
    u8 xfers;/* transfer status */
    u8 rs;   /* receive status */
    u8 ts;   /* transmit status */
    u8 fies; /* Current status of the controller state machine */
    u8 fras; /* Frame tagging status */
} FCanXferStatus;

typedef struct
{
    FCanXferStatus xfer_status;
    u32 tx_err_cnt;
    u32 rx_err_cnt;
    u32 tx_fifo_cnt;
    u32 rx_fifo_cnt;
} FCanStatus;

typedef struct
{
    FCanConfig config;
    u32 is_ready;  /* Device is initialized and ready */
    boolean use_canfd; /* if use canfd function */

    FCanIntrEventConfig intr_event[FCAN_INTR_EVENT_NUM];/* event handler and parameters for interrupt */
} FCanCtrl;

/* get default configuration of specific can id */
const FCanConfig *FCanLookupConfig(FCanInstance instance_id);

/* reset a specific can instance */
void FCanReset(FCanCtrl *instance_p);

/* Deinitializes a specific can instance  */
void FCanDeInitialize(FCanCtrl *instance_p);

/* Initializes a specific can instance  */
FError FCanCfgInitialize(FCanCtrl *instance_p, const FCanConfig *input_config_p);

/* Set the fcan baudrate */
FError FCanBaudrateSet(FCanCtrl *instance_p, FCanBaudrateConfig *baudrate_p);

/* interrupt handler for the driver */
void FCanIntrHandler(s32 vector, void *args);

/* register FCanCtrl interrupt handler function */
void FCanRegisterInterruptHandler(FCanCtrl *instance_p, FCanIntrEventConfig *intr_event_p);

/* receive can message by specific can instance */
FError FCanRecv(FCanCtrl *instance_p, FCanFrame *frame_p);

/* send can message by specific can instance */
FError FCanSend(FCanCtrl *instance_p, FCanFrame *frame_p);

/* Enable the specific can instance */
FError FCanEnable(FCanCtrl *instance_p, boolean enable);

/* read can status, include send and receive error count */
FError FCanStatusGet(FCanCtrl *instance_p, FCanStatus *status_p);

/* Set the can mask and umask id */
FError FCanIdMaskFilterSet(FCanCtrl *instance_p, FCanIdMaskConfig *id_mask_p);

/* Set the can id mask filter enable */
void FCanIdMaskFilterEnable(FCanCtrl *instance_p);

/* Set the can id mask filter disable */
void FCanIdMaskFilterDisable(FCanCtrl *instance_p);

/* Enable can interrupt */
FError FCanInterruptEnable(FCanCtrl *instance_p, FCanIntrEventType event_type);

/* Enable or disable can fd */
FError FCanFdEnable(FCanCtrl *instance_p, boolean enable);

#endif // !FT_CAN_H