/****************************************************************************/
/* Copyright 2010, © Bendor Research Pty. Ltd. All rights reserved.			*/
/* Permission is granted to use this software for any purpose whatsoever	*/
/* as long as this copyright notice is preserved. The code is provided		*/
/* "as is", with no explicit, implicit or implied warranty or guarantee		*/
/* of any kind and Bendor Research Pty. Ltd. can not be held liable for		*/
/* any loss or damages arising out of the use of this software.				*/
/****************************************************************************/
/*																			*/
/*	Include file describing the Philips LPC23xx CAN controller				*/
/*	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~				*/
/*																			*/
/*	2010 Mar	ZK		Original											*/
/*	2010 May	ZK		Modified to match NXP's names						*/
/*																			*/
/****************************************************************************/

#ifndef _LPC23XX_CAN
#define _LPC23XX_CAN

/*
*	Buffer descriptor
*/

struct lpc23xx_canb {

	union {

		unsigned	tfi;			// Transmit frame information
		unsigned	rfs;			// Receive frame status
	};
	unsigned		id;				// Frame identifier
	unsigned char	d[ 8 ];			// Frame data
};

/*
*	Individual controller registers
*/

struct	lpc23xx_canx {

	unsigned			mod;		// Operating mode control
	unsigned			cmr;		// Operation command
	unsigned			gsr;		// Global status and error counters
	unsigned			icr;		// Interrupt and error status
	unsigned			ier;		// Interrupt enable
	unsigned			btr;		// Bus timing control
	unsigned			ewl;		// Error warning limit
	unsigned			sr;			// Status
	struct lpc23xx_canb	rb;			// Receive buffer
	struct lpc23xx_canb	tb[ 3 ];	// Transmit buffers
	unsigned _[4072];
};

/*
*	The filter memory, filter control and two CAN controllers
*/

struct	lpc23xx_can {

	unsigned			af[ 512 ];	// Acceptance filter words
	unsigned _1[3584];
	unsigned		afmr;			// Acceptance filter mode reg
	unsigned		*sff_sa;		// Standard frame individual start addr
	unsigned		*sff_gpr_sa;	// Standard frame group start address
	unsigned		*eff_sa;		// Extended frame individual start addr
	unsigned		*eff_grp_sa;	// Extended frame group start address
	unsigned		*endoftable;	// End of AF table address
	unsigned		*luterrad;		// Look-up table error address
	unsigned		luterr;			// Look-up table error
	unsigned		fcanie;			// FullCAN interrupt enable reg
	unsigned		fcanic0;		// FullCAN interrupt and capture reg 0
	unsigned		fcanic1;		// FullCAN interrupt and capture reg 0
	unsigned _2[4085];
	unsigned		txsr;			// Central transmit status reg
	unsigned		rxsr;			// Central receive status reg
	unsigned		msr;			// Central miscallaneous reg
	unsigned _3[8189];
	struct lpc23xx_canx ctl[2];		// Two CAN controllers, sharing the filter
};

/****************************************************************************/
/*		Register defs for the individual CAN controllers					*/
/****************************************************************************/

/*
*	Definition of the MOD register
*/

#define	CAN_MOD_RM		0x01		// Reset
#define	CAN_MOD_LOM		0x02		// Listen only mode
#define	CAN_MOD_STM		0x04		// Self-test mode
#define	CAN_MOD_TPM		0x08		// Transmit priority (1:CAD ID 0:by setting)
#define	CAN_MOD_SM		0x10		// Sleep mode
#define	CAN_MOD_RPM		0x20		// Receive polarity, active low(0) / high(1)
#define	CAN_MOD_TM		0x80		// Test mode

/*
*	Definition of the CMR register
*/

#define	CAN_CMR_TR		0x01		// Transmit request
#define	CAN_CMR_AT		0x02		// Abort transmission
#define	CAN_CMR_RRB		0x04		// Release receive buffer
#define	CAN_CMR_CDO		0x08		// Clear data overrrun
#define	CAN_CMR_SRR		0x10		// Self reception request
#define	CAN_CMR_STB1	0x20		// Select transmit buffer 1
#define	CAN_CMR_STB2	0x40		// Select transmit buffer 1
#define	CAN_CMR_STB3	0x80		// Select transmit buffer 1

/*
*	Definition of the GSR register
*/

#define	CAN_GSR_RBS		0x01		// Receive buffer full
#define	CAN_GSR_DOS		0x02		// Data overrun
#define	CAN_GSR_TBS		0x04		// Transmit buffer free
#define	CAN_GSR_TCS		0x08		// Transmit complete
#define	CAN_GSR_RS		0x10		// Reception is in progress
#define	CAN_GSR_TS		0x20		// Transmission is in progress
#define	CAN_GSR_ES		0x40		// An error counter is above warning
#define	CAN_GSR_BS		0x80		// Bus-off state reacher

/*
*	Definition of the ICR register
*/

#define	CAN_ICR_RI		0x00000001	// Receive interrupt
#define	CAN_ICR_TI1		0x00000002	// Transmit interrupt 1
#define	CAN_ICR_EI		0x00000004	// Error warning interrupt
#define	CAN_ICR_DOI		0x00000008	// Data overrun interrupt
#define	CAN_ICR_WUI		0x00000010	// Wake-up interrupt
#define	CAN_ICR_EPI		0x00000020	// Error-passive interrupt
#define	CAN_ICR_ALI		0x00000040	// Arbitration lost interrupt
#define	CAN_ICR_BEI		0x00000080	// Bus error interrupt
#define	CAN_ICR_IDI		0x00000100	// ID ready interrupt
#define	CAN_ICR_TI2		0x00000200	// Transmit interrupt 2
#define	CAN_ICR_TI3		0x00000400	// Transmit interrupt 3
#define	CAN_ICR_ERRBIT	0x001f0000	// Error code capture code mask
#define	CAN_ICR_ERRDIR	0x00200000	// Error during Tx(0) or RX(1)
#define	CAN_ICR_ERRC	0x00c00000	// Error type
#define	CAN_ICR_ALCBIT	0xff000000	// Bit number where arbitration was lost

#define	CAN_ERRBIT_SOF		( 3<<16)	// Start of frame
#define	CAN_ERRBIT_ID28_21	( 2<<16)	// Between ID28 and ID21
#define	CAN_ERRBIT_ID20_18	( 6<<16)	// Between ID20 and ID18
#define	CAN_ERRBIT_SRTR		( 4<<16)	// SRTR bit
#define	CAN_ERRBIT_IDE		( 5<<16)	// IDE bit
#define	CAN_ERRBIT_ID17_13	( 7<<16)	// Between ID17 and ID13
#define	CAN_ERRBIT_ID12_5	(15<<16)	// Between ID12 and ID5
#define	CAN_ERRBIT_ID4_0	(14<<16)	// Between ID4 and ID0
#define	CAN_ERRBIT_RTR		(12<<16)	// RTR bit
#define	CAN_ERRBIT_RESB1	(13<<16)	// Reserved bit 1
#define	CAN_ERRBIT_RESB2	( 9<<16)	// Reserved bit 2
#define	CAN_ERRBIT_DLC		(11<<16)	// DLC bit
#define	CAN_ERRBIT_DATA		(10<<16)	// Data field
#define	CAN_ERRBIT_CRCS		( 8<<16)	// CRC sequence
#define	CAN_ERRBIT_CRCD		(24<<16)	// CRC delimiter
#define	CAN_ERRBIT_ACKS		(25<<16)	// Acknowledge slot
#define	CAN_ERRBIT_ACKD		(27<<16)	// Acknowledge delimiter
#define	CAN_ERRBIT_EOF		(26<<16)	// End of frame
#define	CAN_ERRBIT_IMS		(18<<16)	// Intermission
#define	CAN_ERRBIT_AEF		(17<<16)	// Active error flag
#define	CAN_ERRBIT_PEF		(22<<16)	// Passive error flag
#define	CAN_ERRBIT_TDB		(19<<16)	// Tolerate dominant bits
#define	CAN_ERRBIT_ED		(23<<16)	// Error delimiter
#define	CAN_ERRBIT_OLD		(28<<16)	// Overload flag

#define	CAN_ERRC_BE			(0<<22)		// Bit error
#define	CAN_ERRC_FE			(1<<22)		// Form error
#define	CAN_ERRC_SE			(2<<22)		// Stuff error
#define	CAN_ERRC_OE			(3<<22)		// Other error

/*
*	Definition if the IER register
*/

#define	CAN_IER_RIE		0x001		// Receive interrupt
#define	CAN_IER_TIE1	0x002		// Transmit interrupt 1
#define	CAN_IER_EIE		0x004		// Error warning interrupt
#define	CAN_IER_DOIE	0x008		// Data overrun interrupt
#define	CAN_IER_WUIE	0x010		// Wake-up interrupt
#define	CAN_IER_EPIE	0x020		// Error-passive interrupt
#define	CAN_IER_ALIE	0x040		// Arbitration lost interrupt
#define	CAN_IER_BEIE	0x080		// Bus error interrupt
#define	CAN_IER_IDIE	0x100		// ID ready interrupt
#define	CAN_IER_TIE2	0x200		// Transmit interrupt 2
#define	CAN_IER_TIE3	0x400		// Transmit interrupt 3

/*
*	Definition of the BTR register
*/

#define	CAN_BTR_BRP(n)	 (n)		// Baud rate prescaler
#define	CAN_BTR_SJW(n)	 ((n)<<14)	// Synchrnisation jump width
#define	CAN_BTR_TESG1(n) ((n)<<16)	// Time segment 1
#define	CAN_BTR_TESG2(n) ((n)<<20)	// Time segment 2
#define	CAN_BTR_SAM		 0x80000	// Sample 1(0) or 3(1) times

/*
*	Definition of the SR register
*	The RBS, DOS, RS, ES and BS bits are repeated in this register
*	three times. Only the lowest bit number instance is defined here.
*	The other instances can be found 8 and 16 bits to the left.
*/

#define	CAN_SR_RBS		0x000001	// Receive buffer status
#define	CAN_SR_DOS		0x000002	// Data overrun status
#define	CAN_SR_TBS1		0x000004	// Transmit buffer 1 status
#define	CAN_SR_TCS1		0x000008	// Transmit complete 1 status
#define	CAN_SR_RS		0x000010	// Receive status
#define	CAN_SR_TS1		0x000020	// Transmit 1 status
#define	CAN_SR_ES		0x000040	// Error status
#define	CAN_SR_BS		0x000080	// Bus status
#define	CAN_SR_TBS2		0x000400	// Transmit buffer 2 status
#define	CAN_SR_TCS2		0x000800	// Transmit complete 2 status
#define	CAN_SR_TS2		0x002000	// Transmit 2 status
#define	CAN_SR_TBS3		0x000400	// Transmit buffer 3 status
#define	CAN_SR_TCS3		0x000800	// Transmit complete 3 status
#define	CAN_SR_TS3		0x002000	// Transmit 3 status

/*
*	Definition of the RFS register
*/

#define	CAN_RFS_IDI_M	0x000001ff	// ID index (to the filter table) mask
#define	CAN_RFS_IDI_S	0			// ID index (to the filter table) shift
#define CAN_RFS_BP		0x00000200	// Indicates bypass mode
#define	CAN_RFS_DLC_M	0x000f0000	// Data length code mask
#define	CAN_RFS_DLC_S	16			// Data length code shift
#define	CAN_RFS_RTR		0x40000000	// RTR bit was received
#define	CAN_RFS_FF		0x80000000	// Extended ID frame was received

/*
*	Definition of the TFI register
*/

#define	CAN_TFI_PRIO(n)	(n)			// Priority (8 bits)
#define	CAN_TFI_DLC(n)	((n)<<16)	// Data length, 0-8
#define	CAN_TFI_RTR		0x40000000	// Remote transmission request
#define	CAN_TFI_FF		0x80000000	// Extended ID frame

/****************************************************************************/
/*		Register defs for centralized CAN registers							*/
/****************************************************************************/

/*
*	The TXSR register
*/

#define	CAN_TXSR_TS1	0x000001	// Same as controller 1 GSR:TS
#define	CAN_TXSR_TS2	0x000002	// Same as controller 2 GSR:TS
#define	CAN_TXSR_TBS1	0x000100	// Same as controller 1 GSR:TBS
#define	CAN_TXSR_TBS2	0x000200	// Same as controller 2 GSR:TBS
#define	CAN_TXSR_TCS1	0x020000	// Same as controller 1 GSR:TCS
#define	CAN_TXSR_TCS2	0x020000	// Same as controller 2 GSR:TCS

/*
*	The RXSR register
*/

#define CAN_RXSR_RS1	0x000001	// Same as controller 1 GSR:RS
#define CAN_RXSR_RS2	0x000002	// Same as controller 2 GSR:RS
#define CAN_RXSR_RB1	0x000100	// Same as controller 1 GSR:RB
#define CAN_RXSR_RB2	0x000200	// Same as controller 2 GSR:RB
#define CAN_RXSR_DOS1	0x010000	// Same as controller 1 GSR:DOS
#define CAN_RXSR_DOS2	0x020000	// Same as controller 2 GSR:DOS

/*
*	The MSR register
*/

#define	CAN_MSR_E1		0x000001	// Same as controller 1 GSR:ES
#define	CAN_MSR_E2		0x000002	// Same as controller 2 GSR:ES
#define	CAN_MSR_BS1		0x000100	// Same as controller 1 GSR:BS
#define	CAN_MSR_BS2		0x000200	// Same as controller 2 GSR:BS

/****************************************************************************/
/*		Register defs for acceptance filter									*/
/****************************************************************************/

/*
*	Definition of the AFMR register
*/

#define	CAN_AFMR_ACCOFF	0x01		// Acceptance filter is off
#define	CAN_AFMR_ACCBP	0x02		// Acceptance filter bypass
#define	CAN_AFMR_EFCAN	0x04		// Enable FullCAN mode

/*
*	Definition of the LUTERR register
*/

#define	CAN_LUTERR_LUTERR	0x01	// Indicates look-up table error

/*
*	Definition of the FCANIE register
*/

#define	CAN_FCANIE_FCANIE	0x01	// FullCAN interrupt enable

/*
*	CAN controller instance
*/

static volatile struct lpc23xx_can * const lpc_can = (void *) 0xe0038000;

#endif

