Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:06

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  GRCAN driver
0005  *
0006  *  COPYRIGHT (c) 2007-2019.
0007  *  Cobham Gaisler AB.
0008  *
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, this list of conditions and the following disclaimer.
0014  * 2. Redistributions in binary form must reproduce the above copyright
0015  *    notice, this list of conditions and the following disclaimer in the
0016  *    documentation and/or other materials provided with the distribution.
0017  *
0018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028  * POSSIBILITY OF SUCH DAMAGE.
0029  */
0030 
0031 #ifndef GRCAN_DEFAULT_BAUD
0032  /* default to 500kbits/s */
0033  #define GRCAN_DEFAULT_BAUD 500000
0034 #endif
0035 
0036 #ifndef GRCAN_SAMPLING_POINT
0037  #define GRCAN_SAMPLING_POINT 80
0038 #endif
0039 
0040 #define WRAP_AROUND_TX_MSGS 1
0041 #define WRAP_AROUND_RX_MSGS 2
0042 #define GRCAN_MSG_SIZE sizeof(struct grcan_msg)
0043 
0044 struct grcan_msg {
0045     unsigned int head[2];
0046     unsigned char data[8];
0047 };
0048 
0049 struct grcan_config {
0050     struct grcan_timing timing;
0051     struct grcanfd_timing timing_fd;
0052     struct grcan_selection selection;
0053     int abort;
0054     int silent;
0055 };
0056 
0057 struct grcan_priv {
0058     struct drvmgr_dev *dev; /* Driver manager device */
0059     char devName[52];   /* Device Name */
0060     unsigned int baseaddr, ram_base;
0061     struct grcan_regs *regs;
0062     int irq;
0063     int minor;
0064     int open;
0065     int started;
0066     unsigned int channel;
0067     int flushing;
0068     unsigned int corefreq_hz;
0069     int fd_capable;
0070 
0071     /* Circular DMA buffers */
0072     void *_rx, *_rx_hw;
0073     void *_tx, *_tx_hw;
0074     void *txbuf_adr;
0075     void *rxbuf_adr;
0076     struct grcan_msg *rx;
0077     struct grcan_msg *tx;
0078     unsigned int rxbuf_size;    /* requested RX buf size in bytes */
0079     unsigned int txbuf_size;    /* requested TX buf size in bytes */
0080 
0081     int txblock, rxblock;
0082     int txcomplete, rxcomplete;
0083 
0084     struct grcan_filter sfilter;
0085     struct grcan_filter afilter;
0086     int config_changed; /* 0=no changes, 1=changes ==> a Core reset is needed */
0087     struct grcan_config config;
0088     struct grcan_stats stats;
0089 
0090     rtems_id rx_sem, tx_sem, txempty_sem, dev_sem;
0091     SPIN_DECLARE(devlock);
0092 };
0093 
0094 #ifdef GRCAN_REG_BYPASS_CACHE
0095 #define READ_REG(address) grlib_read_uncached32((unsigned int)(address))
0096 #else
0097 #define READ_REG(address) (*(volatile unsigned int *)(address))
0098 #endif
0099 
0100 #ifdef GRCAN_DMA_BYPASS_CACHE
0101 #define READ_DMA_DOUBLE(address) grlib_read_uncached64((uint64_t *)(address))
0102 #define READ_DMA_WORD(address) grlib_read_uncached32((unsigned int)(address))
0103 #define READ_DMA_BYTE(address) grlib_read_uncached8((unsigned int)(address))
0104 #else
0105 #define READ_DMA_DOUBLE(address) (*(volatile uint64_t *)(address))
0106 #define READ_DMA_WORD(address) (*(volatile unsigned int *)(address))
0107 #define READ_DMA_BYTE(address) (*(volatile unsigned char *)(address))
0108 #endif
0109 
0110 extern int state2err[4];
0111 extern struct grlib_canbtrs_ranges grcan_btrs_ranges;
0112 extern struct grlib_canbtrs_ranges grcanfd_nom_btrs_ranges;
0113 extern struct grlib_canbtrs_ranges grcanfd_fd_btrs_ranges;
0114 
0115 int grcan_wait_rxdata(struct grcan_priv *pDev, int min);
0116 int grcan_wait_txspace(struct grcan_priv *pDev, int min);
0117 
0118 static inline unsigned int grcan_hw_rxavail(
0119     unsigned int rp,
0120     unsigned int wp,
0121     unsigned int size)
0122 {
0123     if (rp == wp) {
0124         /* read pointer and write pointer is equal only
0125          * when RX buffer is empty.
0126          */
0127         return 0;
0128     }
0129 
0130     if (wp > rp) {
0131         return (wp - rp) / GRCAN_MSG_SIZE;
0132     } else {
0133         return (size - (rp - wp)) / GRCAN_MSG_SIZE;
0134     }
0135 }
0136 
0137 static inline unsigned int grcan_hw_txspace(
0138     unsigned int rp,
0139     unsigned int wp,
0140     unsigned int size)
0141 {
0142     unsigned int left;
0143 
0144     if (rp == wp) {
0145         /* read pointer and write pointer is equal only
0146          * when TX buffer is empty.
0147          */
0148         return size / GRCAN_MSG_SIZE - WRAP_AROUND_TX_MSGS;
0149     }
0150 
0151     /* size - 4 - abs(read-write) */
0152     if (wp > rp) {
0153         left = size - (wp - rp);
0154     } else {
0155         left = rp - wp;
0156     }
0157 
0158     return left / GRCAN_MSG_SIZE - WRAP_AROUND_TX_MSGS;
0159 }