Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:43

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  * @ingroup can
0006  * @brief Driver API for the GRLIB GRCAN and GRCANFD controllers
0007  */
0008 
0009 /*
0010  *  COPYRIGHT (c) 2007.
0011  *  Cobham Gaisler AB.
0012  *
0013  * Redistribution and use in source and binary forms, with or without
0014  * modification, are permitted provided that the following conditions
0015  * are met:
0016  * 1. Redistributions of source code must retain the above copyright
0017  *    notice, this list of conditions and the following disclaimer.
0018  * 2. Redistributions in binary form must reproduce the above copyright
0019  *    notice, this list of conditions and the following disclaimer in the
0020  *    documentation and/or other materials provided with the distribution.
0021  *
0022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0025  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0032  * POSSIBILITY OF SUCH DAMAGE.
0033  */
0034 
0035 #ifndef __GRCAN_H__
0036 #define __GRCAN_H__
0037 
0038 /**
0039  * @defgroup can GRCAN
0040  *
0041  * @ingroup RTEMSBSPsSharedGRLIB
0042  *
0043  * @brief Macros used for grcan controller
0044  *
0045  * @{
0046  */
0047 
0048 #include <stdint.h>
0049 
0050 #ifdef __cplusplus
0051 extern "C" {
0052 #endif
0053 
0054 struct grcan_regs {
0055     volatile unsigned int conf;          /* 0x00 */
0056     volatile unsigned int stat;          /* 0x04 */
0057     volatile unsigned int ctrl;          /* 0x08 */
0058     volatile unsigned int dummy0[3];     /* 0x0C-0x014 */
0059     volatile unsigned int smask;         /* 0x18 */
0060     volatile unsigned int scode;         /* 0x1C */
0061 
0062     volatile unsigned int dummy1[8];     /* 0x20-0x3C */
0063 
0064     volatile unsigned int nbtr;          /* 0x40 */
0065     volatile unsigned int fdbtr;         /* 0x44 */
0066     volatile unsigned int tdelay;        /* 0x48 */
0067 
0068     volatile unsigned int dummy1b[45];   /* 0x4C-0xFC */
0069 
0070     volatile unsigned int pimsr;         /* 0x100 */
0071     volatile unsigned int pimr;          /* 0x104 */
0072     volatile unsigned int pisr;          /* 0x108 */
0073     volatile unsigned int pir;           /* 0x10C */
0074     volatile unsigned int imr;           /* 0x110 */
0075     volatile unsigned int picr;          /* 0x114 */
0076 
0077     volatile unsigned int dummy2[58];    /* 0x118-0x1FC */
0078 
0079     volatile unsigned int tx0ctrl;       /* 0x200 */
0080     volatile unsigned int tx0addr;       /* 0x204 */
0081     volatile unsigned int tx0size;       /* 0x208 */
0082     volatile unsigned int tx0wr;         /* 0x20C */
0083     volatile unsigned int tx0rd;         /* 0x210 */
0084     volatile unsigned int tx0irq;        /* 0x214 */
0085 
0086     volatile unsigned int dummy3[58];    /* 0x218-0x2FC */
0087 
0088     volatile unsigned int rx0ctrl;       /* 0x300 */
0089     volatile unsigned int rx0addr;       /* 0x304 */
0090     volatile unsigned int rx0size;       /* 0x308 */
0091     volatile unsigned int rx0wr;         /* 0x30C */
0092     volatile unsigned int rx0rd;         /* 0x310 */
0093     volatile unsigned int rx0irq;        /* 0x314 */
0094     volatile unsigned int rx0mask;       /* 0x318 */
0095     volatile unsigned int rx0code;       /* 0x31C */
0096 };
0097 
0098 struct grcan_stats {
0099     unsigned int passive_cnt;
0100     unsigned int overrun_cnt;
0101     unsigned int rxsync_cnt;
0102     unsigned int txsync_cnt;
0103     unsigned int txloss_cnt;
0104     unsigned int ahberr_cnt;
0105     unsigned int ints;
0106     unsigned int busoff_cnt;
0107 };
0108 
0109 struct grcan_timing {
0110     unsigned char scaler;
0111     unsigned char ps1;
0112     unsigned char ps2;
0113     unsigned char rsj;
0114     unsigned char bpr;
0115 };
0116 
0117 struct grcanfd_timing {
0118     unsigned char scaler;
0119     unsigned char ps1;
0120     unsigned char ps2;
0121     unsigned char sjw;
0122     unsigned char resv_zero;
0123 };
0124 
0125 struct grcan_selection {
0126     int selection;
0127     int enable0;
0128     int enable1;
0129 };
0130 
0131 struct grcan_filter {
0132     unsigned long long mask;
0133     unsigned long long code;
0134 };
0135 
0136 #define GRCAN_FDOPT_NOM   0
0137 #define GRCAN_FDOPT_FDBTR 0x01
0138 #define GRCAN_FDOPT_FDFRM 0x02
0139 #define GRCAN_FDMASK (GRCAN_FDOPT_FDBTR | GRCAN_FDOPT_FDFRM)
0140 
0141 /* CAN MESSAGE */
0142 typedef struct {
0143     char extended; /* 1= Extended Frame (29-bit id), 0= STD Frame (11-bit id) */
0144     char rtr; /* RTR - Remote Transmission Request */
0145     char unused; /* Must be 0 to select classic CAN frame */
0146     unsigned char len;
0147     unsigned char data[8];
0148     unsigned int id;
0149 } CANMsg;
0150 
0151 /* CAN-FD MESSAGE */
0152 typedef struct {
0153     uint8_t extended; /* 1= Extended Frame (29-bit id), 0= STD Frame (11-bit id) */
0154     uint8_t rtr;      /* RTR - Remote Transmission Request */
0155     uint8_t fdopts;   /* Bit1: 1=Switch bit rate. bit2: 1=FD frame. */
0156     uint8_t len;      /* 0-8, 12, 16, 20, 24, 32, 48 or 64 bytes */
0157     uint32_t id;
0158     union {
0159         uint64_t dwords[8]; /* up to 64 bytes if FD=1 and len>8 */
0160         uint8_t  bytes[64]; /* up to 64 bytes if FD=1 and len>8 */
0161     } data;
0162 } CANFDMsg;
0163 
0164 enum {
0165     GRCAN_RET_OK            =  0,
0166     GRCAN_RET_INVARG        = -1,
0167     GRCAN_RET_NOTSTARTED    = -2,
0168     GRCAN_RET_TIMEOUT       = -3,
0169     /* Bus-off condition detected (request aborted by driver) */
0170     GRCAN_RET_BUSOFF        = -4,
0171     /* AHB error condition detected (request aborted by driver) */
0172     GRCAN_RET_AHBERR        = -5,
0173 };
0174 
0175 /*
0176  * User functions can cause these transitions:
0177  *   STATE_STOPPED -> STATE_STARTED
0178  *   STATE_STARTED -> STATE_STOPPED
0179  *   STATE_BUSOFF  -> STATE_STOPPED
0180  *   STATE_AHBERR  -> STATE_STOPPED
0181  *
0182  * ISR can cause these transition
0183  *   STATE_STARTED -> STATE_BUSOFF
0184  *   STATE_STARTED -> STATE_AHBERR
0185  *
0186  * STATE_BUSOFF is entered from ISR on bus-off condition. STATE_AHBERR is
0187  * entered from ISR on AHB DMA errors on RX/TX operations. At transition the ISR
0188  * disables DMA, masks all interrupts and releases semaphores.
0189  */
0190 enum grcan_state {
0191     STATE_STOPPED       = 0,
0192     STATE_STARTED       = 1,
0193     STATE_BUSOFF        = 2,
0194     STATE_AHBERR        = 3,
0195 };
0196 
0197 #define GRCAN_CFG_ABORT      0x00000001
0198 #define GRCAN_CFG_ENABLE0    0x00000002
0199 #define GRCAN_CFG_ENABLE1    0x00000004
0200 #define GRCAN_CFG_SELECTION  0x00000008
0201 #define GRCAN_CFG_SILENT     0x00000010
0202 #define GRCAN_CFG_BPR        0x00000300
0203 #define GRCAN_CFG_RSJ        0x00007000
0204 #define GRCAN_CFG_PS1        0x00f00000
0205 #define GRCAN_CFG_PS2        0x000f0000
0206 #define GRCAN_CFG_SCALER     0xff000000
0207 
0208 #define GRCAN_CFG_BPR_BIT    8
0209 #define GRCAN_CFG_RSJ_BIT    12
0210 #define GRCAN_CFG_PS1_BIT    20
0211 #define GRCAN_CFG_PS2_BIT    16
0212 #define GRCAN_CFG_SCALER_BIT 24
0213 
0214 #define GRCAN_CTRL_RESET  0x2
0215 #define GRCAN_CTRL_ENABLE 0x1
0216 
0217 #define GRCAN_TXCTRL_ENABLE 1
0218 #define GRCAN_TXCTRL_ONGOING 1
0219 
0220 #define GRCAN_RXCTRL_ENABLE 1
0221 #define GRCAN_RXCTRL_ONGOING 1
0222 
0223 #define GRCANFD_NBTR_SCALER 0x00ff0000
0224 #define GRCANFD_NBTR_PS1 0x0000fc00
0225 #define GRCANFD_NBTR_PS2 0x000003e0
0226 #define GRCANFD_NBTR_SJW 0x0000001f
0227 
0228 #define GRCANFD_NBTR_SCALER_BIT 16
0229 #define GRCANFD_NBTR_PS1_BIT 10
0230 #define GRCANFD_NBTR_PS2_BIT 5
0231 #define GRCANFD_NBTR_SJW_BIT 0
0232 
0233 #define GRCANFD_FDBTR_SCALER 0x00ff0000
0234 #define GRCANFD_FDBTR_PS1 0x00003c00
0235 #define GRCANFD_FDBTR_PS2 0x000001e0
0236 #define GRCANFD_FDBTR_SJW 0x0000000f
0237 
0238 #define GRCANFD_FDBTR_SCALER_BIT 16
0239 #define GRCANFD_FDBTR_PS1_BIT 10
0240 #define GRCANFD_FDBTR_PS2_BIT 5
0241 #define GRCANFD_FDBTR_SJW_BIT 0
0242 
0243 /* Relative offset of IRQ sources to AMBA Plug&Play */
0244 #define GRCAN_IRQ_IRQ 0
0245 #define GRCAN_IRQ_TXSYNC 1
0246 #define GRCAN_IRQ_RXSYNC 2
0247 
0248 #define GRCAN_ERR_IRQ        0x1
0249 #define GRCAN_OFF_IRQ        0x2
0250 #define GRCAN_OR_IRQ         0x4
0251 #define GRCAN_RXAHBERR_IRQ   0x8
0252 #define GRCAN_TXAHBERR_IRQ   0x10
0253 #define GRCAN_RXIRQ_IRQ      0x20
0254 #define GRCAN_TXIRQ_IRQ      0x40
0255 #define GRCAN_RXFULL_IRQ     0x80
0256 #define GRCAN_TXEMPTY_IRQ    0x100
0257 #define GRCAN_RX_IRQ         0x200
0258 #define GRCAN_TX_IRQ         0x400
0259 #define GRCAN_RXSYNC_IRQ     0x800
0260 #define GRCAN_TXSYNC_IRQ     0x1000
0261 #define GRCAN_RXERR_IRQ      0x2000
0262 #define GRCAN_TXERR_IRQ      0x4000
0263 #define GRCAN_RXMISS_IRQ     0x8000
0264 #define GRCAN_TXLOSS_IRQ     0x10000
0265 
0266 #define GRCAN_STAT_PASS      0x1
0267 #define GRCAN_STAT_OFF       0x2
0268 #define GRCAN_STAT_OR        0x4
0269 #define GRCAN_STAT_AHBERR    0x8
0270 #define GRCAN_STAT_ACTIVE    0x10
0271 #define GRCAN_STAT_RXERRCNT  0xff00
0272 #define GRCAN_STAT_TXERRCNT  0xff0000
0273 
0274 /*
0275  * Return number of GRCAN devices available to driver
0276  */
0277 extern int grcan_dev_count(void);
0278 
0279 /*
0280  * Open a GRCAN device
0281  *
0282  * dev_no:  Device number to open
0283  * return:  Device handle to use with all other grcan_ API functions. The
0284  *      function returns NULL if device can not be opened.
0285  */
0286 extern void *grcan_open(int dev_no);
0287 
0288 /*
0289  * Open a GRCAN device by name. Finds device index then calls
0290  * grcan_open(index).
0291  *
0292  * name:    Device name to open
0293  * dev_no:  Device number matching name. Will be set if device found.
0294  * return:  Device handle to use with all other grcan_ API functions. The
0295  *      function returns NULL if device can not be opened or not found.
0296  */
0297 extern void *grcan_open_by_name(char *name, int *dev_no);
0298 
0299 /*
0300  * Close a GRCAN device
0301  *
0302  * return: This function always returns 0 (success)
0303  */
0304 extern int grcan_close(void *d);
0305 
0306 /*
0307  * Returns if CAN hardware device is CANFD capable.
0308  *
0309  * dev_no:  Device handle
0310  * return:  0=Not FD capable, 1=FD capable.
0311  *      function returns NULL if device can not be opened.
0312  */
0313 extern int grcan_canfd_capable(void *d);
0314 
0315 /*
0316  * Receive CAN messages
0317  *
0318  * Multiple CAN messages can be received in one call.
0319  *
0320  * d: Device handle
0321  * msg: Pointer to receive messages
0322  * count: Number of CAN messages to receive
0323  *
0324  * return:
0325  *   >=0:                       Number of CAN messages received. This can be
0326  *                              less than the count parameter.
0327  *   GRCAN_RET_INVARG:          count parameter less than one or NULL msg.
0328  *   GRCAN_RET_NOTSTARTED:      Device not in started mode
0329  *   GRCAN_RET_TIMEOUT:         Timeout in non-blocking mode
0330  *   GRCAN_RET_BUSOFF:          A read was interrupted by a bus-off error.
0331  *                              Device has left started mode.
0332  *   GRCAN_RET_AHBERR:          Similar to BUSOFF, but was caused by AHB Error.
0333  */
0334 extern int grcan_read(
0335     void *d,
0336     CANMsg *msg,
0337     size_t count
0338 );
0339 
0340 /*
0341  * Receive CAN messages  (only GRCANFD)
0342  *
0343  * Multiple CAN messages can be received in one call.
0344  *
0345  * d: Device handle
0346  * msg: Pointer to receive messages
0347  * count: Number of CAN messages to receive
0348  *
0349  * return:
0350  *   >=0:                       Number of CAN messages received. This can be
0351  *                              less than the count parameter.
0352  *   GRCAN_RET_INVARG:          count parameter less than one or NULL msg.
0353  *   GRCAN_RET_NOTSTARTED:      Device not in started mode
0354  *   GRCAN_RET_TIMEOUT:         Timeout in non-blocking mode
0355  *   GRCAN_RET_BUSOFF:          A read was interrupted by a bus-off error.
0356  *                              Device has left started mode.
0357  *   GRCAN_RET_AHBERR:          Similar to BUSOFF, but was caused by AHB Error.
0358  */
0359 extern int grcanfd_read(
0360     void *d,
0361     CANFDMsg *msg,
0362     size_t count
0363 );
0364 
0365 /*
0366  * Transmit CAN messages
0367  *
0368  * Multiple CAN messages can be transmit in one call.
0369  *
0370  * d: Device handle
0371  * msg: Pointer to messages to transmit
0372  * count: Number of CAN messages to transmit
0373  *
0374  * return:
0375  *   >=0:                       Number of CAN messages transmitted. This can be
0376  *                              less than the count parameter.
0377  *   GRCAN_RET_INVARG:          count parameter less than one.
0378  *   GRCAN_RET_NOTSTARTED:      Device not in started mode
0379  *   GRCAN_RET_TIMEOUT:         Timeout in non-blocking mode
0380  *   GRCAN_RET_BUSOFF:          A write was interrupted by a Bus-off error.
0381  *                              Device has left started mode
0382  *   GRCAN_RET_AHBERR:          Similar to BUSOFF, but was caused by AHB Error.
0383  */
0384 extern int grcan_write(
0385     void *d,
0386     CANMsg *msg,
0387     size_t count
0388 );
0389 
0390 /*
0391  * Transmit CAN-FD complient messages  (only GRCANFD)
0392  *
0393  * Multiple CAN messages can be transmit in one call.
0394  *
0395  * d: Device handle
0396  * msg: Pointer to messages to transmit
0397  * count: Number of CAN messages to transmit
0398  *
0399  * return:
0400  *   >=0:                       Number of CAN messages transmitted. This can be
0401  *                              less than the count parameter.
0402  *   GRCAN_RET_INVARG:          count parameter less than one.
0403  *   GRCAN_RET_NOTSTARTED:      Device not in started mode
0404  *   GRCAN_RET_TIMEOUT:         Timeout in non-blocking mode
0405  *   GRCAN_RET_BUSOFF:          A write was interrupted by a Bus-off error.
0406  *                              Device has left started mode
0407  *   GRCAN_RET_AHBERR:          Similar to BUSOFF, but was caused by AHB Error.
0408  */
0409 extern int grcanfd_write(
0410     void *d,
0411     CANFDMsg *msg,
0412     size_t ucount
0413 );
0414 
0415 /*
0416  * Returns current GRCAN software state
0417  *
0418  * If STATE_BUSOFF or STATE_AHBERR is returned then the function grcan_stop()
0419  * shall be called before continue using the driver.
0420  *
0421  * d: Device handle
0422  * return:
0423  *   STATE_STOPPED              Stopped
0424  *   STATE_STARTED              Started
0425  *   STATE_BUSOFF               Bus-off has been detected
0426  *   STATE_AHBERR               AHB error has been detected
0427  */
0428 extern int grcan_get_state(void *d);
0429 
0430 /* The remaining functions return 0 on success and non-zero on failure. */
0431 
0432 /* Functions controlling operational
0433  * mode
0434  */
0435 /* Bring the link up after open or bus-off */
0436 extern int grcan_start(void *d);
0437 /* stop to change baud rate/config or closing down */
0438 extern int grcan_stop(void *d);
0439 /* Wait until all TX messages have been sent */
0440 extern int grcan_flush(void *d);
0441 
0442 /* Functions that require connection
0443  * to be stopped
0444  */
0445 /* enable silent mode read only state */
0446 extern int grcan_set_silent(void *d, int silent);
0447 /* enable/disable stopping link on AHB Error */
0448 extern int grcan_set_abort(void *d, int abort);
0449 /* Set Enable0,Enable1,Selection */
0450 extern int grcan_set_selection(void *d, const struct grcan_selection *selection);
0451 /* Set baudrate by using driver's baud rate timing calculation routines */
0452 extern int grcan_set_speed(void *d, unsigned int hz);
0453 /* Set baudrate by specifying the timing registers manually */
0454 extern int grcan_set_btrs(void *d, const struct grcan_timing *timing);
0455 
0456 /* Set the Nominal and FD baudrate by using driver's baud rate timing
0457  * calculation routines
0458  */
0459 extern int grcanfd_set_speed(void *d, unsigned int nomhz, unsigned int fdhz);
0460 /* Set Nominal and FD baudrate by specifying the timing registers manually*/
0461 extern int grcanfd_set_btrs(
0462     void *d,
0463     const struct grcanfd_timing *nominal,
0464     const struct grcanfd_timing *fd);
0465 
0466 /* Functions can be called whenever */
0467 /* Enable/disable Blocking on reception (until at least one message has been received) */
0468 int grcan_set_rxblock(void* d, int block);
0469 /* Enable/disable Blocking on transmission (until at least one message has been transmitted) */
0470 int grcan_set_txblock(void* d, int block);
0471 /* Enable/disable Blocking until all requested messages has been sent */
0472 int grcan_set_txcomplete(void* d, int complete);
0473 /* Enable/disable Blocking until all requested has been received */
0474 int grcan_set_rxcomplete(void* d, int complete);
0475 /* Get statistics */
0476 extern int grcan_get_stats(void *d, struct grcan_stats *stats);
0477 /* Clear statistics */
0478 extern int grcan_clr_stats(void *d);
0479 /* Set Acceptance filters, provide pointer to "struct grcan_filter" or NULL to disable filtering (let all messages pass) */
0480 extern int grcan_set_afilter(void *d, const struct grcan_filter *filter);
0481 /* Set Sync Messages RX/TX filters, NULL disables the IRQ completely */
0482 extern int grcan_set_sfilter(void *d, const struct grcan_filter *filter);
0483 /* Get status register of GRCAN core */
0484 extern int grcan_get_status(void *d, unsigned int *status);
0485 
0486 void grcan_register_drv(void);
0487 
0488 #ifdef __cplusplus
0489 }
0490 #endif
0491 
0492 /** @} */
0493 
0494 #endif