/**
 * @section License
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2017, Thomas Barth, barth-dev.de
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#ifndef __DRIVERS_CAN_REGDEF_H_
#define __DRIVERS_CAN_REGDEF_H_

#include "CAN.h"	//CAN_FIR_t

#ifdef __cplusplus
extern "C" {
#endif

/** \brief Start address of CAN registers */
#define MODULE_CAN              					((volatile CAN_Module_t    *)0x3ff6b000)

/** \brief Get standard message ID */
#define _CAN_GET_STD_ID								(((uint32_t)MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.ID[0] << 3) | \
													(MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.ID[1] >> 5))

/** \brief Get extended message ID */
#define _CAN_GET_EXT_ID								(((uint32_t)MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[0] << 21) | \
													(MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[1] << 13) | \
													(MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[2] << 5) | \
													(MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[3] >> 3 ))

/** \brief Set standard message ID */
#define _CAN_SET_STD_ID(x)							MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.ID[0] = ((x) >> 3);	\
													MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.ID[1] = ((x) << 5);

/** \brief Set extended message ID */
#define _CAN_SET_EXT_ID(x)							MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[0] = ((x) >> 21);	\
													MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[1] = ((x) >> 13);	\
													MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[2] = ((x) >> 5);	\
													MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[3] = ((x) << 3);	\

/** \brief Interrupt status register */
typedef enum  {
	__CAN_IRQ_RX=			BIT(0),					/**< \brief RX Interrupt */
	__CAN_IRQ_TX=			BIT(1),					/**< \brief TX Interrupt */
	__CAN_IRQ_ERR=			BIT(2),					/**< \brief Error Interrupt */
	__CAN_IRQ_DATA_OVERRUN=	BIT(3),					/**< \brief Date Overrun Interrupt */
	__CAN_IRQ_WAKEUP=		BIT(4),					/**< \brief Wakeup Interrupt */
	__CAN_IRQ_ERR_PASSIVE=	BIT(5),					/**< \brief Passive Error Interrupt */
	__CAN_IRQ_ARB_LOST=		BIT(6),					/**< \brief Arbitration lost interrupt */
	__CAN_IRQ_BUS_ERR=		BIT(7),					/**< \brief Bus error Interrupt */
}__CAN_IRQ_t;


/** \brief OCMODE options. */
typedef enum  {
	__CAN_OC_BOM=			0b00,					/**< \brief bi-phase output mode */
	__CAN_OC_TOM=			0b01,					/**< \brief test output mode */
	__CAN_OC_NOM=			0b10,					/**< \brief normal output mode */
	__CAN_OC_COM=			0b11,					/**< \brief clock output mode */
}__CAN_OCMODE_t;


/**
 * CAN controller (SJA1000).
 */
typedef struct {
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
	        unsigned int RM:1; 						/**< \brief MOD.0 Reset Mode */
	        unsigned int LOM:1;            			/**< \brief MOD.1 Listen Only Mode */
	        unsigned int STM:1;                     /**< \brief MOD.2 Self Test Mode */
	        unsigned int AFM:1;                   	/**< \brief MOD.3 Acceptance Filter Mode */
	        unsigned int SM:1;            			/**< \brief MOD.4 Sleep Mode */
	        unsigned int reserved_27:27;            /**< \brief \internal Reserved */
	    } B;
	} MOD;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
	        unsigned int TR:1; 						/**< \brief CMR.0 Transmission Request */
	        unsigned int AT:1;            			/**< \brief CMR.1 Abort Transmission */
	        unsigned int RRB:1;                     /**< \brief CMR.2 Release Receive Buffer */
	        unsigned int CDO:1;                   	/**< \brief CMR.3 Clear Data Overrun */
	        unsigned int GTS:1;            			/**< \brief CMR.4 Go To Sleep */
	        unsigned int reserved_27:27;            /**< \brief \internal Reserved */
	    } B;
	} CMR;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
	        unsigned int RBS:1; 					/**< \brief SR.0 Receive Buffer Status */
	        unsigned int DOS:1;            			/**< \brief SR.1 Data Overrun Status */
	        unsigned int TBS:1;                     /**< \brief SR.2 Transmit Buffer Status */
	        unsigned int TCS:1;                   	/**< \brief SR.3 Transmission Complete Status */
	        unsigned int RS:1;            			/**< \brief SR.4 Receive Status */
	        unsigned int TS:1;            			/**< \brief SR.5 Transmit Status */
	        unsigned int ES:1;            			/**< \brief SR.6 Error Status */
	        unsigned int BS:1;            			/**< \brief SR.7 Bus Status */
	        unsigned int reserved_24:24;            /**< \brief \internal Reserved */
	    } B;
	} SR;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
	        unsigned int RI:1; 						/**< \brief IR.0 Receive Interrupt */
	        unsigned int TI:1;            			/**< \brief IR.1 Transmit Interrupt */
	        unsigned int EI:1;                     	/**< \brief IR.2 Error Interrupt */
	        unsigned int DOI:1;                   	/**< \brief IR.3 Data Overrun Interrupt */
	        unsigned int WUI:1;            			/**< \brief IR.4 Wake-Up Interrupt */
	        unsigned int EPI:1;            			/**< \brief IR.5 Error Passive Interrupt */
	        unsigned int ALI:1;            			/**< \brief IR.6 Arbitration Lost Interrupt */
	        unsigned int BEI:1;            			/**< \brief IR.7 Bus Error Interrupt */
	        unsigned int reserved_24:24;            /**< \brief \internal Reserved */
	    } B;
	} IR;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
	        unsigned int RIE:1; 					/**< \brief IER.0 Receive Interrupt Enable */
	        unsigned int TIE:1;            			/**< \brief IER.1 Transmit Interrupt Enable */
	        unsigned int EIE:1;                     /**< \brief IER.2 Error Interrupt Enable */
	        unsigned int DOIE:1;                   	/**< \brief IER.3 Data Overrun Interrupt Enable */
	        unsigned int WUIE:1;            		/**< \brief IER.4 Wake-Up Interrupt Enable */
	        unsigned int EPIE:1;            		/**< \brief IER.5 Error Passive Interrupt Enable */
	        unsigned int ALIE:1;            		/**< \brief IER.6 Arbitration Lost Interrupt Enable */
	        unsigned int BEIE:1;            		/**< \brief IER.7 Bus Error Interrupt Enable */
	        unsigned int reserved_24:24;            /**< \brief \internal Reserved  */
	    } B;
	} IER;
    uint32_t RESERVED0;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
	        unsigned int BRP:6; 					/**< \brief BTR0[5:0] Baud Rate Prescaler */
	        unsigned int SJW:2;            			/**< \brief BTR0[7:6] Synchronization Jump Width*/
	        unsigned int reserved_24:24;            /**< \brief \internal Reserved  */
	    } B;
	} BTR0;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
	        unsigned int TSEG1:4; 					/**< \brief BTR1[3:0] Timing Segment 1 */
	        unsigned int TSEG2:3;            		/**< \brief BTR1[6:4] Timing Segment 2*/
	        unsigned int SAM:1;            			/**< \brief BTR1.7 Sampling*/
	        unsigned int reserved_24:24;            /**< \brief \internal Reserved  */
	    } B;
	} BTR1;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
			unsigned int OCMODE:2; 					/**< \brief OCR[1:0] Output Control Mode, see # */
			unsigned int OCPOL0:1;                  /**< \brief OCR.2 Output Control Polarity 0 */
			unsigned int OCTN0:1;                   /**< \brief OCR.3 Output Control Transistor N0 */
			unsigned int OCTP0:1;            		/**< \brief OCR.4 Output Control Transistor P0 */
			unsigned int OCPOL1:1;            		/**< \brief OCR.5 Output Control Polarity 1 */
			unsigned int OCTN1:1;            		/**< \brief OCR.6 Output Control Transistor N1 */
			unsigned int OCTP1:1;            		/**< \brief OCR.7 Output Control Transistor P1 */
			unsigned int reserved_24:24;            /**< \brief \internal Reserved  */
	    } B;
	} OCR;
    uint32_t RESERVED1[2];
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
			unsigned int ALC:8; 					/**< \brief ALC[7:0] Arbitration Lost Capture */
			unsigned int reserved_24:24;            /**< \brief \internal Reserved  */
	    } B;
	} ALC;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
			unsigned int ECC:8; 					/**< \brief ECC[7:0] Error Code Capture */
			unsigned int reserved_24:24;            /**< \brief \internal Reserved  */
	    } B;
	} ECC;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
			unsigned int EWLR:8; 					/**< \brief EWLR[7:0] Error Warning Limit */
			unsigned int reserved_24:24;            /**< \brief \internal Reserved  */
	    } B;
	} EWLR;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
			unsigned int RXERR:8; 					/**< \brief RXERR[7:0] Receive Error Counter */
			unsigned int reserved_24:24;            /**< \brief \internal Reserved  */
	    } B;
	} RXERR;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
			unsigned int TXERR:8; 					/**< \brief TXERR[7:0] Transmit Error Counter */
			unsigned int reserved_24:24;            /**< \brief \internal Reserved  */
	    } B;
	} TXERR;

    union {
        struct {
            uint32_t CODE[4];						/**< \brief Acceptance Message ID */
            uint32_t MASK[4];						/**< \brief Acceptance Mask */
            uint32_t RESERVED2[5];
        } ACC;										/**< \brief Acceptance filtering */
        struct {
        	CAN_FIR_t	FIR;						/**< \brief Frame information record */
        	union{
				struct {
					uint32_t ID[2];					/**< \brief Standard frame message-ID*/
					uint32_t data[8];				/**< \brief Standard frame payload */
					uint32_t reserved[2];
				} STD;								/**< \brief Standard frame format */
				struct {
					uint32_t ID[4];					/**< \brief Extended frame message-ID*/
					uint32_t data[8];				/**< \brief Extended frame payload */
				} EXT;								/**< \brief Extended frame format */
        	}TX_RX;									/**< \brief RX/TX interface */
        }FCTRL;										/**< \brief Function control regs */
    } MBX_CTRL;										/**< \brief Mailbox control */
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
			unsigned int RMC:8; 					/**< \brief RMC[7:0] RX Message Counter */
			unsigned int reserved_24:24;            /**< \brief \internal Reserved Enable */
	    } B;
	} RMC;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
			unsigned int RBSA:8; 					/**< \brief RBSA[7:0] RX Buffer Start Address  */
			unsigned int reserved_24:24;            /**< \brief \internal Reserved Enable */
	    } B;
	} RBSA;
	union{uint32_t U;								/**< \brief Unsigned access */
	    struct {
			unsigned int COD:3; 					/**< \brief CDR[2:0] CLKOUT frequency selector based of fOSC*/
			unsigned int COFF:1; 					/**< \brief CDR.3 CLKOUT off*/
			unsigned int reserved_1:1; 				/**< \brief \internal Reserved */
			unsigned int RXINTEN:1; 				/**< \brief CDR.5 This bit allows the TX1 output to be used as a dedicated receive interrupt output*/
			unsigned int CBP:1; 					/**< \brief CDR.6 allows to bypass the CAN input comparator and is only possible in reset mode.*/
			unsigned int CAN_M:1; 					/**< \brief CDR.7 If CDR.7 is at logic 0 the CAN controller operates in BasicCAN mode. If set to logic 1 the CAN controller operates in PeliCAN mode. Write access is only possible in reset mode*/
			unsigned int reserved_24:24;            /**< \brief \internal Reserved  */
	    } B;
	} CDR;
    uint32_t IRAM[2];
}CAN_Module_t;

#ifdef __cplusplus
}
#endif

#endif /* __DRIVERS_CAN_REGDEF_H_ */
