-/* sja1000.c
- * Linux CAN-bus device driver.
- * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
- * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
- * email:pisa@cmp.felk.cvut.cz
- * This software is released under the GPL-License.
- * Version lincan-0.3 17 Jun 2004
- */
+/**************************************************************************/
+/* File: sja1000.c - Philips/NXP SJA1000 chip legacy mode (deprecated) */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN 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 LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
#include "../include/can.h"
#include "../include/can_sysdep.h"
return -ENODEV;
/* Set mode, clock out, comparator */
- can_write_reg(chip,chip->sja_cdr_reg,SJACDR);
+ can_write_reg(chip,chip->sja_cdr_reg,SJACDR);
/* Set driver output configuration */
- can_write_reg(chip,chip->sja_ocr_reg,SJAOCR);
+ can_write_reg(chip,chip->sja_ocr_reg,SJAOCR);
if (sja1000_standard_mask(chip,0x0000, 0xffff))
return -ENODEV;
-
+
if (!chip->baudrate)
chip->baudrate=1000000;
if (sja1000_baud_rate(chip,chip->baudrate,chip->clock,0,75,0))
return -ENODEV;
/* Enable hardware interrupts */
- can_write_reg(chip,(sjaCR_RIE|sjaCR_TIE|sjaCR_EIE|sjaCR_OIE),SJACR);
+ can_write_reg(chip,(sjaCR_RIE|sjaCR_TIE|sjaCR_EIE|sjaCR_OIE),SJACR);
sja1000_disable_configuration(chip);
-
+
return 0;
}
if (sja1000_enable_configuration(chip))
return -ENODEV;
- /* The acceptance code bits (SJAACR bits 0-7) and the eight most
+ /* The acceptance code bits (SJAACR bits 0-7) and the eight most
* significant bits of the message identifier (id.10 to id.3) must be
- * equal to those bit positions which are marked relevant by the
+ * equal to those bit positions which are marked relevant by the
* acceptance mask bits (SJAAMR bits 0-7).
* (id.10 to id.3) = (SJAACR.7 to SJAACR.0) v (SJAAMR.7 to SJAAMR.0)
* (Taken from Philips sja1000 Data Sheet)
*/
write_code = (unsigned char) code >> 3;
write_mask = (unsigned char) mask >> 3;
-
+
can_write_reg(chip,write_code,SJAACR);
can_write_reg(chip,write_mask,SJAAMR);
int best_error = 1000000000, error;
int best_tseg=0, best_brp=0, best_rate=0, brp=0;
int tseg=0, tseg1=0, tseg2=0;
-
+
if (sja1000_enable_configuration(chip))
return -ENODEV;
int sja1000_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
{
int i;
-
+
i=can_read_reg(chip,SJASR);
-
+
if (!(i&sjaSR_RBS)) {
//Temp
for (i=0; i<0x20; i++)
sja1000_start_chip(chip);
// disable interrupts for a moment
- can_write_reg(chip, 0, SJACR);
+ can_write_reg(chip, 0, SJACR);
sja1000_irq_read_handler(chip, obj);
#define MAX_TRANSMIT_WAIT_LOOPS 10
-int sja1000_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
+int sja1000_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
struct canmsg_t *msg)
{
int i=0, id=0;
sja1000_start_chip(chip); //sja1000 goes automatically into reset mode on errors
/* Wait until Transmit Buffer Status is released */
- while ( !(can_read_reg(chip, SJASR) & sjaSR_TBS) &&
+ while ( !(can_read_reg(chip, SJASR) & sjaSR_TBS) &&
i++<MAX_TRANSMIT_WAIT_LOOPS) {
udelay(i);
}
-
+
if (!(can_read_reg(chip, SJASR) & sjaSR_TBS)) {
CANMSG("Transmit timed out, cancelling\n");
can_write_reg(chip, sjaCMR_AT, SJACMR);
return 0;
}
-int sja1000_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
+int sja1000_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
struct canmsg_t *msg)
{
can_write_reg(chip, sjaCMR_TR, SJACMR);
return 1;
}
-int sja1000_set_btregs(struct canchip_t *chip, unsigned short btr0,
+int sja1000_set_btregs(struct canchip_t *chip, unsigned short btr0,
unsigned short btr1)
{
if (sja1000_enable_configuration(chip))
return CANCHIP_IRQ_STUCK;
}
- if ((irq_register & sjaIR_RI) != 0)
+ if ((irq_register & sjaIR_RI) != 0)
sja1000_irq_read_handler(chip, obj);
- if ((irq_register & sjaIR_TI) != 0) {
+ if ((irq_register & sjaIR_TI) != 0) {
can_msgobj_set_fl(obj,TX_REQUEST);
while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
can_msgobj_clear_fl(obj,TX_REQUEST);
}
}
- if ((irq_register & (sjaIR_EI|sjaIR_DOI)) != 0) {
+ if ((irq_register & (sjaIR_EI|sjaIR_DOI)) != 0) {
// Some error happened
// FIXME: chip should be brought to usable state. Transmission cancelled if in progress.
// Reset flag set to 0 if chip is already off the bus. Full state report
irq_register=can_read_reg(chip, SJAIR);
} while(irq_register & (sjaIR_WUI|sjaIR_DOI|sjaIR_EI|sjaIR_TI|sjaIR_RI));
-
+
return CANCHIP_IRQ_HANDLED;
}
void sja1000_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
{
int cmd;
-
+
if(obj->tx_slot){
/* Do local transmitted message distribution if enabled */
if (processlocal){
/* fill CAN message timestamp */
can_filltimestamp(&obj->tx_slot->msg.timestamp);
-
+
obj->tx_slot->msg.flags |= MSG_LOCAL;
canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
}
int sja1000_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
{
can_preempt_disable();
-
+
can_msgobj_set_fl(obj,TX_REQUEST);
while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
can_msgobj_clear_fl(obj,TX_REQUEST);
if (can_read_reg(chip, SJASR) & sjaSR_TBS)
sja1000_irq_write_handler(chip, obj);
-
+
can_msgobj_clear_fl(obj,TX_LOCK);
if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
}