Hi Wolfgang,

this patch conflicts with my simple SJA header posted some days ago

http://lists.denx.de/pipermail/u-boot/2009-October/063097.html

together with a fix for two of our boards - which has not much
to do with CAN. WD asked me to use a C struct to access the SJA1000. 

http://lists.denx.de/pipermail/u-boot/2009-October/062902.html

So where does this bring us? Either we want to use C structs for everything
or decide it from patch to patch :-(

Matthias



On Sunday 01 November 2009 12:33, Wolfgang Grandegger wrote:
> From: Wolfgang Grandegger <w...@denx.de>
> 
> Signed-off-by: Wolfgang Grandegger <w...@denx.de>
> ---
>  drivers/can/Makefile  |    3 +-
>  drivers/can/sja1000.c |  223 
> +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/sja1000.h     |  159 +++++++++++++++++++++++++++++++++++
>  3 files changed, 384 insertions(+), 1 deletions(-)
>  create mode 100644 drivers/can/sja1000.c
>  create mode 100644 include/sja1000.h
> 
> diff --git a/drivers/can/Makefile b/drivers/can/Makefile
> index 74d2ff5..e2b6bd6 100644
> --- a/drivers/can/Makefile
> +++ b/drivers/can/Makefile
> @@ -25,7 +25,8 @@ include $(TOPDIR)/config.mk
>  
>  LIB  := $(obj)libcan.a
>  
> -COBJS-$(CONFIG_CAN)  += can.o
> +COBJS-$(CONFIG_CAN)          += can.o
> +COBJS-$(CONFIG_CAN_SJA1000)  += sja1000.o
>  
>  COBJS        := $(COBJS-y)
>  SRCS         := $(COBJS:.o=.c)
> diff --git a/drivers/can/sja1000.c b/drivers/can/sja1000.c
> new file mode 100644
> index 0000000..b75f01c
> --- /dev/null
> +++ b/drivers/can/sja1000.c
> @@ -0,0 +1,223 @@
> +/*
> + * (C) Copyright 2007-2009, Wolfgang Grandegger <w...@denx.de>
> + *
> + * Derived from Xenomai's RT-Socket-CAN driver for SJA1000:
> + *
> + * Copyright (C) 2005,2006 Sebastian Smolorz
> + *                        <sebastian.smol...@stud.uni-hannover.de>
> + *
> + * Copyright (C) 2005, Sascha Hauer, Pengutronix
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 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
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +
> +#include <can.h>
> +#include <sja1000.h>
> +
> +#define SJA1000_OCR  (SJA_OCR_MODE_NORMAL | SJA_OCR_TX0_PUSHPULL)
> +#define SJA1000_CDR  SJA_CDR_CAN_MODE
> +
> +/*
> + * Basic functions to access registers
> + */
> +#define sja1000_read_reg(dev, reg)                   \
> +     in_8 ((volatile u8 *)((dev)->base + (reg)))
> +
> +#define sja1000_write_reg(dev, reg, value)                   \
> +     out_8 ((volatile u8 *)((dev)->base + (reg)), value)
> +
> +/*
> + * Baudrate table
> + */
> +
> +static u16 sja1000_btr0btr1[] = {
> +     0x031c,                 /* 125K */
> +     0x011c,                 /* 250K */
> +     0x001c,                 /* 500K */
> +};
> +
> +int sja1000_init (struct can_dev *dev, unsigned int ibaud)
> +{
> +     int i, wait = 1000;
> +     u16 btr0btr1;
> +
> +     /* Disable the controller's interrupts */
> +     sja1000_write_reg (dev, SJA_IER, 0x00);
> +
> +     /* Set reset mode bit */
> +     sja1000_write_reg (dev, SJA_MOD, SJA_MOD_RM);
> +
> +     /* Read reset mode bit, multiple tests */
> +     do {
> +             udelay (100);
> +             if (sja1000_read_reg (dev, SJA_MOD) & SJA_MOD_RM)
> +                     break;
> +     } while (--wait);
> +
> +     sja1000_write_reg (dev, SJA_CDR, SJA1000_CDR);
> +     sja1000_write_reg (dev, SJA_OCR, SJA1000_OCR);
> +
> +     sja1000_write_reg (dev, SJA_AMR0, 0xFF);
> +     sja1000_write_reg (dev, SJA_AMR1, 0xFF);
> +     sja1000_write_reg (dev, SJA_AMR2, 0xFF);
> +     sja1000_write_reg (dev, SJA_AMR3, 0xFF);
> +
> +     sja1000_write_reg (dev, SJA_RXERR, 0);
> +     sja1000_write_reg (dev, SJA_TXERR, 0);
> +
> +     i = sizeof (sja1000_btr0btr1) / sizeof (u16);
> +     if (ibaud >= i)
> +             ibaud = i - 1;
> +     btr0btr1 = sja1000_btr0btr1[ibaud];
> +     sja1000_write_reg (dev, SJA_BTR0, (btr0btr1 >> 8) & 0xff);
> +     sja1000_write_reg (dev, SJA_BTR1, (btr0btr1 & 0xff));
> +
> +     /* Clear error code capture (i.e. read it) */
> +     sja1000_read_reg (dev, SJA_ECC);
> +
> +     /* Clear reset mode bit in SJA1000 */
> +     sja1000_write_reg (dev, SJA_MOD, 0);
> +
> +     return 0;
> +}
> +
> +int sja1000_xmit (struct can_dev *dev, struct can_msg *msg)
> +{
> +     int i;
> +     u8 fir;
> +
> +     if (msg->dlc > 8)
> +             msg->dlc = 8;
> +     fir = msg->dlc;
> +
> +     sja1000_write_reg (dev, SJA_ID1, msg->id >> 3);
> +     sja1000_write_reg (dev, SJA_ID2, msg->id << 5);
> +     for (i = 0; i < msg->dlc; i++)
> +             sja1000_write_reg (dev, SJA_DATA_SFF (i), msg->data[i]);
> +
> +     /* Write frame information register */
> +     sja1000_write_reg (dev, SJA_FIR, fir);
> +
> +     /* Push the 'send' button */
> +     sja1000_write_reg (dev, SJA_CMR, SJA_CMR_TR);
> +
> +     /* Wait some time */
> +     for (i = 0; i < CAN_XMIT_TIMEOUT_US; i += 10000) {
> +             if (sja1000_read_reg (dev, SJA_SR) & SJA_SR_TCS)
> +                     return 0;
> +             if (ctrlc ())
> +                     break;
> +             udelay (10000);
> +     }
> +
> +     return -1;
> +}
> +
> +int sja1000_recv (struct can_dev *dev, struct can_msg *msg)
> +{
> +     int i;
> +     u8 fir;
> +
> +     while (!(sja1000_read_reg (dev, SJA_SR) & SJA_SR_RBS)) {
> +             if (ctrlc ())
> +                     return -1;
> +     }
> +
> +     /* Read out frame information register */
> +     fir = sja1000_read_reg (dev, SJA_FIR);
> +
> +     /* Extract data length code */
> +     msg->dlc = fir & SJA_FIR_DLC_MASK;
> +
> +     /* If DLC exceeds 8 bytes adjust it to 8 (for the payload size) */
> +     if (msg->dlc > 8)
> +             msg->dlc = 8;
> +
> +     if (fir & SJA_FIR_EFF) {
> +             printf ("Extended CAN messages not supported\n");
> +             return -1;
> +     } else {
> +             msg->id = sja1000_read_reg (dev, SJA_ID1) << 3;
> +             msg->id |= sja1000_read_reg (dev, SJA_ID2) >> 5;
> +
> +             if (!(fir & SJA_FIR_RTR)) {
> +                     for (i = 0; i < msg->dlc; i++)
> +                             msg->data[i] =
> +                                 sja1000_read_reg (dev, SJA_DATA_SFF (i));
> +             }
> +     }
> +     if (fir & SJA_FIR_RTR)
> +             msg->id |= CAN_RTR_FLAG;
> +
> +     /* Release Receive Buffer */
> +     sja1000_write_reg (dev, SJA_CMR, SJA_CMR_RRB);
> +
> +     return 0;
> +}
> +
> +int sja1000_status (struct can_dev *dev, int level)
> +{
> +     printf ("SJA1000 at %#x", dev->base);
> +     if (level > 0) {
> +             int stat = sja1000_read_reg (dev, SJA_SR) & 0xff;
> +             printf (", status 0x%02x", stat);
> +             if (stat & SJA_SR_BS)
> +                     puts (" busoff");
> +             if (stat & SJA_SR_ES)
> +                     puts (" error");
> +             if (stat & SJA_SR_TS)
> +                     puts (" txing");
> +             if (stat & SJA_SR_RS)
> +                     puts (" rxing");
> +             if (stat & SJA_SR_TCS)
> +                     puts (" txdone");
> +             if (stat & SJA_SR_TBS)
> +                     puts (" txfree");
> +             if (stat & SJA_SR_DOS)
> +                     puts (" overrun");
> +             if (stat & SJA_SR_RBS)
> +                     puts (" rxfull");
> +     }
> +     puts ("\n");
> +     if (level > 1) {
> +             int i;
> +             for (i = 0; i < SJA1000_SIZE; i++) {
> +                     if ((i % 0x10) == 0)
> +                             printf ("\n%02x:", i);
> +                     printf (" %02x", sja1000_read_reg (dev, i));
> +             }
> +             puts ("\n");
> +     }
> +     return 0;
> +}
> +
> +void sja1000_register (struct can_dev *dev, unsigned long base)
> +{
> +     dev->name = "sja1000";
> +     dev->base = base;
> +     dev->init = sja1000_init;
> +     dev->xmit = sja1000_xmit;
> +     dev->recv = sja1000_recv;
> +     dev->status = sja1000_status;
> +
> +     can_register (dev);
> +}
> diff --git a/include/sja1000.h b/include/sja1000.h
> new file mode 100644
> index 0000000..56b43bf
> --- /dev/null
> +++ b/include/sja1000.h
> @@ -0,0 +1,159 @@
> +/*
> + * (C) Copyright 2007-2009, Wolfgang Grandegger <w...@denx.de>
> + *
> + * Derived from Xenomai's RT-Socket-CAN driver for SJA1000:
> + *
> + * Copyright (C) 2005,2006 Sebastian Smolorz
> + *                        <sebastian.smol...@stud.uni-hannover.de>
> + *
> + * Copyright (C) 2005, Sascha Hauer, Pengutronix
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 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
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef __SJA1000_H__
> +#define __SJA1000_H__
> +
> +#include <can.h>
> +
> +/* PeliCAN mode address map */
> +
> +/* reset and operating mode */
> +#define SJA_MOD          0       /* Mode register                   */
> +#define SJA_CMR          1       /* Command register                */
> +#define SJA_SR           2       /* Status register                 */
> +#define SJA_IR           3       /* Interrupt register              */
> +#define SJA_IER          4       /* Interrupt enable register       */
> +#define SJA_BTR0         6       /* Bus timing register 0           */
> +#define SJA_BTR1         7       /* Bus timing register 1           */
> +#define SJA_OCR          8       /* Output control register         */
> +#define SJA_ALC         11       /* Arbitration lost capture        */
> +#define SJA_ECC         12       /* Error code capture register     */
> +#define SJA_RXERR       14       /* Receive error counter           */
> +#define SJA_TXERR       15       /* Transmit error counter          */
> +#define SJA_CDR         31       /* Clock divider register          */
> +
> +/* reset mode */
> +#define SJA_ACR0        16       /* Acceptance code register 0      */
> +#define SJA_ACR1        17       /* Acceptance code register 1      */
> +#define SJA_ACR2        18       /* Acceptance code register 2      */
> +#define SJA_ACR3        19       /* Acceptance code register 3      */
> +#define SJA_AMR0        20       /* Acceptance mask register 0      */
> +#define SJA_AMR1        21       /* Acceptance mask register 1      */
> +#define SJA_AMR2        22       /* Acceptance mask register 2      */
> +#define SJA_AMR3        23       /* Acceptance mask register 3      */
> +
> +/* operating mode */
> +#define SJA_FIR         16       /* Frame information register      */
> +#define SJA_ID1         17       /* Identifier 1                    */
> +#define SJA_ID2         18       /* Identifier 2                    */
> +#define SJA_ID3         19       /* Identifier 3 (EFF only)         */
> +#define SJA_ID4         20       /* Identifier 4 (EFF only)         */
> +
> +#define SJA_DATA_SFF(x) (19 + (x)) /* Data registers in case of standard
> +                                    * frame format; 0 <= x <= 7 */
> +#define SJA_DATA_EFF(x) (21 + (x)) /* Data registers in case of extended
> +                                    * frame format; 0 <= x <= 7 */
> +/* Mode register */
> +#define SJA_MOD_RM           (1<<0) /* Reset Mode                          */
> +#define SJA_MOD_LOM          (1<<1) /* Listen Only Mode                    */
> +#define SJA_MOD_STM          (1<<2) /* Self Test Mode                      */
> +#define SJA_MOD_AFM          (1<<3) /* Acceptance Filter Mode              */
> +#define SJA_MOD_SM           (1<<4) /* Sleep Mode                          */
> +
> +/* Command register */
> +#define SJA_CMR_TR           (1<<0) /* Transmission request                */
> +#define SJA_CMR_AT           (1<<1) /* Abort Transmission                  */
> +#define SJA_CMR_RRB          (1<<2) /* Release Receive Buffer              */
> +#define SJA_CMR_CDO          (1<<3) /* Clear Data Overrun                  */
> +#define SJA_CMR_SRR          (1<<4) /* Self reception request              */
> +
> +/* Status register */
> +#define SJA_SR_RBS           (1<<0) /* Receive Buffer Status               */
> +#define SJA_SR_DOS           (1<<1) /* Data Overrun Status                 */
> +#define SJA_SR_TBS           (1<<2) /* Transmit Buffer Status              */
> +#define SJA_SR_TCS           (1<<3) /* Transmission Complete Status        */
> +#define SJA_SR_RS            (1<<4) /* Receive Status                      */
> +#define SJA_SR_TS            (1<<5) /* Transmit Status                     */
> +#define SJA_SR_ES            (1<<6) /* Error Status                        */
> +#define SJA_SR_BS            (1<<7) /* Bus Status                          */
> +
> +/* Interrupt register */
> +#define SJA_IR_RI            (1<<0) /* Receive Interrupt                   */
> +#define SJA_IR_TI            (1<<1) /* Transmit Interrupt                  */
> +#define SJA_IR_EI            (1<<2) /* Error Warning Interrupt             */
> +#define SJA_IR_DOI           (1<<3) /* Data Overrun Interrupt              */
> +#define SJA_IR_WUI           (1<<4) /* Wake-Up Interrupt                   */
> +#define SJA_IR_EPI           (1<<5) /* Error Passive Interrupt             */
> +#define SJA_IR_ALI           (1<<6) /* Arbitration Lost Interrupt          */
> +#define SJA_IR_BEI           (1<<7) /* Bus Error Interrupt                 */
> +
> +/* Interrupt enable register */
> +#define SJA_IER_RIE          (1<<0) /* Receive Interrupt Enable            */
> +#define SJA_IER_TIE          (1<<1) /* Transmit Interrupt Enable           */
> +#define SJA_IER_EIE          (1<<2) /* Error Warning Interrupt Enable      */
> +#define SJA_IER_DOIE         (1<<3) /* Data Overrun Interrupt Enable       */
> +#define SJA_IER_WUIE         (1<<4) /* Wake-Up Interrupt Enable            */
> +#define SJA_IER_EPIE         (1<<5) /* Error Passive Interrupt Enable      */
> +#define SJA_IER_ALIE         (1<<6) /* Arbitration Lost Interrupt Enable   */
> +#define SJA_IER_BEIE         (1<<7) /* Bus Error Interrupt Enable          */
> +
> +/* Output control register */
> +#define SJA_OCR_MODE_BIPHASE 0
> +#define SJA_OCR_MODE_TEST    1
> +#define SJA_OCR_MODE_NORMAL  2
> +#define SJA_OCR_MODE_CLOCK   3
> +#define SJA_OCR_TX0_INVERT   (1<<2)
> +#define SJA_OCR_TX0_PULLDOWN (1<<3)
> +#define SJA_OCR_TX0_PULLUP   (2<<3)
> +#define SJA_OCR_TX0_PUSHPULL (3<<3)
> +#define SJA_OCR_TX1_INVERT   (1<<5)
> +#define SJA_OCR_TX1_PULLDOWN (1<<6)
> +#define SJA_OCR_TX1_PULLUP   (2<<6)
> +#define SJA_OCR_TX1_PUSHPULL (3<<6)
> +
> +/* Error code capture register */
> +
> +/*
> + * The segmentation field gives information about the location of
> + * errors on the bus
> + */
> +#define SJA_ECC_SEG_MASK     31     /* Segmentation field mask             */
> +#define SJA_ECC_DIR          (1<<5) /* Transfer direction                  */
> +#define SJA_ECC_ERR_BIT      (0<<6)
> +#define SJA_ECC_ERR_FORM     (1<<6)
> +#define SJA_ECC_ERR_STUFF    (2<<6)
> +#define SJA_ECC_ERR_MASK     (3<<6) /* Error code mask                     */
> +
> +/* Frame information register */
> +#define SJA_FIR_DLC_MASK     15     /* Data length code mask               */
> +#define SJA_FIR_RTR          (1<<6) /* Remote transmission request         */
> +#define SJA_FIR_EFF          (1<<7) /* Extended frame format               */
> +
> +/* Clock divider register */
> +#define SJA_CDR_CLK_OFF      (1<<3) /* Clock off (CLKOUT pin)              */
> +#define SJA_CDR_CBP          (1<<6) /* CAN input comparator bypass         */
> +#define SJA_CDR_CAN_MODE     (1<<7) /* CAN mode: 1 = PeliCAN               */
> +
> +#define SJA1000_SIZE      0x80
> +
> +void sja1000_register (struct can_dev *dev, unsigned long base);
> +
> +#endif  /* __SJA1000_H__ */
> +

-- 
-------------------------------------------------------------------------
Dipl.-Ing. Matthias Fuchs
Head of System Design

esd electronic system design gmbh
Vahrenwalder Str. 207 - 30165 Hannover - GERMANY
Phone: +49-511-37298-0 - Fax: +49-511-37298-68
Please visit our homepage http://www.esd.eu
Quality Products - Made in Germany
-------------------------------------------------------------------------
Geschäftsführer: Klaus Detering, Dr. Werner Schulze
Amtsgericht Hannover HRB 51373 - VAT-ID DE 115672832
-------------------------------------------------------------------------
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to