Browse Source

first commit source + header

simon bischof 7 years ago
commit
aefc9183eb
59 changed files with 23621 additions and 0 deletions
  1. 1 0
      .metadata/.plugins/org.eclipse.cdt.make.core/specs.c
  2. 109 0
      BMS Master/PRC0_Sources/Exceptions.c
  3. 255 0
      BMS Master/PRC0_Sources/IntcInterrupts_p0.c
  4. 86 0
      BMS Master/PRC0_Sources/ivor_branch_table_p0.c
  5. 24 0
      BMS Master/Project_Headers/BMS_CAN0_gen_test_data.h
  6. 163 0
      BMS Master/Project_Headers/BMS_CANx_Tools.h
  7. 462 0
      BMS Master/Project_Headers/BMS_Defines.h
  8. 237 0
      BMS Master/Project_Headers/BMS_Master.h
  9. 30 0
      BMS Master/Project_Headers/BMS_SoC_estimator.h
  10. 1070 0
      BMS Master/Project_Headers/BMS_Typedefs.h
  11. 48 0
      BMS Master/Project_Headers/BoardPeripherals.h
  12. 43 0
      BMS Master/Project_Headers/DSPI.h
  13. 17 0
      BMS Master/Project_Headers/DebugUndTest.h
  14. 55 0
      BMS Master/Project_Headers/Device.h
  15. 50 0
      BMS Master/Project_Headers/Exceptions.h
  16. 95 0
      BMS Master/Project_Headers/FRAM.h
  17. 102 0
      BMS Master/Project_Headers/FlexCAN.h
  18. 65 0
      BMS Master/Project_Headers/IntcInterrupts.h
  19. 68 0
      BMS Master/Project_Headers/LIN_Uart.h
  20. 8473 0
      BMS Master/Project_Headers/MPC5646C.h
  21. 156 0
      BMS Master/Project_Headers/MPC5646C_HWInit.h
  22. 76 0
      BMS Master/Project_Headers/MultitaskOS.h
  23. 59 0
      BMS Master/Project_Headers/RelaisLEDs.h
  24. 50 0
      BMS Master/Project_Headers/TempSensorSpi.h
  25. 33 0
      BMS Master/Project_Headers/UartToUsb.h
  26. 122 0
      BMS Master/Project_Headers/typedefs.h
  27. 27 0
      BMS Master/Project_Headers/utils.h
  28. 425 0
      BMS Master/Project_Settings/Startup_Code/MPC5646C_HWInit.c
  29. 19 0
      BMS Master/Project_Settings/Startup_Code/MPC5646C_Startup.c
  30. 106 0
      BMS Master/Project_Settings/Startup_Code/MPC5646C_init_flash.c
  31. 70 0
      BMS Master/Project_Settings/Startup_Code/MPC5646C_init_ram.c
  32. 864 0
      BMS Master/Project_Settings/Startup_Code/__ppc_eabi_init.c
  33. 1054 0
      BMS Master/Sources/BMS_CAN0_Mail_Box.c
  34. 627 0
      BMS Master/Sources/BMS_CAN0_Tools.c
  35. 168 0
      BMS Master/Sources/BMS_CAN0_gen_test_data.c
  36. 212 0
      BMS Master/Sources/BMS_CAN1_Mail_Box.c
  37. 163 0
      BMS Master/Sources/BMS_CAN1_Tools.c
  38. 172 0
      BMS Master/Sources/BMS_CAN2_Mail_Box.c
  39. 220 0
      BMS Master/Sources/BMS_CAN2_Tools.c
  40. 201 0
      BMS Master/Sources/BMS_Can_ID_init.c
  41. 856 0
      BMS Master/Sources/BMS_Cell_Config.c
  42. 265 0
      BMS Master/Sources/BMS_Clear_Error_States.c
  43. 347 0
      BMS Master/Sources/BMS_Error_Stack.c
  44. 88 0
      BMS Master/Sources/BMS_Inverter_status.c
  45. 2029 0
      BMS Master/Sources/BMS_Master.c
  46. 447 0
      BMS Master/Sources/BMS_Set_Error_States.c
  47. 822 0
      BMS Master/Sources/BMS_SoC_estimator.c
  48. 287 0
      BMS Master/Sources/BMS_Startup.c
  49. 107 0
      BMS Master/Sources/BoardPeripherals.c
  50. 292 0
      BMS Master/Sources/DSPI.c
  51. 241 0
      BMS Master/Sources/Device.c
  52. 489 0
      BMS Master/Sources/FRAM.c
  53. 356 0
      BMS Master/Sources/FlexCAN.c
  54. 98 0
      BMS Master/Sources/IntcIsrVectors.c
  55. 138 0
      BMS Master/Sources/MultitaskOS.c
  56. 136 0
      BMS Master/Sources/RelaisLEDs.c
  57. 10 0
      BMS Master/Sources/SOC_estimator.c
  58. 136 0
      BMS Master/Sources/TempSensorSpi.c
  59. 200 0
      BMS Master/Sources/main.c

+ 1 - 0
.metadata/.plugins/org.eclipse.cdt.make.core/specs.c

@@ -0,0 +1 @@
+

+ 109 - 0
BMS Master/PRC0_Sources/Exceptions.c

@@ -0,0 +1,109 @@
+/** 
+ * FILE: Exceptions_p0.c
+ * 
+ * COPYRIGHT (c) 2002-2012 Freescale Semiconductor, Inc. All rights reserved.
+ * 
+ * DESCRIPTION: Setup of Core_0 IVPR to point to the EXCEPTION_HANDLERS memory area 
+ *              defined in the linker command file.
+ *              Default setup of the IVORxx registers.
+ * 
+ * Note: We use "_p0" suffix on functions and section names to reference the
+ * Core_0, "_p1" for functions and section names using the Core_1.
+ * 
+ * VERSION: 1.1
+*/
+
+
+/*----------------------------------------------------------------------------*/
+/* Includes                                                                   */
+/*----------------------------------------------------------------------------*/
+
+#include "Exceptions.h" /* Implement functions from this file */
+
+/*----------------------------------------------------------------------------*/
+/* Function Implementations                                                   */
+/*----------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma push /* Save the current state */
+/* Symbol EXCEPTION_HANDLERS is defined in the application linker command file (.lcf) 
+   It is defined to the start of the code memory area used for the .__exception_handlers section. 
+*/
+/*lint -esym(752, EXCEPTION_HANDLERS) */
+__declspec (section ".__exception_handlers_p0") extern long EXCEPTION_HANDLERS;  
+#pragma force_active on
+#pragma function_align 16 /* We use 16 bytes alignment for IVOR exception table entries. */
+__declspec(interrupt)
+__declspec (section ".__exception_handlers_p0")
+void EXCEP_DefaultExceptionHandler(void)
+{
+
+}
+#pragma force_active off
+#pragma pop
+
+__asm void EXCEP_InitExceptionHandlers(void)
+{
+nofralloc
+    // Set the IVPR to the exception handlers address defined in the lcf file.
+    // The IVPR[0-15] bits Vector Base and IVPR[16-31] bits are ignored.
+    lis     r0, EXCEPTION_HANDLERS@h
+    mtivpr  r0
+
+    li		r0, EXCEPTION_HANDLERS@l
+    mtivor0 r0
+    
+    li		r0, (EXCEPTION_HANDLERS + 0x10)@l
+    mtivor1 r0
+    
+    li		r0, (EXCEPTION_HANDLERS + 0x20)@l
+    mtivor2 r0
+       	
+    li		r0, (EXCEPTION_HANDLERS + 0x30)@l
+    mtivor3 r0
+       	
+    li		r0, (EXCEPTION_HANDLERS + 0x40)@l
+    mtivor4 r0
+     	
+    li		r0, (EXCEPTION_HANDLERS + 0x50)@l
+    mtivor5 r0
+    
+    li		r0, (EXCEPTION_HANDLERS + 0x60)@l
+    mtivor6 r0
+    
+    li		r0, (EXCEPTION_HANDLERS + 0x70)@l
+    mtivor7 r0
+    
+    li		r0, (EXCEPTION_HANDLERS + 0x80)@l
+    mtivor8 r0
+    
+    li		r0, (EXCEPTION_HANDLERS + 0x90)@l
+    mtivor9 r0
+    
+    li		r0, (EXCEPTION_HANDLERS + 0xA0)@l
+    mtivor10 r0
+    
+    li		r0, (EXCEPTION_HANDLERS + 0xB0)@l
+    mtivor11 r0
+    
+    li		r0, (EXCEPTION_HANDLERS + 0xC0)@l
+    mtivor12 r0
+    
+    li		r0, (EXCEPTION_HANDLERS + 0xD0)@l
+    mtivor13 r0
+    
+    li		r0, (EXCEPTION_HANDLERS + 0xE0)@l
+    mtivor14 r0
+    
+    li		r0, (EXCEPTION_HANDLERS + 0xF0)@l
+    mtivor15 r0
+
+    blr
+}
+
+#ifdef __cplusplus
+}
+#endif
+

+ 255 - 0
BMS Master/PRC0_Sources/IntcInterrupts_p0.c

@@ -0,0 +1,255 @@
+/** 
+ * FILE: IntcInterrupts_p1.c
+ * 
+ * COPYRIGHT (c) 2002-2012 Freescale Semiconductor, Inc. All rights reserved.
+ * 
+ * DESCRIPTION: Contains the implementations of the generic interrupt 
+ * controller handling routines for the e200z4 MCU . The __INTCInterruptHandler__ 
+ * is located at no specific address and is branched by the PowerPC Zen core 
+ * to that location if the __initExternalInterrupts function has been called 
+ * to setup the core to do so.
+ *
+ * 
+ * Note: We use "_p0" suffix on functions and section names to reference the
+ * Core_0, "_p1" for functions and section names using the Core_1.
+ * 
+ * The following code setup the INTC module for Software Vector Mode.
+ * To enable the Hardware Vector Mode please consult the Qorivva cookbook AN2865.
+ *  
+ * VERSION: 1.2
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* By default we do not use nested interrupts, interrupts are handled in C.  */
+/* In case you want to use nested interrupts, set INTC_NESTED_INTERRUPT.     */
+/* In this case make sure all the needed registers are saved in the prolog   */
+/* and epilog of asm void INTC_INTCInterruptHandler(void)                    */
+/*---------------------------------------------------------------------------*/
+
+#ifndef INTC_NESTED_INTERRUPT
+#define INTC_NESTED_INTERRUPT 0
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Includes                                                                  */
+/*---------------------------------------------------------------------------*/
+
+#include "MPC5646C.h"          /* MPC55xx platform development header       */
+
+#include "IntcInterrupts.h"    /* Implement functions from this file        */
+
+
+
+/*---------------------------------------------------------------------------*/
+/* Inline Assembler Defines                                                  */
+/*---------------------------------------------------------------------------*/
+
+/* This macro allows to use C defined address with the inline assembler */
+#define MAKE_HLI_ADDRESS(hli_name, c_expr) /*lint -e753 */enum { hli_name=/*lint -e30*/((int)(c_expr)) /*lint -esym(749, hli_name) */ };
+
+/* Address of the IACKR Interrupt Controller register. */
+MAKE_HLI_ADDRESS(INTC_IACKR, &INTC.IACKR_PRC0.R)
+
+/* Address of the EOIR End-of-Interrupt Register register. */
+MAKE_HLI_ADDRESS(INTC_EOIR, &INTC.EOIR_PRC0.R)
+
+/* INTC.MCR -- caution, VTES and HVEN for both cores are in this register */
+MAKE_HLI_ADDRESS(INTC_MCR, &INTC.MCR.R)
+
+/*----------------------------------------------------------------------------*/
+/* Function Implementations                                                   */
+/*----------------------------------------------------------------------------*/
+
+/* This is the interrupt service routine table used in software mode.
+   The INTC supports 4 bytes or 8 byte entries, we will use 4 byte entries.
+   The 4/8 bytes mode is configured in INTC_InitINTCInterrupts.
+*/
+#define INTC_INTERRUPTS_REQUEST_VECTOR_TABLE_SIZE (278 * 4)
+
+#pragma push /* Save the current state */
+#pragma section data_type ".__initialized_intc_handlertable" ".__uninitialized_intc_handlertable"
+/* The INTC vector table will be placed in RAM. 
+   We will use the ".__uninitialized_intc_handlertable" name to do the 
+   placement in the Linker Command File (.lcf) to avoid the initialization at 
+   startup time.  This will decrease the code size, but the table won't be 
+   initialized to zero.
+*/ 
+INTCInterruptFn INTCInterruptsHandlerTable[INTC_INTERRUPTS_REQUEST_VECTOR_TABLE_SIZE];
+#pragma pop
+
+#pragma push             /* save the current state */
+#pragma force_active on  /* make sure this function remains */
+#pragma function_align 16 /* We use 16 bytes alignment for Exception handlers */
+/** Handle the interrupt source by jumping to the ISR branch table (IACKR) */
+
+#if INTC_NESTED_INTERRUPT == 0
+
+__declspec(section ".__exception_handlers_p0")
+__declspec(interrupt)
+void INTC_INTCInterruptHandler(void)
+{
+	INTCInterruptFn handlerFn;
+	
+	handlerFn = INTCInterruptsHandlerTable[INTC.IACKR_PRC0.R/4];
+	
+    (**handlerFn)();
+
+    INTC.EOIR_PRC0.R = 0;
+}
+
+#else
+
+__declspec(interrupt)
+__declspec(section ".__exception_handlers_p0")
+__asm void INTC_INTCInterruptHandler(void)
+{
+nofralloc
+prolog:
+    stwu    r1, -0x50 (r1)      /* Create stack frame */
+    stw r0,  0x24 (r1)          /* Store r0 working register  */
+
+    /* Save SRR0 and SRR1 */
+    mfsrr1  r0                  /* Store SRR1 (before enabling EE) */
+    stw     r0,  0x10 (r1)
+    mfsrr0  r0                  /* Store SRR0 (before enabling EE) */
+    stw     r0,  0x0C (r1)
+
+    /* Clear request to processor; r3 contains the address of the ISR */
+    stw     r3,  0x28 (r1)      /* Store r3 to work with */
+    lis     r3, INTC_IACKR@ha    /* Read pointer into ISR Vector Table */
+    lwz     r3, INTC_IACKR@l(r3) /* Load INTC_IACKR, which clears request to processor */
+    lwz     r3, 0x0(r3)         /* Read ISR address from ISR Vector Table using pointer  */
+ //   lwz     r3, 0x400088c6
+
+    /* Enable processor recognition of interrupts */
+    wrteei  1                   /* Set MSR[EE]=1  */
+
+    /* Save rest of context required by EABI */
+    stw     r12, 0x4C (r1)      /* Store r12 */
+    stw     r11, 0x48 (r1)      /* Store r11 */
+    stw     r10, 0x44 (r1)      /* Store r10 */
+    stw     r9,  0x40 (r1)      /* Store r9 */
+    stw     r8,  0x3C (r1)      /* Store r8 */
+    stw     r7,  0x38 (r1)      /* Store r7 */
+    stw     r6,  0x34 (r1)      /* Store r6 */
+    stw     r5,  0x30 (r1)      /* Store r5 */
+    stw     r4,  0x2C (r1)      /* Store r4 */
+    mfcr    r0                  /* Store CR */
+    stw     r0,  0x20 (r1)
+    mfxer   r0                  /* Store XER */
+    stw     r0,  0x1C (r1)
+    mfctr   r0                  /* Store CTR */
+    stw     r0,  0x18 (r1)
+    mflr    r0                  /* Store LR */
+    stw     r0,  0x14 (r1)
+
+    /* Branch to ISR handler address from SW vector table */
+    mtlr    r3                 /* Store ISR address to LR */
+    blrl                       /* Branch to ISR, but return here */
+
+epilog:
+    /* Restore context required by EABI (except working registers) */
+    lwz     r0,  0x14 (r1)      /* Restore LR */
+    mtlr    r0
+    lwz     r0,  0x18 (r1)      /* Restore CTR */
+    mtctr   r0
+    lwz     r0,  0x1C (r1)      /* Restore XER */
+    mtxer   r0
+    lwz     r0,  0x20 (r1)      /* Restore CR */
+    mtcrf   0xff, r0
+    lwz     r5,  0x30 (r1)      /* Restore r5 */
+    lwz     r6,  0x34 (r1)      /* Restore r6 */
+    lwz     r7,  0x38 (r1)      /* Restore r7 */
+    lwz     r8,  0x3C (r1)      /* Restore r8 */
+    lwz     r9,  0x40 (r1)      /* Restore r9 */
+    lwz     r10, 0x44 (r1)      /* Restore r10 */
+    lwz     r11, 0x48 (r1)      /* Restore r11 */
+    lwz     r12, 0x4C (r1)      /* Restore r12 */
+
+    /* Disable processor recognition of interrupts */
+    wrteei  0
+
+    /* Ensure interrupt flag has finished clearing */
+    mbar    0
+
+    /* Write 0 to INTC_EOIR, informing INTC to lower priority */
+    li      r3, 0
+    lis     r4, INTC_EOIR@ha    /* Load upper half of INTC_EOIR address */
+    stw     r3, INTC_EOIR@l(r4) /* Write 0 to INTC_EOIR */
+
+    /* Restore Working Registers */
+    lwz     r3,  0x28 (r1)      /* Restore r3 */
+    lwz     r4,  0x2C (r1)      /* Restore r4 */
+
+    /* Retrieve SRR0 and SRR1 */
+    lwz     r0,  0x0C (r1)      /* Restore SRR0 */
+    mtsrr0  r0
+    lwz     r0,  0x10 (r1)      /* Restore SRR1 */
+    mtsrr1  r0
+
+    /* Restore Other Working Registers */
+    lwz     r0,  0x24 (r1)      /* Restore r0 */
+
+    /* Restore space on stack */
+    addi    r1, r1, 0x50
+
+    /* End of Interrupt */
+    rfi
+}
+
+#endif
+
+#pragma force_active off
+#pragma pop
+
+/**
+ * This function can be used to install an interrupt handler for a given
+ * interrupt vector. It will also set the Priority Status Register for the
+ * source to the one given
+ */
+void INTC_InstallINTCInterruptHandler(INTCInterruptFn handlerFn, unsigned short vectorNum,
+                                      unsigned char psrPriority)
+{
+    /* Set the function pointer in the ISR Handler table */
+    INTCInterruptsHandlerTable[vectorNum] = handlerFn;
+    /* Set the PSR Priority */
+    INTC.PSR[vectorNum].B.PRI = psrPriority; 
+}
+
+/**
+ * This function will setup INTC for Software Vector Mode and
+ * the Vector Table Base Address to INTCInterruptsHandlerTable_p1.
+ * This function can be used from user_init() (no stack frame, no memory access).
+ * 
+ * Note the MCR is common to both cores so we just clear the flags for core 1.
+ */
+__asm void INTC_InitINTCInterrupts( void )
+{
+nofralloc
+    /* Set the location of the ISR Handler Table in INTC IACKR Register */
+    lis r0, INTCInterruptsHandlerTable@ha
+    ori r0, r0, INTCInterruptsHandlerTable@l
+    lis r3,INTC_IACKR@ha
+    stw r0, INTC_IACKR@l(r3)
+
+    /* Set INTC.MCR.B.HVEN_PRC0 = 0 for SW vector mode               */
+    /* and INTC.MCR.B.VTES_PRC0 = 0 for 4-byte branch table entries. */
+    lis r3, INTC_MCR@ha
+    lwz r0, INTC_MCR@l(r3)
+
+    /* clear VTES and HVEN flags for core 0*/
+    andi. r0, r0, 0xFF00
+    stw r0, INTC_MCR@l(r3)
+
+    /* Enable external interrupts by setting MSR[EE] = 1. */
+    wrteei 0
+    blr
+}
+
+#ifdef __cplusplus
+}
+#endif

+ 86 - 0
BMS Master/PRC0_Sources/ivor_branch_table_p0.c

@@ -0,0 +1,86 @@
+/*
+ * FILE: ivor_branch_table_p0.c
+ *   
+ * COPYRIGHT (c) 2007-2012 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * DESCRIPTION: e200z4 IVOR branch table interrupts for core 0. 
+ *
+ *  Rev 1.0 Jul 6 2007 S.M. - Initial version 
+ *  Translated to inline assembly to allow easy transition to VLE
+ *  Rev 1.1 Sept 2012 H.C. - add IVOR comments 
+ *  
+ * VERSION: 1.1 
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* IVOR4 will call this handler */
+extern void INTC_INTCInterruptHandler(void);
+
+#pragma push
+
+#define SIXTEEN_BYTES 16
+
+#pragma section code_type ".ivor_branch_table_p0"
+#pragma force_active on
+#pragma function_align 16  
+#pragma require_prototypes off
+
+asm void ivor_branch_table_p0(void) {
+nofralloc
+	.align SIXTEEN_BYTES
+IVOR0trap:  b   IVOR0trap /* Critical Input interrupt handler */ 
+
+	.align SIXTEEN_BYTES
+IVOR1trap:  b	IVOR1trap /* Machine check / (NMI) interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR2trap:  b	IVOR2trap /* Data Storage interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR3trap:  b	IVOR3trap /* Instruction Storage interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR4trap:  b   INTC_INTCInterruptHandler /* External Interrupt interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR5trap:  b	IVOR5trap /* Alignment interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR6trap:  b	IVOR6trap /* Program interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR7trap:  b	IVOR7trap /* Floating-point unavailable interrupt handler */
+
+.align SIXTEEN_BYTES
+IVOR8trap:  b	IVOR8trap /* System call interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR9trap:  b	IVOR9trap /* AP unavailable interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR10trap: b   IVOR10trap /* Decrementer interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR11trap:  b	IVOR11trap /* Fixed Interval Timer interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR12trap:  b	IVOR12trap /* Watchdog Timer interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR13trap:  b	IVOR13trap /* Data TLB Error interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR14trap:  b	IVOR14trap /* Instruction TLB Error interrupt handler */
+
+	.align SIXTEEN_BYTES
+IVOR15trap:  b  IVOR15trap  /* Debug Interrupt */
+}
+
+#pragma pop
+
+#ifdef __cplusplus
+}
+#endif

+ 24 - 0
BMS Master/Project_Headers/BMS_CAN0_gen_test_data.h

@@ -0,0 +1,24 @@
+/*
+ * BMS_CAN0_gen_test_data.h
+ *
+ *  Created on: May 18, 2016
+ *      Author: uacqk
+ */
+
+#ifndef BMS_CAN0_GEN_TEST_DATA_H_
+#define BMS_CAN0_GEN_TEST_DATA_H_
+
+void gen_data_initSlave(MASTER_CAN0_STRUCT_t* s, uint16_t default_voltage, int8_t default_temperature, uint16_t default_Ubat, uint16_t default_Ibat);
+void gen_data_generate_CAN0_UI_Telegram(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_UI_t* UI_Board,SLAVE_UI_BMS_TELEGRAM* rx_ptr);
+void gen_data_setUbatt(MASTER_CAN0_STRUCT_t* s);
+void gen_data_generate_CAN0_RX0_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X0_5_BMS_TELEGRAM* rx_ptr);
+void gen_data_generate_CAN0_RX1_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X0_5_BMS_TELEGRAM* rx_ptr);
+void gen_data_generate_CAN0_RX2_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X0_5_BMS_TELEGRAM* rx_ptr);
+void gen_data_generate_CAN0_RX3_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X0_5_BMS_TELEGRAM* rx_ptr); 
+void gen_data_generate_CAN0_RX4_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X0_5_BMS_TELEGRAM* rx_ptr); 
+void gen_data_generate_CAN0_RX5_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X0_5_BMS_TELEGRAM* rx_ptr);
+void gen_data_generate_CAN0_RX6_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X6_BMS_TELEGRAM* rx_ptr);
+void gen_data_generate_CAN0_RX7_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X7_BMS_TELEGRAM* rx_ptr); 
+
+
+#endif /* BMS_CAN0_GEN_TEST_DATA_H_ */

+ 163 - 0
BMS Master/Project_Headers/BMS_CANx_Tools.h

@@ -0,0 +1,163 @@
+//##############################################################################
+//
+// FILE:	BMS_CANx_Tools.h
+//
+// TITLE:	Header for BMS_CANx_Tools.c
+//
+//Modified for Use in RCT Project
+//##############################################################################
+//
+//==============================================================================
+// Change History:
+//==============================================================================
+// Datum:   | Name | Version:| Change / Cause:                            | No
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 002
+//------------------------------------------------------------------------------
+// 01.08.13 |  VR  |   1.1   | IAA Project                                | 001
+//------------------------------------------------------------------------------
+// 20.04.12 |  TM  |   1.0   | New Build                                  | 000
+//==============================================================================
+//==============================================================================
+// Comment Change / Cause:
+//==============================================================================
+// Change: 003                                                           // 003
+//----------------------
+//                                                       
+//
+//==============================================================================
+// Change: 002                                                           // 002
+//----------------------
+//                                           
+//
+//==============================================================================
+// Change: 001                                                           // 001
+//----------------------
+// 
+//
+//==============================================================================
+
+#ifndef __CAN_MASTER_H__
+#define __CAN_MASTER_H__
+
+
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+    
+
+
+// ***** External **************************************************************
+//extern CAN_MAILBOX	CAN_TxMB_BalancingCtrl_100;
+//
+//extern CAN_MAILBOX	CAN_TxMB_NLG5_CTL_618;
+//
+//extern CAN_MAILBOX	CAN_TxMB_BMU_DICO_18FF9F1E;
+//extern CAN_MAILBOX	CAN_TxMB_BMU1_EVCU1_18FF9E1E;
+//extern CAN_MAILBOX	CAN_RxMB_DICO1_EVCU_18FF8F03;
+//extern CAN_MAILBOX	CAN_RxMB_DICO2_EVCU_18FF8D03;
+//extern CAN_MAILBOX	CAN_RxMB_EVCU1_BMU_0CFF3D27;
+    
+
+
+
+
+extern MASTER_X_BMS_TELEGRAM	TelegramTxContainer[16];
+extern CAN_MAILBOX* MB_Container[16];
+
+// Mailboxes for Automatic CAN Id Initialization
+
+extern CAN_MAILBOX CAN_TxMB_System300;
+extern CAN_MAILBOX CAN_TxMB_System30A;
+extern CAN_MAILBOX CAN_TxMB_Master0A;
+
+
+
+
+// ***** Funktion Prototypes ***************************************************
+uint16_t 	CAN_Tx_Balance				( uint16_t i);
+void		check_and_save_Voltage		( CAN_MAILBOX *p_MBox, uint16_t SlaveNr, uint16_t SlaveOffset );
+void		check_and_save_Status		( CAN_MAILBOX *p_MBox, uint16_t SlaveNr );
+void		check_and_save_UI			( CAN_MAILBOX *p_MBox );
+void		check_and_save_Temperature	( CAN_MAILBOX *p_MBox, uint16_t SlaveNr, uint16_t SlaveOffset );
+int16_t 	check_Voltage_Border		( uint16_t Row, uint16_t Index );
+int16_t 	check_Status_Border			( uint16_t Row, uint16_t Index );
+int16_t 	check_UI_Border				( uint16_t Row  );
+int16_t 	check_Temperature_Border	( uint16_t Row, uint16_t Index );
+uint16_t 	Sum_Cell_Voltage			( uint16_t Row );
+uint16_t 	Test_MAX_LOAD_CELL_VOLTAGE	( uint16_t Row );
+uint16_t 	Search_MIN_CELL_VOLTAGE		( uint16_t Row );
+
+
+uint16_t 	CAN_Tx_NLG5_CTL_618			( void );
+void 		check_and_save_NLG5_ST		( CAN_MAILBOX *p_MBox );
+
+uint16_t 	CAN_Tx_BMU_DICO				( void );   
+uint16_t 	CAN_Tx_BMU1_EVCU1			( void ); 
+uint16_t 	check_and_save_DICO1_EVCU	( CAN_MAILBOX *p_MBox ); 
+uint16_t 	check_and_save_DICO2_EVCU	( CAN_MAILBOX *p_MBox );           
+uint16_t 	check_and_save_EVCU1_BMU	( CAN_MAILBOX *p_MBox );    
+
+uint16_t CAN_Rx_readout_Mailbox(CAN_MAILBOX *p_MBox,uint8_t *eight_byte_field);
+
+
+
+// ***** Global Prototypes *****************************************************
+uint16_t 	CAN0_init						(void);
+uint16_t 	CAN0_rx_test					(void); 
+uint16_t 	CAN0_tx_test					(uint8_t slave_nr,uint8_t *four_byte_field);
+//uint16_t	CAN0_tx_send_request_telegram	(uint8_t slaveNr);
+uint16_t	CAN0_tx_send_request_telegram	(BMS_CAN0_SLAVE_t* Slave,uint8_t MasterAlive);
+uint16_t 	CAN0_init_telegrams				(MASTER_X_BMS_TELEGRAM* telegram_ptr,uint8_t nrOfSlaves);
+uint16_t	CAN0_is_state_active			(uint8_t* activeSlaves,uint8_t nrOfActiveSlaves,uint8_t nrOfCurrentSlave);
+
+
+uint8_t 	CAN0_check_if_UI_Board_rec(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_UI_t* UI_Board);
+uint16_t 	CAN0_check_if_slave_rec			(BMS_CAN0_SLAVE_t* Slave);
+uint16_t 	saveSlaveX0_Master_telegram		(BMS_CAN0_SLAVE_t* Slave);
+uint16_t 	saveSlaveX1_Master_telegram		(BMS_CAN0_SLAVE_t* Slave);
+uint16_t 	saveSlaveX2_Master_telegram		(BMS_CAN0_SLAVE_t* Slave);
+uint16_t 	saveSlaveX3_Master_telegram		(BMS_CAN0_SLAVE_t* Slave);
+uint16_t 	saveSlaveX4_Master_telegram		(BMS_CAN0_SLAVE_t* Slave);
+uint16_t 	saveSlaveX5_Master_telegram		(BMS_CAN0_SLAVE_t* Slave);
+uint16_t 	saveSlaveX6_Master_telegram		(BMS_CAN0_SLAVE_t* Slave);
+uint16_t 	saveSlaveUI_Master_telegram(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_UI_t* UI_Board);
+uint16_t 	saveSlaveX7_Master_telegram		(BMS_CAN0_SLAVE_t* Slave);
+
+uint16_t 	CAN0_DEBUG_data_check_if_slave_rec(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_SLAVE_t* DummySlave);
+uint8_t 	CAN0_DEBUG_data_check_if_UI_Board_rec(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_SLAVE_t* DummySlave,BMS_CAN0_UI_t* UI_Board,BMS_CAN0_UI_t* Dummy_UI_Board);
+uint16_t 	CAN0_DEBUG_slave_check_if_slave_rec(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_SLAVE_t* DummySlave);
+uint8_t 	CAN0_DEBUG_slave_check_if_UI_Board_rec(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_SLAVE_t* DummySlave,BMS_CAN0_UI_t* UI_Board,BMS_CAN0_UI_t* Dummy_UI_Board);
+uint16_t 	CAN0_update						(void);
+
+uint16_t 	CAN1_init						(void);
+uint16_t 	CAN1_update						(void);
+int16_t 	CAN1_tx_Data_to_Inverter		(uint32_t timestamp,BMS_CAN1_INVERTER_TX* data);
+uint16_t 	CAN1_init_tx_structure			(BMS_CAN1_INVERTER_TX* tx_struct);
+int16_t 	CAN1_send_request_telegram(uint32_t requestId) ;
+uint16_t 	CAN1_wait_for_response(float* value); 
+uint32_t delay_CAN1_ms(uint32_t timestamp,uint32_t delay_ms);
+uint16_t CAN_Tx_MasterX_BMS(MASTER_CAN0_STRUCT_t* s, uint8_t SlaveNummer, uint8_t MasterAlive, uint8_t SetMode, uint32_t Balancer );
+
+uint16_t CAN_Tx_System300( uint16_t IDSEARCH );
+uint16_t CAN_Tx_MasterXA();
+uint32_t CAN0_check_serial_nr_rec_Can_init(MASTER_CAN0_STRUCT_t*s ,uint8_t SlaveNr);
+uint16_t CAN_Tx_System30A( uint8_t *pSERNr );
+
+
+
+
+#ifdef __cplusplus
+    }
+#endif
+
+    
+    
+#endif  /* ifndef*/
+
+    
+    
+// ***** End BMS_CANx_Tools.h **************************************************
+    

+ 462 - 0
BMS Master/Project_Headers/BMS_Defines.h

@@ -0,0 +1,462 @@
+//##############################################################################
+//
+// FILE:	BMS_Defines.h
+//
+// TITLE:	Global Defines
+//
+//
+//##############################################################################
+//
+//==============================================================================
+// Change History:
+//==============================================================================
+// Datum:   | Name | Version:| Change / Cause:                            | No
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 002
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 001
+//------------------------------------------------------------------------------
+// 05.07.13 |  VR  |   1.0   | New Build                                  | 000
+//==============================================================================
+//==============================================================================
+// Comment Change / Cause:
+//==============================================================================
+// Change: 003                                                           // 003
+//----------------------
+//                                                       
+//
+//==============================================================================
+// Change: 002                                                           // 002
+//----------------------
+//                                           
+//
+//==============================================================================
+// Change: 001                                                           // 001
+//----------------------
+// 
+//
+//==============================================================================
+
+#ifndef __BMS_DEFINES_H__
+#define __BMS_DEFINES_H__
+
+// **** general ******
+#define TRUE							1
+#define FALSE							0
+
+// ***** CAN0 FSM **********
+#define CAN0_NR_OF_TELEGRAMS 			8
+#define CAN0_NR_OF_SLAVES				6
+#define CAN0_TIMEOUT_MS					4
+#define CAN0_RASTER_MS					10
+#define CAN0_COMM_CYCLE_MS				250
+#define CAN0_MAX_NR_OF_SLAVES			16
+#define CAN0_MAX_NR_OF_TIMEOUTS			3
+#define CAN0_MAX_NR_OF_FAILED_COM		4
+
+#define CAN0_ALL_TELEGRAMS_REC			0xff
+
+#define BMS_ERROR_STACK_SIZE			32
+
+// ***** CAN1 *************
+#define CAN1_NR_OF_WAIT_CYCLES			6
+#define CAN1_TX_TIMEOUT					3
+
+#define BMS_SOC_NR_OF_CHARGE_AREAS		6
+#define BMS_SOC_NR_OF_DISCARGE_AREAS	6	
+#define BMS_SOC_NR_OF_REST_AREAS		6	
+#define BMS_SOC_NR_OF_RI_POINTS			2
+#define BMS_SOC_MIN_CURRENT_MA			100 // 100mA minimal Charge or discharge current, prevents discharge due to long phases of non doing	
+
+#define BMS_MAX_CURRENT_INCONSITENCY_MA	1000	// maximum difference between current measurend by UI and Inverter = 1000mA
+
+// ***** CAN= Modes *********
+
+#define BMS_NIGHT_MODE_SOC				0.45// Threshold for going into night mode
+#define BMS_WINTER_MODE_SOC				0.4// Threshold for going into winter mode
+
+#define BMS_WINTER_MODE_TIMEOUT			10000// Time before TURNOFF in Winter mode
+#define BMS_WINTER_MODE_RECOVER_PWR		20// minimum power from inverter to start recovering from Winter Mode
+
+// startup FRAM States
+
+#define BMS_STARTUP_FIRST_RUN					0x0001
+#define BMS_STARTUP_WINTER_MODE					0x0002
+#define BMS_STARTUP_ERROR_MODE_1				0x0004
+#define BMS_STARTUP_ERROR_MODE_2				0x0008
+#define BMS_STARTUP_ERROR_MODE_3				0x0010
+#define BMS_STARTUP_UPGRADE_SYSTEM				0x0020
+#define BMS_STARTUP_TEST_MODE					0x0040 // has to be removed in final version
+
+// FRAM ADDRESS
+#define BMS_STARTUP_MODE_ADDR					0x20
+#define BMS_STARTUP_SOC							0x22
+#define BMS_SLAVE_CAN_ID_VALID                  0x24    // uint16_t Slave_Can_Id_valid  =>    2 Byte  =>  till 0x26 occupied
+#define BMS_SLAVE_ANZ                           0x26    // uint16_t Slave_Anz           =>    2 Byte  =>  till 0x28 occupied
+#define BMS_SERNR                               0x28    // uint8_t  SerNr[17][8]        =>  136 Byte  =>  till 0xB0 occupied
+#define BMS_SLAVE_CAN_ID_END                    0xB0
+//#define BMS_ERROR_BUFFER1_OFFSET				0x200;
+//#define BMS_ERROR_BUFFER2_OFFSET				0x300;
+//#define BMS_ERROR_BUFFER3_OFFSET				0x400;
+
+
+//+ **** BMS TX Value IDs *****
+
+#define CAN1_TX_MAX_BATTERY_CHARGE_CURRENT_ID		0x1E5FCA70
+#define CAN1_TX_MAX_BATTERY_CHARGE_VOLTAGE_ID		0x6E491B50
+#define CAN1_TX_MAX_BATTERY_DISCHARGE_CURRENT_ID	0xDF0A735C
+#define CAN1_TX_MIN_BATTERY_DISCHARGE_VOLTAGE_ID	0xB0EBE75A
+#define CAN1_TX_BATTERY_CURRENT_ID					0x21961B58
+#define CAN1_TX_BATTERY_VOLTAGE_ID					0x65EED11B
+#define CAN1_TX_BATTERY_SOC_TARGET_ID				0x8B9FF008
+#define CAN1_TX_BATTERY_SOC_ID						0x959930BF
+#define CAN1_TX_BATTERY_CAPACITY					0xB57B59BD
+#define CAN1_TX_REQUESTED_VALUE_ID_ID				0x69AA598A
+#define CAN1_TX_BATTERY_TEMPERATURE					0x902AFAFB
+#define	CAN1_TX_BATTERY_SOH							0x381B8BF9
+#define CAN1_TX_BATTERY_STATUS						0x71765BD8
+#define CAN1_TX_CELL_STATUS							0xD143A391
+#define CAN1_TX_BATTERY_MODE						0x11111111
+#define CAN1_TX_BATTERY_STATUS_EXTRA				0x0DE3D20D
+
+// ***** BMS RX VALUE IDS
+
+#define CAN1_RX_ACTUAL_AC_POWER_ID					0xDB2D69AE
+#define CAN1_RX_PHASE_L1_VOLTAGE					0xCF053085
+#define CAN1_RX_PHASE_L2_VOLTAGE					0x54B4684E
+#define CAN1_RX_PHASE_L3_VOLTAGE					0x2545E22D
+#define CAN1_RX_DC_INPUT_A_VOLTAGE					0xB298395D
+#define CAN1_RX_DC_INPUT_B_VOLTAGE					0x5BB8075A
+#define CAN1_RX_ISLAND_MODE							0x3623D82A
+#define CAN1_RX_DC_INPUT_A_POWER					0xDB11855B
+#define CAN1_RX_DC_INPUT_B_POWER					0x0CB5D21B
+#define CAN1_RX_TOTAL_DC_PWR						0xE31F8B17
+#define CAN1_RX_BATTERY_CURRENT						0x0AFDD6CF
+#define CAN1_RX_BATTERY_VOLTAGE						0x97E3A6F2
+
+
+#define CAN1_NR_OF_REQUEST_TELEGRAMS				3
+
+// ***** SLAVE OPERATION MODE
+#define BMS_SLAVE_STAND_BY				0x1
+#define BMS_SLAVE_CAL_Test				0x2
+#define BMS_SLAVE_RUN					0x4
+#define BMS_SLAVE_ERROR					0x8
+#define BMS_SLAVE_RESET					0x10
+
+#define BMS_SLAVE_DATA_OK						0x0
+#define BMS_SALVE_DATA_ERROR_ALIVE_CNT			0x1
+#define BMS_SLAVE_DATA_ERROR_ALIVE_TIMEOUT		0x2
+#define BMS_SLAVE_DATA_ERROR_VOLTAGE_LIMIT		0x4
+#define BMS_SLAVE_DATA_ERROR_TEMP_LIMIT			0x8
+#define BMS_SLAVE_DATA_ERROR_HEAT_SINK_LIMIT	0x10
+#define BMS_SLAVE_DATA_ERROR_BOARD_ELECTRONIC	0x20
+#define BMS_SLAVE_DATA_ERROR_OVER_VOLTAGE		0x40
+#define BMS_SLAVE_DATA_ERROR_UNDER_VOLTAGE		0x80
+
+// ******** BMS Error Stack *********** //
+
+#define BMS_ERROR_STACK_DATA_OK							0
+#define BMS_ERROR_STACK_SLAVE_OVER_VOLTAGE				0x001
+#define BMS_ERROR_STACK_SLAVE_UNDER_VOLTAGE				0x002
+#define BMS_ERROR_STACK_SLAVE_OVER_TEMP_CHARGE			0x004
+#define BMS_ERROR_STACK_SLAVE_UNDER_TEMP_CHARGE			0x008
+#define BMS_ERROR_STACK_SLAVE_OVER_TEMP_DISCHARGE		0x010
+#define BMS_ERROR_STACK_SLAVE_UNDER_TEMP_DISCHARGE		0x020
+#define BMS_ERROR_STACK_SLAVE_TEMP_DIFFERENCE			0x040
+#define BMS_ERROR_STACK_SLAVE_TEMP_BOARD				0x080
+#define BMS_ERROR_STACK_SLAVE_SPI_ERROR					0x100
+#define BMS_ERROR_STACK_SLAVE_LTC_TIMING				0x200
+#define BMS_ERROR_STACK_SLAVE_LTC_SELF_TEST				0x400
+#define BMS_ERROR_STACK_SLAVE_CAN_ERROR					0x800
+
+
+#define BMS_ERROR_STACK_UI_OK							0
+#define BMS_ERROR_STACK_UI_CAN_ERROR					0x01
+#define BMS_ERROR_STACK_UI_OVER_CURRENT					0x02
+#define BMS_ERROR_STACK_UI_CURRENT_INCONSIST			0x04
+#define BMS_ERROR_STACK_UI_VOLTAGE_INCONSIST			0x08
+#define BMS_ERROR_STACK_UI_OVER_VOLTAGE					0x10
+
+#define BMS_ERROR_STACK_MASTER_OK						0
+#define BMS_ERROR_STACK_MASTER_VCC_12V					0x001
+#define BMS_ERROR_STACK_MASTER_VCC_3V3					0x002
+#define BMS_ERROR_STACK_MASTER_UMIN_1					0x004
+#define BMS_ERROR_STACK_MASTER_UMIN_2					0x008
+#define BMS_ERROR_STACK_MASTER_UMIN_3					0x010
+#define BMS_ERROR_STACK_MASTER_UMAX_1					0x020
+#define BMS_ERROR_STACK_MASTER_UMAX_2					0x040
+#define BMS_ERROR_STACK_MASTER_UMAX_SYSTEM				0x080
+#define BMS_ERROR_STACK_MASTER_VOLTAGE_INCONSIT			0x100
+#define BMS_ERROR_STACK_MASTER_EXTERN_CAN_ERROR			0x200
+#define BMS_ERROR_STACK_MASTER_FLASH					0x400
+#define BMS_ERROR_STACK_MASTER_I_MAX_DISCHARGE_OP		0x800
+#define BMS_ERROR_STACK_MASTER_I_MAX_CHARGE_OP			0x1000
+#define BMS_ERROR_STACK_MASTER_UMAX_3					0x2000
+
+
+// BMS ERROR HANDLING
+
+#define BMS_ERROR_ERROR_STACK_SIZE				32		// 32 Error Entries possible
+
+#define BMS_ERROR_BUFFER1_OFFSET				0x200;
+#define BMS_ERROR_BUFFER2_OFFSET				0x300;
+#define BMS_ERROR_BUFFER3_OFFSET				0x400;
+
+#define BMS_ERROR_CLASS_1						1
+#define BMS_ERROR_CLASS_2						2
+#define BMS_ERROR_CLASS_3						3
+#define BMS_ERROR_UI_ID							15
+#define BMS_ERROR_MASTER_ID						16	
+
+#define BMS_ERROR_FSM_ES2_TIMEOUT				300000 // 30s timeout at error state 2
+#define BMS_ERROR_FSM_ES3_TIMEOUT				300000 // 30s min timeout at error state 3
+
+#define BMS_ERROR_RESTORE_TIMEOUT				300000 // 5 Minutes for Inverter to clear Error
+
+#define BMS_SOC_LOW_MARK						0.1
+#define BMS_SOC_UMIN_1							3000
+#define BMS_SOC_UMIN_2							2900
+#define BMS_SOC_UMIN_3 							2800
+#define BMS_SOC_UMAX_1							3500
+#define BMS_SOC_UMAX_2							3550
+#define BMS_SOC_UMAX_3							3600
+#define BMS_ERROR_THRESHOLD_UMAX_SYSTEM			610000 // Umax System = 610V
+
+#define BMS_ERROR_THRESHOLD_T_DISCHARGE_MIN		-10
+#define BMS_ERROR_THRESHOLD_T_DISCHARGE_MAX		60
+
+#define BMS_ERROR_THRESHOLD_T_HEATSINK_MIN		-20
+#define BMS_ERROR_THRESHOLD_T_HEATSINK_MAX		80
+
+#define BMS_CAN_ID_INIT_RETURN_RUNNING			0
+#define BMS_CAN_ID_INIT_RETURN_COMPLETE			1
+#define BMS_CAN_ID_INIT_RETURN_ERROR			2
+
+
+
+
+
+// ********* ERROR STATES *****************
+
+
+//  ****** min max operatrion borders ******
+
+#define BMS_SLAVE_MAX_TEMP				45
+#define BMS_SLAVE_MIN_TEMP				5
+#define BMS_SLAVE_MAX_CELL_VOLTAGE		3600
+#define BMS_SLAVE_MIN_CELL_VOLTAGE		2800
+#define BMS_SLAVE_MAX_CURRENT			25000
+#define BMS_SLAVE_BATTERY_CHARGE_THERESOLD	-50
+#define BMS_SLAVE_MAX_BALANCE_VOLTAGE	3400
+#define BMS_SLAVE_MIN_BALANCE_SOC				0.8		// start balancing at 80% SoC
+#define BMS_SLAVE_MAX_BALANCE_HEATSINK_TEMP		45		// Balance to maximum board Temperature of 45 deg celcius 
+
+// ******* SOC ESTIMATOR CONSTANTS *********
+
+#define BMS_SOC_SMOOTH_APPROACH_THRESHOLD  0.01 // one percent
+#define BMS_SOC_DERATE_CHARGE_THRESHOLD_SOC 		0.9		// start disrating at 90% SoC
+#define BMS_SOC_DERATE_CHARGE_THRESHOLD_VOLTAGE		3450    // start dreating at 3450mV
+#define BMS_SOC_DERATE_DISCHARGE_THRESHOLD_SOC 		0.1	// start disrating at 10% SoC
+#define BMS_SOC_DERATE_DISCHARGE_THRESHOLD_VOLTAGE	3000   // start dreating at 3000mV
+#define BMS_SOC_CHARGE_MAX_CURRENT				BMS_SLAVE_MAX_CURRENT/1000
+#define BMS_SLAVE_MAX_CURRENT_A			BMS_SLAVE_MAX_CURRENT/1000.0  
+#define BMS_SOC_NR_OF_AREAS						5
+#define BMS_SOC_FLAG_SOC_100			0x0001
+#define BMS_SOC_FLAG_SOC_HIGH			0x0002  
+#define BMS_SOC_FLAG_SOC_0				0x0004
+#define BMS_SOC_FLAG_SOC_LOW			0x0008 
+
+#define BMS_SOC_CHARGE_SMOOTH_99			0x0001			// SoC at 99%
+#define BMS_SOC_CHARGE_SMOOTH_OVERSHOOT		0x0002			// Coulumb counting too fast
+#define BMS_SOC_CHARGE_SMOOTH_UNDERSHOOT	0x0004			// Coulumb counting too slow
+#define BMS_SOC_DISCHARGE_SMOOTH_01			0x0008			// SoC at 1%
+#define BMS_SOC_DISCHARGE_SMOOTH_OVERSHOOT	0x0010			// Coulumb counting too fast
+#define BMS_SOC_DISCHARGE_SMOOTH_UNDERSHOOT	0x0020			// Coulumb counting too slow
+
+// ***** FSM *******************************************************************
+#define EV__ERROR						0x0001
+#define	EV__STAND_BY					0x0004
+#define EV__INITIALISE					0x0008
+
+#define EV__DRIVE_START_1				0x0010
+#define EV__DRIVE_START_2				0x0020
+#define	EV__DRIVE_START_3				0x0040
+#define EV__DRIVE_START_4				0x0080
+#define EV__DRIVE						0x0100
+#define EV__DRIVE_DELAY					0x0200
+#define EV__SHUT_DOWN_DRIVE				0x0400
+
+#define EV__CHARGE						0x0800
+#define EV__CHARGE_CC					0x1000
+#define EV__CHARGE_CV					0x2000
+#define EV__CHARGE_DELAY				0x4000
+#define EV__SHUT_DOWN_CHARGE			0x8000
+
+
+
+// ***** Error FSM *************************************************************
+#define EEV__NO_ERROR    				0x0000
+#define	EEV__SHUT_DOWN_EMERGENCY		0x0001
+#define	EEV__ALL_OFF					0x0002
+#define EEV__SHUT_DOWN_CHARGE			0x0004
+#define EEV__CHARGE_OFF  				0x0008
+#define EEV__DEGRADATION  				0x0010
+#define EEV__DEGRADATION_ON				0x0020
+
+
+
+// ***** MODE REQUEST 6 FEEDBACK ***********************************************
+#define MF__STANDBY						0x0000
+#define MF__DRIVE						0x0001
+#define MF__CHARGE						0x0002
+#define MF__ERROR						0x0008
+#define MF__END_OF_CHARGE				0X0004
+
+#define MR__STANDBY						MF__STANDBY	
+#define MR__DRIVE						MF__DRIVE
+#define MR__CHARGE						MF__CHARGE	
+
+
+
+// ***** Slave *****************************************************************    
+#define	MAX_CELLS						120
+#define	MAX_SLAVE_CELLS					24
+#define	MAX_SLAVES						MAX_CELLS / MAX_SLAVE_CELLS
+#define MAX_SLAVES_INDEX				MAX_SLAVES -1
+#define	LOOP_TIME						9000
+   
+#define	CYCLE_TIME_BALANCER				20
+#define	CYCLE_TIME_VOLTAGE				30
+#define	CYCLE_TIME_STATUS				100
+#define	CYCLE_TIME_UI					100
+#define	CYCLE_TIME_TEMPERATURE			1000
+	
+#define	MAX_COUNT_VOLTAGE				LOOP_TIME / CYCLE_TIME_VOLTAGE
+#define	MAX_COUNT_STATUS				LOOP_TIME / CYCLE_TIME_STATUS
+#define	MAX_COUNT_UI					LOOP_TIME / CYCLE_TIME_UI
+#define	MAX_COUNT_TEMPERATURE			LOOP_TIME / CYCLE_TIME_TEMPERATURE
+#define MAX_COUNT_BALANCER	    		100
+#define MIN_COUNT_BALANCER              5           // dV = 12mV
+
+#define SLAVE_BALANCE_MIN_DELTA_U_MV	20			// dV_min = 10mV
+    
+
+#define UI_VOLTAGE_FIFO_SIZE			60		// one minute of Voltage values
+#define UI_CURRENT_FIFO_SIZE			60			// one minute of Current values
+#define SOC_SMOOTH_FIFO_SIZE			10
+
+#define INVERTER_VOLTAGE_FIFO_SIZE		200			// approximatlely 1 minute of Battery voltage measured by Inverter
+#define INVERTER_CURRENT_FIFO_SIZE		200			// approximately  1 minute of Battery current measured by Inverter
+// ***** Relais ****************************************************************
+#define RELAIS_ON						1
+#define RELAIS_OFF						0
+#define HS_RELAIS						5
+#define LS_RELAIS						0
+#define PRE_CHARGE_RELAIS				6
+#define PWR_SUPPLY						8	
+#define VBAT_RELAIS						7
+	
+ 
+
+// ***** Cell Errors ***********************************************************
+#define ERROR_MAX_CELL_VOLTAGE			0x0001
+#define ERROR_MIN_CELL_VOLTAGE		    0x0002
+#define ERROR_DELTA_CELL_VOLTAGE		0x0004
+#define ERROR_MAX_CELL_TEMPERATURE		0x0008
+#define ERROR_MIN_CELL_TEMPERATURE	    0x0010
+#define ERROR_DELTA_CELL_TEMPERATURE	0x0020
+#define	ERROR_MAX_LOAD_CELL_VOLTAGE		0x0040
+#define ERROR_PRE_CELL_LOW_VOLTAGE      0x0080
+#define ERROR_PRE_CELL_OVERHEAT         0x0100
+#define	MAX_COUNT_MSG_VOLTAGE			0x3FFFFFFF		// 5 Slaves x 6 MSG -> BitMask = 2^(30-1)
+#define	MAX_COUNT_MSG_TEMPERATURE		0x00007FFF		// 5 Slaves x 3 MSG -> BitMask = 2^(15-1)
+#define	MAX_COUNT_MSG_STATUS			0x0000001F		// 5 Slaves x 1 MSG -> BitMask = 2^( 5-1)
+
+
+// ***** Slave Errors **********************************************************
+#define ERROR_SLAVE_CAN					0x0001
+#define	ERROR_MAX_LTC_TEMP				0x0002
+#define ERROR_MIN_LTC_TEMP				0x0004    
+#define ERROR_MAX_HEATSINK_TEMPERATURE	0x0008    
+#define ERROR_SLAVE_PEC					0x0010
+#define	ERROR_SLAVE_SELFTEST			0x0020
+    
+
+
+// ***** UI Errors *************************************************************
+#define ERROR_MAX_UI_VOLTAGE			0x0001
+#define	ERROR_MIN_UI_VOLTAGE			0x0002
+#define	ERROR_MAX_UI_CURRENT			0x0004
+#define	ERROR_MIN_UI_CURRENT			0x0008
+#define ERROR_UI_PEC_NOK				0x0010
+#define ERROR_VOLTAGE_FRAME_LOST        0x0020
+#define ERROR_STATUS_FRAME_LOST         0x0040
+#define ERROR_TEMPERATURE_FRAME_LOST    0x0080
+#define ERROR_UI_FRAME_LOST             0x0100
+#define ERROR_ISO_GENERAL               0x0200
+#define ERROR_ISO_BAD                   0x0400
+#define ERROR_ISO_LOW                   0x0800
+
+
+// ***** Slave Boarders ********************************************************
+#define MAX_CELL_VOLTAGE				4201
+#define MAX_CELL_VOLTAGE_TEST			MAX_CELL_VOLTAGE + 50
+#define PRE_CELL_LOW_VOLTAGE            3100
+#define MIN_CELL_VOLTAGE				2999
+#define MIN_CELL_VOLTAGE_TEST			MIN_CELL_VOLTAGE - 50
+#define DELTA_CELL_VOLTAGE				500
+#define DELTA_CELL_VOLTAGE_TEST			DELTA_CELL_VOLTAGE + 50
+#define MAX_LOAD_CELL_VOLTAGE  			4150
+#define MIN_LOAD_CELL_CURRENT			400			// 4A
+#define MAX_SOC							144000000	// 40Ah (x3600sec x 10(=>mA))
+
+#define MAX_UI_VOLTAGE					5040
+#define MAX_UI_VOLTAGE_TEST  			MAX_UI_VOLTAGE + 10
+#define	MIN_UI_VOLTAGE					3600
+#define	MIN_UI_VOLTAGE_TEST             MIN_UI_VOLTAGE - 10
+#define MAX_UI_DRIVE_CURRENT		    12000
+#define	MIN_UI_LOAD_CURRENT    			-4000
+
+#define MAX_CELL_TEMPERATURE			60
+#define MAX_CELL_TEMPERATURE_TEST		MAX_CELL_TEMPERATURE + 1
+#define PRE_CELL_OVERHEAT               50
+#define MIN_CELL_TEMPERATURE		   -30 
+#define MIN_CELL_TEMPERATURE_TEST	    MIN_CELL_TEMPERATURE - 1
+#define DELTA_CELL_TEMPERATURE			5
+#define DELTA_CELL_TEMPERATURE_TEST		DELTA_CELL_TEMPERATURE + 1
+
+#define MAX_HEATSINK_TEMPERATURE		70
+#define MAX_HEATSINK_TEMPERATURE_TEST	MAX_HEATSINK_TEMPERATURE + 1
+#define MIN_ISO_R                       20          // kOhm
+#define MIN_ISO_R_TEST                  MIN_ISO_R - 1 // kOhm
+    	
+#define MAX_AVE							4
+#define MAX_AVE_SHIFT					2			// >> 2 = / 4
+
+#define MAX_PRECHARGE_VOLTAGE			50			// 5V
+#define MIN_SHUTDOWN_VOLTAGE			600			// 60V
+#define RELAIS_SETTLING_TIME			19			// 19ms
+#define START_RETRY_DELAY				60000		// 1min
+#define STOP_VOLTAGE_DECLINE_DELAY		50			// 50ms
+#define DELAY_START                     10000         // 1000ms
+
+
+
+// ***** CAN0 Telegram *********************************************************
+#define	CAN0_VOLTAGE_TELEGRAM_SIZE		6
+#define	CAN0_TEMPERATURE_TELEGRAM_SIZE	3
+#define	CAN0_STATUS_TELEGRAM_SIZE		1
+#define	CAN0_BALANCING_TELEGRAM_SIZE	1
+#define	CAN0_UI_TELEGRAM_SIZE			1
+
+
+
+// ***** CAN1 BRUSA ************************************************************
+#define	NLG5_MAINS_CURRENT				500			// 50A
+#define	NLG5_OUTPUT_VOLTAGE				5000		// 500V
+#define	NLG5_OUTPUT_CURRENT				400			// 40A
+
+
+
+#endif  /* ifndef*/

+ 237 - 0
BMS Master/Project_Headers/BMS_Master.h

@@ -0,0 +1,237 @@
+//##############################################################################
+//
+// FILE:	BMS_Master.h
+//
+// TITLE:	Central Header & Main Header
+//
+//
+//##############################################################################
+//
+//==============================================================================
+// Change History:
+//==============================================================================
+// Datum:   | Name | Version:| Change / Cause:                            | No
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 002
+//------------------------------------------------------------------------------
+// 07.02.14 |  VR  |   1.1   | upgrade 2 CoreWarrior 10.5 id: 130916      | 001
+//------------------------------------------------------------------------------
+// 20.04.12 |  TM  |   1.0   | New Build                                  | 000
+//==============================================================================
+//==============================================================================
+// Comment Change / Cause:
+//==============================================================================
+// Change: 003                                                           // 003
+//----------------------
+//                                                       
+//
+//==============================================================================
+// Change: 002                                                           // 002
+//----------------------
+//                                           
+//
+//==============================================================================
+// Change: 001                                                           // 001
+//----------------------
+// 
+//
+//==============================================================================
+
+#ifndef __BMS_MASTER_H__
+#define __BMS_MASTER_H__
+
+
+
+// ***** Includes **************************************************************
+#include "MPC5646C.h"
+#include "Typedefs.h"
+#include "IntcInterrupts.h"
+#include "Device.h"
+#include "FlexCAN.h"
+#include "BMS_Typedefs.h"
+#include "BMS_CANx_Tools.h"
+#include "BMS_CAN0_gen_test_data.h"
+#include "DSPI.h"
+#include "FRAM.h"
+#include "BoardPeripherals.h"
+#include "MultitaskOS.h"
+#include "RelaisLEDs.h"
+#include "BMS_Defines.h"
+
+#include "UartToUsb.h"
+#include "LIN_Uart.h"
+#include "DebugUndTest.h"
+#include "TempSensorSpi.h"
+#include "utils.h"
+
+#include "BMS_SoC_estimator.h"
+
+
+
+// ***** global Variables **********************************************************
+extern 	BSD_t	 	  gBSD;
+extern 	BSE_t		  gBSE;
+extern  uint8_t	      gMaxDischargeCurrent;
+extern 	FramStatus_t  Fram_S;
+extern	uint32_t	  gEvent;
+extern  uint32_t	  gErrorEvent;
+extern  uint8_t       gCANErrorInsert;
+extern  MASTER_CAN0_STRUCT_t gDUMMY_data_struct;
+extern CAN_MAILBOX CAN_Tx0_RCT_INVERTER;
+extern CAN_MAILBOX CAN_Tx1_RCT_INVERTER; 
+extern CAN_MAILBOX CAN_Rx_RCT_INVERTER;
+
+
+
+// ***** Local Prototypes ******************************************************
+
+	
+	uint16_t init_master_CAN0_fsm(MASTER_CAN0_STRUCT_t* s,BMS_SLAVE_CONFIGURATION_t* cellConfig,BMS_UI_CONFIGURATION_t* uiConfig);
+	uint16_t Master_CAN0_fsm(MASTER_CAN0_STRUCT_t* s,uint32_t time);
+	uint16_t init_master_operation_fsm(BMS_MASTER_OPERATION_t* opFsm);
+	uint16_t Master_operation_fsm(MASTER_CAN0_STRUCT_t* canFsm,uint32_t time,BMS_MASTER_OPERATION_t* opFsm);
+	void set_slave_cell_connection_state(MASTER_CAN0_STRUCT_t* s,uint8_t slaveNr,CELL_STATE_t* cell_state);
+	void set_slave_temp_connection_state(MASTER_CAN0_STRUCT_t* s,uint8_t slaveNr,TEMP_SENSOR_STATE_t* temp_state);
+	uint8_t check_slave_data(MASTER_CAN0_STRUCT_t* s,
+			BMS_CAN0_SLAVE_t* Slave,
+			BMS_CAN0_SLAVE_t* tempSlave,
+			int8_t overTemp_charge,
+			int8_t overTemp_discharge,
+			int8_t underTemp_charge,
+			int8_t underTemp_discharge,
+			uint16_t overVoltage,uint16_t underVoltage) ;
+	void initCellConfig(BMS_SLAVE_CONFIGURATION_t* cellConfig);
+	void initUiConfig(BMS_UI_CONFIGURATION_t* uiConfig) ;
+	
+	int16_t CAN1_request_float_value(uint32_t timestamp,float* value,uint32_t requestId) ;
+	uint16_t CAN2_init( void );
+	uint16_t CAN2_update( void );
+	uint32_t set_balancer_off(MASTER_CAN0_STRUCT_t* s) ;
+	uint32_t BMS_set_Error_check_if_stable_discharge(MASTER_CAN0_STRUCT_t* s); 
+	
+	
+	uint8_t check_UI_data(BMS_CAN0_SLAVE_t* Slave, BMS_CAN0_SLAVE_t* tempSlave,BMS_CAN0_UI_t* ui,BMS_CAN0_UI_t* tempUI);
+	uint32_t calc_block_voltage(BMS_CAN0_SLAVE_t* Slave);
+	uint32_t set_block_min_max_temp(BMS_CAN0_SLAVE_t* Slave);
+	uint32_t calc_system_voltage(MASTER_CAN0_STRUCT_t* s);
+	void calc_system_SoC(MASTER_CAN0_STRUCT_t* s);
+	void refresh_inverter_tx_data(MASTER_CAN0_STRUCT_t* s);
+	uint8_t check_if_all_values_are_initialized(MASTER_CAN0_STRUCT_t* s);
+	void shuffle_lsb_msb_can1(uint8_t* value);
+	uint16_t Master_CAN1_fsm(MASTER_CAN0_STRUCT_t* s,MASTER_CAN1_STRUCT_t* can1Fsm,uint32_t time);
+	uint16_t Master_CAN1_fsm_init(MASTER_CAN1_STRUCT_t* can1Fsm);
+	uint32_t Master_CAN1_Inverter_fsm(MASTER_CAN0_STRUCT_t* s,MASTER_CAN1_INVERTER_STRUCT_t* fsmStruct) ;
+	uint32_t set_balancer(MASTER_CAN0_STRUCT_t* s) ;
+
+	
+	uint32_t Master_Balancer_fsm(MASTER_CAN0_STRUCT_t* s);
+	uint32_t calc_min_max_voltage_slave(BMS_CAN0_SLAVE_t* Slave) ;
+	uint32_t calc_min_max_voltage_system(MASTER_CAN0_STRUCT_t* s) ;
+	uint32_t balance_cell(BMS_CAN0_SLAVE_t* Slave,uint8_t cell_nr);
+	uint32_t set_system_min_max_temp(MASTER_CAN0_STRUCT_t* s);
+	uint32_t set_system_min_max_heatsink_temp(MASTER_CAN0_STRUCT_t* s);
+	
+	uint16_t CAN0_clear_all_interrupt_flags();
+	uint32_t generateCellInfoPkg(MASTER_CAN0_STRUCT_t* s, uint8_t cellIndex,BMS_CAN1_INVERTER_CELL_DATA_t* txPkg); 
+	
+
+	uint8_t get_nr_of_connected_slaves(MASTER_CAN0_STRUCT_t* s);
+
+
+	uint32_t ErrorStackPushSlaveError(MASTER_CAN0_STRUCT_t* s,uint8_t slaveNr,uint32_t ErrorCode,uint8_t CellNr,uint8_t ErrorClass); 
+	uint32_t ErrorStackPushUiError(MASTER_CAN0_STRUCT_t* s,uint32_t ErrorCode,uint8_t ErrorClass);
+	uint32_t ErrorStackPushMasterError(MASTER_CAN0_STRUCT_t* s,uint32_t ErrorCode,uint8_t ErrorClass);
+	uint32_t ErrorStackGenerateStatusPkg(uint8_t* targetBuffer,uint8_t* ErrorCode);
+	uint32_t ErrorStackCheckBufferForError(MASTER_CAN0_STRUCT_t* s,uint32_t ErrorWord,uint8_t ErrorClass) ;
+	uint32_t ErrorStackCheckForActiveErrors(MASTER_CAN0_STRUCT_t* s,uint8_t ErrorClass); 
+	uint32_t ErrorStackClearBuffer(MASTER_CAN0_STRUCT_t* s);
+	uint32_t ErrorStackCheckForActiveErrors(MASTER_CAN0_STRUCT_t* s,uint8_t ErrorClass);
+	
+	uint32_t BMS_Clear_Error_Buffer(MASTER_CAN0_STRUCT_t* s,uint8_t ErrorClass);
+	
+	
+	uint32_t BMS_Master_ES1_fsm(MASTER_CAN0_STRUCT_t* s);
+	uint32_t BMS_Master_ES2_fsm(MASTER_CAN0_STRUCT_t* s);
+	uint32_t BMS_Master_ES3_fsm(MASTER_CAN0_STRUCT_t* s);
+	
+	
+	uint32_t BMS_Set_Error_check_Voltage_level_min(MASTER_CAN0_STRUCT_t* s);
+	
+	
+	uint16_t Master_CAN0_ERROR_fsm(MASTER_CAN0_STRUCT_t* s,uint32_t time);
+
+	
+	int32_t checkIfInverterHasPower(MASTER_CAN0_STRUCT_t* s);
+	uint32_t OPModeFSM(MASTER_CAN0_STRUCT_t* s);
+	uint32_t RunningModeFSM(MASTER_CAN0_STRUCT_t* s);
+	
+	uint32_t write_fram_byte(uint8_t byte,uint32_t timeout,const vuint16_t Addr);
+	uint32_t write_fram_word(uint16_t word,uint32_t timeout,const vuint16_t Addr);
+	uint32_t write_fram_float(float float_value,uint32_t timeout,const vuint16_t Addr); 
+	uint32_t read_fram_byte(uint8_t* word,uint32_t timeout,const vuint16_t Addr);
+	uint32_t read_fram_word(uint16_t* word,uint32_t timeout,const vuint16_t Addr);
+	uint32_t read_fram_float(float* word,uint32_t timeout,const vuint16_t Addr);
+	uint32_t write_fram_set_SoC(float SoC) ;
+	uint32_t read_fram_get_startup_state(MASTER_CAN0_STRUCT_t* s);
+	float 	read_fram_get_SoC() ;
+	uint32_t write_fram_set_startup_state(MASTER_CAN0_STRUCT_t* s) ;
+	uint32_t write_fram_clear_startup_state();
+	uint32_t write_fram_uint32(uint32_t word,uint32_t timeout,const vuint16_t Addr);
+	uint32_t read_fram_uint32(uint32_t* word,uint32_t timeout,const vuint16_t Addr);
+	uint32_t write_fram_write_error(uint32_t Error,uint8_t ErrorLevel,uint8_t ErrorNr);
+	uint32_t read_fram_read_error_buffer(MASTER_CAN0_STRUCT_t* s) ;
+	uint32_t write_fram_clear_error_buffer(MASTER_CAN0_STRUCT_t* s) ;
+	uint32_t readMasterTempSensorFsm(MASTER_CAN0_STRUCT_t* s) ;
+
+	
+	uint32_t startup_BMS(MASTER_CAN0_STRUCT_t* s) ;
+	
+	
+	int32_t bms_SoC_init_estimator_FRAM(MASTER_SOC_ESTIMATOR_t* cell_SoC, uint16_t voltage);
+	
+	uint32_t BMS_Set_Error_check_System_voltage_level_max(MASTER_CAN0_STRUCT_t* s);
+	uint32_t BMS_Set_Error_check_Voltage_level_max(MASTER_CAN0_STRUCT_t* s) ;
+	uint32_t BMS_set_Error_check_if_stable_charge(MASTER_CAN0_STRUCT_t* s) ;
+	
+	uint32_t BMS_Set_Error_Check_derating(MASTER_CAN0_STRUCT_t* s);
+	uint32_t BMS_Clear_Error_State_Slave(MASTER_CAN0_STRUCT_t* s,BMS_ERROR_STATE_t* error_state);
+	uint32_t BMS_Clear_Error_State_check_restore_timeout(MASTER_CAN0_STRUCT_t* s) ;
+	uint32_t BMS_Clear_Error_State_Master(MASTER_CAN0_STRUCT_t* s,BMS_ERROR_STATE_t* error_state,uint8_t Error_nr,uint8_t Error_class) ;
+	uint32_t BMS_Clear_Error_init_recovery_struct(MASTER_CAN0_STRUCT_t* s);
+	uint32_t BMS_RCT_init_fsm(MASTER_CAN0_STRUCT_t* s);
+	
+	uint32_t BMS_RCT_Inverter_fsm (MASTER_CAN0_STRUCT_t* s);
+	uint32_t ErrorStackCheckifUmin1ErrorRecoveryPending(MASTER_CAN0_STRUCT_t* s);
+	uint32_t ErrorStackCheckifUmin2ErrorRecoveryPending(MASTER_CAN0_STRUCT_t* s);
+	uint32_t ErrorStackCheckifAnyErrorRecoveryPending(MASTER_CAN0_STRUCT_t* s);
+	
+	uint32_t initUIFifo(MASTER_CAN0_STRUCT_t* s);
+	uint32_t popUIFiFo(MASTER_CAN0_STRUCT_t* s) ;
+	uint32_t BMS_Set_Error_CAN1_Timeout(MASTER_CAN0_STRUCT_t* s) ;
+	
+	uint32_t BMS_Can_ID_init_recofigure_CAN_IDs(MASTER_CAN0_STRUCT_t* s) ;
+	uint32_t BMS_Can_ID_init_fsm (MASTER_CAN0_STRUCT_t* s);
+	uint32_t BMS_Can_ID_init_init_startupConfig (MASTER_CAN0_STRUCT_t* s);
+	
+	uint32_t Master_CAN1_select_comm_mode (MASTER_CAN0_STRUCT_t* s,MASTER_CAN1_INVERTER_STRUCT_t* fsmStruct) ;
+	uint32_t Master_CAN1_Fast_request_fsm (MASTER_CAN0_STRUCT_t* s,MASTER_CAN1_INVERTER_STRUCT_t* fsmStruct) ;
+	uint32_t pushInverterCurrentFIFO(MASTER_CAN0_STRUCT_t* s);
+	uint32_t BMS_Set_Error_Check_current_consitency(MASTER_CAN0_STRUCT_t* s);
+	uint32_t BMS_Set_Error_Check_voltage_inconsitency(MASTER_CAN0_STRUCT_t* s);
+	
+	uint32_t initSoCFifo(MASTER_CAN0_STRUCT_t* s); 
+	uint32_t pushSoCFiFo(MASTER_SOC_ESTIMATOR_t* est);
+
+	
+
+// ***** Global Prototypes *****************************************************
+	void 	  SwitchRelais  ( uint8_t, uint8_t );
+
+	
+
+#endif  /* ifndef*/
+
+	
+	
+// ***** End BMS_Master.h ******************************************************
+	

+ 30 - 0
BMS Master/Project_Headers/BMS_SoC_estimator.h

@@ -0,0 +1,30 @@
+/*
+ * BMS_SoC_estimator.h
+ *
+ *  Created on: Jul 18, 2016
+ *      Author: le8041
+ */
+
+#ifndef BMS_SOC_ESTIMATOR_H_
+#define BMS_SOC_ESTIMATOR_H_
+
+
+
+/**
+* @function bms_SoC_init_estimator_constants 
+* @brief  bms_SoC_init_estimator_constants
+* @param cell_SoC standart uebergabeparameter
+*/
+float calc_start_SoC(uint16_t voltage);
+int32_t bms_SoC_init_estimator(MASTER_SOC_ESTIMATOR_t* cell_SoC, uint16_t voltage) ;
+uint32_t bms_SoC_running_fsm(MASTER_SOC_ESTIMATOR_t* est, int16_t I_batt, uint16_t U_batt_max,uint16_t U_batt_min, int8_t temp_min, int8_t temp_max);
+float bms_SoC_get_norm(float value);
+float bms_calc_charge_derating(float SoC);
+float bms_calc_discharge_derating(float SoC);
+uint32_t bms_set_derating(MASTER_SOC_ESTIMATOR_t* est, int8_t minTemp, int8_t maxTemp);
+float bms_calc_charge_temp_derating(int8_t Temp) ;
+float bms_calc_discharge_temp_derating(int8_t Temp);
+float linear_interpolate(int8_t x1,int8_t x2,int8_t x,float y1,float y2);
+
+
+#endif /* BMS_SOC_ESTIMATOR_H_ */

+ 1070 - 0
BMS Master/Project_Headers/BMS_Typedefs.h

@@ -0,0 +1,1070 @@
+//##############################################################################
+//
+// FILE:	BMS_Typedefs.h
+//
+// TITLE:	Global Typedefs
+//
+//
+//##############################################################################
+//
+//==============================================================================
+// Change History:
+//==============================================================================
+// Datum:   | Name | Version:| Change / Cause:                            | No
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 002
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 001
+//------------------------------------------------------------------------------
+// 05.07.13 |  VR  |   1.0   | New Build                                  | 000
+//==============================================================================
+//==============================================================================
+// Comment Change / Cause:
+//==============================================================================
+// Change: 003                                                           // 003
+//----------------------
+//                                                       
+//
+//==============================================================================
+// Change: 002                                                           // 002
+//----------------------
+//                                           
+//
+//==============================================================================
+// Change: 001                                                           // 001
+//----------------------
+// 
+//
+//==============================================================================
+
+#ifndef __BMS_TYPEDEFS_H__
+#define __BMS_TYPEDEFS_H__
+
+
+#include	"BMS_Defines.h"
+
+
+// ***** Slave_Status_Flags ****************************************************
+typedef union {
+	uint16_t R;
+    struct { 	//Big Endian
+    //High Byte
+    uint16_t rsvd_h:8;
+    
+    //Low Byte
+    uint16_t LTC_PEC_NOK:1;
+    uint16_t LTC_Timeout:1;
+    uint16_t LTC2_THSD:1;
+    uint16_t LTC1_THSD:1;
+    uint16_t LTC2_Temp_above80:1;
+    uint16_t LTC1_Temp_above80:1;
+    uint16_t LTC2_Temp_belowM40:1;
+    uint16_t LTC1_Temp_belowM40:1;
+    } B;
+} Slave_Status_Flags_t;
+  
+
+
+// ***** Slave_Self_Test_Flags *************************************************   
+typedef union {
+	uint16_t R;
+    struct { 	//Big Endian
+    //High Byte
+    uint16_t rsvd:1;
+    uint16_t LTC2_Mux_NOK:1;
+    uint16_t LTC2_RefH_NOK:1;
+    uint16_t LTC2_RefL_NOK:1;
+    uint16_t LTC2_TST2_NOK:1;	
+    uint16_t LTC2_TST1_NOK:1;
+    uint16_t LTC2_VST2_NOK:1;
+    uint16_t LTC2_VST1_NOK:1;
+    
+    //Low Byte
+    uint16_t LTC_PEC_NOK:1;
+    uint16_t LTC1_Mux_NOK:1;
+    uint16_t LTC1_RefH_NOK:1;
+    uint16_t LTC1_RefL_NOK:1;
+    uint16_t LTC1_TST2_NOK:1;	
+    uint16_t LTC1_TST1_NOK:1;
+    uint16_t LTC1_VST2_NOK:1;
+    uint16_t LTC1_VST1_NOK:1;
+    } B;
+} Slave_Self_Test_Flags_t;
+    
+    
+ 
+// ***** Slave_Control *********************************************************
+typedef struct {
+    uint16_t Balancing_dV[MAX_CELLS];
+    uint32_t Balancing_OnOff_Flags[MAX_SLAVES];
+    union {
+    	uint8_t R[MAX_SLAVES];
+    	struct {
+    		uint8_t rsvd:5;
+    		uint8_t Fan2_RightLeft:1;
+    		uint8_t Fan2_OnOff:1;
+    		uint8_t Fan1_OnOff:1;
+    	} B[MAX_SLAVES];
+    } FanCtrl;
+    uint8_t Relais_OnOff[MAX_SLAVES];
+} Slave_Control_t;
+    
+    
+
+// ****** Slave_Status *********************************************************
+typedef struct {
+    Slave_Status_Flags_t	StatusFlags;
+    Slave_Self_Test_Flags_t	SelfTest_Flags;
+    uint8_t					LTC_PEC_FailCount;
+    int8_t					HeatSink_Temp;
+} Slave_Status_t;
+    
+    
+
+// ***** BSD (Battery Management System Slave Data ) ***************************
+typedef struct {
+	uint16_t 			BlockVoltage		[MAX_COUNT_UI];
+	int16_t	 			BlockCurrent		[MAX_COUNT_UI];
+	int32_t				BlockCurrentSum;
+	uint8_t				BlockCounter		[MAX_COUNT_UI];
+	uint16_t 			CellVoltage			[MAX_COUNT_VOLTAGE]     [MAX_CELLS];
+	int8_t 				CellTemperature		[MAX_COUNT_TEMPERATURE] [MAX_CELLS];
+	Slave_Status_t 		Slave_Status		[MAX_COUNT_STATUS]      [MAX_SLAVES];
+	Slave_Control_t		Balancer;
+	uint16_t			r_UI;
+	uint16_t			w_UI;
+	uint16_t			r_Voltage;
+	uint16_t			w_Voltage;
+	uint16_t			r_Temperature;
+	uint16_t			w_Temperature;
+	uint16_t			r_Status;
+	uint16_t			w_Status;
+	uint16_t			r_Balancer;
+	uint16_t			w_Balancer;
+} BSD_t;
+
+
+
+// ***** BSE ( Battery Management System Slave Errors ) ************************
+typedef struct {
+	int16_t		ErrorCell	[MAX_CELLS];
+	int16_t		ErrorSlave	[MAX_SLAVES];
+	int16_t		ErrorBMS;
+	uint32_t	CountVoltage;
+	uint32_t	CountTemperature;
+	uint32_t	CountStatus;
+} BSE_t;
+
+
+
+// ***** Main Contactor Feedback ***********************************************
+typedef union {
+	uint8_t R;
+    struct {
+    uint8_t 	free                  :6;
+    uint8_t		b_MainContactorError  :1;
+    uint8_t 	b_MainContactorSwitch :1;
+    
+    
+    } B;
+} b_MC_Fb_BMU_t;
+
+
+
+// ***** BMU_DICO ( Battery Management Unit to DICO ) **************************
+typedef struct {
+	uint8_t			voltageBattMax;				// Maximum Battery Voltage
+	uint8_t			voltageBattMin;				// Minimum Battery Voltage
+	uint8_t			currentBatMaxCharge;		// Maximum Charge Current
+	uint8_t			currentBatMaxDischarge;		// Maximum Discharge Current
+	uint8_t			batterySOC;					// State Of Charge
+	uint8_t			voltageBattFb;				// Total Battery Voltage
+	uint8_t			currentBattFb;				// Total Battery Current
+	b_MC_Fb_BMU_t	b_MC_Fb_BMU;				// Main Contactor Feedback
+} BMU_DICO_t;
+
+
+
+// ***** StatusByte_1_DCU ******************************************************
+typedef union {
+	uint8_t R;
+    struct {
+    uint8_t		b_motDir		:1;		// Direction Vehicle
+    uint8_t		b_reverse       :1;		// Reverse Active
+    uint8_t		b_neutral       :1;		// Neutral Active
+    uint8_t		b_drive	        :1;		// Drive Active
+    uint8_t		b_PC_Activ   	:1;		// Precharging Active
+    uint8_t 	b_keyStart_DICO1:1;		// Key Start Acknowledge
+    uint8_t		b_ini 			:1;		// Initialisation Active
+    uint8_t 	b_pulsEnGlobalFb:1;		// Drive System Active
+    } B;
+} b_StatusByte_1_DCU_t;
+
+
+
+// ***** StatusByte_2_DCU ******************************************************
+typedef union {
+	uint8_t R;
+    struct {
+    uint8_t		b_MC_Rq      	:1;		// Main Contactor Request 
+    uint8_t		b_PC_Rq 		:1;		// Precharge Contactor Request
+    uint8_t		b_fan_Rq        :1;		// Fan Control Request
+    uint8_t		b_pumpOn_Rq     :1;		// Pump On Request
+    uint8_t		b_errorGen1SAE	:1;		// Charging Error
+    uint8_t 	b_perfRedSys 	:1;		// Performing Reduction System
+    uint8_t		b_warningSys    :1;		// Red Lamp Flashing System
+    uint8_t 	b_errorSys      :1;		// Red Lamp System
+    } B;
+} b_StatusByte_2_DCU_t;
+
+
+
+// ***** ErrorBuffer ***********************************************************
+typedef union {
+	uint8_t R;
+    struct {
+    uint8_t 	b_errBufferIndication 	:1;	// Error Buffer Indication
+    uint8_t		Reserved     			:3;
+    uint8_t 	errCountMark 			:4;	// Online Diagnoses Error Buffer Number
+    } B;
+} b_ErrorBuffer_t;
+
+
+
+// ***** DICO1_EVCU ( DICO1 to Electronic Vehicle Control Unit ) ***************
+typedef struct {
+	b_StatusByte_1_DCU_t	b_StatusByte_1_DCU;
+	b_StatusByte_2_DCU_t	b_StatusByte_2_DCU;
+	uint16_t				rpmSys;					// Drive Motor Speed;
+	uint8_t					tqRefSys;				// Drive Motor Torque Reference;
+	uint8_t					tqSys;					// Actual Drive Motor Torque Feedback;
+	uint8_t					powerBR_fb;				// Brake Resistor Power Feedback;
+	b_ErrorBuffer_t			b_ErrorBufferIndication;
+} DICO1_EVCU_t;
+
+
+
+// ***** DiagnosticInverter1 ***************************************************
+typedef union {
+	uint8_t R;
+    struct {
+    uint8_t 	diagnMotor1	:2;		// Diagnostic / Inverter Motor 1
+    uint8_t 	diagnMotor2	:2;		// Diagnostic / Inverter Motor 2
+    uint8_t 	diagnMotor3	:2;		// Diagnostic / Inverter Motor 3
+    uint8_t 	diagnMotor4	:2;		// Diagnostic / Inverter Motor 4
+    } B;
+} b_DiagnosticInverter1_t;
+
+
+
+// ***** DiagnosticInverter2 ***************************************************
+typedef union {
+	uint8_t R;
+    struct {
+    uint8_t		diagnGenerator1		:2;	// Diagnostic Inverter / Generator 1
+    uint8_t		diagnGenerator2		:2;	// Diagnostic Inverter / Generator 2
+    uint8_t		emergency_MC_Off	:2;	// Emergency Main Contactor Off
+    uint8_t 	b_emergencyEngineOff:2;	// Emergency Engine Off
+    } B;
+} b_DiagnosticInverter2_t;
+
+
+
+// ***** DiagnosticInverter3 ***************************************************
+typedef union {
+	uint8_t R;
+    struct {
+    uint8_t 	diagnAux1 	:2;	// Diagnostic Inverter / AUX-Mot 1
+    uint8_t 	diagnAux2 	:2;	// Diagnostic Inverter / AUX-Mot 2
+    uint8_t 	diagnDCDC1 	:2;	// Diagnostic DC/DC 1
+    uint8_t 	diagnDCDC2 	:2;	// Diagnostic DC/DC 2
+    } B;
+} b_DiagnosticInverter3_t;
+
+
+
+// ***** Current_HEV_Mode ******************************************************
+typedef union {
+	uint8_t R;
+    struct {
+    uint8_t		operationModeFb		:4;		// Current HEV Mode
+    uint8_t		diagnDICO			:2;		// Diagnostic DICO Master
+    uint8_t 	b_startCE_extHyMode	:2;		// Engine start with 24 V starter
+    } B;
+} b_Current_HEV_Mode_t;
+
+
+
+// ***** DICO2_EVCU ( DICO2 to Electronic Vehicle Control Unit ) ***************
+typedef struct {
+	b_DiagnosticInverter1_t	b_DiagnosticInverter1;
+	b_DiagnosticInverter2_t	b_DiagnosticInverter2;
+	b_DiagnosticInverter3_t	b_DiagnosticInverter3;
+	b_Current_HEV_Mode_t	b_Current_HEV_Mode;
+	uint16_t				powerGenerator1Fb;		// Power Generator 1
+	uint16_t				rpmGenerator1Fb;		// Speed Generator 1
+} DICO2_EVCU_t;
+
+
+
+// ***** ModeFeedback **********************************************************
+typedef union {
+	uint16_t R;
+    struct {
+    uint16_t	Reserved		:13;
+    uint16_t	BMS_EoC			:1;
+    uint16_t 	Mode_Feedback	:2;
+    } B;
+} ModeFeedback_t;
+
+
+
+// ***** BMU1_EVCU ( Battery Management Unit to Electronic Vehicle Control Unit ) *
+typedef struct {
+	ModeFeedback_t		ModeFeedBack;
+} BMU1_EVCU_t;
+
+
+
+// ***** ModeRequest ***********************************************************
+typedef union {
+	uint16_t R;
+    struct {
+    uint16_t	Reserved		:14;
+    uint16_t 	Mode_Request	:2;
+    } B;
+} ModeRequest_t;
+
+
+
+// ***** EVCU1_BMU ( Electronic Vehicle Control Unit to Battery Management Unit  ) *
+typedef struct {
+	ModeRequest_t		ModeRequest;
+} EVCU1_BMU_t;
+
+
+
+// ***** NLG5 Control Bitmap ***************************************************
+typedef union {
+	uint8_t R;
+    struct {
+    uint8_t 	Reserved	:5;
+    uint8_t		NLG5_C_CP_V	:1;			// Control Pilot Ventilation Request
+    uint8_t		NLG5_C_C_EL	:1;			// Clear Error Latch
+    uint8_t		NLG5_C_C_EN	:1;			// CAN enable
+    } B;
+} NLG5_CTLB_t;
+
+
+
+// ***** NLG5 Control BMU to BRUSA *********************************************
+typedef struct {
+	NLG5_CTLB_t		NLG5_CTLB;			// NLG5 Control Bitmap
+	uint16_t		NLG5_MC_MAX;		// Mains Current Maximum
+	uint16_t		NLG5_OV_COM;		// Output Voltage Command
+	uint16_t		NLG5_OC_COM;		// Output Current Command
+} NLG5_CTL_t;
+
+
+
+// ***** NLG5 Status Bitmap 1 **************************************************
+typedef union {
+	uint8_t R;
+    struct {
+    uint8_t 	NLG5_S_CP_DT	:1;		// Control pilot detected
+    uint8_t 	NLG5_S_UM_II	:1;		// USA mains LEVEL II , 240V/32A/60Hz
+    uint8_t 	NLG5_S_UM_I		:1;		// USA mains LEVEL I, 120V/12A/60Hz
+    uint8_t 	NLG5_S_EUM		:1;		// Europe mains (230V/50Hz)
+    uint8_t 	NLG5_S_FAN		:1;		// NLG5 Fan active
+    uint8_t 	NLG5_S_WAR		:1;		// NLG5 general limit warning
+    uint8_t 	NLG5_S_ERR		:1;		// NLG5 general error latch
+    uint8_t 	NLG5_S_HE		:1;		// NLG5 power enable
+    } B;
+} NLG5_STB1_t;
+
+
+
+// ***** NLG5 Status Bitmap 2 **************************************************
+typedef union {
+	uint8_t R;
+    struct {
+    uint8_t 	NLG5_S_L_PMAX	:1;		// Limitation by NLG5 maximum power
+    uint8_t 	NLG5_S_L_CP		:1;		// Limitation by control pilot
+    uint8_t 	NLG5_S_L_PI		:1;		// Limitation by power indicator
+    uint8_t 	NLG5_S_L_MC		:1;		// Limitation by mains current
+    uint8_t 	NLG5_S_L_OC		:1;		// Limitation by output current
+    uint8_t 	NLG5_S_L_OV		:1;		// Limitation by output voltage
+    uint8_t 	NNLG5_S_BPD_II	:1;		// Limitation by output voltage
+    uint8_t 	NLG5_S_BPD_I	:1;		// Bypass detection I
+    } B;
+} NLG5_STB2_t;
+
+
+
+// ***** NLG5 Status Bitmap 3 **************************************************
+typedef union {
+	uint8_t R;
+    struct {
+    uint8_t 	NLG5_S_L_T_BATT	:1;		// Limitation by battery temperature
+    uint8_t 	NLG5_S_L_T_TR	:1;		// Limitation by temperature transformer
+    uint8_t 	NLG5_S_L_T_DIO	:1;		// Limitation by temperature diodes
+    uint8_t 	NLG5_S_L_T_POW	:1;		// Limitation by temperature power stage
+    uint8_t 	NLG5_S_L_T_CPRIM:1;		// Limitation by temperature Capacitors prim.
+    uint8_t 	NLG5_S_L_MO_MAX	:1;		// Limitation by NLG5 maximum output voltage
+    uint8_t 	NLG5_S_L_OC_MAX	:1;		// Limitation by NLG5 maximum output current
+    uint8_t 	NLG5_S_L_MC_MAX	:1;		// Limitation by NLG5 maximum mains current
+    } B;
+} NLG5_STB3_t;
+
+
+
+// ***** NLG5 Status BRUSA to BMU **********************************************
+typedef struct {
+	NLG5_STB1_t		NLG5_STB1;			// NLG5 Status Bitmap 1/4
+	NLG5_STB2_t		NLG5_STB2;			// NLG5 Status Bitmap 2/4
+	NLG5_STB3_t		NLG5_STB3;			// NLG5 Status Bitmap 3/4
+	uint8_t			NLG5_STB4;			// NLG5 Status Bitmap 4/4
+} NLG5_ST_t;
+
+
+// ***** CAN0 REQUEST TELEGRAM ****************
+typedef struct {
+union {
+	uint8_t Byte[4];
+	struct {
+		uint8_t MasterAlive:3;
+	    uint8_t SetMode:5;
+		uint8_t BalancingCell0_7;
+		uint8_t BalancingCell8_15;
+		uint8_t BalancingCell16_23;
+	}Values;
+};
+}MASTER_X_BMS_TELEGRAM;
+
+//  ***** CAN0 SLAVE 0 - 5 Telegram
+typedef struct{
+	uint16_t	SlaveAlive:3;
+	uint16_t	Vcell0:13;
+	uint16_t	Vcell1;
+	uint16_t	Vcell2;
+	uint16_t	Vcell3;
+}SLAVE_X0_5_BMS_TELEGRAM;
+
+//  ***** CAN0 SLVAE 6 TELEGRAM
+typedef struct{
+	uint8_t		SlaveAlive:3;
+	uint8_t		SlaveMode:5;
+	uint8_t		reserved1:2;
+	uint8_t		SlaveError:6;
+	uint16_t	reserved2;
+	uint16_t	reserved3;
+	uint16_t	reserved4;	
+}SLAVE_X6_BMS_TELEGRAM;
+
+//  ***** CAN0 SLVAE 7 TELEGRAM
+typedef struct{
+	uint8_t		SlaveAlive:3;
+	uint8_t		MuxCounter:3;
+	uint8_t		reserverd1:2;
+	int8_t		TempHeatSink;
+	int8_t		TempSens0;
+	int8_t		TempSens1;
+	int8_t		TempSens2;
+	int8_t		TempSens3;
+	uint16_t	reserved2;
+}SLAVE_X7_BMS_TELEGRAM;
+
+//  ***** CAN0 UI TELEGRAM
+typedef struct{
+	uint8_t		UIAlive:3;
+	uint8_t		UIMode:5;
+	uint16_t	Ubatt;
+	uint16_t		Ibatt;
+	uint16_t	reserved;
+	uint8_t		Checksum;
+}SLAVE_UI_BMS_TELEGRAM;
+
+typedef struct {
+	uint8_t	HS_closed:1;
+	uint8_t LS_closed:1;
+	uint8_t	PRECHARGE_closed:1;
+	uint8_t reseved:5; 
+}BMS_MASTER_RELAY_STATE;
+
+typedef enum {
+	BMS_CAN_ID_SEARCH_INIT=0,
+	BMS_CAN_ID_SEARCH_CHECK_COMMUNICATION,
+	BMS_CAN_ID_SEARCH_RECONFIGURE_CAN0_IDS,
+	BMS_CAN_ID_SEARCH_SAFE_CONFIGURATION
+}BMS_CAN_ID_SEARCH_FSM_t;
+
+typedef union{
+	uint16_t word;
+	struct{
+		uint16_t SOC_Initialized:1;
+		uint16_t Slave_Can_Id_valid:1;
+		uint16_t reserved:14;
+	}Bit;
+}MASTER_STARTUP_STATE;
+
+typedef struct {
+	uint8_t CanId;
+	uint8_t SerialNr[8];
+}SLAVE_ID_t;
+
+typedef struct {
+	MASTER_STARTUP_STATE state;
+	BMS_CAN_ID_SEARCH_FSM_t fsmState;
+	SLAVE_ID_t SlaveConfig[CAN0_MAX_NR_OF_SLAVES];
+	float maxBatteryVoltage;
+	float minBatteryVoltage;
+	float startSoC;
+}MASTER_STARTUP_CONFIG_t;
+
+// states of RUNNING_MODE_FSM
+
+typedef enum {
+	RUN_MODE_INIT=0,
+	RUN_MODE_CHECK_FOR_ACTIVE_ERRORS,
+	RUN_MODE_ES3_FSM,
+	RUN_MODE_ES2_FSM,
+	RUN_MODE_ES1_FSM,
+	RUN_MODE_OPERATION,
+	RUN_MODE_SYSTEM_POWER_DOWN
+}MASTER_RUNNING_MODE;
+
+// states of Master CAN0 Fsm
+
+typedef enum{
+	OP_MODE_INIT=0,
+	OP_MODE_CHECK_STARTUP_CONDITIONS,
+	OP_MODE_SET_PRECHARGE_RELAY,
+	OP_MODE_SET_MAIN_RELAY,
+	OP_MODE_NORMAL,
+	OP_MODE_SOC_LOW,
+	OP_MODE_ERROR
+}MASTER_CAN0_OPERATION_MODE;
+
+typedef enum{
+	ES1_FSM_INIT=0,
+	ES1_FSM_CHECK_IF_ERROR_VALID,
+	ES1_FSM_ERROR_REVOKED
+}MASTER_CAN0_ES1_STATE;
+
+typedef enum{
+	ES2_FSM_INIT=0,
+	ES2_FSM_CHECK_IF_ERROR_VALID,
+	ES2_FSM_WAIT_FOR_SHUTDOWN,
+	ES2_FSM_ERROR_REVOKED,
+	ES2_FSM_SYSTEM_SHUTDOWN
+}MASTER_CAN0_ES2_STATE;
+
+typedef enum{
+	ES3_FSM_INIT=0,
+	ES3_FSM_CONNECT_TO_SERVICE_TOOL,
+	ES3_FSM_SYSTEM_SHUTDOWN,
+	ES3_FSM_SYSTEM_REPAIR,
+	ES3_FSM_ERROR_REVOKED
+}MASTER_CAN0_ES3_STATE;
+
+typedef enum{
+	RCT_INV_INACTIVE=0,
+	RCT_INV_CAN_CONNECTED,
+	RCT_INV_RELALY_CONNECTED,
+	RCT_INV_RELAY_DISCONNECT
+}BMS_RCT_INVERTER_FSM_STATE_t;
+
+typedef struct {
+	BMS_RCT_INVERTER_FSM_STATE_t state;
+	uint8_t inverterCanOnline;
+	uint8_t inverterIsCharging;
+	float startupPwr;	
+}BMS_RCT_INVERTER_t;
+
+typedef enum {	INIT=0,
+				CHECK_IF_SLAVE_ACTIVE,
+				SEND_REQUEST_TELEGRAM,
+				WAIT_FOR_SLAVE_RESPONSE,
+				CHECK_CAN_DATA,
+				DO_CALCULATIONS,
+				RUNNING_MODE_FSM,
+				HANDLE_CAN_ERROR,
+				WAIT_FOR_NEXT_SLAVE_TIMESLOT,
+				SEND_RECEIVE_INVERTER_DATA,
+				WAIT_FOR_NEXT_COMMUNICATION_CYCLE,
+				SHUT_DOWN_BMS,
+				ERROR_UNKNOWN_STATE
+}MASTER_CAN0_FSM_STATE_t;
+
+typedef enum {	ERROR_INIT=0,
+				ERROR_CHECK_IF_SLAVE_ACTIVE,
+				ERROR_SEND_REQUEST_TELEGRAM,
+				ERROR_WAIT_FOR_SLAVE_RESPONSE,
+				ERROR_CHECK_CAN_DATA,
+				ERROR_DO_CALCULATIONS,
+				ERROR_HANDLE_CAN_ERROR,
+				ERROR_WAIT_FOR_NEXT_SLAVE_TIMESLOT,
+				ERROR_SEND_RECEIVE_INVERTER_DATA,
+				ERROR_WAIT_FOR_NEXT_COMMUNICATION_CYCLE,
+				ERROR_SHUT_DOWN_BMS,
+				ERROR_ERROR_UNKNOWN_STATE
+}MASTER_CAN0_ERROR_FSM_STATE_t;
+
+// states of Master CAN1 Fsm
+
+typedef enum {	CAN1_INIT=0,
+				CAN1_SEND_DATA,
+				CAN1_WAIT_TILL_NEXT_TRANSMIT,
+				CAN1_REQUEST_DATA,
+				CAN1_WAIT_FOR_REQUEST_RESPONSE,
+				CAN1_WAIT_FOR_NEXT_CYCLE
+}MASTER_CAN1_FSM_STATE_t;
+
+typedef enum { 	CAN1_FSM_INIT=0,
+			   	CAN1_FSM_SEND_HIGH_PRIO_DATA,
+			   	CAN1_FSM_SEND_LOW_PRIO_DATA,
+			   	CAN1_FSM_SEND_REQUEST_DATA,
+			   	CAN1_FSM_WAIT_FOR_RESPONSE,
+			   	CAN1_FSM_SEND_ES_1,
+			   	CAN1_FSM_SEND_ES_2,
+			   	CAN1_FSM_SEND_ES_3,
+			   	CAN1_FSM_ERROR
+}MASTER_CAN1_FSM_INVERTER_STATE_t;
+
+typedef enum {	CAN1_FAST_RX_FSM_REQUEST_BATTERY_CURRENT=0,
+				CAN1_FAST_RX_FSM_REQUEST_BATTERY_VOLTAGE,
+				CAN1_FAST_RX_FSM_REQUEST_COMPLETE
+}MASTER_CAN1_FSM_FAST_REQUEST_STATE_t;
+
+
+// CONNECTIONS STATUS OF SLAVE
+
+typedef enum {
+	NOT_CONNECTED=0,
+	CONNECTED,
+	DEBUG_SLAVE_SIMULATED,
+	DEBUG_DATA_SIMULATED,
+	TIMEOUT,
+	TELEGRAM_LOST
+}SLAVE_CAN0_CONNECT_STATUS_t;
+
+
+typedef enum {	MASTER_OPERATION_INIT=0,
+				SET_PRECHARGE_RELAIS,
+				SET_MAIN_RELAIS,
+				MASTER_OPERATION_COMPLETE
+}MASTER_OPERATION_FSM_STATE_t;
+
+typedef struct{
+	uint16_t	SlaveErrorCounterRegister;
+	uint32_t	SlaveErrorStateRegister;
+	uint8_t		FailedComCnt;
+	uint8_t		WrongAliveCnt;
+}SLAVE_ERROR_STRUCT_t;
+
+typedef enum {
+	SLAVE=0,
+	UI
+}SLAVE_CAN0_TYPE_t;
+
+
+typedef enum  {
+	BMS_BALANCE_INIT=0,
+	BMS_BALANCE_GET_VOLTAGE,
+	BMS_BALANCE_BALANCE_CELLS,
+	BMS_BALANCE_COOL,
+	BMS_BALANCE_OFF
+}BMS_BALANCE_STATE_t;
+
+// fsm struct for running mode fsm
+
+typedef struct {
+	MASTER_RUNNING_MODE RunningMode;
+	MASTER_CAN0_OPERATION_MODE OperationMode;
+	uint32_t OperationModeTimestamp;
+	MASTER_CAN0_ES1_STATE ErrorState1fsm;
+	uint32_t ErrorState2Timestamp;
+	uint32_t ErrorState3Timestamp;
+	MASTER_CAN0_ES2_STATE ErrorState2fsm;
+	MASTER_CAN0_ES3_STATE ErrorState3fsm;
+	uint32_t onCounter; // counter for relay closed time
+}BMS_RUNNING_MODE_t;
+
+// connection status of cells
+
+typedef enum {
+	CELL_NOT_CONNECTED=0,
+	CELL_BYPASSED,
+	CELL_CONNECTED
+}CELL_STATE_t;
+
+typedef enum {
+	TEMP_SENSOR_NOT_CONNECTED=0,
+	TEMP_SENSOR_CONNECTED
+}TEMP_SENSOR_STATE_t;
+
+typedef struct {
+	uint32_t valueId;
+	float	value;
+}BMS_CAN1_INVERTER_FLOAT_t;
+
+typedef struct {
+	uint32_t valueId;
+	uint32_t payload;
+}BMS_CAN1_INVERTER_CELL_DATA_t;
+
+typedef struct {
+	uint32_t valueId;
+	uint32_t	value;
+}BMS_CAN1_INVERTER_INTEGER_32_t;
+
+typedef struct {
+	uint32_t valueId;
+	uint32_t	value;
+}BMS_CAN1_INVERTER_INTEGER_16_t;
+
+typedef struct {
+	uint32_t	valueId;
+	uint8_t		globalBatteryStatus;
+	uint8_t		errorCode;
+	uint8_t		byte6;
+	uint8_t		byte7;
+}BMS_CAN1_INVERTER_BATTERY_STATUS_t;
+
+typedef struct {
+	union {
+		uint8_t Byte[14][8];
+		struct {
+			BMS_CAN1_INVERTER_INTEGER_32_t batteryModeExtra;
+			BMS_CAN1_INVERTER_FLOAT_t maxBatteryChargeCurrent;
+			BMS_CAN1_INVERTER_FLOAT_t maxBatteryChargeVoltage;
+			BMS_CAN1_INVERTER_FLOAT_t maxBatteryDischargeCurrent;
+			BMS_CAN1_INVERTER_FLOAT_t minBatteryDischargeVoltage;
+			BMS_CAN1_INVERTER_FLOAT_t batteryCurrent;
+			BMS_CAN1_INVERTER_FLOAT_t batteryVoltage;
+			BMS_CAN1_INVERTER_FLOAT_t batterySOCtarget;
+			BMS_CAN1_INVERTER_FLOAT_t batterySOC;
+			BMS_CAN1_INVERTER_FLOAT_t batteryCapacity;
+			BMS_CAN1_INVERTER_FLOAT_t batteryTemperature;
+			BMS_CAN1_INVERTER_FLOAT_t batterySOH;
+			BMS_CAN1_INVERTER_INTEGER_32_t batteryMode;
+			BMS_CAN1_INVERTER_BATTERY_STATUS_t batteryStatus; 
+			
+		}Values;
+	};
+}BMS_CAN1_INVERTER_TX;
+
+typedef struct {
+	union {
+		uint8_t Byte[8];
+		struct {
+			uint32_t valueId;
+			uint32_t requestId;
+		};
+	};
+}BMS_CAN1_INVERTER_REQUEST;
+
+ /// Error handling
+
+typedef struct {
+	union {
+		uint32_t Word;
+		struct{
+			uint32_t SubsystemNr:5;
+			uint32_t ErrorType:21;
+			uint32_t CellNr:5;
+			uint32_t active:1;
+		}Slave;
+		struct{
+			uint32_t SubsystemNr:5;
+			uint32_t ErrorCode:26;
+			uint32_t active:1;
+		}Master;
+		struct{
+			uint32_t SubsystemNr:5;
+			uint32_t ErrorCode:26;
+			uint32_t active:1;
+		}UI;
+	};
+}BMS_ERROR_STATE_t;
+
+typedef struct {
+	uint8_t recoveryPending;
+	uint32_t recoveryTimestamp;// used to determine timespan for inverter to be able to fix errors
+}BMS_ERROR_RECOVERY_STRUCT_t;
+
+typedef struct {
+	BMS_ERROR_STATE_t ES1_Error[BMS_ERROR_ERROR_STACK_SIZE]; // Class 1 errors
+	BMS_ERROR_STATE_t ES2_Error[BMS_ERROR_ERROR_STACK_SIZE]; // Class 2 errors
+	BMS_ERROR_STATE_t ES3_Error[BMS_ERROR_ERROR_STACK_SIZE]; // Class 3 errors
+	BMS_ERROR_RECOVERY_STRUCT_t ES1_Error_Recovery[BMS_ERROR_ERROR_STACK_SIZE];
+	BMS_ERROR_RECOVERY_STRUCT_t ES2_Error_Recovery[BMS_ERROR_ERROR_STACK_SIZE];
+	uint8_t ES1_ErrorCounter;//Number of Class 1 errors
+	uint8_t ES2_ErrorCounter;//Number of Class 2 errors
+	uint8_t ES2_New_Error;  // flag to mark newly occured errors
+	uint8_t ES3_ErrorCounter;//Number of Class 3 errors
+}BMS_ERROR_BUFFER_t;
+
+typedef struct {
+	BMS_ERROR_STATE_t ES1_Error[BMS_ERROR_ERROR_STACK_SIZE]; // Class 1 errors
+	BMS_ERROR_STATE_t ES2_Error[BMS_ERROR_ERROR_STACK_SIZE]; // Class 2 errors
+	BMS_ERROR_STATE_t ES3_Error[BMS_ERROR_ERROR_STACK_SIZE]; // Class 3 errors
+	uint32_t counter;
+}BMS_ERROR_FRAM_DEBUG_t;
+
+typedef struct {
+	float actualACpower;
+	float  phaseL1Voltage;
+	float  phaseL2Voltage;
+	float  phaseL3Voltage;
+	float  DCinputA_voltage;
+	float  DCinputB_voltage;
+	uint16_t  islandMode;
+	float  DCinputA_power;
+	float  DCinputB_power;
+	float expectedInputPower;
+	float batteryVoltage;
+	float batteryCurrent;
+}BMS_CAN1_INVERTER_RX;
+
+typedef struct {
+	BMS_CAN1_INVERTER_TX txStruct;
+	BMS_CAN1_INVERTER_RX rxStruct;	
+}BMS_CAN1_INVERTER;
+
+// ***** struct for selecting pending Master or Slave Telegram ********
+typedef struct {
+	uint8_t nrOfRecTelegrams;
+	uint8_t	transmission_pending;
+	uint32_t timestamp;
+	MASTER_CAN0_FSM_STATE_t state;
+	uint8_t slaveSelect;
+	uint8_t telegramSelect;
+} MASTER_CAN0_STATE_t ;
+
+typedef struct {
+	float I_max_charge_temp_max;
+	float I_max_charge_temp_min;
+	float I_max_charge_SoC ;
+	float I_max_discharge_temp_max;
+	float I_max_discharge_temp_min;
+	float I_max_discharge_SoC	;
+	float I_max_charge_derate;
+	float I_max_discharge_derate; 
+}MASTER_OVER_CURRENT_LIMITS_t;
+
+
+// ***** struct to contain slave DATA and status and to acess Mailboxes and registers*******
+
+typedef struct {
+	SLAVE_CAN0_CONNECT_STATUS_t SlaveConnectionState;
+	SLAVE_CAN0_TYPE_t SlaveType;
+	CAN_MAILBOX* TxMailbox_ptr;
+	MASTER_X_BMS_TELEGRAM* TxTelegram_ptr;
+	uint16_t CellVoltage[MAX_SLAVE_CELLS];
+	uint16_t minCellVoltage;
+	uint16_t maxCellVoltage;
+	uint32_t BlockVoltage;
+	int8_t CellTemp[MAX_SLAVE_CELLS];
+	CELL_STATE_t CellConnectionState[MAX_SLAVE_CELLS];
+	TEMP_SENSOR_STATE_t TempSensConnectionState[MAX_SLAVE_CELLS];
+	int8_t HeatSinkTemp;
+	int8_t maxCellTemp;
+	int8_t minCellTemp;
+	uint8_t SlaveAliveCnt[CAN0_NR_OF_TELEGRAMS];
+	uint8_t	SlaveMode;
+	uint8_t SlaveError;
+	uint8_t	SlaveTelegramsRecFlag;
+	uint8_t Set_Mode;
+	uint8_t Balance_Cell_0_7;
+	uint8_t Balance_Cell_8_15;
+	uint8_t Balance_Cell_16_23;
+	uint8_t MuxCounter;
+	uint8_t MasterAliveCnt;
+	SLAVE_ERROR_STRUCT_t SlaveCanCommuniationError;
+}BMS_CAN0_SLAVE_t;
+
+typedef struct {
+	uint16_t Ubatt;
+	int16_t Ibatt;
+	uint8_t	 Checksum;
+	uint32_t UbattFiFo[UI_VOLTAGE_FIFO_SIZE];
+	uint32_t SystemVoltageFiFo[UI_VOLTAGE_FIFO_SIZE];
+	int16_t IbattFiFo[UI_CURRENT_FIFO_SIZE];
+	float Ibatt_Inverter_FIFO[UI_CURRENT_FIFO_SIZE];
+}BMS_CAN0_UI_t;
+
+
+
+typedef struct {
+	uint8_t slaveNr;
+	SLAVE_CAN0_TYPE_t type;
+	SLAVE_CAN0_CONNECT_STATUS_t connectionSate;
+	CELL_STATE_t cellConnectionState[MAX_SLAVE_CELLS];
+	TEMP_SENSOR_STATE_t tempSensConnectionState[MAX_SLAVE_CELLS];
+}BMS_SLAVE_CONFIGURATION_t;
+
+typedef struct {
+	uint8_t slaveNr;
+	SLAVE_CAN0_TYPE_t type;
+	SLAVE_CAN0_CONNECT_STATUS_t connectionSate;
+}BMS_UI_CONFIGURATION_t;
+
+typedef struct {
+	uint32_t timestamp;
+	MASTER_OPERATION_FSM_STATE_t FsmState;
+}BMS_MASTER_OPERATION_t;
+
+typedef struct {
+	MASTER_CAN1_FSM_STATE_t fsmState;
+	uint8_t		txMsgNr;
+	uint32_t    timestamp;
+	uint32_t 	delay;
+} MASTER_CAN1_STRUCT_t;
+
+typedef struct {
+	MASTER_CAN1_FSM_INVERTER_STATE_t fsmState;
+	MASTER_CAN1_FSM_FAST_REQUEST_STATE_t fastRxState;
+	uint8_t 	fastRequestFsmRunning;
+	uint8_t 	slowRequestFsmRunning;
+	uint32_t	highPrioMsgNr;
+	uint8_t    lowPrioMsgNr;
+	uint8_t		transmitErrorNrEs1;
+	uint8_t		transmitErrorNrEs2;
+	uint8_t		transmitErrorNrEs3;
+	uint32_t 	requestTelegramNr;
+	uint32_t	timeoutCyclesCnt;
+	uint32_t	receivedTelegrams;
+	uint32_t 	nrOfRecCurrentSamples;
+} MASTER_CAN1_INVERTER_STRUCT_t;
+
+typedef enum {
+	BMS_SOC_IDLE=0,
+	BMS_SOC_CHECK_CURRENT,
+	BMS_SOC_CHARGE,
+	BMS_SOC_CHARGE_AREA_FULL, 
+	BMS_SOC_CHARGE_AREA_HIGH,
+	BMS_SOC_CHARGE_WAIT_FOR_RELAXATION,
+	BMS_SOC_CHARGE_AREA_CHARGE,
+	BMS_SOC_CHARGE_C_CNT,
+	BMS_SOC_CHARGE_SMOOTHING,
+	BMS_SOC_CHARGE_DERATE,
+	BMS_SOC_DISCHARGE,
+	BMS_SOC_DISCHARGE_AREA_EMPTY, 
+	BMS_SOC_DISCHARGE_AREA_LOW,
+	BMS_SOC_DISCHARGE_WAIT_FOR_RELAXATION,
+	BMS_SOC_DISCHARGE_AREA_DISCHARGE,
+	BMS_SOC_DISCHARGE_C_CNT,
+	BMS_SOC_DISCHARGE_SMOOTHING,
+	BMS_SOC_DISCHARGE_DERATE,
+	BMS_SOC_REST,
+	BMS_SOC_READY
+}MASTER_SOC_ESTIMATOR_STATE_t;
+
+typedef enum {
+	BMS_MASTER_TEMP_SENSOR_INITIATE_MEASUREMENT=0,
+	BMS_MASTER_TEMP_SENSOR_UPDATE_MEASUREMENT
+}MASTER_TEMP_SENSOR_FSM_t;
+
+/*
+ * Voltage Areas assigned with State of charge Area to support coulumb counting
+ */
+typedef struct {
+	float SoC_limit_high;  		// upper limit for SOC in Area [0...1]
+	float SoC_limit_low;		// lower limit of SOC in Area [0 ...1]
+	uint16_t OCV_limit_high; 	// upper limit of Open Clamp Voltage in Area [mV]
+	uint16_t OCV_limit_low;		// lower limit of Open Clamp Voltage in Area [mV]
+	uint16_t OCV_hysteresis;    // hyseresis for detection of new Area [mV]
+} MASTER_SOC_ESTIMATOR_AREA_t;
+
+typedef struct {
+	uint16_t U_bat_max;			// Maximum Clamp Voltage => SoC = 100%
+	uint16_t U_ocv_correct;		// Open Clamp Voltage used to Correct Columb counting
+	float 	 Ri_charge;			// Ri of cell at charging
+	float	 U_ocv_SoC;			// SoC @ U_ocv_correct
+} MASTER_SOC_ESTIMATOR_CHARGE_THRESHOLD_t;
+
+typedef struct {
+	uint16_t U_bat_min;			// Minimum Clamp Voltage => SoC = 0%
+	uint16_t U_ocv_correct;		// Open Clamp Voltage used to Correct Columb counting
+	float 	 Ri_discharge;		// Ri of cell at discharging 
+	float	 U_ocv_SoC;			// SoC @ U_ocv_correct
+} MASTER_SOC_ESTIMATOR_DISCHARGE_THRESHOLD_t;
+
+typedef struct {
+	float SoC;
+	uint16_t OCV;
+}MASTER_SOC_ESTIMATOR_INIT_SOC_LUT_t;
+/*
+ * 
+ */
+typedef struct {
+	float capacity;
+	float SoC_Ah;
+	float SoC_percentage;
+	float SoC_percentage_smooth; 
+	float SoC_Ah_smooth; 
+	float delta_t;
+	float MaxBatteryChargeCurrent;
+	float MaxBatteryDischargeCurrent;
+	float SoC_percentage_smooth_FiFo[SOC_SMOOTH_FIFO_SIZE];
+	uint16_t Ocv_calc;
+	uint16_t ChargeRelaxationWaitCnt;
+	uint16_t DischargeRelaxationWaitCnt;
+	uint16_t flags;
+	uint16_t ChargeSmoothFlags;
+	MASTER_SOC_ESTIMATOR_STATE_t state;
+	MASTER_SOC_ESTIMATOR_CHARGE_THRESHOLD_t ChargeThreshold;
+	MASTER_SOC_ESTIMATOR_DISCHARGE_THRESHOLD_t DischargeThreshold; 
+} MASTER_SOC_ESTIMATOR_t;
+
+
+
+
+typedef struct {
+	MASTER_OVER_CURRENT_LIMITS_t currentLimits;
+	MASTER_STARTUP_CONFIG_t startupConfig;
+	BMS_MASTER_RELAY_STATE relayState;
+	MASTER_TEMP_SENSOR_FSM_t MasterTempSensState;
+	int16_t masterTemp;
+	BMS_RUNNING_MODE_t RunMode;
+	uint32_t winterModeTimestamp;
+	BMS_CAN0_SLAVE_t Slave[CAN0_MAX_NR_OF_SLAVES];
+	BMS_CAN0_UI_t	UI_Board;
+	BMS_CAN0_SLAVE_t tempSlave;
+	BMS_CAN0_UI_t	temp_UI_Board;	
+	uint32_t reset_test_timestamp;
+	uint32_t	StateOfCharge;			// SOC in mAs
+	uint16_t minCellVoltage;
+	uint16_t maxCellVoltage;
+	int8_t minCellTemp;
+	int8_t maxCellTemp;
+	int8_t maxHeatSinkTemp;
+	int8_t minHeatSinkTemp;
+	float SoC_outside;
+	MASTER_CAN0_FSM_STATE_t FsmState;
+	MASTER_CAN0_ERROR_FSM_STATE_t FsmErrorState;
+	BMS_ERROR_BUFFER_t ErrorBuffer;
+	BMS_CAN1_INVERTER inverter;
+	BMS_RCT_INVERTER_t inverterState;
+	uint8_t slaveSelect;
+	uint32_t timestamp;
+	uint32_t time;
+	uint32_t cycleTimestamp;
+	uint8_t transmission_pending;
+	uint8_t cycleCounter;
+	uint32_t systemVoltage;
+	uint8_t allValuesInitialized;
+	uint8_t	startCan1Comm;
+	uint8_t NrOfSlaves;
+	BMS_BALANCE_STATE_t balancerState;
+	MASTER_SOC_ESTIMATOR_t  SoC_estimator;
+	uint8_t	SoC_initialized;
+	uint8_t ErrorFlags;
+	MASTER_CAN1_INVERTER_STRUCT_t CAN1_fsmStruct;
+	float UiInverterInconsistency;
+	float UiSlaveInconsistency;
+} MASTER_CAN0_STRUCT_t;
+
+
+#endif  /* ifndef*/

+ 48 - 0
BMS Master/Project_Headers/BoardPeripherals.h

@@ -0,0 +1,48 @@
+
+#ifndef __BOARDPERIPH_H__
+#define __BOARDPERIPH_H__
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+union Periph_Flags {
+	uint8_t R;
+	struct {
+		uint8_t rsvd:6;
+		uint8_t init_ok:1;
+		uint8_t test_ok:1;
+		uint8_t test_fail:1;
+	} B;
+};
+
+typedef struct {
+	union Periph_Flags FRAM_Flags;
+	uint32_t test_time;
+} Board_Status;
+
+
+
+//-------------------------------------------------------
+//API
+
+
+
+//extern Board_Status Board_S;
+
+       void   BoardPeriph_init               ( void );
+extern void   BoardPeriph_test_init          ( void );
+extern int8_t BoardPeriph_test_update_polled ( void );
+extern void   BoardPeriph_update_1ms         ( void );
+extern void   BoardPeriph_update_polled      ( void );
+
+//-------------------------------------------------------
+
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif  /* ifndef*/

+ 43 - 0
BMS Master/Project_Headers/DSPI.h

@@ -0,0 +1,43 @@
+//==============================================================================
+// Purpose:    SPI Interface für das DSPI-Modul des MPC5646
+//
+// Created on:  20.04.2012 by IPE
+//
+// History
+//		20.04.2012 neu, T.Maurer
+//==============================================================================
+
+#ifndef __DSPI_H__
+#define __DSPI_H__
+
+// Globale Datentypen
+
+//DSPI_config_t
+//Konfiguration des DSPI-Moduls
+typedef struct {
+	volatile struct DSPI_tag *p_Modul;	//Adresse des Moduls
+	enum {DSPI_Master,DSPI_Slave} MaSlv_Mode;
+	uint8_t FrameSize;	//Anzahl Bits
+	enum {DSPI_ClassicFormat,DSPI_ModifiedFormat} TimingFormat;
+	enum {DSPI_Baud15MHz,DSPI_Baud5MHz,DSPI_Baud2MHz} Baud_Setting; //nur MasterMode;
+	uint8_t CStoSCK_Delay_Cycles;	//nur MasterMode; Werte >15 müssen in DSPI_init() implementiert werden
+	uint8_t AfterSCK_Delay_Cycles;	//nur MasterMode;
+	uint8_t DelayAfterTransfer_Cycles;	//nur MasterMode;
+	uint16_t Std_CS_Mask;
+	enum{CS_Cont_ON, CS_Cont_OFF} CS_Cont;
+	enum {DSPI0_PortA12,DSPI1_PortE4,DSPI2_PortC12,
+		DSPI3_PortG2,DSPI4_PortK9,DSPI6_PortG14} Port;	//Auswahl der Rx/Tx-Port-Pins für ein CAN-Modul
+} DSPI_config_t;
+
+
+extern const DSPI_config_t SPI_6_Config;	//ISA
+
+extern int8_t DSPI_init(DSPI_config_t *Config);
+extern int8_t DSPI_check_and_read(DSPI_config_t *p_Config, uint32_t *data);
+extern int8_t DSPI_push(DSPI_config_t *const p_Config, uint16_t data, uint8_t isEOQ);
+extern int8_t DSPI_pop(DSPI_config_t *const p_Config, volatile uint16_t *const data);
+extern int8_t DSPI_Clear_RxFifo(DSPI_config_t *const p_Config);
+int8_t DSPI_init_Tx(DSPI_config_t *const p_Config);
+
+
+#endif /*ifndef*/

+ 17 - 0
BMS Master/Project_Headers/DebugUndTest.h

@@ -0,0 +1,17 @@
+// Purpose:     Funktionen zum Testen auf dem MasterBoard
+//
+// Created on:  16.05.2012 by IPE
+//
+// History
+//		16.05.2012 neu, T.Maurer
+//==============================================================================
+
+#include "Device.h"
+#include "BoardPeripherals.h"
+
+//"Balancer-Lauflicht"
+//Die Funktion schaltet für jeden Slave den Balancer aus und den nächsten Balancer ein
+extern uint8_t BalancerTest(void);
+
+//ohne Funktion
+extern void CAN_Test(void);

+ 55 - 0
BMS Master/Project_Headers/Device.h

@@ -0,0 +1,55 @@
+//==============================================================================
+// Purpose:     Intitialisierung von Betriebsmodus, Clock;
+//				GPIO-Funktionen
+//
+// Created on:  20.04.2012 by IPE
+//
+// History
+//		20.04.2012 neu, T.Maurer
+//==============================================================================
+
+
+#ifndef __DEVICE_H__
+#define __DEVICE_H__
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+//MACROS
+//Pins des MPC
+#define READ_INPIN(NR) 	        SIU.GPDI[NR].B.PDI
+#define SET_OUTPIN(NR) 		    SIU.GPDO[NR].B.PDO=1
+#define CLEAR_OUTPIN(NR) 	    SIU.GPDO[NR].B.PDO=0
+#define TOGGLE_OUTPIN(NR) 		SIU.GPDO[NR].B.PDO = (SIU.GPDO[NR].B.PDO)?0:1
+#define GET_OUTPIN_VAL(NR) 		SIU.GPDO[NR].B.PDO
+
+
+
+
+//PROTOTYPES
+ void init_Device(void);
+//----------------------
+//extern void initMODE(void);
+//extern void setPLL(void);
+//extern void disableWatchdog(void);
+
+ void Asm_initIrqVectors( void );
+//extern void initINTC(void);
+//extern void enableIrq(void);
+ void initMODE(void);
+ void setPLL(void);
+ void disableWatchdog(void);
+ void initINTC(void);
+ void init_Mode_and_Clock(void);
+ //asm void initIrqVectors(void);
+ //extern void initINTC(void);
+ void enableIrq(void);
+
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif  /* ifndef*/

+ 50 - 0
BMS Master/Project_Headers/Exceptions.h

@@ -0,0 +1,50 @@
+/**
+ * FILE: Exceptions.h
+ *
+ * DESCRIPTION: Defines the default INTC exception handler and the INTC initialization function.
+ *				These functions are defined in Core_0 memory space.
+ * VERSION: 1.1
+ */
+
+#ifndef _EXCEPTIONS_H_
+#define _EXCEPTIONS_H_
+
+/*----------------------------------------------------------------------------*/
+/* Function declarations                                                      */
+/*----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma section RX ".__exception_handlers_p0"
+
+/**
+ * This function is used as default exceptions handler
+ */
+__declspec (section ".__exception_handlers_p0") void EXCEP_DefaultExceptionHandler(void);
+
+
+/**
+ * This function will setup the PowerPC Zen core IVPR and IVORxx registers.
+ * IVPR will be set to the EXCEPTION_HANDLERS memory area defined in the 
+ * linker command file (.lcf of the current build target)  
+ * IVORxx will be set by default to the exception handler function: 
+ *     __DefaultExceptionHandler__.
+ *
+ * If an Exception is used in the application code, the exception handler routine
+ * should be defined like the EXCEP_DefaultExceptionHandler function 
+ * (i.e. interrupt function, forced active and placed in the 
+ * ".__exception_handlers_p0" code section). 
+ * The corresponding entries in the ivor_branch_table should then be set to 
+ * branch to this address.
+ *    
+ */
+__asm void EXCEP_InitExceptionHandlers(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 95 - 0
BMS Master/Project_Headers/FRAM.h

@@ -0,0 +1,95 @@
+// ----------------------------------------------------------------------------
+// FRAM.h - 
+// ----------------------------------------------------------------------------
+// Beschreibung:	FRAM (FM25V02) Defines und Prototypen
+//					HW: BMS-Master, IPE 362-02-02R0
+// Revision:		12. Mai 2012 T. Blank, IPE : neu,
+//					16.Juli 2012 T.Maurer, IPE : FSMs,IF
+// ----------------------------------------------------------------------------
+
+#ifndef _FRAM_H_
+#define _FRAM_H_
+
+
+
+//SPI-Konfiguration
+//extern const DSPI_config_t FRAM_SPI_Config;
+
+#define WREN_OPC	0b00000110		// Set Write Enable Latch
+#define WRDI_OPC	0b00000100		// Write Disable
+#define RDSR_OPC	0b00000101		// Read Status Register
+#define WRSR_OPC	0b00000001		// Write Status Register
+#define READ_OPC	0b00000011		// Read Memory Data
+#define FSTRD_OPC	0b00001011		// Fast Read Memora Data
+#define WRITE_OPC	0b00000010		// Write Memory Data
+#define SLEEP_OPC	0b10111001		// Enter Sleep Mode
+#define RDID_OPC	0b10011111		// Read Device ID
+#define SNR_OPC		0b11000011		// Read S/N
+
+
+
+
+
+typedef struct {
+	enum {Fram_Idle=0,Fram_Write_1,Fram_Write_2,Fram_Write_3,Fram_Read_1,Fram_Read_2,Fram_Read_3} FsmState;
+	enum {NoTask,RamWrite,RamRead,RamTest} TaskTrigger;
+	uint8_t  FramTest_state;
+	uint16_t Addr;
+	vuint8_t *datastart;
+	uint8_t  num_data;
+	uint8_t  n_RxDummies;
+	union {
+		uint8_t R;
+		struct {
+			uint8_t JobFinished:1;
+			uint8_t FSM_TO:1;
+			uint8_t rsvd:6;
+			} B;
+	} Flags;
+} FramStatus_t;
+
+
+
+//====================================================================
+// API
+
+extern int8_t FRAM_init(void);
+//init des SPI-Moduls, der IO-Steuer-Pins und des Status
+
+extern int8_t FRAM_update(uint8_t tick);
+//ruft FRAM_FSM_update auf.
+//Der Param. "tick" triggert den TimeOut-Zaehler
+// -> (tick=1 jede 1ms, tick=0 sonst)
+//bei einem TimeOut-Event wird FRAM_init aufgerufen und das TO-Flag gesetzt
+//Die FSM kann dadurch im polling-Betrieb aufgerufen werden, also auch ungetaktet.
+
+extern int8_t FRAM_trigger_write(const vuint16_t Addr, vuint8_t *const data, const vuint8_t num_data);
+//triggert ein Schreiben in den Speicher.
+//Param: Addr = Startadresse; num_data = Anzahl Bytes; *data = DatenArray
+//return -1 wenn num_data < 1
+//return -2 wenn FSM nicht im Leerlauf
+//return -3 wenn Test-Routine läuft
+//return 0  wenn Trigger-Erfolg
+
+extern int8_t FRAM_trigger_read(const vuint16_t Addr, vuint8_t *const data, vuint8_t num_data);
+//triggert ein Lesen aus dem Speicher.
+//Param: Addr = Startadresse; num_data = Anzahl Bytes; *data = Ziel-DatenArray
+//return -1 wenn num_data < 1
+//return -2 wenn FSM nicht im Leerlauf
+//return -3 wenn Test-Routine läuft
+//return 0  wenn Trigger-Erfolg
+
+
+//-----------------------------------------------
+//Test-Modus des RAMs. Waehrend des Tests werden FRAM_trigger_write()
+//und FRAM_trigger_read() blockiert. 
+extern int8_t FRAM_trigger_Test(void);
+//Startet eine (den Prozessor nicht blockierende) Test-Routine.
+
+extern int8_t FRAM_Test_update(void);
+//Fsm der Testroutine.
+
+
+
+#endif  /* ifndef*/
+

+ 102 - 0
BMS Master/Project_Headers/FlexCAN.h

@@ -0,0 +1,102 @@
+//==============================================================================
+// Purpose:     allgemeines CAN Interface für FlexCAN von MPC5646
+//
+// Created on:  20.04.2012 by IPE
+//
+// History
+//		20.04.2012 neu, T.Maurer
+//==============================================================================
+
+
+
+#ifndef __FLEXCAN_H__
+#define __FLEXCAN_H__
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+    
+
+// Constants
+#define CAN_DATA_ARR_LEN	8	//Max Anzahl der Datenbytes der CAN-Schittstelle
+
+
+
+//==============================================================================
+//== API ==
+
+
+//Return-Werte der Funktionen
+#define CAN_OK		0
+#define CAN_ERROR	-1
+
+
+
+// Globale Datentypen
+
+//CAN_CONFIG
+//Konfiguration des CAN-Moduls
+typedef struct {
+	volatile struct FLEXCAN_tag *CAN_Modul;											//Adresse des FlexCAN-Moduls
+	enum {CAN0_PortB0_1=0, CAN1_PortC10_11, CAN2_PortE8_9, CAN3_PortF8_9 } Port;	//Auswahl der Rx/Tx-Port-Pins für ein CAN-Modul
+	enum {TxPushPull=0,Tx_OpenDrain} TxPortType;									//Tx Pin wird als Push-Pull (CMOS) oder Open-Drain konfiguriert
+	enum {RxMask_Global=0,RxMask_Individual} RxMaskType;							//Auswahl zwischen globaler RxMaske oder individueller RxMaske
+	uint32_t GlobalRxMask;															//globale RxMaske des Moduls; nur von Bedeutung wenn in RxMaskType "RxMask_Global" ausgewählt
+	enum {CANBaud_1000kHz_OSC_40MHz=0, CANBaud_500kHz_OSC_40MHz, CANBaud_250kHz_OSC_40MHz, CANBaud_125kHz_OSC_40MHz} BaudConfig;
+} CAN_CONFIG;
+
+
+//CAN_MAILBOX
+//Konfiguration und ID der MessageBox
+typedef struct {
+	CAN_CONFIG *p_CAN_Config;
+	uint8_t MBNumber;		//Message Buffer Number, 0..63
+	enum {MB_Tx,MB_Rx} Direction;
+	uint8_t RemoteEn;		//Remote Frame Transmission Ein, aktiviert den RTR-Modus der MB
+	uint8_t DataBytes;		//Anzahl der Datenbytes, max=8
+	uint8_t Interrupt;		//Empfang oder Senden generiert einen Interrupt
+	uint32_t AcceptMask;	//individuelle RxMaske der MsgBox; ohne Bedeutung,wenn in CAN_CONFIG RxMask_Global oder wenn es eine Tx-MB ist
+	enum {SHORT_ID, LONG_ID} IDE;
+	uint32_t ID;			//ID : Rx -> ID oder maskierte ID zur CAN-Nachrichten-Filterung. Nur die in AcceptMask/GlobalRxMask selektierten Bits werden beachtet
+} CAN_MAILBOX;
+
+
+
+// Global functions
+
+extern int8_t CAN_Init(CAN_CONFIG *config);
+//Initialisierung der Kontrollregister des CAN-Moduls
+//return: CAN_OK oder CAN_ERROR
+
+extern int8_t CAN_Init_Mailbox(CAN_MAILBOX *mbox);
+//Initialisierung der Message-Buffer und ihrer Einstellungen
+//return: CAN_OK oder CAN_ERROR
+
+extern int8_t CAN_Write(CAN_MAILBOX *mbox, uint8_t *data);
+//schreiben auf einen Tx-MessageBuffer
+//return: CAN_OK oder CAN_ERROR
+
+extern int8_t CAN_Write_dataset(CAN_MAILBOX *mbox, uint8_t* data,uint32_t timestamp);
+
+extern int8_t CAN_Read(CAN_MAILBOX *mbox, uint8_t *data);
+//lesen von einem Message-Buffer
+//return: CAN_OK oder CAN_ERROR
+
+extern int8_t CAN_Abort(CAN_MAILBOX *mbox);
+//Abbruch eines Sende-Prozesses
+//Gibt CAN_ERROR zurück, wenn mbox eine Rx-MB ist
+
+extern uint8_t CAN_Get_error_Register(CAN_CONFIG *config,uint32_t* can_esr);
+
+extern int8_t CAN_Check_error_Register(CAN_CONFIG *config) ;
+
+//==============================================================================
+
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif  /* ifndef*/

+ 65 - 0
BMS Master/Project_Headers/IntcInterrupts.h

@@ -0,0 +1,65 @@
+/*
+ * FILE: IntcInterrupts.h
+ *
+ * DESCRIPTION: Contains defines for utilizing the Interrupt Controller in 
+ * the MCU. 
+ * 
+ * Note: We use "_p0" suffix on functions and section names to reference the
+ * Core_0, "_p1" for functions and section names using the Core_1.
+ * 
+ * VERSION: 1.2 
+ */
+
+#ifndef _INTCINTERRUPTS_H_
+#define _INTCINTERRUPTS_H_
+
+/*----------------------------------------------------------------------------*/
+/* Types                                                                      */
+/*----------------------------------------------------------------------------*/
+
+/** All interrupt handlers should be of this type */
+typedef void(*INTCInterruptFn)(void);
+
+/*----------------------------------------------------------------------------*/
+/* Function declarations                                                      */
+/*----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This function will setup INTC for Software Vector Mode and
+ * the Vector Table Base Address to INTCInterruptsHandlerTable.
+ * This function can be used from user_init() (no stack frame, no memory access).
+ */
+__asm void INTC_InitINTCInterrupts(void);
+
+/**
+ * This function can be used to install an interrupt handler for a given
+ * interrupt vector. It will also set the Priority Status Register for the
+ * source to the one given.
+ * parameter handlerFn: The function to call when the interrupt occurs.
+ * parameter vectoryNum: The number of the INTC Interrupt Request Source we 
+ * wish to install the handler for.
+ * parameter psrPriority: The priority to set in the Interrupt Controller 
+ * Priority Select Register.
+ */
+void INTC_InstallINTCInterruptHandler(INTCInterruptFn handlerFn, 
+                                      unsigned short vectorNum,
+                                      unsigned char psrPriority);
+
+#pragma section RX ".__exception_handlers_p0"
+
+/**
+ * This function is used to Handle the interrupt source by jumping to the ISR
+ * branch table (IACKR)
+ */
+__declspec (section ".__exception_handlers_p0") void INTC_INTCInterruptHandler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 68 - 0
BMS Master/Project_Headers/LIN_Uart.h

@@ -0,0 +1,68 @@
+//==============================================================================
+// Purpose:    Uart-Interface für das LINFlex-Modul des MPC5646
+//
+// Created on:  11.07.2012 by KIT-IPE (Fachgr.: Blank)
+//
+// History
+//		11.07.2012 neu, T. Maurer
+//==============================================================================
+
+#ifndef __LIN_H__
+#define __LIN_H__
+
+
+
+// Globale Datentypen
+
+#define USE_LINFLEX_MS_TAG
+
+#ifdef USE_LINFLEX_MS_TAG
+	#define T_LINFLEX_TAG LINFLEX_MS_tag
+#else
+	#define T_LINFLEX_TAG LINFLEX_M_tag
+#endif
+
+
+
+//API
+
+
+typedef struct {
+	volatile struct T_LINFLEX_TAG *p_Modul;	//Adresse des Moduls
+	enum {LIN_Baud_115200} Baud_Setting;
+	enum {parity_none, parity_even, parity_odd} ParityMode;
+	enum {LIN0_PortB2=0,LIN4_PortA5,LIN1_PortC6} Port;	//Auswahl der Rx/Tx-Port-Pins
+} LIN_config_t;
+//Konfiguration des LIN-Moduls
+
+
+extern int8_t LIN_init(LIN_config_t *const Config);
+//Initialisierung von LINFLEX-Registern und Port-Registern für dieUart-Übertragung.
+//Parameter LIN_config_t Config bestimmt die Einstellungen des Moduls
+//return -1 wenn fehlerhafte Werte in Config
+//return 0 sonst
+
+extern uint8_t LIN_checkErrFlags(LIN_config_t *const p_Config);
+//liest das Uart-Status-Register UARTSR des LIN-Moduls
+//und setzt die Flags zurück
+//return Byte mit Flags:
+//	bit0 : Fehler im Datenformat
+//	bit1 : Fifo/Buffer-Überlauf
+
+extern int8_t LIN_push(LIN_config_t *const p_Config, const int16_t data);
+//ueberprueft, ob eine alte Uebertragung noch laeuft und 
+//schreibt ein Byte auf den Tx-Puffer
+//return -1 , wenn Buffer noch nicht frei
+//return 0 , wenn Byte auf Buffer geschrieben wurde
+// - TX-Fifo funktioniert nicht (?) - deshalb Buffer-Modus
+
+extern int8_t LIN_pop(LIN_config_t *const p_Config, int16_t *const data);
+//ueberprueft, ob der Rx-Fifo leer ist. Wenn nicht, wird das naechste Byte gelesen
+//return -1 , wenn RxFifo leer
+//return 0 , wenn Byte gelesen
+
+extern int8_t LIN_Clear_RxFifo(LIN_config_t *const p_Config);
+//leert den Rx-Fifo
+
+
+#endif /*ifndef*/

+ 8473 - 0
BMS Master/Project_Headers/MPC5646C.h

@@ -0,0 +1,8473 @@
+/***************************************************************** 
+ *
+ * FILE        : MPC564xBC_V1.0.h
+ * 
+ * DESCRIPTION : This is the header file describing the register
+ *               set for the MPC564xB/C family of devices
+ *
+ * COPYRIGHT   :(c) 2011, Freescale
+ * 
+ * VERSION     : 1.0 (Based on RM Rev2 RC)
+ * DATE        : April 2011 
+ * AUTHOR      : r19325
+ * HISTORY     : Based on MPC5604B, MPC5607B and MPC5668
+ *  0.1 Jun10  : Initial release based on RM RevA, Ver 0.1
+ *  0.2 Jul10  : Corrections based on RM Rev1 Draft D
+ *  0.3 Feb11  : Corrections based on MPC5607B header and RM R2 DraftB
+ *  1.0 Mar11  : 1st official release based on RM Rev2 RC
+ *
+ *
+ * Implementation comments:
+ * -----------------------
+ *
+ * The header file does not include definitions for flexray as the
+ *  expectation is that flexray will be used with drivers
+ *
+ * DSPI implementation supports master mode only
+ *
+ * The register protection registers are not included. These can
+ *  be easily addressed using a macro to reference the existing
+ *  registers which simplifies the protection process. 
+ *
+ * Please report any comments or feedback via the "technical service
+ *  request" tool listed under the support tab at www.freescale.com
+ *
+ *
+ ***************************************************************** 
+ * Copyright:
+ *	Freescale Semiconductor, INC. All Rights Reserved.
+ *  You are hereby granted a copyright license to use, modify, and
+ *  distribute the SOFTWARE so long as this entire notice is
+ *  retained without alteration in any modified and/or redistributed
+ *  versions, and that such modified versions are clearly identified
+ *  as such. No licenses are granted by implication, estoppel or
+ *  otherwise under any patents or trademarks of Freescale
+ *  Semiconductor, Inc. This software is provided on an "AS IS"
+ *  basis and without warranty.
+ *
+ *  To the maximum extent permitted by applicable law, Freescale
+ *  Semiconductor DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
+ *  INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
+ *  PARTICULAR PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
+ *  REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
+ *  AND ANY ACCOMPANYING WRITTEN MATERIALS.
+ *
+ *  To the maximum extent permitted by applicable law, IN NO EVENT
+ *  SHALL Freescale Semiconductor BE LIABLE FOR ANY DAMAGES WHATSOEVER
+ *  (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+ *  BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER
+ *  PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
+ *
+ *  Freescale Semiconductor assumes no responsibility for the
+ *  maintenance and support of this software
+ *
+ ******************************************************************/
+ 
+/*>>>>NOTE! this file is auto-generated please do not edit it!<<<<*/
+
+/***************************************************************** 
+* Example instantiation and use:            
+*                                           
+*  <MODULE>.<REGISTER>.B.<BIT> = 1;         
+*  <MODULE>.<REGISTER>.R       = 0x10000000;
+*                                           
+******************************************************************/
+
+#ifndef _MPC5646x_H_
+#define _MPC5646x_H_
+
+#include "typedefs.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef __MWERKS__
+#pragma push
+#pragma ANSI_strict off
+#endif
+/****************************************************************************/
+/*                     MODULE : CFLASH                                       */
+/****************************************************************************/
+struct CFLASH_tag {
+
+    union { /* Module Configuration (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t EDC:1;
+            vuint32_t :4;
+            vuint32_t SIZE:3;
+            vuint32_t :1;
+            vuint32_t LAS:3;
+            vuint32_t :3;
+            vuint32_t MAS:1;
+            vuint32_t EER:1;
+            vuint32_t RWE:1;
+            vuint32_t :2;
+            vuint32_t PEAS:1;
+            vuint32_t DONE:1;
+            vuint32_t PEG:1;
+            vuint32_t :4;
+            vuint32_t PGM:1;
+            vuint32_t PSUS:1;
+            vuint32_t ERS:1;
+            vuint32_t ESUS:1;
+            vuint32_t EHV:1;
+        } B;
+    } MCR;
+
+    union { /* Low/Mid address block locking (Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t LME:1;
+            vuint32_t :10;
+            vuint32_t TSLK:1;
+            vuint32_t :2;
+            vuint32_t MLK:2;
+            vuint32_t LLK:16;
+        } B;
+    } LML;
+
+    union { /* High address space block locking (Base+0x0008)*/
+        vuint32_t R;
+        struct {
+            vuint32_t HBE:1;
+            vuint32_t :19;
+            vuint32_t HLK:12;
+        } B;
+    } HBL;
+
+    union { /* Secondary Low/Mid block lock (Base+0x000C)*/
+        vuint32_t R;
+        struct {
+            vuint32_t SLE:1;
+            vuint32_t :10;
+            vuint32_t STSLK:1;
+            vuint32_t :2;
+            vuint32_t SMK:2;
+            vuint32_t SLK:16;
+        } B;
+    } SLL;
+
+    union { /* Low/Mid address space block sel (Base+0x0010)*/
+        vuint32_t R;
+        struct {
+            vuint32_t:14;
+            vuint32_t MSL:2;
+            vuint32_t LSL:16;
+        } B;
+    } LMS;
+
+    union { /* High address Space block select (Base+0x0014)*/
+        vuint32_t R;
+        struct {
+            vuint32_t :20;
+            vuint32_t HSL:12;
+        } B;
+    } HBS;
+
+    union { /* Address (Base+0x0018) */
+        vuint32_t R; /* Can't put ADD in array as it runs [3..22] */
+        struct {
+            vuint32_t :9;
+            vuint32_t ADD:20;
+            vuint32_t :3;
+        } B;
+    } ADR;
+
+
+    /* Note the following 3 registers, BIU[0..2] are mirrored to */
+    /*  the code flash configuraiton PFCR[0..2] registers        */
+    /* To make it easier to code, the BIU registers have been    */
+    /*  replaced with the PFCR registers in this header file!    */
+    /* A commented out BIU register is shown for reference!      */
+
+
+    union { /* CFLASH Configuration 0 (Base+0x001C) */
+        vuint32_t R;
+        struct {
+            vuint32_t B02_APC:5;
+            vuint32_t :5; /* vuint32_t B02_WWSC:5; (removed RevD) */
+            vuint32_t B02_RWSC:5;
+            vuint32_t B02_RWWC2:1;
+            vuint32_t B02_RWWC1:1;
+            vuint32_t B02_P1_BCFG:2;
+            vuint32_t B02_P1_DPFE:1;
+            vuint32_t B02_P1_IPFE:1;
+            vuint32_t B02_P1_PFLM:2;
+            vuint32_t B02_P1_BFE:1;
+            vuint32_t B02_RWWC0:1;
+            vuint32_t B02_P0_BCFG:2;
+            vuint32_t B02_P0_DPFE:1;
+            vuint32_t B02_P0_IPFE:1;
+            vuint32_t B02_P0_PFLM:2;
+            vuint32_t B02_P0_BFE:1;
+        } B;
+    } PFCR0;
+    /* Commented out Bus Interface Unit 0 (Base+0x001C) */
+    /*union {              
+
+        vuint32_t R;
+
+        struct {
+
+            vuint32_t BI0:32;
+
+        } B;
+
+    } BIU0;  */
+    union { /* CFLASH Configuration 1 (Base+0x0020) */
+        vuint32_t R;
+        struct {
+            vuint32_t B1_APC:5;
+            vuint32_t B1_WWSC:5;
+            vuint32_t B1_RWSC:5;
+            vuint32_t B1_RWWC2:1;
+            vuint32_t B1_RWWC1:1;
+            vuint32_t :6;
+            vuint32_t B1_P1_BFE:1;
+            vuint32_t B1_RWWC0:1;
+            vuint32_t :6;
+            vuint32_t B1_P0_BFE:1;
+        } B;
+    } PFCR1;
+    /* Commented out Bus Interface Unit 1 (Base+0x0020) */
+    /*union {                 
+
+        vuint32_t R;
+
+        struct {
+
+            vuint32_t BI1:32;
+
+        } B;
+
+    } BIU1; */
+    union { /* CFLASH Access Protection (Base+0x0024) */
+        vuint32_t R;
+        struct {
+            vuint32_t :6;
+            vuint32_t ARBM:2;
+            vuint32_t M7PFD:1;
+            vuint32_t M6PFD:1;
+            vuint32_t M5PFD:1;
+            vuint32_t M4PFD:1;
+            vuint32_t M3PFD:1;
+            vuint32_t M2PFD:1;
+            vuint32_t M1PFD:1;
+            vuint32_t M0PFD:1;
+            vuint32_t M7AP:2;
+            vuint32_t M6AP:2;
+            vuint32_t M5AP:2;
+            vuint32_t M4AP:2;
+            vuint32_t M3AP:2;
+            vuint32_t M2AP:2;
+            vuint32_t M1AP:2;
+            vuint32_t M0AP:2;
+        } B;
+    } PFAPR;
+    /* Commented out Bus Interface Unit 2 (Base+0x0024) */
+    /*union {                
+
+        vuint32_t R;
+
+        struct {
+
+            vuint32_t BI2:32;
+
+        } B;
+
+    } BIU2; */
+    vuint8_t CFLASH_reserved0[20]; /* Reserved 20 Bytes (Base+0x0028-0x003B) */
+
+    union { /* User Test 0 (Base+0x003C) */
+        vuint32_t R;
+        struct {
+            vuint32_t UTE:1;
+            vuint32_t :7;
+            vuint32_t DSI:8;
+            vuint32_t :10;
+            vuint32_t MRE:1;
+            vuint32_t MRV:1;
+            vuint32_t EIE:1;
+            vuint32_t AIS:1;
+            vuint32_t AIE:1;
+            vuint32_t AID:1;
+        } B;
+    } UT0;
+
+    union { /* User Test 1 (Base+0x0040) */
+        vuint32_t R;
+        struct {
+            vuint32_t DAI:32;
+        } B;
+    } UT1;
+
+    union { /* User Test 2 (Base+0x0044) */
+        vuint32_t R;
+        struct {
+            vuint32_t DAI:32;
+        } B;
+    } UT2;
+
+    union { /* User Multiple Input Sig 0..4 (Base+0x0048-0x005B) */
+        vuint32_t R;
+        struct {
+            vuint32_t MS:32;
+        } B;
+    } UMISR[5];
+
+    vuint8_t CFLASH_reserved1[16292]; /* Reserved 16292 (Base+0x005C-0x3FFF)*/
+
+}; /* end of CFLASH_tag */
+/****************************************************************************/
+/*                     MODULE : DFLASH                                       */
+/****************************************************************************/
+struct DFLASH_tag {
+
+    union { /* Module Configuration (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t EDC:1;
+            vuint32_t :4;
+            vuint32_t SIZE:3;
+            vuint32_t :1;
+            vuint32_t LAS:3;
+            vuint32_t :1;
+            vuint32_t MAS:3;
+            vuint32_t EER:1;
+            vuint32_t RWE:1;
+            vuint32_t :2;
+            vuint32_t PEAS:1;
+            vuint32_t DONE:1;
+            vuint32_t PEG:1;
+            vuint32_t :4;
+            vuint32_t PGM:1;
+            vuint32_t PSUS:1;
+            vuint32_t ERS:1;
+            vuint32_t ESUS:1;
+            vuint32_t EHV:1;
+        } B;
+    } MCR;
+
+    union { /* Low/Mid address block locking (Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t LME:1;
+            vuint32_t :10;
+            vuint32_t TSLK:1;
+            vuint32_t :16;
+            vuint32_t LLK:4;
+        } B;
+    } LML;
+
+    vuint8_t DFLASH_reserved0[4]; /* Reserved 4 Bytes (+0x0008-0x000B) */
+
+    union { /* Secondary Low/mid block locking (Base+0x000C)*/
+        vuint32_t R;
+        struct {
+            vuint32_t SLE:1;
+            vuint32_t :10;
+            vuint32_t STSLK:1;
+            vuint32_t :16;
+            vuint32_t SLK:4;
+        } B;
+    } SLL;
+
+    union { /* Low/Mid address space block sel (Base+0x0010)*/
+        vuint32_t R;
+        struct {
+            vuint32_t:28;
+            vuint32_t LSL:4;
+        } B;
+    } LMS;
+
+    vuint8_t DFLASH_reserved1[4]; /* Reserved 4 Bytes (+0x0014-0x0017) */
+
+    union { /* Address (Base+0x0018) */
+        vuint32_t R; /* Can't put ADD in array as it runs [2..22] */
+        struct {
+            vuint32_t :9;
+            vuint32_t ADD:21;
+            vuint32_t :2;
+        } B;
+    } ADR;
+
+    vuint8_t DFLASH_reserved2[32]; /* Reserved 32 Bytes (+0x001C-0x003B) */
+
+    union { /* User Test 0 (Base+0x003C) */
+        vuint32_t R;
+        struct {
+            vuint32_t UTE:1;
+            vuint32_t :8;
+            vuint32_t DSI:7;
+            vuint32_t :10;
+            vuint32_t MRE:1;
+            vuint32_t MRV:1;
+            vuint32_t EIE:1;
+            vuint32_t AIS:1;
+            vuint32_t AIE:1;
+            vuint32_t AID:1;
+        } B;
+    } UT0;
+
+    union { /* User Test 1 (Base+0x0040) */
+        vuint32_t R;
+        struct {
+            vuint32_t DAI:32;
+        } B;
+    } UT1;
+
+    vuint8_t DFLASH_reserved3[4]; /* Reserved 4 Bytes (+0x0044-0x0047) */
+
+    union { /* User Multiple Input sig 0..1 (+0x0048-0x004F)*/
+        vuint32_t R;
+        struct {
+            vuint32_t MS:32;
+        } B;
+    } UMISR[2];
+
+}; /* end of DFLASH_tag */
+/****************************************************************************/
+/*          MODULE : SIU Lite (tagged as SIU for compatibility)             */
+/****************************************************************************/
+struct SIU_tag {
+
+    vuint8_t SIU_reserved0[4]; /* Reserved 4 Bytes (Base+0x0) */
+
+    union { /* MCU ID1 (Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t PARTNUM:16;
+            vuint32_t CSP:1;
+            vuint32_t PKG:5;
+            vuint32_t :2;
+            vuint32_t MAJOR_MASK:4;
+            vuint32_t MINOR_MASK:4;
+        } B;
+    } MIDR1;
+
+    union { /* MCU ID2 (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t SF:1;
+            vuint32_t FLASH_SIZE_1:4;
+            vuint32_t FLASH_SIZE_2:4;
+            vuint32_t :7;
+            vuint32_t PARTNUM:8;
+            vuint32_t :3;
+            vuint32_t EE:1;
+            vuint32_t :3;
+            vuint32_t FR:1;
+        } B;
+    } MIDR2;
+
+    vuint8_t SIU_reserved1[8]; /* Reserved 8 Bytes (Base+(0x000C--0x0013)) */
+
+    union { /* Interrupt Status Flag (Base+0x0014)*/
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t EIF23:1;
+            vuint32_t EIF22:1;
+            vuint32_t EIF21:1;
+            vuint32_t EIF20:1;
+            vuint32_t EIF19:1;
+            vuint32_t EIF18:1;
+            vuint32_t EIF17:1;
+            vuint32_t EIF16:1;
+            vuint32_t EIF15:1;
+            vuint32_t EIF14:1;
+            vuint32_t EIF13:1;
+            vuint32_t EIF12:1;
+            vuint32_t EIF11:1;
+            vuint32_t EIF10:1;
+            vuint32_t EIF9:1;
+            vuint32_t EIF8:1;
+            vuint32_t EIF7:1;
+            vuint32_t EIF6:1;
+            vuint32_t EIF5:1;
+            vuint32_t EIF4:1;
+            vuint32_t EIF3:1;
+            vuint32_t EIF2:1;
+            vuint32_t EIF1:1;
+            vuint32_t EIF0:1;
+        } B;
+    } ISR;
+
+    union { /* Interrupt Request Enable (Base+0x0018) */
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t EIRE23:1;
+            vuint32_t EIRE22:1;
+            vuint32_t EIRE21:1;
+            vuint32_t EIRE20:1;
+            vuint32_t EIRE19:1;
+            vuint32_t EIRE18:1;
+            vuint32_t EIRE17:1;
+            vuint32_t EIRE16:1;
+            vuint32_t EIRE15:1;
+            vuint32_t EIRE14:1;
+            vuint32_t EIRE13:1;
+            vuint32_t EIRE12:1;
+            vuint32_t EIRE11:1;
+            vuint32_t EIRE10:1;
+            vuint32_t EIRE9:1;
+            vuint32_t EIRE8:1;
+            vuint32_t EIRE7:1;
+            vuint32_t EIRE6:1;
+            vuint32_t EIRE5:1;
+            vuint32_t EIRE4:1;
+            vuint32_t EIRE3:1;
+            vuint32_t EIRE2:1;
+            vuint32_t EIRE1:1;
+            vuint32_t EIRE0:1;
+        } B;
+    } IRER;
+
+    vuint8_t SIU_reserved2[12]; /* Reserved 12 Bytes (Base+0x001C-0x0027) */
+
+    union { /* Interrupt Rising-Edge Event Enable (+0x0028) */
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t IREE23:1;
+            vuint32_t IREE22:1;
+            vuint32_t IREE21:1;
+            vuint32_t IREE20:1;
+            vuint32_t IREE19:1;
+            vuint32_t IREE18:1;
+            vuint32_t IREE17:1;
+            vuint32_t IREE16:1;
+            vuint32_t IREE15:1;
+            vuint32_t IREE14:1;
+            vuint32_t IREE13:1;
+            vuint32_t IREE12:1;
+            vuint32_t IREE11:1;
+            vuint32_t IREE10:1;
+            vuint32_t IREE9:1;
+            vuint32_t IREE8:1;
+            vuint32_t IREE7:1;
+            vuint32_t IREE6:1;
+            vuint32_t IREE5:1;
+            vuint32_t IREE4:1;
+            vuint32_t IREE3:1;
+            vuint32_t IREE2:1;
+            vuint32_t IREE1:1;
+            vuint32_t IREE0:1;
+        } B;
+    } IREER;
+
+    union { /* Interrupt Falling-Edge Event Enable (+0x002C)*/
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t IFEE23:1;
+            vuint32_t IFEE22:1;
+            vuint32_t IFEE21:1;
+            vuint32_t IFEE20:1;
+            vuint32_t IFEE19:1;
+            vuint32_t IFEE18:1;
+            vuint32_t IFEE17:1;
+            vuint32_t IFEE16:1;
+            vuint32_t IFEE15:1;
+            vuint32_t IFEE14:1;
+            vuint32_t IFEE13:1;
+            vuint32_t IFEE12:1;
+            vuint32_t IFEE11:1;
+            vuint32_t IFEE10:1;
+            vuint32_t IFEE9:1;
+            vuint32_t IFEE8:1;
+            vuint32_t IFEE7:1;
+            vuint32_t IFEE6:1;
+            vuint32_t IFEE5:1;
+            vuint32_t IFEE4:1;
+            vuint32_t IFEE3:1;
+            vuint32_t IFEE2:1;
+            vuint32_t IFEE1:1;
+            vuint32_t IFEE0:1;
+        } B;
+    } IFEER;
+
+    union { /* Interrupt Filter Enable (Base+0x0030) */
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t IFE23:1;
+            vuint32_t IFE22:1;
+            vuint32_t IFE21:1;
+            vuint32_t IFE20:1;
+            vuint32_t IFE19:1;
+            vuint32_t IFE18:1;
+            vuint32_t IFE17:1;
+            vuint32_t IFE16:1;
+            vuint32_t IFE15:1;
+            vuint32_t IFE14:1;
+            vuint32_t IFE13:1;
+            vuint32_t IFE12:1;
+            vuint32_t IFE11:1;
+            vuint32_t IFE10:1;
+            vuint32_t IFE9:1;
+            vuint32_t IFE8:1;
+            vuint32_t IFE7:1;
+            vuint32_t IFE6:1;
+            vuint32_t IFE5:1;
+            vuint32_t IFE4:1;
+            vuint32_t IFE3:1;
+            vuint32_t IFE2:1;
+            vuint32_t IFE1:1;
+            vuint32_t IFE0:1;
+        } B;
+    } IFER;
+
+    vuint8_t SIU_reserved3[12]; /* Reserved 12 Bytes (Base+0x0034-0x003F) */
+
+    union { /* Pad Configuration 0..198 (Base+0x0040-0x01CD)*/
+        vuint16_t R;
+        struct {
+            vuint16_t :1;
+            vuint16_t SMC:1;
+            vuint16_t APC:1;
+            vuint16_t PA:3;
+            vuint16_t OBE:1;
+            vuint16_t IBE:1;
+            vuint16_t :2; /* vuint16_t DSC:2; */
+            vuint16_t ODE:1;
+            vuint16_t :2; /* vuint16_t HYS:1; */
+            vuint16_t SRC:1;
+            vuint16_t WPE:1;
+            vuint16_t WPS:1;
+        } B;
+    } PCR[199];
+
+    vuint8_t SIU_reserved4[818]; /*Reserved 818 Bytes (Base+0x01CE-0x04FF) */
+
+    union { /* Pad Selection for Mux Input (0x0500-0x543) */
+        vuint8_t R;
+        struct {
+            vuint8_t :4;
+            vuint8_t PADSEL:4;
+        } B;
+    } PSMI[68];
+
+    vuint8_t SIU_reserved5[188]; /*Reserved 188 Bytes (Base+0x0544-0x05FF) */
+
+    union { /* GPIO Pad Data Output (Base+0x0600-0x06C7) */
+        vuint8_t R;
+        struct {
+            vuint8_t :7;
+            vuint8_t PDO:1;
+        } B;
+    } GPDO[200];
+
+    vuint8_t SIU_reserved6[312]; /*Reserved 312 Bytes (Base+0x06C8-0x07FF) */
+
+    union { /* GPIO Pad Data Input (Base+0x0800-0x08C7) */
+        vuint8_t R;
+        struct {
+            vuint8_t :7;
+            vuint8_t PDI:1;
+        } B;
+    } GPDI[200];
+
+    vuint8_t SIU_reserved7[824]; /*Reserved 824 Bytes (Base+0x08C8-0x0BFF) */
+
+    union { /* Parallel GPIO Pad Data Out 0-6 (0x0C00-0xC018) */
+        vuint32_t R;
+        struct {
+            vuint32_t PPDO:32;
+        } B;
+    } PGPDO[7];
+
+    vuint8_t SIU_reserved8[36]; /* Reserved 36 Bytes (Base+0x0C1C-0x0C3F) */
+
+    union { /* Parallel GPIO Pad Data In 0-6 (0x0C40-0x0C58) */
+        vuint32_t R;
+        struct {
+            vuint32_t PPDI:32;
+        } B;
+    } PGPDI[7];
+
+    vuint8_t SIU_reserved9[36]; /* Reserved 36 Bytes (Base+0x0C5C-0x0C7F) */
+
+    union { /* Masked Parallel GPIO Pad Data Out 0-12 (0x0C80-0x0CB0) */
+        vuint32_t R;
+        struct {
+            vuint32_t MASK:16;
+            vuint32_t MPPDO:16;
+        } B;
+    } MPGPDO[13];
+
+    vuint8_t SIU_reserved10[844]; /*Reserved 844 Bytes (Base+0x0CB4-0x0FFF)*/
+
+    union { /* Interrupt Filter Max Counter 0..23 (+0x1000-0x105C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :28;
+            vuint32_t MAXCNT:4;
+        } B;
+    } IFMC[24];
+
+    vuint8_t SIU_reserved11[32]; /* Reserved 32 Bytes (Base+0x1060-0x107F) */
+
+    union { /* Interrupt Filter Clock Prescaler (Base+0x1080) */
+        vuint32_t R;
+        struct {
+            vuint32_t :28;
+            vuint32_t IFCP:4;
+        } B;
+    } IFCPR;
+
+    vuint8_t SIU_reserved12[124]; /* Reserved 124 Bytes (+0x1084-0x10FF)   */
+
+
+ /* PISR group 1 (eMIOS 0 to DSPI 0)                                     */
+
+    union { /* Parallel Input Select 0 (Base+0x1100)        */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS0:4;
+            vuint32_t IPS1:4;
+            vuint32_t IPS2:4;
+            vuint32_t IPS3:4;
+            vuint32_t IPS4:4;
+            vuint32_t IPS5:4;
+            vuint32_t IPS6:4;
+            vuint32_t IPS7:4;
+        } B;
+    } PISR0;
+
+    union { /* Parallel Input Select 1 (Base+0x1104)        */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS8:4;
+            vuint32_t IPS9:4;
+            vuint32_t IPS10:4;
+            vuint32_t IPS11:4;
+            vuint32_t IPS12:4;
+            vuint32_t IPS13:4;
+            vuint32_t IPS14:4;
+            vuint32_t IPS15:4;
+        } B;
+    } PISR1;
+
+    union { /* Parallel Input Select 2 (Base+0x1108)        */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS16:4;
+            vuint32_t IPS17:4;
+            vuint32_t IPS18:4;
+            vuint32_t IPS19:4;
+            vuint32_t IPS20:4;
+            vuint32_t IPS21:4;
+            vuint32_t IPS22:4;
+            vuint32_t IPS23:4;
+        } B;
+    } PISR2;
+
+    union { /* Parallel Input Select 3 (Base+0x110C)        */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS24:4;
+            vuint32_t IPS25:4;
+            vuint32_t IPS26:4;
+            vuint32_t IPS27:4;
+            vuint32_t IPS28:4;
+            vuint32_t IPS29:4;
+            vuint32_t IPS30:4;
+            vuint32_t IPS31:4;
+        } B;
+    } PISR3;
+
+ /* PISR group 2 (eMIOS 1 to DSPI 1)                                     */
+
+   union { /* Parallel Input Select 4 (Base+0x1110)        */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS0:4;
+            vuint32_t IPS1:4;
+            vuint32_t IPS2:4;
+            vuint32_t IPS3:4;
+            vuint32_t IPS4:4;
+            vuint32_t IPS5:4;
+            vuint32_t IPS6:4;
+            vuint32_t IPS7:4;
+        } B;
+    } PISR4;
+
+    union { /* Parallel Input Select 5 (Base+0x1114)        */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS8:4;
+            vuint32_t IPS9:4;
+            vuint32_t IPS10:4;
+            vuint32_t IPS11:4;
+            vuint32_t IPS12:4;
+            vuint32_t IPS13:4;
+            vuint32_t IPS14:4;
+            vuint32_t IPS15:4;
+        } B;
+    } PISR5;
+
+    union { /* Parallel Input Select 6 (Base+0x1118)        */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS16:4;
+            vuint32_t IPS17:4;
+            vuint32_t IPS18:4;
+            vuint32_t IPS19:4;
+            vuint32_t IPS20:4;
+            vuint32_t IPS21:4;
+            vuint32_t IPS22:4;
+            vuint32_t IPS23:4;
+        } B;
+    } PISR6;
+
+    union { /* Parallel Input Select 7 (Base+0x111C)        */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS24:4;
+            vuint32_t IPS25:4;
+            vuint32_t IPS26:4;
+            vuint32_t IPS27:4;
+            vuint32_t IPS28:4;
+            vuint32_t IPS29:4;
+            vuint32_t IPS30:4;
+            vuint32_t IPS31:4;
+        } B;
+    } PISR7;
+
+ /* PISR group 3 (eMIOS 0 to DSPI 3)                                     */
+
+   union { /* Parallel Input Select 8 (Base+0x1120)        */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS0:4;
+            vuint32_t IPS1:4;
+            vuint32_t IPS2:4;
+            vuint32_t IPS3:4;
+            vuint32_t IPS4:4;
+            vuint32_t IPS5:4;
+            vuint32_t IPS6:4;
+            vuint32_t IPS7:4;
+        } B;
+    } PISR8;
+
+    union { /* Parallel Input Select 9 (Base+0x1124)        */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS8:4;
+            vuint32_t IPS9:4;
+            vuint32_t IPS10:4;
+            vuint32_t IPS11:4;
+            vuint32_t IPS12:4;
+            vuint32_t IPS13:4;
+            vuint32_t IPS14:4;
+            vuint32_t IPS15:4;
+        } B;
+    } PISR9;
+
+    union { /* Parallel Input Select 10 (Base+0x1128)       */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS16:4;
+            vuint32_t IPS17:4;
+            vuint32_t IPS18:4;
+            vuint32_t IPS19:4;
+            vuint32_t IPS20:4;
+            vuint32_t IPS21:4;
+            vuint32_t IPS22:4;
+            vuint32_t IPS23:4;
+        } B;
+    } PISR10;
+
+    union { /* Parallel Input Select 11 (Base+0x112C)       */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS24:4;
+            vuint32_t IPS25:4;
+            vuint32_t IPS26:4;
+            vuint32_t IPS27:4;
+            vuint32_t IPS28:4;
+            vuint32_t IPS29:4;
+            vuint32_t IPS30:4;
+            vuint32_t IPS31:4;
+        } B;
+    } PISR11;
+
+ /* PISR group 4 (eMIOS 1 to DSPI 4)                                     */
+
+   union { /* Parallel Input Select 12 (Base+0x1130)        */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS0:4;
+            vuint32_t IPS1:4;
+            vuint32_t IPS2:4;
+            vuint32_t IPS3:4;
+            vuint32_t IPS4:4;
+            vuint32_t IPS5:4;
+            vuint32_t IPS6:4;
+            vuint32_t IPS7:4;
+        } B;
+    } PISR12;
+
+    union { /* Parallel Input Select 13 (Base+0x1134)        */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS8:4;
+            vuint32_t IPS9:4;
+            vuint32_t IPS10:4;
+            vuint32_t IPS11:4;
+            vuint32_t IPS12:4;
+            vuint32_t IPS13:4;
+            vuint32_t IPS14:4;
+            vuint32_t IPS15:4;
+        } B;
+    } PISR13;
+
+    union { /* Parallel Input Select 14 (Base+0x1138)       */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS16:4;
+            vuint32_t IPS17:4;
+            vuint32_t IPS18:4;
+            vuint32_t IPS19:4;
+            vuint32_t IPS20:4;
+            vuint32_t IPS21:4;
+            vuint32_t IPS22:4;
+            vuint32_t IPS23:4;
+        } B;
+    } PISR14;
+
+    union { /* Parallel Input Select 15 (Base+0x113C)       */
+        vuint32_t R;
+        struct {
+            vuint32_t IPS24:4;
+            vuint32_t IPS25:4;
+            vuint32_t IPS26:4;
+            vuint32_t IPS27:4;
+            vuint32_t IPS28:4;
+            vuint32_t IPS29:4;
+            vuint32_t IPS30:4;
+            vuint32_t IPS31:4;
+        } B;
+    } PISR15;
+
+
+    vuint8_t SIU_reserved13[192]; /*Reserved 192 Bytes (Base+0x1140-0x11FF)*/
+
+    union { /* DSPI Input Select (Base+0x1200) */
+        vuint32_t R;
+        struct {
+            vuint32_t SINSEL0:2;
+            vuint32_t SSSSEL0:2;
+            vuint32_t SCKSEL0:2;
+            vuint32_t TRIGSEL0:2;
+            vuint32_t SINSEL1:2;
+            vuint32_t SSSSEL1:2;
+            vuint32_t SCKSEL1:2;
+            vuint32_t TRIGSEL1:2;
+            vuint32_t SINSEL2:2;
+            vuint32_t SSSSEL2:2;
+            vuint32_t SCKSEL2:2;
+            vuint32_t TRIGSEL2:2;
+            vuint32_t SINSEL3:2;
+            vuint32_t SSSSEL3:2;
+            vuint32_t SCKSEL3:2;
+            vuint32_t TRIGSEL3:2;
+        } B;
+    } DISR;
+
+}; /* end of SIU_tag */
+/****************************************************************************/
+/*                          MODULE : WKUP                                   */
+/****************************************************************************/
+struct WKUP_tag{
+
+    union { /* NMI Status Flag (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t NIF0:1;
+            vuint32_t NOVF0:1;
+            vuint32_t :6;
+            vuint32_t NIF1:1;
+            vuint32_t NOVF1:1;
+            vuint32_t :22;
+        } B;
+    } NSR;
+
+    vuint8_t WKUP_reserved0[4]; /* Reserved 4 Bytes (Base+0x0004-0x0007) */
+
+    union { /* NMI Configuration (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t NLOCK0:1;
+            vuint32_t NDSS0:2;
+            vuint32_t NWRE0:1;
+            vuint32_t :1;
+            vuint32_t NREE0:1;
+            vuint32_t NFEE0:1;
+            vuint32_t NFE0:1;
+            vuint32_t NLOCK1:1;
+            vuint32_t NDSS1:2;
+            vuint32_t NWRE1:1;
+            vuint32_t :1;
+            vuint32_t NREE1:1;
+            vuint32_t NFEE1:1;
+            vuint32_t NFE1:1;
+            vuint32_t :16;
+        } B;
+    } NCR;
+
+    vuint8_t WKUP_reserved1[8]; /* Reserved 8 Bytes (Base+0x000C-0x0013) */
+
+    union { /* Wakeup/Interrup status flag (Base+0x0014) */
+        vuint32_t R;
+        struct {
+            vuint32_t EIF:32;
+        } B;
+    } WISR;
+
+    union { /* Interrupt Request Enable (Base+0x0018) */
+        vuint32_t R;
+        struct {
+            vuint32_t EIRE:32;
+        } B;
+    } IRER;
+
+    union { /* Wakeup Request Enable (Base+0x001C) */
+        vuint32_t R;
+        struct {
+            vuint32_t WRE:32;
+        } B;
+    } WRER;
+
+    vuint8_t WKUP_reserved2[8]; /* Reserved 8 Bytes (Base+0x0020-0x0027) */
+
+    union { /* Wakeup/Interrupt Rising-Edge (Base+0x0028) */
+        vuint32_t R;
+        struct {
+            vuint32_t IREE:32;
+        } B;
+    } WIREER;
+
+    union { /* Wakeup/Interrupt Falling-Edge (Base+0x002C) */
+        vuint32_t R;
+        struct {
+            vuint32_t IFEE:32;
+        } B;
+    } WIFEER;
+
+    union { /* Wakeup/Interrupt Filter Enable (Base+0x0030) */
+        vuint32_t R;
+        struct {
+            vuint32_t IFE:32;
+        } B;
+    } WIFER;
+
+    union { /* Wakeup/Interrupt Pullup Enable (Base+0x0034) */
+        vuint32_t R;
+        struct {
+            vuint32_t IPUE:32;
+        } B;
+    } WIPUER; /* Wakeup/Interrupt Pullup Enable Register */
+
+    vuint8_t WKUP_reserved3[16328]; /* Reserved 16328 (Base+0x0038-0x3FFF) */
+
+}; /* end of WKUP_tag */
+/****************************************************************************/
+/*                          MODULE : EMIOS                                  */
+/****************************************************************************/
+
+struct EMIOS_CHANNEL_tag{
+
+    union { /* Channel A Data (UCn Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t A:16;
+        } B;
+    } CADR;
+
+    union { /* Channel B Data (UCn Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t B:16;
+        } B;
+    } CBDR;
+
+    union { /* Channel Counter (UCn Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t C:16;
+        } B;
+    } CCNTR;
+
+    union { /* Channel Control (UCn Base+0x000C) */
+        vuint32_t R;
+        struct {
+            vuint32_t FREN:1;
+            vuint32_t :3;
+            vuint32_t UCPRE:2;
+            vuint32_t UCPEN:1;
+            vuint32_t DMA:1;
+            vuint32_t :1;
+            vuint32_t IF:4;
+            vuint32_t FCK:1;
+            vuint32_t FEN:1;
+            vuint32_t :3;
+            vuint32_t FORCMA:1;
+            vuint32_t FORCMB:1;
+            vuint32_t :1;
+            vuint32_t BSL:2;
+            vuint32_t EDSEL:1;
+            vuint32_t EDPOL:1;
+            vuint32_t MODE:7;
+        } B;
+    } CCR;
+
+    union { /* Channel Status (UCn Base+0x0010) */
+        vuint32_t R;
+        struct {
+            vuint32_t OVR:1;
+            vuint32_t :15;
+            vuint32_t OVFL:1;
+            vuint32_t :12;
+            vuint32_t UCIN:1;
+            vuint32_t UCOUT:1;
+            vuint32_t FLAG:1;
+        } B;
+    } CSR;
+
+    union { /* Alternate Channel A Data (UCn Base+0x0014) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t ALTA:16;
+        } B;
+    } ALTCADR;
+
+    vuint8_t EMIOS_CHANNEL_reserved0[8]; /* (UCn Base + (0x0018-0x001F) */
+
+}; /* end of EMIOS_CHANNEL_tag */
+
+
+struct EMIOS_tag{
+
+    union { /* Module Configuration (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t :1;
+            vuint32_t MDIS:1;
+            vuint32_t FRZ:1;
+            vuint32_t GTBE:1;
+            vuint32_t :1;
+            vuint32_t GPREN:1;
+            vuint32_t :10;
+            vuint32_t GPRE:8;
+            vuint32_t :8;
+        } B;
+    } MCR;
+
+    union { /* Global Flag (Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t F31:1;
+            vuint32_t F30:1;
+            vuint32_t F29:1;
+            vuint32_t F28:1;
+            vuint32_t F27:1;
+            vuint32_t F26:1;
+            vuint32_t F25:1;
+            vuint32_t F24:1;
+            vuint32_t F23:1;
+            vuint32_t F22:1;
+            vuint32_t F21:1;
+            vuint32_t F20:1;
+            vuint32_t F19:1;
+            vuint32_t F18:1;
+            vuint32_t F17:1;
+            vuint32_t F16:1;
+            vuint32_t F15:1;
+            vuint32_t F14:1;
+            vuint32_t F13:1;
+            vuint32_t F12:1;
+            vuint32_t F11:1;
+            vuint32_t F10:1;
+            vuint32_t F9:1;
+            vuint32_t F8:1;
+            vuint32_t F7:1;
+            vuint32_t F6:1;
+            vuint32_t F5:1;
+            vuint32_t F4:1;
+            vuint32_t F3:1;
+            vuint32_t F2:1;
+            vuint32_t F1:1;
+            vuint32_t F0:1;
+        } B;
+    } GFR;
+
+    union { /* Output Update Disable (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t OU31:1;
+            vuint32_t OU30:1;
+            vuint32_t OU29:1;
+            vuint32_t OU28:1;
+            vuint32_t OU27:1;
+            vuint32_t OU26:1;
+            vuint32_t OU25:1;
+            vuint32_t OU24:1;
+            vuint32_t OU23:1;
+            vuint32_t OU22:1;
+            vuint32_t OU21:1;
+            vuint32_t OU20:1;
+            vuint32_t OU19:1;
+            vuint32_t OU18:1;
+            vuint32_t OU17:1;
+            vuint32_t OU16:1;
+            vuint32_t OU15:1;
+            vuint32_t OU14:1;
+            vuint32_t OU13:1;
+            vuint32_t OU12:1;
+            vuint32_t OU11:1;
+            vuint32_t OU10:1;
+            vuint32_t OU9:1;
+            vuint32_t OU8:1;
+            vuint32_t OU7:1;
+            vuint32_t OU6:1;
+            vuint32_t OU5:1;
+            vuint32_t OU4:1;
+            vuint32_t OU3:1;
+            vuint32_t OU2:1;
+            vuint32_t OU1:1;
+            vuint32_t OU0:1;
+        } B;
+    } OUDR;
+
+    union { /* Disable Channel (Base+0x000F) */
+        vuint32_t R;
+        struct {
+            vuint32_t CHDIS31:1;
+            vuint32_t CHDIS30:1;
+            vuint32_t CHDIS29:1;
+            vuint32_t CHDIS28:1;
+            vuint32_t CHDIS27:1;
+            vuint32_t CHDIS26:1;
+            vuint32_t CHDIS25:1;
+            vuint32_t CHDIS24:1;
+            vuint32_t CHDIS23:1;
+            vuint32_t CHDIS22:1;
+            vuint32_t CHDIS21:1;
+            vuint32_t CHDIS20:1;
+            vuint32_t CHDIS19:1;
+            vuint32_t CHDIS18:1;
+            vuint32_t CHDIS17:1;
+            vuint32_t CHDIS16:1;
+            vuint32_t CHDIS15:1;
+            vuint32_t CHDIS14:1;
+            vuint32_t CHDIS13:1;
+            vuint32_t CHDIS12:1;
+            vuint32_t CHDIS11:1;
+            vuint32_t CHDIS10:1;
+            vuint32_t CHDIS9:1;
+            vuint32_t CHDIS8:1;
+            vuint32_t CHDIS7:1;
+            vuint32_t CHDIS6:1;
+            vuint32_t CHDIS5:1;
+            vuint32_t CHDIS4:1;
+            vuint32_t CHDIS3:1;
+            vuint32_t CHDIS2:1;
+            vuint32_t CHDIS1:1;
+            vuint32_t CHDIS0:1;
+        } B;
+    } UCDIS;
+
+    vuint8_t EMIOS_reserved0[16]; /* Reserved 16 Bytes (Base+0x0010-0x001F) */
+
+    struct EMIOS_CHANNEL_tag CH[32]; /* Add in 32 unified channels */
+
+    vuint8_t EMIOS_reserved1[3040]; /* 3040 bytes (Base+0x0420-0x0FFF) */
+
+}; /* end of EMIOS_tag */
+/****************************************************************************/
+/*                          MODULE : SSCM                                   */
+/****************************************************************************/
+struct SSCM_tag{
+
+    union { /* Status (Base+0x0000) */
+        vuint16_t R;
+        struct {
+            vuint16_t :1;
+            vuint16_t CER:1;
+            vuint16_t :1;
+            vuint16_t Z4_NXEN:1;
+            vuint16_t Z0_NXEN:1;
+            vuint16_t PUB:1;
+            vuint16_t SEC:1;
+            vuint16_t :1;
+            vuint16_t BMODE:3;
+            vuint16_t VLE:1;
+            vuint16_t :4;
+        } B;
+    } STATUS;
+
+    union { /* System Memory Configuration (Base+0x002) */
+        vuint16_t R;
+        struct {
+            vuint16_t JPIN:10;
+            vuint16_t ILVD:1;
+            vuint16_t MREV:4;
+            vuint16_t DVLD:1;
+        } B;
+    } MEMCONFIG;
+
+    vuint8_t SSCM_reserved0[2]; /* Reserved 2 bytes (Base+0x0004-0x0005) */
+
+    union { /* Error Configuration (Base+0x0006) */
+        vuint16_t R;
+        struct {
+            vuint16_t :14;
+            vuint16_t PAE:1;
+            vuint16_t RAE:1;
+        } B;
+    } ERROR;
+
+   union { /* Debug Status Port (Base+0x0008) */
+        vuint16_t R;
+        struct {
+            vuint16_t :13;
+            vuint16_t DEBUG_MODE:3;
+        } B;
+    } DEBUGPORT;
+
+    vuint8_t SSCM_reserved1[2]; /* Reserved 2 bytes (Base+0x000A-0x000B) */
+
+    union { /* Password Comparison High Word (Base+0x000C) */
+      vuint32_t R;
+      struct {
+            vuint32_t PWD_HI:32;
+        } B;
+    } PWCMPH;
+
+    union { /* Password Comparison Low Word (Base+0x0010)*/
+        vuint32_t R;
+        struct {
+            vuint32_t PWD_LO:32;
+        } B;
+    } PWCMPL;
+
+    vuint8_t SSCM_reserved2[4]; /* Reserved 4 bytes (Base+0x0014-0x0017) */
+
+    union { /* DPM Boot (Base+0x0018)*/
+        vuint32_t R;
+        struct {
+            vuint32_t PBOOT:30;
+            vuint32_t DVLE:1;
+            vuint32_t :1;
+        } B;
+    } DPMBOOT;
+
+    union { /* DPM Boot Key (Base+0x001C)*/
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t KEY:16;
+        } B;
+    } DPMKEY;
+
+    union { /* User option status (Base+0x0020)*/
+        vuint32_t R;
+        struct {
+            vuint32_t UOPT:32;
+        } B;
+    } UOPS;
+
+    vuint8_t SSCM_reserved3[4]; /* Reserved 4 bytes (Base+0x0024-0x0027) */
+
+   union { /* Processor Start Address (Base+0x0028)*/
+        vuint32_t R;
+        struct {
+            vuint32_t SADR:32;
+        } B;
+    } PSA;
+
+   union { /* Code Length (Base+0x002C)*/
+        vuint32_t R;
+        struct {
+            vuint32_t CL:32;
+        } B;
+    } CLEN;
+
+
+
+}; /* end of SSCM_tag */
+/****************************************************************************/
+/*                          MODULE : ME                                   */
+/****************************************************************************/
+struct ME_tag{
+
+    union { /* Global Status (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t S_CURRENTMODE:4;
+            vuint32_t S_MTRANS:1;
+            vuint32_t :1; /*  vuint32_t S_DC:1; (Not on B3M) */
+            vuint32_t :2;
+            vuint32_t S_PDO:1;
+            vuint32_t :2;
+            vuint32_t S_MVR:1;
+            vuint32_t S_DFLA:2;
+            vuint32_t S_CFLA:2;
+            vuint32_t :9;
+            vuint32_t S_FMPLL:1;
+            vuint32_t S_FXOSC:1;
+            vuint32_t S_FIRC:1;
+            vuint32_t S_SYSCLK:4;
+        } B;
+    } GS;
+
+    union { /* Mode Control (Base+0x004) */
+        vuint32_t R;
+        struct {
+            vuint32_t TARGET_MODE:4;
+            vuint32_t :12;
+             vuint32_t KEY:16;
+        } B;
+    } MCTL;
+
+    union { /* Mode Enable (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t RESET_DEST:1;
+            vuint32_t :1;
+            vuint32_t STANDBY:1;
+            vuint32_t :2;
+            vuint32_t STOP:1;
+            vuint32_t :1;
+            vuint32_t HALT:1;
+            vuint32_t RUN3:1;
+            vuint32_t RUN2:1;
+            vuint32_t RUN1:1;
+            vuint32_t RUN0:1;
+            vuint32_t DRUN:1;
+            vuint32_t SAFE:1;
+            vuint32_t TEST:1;
+            vuint32_t RESET:1;
+        } B;
+    } MER;
+
+    union { /* Interrupt Status (Base+0x000C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :28;
+            vuint32_t I_ICONF:1;
+            vuint32_t I_IMODE:1;
+            vuint32_t I_SAFE:1;
+            vuint32_t I_MTC:1;
+        } B;
+    } IS;
+
+    union { /* Interrupt Mask (Base+0x0010) */
+        vuint32_t R;
+        struct {
+            vuint32_t :27;
+            vuint32_t M_ICONF_CU:1;
+            vuint32_t M_ICONF:1;
+            vuint32_t M_IMODE:1;
+            vuint32_t M_SAFE:1;
+            vuint32_t M_MTC:1;
+        } B;
+    } IM;
+
+    union { /* Invalid Mode Transition Status (Base+0x0014) */
+        vuint32_t R;
+        struct {
+            vuint32_t :27;
+            vuint32_t S_MTI:1;
+            vuint32_t S_MRI:1;
+            vuint32_t S_DMA:1;
+            vuint32_t S_NMA:1;
+            vuint32_t S_SEA:1;
+        } B;
+    } IMTS;
+
+    union { /* Debug Mode Transition Status (Base+0x0018) */
+        vuint32_t R;
+        struct {
+            vuint32_t PREVIOUS_MODE:4;
+            vuint32_t :4;
+            vuint32_t MPH_BUSY:1;
+            vuint32_t :2;
+            vuint32_t PMC_PROG:1;
+            vuint32_t CORE_DBG:1;
+            vuint32_t :2;
+            vuint32_t SMR:1;
+            vuint32_t :1;
+            vuint32_t VREG_CSRC_SC:1;
+            vuint32_t CSRC_CSRC_SC:1;
+            vuint32_t FIRC_SC:1;
+            vuint32_t SCSRC_SC:1;
+            vuint32_t SYSCLK_SW:1;
+            vuint32_t DFLASH_SC:1;
+            vuint32_t CFLASH_SC:1;
+            vuint32_t CDP_PRPH_0_143:1;
+            vuint32_t :3;
+            vuint32_t CDP_PRPH_96_127:1;
+            vuint32_t CDP_PRPH_64_95:1;
+            vuint32_t CDP_PRPH_32_63:1;
+            vuint32_t CDP_PRPH_0_31:1;
+        } B;
+    } DMTS;
+
+    vuint8_t ME_reserved0[4]; /* reserved 4 bytes (Base+0x001C-0x001F) */
+
+    union { /* Reset Mode Configuration (Base+0x0020) */
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t PDO:1;
+            vuint32_t :2;
+            vuint32_t MVRON:1;
+            vuint32_t DFLAON:2;
+            vuint32_t CFLAON:2;
+            vuint32_t :9;
+            vuint32_t FMPLLON:1;
+            vuint32_t FXOSC0ON:1;
+            vuint32_t FIRCON:1;
+            vuint32_t SYSCLK:4;
+        } B;
+    } RESET;
+
+    union { /* Test Mode Configuration (Base+0x0024) */
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t PDO:1;
+            vuint32_t :2;
+            vuint32_t MVRON:1;
+            vuint32_t DFLAON:2;
+            vuint32_t CFLAON:2;
+            vuint32_t :9;
+            vuint32_t FMPLLON:1;
+            vuint32_t FXOSC0ON:1;
+            vuint32_t FIRCON:1;
+            vuint32_t SYSCLK:4;
+        } B;
+    } TEST;
+
+    union { /* Safe Mode Configuration (Base+0x0028) */
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t PDO:1;
+            vuint32_t :2;
+            vuint32_t MVRON:1;
+            vuint32_t DFLAON:2;
+            vuint32_t CFLAON:2;
+            vuint32_t :9;
+            vuint32_t FMPLLON:1;
+            vuint32_t FXOSC0ON:1;
+            vuint32_t FIRCON:1;
+            vuint32_t SYSCLK:4;
+        } B;
+    } SAFE;
+
+    union { /* DRUN Mode Configuration (Base+0x002C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t PDO:1;
+            vuint32_t :2;
+            vuint32_t MVRON:1;
+            vuint32_t DFLAON:2;
+            vuint32_t CFLAON:2;
+            vuint32_t :9;
+            vuint32_t FMPLLON:1;
+            vuint32_t FXOSC0ON:1;
+            vuint32_t FIRCON:1;
+            vuint32_t SYSCLK:4;
+        } B;
+    } DRUN;
+
+    union { /* RUN 0->4 Mode Configuration (+0x0030-0x003C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t PDO:1;
+            vuint32_t :2;
+            vuint32_t MVRON:1;
+            vuint32_t DFLAON:2;
+            vuint32_t CFLAON:2;
+            vuint32_t :9;
+            vuint32_t FMPLLON:1;
+            vuint32_t FXOSC0ON:1;
+            vuint32_t FIRCON:1;
+            vuint32_t SYSCLK:4;
+        } B;
+    } RUN[4];
+
+    union { /* HALT Mode Configuration (Base+0x0040) */
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t PDO:1;
+            vuint32_t :2;
+            vuint32_t MVRON:1;
+            vuint32_t DFLAON:2;
+            vuint32_t CFLAON:2;
+            vuint32_t :9;
+            vuint32_t FMPLLON:1;
+            vuint32_t FXOSC0ON:1;
+            vuint32_t FIRCON:1;
+            vuint32_t SYSCLK:4;
+        } B;
+    } HALT;
+
+    vuint8_t ME_reserved1[4]; /* reserved 4 bytes (Base+0x0044-0x0047) */
+
+    union { /* STOP Mode Configuration (Base+0x0048) */
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t PDO:1;
+            vuint32_t :2;
+            vuint32_t MVRON:1;
+            vuint32_t DFLAON:2;
+            vuint32_t CFLAON:2;
+            vuint32_t :9;
+            vuint32_t FMPLLON:1;
+            vuint32_t FXOSC0ON:1;
+            vuint32_t FIRCON:1;
+            vuint32_t SYSCLK:4;
+        } B;
+    } STOP;
+
+    vuint8_t ME_reserved2[8]; /* reserved 8 bytes (Base+0x004C-0x0053) */
+
+    union { /* STANDBY Mode Configuration (Base+0x0054) */
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t PDO:1;
+            vuint32_t :2;
+            vuint32_t MVRON:1;
+            vuint32_t DFLAON:2;
+            vuint32_t CFLAON:2;
+            vuint32_t :9;
+            vuint32_t FMPLLON:1;
+            vuint32_t FXOSC0ON:1;
+            vuint32_t FIRCON:1;
+            vuint32_t SYSCLK:4;
+        } B;
+    } STANDBY;
+
+    vuint8_t ME_reserved3[8]; /* reserved 8 bytes (Base+0x0058-0x005F) */
+
+    union {
+        vuint32_t R;
+        struct { /* Peripheral Status 0 (Base+0x0060) */
+            vuint32_t :7;
+            vuint32_t S_FLEXRAY:1;
+            vuint32_t S_DMA_CH_MUX:1;
+            vuint32_t :1;
+            vuint32_t S_FLEXCAN5:1;
+            vuint32_t S_FLEXCAN4:1;
+            vuint32_t S_FLEXCAN3:1;
+            vuint32_t S_FLEXCAN2:1;
+            vuint32_t S_FLEXCAN1:1;
+            vuint32_t S_FLEXCAN0:1;
+            vuint32_t :2;
+            vuint32_t S_LINFLEX9:1;
+            vuint32_t S_LINFLEX8:1;
+            vuint32_t S_DSPI7:1;
+            vuint32_t S_DSPI6:1;
+            vuint32_t S_DSPI5:1;
+            vuint32_t S_DSPI4:1;
+            vuint32_t S_DSPI3:1;
+            vuint32_t S_DSPI2:1;
+            vuint32_t S_DSPI1:1;
+            vuint32_t S_DSPI0:1;
+            vuint32_t :4;
+        } B;
+    } PS0;
+
+    union { /* Peripheral Status 1 (Base+0x0064)*/
+        vuint32_t R;
+        struct {
+            vuint32_t :3;
+            vuint32_t S_CANSAMPLER:1;
+            vuint32_t :2;
+            vuint32_t S_CTUL:1;
+            vuint32_t :1;
+            vuint32_t S_LINFLEX7:1;
+            vuint32_t S_LINFLEX6:1;
+            vuint32_t S_LINFLEX5:1;
+            vuint32_t S_LINFLEX4:1;
+            vuint32_t S_LINFLEX3:1;
+            vuint32_t S_LINFLEX2:1;
+            vuint32_t S_LINFLEX1:1;
+            vuint32_t S_LINFLEX0:1;
+            vuint32_t :3;
+            vuint32_t S_I2C:1;
+            vuint32_t :10;
+            vuint32_t S_ADC1:1;
+            vuint32_t S_ADC0:1;
+        } B;
+    } PS1;
+
+    union { /* Peripheral Status 2 (Base+0x0068) */
+        vuint32_t R;
+        struct {
+            vuint32_t :3;
+            vuint32_t S_PIT_RTI:1;
+            vuint32_t S_RTC_API:1;
+            vuint32_t :16;
+            vuint32_t S_EMIOS1:1;
+            vuint32_t S_EMIOS0:1;
+            vuint32_t :2;
+            vuint32_t S_WKUP:1; /* Also called S_WKPU on B3M RM */
+            vuint32_t S_SIUL:1;
+            vuint32_t :4;
+        } B;
+    } PS2;
+
+    union { /* Peripheral Status 3 (Base+0x006C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :23;
+            vuint32_t S_CMU:1;
+            vuint32_t :8;
+        } B;
+    } PS3;
+
+    vuint8_t ME_reserved4[16]; /* reserved 16 bytes (Base+0x0070-0x007F) */
+
+    union { /* RUN Peripheral Config 0..7 (+0x0080-009C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :24;
+            vuint32_t RUN3:1;
+            vuint32_t RUN2:1;
+            vuint32_t RUN1:1;
+            vuint32_t RUN0:1;
+            vuint32_t DRUN:1;
+            vuint32_t SAFE:1;
+            vuint32_t TEST:1;
+            vuint32_t RESET:1;
+        } B;
+    } RUNPC[8];
+
+    union { /* Low Pwr Periph Config 0..7 (+0x00A0-0x00BC) */
+      vuint32_t R;
+      struct {
+            vuint32_t :18;
+            vuint32_t STANDBY:1;
+            vuint32_t :2;
+            vuint32_t STOP:1;
+            vuint32_t :1;
+            vuint32_t HALT:1;
+            vuint32_t :8;
+        } B;
+    } LPPC[8];
+
+
+    /* Note on PCTL registers: There are only some PCTL implemented in      */
+    /*  Bolero 3M. In order to make the PCTL easily addressable, these      */
+    /*  are defined as an array (ie ME.PCTL[x].R). This means you have      */
+    /*  to be careful when addressing these registers in order not to       */
+    /*  access a PCTL that is not implemented. Following are available:     */
+    /*  104, 92, 91, 73, 72, 69, 68, 60, 57, 44, 33, 32, 24, 23, 21-16, 13-4*/
+
+    union { /* Peripheral Control 0..143 (+0x00C0-0x0128) */
+        vuint8_t R;
+        struct {
+            vuint8_t :1;
+            vuint8_t DBG_F:1;
+            vuint8_t LP_CFG:3;
+            vuint8_t RUN_CFG:3;
+        } B;
+    } PCTL[105];
+
+}; /* end of ME_tag */
+/****************************************************************************/
+/*                          MODULE : CGM                                    */
+/****************************************************************************/
+struct CGM_tag{
+
+
+    /*
+
+    The "CGM" has fairly wide coverage and essentially includes everything in
+
+    chapter 3 of the Bolero 3M Reference Manual:
+
+
+
+        Base Address | Clock Sources
+
+       -----------------------------
+
+        0xC3FE0000   | FXOSC_CTL
+
+        0xC3FE0040   | SXOSC_CTL
+
+        0xC3FE0060   | FIRC_CTL
+
+        0xC3FE0080   | SIRC_CTL
+
+        0xC3FE00A0   | FMPLL
+
+        0xC3FE00C0   | CGM Block 1
+
+        0xC3FE0100   | CMU    
+
+        0xC3FE0120   | CGM Block 2
+
+
+
+        In this header file, "Base" referrs to the 1st address, 0xC3FE_0000 
+
+    */
+    /* FXOSC - 0xC3FE_0000*/
+    union { /* Fast OSC Control (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t OSCBYP:1;
+            vuint32_t :7;
+            vuint32_t EOCV:8;
+            vuint32_t M_OSC:1;
+            vuint32_t :2;
+            vuint32_t OSCDIV:5;
+            vuint32_t I_OSC:1;
+            vuint32_t:7;
+        } B;
+    } FXOSC_CTL;
+
+
+    /* Reserved Space between end of FXOSC and start SXOSC                 */
+    vuint8_t CGM_reserved0[60]; /* Reserved 60 bytes (Base+0x0004-0x003F)  */
+
+
+    /* SXOSC - 0xC3FE_0040*/
+    union { /* Slow Osc Control (Base+0x0040)              */
+        vuint32_t R;
+        struct {
+            vuint32_t OSCBYP:1;
+            vuint32_t :7;
+            vuint32_t EOCV:8;
+            vuint32_t M_OSC:1;
+            vuint32_t :2;
+            vuint32_t OSCDIV:5;
+            vuint32_t I_OSC:1;
+            vuint32_t :5;
+            vuint32_t S_OSC:1;
+            vuint32_t OSCON:1;
+        } B;
+    } SXOSC_CTL;
+
+
+    /* Reserved space between end of SXOSC and start of FIRC               */
+    vuint8_t CGM_reserved1[28]; /*Reserved 28 bytes (Base+0x0044-0x005F)   */
+
+
+    /* FIRC - 0x3CFE_0060 */
+    union { /* Fast IRC Control (Base+0x0060)              */
+        vuint32_t R;
+        struct {
+            vuint32_t :10;
+            vuint32_t RCTRIM:6;
+            vuint32_t :3;
+            vuint32_t RCDIV:5;
+            vuint32_t :8;
+        } B;
+    } FIRC_CTL;
+
+
+    /* Reserved space between end of FIRC and start of SIRC                */
+    vuint8_t CGM_reserved2[28]; /*Reserved 28 bytes (Base+0x0064-0x007F)   */
+
+
+    /* SIRC - 0x3FE_0080 */
+    union { /* Slow IRC Control (Base+0x0080)              */
+        vuint32_t R;
+        struct {
+            vuint32_t :11;
+            vuint32_t SIRCTRIM:5;
+            vuint32_t :3;
+            vuint32_t SIRCDIV:5;
+            vuint32_t :3;
+            vuint32_t S_SIRC:1;
+            vuint32_t :3;
+            vuint32_t SIRCON_STDBY:1;
+        } B;
+    } SIRC_CTL;
+
+
+    /* Reserved space between end of SIRC and start of FMPLL               */
+    vuint8_t CGM_reserved3[28]; /*Reserved 28 bytes (Base+0x0084-0x009F)   */
+
+
+    /* FMPLL - 0xC3FE_00A0 */
+    union { /* FMPLL Control (Base+0x00A0)                 */
+        vuint32_t R;
+        struct {
+            vuint32_t :2;
+            vuint32_t IDF:4;
+            vuint32_t ODF:2;
+            vuint32_t :1;
+            vuint32_t NDIV:7;
+            vuint32_t :7;
+            vuint32_t EN_PLL_SW:1;
+            vuint32_t MODE:1;
+            vuint32_t UNLOCK_ONCE:1;
+            vuint32_t :1;
+            vuint32_t I_LOCK:1;
+            vuint32_t S_LOCK:1;
+            vuint32_t PLL_FAIL_MASK:1;
+            vuint32_t PLL_FAIL_FLAG:1;
+            vuint32_t :1;
+        } B;
+    } FMPLL_CR;
+
+    union { /* FMPLL Modulation (Base+0x00A4)              */
+        vuint32_t R;
+        struct {
+            vuint32_t STRB_BYPASS:1;
+            vuint32_t :1;
+            vuint32_t SPRD_SEL:1;
+            vuint32_t MOD_PERIOD:13;
+            vuint32_t FM_EN:1;
+            vuint32_t INC_STEP:15;
+        } B;
+    } FMPLL_MR;
+
+
+    /* Reserved space between end of FMPLL and start of CGM Block 1        */
+    vuint8_t CGM_reserved4[24]; /*Reserved 24 bytes (Base+0x00A8-0x00BF)   */
+
+
+    /* CGM Block 1 - 0xC3FE_00C0 */
+    union { /* CMU Z0 Clock Divider Config (Base+0x00C0)   */
+        vuint8_t R;
+        struct {
+            vuint8_t :7;
+            vuint8_t DIV:1;
+        } B;
+    } Z0_DCR;
+
+    vuint8_t CGM_reserved5[31]; /*Reserved 31 bytes (Base+0x00C1-0x00DF)   */
+
+    union { /* CMU FEC Clock Divider Config (Base+0x00E0)  */
+        vuint8_t R;
+        struct {
+            vuint8_t :7;
+            vuint8_t DIV:1;
+        } B;
+    } FEC_DCR;
+
+
+    /* Reserved space between end of CGM Block1 and start of CMU           */
+    vuint8_t CGM_reserved6[31]; /*Reserved 31 bytes (Base+0x00E1-0x00FF)   */
+
+
+    /* CMU - 0xC3FE_0100 */
+    union { /* CMU Control Status (Base+0x0100)            */
+        vuint32_t R;
+        struct {
+            vuint32_t :8;
+            vuint32_t SFM:1;
+            vuint32_t :13;
+            vuint32_t CLKSEL1:2;
+            vuint32_t :5;
+            vuint32_t RCDIV:2;
+            vuint32_t CME_A:1;
+        } B;
+    } CMU_CSR;
+
+    union { /* CMU Frequency Display (Base+0x0104)         */
+        vuint32_t R;
+        struct {
+            vuint32_t :12;
+            vuint32_t FD:20;
+        } B;
+    } CMU_FDR;
+
+    union { /* CMU High Freq Reference FMPLL (Base+0x0108) */
+        vuint32_t R;
+        struct {
+            vuint32_t :20;
+            vuint32_t HFREF:12;
+        } B;
+    } CMU_HFREFR;
+
+    union { /* CMU Low Freq Reference FMPLL (Base+0x010C)  */
+        vuint32_t R;
+        struct {
+            vuint32_t :20;
+            vuint32_t LFREF:12;
+        } B;
+    } CMU_LFREFR;
+
+    union { /* CMU Interrupt Status (Base+0x0110)          */
+        vuint32_t R;
+        struct {
+            vuint32_t :29;
+            vuint32_t FHHI:1;
+            vuint32_t FLLI:1;
+            vuint32_t OLRI:1;
+        } B;
+    } CMU_ISR;
+
+
+    /* Note about CMU_IMR: On Bolero 3M this register will always read as 0 */
+    /* Commented out register definition is below but this register should  */
+    /* not be accessed in Bolero 3M                                         */
+
+    /* Reserved space where IMR was previously positioned                  */
+    vuint8_t CGM_reserved7[4]; /*Reserved 4 bytes (Base+0x0114-0x0117)     */
+
+    /*union {   Interrupt Mask Register Removed from Bolero3M (Read 0)
+
+        vuint32_t R;
+
+        struct {
+
+            vuint32_t :32;
+
+        } B;
+
+    } CMU_IMR; */
+    union { /* CMU Measurement Duration (Base+0x0118)      */
+        vuint32_t R;
+        struct {
+            vuint32_t :12;
+            vuint32_t MD:20;
+        } B;
+    } CMU_MDR;
+
+
+    /* Reserved space between end of CMU and start of CGM Block 2          */
+    vuint8_t CGM_reserved8[4]; /*Reserved 4 bytes (Base+0x011C-0x011F)     */
+
+
+     /* CGM - 0xC3FE0120   */
+    union { /* CGM Flash Clock Divider Config (Base+0x0120) */
+        vuint8_t R;
+        struct {
+            vuint8_t :7;
+            vuint8_t DIV:1;
+        } B;
+    } FLASH_DCR;
+
+    vuint8_t CGM_reserved9[591]; /*Reserved 591 bytes (Base+0x0121-0x036F) */
+
+    union { /* GCM Output Clock Enable (Base+0x0370)       */
+        vuint32_t R;
+        struct {
+            vuint32_t :31;
+            vuint32_t EN:1;
+        } B;
+    } OC_EN;
+
+    union { /* CGM Output Clock Division Sel (Base+0x0374) */
+        vuint8_t R;
+        struct {
+            vuint8_t :2;
+            vuint8_t SELDIV:2;
+            vuint8_t SELCTL:4;
+        } B;
+    } OCDS_SC;
+
+    vuint8_t CGM_reserved10[3]; /*Reserved 3 bytes (Base+0x0375-0x0377)    */
+
+    union { /* CGM System Clock Select Status (Base+0x0378) */
+        vuint32_t R;
+        struct {
+            vuint32_t :4;
+            vuint32_t SELSTAT:4;
+            vuint32_t :24;
+        } B;
+    } SC_SS;
+
+    union { /* CGM Sys Clk Div Config0 (Base+0x037C)       */
+        vuint8_t R;
+        struct {
+            vuint8_t DE0:1;
+            vuint8_t :3;
+            vuint8_t DIV0:4;
+        } B;
+    } SC_DC0;
+
+    union { /* CGM Sys Clk Div Config1 (Base+0x037D)       */
+        vuint8_t R;
+        struct {
+            vuint8_t DE1:1;
+            vuint8_t :3;
+            vuint8_t DIV1:4;
+        } B;
+    } SC_DC1;
+
+    union { /* CGM Sys Clk Div Config1 (Base+0x037E)       */
+        vuint8_t R;
+        struct {
+            vuint8_t DE2:1;
+            vuint8_t :3;
+            vuint8_t DIV2:4;
+        } B;
+    } SC_DC2;
+
+    vuint8_t CGM_reserved11[1]; /*Reserved 1 byte (Base+0x037F)            */
+
+    union { /* CGM Aux Clock0 Select Control (+0x0380-0x383) */
+        vuint32_t R;
+        struct {
+            vuint32_t :4;
+            vuint32_t SELCTL:4;
+            vuint32_t :24;
+        } B;
+    } AC0_SC;
+
+    vuint8_t CGM_reserved12[4]; /*Reserved 4 bytes (Base+0x0384-0x0387)  */
+
+    union { /* CGM Aux Clock1 Select Control (Base+0x0388) */
+        vuint32_t R;
+        struct {
+            vuint32_t :4;
+            vuint32_t SELCTL:4;
+            vuint32_t :24;
+        } B;
+    } AC1_SC;
+
+    union { /* CGM Aux Clock1 Divider 0 Config (Base+0x038C) */
+       vuint8_t R;
+        struct {
+            vuint8_t DE0:1;
+            vuint8_t :3;
+            vuint8_t DIV0:4;
+        } B;
+    } AC1_DC0;
+
+}; /* end of CGM_tag */
+/****************************************************************************/
+/*                          MODULE : RGM                                   */
+/****************************************************************************/
+struct RGM_tag{
+
+    union { /* Functional Event Status (Base+0x0000) */
+        vuint16_t R;
+        struct {
+            vuint16_t F_EXR:1;
+            vuint16_t F_ST_NCF:1;
+            vuint16_t F_ST_CF:1;
+            vuint16_t F_ST_DONE:1;
+            vuint16_t :1;
+            vuint16_t F_Z4CORE:1;
+            vuint16_t :1;
+            vuint16_t F_FLASH:1;
+            vuint16_t F_LVD45:1;
+            vuint16_t F_CMU_FHL:1;
+            vuint16_t F_CMU_OLR:1;
+            vuint16_t F_FMPLL:1;
+            vuint16_t F_CHKSTOP:1;
+            vuint16_t F_SOFT_FUNC:1;
+            vuint16_t F_Z0CORE:1;
+            vuint16_t F_JTAG:1;
+        } B;
+    } FES;
+
+    union { /* Destructive Event Status (Base+0x0002) */
+        vuint16_t R;
+        struct {
+            vuint16_t F_POR:1;
+            vuint16_t F_SOFT_DEST:1;
+            vuint16_t :10;
+            vuint16_t F_LVD27:1;
+            vuint16_t F_SWT:1;
+            vuint16_t F_LVD12_PD1:1;
+            vuint16_t F_LVD12_PD0:1;
+        } B;
+    } DES;
+
+    union { /* Functional Event Reset Disable (+0x0004) */
+        vuint16_t R;
+        struct {
+            vuint16_t D_EXR:1;
+            vuint16_t D_ST_NCF:1;
+            vuint16_t D_ST_CF:1;
+            vuint16_t D_ST_DONE:1;
+            vuint16_t :1;
+            vuint16_t D_Z4CORE:1;
+            vuint16_t :1;
+            vuint16_t D_FLASH:1;
+            vuint16_t D_LVD45:1;
+            vuint16_t D_CMU_FHL:1;
+            vuint16_t D_CMU_OLR:1;
+            vuint16_t D_FMPLL:1;
+            vuint16_t D_CHKSTOP:1;
+            vuint16_t D_SOFT_FUNC:1;
+            vuint16_t D_Z0CORE:1;
+            vuint16_t D_JTAG:1;
+        } B;
+    } FERD;
+
+    union { /* Destructive Event Reset Disable (Base+0x0006)*/
+        vuint16_t R;
+        struct {
+            vuint16_t :1;
+            vuint16_t D_SOFT_DEST:1;
+            vuint16_t :10;
+            vuint16_t D_LVD27:1;
+            vuint16_t D_SWT:1;
+            vuint16_t D_LVD12_PD1:1;
+            vuint16_t D_LVD12_PD0:1;
+        } B;
+    } DERD;
+
+    vuint8_t RGM_reserved0[8]; /*Reserved 8 bytes (Base+0x008-0x000F) */
+
+    union { /* Functional Event Alt Request (Base+0x0010) */
+        vuint16_t R;
+        struct {
+            vuint16_t :1;
+            vuint16_t AR_ST_NCF:1;
+            vuint16_t AR_ST_CF:1;
+            vuint16_t :2;
+            vuint16_t AR_Z4CORE:1;
+            vuint16_t :2;
+            vuint16_t AR_LVD45:1;
+            vuint16_t AR_CMU_FHL:1;
+            vuint16_t AR_CMU_OLR:1;
+            vuint16_t AR_FMPLL:1;
+            vuint16_t :2;
+            vuint16_t AR_Z0CORE:1;
+            vuint16_t AR_JTAG:1;
+        } B;
+    } FEAR;
+
+    vuint8_t RGM_reserved1[6]; /*Reserved 6 bytes (Base+0x0012-0x0017) */
+
+    union { /* Functional Event Short Sequence (+0x0018) */
+        vuint16_t R;
+        struct {
+            vuint16_t SS_EXR:1;
+            vuint16_t :2;
+            vuint16_t SS_ST_DONE:1;
+            vuint16_t :1;
+            vuint16_t SS_Z4CORE:1;
+            vuint16_t :1;
+            vuint16_t SS_FLASH:1;
+            vuint16_t SS_LVD45:1;
+            vuint16_t SS_CMU_FHL:1;
+            vuint16_t SS_CMU_OLR:1;
+            vuint16_t SS_FMPLL:1;
+            vuint16_t SS_CHKSTOP:1;
+            vuint16_t SS_SOFT_FUNC:1;
+            vuint16_t SS_Z0CORE:1;
+            vuint16_t SS_JTAG:1;
+        } B;
+    } FESS;
+
+    union { /* STANDBY reset sequence (Base+0x001A) */
+        vuint16_t R;
+        struct {
+            vuint16_t :7;
+            vuint16_t SB_CPU:1;
+            vuint16_t BOOT_FROM_BKP_RAM:1;
+            vuint16_t :7;
+        } B;
+    } STDBY;
+
+    union { /* Functional Bidirectional Reset En (+0x001C) */
+        vuint16_t R;
+        struct {
+            vuint16_t BE_EXR:1;
+            vuint16_t :2;
+            vuint16_t BE_ST_DONE:1;
+            vuint16_t :1;
+            vuint16_t BE_Z4CORE:1;
+            vuint16_t :1;
+            vuint16_t BE_FLASH:1;
+            vuint16_t BE_LVD45:1;
+            vuint16_t BE_CMU_FHL:1;
+            vuint16_t BE_CMU_OLR:1;
+            vuint16_t BE_FMPLL:1;
+            vuint16_t BE_CHKSTOP:1;
+            vuint16_t BE_SOFT_FUNC:1;
+            vuint16_t BE_Z0CORE:1;
+            vuint16_t BE_JTAG:1;
+        } B;
+    } FBRE;
+
+}; /* end of RGM_tag */
+/****************************************************************************/
+/*                          MODULE : PCU                                   */
+/****************************************************************************/
+struct PCU_tag{
+
+    union { /* PCU Power domain 0-3 config (+0x0000-0x000C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :18;
+            vuint32_t STBY:1;
+            vuint32_t :2;
+            vuint32_t STOP:1;
+            vuint32_t :1;
+            vuint32_t HALT:1;
+            vuint32_t RUN3:1;
+            vuint32_t RUN2:1;
+            vuint32_t RUN1:1;
+            vuint32_t RUN0:1;
+            vuint32_t DRUN:1;
+            vuint32_t SAFE:1;
+            vuint32_t TEST:1;
+            vuint32_t RST:1;
+        } B;
+    } PCONF[4];
+
+    vuint8_t PCU_reserved0[48]; /* Reserved 48 bytes (Base+0x0010-0x003F) */
+
+    union { /* PCU Power Domain Status (Base+0x0040) */
+        vuint32_t R;
+        struct {
+            vuint32_t :28;
+            vuint32_t PD3:1;
+            vuint32_t PD2:1;
+            vuint32_t PD1:1;
+            vuint32_t PD0:1;
+        } B;
+    } PSTAT;
+
+    vuint8_t PCU_reserved1[60]; /* Reserved 60 bytes (Base+0x0044-0x007F) */
+
+
+ /* Following registers are from Voltage Regulators chapter of RM */
+
+    union { /* PCU Voltage Regulator Control (Base+0x0080) */
+        vuint32_t R;
+        struct {
+            vuint32_t :31;
+            vuint32_t MASK_LVDHV5:1;
+        } B;
+    } VREG_CTL; /* Changed from VCTL for consistency with other regs here */
+
+    union { /* PCU PDMODE (Base+0x0084) */
+        vuint32_t R;
+        struct {
+            vuint32_t :15;
+            vuint32_t PORPU:1;
+            vuint32_t :15;
+            vuint32_t PDMODE:1;
+        } B;
+    } VREG_PDMODE;
+
+
+}; /* end of PCU_tag */
+/****************************************************************************/
+/*                          MODULE : RTC/API                                */
+/****************************************************************************/
+struct RTC_tag{
+
+    union { /* RTC Supervisor Control (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t SUPV:1;
+            vuint32_t :31;
+        } B;
+    } RTCSUPV ;
+
+    union { /* RTC Control (Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t CNTEN:1;
+            vuint32_t RTCIE:1;
+            vuint32_t FRZEN:1;
+            vuint32_t ROVREN:1;
+            vuint32_t RTCVAL:12;
+            vuint32_t APIEN:1;
+            vuint32_t APIIE:1;
+            vuint32_t CLKSEL:2;
+            vuint32_t DIV512EN:1;
+            vuint32_t DIV32EN:1;
+            vuint32_t APIVAL:10;
+        } B;
+    } RTCC;
+
+    union { /* RTC Status (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t :2;
+            vuint32_t RTCF:1;
+            vuint32_t :15;
+            vuint32_t APIF:1;
+            vuint32_t :2;
+            vuint32_t ROVRF:1;
+            vuint32_t :10;
+        } B;
+    } RTCS;
+
+    union { /* RTC Counter (Base+0x000C) */
+        vuint32_t R;
+        struct {
+            vuint32_t RTCCNT:32;
+        } B;
+    } RTCCNT;
+
+}; /* end of RTC_tag */
+/****************************************************************************/
+/*                          MODULE : pit                                    */
+/****************************************************************************/
+struct PIT_tag {
+
+    union { /* PIT Module Control (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t:29;
+            vuint32_t MDIS_RTI:1;
+            vuint32_t MDIS:1;
+            vuint32_t FRZ:1;
+        } B;
+    } PITMCR;
+
+    vuint8_t PIT_reserved0[236]; /* Reserved 236 Bytes (Base+0x0004-0x00EF) */
+
+
+    /* RTI Config Registers (Base + 0x00F0-0x00FF) */
+     struct {
+
+        union { /* RTI Timer Load Value (Offset+0x0000) */
+            vuint32_t R;
+            struct {
+                vuint32_t TSV:32;
+            } B;
+        } LDVAL;
+
+        union { /* RTI Current Timer Value (Offset+0x0004) */
+            vuint32_t R;
+            struct {
+                vuint32_t TVL:32;
+            } B;
+        } CVAL;
+
+        union { /* RTI Timer Control (Offset+0x0008) */
+            vuint32_t R;
+            struct {
+                vuint32_t :30;
+                vuint32_t TIE:1;
+                vuint32_t TEN:1;
+            } B;
+        } TCTRL;
+
+        union { /* RTI Timer Flag (Offset+0x000C) */
+            vuint32_t R;
+            struct {
+                vuint32_t :31;
+                vuint32_t TIF:1;
+            } B;
+        } TFLG;
+
+    }RTI; /* End of RTI registers */
+
+
+    /* PIT Timer Channels 0..7 (Base+0x0100-0x017C) */
+    struct {
+
+        union { /* PIT Timer Load Value (Offset+0x0000) */
+            vuint32_t R;
+            struct {
+                vuint32_t TSV:32;
+            } B;
+        } LDVAL;
+
+        union { /* PIT Current Timer Value (Offset+0x0004) */
+            vuint32_t R;
+            struct {
+                vuint32_t TVL:32;
+            } B;
+        } CVAL;
+
+        union { /* PIT Timer Control (Offset+0x0008) */
+            vuint32_t R;
+            struct {
+                vuint32_t :30;
+                vuint32_t TIE:1;
+                vuint32_t TEN:1;
+            } B;
+        } TCTRL;
+
+        union { /* PIT Timer Flag (Offset+0x000C) */
+            vuint32_t R;
+            struct {
+                vuint32_t :31;
+                vuint32_t TIF:1;
+            } B;
+        } TFLG;
+
+    }CH[8]; /* End of PIT Timer Channels */
+
+}; /* end of PIT_tag */
+/****************************************************************************/
+/*          MODULE : STCU (Self-Test Control Unit)                          */
+/****************************************************************************/
+struct STCU_tag {
+
+    union { /* STCU Run (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t :31;
+            vuint32_t RUN:1;
+        } B;
+    } RUN;
+
+    vuint8_t STCU_reserved0[4]; /* Reserved 4 bytes (Base+0x0004-0x0007) */
+
+    union { /* STCU SK Code (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t SKC:32;
+        } B;
+    } SKC;
+
+    union { /* STCU Config (Base+0x000C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :1;
+            vuint32_t PTR:7;
+            vuint32_t :20;
+            vuint32_t CLK_CFG:4;
+        } B;
+    } CFG;
+
+    union { /* STCU Watchdog Granularity (Base+0x0010) */
+        vuint32_t R;
+        struct {
+            vuint32_t :29;
+            vuint32_t GMBIST:3;
+        } B;
+    } WDGG;
+
+    union { /* STCU CRC Expected Status (Base+0x0014) */
+        vuint32_t R;
+        struct {
+            vuint32_t CRCE:32;
+        } B;
+    } CRCE;
+
+    union { /* STCU CRC Read Status (Base+0x0018) */
+        vuint32_t R;
+        struct {
+            vuint32_t CRCR:32;
+        } B;
+    } CRCR;
+
+    union { /* STCU Error (Base+0x001C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :4;
+            vuint32_t WDTOSFM:1;
+            vuint32_t CRCSSFM:1;
+            vuint32_t ENGESFM:1;
+            vuint32_t INVPSFM:1;
+            vuint32_t :4;
+            vuint32_t WDTOCFM:1;
+            vuint32_t CRCSCFM:1;
+            vuint32_t ENGECFM:1;
+            vuint32_t INVPCFM:1;
+            vuint32_t :5;
+            vuint32_t CFSF:1;
+            vuint32_t NCFSF:1;
+            vuint32_t SIRSF:1;
+            vuint32_t :4;
+            vuint32_t WDTO:1;
+            vuint32_t CRCS:1;
+            vuint32_t ENGE:1;
+            vuint32_t INVP:1;
+        } B;
+    } ERR;
+
+    union { /* STCU Error Key (Base+0x0020) */
+        vuint32_t R;
+        struct {
+            vuint32_t ERR_SK:32;
+        } B;
+    } ERRK;
+
+    vuint8_t STCU_reserved1[24]; /* Reserved 24 bytes (Base+0x0024-0x003B) */
+
+    union { /* STCU MBIST Status Low (Base+0x003C) */
+        vuint32_t R;
+        struct {
+            vuint32_t MBS31:1;
+            vuint32_t MBS30:1;
+            vuint32_t MBS29:1;
+            vuint32_t MBS28:1;
+            vuint32_t MBS27:1;
+            vuint32_t MBS26:1;
+            vuint32_t MBS25:1;
+            vuint32_t MBS24:1;
+            vuint32_t MBS23:1;
+            vuint32_t MBS22:1;
+            vuint32_t MBS21:1;
+            vuint32_t MBS20:1;
+            vuint32_t MBS19:1;
+            vuint32_t MBS18:1;
+            vuint32_t MBS17:1;
+            vuint32_t MBS16:1;
+            vuint32_t MBS15:1;
+            vuint32_t MBS14:1;
+            vuint32_t MBS13:1;
+            vuint32_t MBS12:1;
+            vuint32_t MBS11:1;
+            vuint32_t MBS10:1;
+            vuint32_t MBS9:1;
+            vuint32_t MBS8:1;
+            vuint32_t MBS7:1;
+            vuint32_t MBS6:1;
+            vuint32_t MBS5:1;
+            vuint32_t MBS4:1;
+            vuint32_t MBS3:1;
+            vuint32_t MBS2:1;
+            vuint32_t MBS1:1;
+            vuint32_t MBS0:1;
+        } B;
+    } MBSL;
+
+    union { /* STCU MBIST Status High (Base+0x0040) */
+        vuint32_t R;
+        struct {
+            vuint32_t :23;
+            vuint32_t MBS40:1;
+            vuint32_t MBS39:1;
+            vuint32_t MBS38:1;
+            vuint32_t MBS37:1;
+            vuint32_t MBS36:1;
+            vuint32_t MBS35:1;
+            vuint32_t MBS34:1;
+            vuint32_t MBS33:1;
+            vuint32_t MBS32:1;
+        } B;
+    } MBSH;
+
+    union { /* STCU MBIST End Flag Low (Base+0x0044) */
+        vuint32_t R;
+        struct {
+            vuint32_t MBE31:1;
+            vuint32_t MBE30:1;
+            vuint32_t MBE29:1;
+            vuint32_t MBE28:1;
+            vuint32_t MBE27:1;
+            vuint32_t MBE26:1;
+            vuint32_t MBE25:1;
+            vuint32_t MBE24:1;
+            vuint32_t MBE23:1;
+            vuint32_t MBE22:1;
+            vuint32_t MBE21:1;
+            vuint32_t MBE20:1;
+            vuint32_t MBE19:1;
+            vuint32_t MBE18:1;
+            vuint32_t MBE17:1;
+            vuint32_t MBE16:1;
+            vuint32_t MBE15:1;
+            vuint32_t MBE14:1;
+            vuint32_t MBE13:1;
+            vuint32_t MBE12:1;
+            vuint32_t MBE11:1;
+            vuint32_t MBE10:1;
+            vuint32_t MBE9:1;
+            vuint32_t MBE8:1;
+            vuint32_t MBE7:1;
+            vuint32_t MBE6:1;
+            vuint32_t MBE5:1;
+            vuint32_t MBE4:1;
+            vuint32_t MBE3:1;
+            vuint32_t MBE2:1;
+            vuint32_t MBE1:1;
+            vuint32_t MBE0:1;
+        } B;
+    } MBEL;
+
+    union { /* STCU MBIST End Flag High (Base+0x0048) */
+        vuint32_t R;
+        struct {
+            vuint32_t :23;
+            vuint32_t MBE40:1;
+            vuint32_t MBE39:1;
+            vuint32_t MBE38:1;
+            vuint32_t MBE37:1;
+            vuint32_t MBE36:1;
+            vuint32_t MBE35:1;
+            vuint32_t MBE34:1;
+            vuint32_t MBE33:1;
+            vuint32_t MBE32:1;
+        } B;
+    } MBEH;
+
+    union { /* STCU MBIST Status End Key (Base+0x004C) */
+        vuint32_t R;
+        struct {
+            vuint32_t MBSEK:32;
+        } B;
+    } MBSEK;
+
+    union { /* STCU MBIST Critical FM Low (Base+0x0050) */
+        vuint32_t R;
+        struct {
+            vuint32_t MBCFM31:1;
+            vuint32_t MBCFM30:1;
+            vuint32_t MBCFM29:1;
+            vuint32_t MBCFM28:1;
+            vuint32_t MBCFM27:1;
+            vuint32_t MBCFM26:1;
+            vuint32_t MBCFM25:1;
+            vuint32_t MBCFM24:1;
+            vuint32_t MBCFM23:1;
+            vuint32_t MBCFM22:1;
+            vuint32_t MBCFM21:1;
+            vuint32_t MBCFM20:1;
+            vuint32_t MBCFM19:1;
+            vuint32_t MBCFM18:1;
+            vuint32_t MBCFM17:1;
+            vuint32_t MBCFM16:1;
+            vuint32_t MBCFM15:1;
+            vuint32_t MBCFM14:1;
+            vuint32_t MBCFM13:1;
+            vuint32_t MBCFM12:1;
+            vuint32_t MBCFM11:1;
+            vuint32_t MBCFM10:1;
+            vuint32_t MBCFM9:1;
+            vuint32_t MBCFM8:1;
+            vuint32_t MBCFM7:1;
+            vuint32_t MBCFM6:1;
+            vuint32_t MBCFM5:1;
+            vuint32_t MBCFM4:1;
+            vuint32_t MBCFM3:1;
+            vuint32_t MBCFM2:1;
+            vuint32_t MBCFM1:1;
+            vuint32_t MBCFM0:1;
+        } B;
+    } MBCFML;
+
+    union { /* STCU MBIST Critical FM High (Base+0x0054) */
+        vuint32_t R;
+        struct {
+            vuint32_t :23;
+            vuint32_t MBCFM40:1;
+            vuint32_t MBCFM39:1;
+            vuint32_t MBCFM38:1;
+            vuint32_t MBCFM37:1;
+            vuint32_t MBCFM36:1;
+            vuint32_t MBCFM35:1;
+            vuint32_t MBCFM34:1;
+            vuint32_t MBCFM33:1;
+            vuint32_t MBCFM32:1;
+        } B;
+    } MBCFMH;
+
+    union { /* STCU MBIST Stay-In-Reset FM Low (Base+0x0058)*/
+        vuint32_t R;
+        struct {
+            vuint32_t MBSFM31:1;
+            vuint32_t MBSFM30:1;
+            vuint32_t MBSFM29:1;
+            vuint32_t MBSFM28:1;
+            vuint32_t MBSFM27:1;
+            vuint32_t MBSFM26:1;
+            vuint32_t MBSFM25:1;
+            vuint32_t MBSFM24:1;
+            vuint32_t MBSFM23:1;
+            vuint32_t MBSFM22:1;
+            vuint32_t MBSFM21:1;
+            vuint32_t MBSFM20:1;
+            vuint32_t MBSFM19:1;
+            vuint32_t MBSFM18:1;
+            vuint32_t MBSFM17:1;
+            vuint32_t MBSFM16:1;
+            vuint32_t MBSFM15:1;
+            vuint32_t MBSFM14:1;
+            vuint32_t MBSFM13:1;
+            vuint32_t MBSFM12:1;
+            vuint32_t MBSFM11:1;
+            vuint32_t MBSFM10:1;
+            vuint32_t MBSFM9:1;
+            vuint32_t MBSFM8:1;
+            vuint32_t MBSFM7:1;
+            vuint32_t MBSFM6:1;
+            vuint32_t MBSFM5:1;
+            vuint32_t MBSFM4:1;
+            vuint32_t MBSFM3:1;
+            vuint32_t MBSFM2:1;
+            vuint32_t MBSFM1:1;
+            vuint32_t MBSFM0:1;
+        } B;
+    } MBSFML;
+
+    union { /* STCU MBIST Stay-In-Reset FM High (Base+0x005C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :23;
+            vuint32_t MBSFM40:1;
+            vuint32_t MBSFM39:1;
+            vuint32_t MBSFM38:1;
+            vuint32_t MBSFM37:1;
+            vuint32_t MBSFM36:1;
+            vuint32_t MBSFM35:1;
+            vuint32_t MBSFM34:1;
+            vuint32_t MBSFM33:1;
+            vuint32_t MBSFM32:1;
+        } B;
+    } MBSFMH;
+
+   union { /* STCU MBIST FM Key (Base+0x0060) */
+        vuint32_t R;
+        struct {
+            vuint32_t MBFMK:32;
+        } B;
+    } MBFMK;
+
+    vuint8_t STCU_reserved2[668]; /*Reserved 668 bytes (Base+0x0064-0x02FF) */
+
+    union { /* STCU MBIST Comtrol (Base+0x0300) */
+        vuint32_t R;
+        struct {
+            vuint32_t :1;
+            vuint32_t PTR:7;
+            vuint32_t :2;
+            vuint32_t MB_TIME:6;
+            vuint32_t :16;
+        } B;
+    } MBCTRL[41];
+
+
+}; /* end of STCU_tag */
+/****************************************************************************/
+/*                          MODULE : ADC0 (10 Bit)                          */
+/*                                   CH[0..15], CH[32..95]                  */
+/****************************************************************************/
+struct ADC0_tag {
+
+    union { /* ADC0 Main Configuration (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t OWREN:1;
+            vuint32_t WLSIDE:1;
+            vuint32_t MODE:1;
+            vuint32_t EDGLEV:1;
+            vuint32_t TRGEN:1;
+            vuint32_t EDGE:1;
+            vuint32_t XSTRTEN:1;
+            vuint32_t NSTART:1;
+            vuint32_t:1;
+            vuint32_t JTRGEN:1;
+            vuint32_t JEDGE:1;
+            vuint32_t JSTART:1;
+            vuint32_t:2;
+            vuint32_t CTUEN:1;
+            vuint32_t:9;
+            vuint32_t ABORT_CHAIN:1;
+            vuint32_t ABORT:1;
+            vuint32_t ACKO:1;
+            vuint32_t:2;
+            vuint32_t:2;
+            vuint32_t PWDN:1;
+        } B;
+    } MCR;
+
+    union { /* ADC0 Main Status (Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t:7;
+            vuint32_t NSTART:1;
+            vuint32_t JABORT:1;
+            vuint32_t:2;
+            vuint32_t JSTART:1;
+            vuint32_t:3;
+            vuint32_t CTUSTART:1;
+            vuint32_t CHADDR:7;
+            vuint32_t:3;
+            vuint32_t ACKO:1;
+            vuint32_t:2;
+            vuint32_t ADCSTATUS:3;
+        } B;
+    } MSR;
+
+    vuint8_t ADC0_reserved0[8]; /* Reserved 8 bytes (Base+0x0008-0x000F) */
+
+    union { /* ADC0 Interrupt Status (Base+0x0010) */
+        vuint32_t R;
+        struct {
+            vuint32_t:27;
+            //vuint32_t OFFCANCOVR:1;
+            //vuint32_t EOFFSET:1;
+            vuint32_t EOCTU:1;
+            vuint32_t JEOC:1;
+            vuint32_t JECH:1;
+            vuint32_t EOC:1;
+            vuint32_t ECH:1;
+        } B;
+    } ISR;
+
+    union { /* ADC0 Channel Pending 0 (Base+0x0014) */
+        vuint32_t R; /*      (For precision channels)        */
+        struct {
+            vuint32_t :16;
+            vuint32_t EOC_CH15:1;
+            vuint32_t EOC_CH14:1;
+            vuint32_t EOC_CH13:1;
+            vuint32_t EOC_CH12:1;
+            vuint32_t EOC_CH11:1;
+            vuint32_t EOC_CH10:1;
+            vuint32_t EOC_CH9:1;
+            vuint32_t EOC_CH8:1;
+            vuint32_t EOC_CH7:1;
+            vuint32_t EOC_CH6:1;
+            vuint32_t EOC_CH5:1;
+            vuint32_t EOC_CH4:1;
+            vuint32_t EOC_CH3:1;
+            vuint32_t EOC_CH2:1;
+            vuint32_t EOC_CH1:1;
+            vuint32_t EOC_CH0:1;
+        } B;
+    } CE0CFR0;
+
+    union { /* ADC0 Channel Pending 1 (Base+0x0018) */
+        vuint32_t R; /*      (For standard Channels)         */
+        struct {
+            vuint32_t EOC_CH63:1;
+            vuint32_t EOC_CH62:1;
+            vuint32_t EOC_CH61:1;
+            vuint32_t EOC_CH60:1;
+            vuint32_t EOC_CH59:1;
+            vuint32_t EOC_CH58:1;
+            vuint32_t EOC_CH57:1;
+            vuint32_t EOC_CH56:1;
+            vuint32_t EOC_CH55:1;
+            vuint32_t EOC_CH54:1;
+            vuint32_t EOC_CH53:1;
+            vuint32_t EOC_CH52:1;
+            vuint32_t EOC_CH51:1;
+            vuint32_t EOC_CH50:1;
+            vuint32_t EOC_CH49:1;
+            vuint32_t EOC_CH48:1;
+            vuint32_t EOC_CH47:1;
+            vuint32_t EOC_CH46:1;
+            vuint32_t EOC_CH45:1;
+            vuint32_t EOC_CH44:1;
+            vuint32_t EOC_CH43:1;
+            vuint32_t EOC_CH42:1;
+            vuint32_t EOC_CH41:1;
+            vuint32_t EOC_CH40:1;
+            vuint32_t EOC_CH39:1;
+            vuint32_t EOC_CH38:1;
+            vuint32_t EOC_CH37:1;
+            vuint32_t EOC_CH36:1;
+            vuint32_t EOC_CH35:1;
+            vuint32_t EOC_CH34:1;
+            vuint32_t EOC_CH33:1;
+            vuint32_t EOC_CH32:1;
+        } B;
+    } CE0CFR1;
+
+    union { /* ADC0 Channel Pending 2 (Base+0x001C) */
+        vuint32_t R; /*      (For external mux'd Channels)   */
+        struct {
+            vuint32_t EOC_CH95:1;
+            vuint32_t EOC_CH94:1;
+            vuint32_t EOC_CH93:1;
+            vuint32_t EOC_CH92:1;
+            vuint32_t EOC_CH91:1;
+            vuint32_t EOC_CH90:1;
+            vuint32_t EOC_CH89:1;
+            vuint32_t EOC_CH88:1;
+            vuint32_t EOC_CH87:1;
+            vuint32_t EOC_CH86:1;
+            vuint32_t EOC_CH85:1;
+            vuint32_t EOC_CH84:1;
+            vuint32_t EOC_CH83:1;
+            vuint32_t EOC_CH82:1;
+            vuint32_t EOC_CH81:1;
+            vuint32_t EOC_CH80:1;
+            vuint32_t EOC_CH79:1;
+            vuint32_t EOC_CH78:1;
+            vuint32_t EOC_CH77:1;
+            vuint32_t EOC_CH76:1;
+            vuint32_t EOC_CH75:1;
+            vuint32_t EOC_CH74:1;
+            vuint32_t EOC_CH73:1;
+            vuint32_t EOC_CH72:1;
+            vuint32_t EOC_CH71:1;
+            vuint32_t EOC_CH70:1;
+            vuint32_t EOC_CH69:1;
+            vuint32_t EOC_CH68:1;
+            vuint32_t EOC_CH67:1;
+            vuint32_t EOC_CH66:1;
+            vuint32_t EOC_CH65:1;
+            vuint32_t EOC_CH64:1;
+        } B;
+    } CE0CFR2;
+
+    union { /* ADC0 Interrupt Mask (Base+0020) */
+        vuint32_t R;
+        struct {
+            vuint32_t:27;
+            vuint32_t MSKEOCTU:1;
+            vuint32_t MSKJEOC:1;
+            vuint32_t MSKJECH:1;
+            vuint32_t MSKEOC:1;
+            vuint32_t MSKECH:1;
+        } B;
+    } IMR;
+
+    union { /* ADC0 Channel Interrupt Mask 0 (Base+0x0024) */
+        vuint32_t R; /*      (For Precision Channels)               */
+        struct {
+            vuint32_t:16;
+            vuint32_t CIM15:1;
+            vuint32_t CIM14:1;
+            vuint32_t CIM13:1;
+            vuint32_t CIM12:1;
+            vuint32_t CIM11:1;
+            vuint32_t CIM10:1;
+            vuint32_t CIM9:1;
+            vuint32_t CIM8:1;
+            vuint32_t CIM7:1;
+            vuint32_t CIM6:1;
+            vuint32_t CIM5:1;
+            vuint32_t CIM4:1;
+            vuint32_t CIM3:1;
+            vuint32_t CIM2:1;
+            vuint32_t CIM1:1;
+            vuint32_t CIM0:1;
+        } B;
+    } CIMR0;
+
+    union { /* ADC0 Channel Interrupt Mask 1 (+0x0028) */
+        vuint32_t R; /*      (For Standard Channels)            */
+        struct {
+            vuint32_t CIM63:1;
+            vuint32_t CIM62:1;
+            vuint32_t CIM61:1;
+            vuint32_t CIM60:1;
+            vuint32_t CIM59:1;
+            vuint32_t CIM58:1;
+            vuint32_t CIM57:1;
+            vuint32_t CIM56:1;
+            vuint32_t CIM55:1;
+            vuint32_t CIM54:1;
+            vuint32_t CIM53:1;
+            vuint32_t CIM52:1;
+            vuint32_t CIM51:1;
+            vuint32_t CIM50:1;
+            vuint32_t CIM49:1;
+            vuint32_t CIM48:1;
+            vuint32_t CIM47:1;
+            vuint32_t CIM46:1;
+            vuint32_t CIM45:1;
+            vuint32_t CIM44:1;
+            vuint32_t CIM43:1;
+            vuint32_t CIM42:1;
+            vuint32_t CIM41:1;
+            vuint32_t CIM40:1;
+            vuint32_t CIM39:1;
+            vuint32_t CIM38:1;
+            vuint32_t CIM37:1;
+            vuint32_t CIM36:1;
+            vuint32_t CIM35:1;
+            vuint32_t CIM34:1;
+            vuint32_t CIM33:1;
+            vuint32_t CIM32:1;
+        } B;
+    } CIMR1;
+
+    union { /* ADC0 Channel Interrupt Mask 2 (+0x002C) */
+        vuint32_t R; /*      (For PExternal Mux'd Channels)     */
+        struct {
+            vuint32_t CIM95:1;
+            vuint32_t CIM94:1;
+            vuint32_t CIM93:1;
+            vuint32_t CIM92:1;
+            vuint32_t CIM91:1;
+            vuint32_t CIM90:1;
+            vuint32_t CIM89:1;
+            vuint32_t CIM88:1;
+            vuint32_t CIM87:1;
+            vuint32_t CIM86:1;
+            vuint32_t CIM85:1;
+            vuint32_t CIM84:1;
+            vuint32_t CIM83:1;
+            vuint32_t CIM82:1;
+            vuint32_t CIM81:1;
+            vuint32_t CIM80:1;
+            vuint32_t CIM79:1;
+            vuint32_t CIM78:1;
+            vuint32_t CIM77:1;
+            vuint32_t CIM76:1;
+            vuint32_t CIM75:1;
+            vuint32_t CIM74:1;
+            vuint32_t CIM73:1;
+            vuint32_t CIM72:1;
+            vuint32_t CIM71:1;
+            vuint32_t CIM70:1;
+            vuint32_t CIM69:1;
+            vuint32_t CIM68:1;
+            vuint32_t CIM67:1;
+            vuint32_t CIM66:1;
+            vuint32_t CIM65:1;
+            vuint32_t CIM64:1;
+        } B;
+    } CIMR2;
+
+    union { /* ADC0 Watchdog Threshold Interrupt Status (+0x0030)*/
+        vuint32_t R;
+        struct {
+            vuint32_t:20;
+            vuint32_t WDG5H:1;
+            vuint32_t WDG5L:1;
+            vuint32_t WDG4H:1;
+            vuint32_t WDG4L:1;
+            vuint32_t WDG3H:1;
+            vuint32_t WDG3L:1;
+            vuint32_t WDG2H:1;
+            vuint32_t WDG2L:1;
+            vuint32_t WDG1H:1;
+            vuint32_t WDG1L:1;
+            vuint32_t WDG0H:1;
+            vuint32_t WDG0L:1;
+        } B;
+    } WTISR;
+
+    union { /* ADC0 Watchdog Threshold Interrupt Mask (+0x0034) */
+        vuint32_t R;
+        struct {
+            vuint32_t:20;
+            vuint32_t MSKWDG5H:1;
+            vuint32_t MSKWDG5L:1;
+            vuint32_t MSKWDG4H:1;
+            vuint32_t MSKWDG4L:1;
+            vuint32_t MSKWDG3H:1;
+            vuint32_t MSKWDG3L:1;
+            vuint32_t MSKWDG2H:1;
+            vuint32_t MSKWDG2L:1;
+            vuint32_t MSKWDG1H:1;
+            vuint32_t MSKWDG1L:1;
+            vuint32_t MSKWDG0H:1;
+            vuint32_t MSKWDG0L:1;
+        } B;
+    } WTIMR;
+
+    vuint8_t ADC0_reserved1[8]; /* Reserved 8 bytes (Base+0x0038-0x003F) */
+
+    union { /* ADC0 DMA Enable (Base+0x0040) */
+        vuint32_t R;
+        struct {
+            vuint32_t:30;
+            vuint32_t DCLR:1;
+            vuint32_t DMAEN:1;
+        } B;
+    } DMAE;
+
+    union { /* ADC0 DMA Channel Select 0 (Base+0x0044) */
+        vuint32_t R; /*      (for precision channels)           */
+        struct {
+          vuint32_t:16;
+            vuint32_t DMA15:1;
+            vuint32_t DMA14:1;
+            vuint32_t DMA13:1;
+            vuint32_t DMA12:1;
+            vuint32_t DMA11:1;
+            vuint32_t DMA10:1;
+            vuint32_t DMA9:1;
+            vuint32_t DMA8:1;
+            vuint32_t DMA7:1;
+            vuint32_t DMA6:1;
+            vuint32_t DMA5:1;
+            vuint32_t DMA4:1;
+            vuint32_t DMA3:1;
+            vuint32_t DMA2:1;
+            vuint32_t DMA1:1;
+            vuint32_t DMA0:1;
+        } B;
+    } DMAR0;
+
+    union { /* ADC0 DMA Channel Select 1 (Base+0x0048) */
+        vuint32_t R; /*      (for standard channels)            */
+        struct {
+            vuint32_t DMA63:1;
+            vuint32_t DMA62:1;
+            vuint32_t DMA61:1;
+            vuint32_t DMA60:1;
+            vuint32_t DMA59:1;
+            vuint32_t DMA58:1;
+            vuint32_t DMA57:1;
+            vuint32_t DMA56:1;
+            vuint32_t DMA55:1;
+            vuint32_t DMA54:1;
+            vuint32_t DMA53:1;
+            vuint32_t DMA52:1;
+            vuint32_t DMA51:1;
+            vuint32_t DMA50:1;
+            vuint32_t DMA49:1;
+            vuint32_t DMA48:1;
+            vuint32_t DMA47:1;
+            vuint32_t DMA46:1;
+            vuint32_t DMA45:1;
+            vuint32_t DMA44:1;
+            vuint32_t DMA43:1;
+            vuint32_t DMA42:1;
+            vuint32_t DMA41:1;
+            vuint32_t DMA40:1;
+            vuint32_t DMA39:1;
+            vuint32_t DMA38:1;
+            vuint32_t DMA37:1;
+            vuint32_t DMA36:1;
+            vuint32_t DMA35:1;
+            vuint32_t DMA34:1;
+            vuint32_t DMA33:1;
+            vuint32_t DMA32:1;
+        } B;
+    } DMAR1;
+
+    union { /* ADC0 DMA Channel Select 2 (Base+0x004C) */
+        vuint32_t R; /*      (for external mux'd channels)      */
+        struct {
+            vuint32_t DMA95:1;
+            vuint32_t DMA94:1;
+            vuint32_t DMA93:1;
+            vuint32_t DMA92:1;
+            vuint32_t DMA91:1;
+            vuint32_t DMA90:1;
+            vuint32_t DMA89:1;
+            vuint32_t DMA88:1;
+            vuint32_t DMA87:1;
+            vuint32_t DMA86:1;
+            vuint32_t DMA85:1;
+            vuint32_t DMA84:1;
+            vuint32_t DMA83:1;
+            vuint32_t DMA82:1;
+            vuint32_t DMA81:1;
+            vuint32_t DMA80:1;
+            vuint32_t DMA79:1;
+            vuint32_t DMA78:1;
+            vuint32_t DMA77:1;
+            vuint32_t DMA76:1;
+            vuint32_t DMA75:1;
+            vuint32_t DMA74:1;
+            vuint32_t DMA73:1;
+            vuint32_t DMA72:1;
+            vuint32_t DMA71:1;
+            vuint32_t DMA70:1;
+            vuint32_t DMA69:1;
+            vuint32_t DMA68:1;
+            vuint32_t DMA67:1;
+            vuint32_t DMA66:1;
+            vuint32_t DMA65:1;
+            vuint32_t DMA64:1;
+        } B;
+    } DMAR2;
+
+    vuint8_t ADC0_reserved2[16]; /* Reserved 16 bytes (Base+0x0050-0x005F) */
+
+    /* Note the threshold registers are split [0..3] then [4..5]. For this  */
+    /*  reason thay are NOT implemented as an array in order to maintain    */
+    /*  concistency through all THRHLR registers                            */
+
+    union { /* ADC0 Threshold  0 (Base+0x0060) */
+        vuint32_t R;
+        struct {
+          vuint32_t:6;
+            vuint32_t THRH:10;
+            vuint32_t:6;
+            vuint32_t THRL:10;
+        } B;
+    } THRHLR0;
+
+    union { /* ADC0 Threshold  1 (Base+0x0064) */
+        vuint32_t R;
+        struct {
+          vuint32_t:6;
+            vuint32_t THRH:10;
+            vuint32_t:6;
+            vuint32_t THRL:10;
+        } B;
+    } THRHLR1;
+
+    union { /* ADC0 Threshold  2 (Base+0x0068) */
+        vuint32_t R;
+        struct {
+          vuint32_t:6;
+            vuint32_t THRH:10;
+            vuint32_t:6;
+            vuint32_t THRL:10;
+        } B;
+    } THRHLR2;
+
+    union { /* ADC0 Threshold  3 (Base+0x006C) */
+        vuint32_t R;
+        struct {
+          vuint32_t:6;
+            vuint32_t THRH:10;
+            vuint32_t:6;
+            vuint32_t THRL:10;
+        } B;
+    } THRHLR3;
+
+    vuint8_t ADC0_reserved3[16]; /* Reserved 16 bytes (Base+0x0070-0x007F) */
+
+    union { /* ADC0 Presampling Control (Base+0x0080) */
+        vuint32_t R;
+        struct {
+          vuint32_t:25;
+            vuint32_t PREVAL2:2;
+            vuint32_t PREVAL1:2;
+            vuint32_t PREVAL0:2;
+            vuint32_t PRECONV:1;
+        } B;
+    } PSCR;
+
+    union { /* ADC0 Presampling 0 (Base+0x0084) */
+        vuint32_t R; /*      (precision channels)        */
+        struct {
+            vuint32_t:16;
+            vuint32_t PRES15:1;
+            vuint32_t PRES14:1;
+            vuint32_t PRES13:1;
+            vuint32_t PRES12:1;
+            vuint32_t PRES11:1;
+            vuint32_t PRES10:1;
+            vuint32_t PRES9:1;
+            vuint32_t PRES8:1;
+            vuint32_t PRES7:1;
+            vuint32_t PRES6:1;
+            vuint32_t PRES5:1;
+            vuint32_t PRES4:1;
+            vuint32_t PRES3:1;
+            vuint32_t PRES2:1;
+            vuint32_t PRES1:1;
+            vuint32_t PRES0:1;
+        } B;
+    } PSR0;
+
+    union { /* ADC0 Presampling 1 (Base+0x0088) */
+        vuint32_t R; /*      (standard channels)         */
+        struct {
+            vuint32_t PRES63:1;
+            vuint32_t PRES62:1;
+            vuint32_t PRES61:1;
+            vuint32_t PRES60:1;
+            vuint32_t PRES59:1;
+            vuint32_t PRES58:1;
+            vuint32_t PRES57:1;
+            vuint32_t PRES56:1;
+            vuint32_t PRES55:1;
+            vuint32_t PRES54:1;
+            vuint32_t PRES53:1;
+            vuint32_t PRES52:1;
+            vuint32_t PRES51:1;
+            vuint32_t PRES50:1;
+            vuint32_t PRES49:1;
+            vuint32_t PRES48:1;
+            vuint32_t PRES47:1;
+            vuint32_t PRES46:1;
+            vuint32_t PRES45:1;
+            vuint32_t PRES44:1;
+            vuint32_t PRES43:1;
+            vuint32_t PRES42:1;
+            vuint32_t PRES41:1;
+            vuint32_t PRES40:1;
+            vuint32_t PRES39:1;
+            vuint32_t PRES38:1;
+            vuint32_t PRES37:1;
+            vuint32_t PRES36:1;
+            vuint32_t PRES35:1;
+            vuint32_t PRES34:1;
+            vuint32_t PRES33:1;
+            vuint32_t PRES32:1;
+        } B;
+    } PSR1;
+
+    union { /* ADC0 Presampling 2 (Base+0x008C) */
+        vuint32_t R; /*      (external mux'd channels)   */
+        struct {
+            vuint32_t PRES95:1;
+            vuint32_t PRES94:1;
+            vuint32_t PRES93:1;
+            vuint32_t PRES92:1;
+            vuint32_t PRES91:1;
+            vuint32_t PRES90:1;
+            vuint32_t PRES89:1;
+            vuint32_t PRES88:1;
+            vuint32_t PRES87:1;
+            vuint32_t PRES86:1;
+            vuint32_t PRES85:1;
+            vuint32_t PRES84:1;
+            vuint32_t PRES83:1;
+            vuint32_t PRES82:1;
+            vuint32_t PRES81:1;
+            vuint32_t PRES80:1;
+            vuint32_t PRES79:1;
+            vuint32_t PRES78:1;
+            vuint32_t PRES77:1;
+            vuint32_t PRES76:1;
+            vuint32_t PRES75:1;
+            vuint32_t PRES74:1;
+            vuint32_t PRES73:1;
+            vuint32_t PRES72:1;
+            vuint32_t PRES71:1;
+            vuint32_t PRES70:1;
+            vuint32_t PRES69:1;
+            vuint32_t PRES68:1;
+            vuint32_t PRES67:1;
+            vuint32_t PRES66:1;
+            vuint32_t PRES65:1;
+            vuint32_t PRES64:1;
+        } B;
+    } PSR2;
+
+    vuint8_t ADC0_reserved4[4]; /* Reserved 4 bytes (Base+0x0090-0x0093) */
+
+    /* Note the following CTR registers are NOT implemented as an array to */
+    /*  try and maintain some concistency through the header file          */
+    /*  (The registers are however identical)                              */
+
+    union { /* ADC0 Conversion Timing 0 (Base+0x0094) */
+        vuint32_t R; /*      (precision channels)              */
+        struct {
+            vuint32_t:16;
+            vuint32_t INPLATCH:1;
+            vuint32_t:1;
+            vuint32_t OFFSHIFT:2;
+            vuint32_t:1;
+            vuint32_t INPCMP:2;
+            vuint32_t:1;
+            vuint32_t INPSAMP:8;
+        } B;
+    } CTR0;
+
+    union { /* ADC0 Conversion Timing 1 (Base+0x0098) */
+        vuint32_t R; /*      (standard channels)              */
+        struct {
+            vuint32_t:16;
+            vuint32_t INPLATCH:1;
+            vuint32_t:1;
+            vuint32_t OFFSHIFT:2;
+            vuint32_t:1;
+            vuint32_t INPCMP:2;
+            vuint32_t:1;
+            vuint32_t INPSAMP:8;
+        } B;
+    } CTR1;
+
+    union { /* ADC0 Conversion Timing 2 (Base+0x009C) */
+        vuint32_t R; /*      (precision channels)              */
+        struct {
+            vuint32_t:16;
+            vuint32_t INPLATCH:1;
+            vuint32_t:1;
+            vuint32_t OFFSHIFT:2;
+            vuint32_t:1;
+            vuint32_t INPCMP:2;
+            vuint32_t:1;
+            vuint32_t INPSAMP:8;
+        } B;
+    } CTR2;
+
+    vuint8_t ADC0_reserved5[4]; /* Reserved 4 bytes (Base+0x00A0-0x00A3) */
+
+    union { /* ADC0 Normal Conversion Mask 0 (Base+0x00A4) */
+        vuint32_t R; /*      (precision channels)                  */
+        struct {
+            vuint32_t :16;
+            vuint32_t CH15:1;
+            vuint32_t CH14:1;
+            vuint32_t CH13:1;
+            vuint32_t CH12:1;
+            vuint32_t CH11:1;
+            vuint32_t CH10:1;
+            vuint32_t CH9:1;
+            vuint32_t CH8:1;
+            vuint32_t CH7:1;
+            vuint32_t CH6:1;
+            vuint32_t CH5:1;
+            vuint32_t CH4:1;
+            vuint32_t CH3:1;
+            vuint32_t CH2:1;
+            vuint32_t CH1:1;
+            vuint32_t CH0:1;
+        } B;
+    } NCMR0;
+
+    union { /* ADC0 Normal Conversion Mask 1 (Base+0x00A8) */
+        vuint32_t R; /*      (standard channels)                    */
+        struct {
+            vuint32_t CH63:1;
+            vuint32_t CH62:1;
+            vuint32_t CH61:1;
+            vuint32_t CH60:1;
+            vuint32_t CH59:1;
+            vuint32_t CH58:1;
+            vuint32_t CH57:1;
+            vuint32_t CH56:1;
+            vuint32_t CH55:1;
+            vuint32_t CH54:1;
+            vuint32_t CH53:1;
+            vuint32_t CH52:1;
+            vuint32_t CH51:1;
+            vuint32_t CH50:1;
+            vuint32_t CH49:1;
+            vuint32_t CH48:1;
+            vuint32_t CH47:1;
+            vuint32_t CH46:1;
+            vuint32_t CH45:1;
+            vuint32_t CH44:1;
+            vuint32_t CH43:1;
+            vuint32_t CH42:1;
+            vuint32_t CH41:1;
+            vuint32_t CH40:1;
+            vuint32_t CH39:1;
+            vuint32_t CH38:1;
+            vuint32_t CH37:1;
+            vuint32_t CH36:1;
+            vuint32_t CH35:1;
+            vuint32_t CH34:1;
+            vuint32_t CH33:1;
+            vuint32_t CH32:1;
+        } B;
+    } NCMR1;
+
+    union { /* ADC0 Normal Conversion Mask 2 (Base+0x00AC) */
+        vuint32_t R; /*      (For external mux'd channels)          */
+        struct {
+            vuint32_t CH95:1;
+            vuint32_t CH94:1;
+            vuint32_t CH93:1;
+            vuint32_t CH92:1;
+            vuint32_t CH91:1;
+            vuint32_t CH90:1;
+            vuint32_t CH89:1;
+            vuint32_t CH88:1;
+            vuint32_t CH87:1;
+            vuint32_t CH86:1;
+            vuint32_t CH85:1;
+            vuint32_t CH84:1;
+            vuint32_t CH83:1;
+            vuint32_t CH82:1;
+            vuint32_t CH81:1;
+            vuint32_t CH80:1;
+            vuint32_t CH79:1;
+            vuint32_t CH78:1;
+            vuint32_t CH77:1;
+            vuint32_t CH76:1;
+            vuint32_t CH75:1;
+            vuint32_t CH74:1;
+            vuint32_t CH73:1;
+            vuint32_t CH72:1;
+            vuint32_t CH71:1;
+            vuint32_t CH70:1;
+            vuint32_t CH69:1;
+            vuint32_t CH68:1;
+            vuint32_t CH67:1;
+            vuint32_t CH66:1;
+            vuint32_t CH65:1;
+            vuint32_t CH64:1;
+        } B;
+    } NCMR2;
+
+    vuint8_t ADC0_reserved6[4]; /* Reserved 4 bytes (Base+0x00B0-0x00B3) */
+
+    union { /* ADC0 Injected Conversion Mask0 (Base+0x00B4) */
+        vuint32_t R; /*      (precision channels)                    */
+        struct {
+            vuint32_t :16;
+            vuint32_t CH15:1;
+            vuint32_t CH14:1;
+            vuint32_t CH13:1;
+            vuint32_t CH12:1;
+            vuint32_t CH11:1;
+            vuint32_t CH10:1;
+            vuint32_t CH9:1;
+            vuint32_t CH8:1;
+            vuint32_t CH7:1;
+            vuint32_t CH6:1;
+            vuint32_t CH5:1;
+            vuint32_t CH4:1;
+            vuint32_t CH3:1;
+            vuint32_t CH2:1;
+            vuint32_t CH1:1;
+            vuint32_t CH0:1;
+        } B;
+    } JCMR0;
+
+    union { /* ADC0 Injected Conversion Mask1 (Base+0x00B8) */
+        vuint32_t R; /*      (standard channels)                     */
+        struct {
+            vuint32_t CH63:1;
+            vuint32_t CH62:1;
+            vuint32_t CH61:1;
+            vuint32_t CH60:1;
+            vuint32_t CH59:1;
+            vuint32_t CH58:1;
+            vuint32_t CH57:1;
+            vuint32_t CH56:1;
+            vuint32_t CH55:1;
+            vuint32_t CH54:1;
+            vuint32_t CH53:1;
+            vuint32_t CH52:1;
+            vuint32_t CH51:1;
+            vuint32_t CH50:1;
+            vuint32_t CH49:1;
+            vuint32_t CH48:1;
+            vuint32_t CH47:1;
+            vuint32_t CH46:1;
+            vuint32_t CH45:1;
+            vuint32_t CH44:1;
+            vuint32_t CH43:1;
+            vuint32_t CH42:1;
+            vuint32_t CH41:1;
+            vuint32_t CH40:1;
+            vuint32_t CH39:1;
+            vuint32_t CH38:1;
+            vuint32_t CH37:1;
+            vuint32_t CH36:1;
+            vuint32_t CH35:1;
+            vuint32_t CH34:1;
+            vuint32_t CH33:1;
+            vuint32_t CH32:1;
+        } B;
+    } JCMR1;
+
+    union { /* ADC0 Injected Conversion Mask2 (Base+0x00BC) */
+        vuint32_t R; /*      (external mux'd channels)               */
+        struct {
+            vuint32_t CH95:1;
+            vuint32_t CH94:1;
+            vuint32_t CH93:1;
+            vuint32_t CH92:1;
+            vuint32_t CH91:1;
+            vuint32_t CH90:1;
+            vuint32_t CH89:1;
+            vuint32_t CH88:1;
+            vuint32_t CH87:1;
+            vuint32_t CH86:1;
+            vuint32_t CH85:1;
+            vuint32_t CH84:1;
+            vuint32_t CH83:1;
+            vuint32_t CH82:1;
+            vuint32_t CH81:1;
+            vuint32_t CH80:1;
+            vuint32_t CH79:1;
+            vuint32_t CH78:1;
+            vuint32_t CH77:1;
+            vuint32_t CH76:1;
+            vuint32_t CH75:1;
+            vuint32_t CH74:1;
+            vuint32_t CH73:1;
+            vuint32_t CH72:1;
+            vuint32_t CH71:1;
+            vuint32_t CH70:1;
+            vuint32_t CH69:1;
+            vuint32_t CH68:1;
+            vuint32_t CH67:1;
+            vuint32_t CH66:1;
+            vuint32_t CH65:1;
+            vuint32_t CH64:1;
+        } B;
+    } JCMR2;
+
+    vuint8_t ADC0_reserved7[4]; /* Reserved 4 bytes (Base+0x00C0-0x00C3) */
+
+    union { /* ADC0 Decode Signals Delay (Base+0x00C4) */
+        vuint32_t R;
+        struct {
+            vuint32_t:20;
+            vuint32_t DSD:12;
+        } B;
+    } DSDR;
+
+    union { /* ADC0 Power-Down exit Delay (Base+0x00C8) */
+        vuint32_t R;
+        struct {
+            vuint32_t:24;
+            vuint32_t PDED:8;
+        } B;
+    } PDEDR;
+
+    vuint8_t ADC0_reserved8[52]; /* Reserved 52 bytes (Base+0x00CC-0x00FF) */
+
+    union { /* ADC0 Channel 0-95 Data (Base+0x0100-0x027C) */
+        vuint32_t R; /* Note CDR[16..31] are reserved               */
+        struct {
+            vuint32_t:12;
+            vuint32_t VALID:1;
+            vuint32_t OVERW:1;
+            vuint32_t RESULT:2;
+            vuint32_t:6;
+            vuint32_t CDATA:10;
+        } B;
+    } CDR[96];
+
+    union { /* ADC0 Threshold 4 (Base+0x0280) */
+        vuint32_t R;
+        struct {
+            vuint32_t:6;
+            vuint32_t THRH:10;
+            vuint32_t:6;
+            vuint32_t THRL:10;
+        } B;
+    } THRHLR4;
+
+    union { /* ADC0 Threshold 5 (Base+0x0284) */
+        vuint32_t R;
+        struct {
+            vuint32_t:6;
+            vuint32_t THRH:10;
+            vuint32_t:6;
+            vuint32_t THRL:10;
+        } B;
+    } THRHLR5;
+
+    vuint8_t ADC0_reserved10[40]; /* Reserved 40 bytes (Base+0x0288-0x02AF) */
+
+    union { /* ADC0 Channel Watchdog Select 0 (Base+0x02B0) */
+        vuint32_t R; /*      (precision channels)                    */
+        struct {
+            vuint32_t:1;
+            vuint32_t WSEL_CH7:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH6:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH5:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH4:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH3:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH2:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH1:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH0:3;
+        } B;
+    } CWSELR0;
+
+    union { /* ADC0 Channel Watchdog Select 1 (Base+0x02B4) */
+        vuint32_t R; /*      (precision channels)                    */
+        struct {
+            vuint32_t:1;
+            vuint32_t WSEL_CH15:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH14:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH13:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH12:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH11:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH10:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH9:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH8:3;
+        } B;
+    } CWSELR1;
+
+    vuint8_t ADC0_reserved11[8]; /* Reserved 8 bytes (Base+0x02B8-0x02BF) */
+
+    union { /* ADC0 Channel Watchdog Select 4 (Base+0x02C0) */
+        vuint32_t R; /*      (standard channels)                     */
+        struct {
+            vuint32_t:1;
+            vuint32_t WSEL_CH39:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH38:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH37:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH36:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH35:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH34:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH33:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH32:3;
+        } B;
+    } CWSELR4;
+
+    union { /* ADC0 Channel Watchdog Select 5 (Base+0x02C4) */
+        vuint32_t R; /*      (standard channels)                     */
+        struct {
+            vuint32_t:1;
+            vuint32_t WSEL_CH47:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH46:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH45:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH44:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH43:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH42:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH41:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH40:3;
+        } B;
+    } CWSELR5;
+
+    union { /* ADC0 Channel Watchdog Select 6 (Base+0x02C8) */
+        vuint32_t R; /*      (standard channels)                     */
+        struct {
+            vuint32_t:1;
+            vuint32_t WSEL_CH55:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH54:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH53:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH52:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH51:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH50:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH49:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH48:3;
+        } B;
+    } CWSELR6;
+
+    union { /* ADC0 Channel Watchdog Select 7 (Base+0x02CC) */
+        vuint32_t R; /*      (standard channels)                     */
+        struct {
+            vuint32_t:1;
+            vuint32_t WSEL_CH63:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH62:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH61:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH60:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH59:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH58:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH57:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH56:3;
+        } B;
+    } CWSELR7;
+
+    union { /* ADC0 Channel Watchdog Select 8 (Base+0x02D0) */
+        vuint32_t R; /*      (external mux'd channels)               */
+        struct {
+            vuint32_t:1;
+            vuint32_t WSEL_CH71:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH70:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH69:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH68:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH67:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH66:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH65:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH64:3;
+        } B;
+    } CWSELR8;
+
+    union { /* ADC0 Channel Watchdog Select 9 (Base+0x02D4) */
+        vuint32_t R; /*      (external mux'd channels)               */
+        struct {
+            vuint32_t:1;
+            vuint32_t WSEL_CH79:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH78:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH77:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH76:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH75:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH74:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH73:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH72:3;
+        } B;
+    } CWSELR9;
+
+    union { /* ADC0 Channel Watchdog Select 10 (Base+0x02D8)*/
+        vuint32_t R; /*      (external mux'd channels)               */
+        struct {
+            vuint32_t:1;
+            vuint32_t WSEL_CH87:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH86:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH85:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH84:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH83:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH82:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH81:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH80:3;
+        } B;
+    } CWSELR10;
+
+    union { /* ADC0 Channel Watchdog Select 11 (Base+0x02DC)*/
+        vuint32_t R; /*      (external mux'd channels)               */
+        struct {
+            vuint32_t:1;
+            vuint32_t WSEL_CH95:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH94:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH93:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH92:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH91:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH90:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH89:3;
+            vuint32_t:1;
+            vuint32_t WSEL_CH88:3;
+        } B;
+    } CWSELR11;
+
+    union { /* ADC0 Channel Watchdog Enable0 (Base++0x02E0) */
+        vuint32_t R; /*      (precision channels)                    */
+        struct {
+            vuint32_t :16;
+            vuint32_t CWEN15:1;
+            vuint32_t CWEN14:1;
+            vuint32_t CWEN13:1;
+            vuint32_t CWEN12:1;
+            vuint32_t CWEN11:1;
+            vuint32_t CWEN10:1;
+            vuint32_t CWEN9:1;
+            vuint32_t CWEN8:1;
+            vuint32_t CWEN7:1;
+            vuint32_t CWEN6:1;
+            vuint32_t CWEN5:1;
+            vuint32_t CWEN4:1;
+            vuint32_t CWEN3:1;
+            vuint32_t CWEN2:1;
+            vuint32_t CWEN1:1;
+            vuint32_t CWEN0:1;
+        } B;
+    } CWENR0;
+
+    union { /* ADC0 Channel Watchdog Enable1 (Base++0x02E4) */
+        vuint32_t R; /*      (standard channels)                     */
+        struct {
+            vuint32_t CWEN63:1;
+            vuint32_t CWEN62:1;
+            vuint32_t CWEN61:1;
+            vuint32_t CWEN60:1;
+            vuint32_t CWEN59:1;
+            vuint32_t CWEN58:1;
+            vuint32_t CWEN57:1;
+            vuint32_t CWEN56:1;
+            vuint32_t CWEN55:1;
+            vuint32_t CWEN54:1;
+            vuint32_t CWEN53:1;
+            vuint32_t CWEN52:1;
+            vuint32_t CWEN51:1;
+            vuint32_t CWEN50:1;
+            vuint32_t CWEN49:1;
+            vuint32_t CWEN48:1;
+            vuint32_t CWEN47:1;
+            vuint32_t CWEN46:1;
+            vuint32_t CWEN45:1;
+            vuint32_t CWEN44:1;
+            vuint32_t CWEN43:1;
+            vuint32_t CWEN42:1;
+            vuint32_t CWEN41:1;
+            vuint32_t CWEN40:1;
+            vuint32_t CWEN39:1;
+            vuint32_t CWEN38:1;
+            vuint32_t CWEN37:1;
+            vuint32_t CWEN36:1;
+            vuint32_t CWEN35:1;
+            vuint32_t CWEN34:1;
+            vuint32_t CWEN33:1;
+            vuint32_t CWEN32:1;
+        } B;
+    } CWENR1;
+
+    union { /* ADC0 Channel Watchdog Enable2 (Base++0x02E8) */
+        vuint32_t R; /*      (external mux'd channels)               */
+        struct {
+            vuint32_t CWEN95:1;
+            vuint32_t CWEN94:1;
+            vuint32_t CWEN93:1;
+            vuint32_t CWEN92:1;
+            vuint32_t CWEN91:1;
+            vuint32_t CWEN90:1;
+            vuint32_t CWEN89:1;
+            vuint32_t CWEN88:1;
+            vuint32_t CWEN87:1;
+            vuint32_t CWEN86:1;
+            vuint32_t CWEN85:1;
+            vuint32_t CWEN84:1;
+            vuint32_t CWEN83:1;
+            vuint32_t CWEN82:1;
+            vuint32_t CWEN81:1;
+            vuint32_t CWEN80:1;
+            vuint32_t CWEN79:1;
+            vuint32_t CWEN78:1;
+            vuint32_t CWEN77:1;
+            vuint32_t CWEN76:1;
+            vuint32_t CWEN75:1;
+            vuint32_t CWEN74:1;
+            vuint32_t CWEN73:1;
+            vuint32_t CWEN72:1;
+            vuint32_t CWEN71:1;
+            vuint32_t CWEN70:1;
+            vuint32_t CWEN69:1;
+            vuint32_t CWEN68:1;
+            vuint32_t CWEN67:1;
+            vuint32_t CWEN66:1;
+            vuint32_t CWEN65:1;
+            vuint32_t CWEN64:1;
+        } B;
+    } CWENR2;
+
+    vuint8_t ADC0_reserved12[4]; /* Reserved 4 bytes (Base+0x02EC-0x02EF) */
+
+    union { /* ADC0 Watchdog out of range 0 (Base+0x02F0) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t AWOR_CH15:1;
+            vuint32_t AWOR_CH14:1;
+            vuint32_t AWOR_CH13:1;
+            vuint32_t AWOR_CH12:1;
+            vuint32_t AWOR_CH11:1;
+            vuint32_t AWOR_CH10:1;
+            vuint32_t AWOR_CH9:1;
+            vuint32_t AWOR_CH8:1;
+            vuint32_t AWOR_CH7:1;
+            vuint32_t AWOR_CH6:1;
+            vuint32_t AWOR_CH5:1;
+            vuint32_t AWOR_CH4:1;
+            vuint32_t AWOR_CH3:1;
+            vuint32_t AWOR_CH2:1;
+            vuint32_t AWOR_CH1:1;
+            vuint32_t AWOR_CH0:1;
+        } B;
+    } AWORR0;
+
+    union { /* ADC0 Watchdog out of range 1 (Base+0x02F4) */
+        vuint32_t R;
+        struct {
+            vuint32_t AWORR_CH63:1;
+            vuint32_t AWORR_CH62:1;
+            vuint32_t AWORR_CH61:1;
+            vuint32_t AWOR_CH60:1;
+            vuint32_t AWOR_CH59:1;
+            vuint32_t AWOR_CH58:1;
+            vuint32_t AWOR_CH57:1;
+            vuint32_t AWOR_CH56:1;
+            vuint32_t AWOR_CH55:1;
+            vuint32_t AWOR_CH54:1;
+            vuint32_t AWOR_CH53:1;
+            vuint32_t AWOR_CH52:1;
+            vuint32_t AWOR_CH51:1;
+            vuint32_t AWOR_CH50:1;
+            vuint32_t AWOR_CH49:1;
+            vuint32_t AWOR_CH48:1;
+            vuint32_t AWOR_CH47:1;
+            vuint32_t AWOR_CH46:1;
+            vuint32_t AWOR_CH45:1;
+            vuint32_t AWOR_CH44:1;
+            vuint32_t AWOR_CH43:1;
+            vuint32_t AWOR_CH42:1;
+            vuint32_t AWOR_CH41:1;
+            vuint32_t AWOR_CH40:1;
+            vuint32_t AWOR_CH39:1;
+            vuint32_t AWOR_CH38:1;
+            vuint32_t AWOR_CH37:1;
+            vuint32_t AWOR_CH36:1;
+            vuint32_t AWOR_CH35:1;
+            vuint32_t AWOR_CH34:1;
+            vuint32_t AWOR_CH33:1;
+            vuint32_t AWOR_CH32:1;
+        } B;
+    } AWORR1;
+
+    union { /* ADC0 Watchdog out of range 2 (Base+0x02F8) */
+        vuint32_t R;
+        struct {
+            vuint32_t AWOR_CH95:1;
+            vuint32_t AWOR_CH94:1;
+            vuint32_t AWOR_CH93:1;
+            vuint32_t AWOR_CH92:1;
+            vuint32_t AWOR_CH91:1;
+            vuint32_t AWOR_CH90:1;
+            vuint32_t AWOR_CH89:1;
+            vuint32_t AWOR_CH88:1;
+            vuint32_t AWOR_CH87:1;
+            vuint32_t AWOR_CH86:1;
+            vuint32_t AWOR_CH85:1;
+            vuint32_t AWOR_CH84:1;
+            vuint32_t AWOR_CH83:1;
+            vuint32_t AWOR_CH82:1;
+            vuint32_t AWOR_CH81:1;
+            vuint32_t AWOR_CH80:1;
+            vuint32_t AWOR_CH79:1;
+            vuint32_t AWOR_CH78:1;
+            vuint32_t AWOR_CH77:1;
+            vuint32_t AWOR_CH76:1;
+            vuint32_t AWOR_CH75:1;
+            vuint32_t AWOR_CH74:1;
+            vuint32_t AWOR_CH73:1;
+            vuint32_t AWOR_CH72:1;
+            vuint32_t AWOR_CH71:1;
+            vuint32_t AWOR_CH70:1;
+            vuint32_t AWOR_CH69:1;
+            vuint32_t AWOR_CH68:1;
+            vuint32_t AWOR_CH67:1;
+            vuint32_t AWOR_CH66:1;
+            vuint32_t AWOR_CH65:1;
+            vuint32_t AWOR_CH64:1;
+        } B;
+    } AWORR2;
+
+   vuint8_t ADC0_reserved13[4]; /* Reserved 4 bytes (Base+0x02FC-0x02FF) */
+
+}; /* end of ADC0_tag */
+/****************************************************************************/
+/*                          MODULE : ADC1 (12 Bit)                          */
+/*                                   CH[0..15], CH[32..44]                  */
+/****************************************************************************/
+struct ADC1_tag {
+
+    union { /* ADC1 Main Configuration (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t OWREN:1;
+            vuint32_t WLSIDE:1;
+            vuint32_t MODE:1;
+            vuint32_t:4;
+            vuint32_t NSTART:1;
+            vuint32_t:1;
+            vuint32_t JTRGEN:1;
+            vuint32_t JEDGE:1;
+            vuint32_t JSTART:1;
+            vuint32_t:2;
+            vuint32_t CTUEN:1;
+            vuint32_t:9;
+            vuint32_t ABORT_CHAIN:1;
+            vuint32_t ABORT:1;
+            vuint32_t ACKO:1;
+            vuint32_t:4;
+            vuint32_t PWDN:1;
+        } B;
+    } MCR;
+
+    union { /* ADC1 Main Status (Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t:7;
+            vuint32_t NSTART:1;
+            vuint32_t JABORT:1;
+            vuint32_t:2;
+            vuint32_t JSTART:1;
+            vuint32_t:3;
+            vuint32_t CTUSTART:1;
+            vuint32_t CHADDR:7;
+            vuint32_t:3;
+            vuint32_t ACKO:1;
+            vuint32_t:2;
+            vuint32_t ADCSTATUS:3;
+        } B;
+    } MSR;
+
+    vuint8_t ADC1_reserved0[8]; /* Reserved 8 bytes (Base+0x0008-0x000F) */
+
+    union { /* ADC1 Interrupt Status (Base+0x0010) */
+        vuint32_t R;
+        struct {
+            vuint32_t:27;
+            vuint32_t EOCTU:1;
+            vuint32_t JEOC:1;
+            vuint32_t JECH:1;
+            vuint32_t EOC:1;
+            vuint32_t ECH:1;
+        } B;
+    } ISR;
+
+    union { /* ADC1 Channel Pending 0 (Base+0x0014) */
+        vuint32_t R; /*      (For precision channels)        */
+        struct {
+            vuint32_t :16;
+            vuint32_t EOC_CH15:1;
+            vuint32_t EOC_CH14:1;
+            vuint32_t EOC_CH13:1;
+            vuint32_t EOC_CH12:1;
+            vuint32_t EOC_CH11:1;
+            vuint32_t EOC_CH10:1;
+            vuint32_t EOC_CH9:1;
+            vuint32_t EOC_CH8:1;
+            vuint32_t EOC_CH7:1;
+            vuint32_t EOC_CH6:1;
+            vuint32_t EOC_CH5:1;
+            vuint32_t EOC_CH4:1;
+            vuint32_t EOC_CH3:1;
+            vuint32_t EOC_CH2:1;
+            vuint32_t EOC_CH1:1;
+            vuint32_t EOC_CH0:1;
+        } B;
+    } CE0CFR0;
+
+    union { /* ADC1 Channel Pending 1 (Base+0x0018) */
+        vuint32_t R; /*      (For standard Channels)         */
+        struct {
+            vuint32_t:19;
+            vuint32_t EOC_CH44:1;
+            vuint32_t EOC_CH43:1;
+            vuint32_t EOC_CH42:1;
+            vuint32_t EOC_CH41:1;
+            vuint32_t EOC_CH40:1;
+            vuint32_t EOC_CH39:1;
+            vuint32_t EOC_CH38:1;
+            vuint32_t EOC_CH37:1;
+            vuint32_t EOC_CH36:1;
+            vuint32_t EOC_CH35:1;
+            vuint32_t EOC_CH34:1;
+            vuint32_t EOC_CH33:1;
+            vuint32_t EOC_CH32:1;
+        } B;
+    } CE0CFR1;
+
+    vuint8_t ADC1_reserved1[4]; /* Reserved 4 bytes (Base+0x001C-0x001F) */
+
+    union { /* ADC1 Interrupt Mask (Base+0020) */
+        vuint32_t R;
+        struct {
+            vuint32_t:27;
+            vuint32_t MSKEOCTU:1;
+            vuint32_t MSKJEOC:1;
+            vuint32_t MSKJECH:1;
+            vuint32_t MSKEOC:1;
+            vuint32_t MSKECH:1;
+        } B;
+    } IMR;
+
+    union { /* ADC1 Channel Interrupt Mask 0 (Base+0x0024) */
+        vuint32_t R; /*      (For Precision Channels)               */
+        struct {
+            vuint32_t:16;
+            vuint32_t CIM15:1;
+            vuint32_t CIM14:1;
+            vuint32_t CIM13:1;
+            vuint32_t CIM12:1;
+            vuint32_t CIM11:1;
+            vuint32_t CIM10:1;
+            vuint32_t CIM9:1;
+            vuint32_t CIM8:1;
+            vuint32_t CIM7:1;
+            vuint32_t CIM6:1;
+            vuint32_t CIM5:1;
+            vuint32_t CIM4:1;
+            vuint32_t CIM3:1;
+            vuint32_t CIM2:1;
+            vuint32_t CIM1:1;
+            vuint32_t CIM0:1;
+        } B;
+    } CIMR0;
+
+    union { /* ADC1 Channel Interrupt Mask 1 (+0x0028) */
+        vuint32_t R; /*      (For Standard Channels)            */
+        struct {
+            vuint32_t:19;
+            vuint32_t CIM44:1;
+            vuint32_t CIM43:1;
+            vuint32_t CIM42:1;
+            vuint32_t CIM41:1;
+            vuint32_t CIM40:1;
+            vuint32_t CIM39:1;
+            vuint32_t CIM38:1;
+            vuint32_t CIM37:1;
+            vuint32_t CIM36:1;
+            vuint32_t CIM35:1;
+            vuint32_t CIM34:1;
+            vuint32_t CIM33:1;
+            vuint32_t CIM32:1;
+        } B;
+    } CIMR1;
+
+    vuint8_t ADC1_reserved2[4]; /* Reserved 4 bytes (Base+0x002C-0x002F) */
+
+    union { /* ADC1 Watchdog Threshold Interrupt Status (+0x0030)*/
+        vuint32_t R;
+        struct {
+            vuint32_t:26;
+            vuint32_t WDG2H:1;
+            vuint32_t WDG2L:1;
+            vuint32_t WDG1H:1;
+            vuint32_t WDG1L:1;
+            vuint32_t WDG0H:1;
+            vuint32_t WDG0L:1;
+        } B;
+    } WTISR;
+
+    union { /* ADC1 Watchdog Threshold Interrupt Mask (+0x0034) */
+        vuint32_t R;
+        struct {
+            vuint32_t:26;
+            vuint32_t MSKWDG2H:1;
+            vuint32_t MSKWDG2L:1;
+            vuint32_t MSKWDG1H:1;
+            vuint32_t MSKWDG1L:1;
+            vuint32_t MSKWDG0H:1;
+            vuint32_t MSKWDG0L:1;
+        } B;
+    } WTIMR;
+
+    vuint8_t ADC1_reserved3[8]; /* Reserved 8 bytes (Base+0x0038-0x003F) */
+
+    union { /* ADC1 DMA Enable (Base+0x0040) */
+        vuint32_t R;
+        struct {
+            vuint32_t:30;
+            vuint32_t DCLR:1;
+            vuint32_t DMAEN:1;
+        } B;
+    } DMAE;
+
+    union { /* ADC1 DMA Channel Select 0 (Base+0x0044) */
+        vuint32_t R; /*      (for precision channels)           */
+        struct {
+          vuint32_t:16;
+            vuint32_t DMA15:1;
+            vuint32_t DMA14:1;
+            vuint32_t DMA13:1;
+            vuint32_t DMA12:1;
+            vuint32_t DMA11:1;
+            vuint32_t DMA10:1;
+            vuint32_t DMA9:1;
+            vuint32_t DMA8:1;
+            vuint32_t DMA7:1;
+            vuint32_t DMA6:1;
+            vuint32_t DMA5:1;
+            vuint32_t DMA4:1;
+            vuint32_t DMA3:1;
+            vuint32_t DMA2:1;
+            vuint32_t DMA1:1;
+            vuint32_t DMA0:1;
+        } B;
+    } DMAR0;
+
+    union { /* ADC1 DMA Channel Select 1 (Base+0x0048) */
+        vuint32_t R; /*      (for standard channels)            */
+        struct {
+            vuint32_t:19;
+            vuint32_t DMA44:1;
+            vuint32_t DMA43:1;
+            vuint32_t DMA42:1;
+            vuint32_t DMA41:1;
+            vuint32_t DMA40:1;
+            vuint32_t DMA39:1;
+            vuint32_t DMA38:1;
+            vuint32_t DMA37:1;
+            vuint32_t DMA36:1;
+            vuint32_t DMA35:1;
+            vuint32_t DMA34:1;
+            vuint32_t DMA33:1;
+            vuint32_t DMA32:1;
+        } B;
+    } DMAR1;
+
+    vuint8_t ADC1_reserved4[20]; /* Reserved 20 bytes (Base+0x004C-0x005F) */
+
+    /* Note the threshold registers are not implemented as an array for    */
+    /*  concistency with ADC0 header section                               */
+
+    union { /* ADC1 Threshold  0 (Base+0x0060) */
+        vuint32_t R;
+        struct {
+          vuint32_t:4;
+            vuint32_t THRH:12;
+            vuint32_t:4;
+            vuint32_t THRL:12;
+        } B;
+    } THRHLR0;
+
+    union { /* ADC1 Threshold  1 (Base+0x0064) */
+        vuint32_t R;
+        struct {
+            vuint32_t:4;
+            vuint32_t THRH:12;
+            vuint32_t:4;
+            vuint32_t THRL:12;
+        } B;
+    } THRHLR1;
+
+    union { /* ADC1 Threshold  2 (Base+0x0068) */
+        vuint32_t R;
+        struct {
+          vuint32_t:4;
+            vuint32_t THRH:12;
+            vuint32_t:4;
+            vuint32_t THRL:12;
+        } B;
+    } THRHLR2;
+
+    vuint8_t ADC1_reserved5[20]; /* Reserved 20 bytes (Base+0x006C-0x007F) */
+
+    union { /* ADC1 Presampling Control (Base+0x0080) */
+        vuint32_t R;
+        struct {
+          vuint32_t:25;
+            vuint32_t PREVAL2:2;
+            vuint32_t PREVAL1:2;
+            vuint32_t PREVAL0:2;
+            vuint32_t PRECONV:1;
+        } B;
+    } PSCR;
+
+    union { /* ADC1 Presampling 0 (Base+0x0084) */
+        vuint32_t R; /*      (precision channels)        */
+        struct {
+            vuint32_t:16;
+            vuint32_t PRES15:1;
+            vuint32_t PRES14:1;
+            vuint32_t PRES13:1;
+            vuint32_t PRES12:1;
+            vuint32_t PRES11:1;
+            vuint32_t PRES10:1;
+            vuint32_t PRES9:1;
+            vuint32_t PRES8:1;
+            vuint32_t PRES7:1;
+            vuint32_t PRES6:1;
+            vuint32_t PRES5:1;
+            vuint32_t PRES4:1;
+            vuint32_t PRES3:1;
+            vuint32_t PRES2:1;
+            vuint32_t PRES1:1;
+            vuint32_t PRES0:1;
+        } B;
+    } PSR0;
+
+    union { /* ADC1 Presampling 1 (Base+0x0088) */
+        vuint32_t R; /*      (standard channels)         */
+        struct {
+            vuint32_t:19;
+            vuint32_t PRES44:1;
+            vuint32_t PRES43:1;
+            vuint32_t PRES42:1;
+            vuint32_t PRES41:1;
+            vuint32_t PRES40:1;
+            vuint32_t PRES39:1;
+            vuint32_t PRES38:1;
+            vuint32_t PRES37:1;
+            vuint32_t PRES36:1;
+            vuint32_t PRES35:1;
+            vuint32_t PRES34:1;
+            vuint32_t PRES33:1;
+            vuint32_t PRES32:1;
+        } B;
+    } PSR1;
+
+    vuint8_t ADC1_reserved6[8]; /* Reserved 8 bytes (Base+0x008C-0x0093) */
+
+    /* Note the following CTR registers are NOT implemented as an array to */
+    /*  try and maintain some concistency through the header file          */
+    /*  (The registers are however identical)                              */
+
+    union { /* ADC1 Conversion Timing 0 (Base+0x0094) */
+        vuint32_t R; /*      (precision channels)              */
+        struct {
+            vuint32_t:16;
+            vuint32_t INPLATCH:1;
+            vuint32_t:1;
+            vuint32_t OFFSHIFT:2;
+            vuint32_t:1;
+            vuint32_t INPCMP:2;
+            vuint32_t:1;
+            vuint32_t INPSAMP:8;
+        } B;
+    } CTR0;
+
+    union { /* ADC1 Conversion Timing 1 (Base+0x0098) */
+        vuint32_t R; /*      (standard channels)              */
+        struct {
+            vuint32_t:16;
+            vuint32_t INPLATCH:1;
+            vuint32_t:1;
+            vuint32_t OFFSHIFT:2;
+            vuint32_t:1;
+            vuint32_t INPCMP:2;
+            vuint32_t:1;
+            vuint32_t INPSAMP:8;
+        } B;
+    } CTR1;
+
+    vuint8_t ADC1_reserved7[8]; /* Reserved 8 bytes (Base+0x009C-0x00A3) */
+
+    union { /* ADC1 Normal Conversion Mask 0 (Base+0x00A4) */
+        vuint32_t R; /*      (precision channels)                  */
+        struct {
+            vuint32_t :16;
+            vuint32_t CH15:1;
+            vuint32_t CH14:1;
+            vuint32_t CH13:1;
+            vuint32_t CH12:1;
+            vuint32_t CH11:1;
+            vuint32_t CH10:1;
+            vuint32_t CH9:1;
+            vuint32_t CH8:1;
+            vuint32_t CH7:1;
+            vuint32_t CH6:1;
+            vuint32_t CH5:1;
+            vuint32_t CH4:1;
+            vuint32_t CH3:1;
+            vuint32_t CH2:1;
+            vuint32_t CH1:1;
+            vuint32_t CH0:1;
+        } B;
+    } NCMR0;
+
+    union { /* ADC1 Normal Conversion Mask 1 (Base+0x00A8) */
+        vuint32_t R; /*      (standard channels)                    */
+        struct {
+            vuint32_t:19;
+            vuint32_t CH44:1;
+            vuint32_t CH43:1;
+            vuint32_t CH42:1;
+            vuint32_t CH41:1;
+            vuint32_t CH40:1;
+            vuint32_t CH39:1;
+            vuint32_t CH38:1;
+            vuint32_t CH37:1;
+            vuint32_t CH36:1;
+            vuint32_t CH35:1;
+            vuint32_t CH34:1;
+            vuint32_t CH33:1;
+            vuint32_t CH32:1;
+        } B;
+    } NCMR1;
+
+    vuint8_t ADC1_reserved8[8]; /* Reserved 8 bytes (Base+0x00AC-0x00B3) */
+
+    union { /* ADC1 Injected Conversion Mask0 (Base+0x00B4) */
+        vuint32_t R; /*      (precision channels)                    */
+        struct {
+            vuint32_t :16;
+            vuint32_t CH15:1;
+            vuint32_t CH14:1;
+            vuint32_t CH13:1;
+            vuint32_t CH12:1;
+            vuint32_t CH11:1;
+            vuint32_t CH10:1;
+            vuint32_t CH9:1;
+            vuint32_t CH8:1;
+            vuint32_t CH7:1;
+            vuint32_t CH6:1;
+            vuint32_t CH5:1;
+            vuint32_t CH4:1;
+            vuint32_t CH3:1;
+            vuint32_t CH2:1;
+            vuint32_t CH1:1;
+            vuint32_t CH0:1;
+        } B;
+    } JCMR0;
+
+    union { /* ADC1 Injected Conversion Mask1 (Base+0x00B8) */
+        vuint32_t R; /*      (standard channels)                     */
+        struct {
+            vuint32_t :19;
+            vuint32_t CH44:1;
+            vuint32_t CH43:1;
+            vuint32_t CH42:1;
+            vuint32_t CH41:1;
+            vuint32_t CH40:1;
+            vuint32_t CH39:1;
+            vuint32_t CH38:1;
+            vuint32_t CH37:1;
+            vuint32_t CH36:1;
+            vuint32_t CH35:1;
+            vuint32_t CH34:1;
+            vuint32_t CH33:1;
+            vuint32_t CH32:1;
+        } B;
+    } JCMR1;
+
+    vuint8_t ADC1_reserved9[68]; /* Reserved 68 bytes (Base+0x00BC-0x00FF) */
+
+    union { /* ADC1 Channel 0-44 Data (Base+0x0100-0x01B0) */
+        vuint32_t R; /* Note CDR[16..31] are reserved               */
+        struct {
+            vuint32_t:12;
+            vuint32_t VALID:1;
+            vuint32_t OVERW:1;
+            vuint32_t RESULT:2;
+            vuint32_t:4;
+            vuint32_t CDATA:12;
+        } B;
+    } CDR[45];
+
+    vuint8_t ADC1_reserved10[252]; /* Reserved 252 bytes (Base+0x01B4-0x002AF) */
+
+    union { /* ADC1 Channel Watchdog Select 0 (Base+0x02B0) */
+        vuint32_t R; /*      (precision channels)                    */
+        struct {
+            vuint32_t:2;
+            vuint32_t WSEL_CH7:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH6:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH5:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH4:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH3:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH2:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH1:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH0:2;
+        } B;
+    } CWSELR0;
+
+    union { /* ADC1 Channel Watchdog Select 1 (Base+0x02B4) */
+        vuint32_t R; /*      (precision channels)                    */
+        struct {
+            vuint32_t:2;
+            vuint32_t WSEL_CH15:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH14:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH13:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH12:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH11:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH10:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH9:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH8:2;
+        } B;
+    } CWSELR1;
+
+    vuint8_t ADC1_reserved11[8]; /* Reserved 8 bytes (Base+0x02B8-0x02BF) */
+
+    union { /* ADC1 Channel Watchdog Select 4 (Base+0x02C0) */
+        vuint32_t R; /*      (standard channels)                     */
+        struct {
+            vuint32_t:2;
+            vuint32_t WSEL_CH39:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH38:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH37:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH36:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH35:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH34:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH33:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH32:2;
+        } B;
+    } CWSELR4;
+
+    union { /* ADC1 Channel Watchdog Select 5 (Base+0x02C4) */
+        vuint32_t R; /*      (standard channels)                     */
+        struct {
+            vuint32_t:14;
+            vuint32_t WSEL_CH44:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH43:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH42:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH41:2;
+            vuint32_t:2;
+            vuint32_t WSEL_CH40:2;
+        } B;
+    } CWSELR5;
+
+    vuint8_t ADC1_reserved12[24]; /* Reserved 24 bytes (Base+0x02C8-0x02DF) */
+
+    union { /* ADC1 Channel Watchdog Enable0 (Base++0x02E0) */
+        vuint32_t R; /*      (precision channels)                    */
+        struct {
+            vuint32_t :16;
+            vuint32_t CWEN15:1;
+            vuint32_t CWEN14:1;
+            vuint32_t CWEN13:1;
+            vuint32_t CWEN12:1;
+            vuint32_t CWEN11:1;
+            vuint32_t CWEN10:1;
+            vuint32_t CWEN9:1;
+            vuint32_t CWEN8:1;
+            vuint32_t CWEN7:1;
+            vuint32_t CWEN6:1;
+            vuint32_t CWEN5:1;
+            vuint32_t CWEN4:1;
+            vuint32_t CWEN3:1;
+            vuint32_t CWEN2:1;
+            vuint32_t CWEN1:1;
+            vuint32_t CWEN0:1;
+        } B;
+    } CWENR0;
+
+    union { /* ADC1 Channel Watchdog Enable1 (Base++0x02E4) */
+        vuint32_t R; /*      (standard channels)                     */
+        struct {
+            vuint32_t :19;
+            vuint32_t CWEN44:1;
+            vuint32_t CWEN43:1;
+            vuint32_t CWEN42:1;
+            vuint32_t CWEN41:1;
+            vuint32_t CWEN40:1;
+            vuint32_t CWEN39:1;
+            vuint32_t CWEN38:1;
+            vuint32_t CWEN37:1;
+            vuint32_t CWEN36:1;
+            vuint32_t CWEN35:1;
+            vuint32_t CWEN34:1;
+            vuint32_t CWEN33:1;
+            vuint32_t CWEN32:1;
+        } B;
+    } CWENR1;
+
+    vuint8_t ADC1_reserved13[8]; /* Reserved 8 bytes (Base+0x02E8-0x02EF) */
+
+    union { /* ADC1 Watchdog out of range 0 (Base+0x02F0) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t AWOR_CH15:1;
+            vuint32_t AWOR_CH14:1;
+            vuint32_t AWOR_CH13:1;
+            vuint32_t AWOR_CH12:1;
+            vuint32_t AWOR_CH11:1;
+            vuint32_t AWOR_CH10:1;
+            vuint32_t AWOR_CH9:1;
+            vuint32_t AWOR_CH8:1;
+            vuint32_t AWOR_CH7:1;
+            vuint32_t AWOR_CH6:1;
+            vuint32_t AWOR_CH5:1;
+            vuint32_t AWOR_CH4:1;
+            vuint32_t AWOR_CH3:1;
+            vuint32_t AWOR_CH2:1;
+            vuint32_t AWOR_CH1:1;
+            vuint32_t AWOR_CH0:1;
+        } B;
+    } AWORR0;
+
+    union { /* ADC1 Watchdog out of range 1 (Base+0x02F4) */
+        vuint32_t R;
+        struct {
+            vuint32_t :19;
+            vuint32_t AWOR_CH44:1;
+            vuint32_t AWOR_CH43:1;
+            vuint32_t AWOR_CH42:1;
+            vuint32_t AWOR_CH41:1;
+            vuint32_t AWOR_CH40:1;
+            vuint32_t AWOR_CH39:1;
+            vuint32_t AWOR_CH38:1;
+            vuint32_t AWOR_CH37:1;
+            vuint32_t AWOR_CH36:1;
+            vuint32_t AWOR_CH35:1;
+            vuint32_t AWOR_CH34:1;
+            vuint32_t AWOR_CH33:1;
+            vuint32_t AWOR_CH32:1;
+        } B;
+    } AWORR1;
+
+    vuint8_t ADC1_reserved14[8]; /* Reserved 8 bytes (Base+0x02F8-0x02FF) */
+
+}; /* end of ADC1_tag */
+/****************************************************************************/
+/*                          MODULE : I2C                                    */
+/****************************************************************************/
+struct I2C_tag{
+
+    union { /* I2C Bus Address (Base+0x0000) */
+        vuint8_t R;
+        struct {
+            vuint8_t ADR:7;
+            vuint8_t :1;
+        } B;
+    } IBAD;
+
+    union { /* I2C Bus Frequency Divider (Base+0x0001) */
+        vuint8_t R;
+        struct {
+            vuint8_t IBC:8;
+        } B;
+    } IBFD;
+
+    union { /* I2C Bus Control (Base+0x0002) */
+        vuint8_t R;
+        struct {
+            vuint8_t MDIS:1;
+            vuint8_t IBIE:1;
+            vuint8_t MS:1;
+            vuint8_t TX:1;
+            vuint8_t NOACK:1;
+            vuint8_t RSTA:1;
+            vuint8_t DMAEN:1;
+            vuint8_t IBDOZE:1;
+        } B;
+    } IBCR;
+
+    union { /* I2C Bus Status (Base+0x0003) */
+        vuint8_t R;
+        struct {
+            vuint8_t TCF:1;
+            vuint8_t IAAS:1;
+            vuint8_t IBB:1;
+            vuint8_t IBAL:1;
+            vuint8_t :1;
+            vuint8_t SRW:1;
+            vuint8_t IBIF:1;
+            vuint8_t RXAK:1;
+        } B;
+    } IBSR;
+
+    union { /* I2C Bus Data I/O (Base+0x0004) */
+        vuint8_t R;
+        struct {
+            vuint8_t DATA:8;
+        } B;
+    } IBDR;
+
+    union { /* I2C Interrupt Configuration (Base+0x0005) */
+        vuint8_t R;
+        struct {
+            vuint8_t BIIE:1;
+            vuint8_t :7;
+        } B;
+    } IBIC;
+
+    vuint8_t I2C_reserved0[16378]; /* Reserved 16378 (Base+0x0006-0x3FFF) */
+
+}; /* end of i2c_tag */
+/****************************************************************************/
+/*                   MODULE : LINFLEX (Master/Slave with DMA)               */
+/****************************************************************************/
+
+struct LINFLEX_MS_tag {
+
+    union { /* LINFLEX LIN Control 1 (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t CCD:1;
+            vuint32_t CFD:1;
+            vuint32_t LASE:1;
+            vuint32_t AWUM:1;
+            vuint32_t MBL:4;
+            vuint32_t BF:1;
+            vuint32_t SFTM:1;
+            vuint32_t LBKM:1;
+            vuint32_t MME:1;
+            vuint32_t SBDT:1;
+            vuint32_t RBLM:1;
+            vuint32_t SLEEP:1;
+            vuint32_t INIT:1;
+        } B;
+    } LINCR1;
+
+    union { /* LINFLEX LIN Interrupt Enable (Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t SZIE:1;
+            vuint32_t OCIE:1;
+            vuint32_t BEIE:1;
+            vuint32_t CEIE:1;
+            vuint32_t HEIE:1;
+              vuint32_t:2;
+            vuint32_t FEIE:1;
+            vuint32_t BOIE:1;
+            vuint32_t LSIE:1;
+            vuint32_t WUIE:1;
+            vuint32_t DBFIE:1;
+            vuint32_t DBEIE:1;
+            vuint32_t DRIE:1;
+            vuint32_t DTIE:1;
+            vuint32_t HRIE:1;
+        } B;
+    } LINIER;
+
+    union { /* LINFLEX LIN Status (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t LINS:4;
+            vuint32_t:2;
+            vuint32_t RMB:1;
+            vuint32_t:1;
+            vuint32_t RBSY:1;
+            vuint32_t RPS:1;
+            vuint32_t WUF:1;
+            vuint32_t DBFF:1;
+            vuint32_t DBEF:1;
+            vuint32_t DRF:1;
+            vuint32_t DTF:1;
+            vuint32_t HRF:1;
+        } B;
+    } LINSR;
+
+    union { /* LINFLEX LIN Error Status (Base+0x000C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t SZF:1;
+            vuint32_t OCF:1;
+            vuint32_t BEF:1;
+            vuint32_t CEF:1;
+            vuint32_t SFEF:1;
+            vuint32_t BDEF:1;
+            vuint32_t IDPEF:1;
+            vuint32_t FEF:1;
+            vuint32_t BOF:1;
+            vuint32_t:6;
+            vuint32_t NF:1;
+        } B;
+    } LINESR;
+
+    union { /* LINFLEX UART Mode Control (Base+0x0010) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t TDFL:3;
+            vuint32_t RDFL:3;
+            vuint32_t RFBM:1;
+            vuint32_t TFBM:1;
+            vuint32_t WL1:1;
+            vuint32_t PC1:1;
+            vuint32_t RXEN:1;
+            vuint32_t TXEN:1;
+            vuint32_t PC0:1;
+            vuint32_t PCE:1;
+            vuint32_t WL0:1;
+            vuint32_t UART:1;
+        } B;
+    } UARTCR;
+
+    union { /* LINFLEX UART Mode Status (Base+0x0014) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t SZF:1;
+            vuint32_t OCF:1;
+            vuint32_t PE:4; /*Can check all 4 RX'd bytes at once with array*/
+            vuint32_t RMB:1;
+            vuint32_t FEF:1;
+            vuint32_t BOF:1;
+            vuint32_t RPS:1;
+            vuint32_t WUF:1;
+            vuint32_t:2;
+            vuint32_t DRF:1;
+            vuint32_t DTF:1;
+            vuint32_t NF:1;
+        } B;
+    } UARTSR;
+
+    union { /* LINFLEX TimeOut Control Status ((Base+0x0018)*/
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t:5;
+            vuint32_t LTOM:1;
+            vuint32_t IOT:1;
+            vuint32_t TOCE:1;
+            vuint32_t CNT:8;
+        } B;
+    } LINTCSR;
+
+    union { /* LINFLEX LIN Output Compare (Base+0x001C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t OC2:8;
+            vuint32_t OC1:8;
+        } B;
+    } LINOCR;
+
+    union { /* LINFLEX LIN Timeout Control (Base+0x0020) */
+        vuint32_t R;
+        struct {
+            vuint32_t :20;
+            vuint32_t RTO:4;
+            vuint32_t:1;
+            vuint32_t HTO:7;
+        } B;
+    } LINTOCR;
+
+    union { /* LINFLEX LIN Fractional Baud Rate (+0x0024) */
+        vuint32_t R;
+        struct {
+            vuint32_t:28;
+            vuint32_t DIV_F:4;
+        } B;
+    } LINFBRR;
+
+    union { /* LINFLEX LIN Integer Baud Rate (Base+0x0028) */
+        vuint32_t R;
+        struct {
+            vuint32_t:19;
+            vuint32_t DIV_M:13;
+        } B;
+    } LINIBRR;
+
+    union { /* LINFLEX LIN Checksum Field (Base+0x002C) */
+        vuint32_t R;
+        struct {
+            vuint32_t:24;
+            vuint32_t CF:8;
+        } B;
+    } LINCFR;
+
+    union { /* LINFLEX LIN Control 2 (Base+0x0030) */
+        vuint32_t R;
+        struct {
+            vuint32_t:17;
+            vuint32_t IOBE:1;
+            vuint32_t IOPE:1;
+            vuint32_t WURQ:1;
+            vuint32_t DDRQ:1;
+            vuint32_t DTRQ:1;
+            vuint32_t ABRQ:1;
+            vuint32_t HTRQ:1;
+            vuint32_t:8;
+        } B;
+    } LINCR2;
+
+    union { /* LINFLEX Buffer Identifier (Base+0x0034) */
+        vuint32_t R;
+        struct {
+            vuint32_t:16;
+            vuint32_t DFL:6;
+            vuint32_t DIR:1;
+            vuint32_t CCS:1;
+            vuint32_t:2;
+            vuint32_t ID:6;
+        } B;
+    } BIDR;
+
+    union { /* LINFLEX Buffer Data LSB (Base+0x0038) */
+        vuint32_t R;
+        struct {
+            vuint32_t DATA3:8;
+            vuint32_t DATA2:8;
+            vuint32_t DATA1:8;
+            vuint32_t DATA0:8;
+        } B;
+    } BDRL;
+
+    union { /* LINFLEX Buffer Data MSB (Base+0x003C */
+        vuint32_t R;
+        struct {
+            vuint32_t DATA7:8;
+            vuint32_t DATA6:8;
+            vuint32_t DATA5:8;
+            vuint32_t DATA4:8;
+        } B;
+    } BDRM;
+
+    union { /* LINFLEX Identifier Filter Enable (+0x0040) */
+        vuint32_t R;
+        struct {
+            vuint32_t:24;
+            vuint32_t FACT:8;
+        } B;
+    } IFER;
+
+    union { /* LINFLEX Identifier Filter Match Index (+0x0044)*/
+        vuint32_t R;
+        struct {
+            vuint32_t:28;
+            vuint32_t IFMI:4;
+        } B;
+    } IFMI;
+
+    union { /* LINFLEX Identifier Filter Mode (Base+0x0048) */
+        vuint32_t R;
+        struct {
+            vuint32_t:28;
+            vuint32_t IFM:4;
+        } B;
+    } IFMR;
+
+    union { /* LINFLEX Identifier Filter Control 0..15 (+0x004C-0x0088)*/
+        vuint32_t R;
+        struct {
+            vuint32_t:16;
+            vuint32_t DFL:6;
+            vuint32_t DIR:1;
+            vuint32_t CCS:1;
+            vuint32_t:2;
+            vuint32_t ID:6;
+        } B;
+    } IFCR[16];
+
+    union { /* LINFLEX Global Counter (+0x008C) */
+        vuint32_t R;
+        struct {
+            vuint32_t:26;
+            vuint32_t TDFBM:1;
+            vuint32_t RDFBM:1;
+            vuint32_t TDLIS:1;
+            vuint32_t RDLIS:1;
+            vuint32_t STOP:1;
+            vuint32_t SR:1;
+        } B;
+    } GCR;
+
+    union { /* LINFLEX UART preset timeout (+0x0090) */
+        vuint32_t R;
+        struct {
+            vuint32_t:20;
+            vuint32_t PTO:12;
+        } B;
+    } UARTPTO;
+
+    union { /* LINFLEX UART current timeout (+0x0094) */
+        vuint32_t R;
+        struct {
+            vuint32_t:20;
+            vuint32_t CTO:12;
+        } B;
+    } UARTCTO;
+
+    union { /* LINFLEX DMA Tx Enable (+0x0098) */
+        vuint32_t R;
+        struct {
+            vuint32_t:16;
+            vuint32_t DTE15:1;
+            vuint32_t DTE14:1;
+            vuint32_t DTE13:1;
+            vuint32_t DTE12:1;
+            vuint32_t DTE11:1;
+            vuint32_t DTE10:1;
+            vuint32_t DTE9:1;
+            vuint32_t DTE8:1;
+            vuint32_t DTE7:1;
+            vuint32_t DTE6:1;
+            vuint32_t DTE5:1;
+            vuint32_t DTE4:1;
+            vuint32_t DTE3:1;
+            vuint32_t DTE2:1;
+            vuint32_t DTE1:1;
+            vuint32_t DTE0:1;
+        } B;
+    } DMATXE;
+
+    union { /* LINFLEX DMA RX Enable (+0x009C) */
+        vuint32_t R;
+        struct {
+            vuint32_t:16;
+            vuint32_t DRE15:1;
+            vuint32_t DRE14:1;
+            vuint32_t DRE13:1;
+            vuint32_t DRE12:1;
+            vuint32_t DRE11:1;
+            vuint32_t DRE10:1;
+            vuint32_t DRE9:1;
+            vuint32_t DRE8:1;
+            vuint32_t DRE7:1;
+            vuint32_t DRE6:1;
+            vuint32_t DRE5:1;
+            vuint32_t DRE4:1;
+            vuint32_t DRE3:1;
+            vuint32_t DRE2:1;
+            vuint32_t DRE1:1;
+            vuint32_t DRE0:1;
+        } B;
+    } DMARXE;
+
+
+
+}; /* end of LINFLEX_tag */
+/****************************************************************************/
+/*                     MODULE : LINFLEX (Master with DMA)                   */
+/****************************************************************************/
+
+struct LINFLEX_M_tag {
+
+    union { /* LINFLEX LIN Control 1 (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t CCD:1;
+            vuint32_t CFD:1;
+            vuint32_t LASE:1;
+            vuint32_t AWUM:1;
+            vuint32_t MBL:4;
+            vuint32_t BF:1;
+            vuint32_t SFTM:1;
+            vuint32_t LBKM:1;
+            vuint32_t MME:1;
+            vuint32_t SBDT:1;
+            vuint32_t RBLM:1;
+            vuint32_t SLEEP:1;
+            vuint32_t INIT:1;
+        } B;
+    } LINCR1;
+
+    union { /* LINFLEX LIN Interrupt Enable (Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t SZIE:1;
+            vuint32_t OCIE:1;
+            vuint32_t BEIE:1;
+            vuint32_t CEIE:1;
+            vuint32_t HEIE:1;
+              vuint32_t:2;
+            vuint32_t FEIE:1;
+            vuint32_t BOIE:1;
+            vuint32_t LSIE:1;
+            vuint32_t WUIE:1;
+            vuint32_t DBFIE:1;
+            vuint32_t DBEIE:1;
+            vuint32_t DRIE:1;
+            vuint32_t DTIE:1;
+            vuint32_t HRIE:1;
+        } B;
+    } LINIER;
+
+    union { /* LINFLEX LIN Status (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t LINS:4;
+            vuint32_t:2;
+            vuint32_t RMB:1;
+            vuint32_t:1;
+            vuint32_t RBSY:1;
+            vuint32_t RPS:1;
+            vuint32_t WUF:1;
+            vuint32_t DBFF:1;
+            vuint32_t DBEF:1;
+            vuint32_t DRF:1;
+            vuint32_t DTF:1;
+            vuint32_t HRF:1;
+        } B;
+    } LINSR;
+
+    union { /* LINFLEX LIN Error Status (Base+0x000C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t SZF:1;
+            vuint32_t OCF:1;
+            vuint32_t BEF:1;
+            vuint32_t CEF:1;
+            vuint32_t SFEF:1;
+            vuint32_t BDEF:1;
+            vuint32_t IDPEF:1;
+            vuint32_t FEF:1;
+            vuint32_t BOF:1;
+            vuint32_t:6;
+            vuint32_t NF:1;
+        } B;
+    } LINESR;
+
+    union { /* LINFLEX UART Mode Control (Base+0x0010) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t TDFL:3;
+            vuint32_t RDFL:3;
+            vuint32_t RFBM:1;
+            vuint32_t TFBM:1;
+            vuint32_t WL1:1;
+            vuint32_t PC1:1;
+            vuint32_t RXEN:1;
+            vuint32_t TXEN:1;
+            vuint32_t PC0:1;
+            vuint32_t PCE:1;
+            vuint32_t WL0:1;
+            vuint32_t UART:1;
+        } B;
+    } UARTCR;
+
+    union { /* LINFLEX UART Mode Status (Base+0x0014) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t SZF:1;
+            vuint32_t OCF:1;
+            vuint32_t PE:4; /*Can check all 4 RX'd bytes at once with array*/
+            vuint32_t RMB:1;
+            vuint32_t FEF:1;
+            vuint32_t BOF:1;
+            vuint32_t RPS:1;
+            vuint32_t WUF:1;
+            vuint32_t:2;
+            vuint32_t DRF:1;
+            vuint32_t DTF:1;
+            vuint32_t NF:1;
+        } B;
+    } UARTSR;
+
+    union { /* LINFLEX TimeOut Control Status ((Base+0x0018)*/
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t:5;
+            vuint32_t LTOM:1;
+            vuint32_t IOT:1;
+            vuint32_t TOCE:1;
+            vuint32_t CNT:8;
+        } B;
+    } LINTCSR;
+
+    union { /* LINFLEX LIN Output Compare (Base+0x001C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t OC2:8;
+            vuint32_t OC1:8;
+        } B;
+    } LINOCR;
+
+    union { /* LINFLEX LIN Timeout Control (Base+0x0020) */
+        vuint32_t R;
+        struct {
+            vuint32_t :20;
+            vuint32_t RTO:4;
+            vuint32_t:1;
+            vuint32_t HTO:7;
+        } B;
+    } LINTOCR;
+
+    union { /* LINFLEX LIN Fractional Baud Rate (+0x0024) */
+        vuint32_t R;
+        struct {
+            vuint32_t:28;
+            vuint32_t DIV_F:4;
+        } B;
+    } LINFBRR;
+
+    union { /* LINFLEX LIN Integer Baud Rate (Base+0x0028) */
+        vuint32_t R;
+        struct {
+            vuint32_t:19;
+            vuint32_t DIV_M:13;
+        } B;
+    } LINIBRR;
+
+    union { /* LINFLEX LIN Checksum Field (Base+0x002C) */
+        vuint32_t R;
+        struct {
+            vuint32_t:24;
+            vuint32_t CF:8;
+        } B;
+    } LINCFR;
+
+    union { /* LINFLEX LIN Control 2 (Base+0x0030) */
+        vuint32_t R;
+        struct {
+            vuint32_t:17;
+            vuint32_t IOBE:1;
+            vuint32_t IOPE:1;
+            vuint32_t WURQ:1;
+            vuint32_t DDRQ:1;
+            vuint32_t DTRQ:1;
+            vuint32_t ABRQ:1;
+            vuint32_t HTRQ:1;
+            vuint32_t:8;
+        } B;
+    } LINCR2;
+
+    union { /* LINFLEX Buffer Identifier (Base+0x0034) */
+        vuint32_t R;
+        struct {
+            vuint32_t:16;
+            vuint32_t DFL:6;
+            vuint32_t DIR:1;
+            vuint32_t CCS:1;
+            vuint32_t:2;
+            vuint32_t ID:6;
+        } B;
+    } BIDR;
+
+    union { /* LINFLEX Buffer Data LSB (Base+0x0038) */
+        vuint32_t R;
+        struct {
+            vuint32_t DATA3:8;
+            vuint32_t DATA2:8;
+            vuint32_t DATA1:8;
+            vuint32_t DATA0:8;
+        } B;
+    } BDRL;
+
+    union { /* LINFLEX Buffer Data MSB (Base+0x003C */
+        vuint32_t R;
+        struct {
+            vuint32_t DATA7:8;
+            vuint32_t DATA6:8;
+            vuint32_t DATA5:8;
+            vuint32_t DATA4:8;
+        } B;
+    } BDRM;
+
+    union { /* LINFLEX Identifier Filter Enable (+0x0040) */
+        vuint32_t R;
+        struct {
+            vuint32_t:24;
+            vuint32_t FACT:8;
+        } B;
+    } IFER;
+
+    union { /* LINFLEX Identifier Filter Match Index (+0x0044)*/
+        vuint32_t R;
+        struct {
+            vuint32_t:28;
+            vuint32_t IFMI:4;
+        } B;
+    } IFMI;
+
+    union { /* LINFLEX Identifier Filter Mode (Base+0x0048) */
+        vuint32_t R;
+        struct {
+            vuint32_t:28;
+            vuint32_t IFM:4;
+        } B;
+    } IFMR;
+
+    /* ----------------                                               */
+    /* For Master-Only LINFLEX, this is where the memory map changes! */
+    /* ----------------                                               */
+
+    union { /* LINFLEX Global Counter (+0x004C) */
+        vuint32_t R;
+        struct {
+            vuint32_t:26;
+            vuint32_t TDFBM:1;
+            vuint32_t RDFBM:1;
+            vuint32_t TDLIS:1;
+            vuint32_t RDLIS:1;
+            vuint32_t STOP:1;
+            vuint32_t SR:1;
+        } B;
+    } GCR;
+
+    union { /* LINFLEX UART preset timeout (+0x0050) */
+        vuint32_t R;
+        struct {
+            vuint32_t:20;
+            vuint32_t PTO:12;
+        } B;
+    } UARTPTO;
+
+    union { /* LINFLEX UART current timeout (+0x0054) */
+        vuint32_t R;
+        struct {
+            vuint32_t:20;
+            vuint32_t CTO:12;
+        } B;
+    } UARTCTO;
+
+    union { /* LINFLEX DMA Tx Enable (+0x0058) */
+        vuint32_t R;
+        struct {
+            vuint32_t:16;
+            vuint32_t DTE15:1;
+            vuint32_t DTE14:1;
+            vuint32_t DTE13:1;
+            vuint32_t DTE12:1;
+            vuint32_t DTE11:1;
+            vuint32_t DTE10:1;
+            vuint32_t DTE9:1;
+            vuint32_t DTE8:1;
+            vuint32_t DTE7:1;
+            vuint32_t DTE6:1;
+            vuint32_t DTE5:1;
+            vuint32_t DTE4:1;
+            vuint32_t DTE3:1;
+            vuint32_t DTE2:1;
+            vuint32_t DTE1:1;
+            vuint32_t DTE0:1;
+        } B;
+    } DMATXE;
+
+    union { /* LINFLEX DMA RX Enable (+0x005C) */
+        vuint32_t R;
+        struct {
+            vuint32_t:16;
+            vuint32_t DRE15:1;
+            vuint32_t DRE14:1;
+            vuint32_t DRE13:1;
+            vuint32_t DRE12:1;
+            vuint32_t DRE11:1;
+            vuint32_t DRE10:1;
+            vuint32_t DRE9:1;
+            vuint32_t DRE8:1;
+            vuint32_t DRE7:1;
+            vuint32_t DRE6:1;
+            vuint32_t DRE5:1;
+            vuint32_t DRE4:1;
+            vuint32_t DRE3:1;
+            vuint32_t DRE2:1;
+            vuint32_t DRE1:1;
+            vuint32_t DRE0:1;
+        } B;
+    } DMARXE;
+
+
+
+}; /* end of LINFLEX_tag */
+/****************************************************************************/
+/*                          MODULE : CTU Lite                               */
+/****************************************************************************/
+struct CTU_tag{
+
+    vuint8_t CTU_reserved[48]; /* Reserved 48 bytes (Base+0x0000-0x002F) */
+
+    union { /* Event Config 0..63 (Base+0x0030-0x012C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t TM:1;
+            vuint32_t CLR_FLAG:1;
+            vuint32_t :5;
+            vuint32_t ADC_SEL:1;
+            vuint32_t :1;
+            vuint32_t CHANNEL_VALUE:7;
+        } B;
+    } EVTCFGR[64];
+
+
+}; /* end of CTU_tag */
+/****************************************************************************/
+/*                          MODULE : CANSP                                  */
+/****************************************************************************/
+struct CANSP_tag{
+
+    union { /* CANSP Control (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t RX_COMPLETE:1;
+            vuint32_t BUSY:1;
+            vuint32_t ACTIVE_CK:1;
+            vuint32_t :3;
+            vuint32_t MODE:1;
+            vuint32_t CAN_RX_SEL:3;
+            vuint32_t BRP:5;
+            vuint32_t CAN_SMPLR_EN:1;
+        } B;
+    } CR;
+
+    union { /* CANSP Sample 0..11 (Base+0x0000-0x0030)*/
+        vuint32_t R;
+    } SR[12];
+
+}; /* end of CANSP_tag */
+/****************************************************************************/
+/*                          MODULE : XBAR                                   */
+/****************************************************************************/
+struct XBAR_tag{
+
+    union { /* XBAR Master Priority Slave Port 0 (+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t:1;
+            vuint32_t MSTR_7:3;
+            vuint32_t:1;
+            vuint32_t MSTR_6:3;
+            vuint32_t:1;
+            vuint32_t MSTR_5:3;
+            vuint32_t:1;
+            vuint32_t MSTR_4:3;
+            vuint32_t:1;
+            vuint32_t MSTR_3:3;
+            vuint32_t:1;
+            vuint32_t MSTR_2:3;
+            vuint32_t:1;
+            vuint32_t MSTR_1:3;
+            vuint32_t:1;
+            vuint32_t MSTR_0:3;
+        } B;
+    } MPR0;
+
+     vuint8_t XBAR_reserved0[12]; /* Reserved 12 bytes (Base+0x0004-0x000F)*/
+
+    union { /* XBAR General Purpose Control Slave 0 (+0x0010) */
+        vuint32_t R;
+        struct {
+            vuint32_t RO:1;
+            vuint32_t HLP:1;
+            vuint32_t:6;
+            vuint32_t HPE7:1;
+            vuint32_t HPE6:1;
+            vuint32_t HPE5:1;
+            vuint32_t HPE4:1;
+            vuint32_t HPE3:1;
+            vuint32_t HPE2:1;
+            vuint32_t HPE1:1;
+            vuint32_t HPE0:1;
+            vuint32_t:6;
+            vuint32_t ARB:2;
+            vuint32_t:2;
+            vuint32_t PCTL:2;
+            vuint32_t:1;
+            vuint32_t PARK:3;
+        } B;
+    } SGPCR0;
+
+     vuint8_t XBAR_reserved1[236]; /*Reserved 236 bytes (Base+0x0014-0x00FF)*/
+
+    union { /* XBAR Master Priority Slave Port 1 (+0x0100) */
+        vuint32_t R;
+        struct {
+            vuint32_t:1;
+            vuint32_t MSTR_7:3;
+            vuint32_t:1;
+            vuint32_t MSTR_6:3;
+            vuint32_t:1;
+            vuint32_t MSTR_5:3;
+            vuint32_t:1;
+            vuint32_t MSTR_4:3;
+            vuint32_t:1;
+            vuint32_t MSTR_3:3;
+            vuint32_t:1;
+            vuint32_t MSTR_2:3;
+            vuint32_t:1;
+            vuint32_t MSTR_1:3;
+            vuint32_t:1;
+            vuint32_t MSTR_0:3;
+        } B;
+    } MPR1;
+
+     vuint8_t XBAR_reserved2[12]; /* Reserved 12 bytes (Base+0x0104-0x010F)*/
+
+    union { /* XBAR General Purpose Control Slave 1 (+0x0110) */
+        vuint32_t R;
+        struct {
+            vuint32_t RO:1;
+            vuint32_t HLP:1;
+            vuint32_t:6;
+            vuint32_t HPE7:1;
+            vuint32_t HPE6:1;
+            vuint32_t HPE5:1;
+            vuint32_t HPE4:1;
+            vuint32_t HPE3:1;
+            vuint32_t HPE2:1;
+            vuint32_t HPE1:1;
+            vuint32_t HPE0:1;
+            vuint32_t:6;
+            vuint32_t ARB:2;
+            vuint32_t:2;
+            vuint32_t PCTL:2;
+            vuint32_t:1;
+            vuint32_t PARK:3;
+        } B;
+    } SGPCR1;
+
+     vuint8_t XBAR_reserved3[236]; /*Reserved 236 bytes (Base+0x0114-0x01FF)*/
+
+    union { /* XBAR Master Priority Slave Port 2 (+0x0200) */
+        vuint32_t R;
+        struct {
+            vuint32_t:1;
+            vuint32_t MSTR_7:3;
+            vuint32_t:1;
+            vuint32_t MSTR_6:3;
+            vuint32_t:1;
+            vuint32_t MSTR_5:3;
+            vuint32_t:1;
+            vuint32_t MSTR_4:3;
+            vuint32_t:1;
+            vuint32_t MSTR_3:3;
+            vuint32_t:1;
+            vuint32_t MSTR_2:3;
+            vuint32_t:1;
+            vuint32_t MSTR_1:3;
+            vuint32_t:1;
+            vuint32_t MSTR_0:3;
+        } B;
+    } MPR2;
+
+    vuint8_t XBAR_reserved4[12]; /* Reserved 12 bytes (Base+0x0204-0x020F)*/
+
+    union { /* XBAR General Purpose Control Slave 2 (+0x0210) */
+        vuint32_t R;
+        struct {
+            vuint32_t RO:1;
+            vuint32_t HLP:1;
+            vuint32_t:6;
+            vuint32_t HPE7:1;
+            vuint32_t HPE6:1;
+            vuint32_t HPE5:1;
+            vuint32_t HPE4:1;
+            vuint32_t HPE3:1;
+            vuint32_t HPE2:1;
+            vuint32_t HPE1:1;
+            vuint32_t HPE0:1;
+            vuint32_t:6;
+            vuint32_t ARB:2;
+            vuint32_t:2;
+            vuint32_t PCTL:2;
+            vuint32_t:1;
+            vuint32_t PARK:3;
+        } B;
+    } SGPCR2;
+
+    vuint8_t XBAR_reserved5[236]; /*Reserved 236 bytes (Base+0x0214-0x02FF)*/
+
+    union { /* XBAR Master Priority Slave Port 3 (+0x0300) */
+        vuint32_t R;
+        struct {
+            vuint32_t:1;
+            vuint32_t MSTR_7:3;
+            vuint32_t:1;
+            vuint32_t MSTR_6:3;
+            vuint32_t:1;
+            vuint32_t MSTR_5:3;
+            vuint32_t:1;
+            vuint32_t MSTR_4:3;
+            vuint32_t:1;
+            vuint32_t MSTR_3:3;
+            vuint32_t:1;
+            vuint32_t MSTR_2:3;
+            vuint32_t:1;
+            vuint32_t MSTR_1:3;
+            vuint32_t:1;
+            vuint32_t MSTR_0:3;
+        } B;
+    } MPR3;
+
+    vuint8_t XBAR_reserved6[12]; /* Reserved 12 bytes (Base+0x0304-0x030F)*/
+
+    union { /* XBAR General Purpose Control Slave 3 (+0x0310) */
+        vuint32_t R;
+        struct {
+            vuint32_t RO:1;
+            vuint32_t HLP:1;
+            vuint32_t:6;
+            vuint32_t HPE7:1;
+            vuint32_t HPE6:1;
+            vuint32_t HPE5:1;
+            vuint32_t HPE4:1;
+            vuint32_t HPE3:1;
+            vuint32_t HPE2:1;
+            vuint32_t HPE1:1;
+            vuint32_t HPE0:1;
+            vuint32_t:6;
+            vuint32_t ARB:2;
+            vuint32_t:2;
+            vuint32_t PCTL:2;
+            vuint32_t:1;
+            vuint32_t PARK:3;
+        } B;
+    } SGPCR3;
+
+    vuint8_t XBAR_reserved7[1004]; /*Reserved 1004 bytes (Base+0x0314-0x06FF)*/
+
+    union { /* XBAR Master Priority Slave Port 7 (+0x0700) */
+        vuint32_t R;
+        struct {
+            vuint32_t:1;
+            vuint32_t MSTR_7:3;
+            vuint32_t:1;
+            vuint32_t MSTR_6:3;
+            vuint32_t:1;
+            vuint32_t MSTR_5:3;
+            vuint32_t:1;
+            vuint32_t MSTR_4:3;
+            vuint32_t:1;
+            vuint32_t MSTR_3:3;
+            vuint32_t:1;
+            vuint32_t MSTR_2:3;
+            vuint32_t:1;
+            vuint32_t MSTR_1:3;
+            vuint32_t:1;
+            vuint32_t MSTR_0:3;
+        } B;
+    } MPR7;
+
+    vuint8_t XBAR_reserved8[12]; /* Reserved 12 bytes (Base+0x0704-0x070F)*/
+
+    union { /* XBAR General Purpose Control Slave 7 (+0x0710) */
+        vuint32_t R;
+        struct {
+            vuint32_t RO:1;
+            vuint32_t HLP:1;
+            vuint32_t:6;
+            vuint32_t HPE7:1;
+            vuint32_t HPE6:1;
+            vuint32_t HPE5:1;
+            vuint32_t HPE4:1;
+            vuint32_t HPE3:1;
+            vuint32_t HPE2:1;
+            vuint32_t HPE1:1;
+            vuint32_t HPE0:1;
+            vuint32_t:6;
+            vuint32_t ARB:2;
+            vuint32_t:2;
+            vuint32_t PCTL:2;
+            vuint32_t:1;
+            vuint32_t PARK:3;
+        } B;
+    } SGPCR7;
+
+    vuint8_t XBAR_reserved9[236]; /*Reserved 236 bytes (Base+0x0714-0x07FF)*/
+
+   union { /* XBAR General Purpose Control Master 0 (+0x0800) */
+        vuint32_t R;
+        struct {
+            vuint32_t:29;
+            vuint32_t AULB:3;
+        } B;
+   } MGPCR0;
+
+    vuint8_t XBAR_reserved10[252]; /*Reserved 252 bytes (Base+0x0804-0x08FF)*/
+
+   union { /* XBAR General Purpose Control Master 1 (+0x0900) */
+        vuint32_t R;
+        struct {
+            vuint32_t:29;
+            vuint32_t AULB:3;
+        } B;
+   } MGPCR1;
+
+    vuint8_t XBAR_reserved11[252]; /*Reserved 252 bytes (Base+0x0904-0x09FF)*/
+
+   union { /* XBAR General Purpose Control Master 2 (+0x0A00) */
+        vuint32_t R;
+        struct {
+            vuint32_t:29;
+            vuint32_t AULB:3;
+        } B;
+   } MGPCR2;
+
+    vuint8_t XBAR_reserved12[252]; /*Reserved 252 bytes (Base+0x0A04-0x0AFF)*/
+
+   union { /* XBAR General Purpose Control Master 3 (+0x0B00) */
+        vuint32_t R;
+        struct {
+            vuint32_t:29;
+            vuint32_t AULB:3;
+        } B;
+   } MGPCR3;
+
+    vuint8_t XBAR_reserved13[252]; /*Reserved 252 bytes (Base+0x0B04-0x0BFF)*/
+
+   union { /* XBAR General Purpose Control Master 4 (+0x0C00) */
+        vuint32_t R;
+        struct {
+            vuint32_t:29;
+            vuint32_t AULB:3;
+        } B;
+   } MGPCR4;
+
+    vuint8_t XBAR_reserved14[252]; /*Reserved 252 bytes (Base+0x0C04-0x0CFF)*/
+
+   union { /* XBAR General Purpose Control Master 5 (+0x0D00) */
+        vuint32_t R;
+        struct {
+            vuint32_t:29;
+            vuint32_t AULB:3;
+        } B;
+   } MGPCR5;
+
+    vuint8_t XBAR_reserved15[252]; /*Reserved 252 bytes (Base+0x0D04-0x0DFF)*/
+
+   union { /* XBAR General Purpose Control Master 6 (+0x0E00) */
+        vuint32_t R;
+        struct {
+            vuint32_t:29;
+            vuint32_t AULB:3;
+        } B;
+   } MGPCR6;
+
+    vuint8_t XBAR_reserved16[252]; /*Reserved 252 bytes (Base+0x0E04-0x0EFF)*/
+
+   union { /* XBAR General Purpose Control Master 7 (+0x0F00) */
+        vuint32_t R;
+        struct {
+            vuint32_t:29;
+            vuint32_t AULB:3;
+        } B;
+   } MGPCR7;
+
+
+}; /* end of XBAR_tag */
+/****************************************************************************/
+/*          MODULE : MPU (Memory Protection Unit)                           */
+/****************************************************************************/
+struct MPU_tag {
+
+    union { /* Control/Error Status (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t SPERR:8;
+            vuint32_t :4;
+            vuint32_t HRL:4;
+            vuint32_t NSP:4;
+            vuint32_t NGRD:4;
+            vuint32_t :7;
+            vuint32_t VLD:1;
+        } B;
+    } CESR;
+
+    vuint8_t MPU_reserved0[12]; /* Reserved 12 Bytes (Base+0x0004-0x000F) */
+
+
+   union { /* Error Address Slave Port0 (Base+0x0010) */
+        vuint32_t R;
+        struct {
+            vuint32_t EADDR:32;
+        } B;
+    } EAR0;
+
+    union { /* Error Detail Slave Port0 (Base+0x0014) */
+        vuint32_t R;
+        struct {
+            vuint32_t EACD:16;
+            vuint32_t EPID:8;
+            vuint32_t EMN:4;
+            vuint32_t EATTR:3;
+            vuint32_t ERW:1;
+        } B;
+    } EDR0;
+
+
+    union { /* Error Address Slave Port1 (Base+0x0018) */
+        vuint32_t R;
+        struct {
+            vuint32_t EADDR:32;
+        } B;
+    } EAR1;
+
+    union { /* Error Detail Slave Port1 (Base+0x001C) */
+        vuint32_t R;
+        struct {
+            vuint32_t EACD:16;
+            vuint32_t EPID:8;
+            vuint32_t EMN:4;
+            vuint32_t EATTR:3;
+            vuint32_t ERW:1;
+        } B;
+    } EDR1;
+
+
+    union { /* Error Address Slave Port2 (Base+0x0020) */
+        vuint32_t R;
+        struct {
+            vuint32_t EADDR:32;
+        } B;
+    } EAR2;
+
+    union { /* Error Detail Slave Port2 (Base+0x0024) */
+        vuint32_t R;
+        struct {
+            vuint32_t EACD:16;
+            vuint32_t EPID:8;
+            vuint32_t EMN:4;
+            vuint32_t EATTR:3;
+            vuint32_t ERW:1;
+        } B;
+    } EDR2;
+
+
+    union { /* Error Address Slave Port3 (Base+0x0028) */
+        vuint32_t R;
+        struct {
+            vuint32_t EADDR:32;
+        } B;
+    } EAR3;
+
+    union { /* Error Detail Slave Port3 (Base+0x002C) */
+        vuint32_t R;
+        struct {
+            vuint32_t EACD:16;
+            vuint32_t EPID:8;
+            vuint32_t EMN:4;
+            vuint32_t EATTR:3;
+            vuint32_t ERW:1;
+        } B;
+    } EDR3;
+
+
+    union { /* Error Address Slave Port4 (Base+0x0030) */
+        vuint32_t R;
+        struct {
+            vuint32_t EADDR:32;
+        } B;
+    } EAR4;
+
+    union { /* Error Detail Slave Port4 (Base+0x0034) */
+        vuint32_t R;
+        struct {
+            vuint32_t EACD:16;
+            vuint32_t EPID:8;
+            vuint32_t EMN:4;
+            vuint32_t EATTR:3;
+            vuint32_t ERW:1;
+        } B;
+    } EDR4;
+
+    vuint8_t MPU_reserved1[968]; /* Reserved 968 Bytes (Base+0x0038-0x03FF) */
+
+    struct { /* Region Descriptor 0..15 (Base+0x0400-0x04F0) */
+
+        union { /* - Word 0 */
+            vuint32_t R;
+            struct {
+                vuint32_t SRTADDR:27;
+                vuint32_t :5;
+            } B;
+        } WORD0;
+
+        union { /* - Word 1 */
+            vuint32_t R;
+            struct {
+                vuint32_t ENDADDR:27;
+                vuint32_t :5;
+            } B;
+        } WORD1;
+
+       union { /* - Word 2 */
+            vuint32_t R;
+            struct {
+                vuint32_t M7RE:1;
+                vuint32_t M7WE:1;
+                vuint32_t M6RE:1;
+                vuint32_t M6WE:1;
+                vuint32_t M5RE:1;
+                vuint32_t M5WE:1;
+                vuint32_t M4RE:1;
+                vuint32_t M4WE:1;
+                vuint32_t M3PE:1;
+                vuint32_t M3SM:2;
+                vuint32_t M3UM:3;
+                vuint32_t M2PE:1;
+                vuint32_t M2SM:2;
+                vuint32_t M2UM:3;
+                vuint32_t M1PE:1;
+                vuint32_t M1SM:2;
+                vuint32_t M1UM:3;
+                vuint32_t M0PE:1;
+                vuint32_t M0SM:2;
+                vuint32_t M0UM:3;
+            } B;
+        } WORD2;
+
+        union { /* - Word 3 */
+            vuint32_t R;
+            struct {
+                vuint32_t PID:8;
+                vuint32_t PIDMASK:8;
+                vuint32_t :15;
+                vuint32_t VLD:1;
+            } B;
+        } WORD3;
+
+    }RGD[16]; /* End of Region Descriptor Structure) */
+
+    vuint8_t MPU_reserved2[768]; /* Reserved 768 Bytes (Base+0x0500-0x07FF) */
+
+    union { /* Region Descriptor Alt 0..15 (0x0800-0x083F) */
+        vuint32_t R;
+        struct {
+            vuint32_t M7RE:1;
+            vuint32_t M7WE:1;
+            vuint32_t M6RE:1;
+            vuint32_t M6WE:1;
+            vuint32_t M5RE:1;
+            vuint32_t M5WE:1;
+            vuint32_t M4RE:1;
+            vuint32_t M4WE:1;
+            vuint32_t M3PE:1;
+            vuint32_t M3SM:2;
+            vuint32_t M3UM:3;
+            vuint32_t M2PE:1;
+            vuint32_t M2SM:2;
+            vuint32_t M2UM:3;
+            vuint32_t M1PE:1;
+            vuint32_t M1SM:2;
+            vuint32_t M1UM:3;
+            vuint32_t M0PE:1;
+            vuint32_t M0SM:2;
+            vuint32_t M0UM:3;
+        } B;
+    } RGDAAC[16];
+
+    vuint8_t MPU_reserved3[14242]; /* Reserved 14242 Bytes (+0x0840-0x03FFF) */
+
+}; /* end of MPU_tag */
+/****************************************************************************/
+/*          MODULE : CSE (Cryptographic Security Engine)                    */
+/****************************************************************************/
+struct CSE_tag {
+
+    union { /* CSE Control (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t DIV:8;
+            vuint32_t :4;
+            vuint32_t MDIS:1;
+            vuint32_t SUS:1;
+            vuint32_t :1; /* vuint32_t DRE:1; removed RevD */
+            vuint32_t CIE:1;
+        } B;
+    } CR;
+
+    union { /* CSE Status (Read Only) (Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t :23;
+            vuint32_t EX:1;
+            vuint32_t IDB:1;
+            vuint32_t EDB:1;
+            vuint32_t RIN:1;
+            vuint32_t BOK:1;
+            vuint32_t BFN:1;
+            vuint32_t BIN:1;
+            vuint32_t SB:1;
+            vuint32_t BSY:1;
+        } B;
+    } SR;
+
+    union { /* CSE Interrupt (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t :31;
+            vuint32_t CIF:1;
+        } B;
+    } IR;
+
+    union { /* CSE Error Code (Base+0x000C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :27;
+            vuint32_t EC:5;
+        } B;
+    } ECR;
+
+    vuint8_t CSE_reserved0[13]; /* Reserved 13 Bytes (Base+0x0010-0x001C) */
+
+    union { /* CSE Command (Base+0x0020) */
+        vuint32_t R;
+        struct {
+            vuint32_t :27;
+            vuint32_t CMD:5;
+        } B;
+    } CMD;
+
+
+    /*-- Note parameter registers cannot be array since no P0 (SHE spec) --*/
+
+    union { /* CSE Paramter 1 (Base+0x0024) */
+        vuint32_t R;
+        struct {
+            vuint32_t PARM:32;
+        } B;
+    } P1;
+
+    union { /* CSE Paramter 2 (Base+0x0028) */
+        vuint32_t R;
+        struct {
+            vuint32_t PARM:32;
+        } B;
+    } P2;
+
+    union { /* CSE Paramter 3 (Base+0x002C) */
+        vuint32_t R;
+        struct {
+            vuint32_t PARM:32;
+        } B;
+    } P3;
+
+    union { /* CSE Paramter 4 (Base+0x0030) */
+        vuint32_t R;
+        struct {
+            vuint32_t PARM:32;
+        } B;
+    } P4;
+
+    union { /* CSE Paramter 5 (Base+0x0034) */
+        vuint32_t R;
+        struct {
+            vuint32_t PARM:32;
+        } B;
+    } P5;
+
+    vuint8_t CSE_reserved1[16328]; /* Reserved 16328 Bytes (0x0038-0x3FFF) */
+
+}; /* end of CSE_tag */
+/****************************************************************************/
+/*          MODULE : SEMA4 (Semaphores)                                     */
+/****************************************************************************/
+ struct SEMA4_tag {
+
+    union { /* Gate 0..15 (Base+0x0000-0x000F) */
+        vuint8_t R;
+        struct {
+            vuint8_t:6;
+            vuint8_t GTFSM:2;
+        } B;
+    } GATE[16];
+
+    vuint8_t SEMA4_reserved0[48]; /* Reserved 48 Bytes (Base+0x0010-0x003F) */
+
+    union { /* CP0 IRQ Notification enable (Base+0x0040) */
+        vuint16_t R;
+        struct {
+            vuint16_t INE0:1;
+            vuint16_t INE1:1;
+            vuint16_t INE2:1;
+            vuint16_t INE3:1;
+            vuint16_t INE4:1;
+            vuint16_t INE5:1;
+            vuint16_t INE6:1;
+            vuint16_t INE7:1;
+            vuint16_t INE8:1;
+            vuint16_t INE9:1;
+            vuint16_t INE10:1;
+            vuint16_t INE11:1;
+            vuint16_t INE12:1;
+            vuint16_t INE13:1;
+            vuint16_t INE14:1;
+            vuint16_t INE15:1;
+        } B;
+    } CP0INE;
+
+    vuint8_t SEMA4_reserved1[6]; /* Reserved 6 Bytes (Base+0x0042-0x0047) */
+
+    union { /* CP1 IRQ Notification enable (Base+0x0048) */
+        vuint16_t R;
+        struct {
+            vuint16_t INE0:1;
+            vuint16_t INE1:1;
+            vuint16_t INE2:1;
+            vuint16_t INE3:1;
+            vuint16_t INE4:1;
+            vuint16_t INE5:1;
+            vuint16_t INE6:1;
+            vuint16_t INE7:1;
+            vuint16_t INE8:1;
+            vuint16_t INE9:1;
+            vuint16_t INE10:1;
+            vuint16_t INE11:1;
+            vuint16_t INE12:1;
+            vuint16_t INE13:1;
+            vuint16_t INE14:1;
+            vuint16_t INE15:1;
+        } B;
+    } CP1INE;
+
+    vuint8_t SEMA4_reserved2[54]; /* Reserved 54 Bytes (Base+0x004A-0x007F) */
+
+    union { /* CP0 IRQ Notification (Base+0x0080) */
+        vuint16_t R;
+        struct {
+            vuint16_t GN0:1;
+            vuint16_t GN1:1;
+            vuint16_t GN2:1;
+            vuint16_t GN3:1;
+            vuint16_t GN4:1;
+            vuint16_t GN5:1;
+            vuint16_t GN6:1;
+            vuint16_t GN7:1;
+            vuint16_t GN8:1;
+            vuint16_t GN9:1;
+            vuint16_t GN10:1;
+            vuint16_t GN11:1;
+            vuint16_t GN12:1;
+            vuint16_t GN13:1;
+            vuint16_t GN14:1;
+            vuint16_t GN15:1;
+        } B;
+    } CP0NTF;
+
+    vuint8_t SEMA4_reserved3[6]; /* Reserved 6 Bytes (Base+0x0082-0x0087) */
+
+    union { /* CP1 IRQ Notification (Base+0x0088) */
+        vuint16_t R;
+        struct {
+            vuint16_t GN0:1;
+            vuint16_t GN1:1;
+            vuint16_t GN2:1;
+            vuint16_t GN3:1;
+            vuint16_t GN4:1;
+            vuint16_t GN5:1;
+            vuint16_t GN6:1;
+            vuint16_t GN7:1;
+            vuint16_t GN8:1;
+            vuint16_t GN9:1;
+            vuint16_t GN10:1;
+            vuint16_t GN11:1;
+            vuint16_t GN12:1;
+            vuint16_t GN13:1;
+            vuint16_t GN14:1;
+            vuint16_t GN15:1;
+        } B;
+    } CP1NTF;
+
+    vuint8_t SEMA4_reserved4[118]; /* Reserved 118 Bytes (+0x008A-0x00FF) */
+
+    union { /* Reset gate (Base+0x0100) */
+        vuint16_t R;
+        struct {
+            vuint16_t:2;
+            vuint16_t RSTGSM:2;
+            vuint16_t:1;
+            vuint16_t RSTGMS:3;
+            vuint16_t RSTGTN:8;
+        } B;
+    } RSTGT;
+
+    vuint8_t SEMA4_reserved5[2]; /* Reserved 2 Bytes (Base+0x0102-0x0103) */
+
+    union {
+        vuint16_t R;
+        struct {
+            vuint16_t:2;
+            vuint16_t RSTNSM:2;
+            vuint16_t:1;
+            vuint16_t RSTNMS:3;
+            vuint16_t RSTNTN:8;
+        } B;
+    } RSTNTF;
+
+    vuint8_t SEMA4_reserved6[16122]; /* Reserved 16122 (Base+0x0106-0x3FFF) */
+
+ }; /* end of SEMA4_tag */
+/****************************************************************************/
+/*                          MODULE : SWT                                   */
+/****************************************************************************/
+struct SWT_tag{
+
+    union { /* SWT Control (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t MAP0:1;
+            vuint32_t MAP1:1;
+            vuint32_t MAP2:1;
+            vuint32_t MAP3:1;
+            vuint32_t MAP4:1;
+            vuint32_t MAP5:1;
+            vuint32_t MAP6:1;
+            vuint32_t MAP7:1;
+            vuint32_t :14;
+            vuint32_t KEY:1;
+            vuint32_t RIA:1;
+            vuint32_t WND:1;
+            vuint32_t ITR:1;
+            vuint32_t HLK:1;
+            vuint32_t SLK:1;
+            vuint32_t CSL:1;
+            vuint32_t STP:1;
+            vuint32_t FRZ:1;
+            vuint32_t WEN:1;
+        } B;
+    } CR;
+
+    union { /* SWT Interrupt (Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t :31;
+            vuint32_t TIF:1;
+        } B;
+    } IR;
+
+    union { /* SWT Time-Out (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t WTO:32;
+        } B;
+    } TO;
+
+    union { /* SWT Window (Base+0x000C) */
+        vuint32_t R;
+        struct {
+            vuint32_t WST:32;
+        } B;
+    } WN;
+
+    union { /* SWT Service (Base+0x0010) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t WSC:16;
+        } B;
+    } SR;
+
+    union { /* SWT Counter Output (Base+0x0014) */
+        vuint32_t R;
+        struct {
+            vuint32_t CNT:32;
+        } B;
+    } CO;
+
+    union { /* SWT Service Key (Base+0x0018) */
+        vuint32_t R; /*  New for Bolero 3M  */
+        struct {
+            vuint32_t :16;
+            vuint32_t SK:16;
+        } B;
+    } SK;
+
+}; /* end of SWT_tag */
+/****************************************************************************/
+/*                          MODULE : STM                                   */
+/****************************************************************************/
+  struct STM_CHANNEL_tag{
+
+    union { /* STM Channel Control 0..3 */
+        vuint32_t R;
+        struct {
+            vuint32_t :31;
+            vuint32_t CEN:1;
+        } B;
+    } CCR;
+
+    union { /* STM Channel Interrupt 0..3 */
+        vuint32_t R;
+        struct {
+            vuint32_t :31;
+            vuint32_t CIF:1;
+        } B;
+    } CIR;
+
+    union { /* STM Channel Compare 0..3 */
+        vuint32_t R;
+        struct {
+            vuint32_t CMP:32;
+        } B;
+    } CMP;
+
+    vuint8_t STM_CHANNEL_reserved[4]; /* Reserved 4 bytes between ch reg's */
+
+  }; /* end of STM_CHANNEL_tag */
+
+
+struct STM_tag{
+
+    union { /* STM Control (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t CPS:8;
+            vuint32_t :6;
+            vuint32_t FRZ:1;
+            vuint32_t TEN:1;
+        } B;
+    } CR;
+
+    union { /* STM Count (Base+0x0004) */
+        vuint32_t R;
+    } CNT;
+
+    vuint8_t STM_reserved0[8]; /* Reserved 8 bytes (Base+0x0008-0x000F) */
+
+    struct STM_CHANNEL_tag CH[4]; /*STM Channels 0..3 (Base+0x0010-0x0048) */
+
+}; /* end of STM_tag */
+/****************************************************************************/
+/*                          MODULE : ECSM                                   */
+/****************************************************************************/
+struct ECSM_tag{
+
+    union { /* ECSM Processor Core Type (Base+0x0000) */
+        vuint16_t R;
+    } PCT;
+
+    union { /* ECSM Revision (Base+0x0002) */
+        vuint16_t R;
+    } REV;
+
+    vuint8_t ECSM_reserved0[4]; /* Reserved 4 bytes (Base+0x0004-0x0007) */
+
+    union { /* ECSM IPS Module Configuration (Base+0x0008) */
+        vuint32_t R;
+    } IMC;
+
+    vuint8_t ECSM_reserved1[19]; /* Reserved 19 bytes (Base+0x000C-0x001E) */
+
+    union { /* ECSM Miscellaneous Interrupt (Base+0x001F) */
+        vuint8_t R;
+        struct {
+            vuint8_t FB0AI:1;
+            vuint8_t FB0SI:1;
+            vuint8_t FB1AI:1;
+            vuint8_t FB1SI:1;
+            vuint8_t :4;
+        } B;
+    } MIR;
+
+    vuint8_t ECSM_reserved3[4]; /* Reserved 4 bytes (Base+0x0020-0x0023) */
+
+    union { /*ECSM Miscellaneous User-Defined Control (+0x0024)*/
+        vuint32_t R;
+        struct {
+            vuint32_t XBAR_ARB:1;
+            vuint32_t RAM_WS:1;
+            vuint32_t :19;
+            vuint32_t MUDCR:11;
+        } B;
+    } MUDCR;
+
+    vuint8_t ECSM_reserved4[27]; /* Reserved 27 bytes (Base+0x0028-0x0042) */
+
+    union { /* ECSM ECC Configuration (Base+0x0043) */
+        vuint8_t R;
+        struct {
+            vuint8_t :2;
+            vuint8_t ER1BR:1;
+            vuint8_t EF1BR:1;
+            vuint8_t :2;
+            vuint8_t ERNCR:1;
+            vuint8_t EFNCR:1;
+        } B;
+    } ECR;
+
+    vuint8_t ECSM_reserved5[3]; /* Reserved 3 bytes (Base+0x0044-0x0046) */
+
+    union { /* ECSM ECC Status (Base+0x0047) */
+        vuint8_t R;
+        struct {
+            vuint8_t :2;
+            vuint8_t R1BC:1;
+            vuint8_t F1BC:1;
+            vuint8_t :2;
+            vuint8_t RNCE:1;
+            vuint8_t FNCE:1;
+        } B;
+    } ESR;
+
+    vuint8_t ECSM_reserved6[2]; /* Reserved 2 bytes (Base+0x0048-0x0049) */
+
+    union { /* ECSM ECC Error Generation (Base+0x004A) */
+        vuint16_t R;
+        struct {
+            vuint16_t :2;
+            vuint16_t FRC1BI:1;
+            vuint16_t FR11BI:1;
+            vuint16_t :2;
+            vuint16_t FRCNCI:1;
+            vuint16_t FR1NCI:1;
+            vuint16_t :1;
+            vuint16_t ERRBIT:7;
+        } B;
+    } EEGR;
+
+    vuint8_t ECSM_reserved7[4]; /* Reserved 4 bytes (Base+0x004C-0x004F) */
+
+    union { /* ECSM Flash ECC Address(Base+0x0050) */
+        vuint32_t R;
+    } FEAR;
+
+    vuint8_t ECSM_reserved8[2]; /* Reserved 2 bytes (Base+0x0054-0x0055) */
+
+    union { /* ECSM Flash ECC Master Number (Base+0x0056) */
+        vuint8_t R;
+        struct {
+            vuint8_t :4;
+            vuint8_t FEMR:4;
+        } B;
+    } FEMR;
+
+    union { /* ECSM Flash ECC Attributes (Base+0x0057) */
+        vuint8_t R;
+        struct {
+            vuint8_t WRITE:1;
+           vuint8_t SIZE:3;
+            vuint8_t PROTECTION:4;
+        } B;
+    } FEAT;
+
+    vuint8_t ECSM_reserved9[4]; /* Reserved 4 bytes (Base+0x0058-0x005B) */
+
+    union { /* ECSM Flash ECC Data (Base+0x005C) */
+        vuint32_t R;
+    } FEDR;
+
+    union { /* ECSM RAM ECC Address (Base+0x0060) */
+        vuint32_t R;
+    } REAR;
+
+    vuint8_t ECSM_reserved10[1]; /* Reserved 1 bytes (Base+0x0064) */
+
+    union { /* ECSM RAM ECC Address (Base+0x0065) */
+        vuint8_t R;
+    } RESR;
+
+    union { /* ECSM RAM ECC Master Number (Base+0x0066) */
+        vuint8_t R;
+        struct {
+            vuint8_t :4;
+            vuint8_t REMR:4;
+        } B;
+    } REMR;
+
+    union { /* ECSM RAM ECC Attributes (Base+0x0067) */
+        vuint8_t R;
+        struct {
+            vuint8_t WRITE:1;
+            vuint8_t SIZE:3;
+            vuint8_t PROTECTION:4;
+        } B;
+    } REAT;
+
+    vuint8_t ECSM_reserved11[4]; /* Reserved 4 bytes (Base+0x0068-0x006B) */
+
+    union { /* ECSM RAM ECC Data (Base+0x006C) */
+        vuint32_t R;
+    } REDR;
+
+}; /* end of ECSM_tag */
+/****************************************************************************/
+/*                          MODULE : eDMA                                   */
+/****************************************************************************/
+
+  /* There are 4 different TCD structures which should be used based on     */
+  /*  how the DMA is configured as below. CAUTION - Do not mix TCD's        */
+  /*                                                                        */
+  /*  Channel Linking      Minor Loop Mapping     Addressing TCD            */
+  /*       OFF                   OFF               XBAR.TCD[x]              */
+  /*       OFF                   ON                XBAR.ML_TCD[x]           */
+  /*       ON                    OFF               XBAR.CL_TCD[X]           */
+  /*       ON                    ON                XBAR.MLCL_TCD[X]         */
+  /*                                                                        */
+
+
+  /* (1) - Standard TCD (Channel Linking OFF, Minor Loop mapping OFF        */
+    struct EDMA_TCD_STD_tag {
+
+        vuint32_t SADDR; /* Source address                         */
+
+        vuint16_t SMOD:5; /* Source address modulo                  */
+        vuint16_t SSIZE:3; /* Source data transfer size              */
+        vuint16_t DMOD:5; /* Destination address modulo             */
+        vuint16_t DSIZE:3; /* Destination data transfer size         */
+        vint16_t SOFF; /* Source address signed offset           */
+
+        vuint32_t NBYTES; /* Inner "minor" byte transfer count      */
+
+        vint32_t SLAST; /* Last source address adjustment         */
+
+        vuint32_t DADDR; /* Destination address                    */
+
+        vuint16_t CITERE_LINK:1; /* Enable ch-to-ch link on minor complete */
+        vuint16_t CITER:15; /* Current Major iteration count          */
+        vint16_t DOFF; /* Destination address signed offset      */
+
+        vint32_t DLAST_SGA; /* Last desitination address adjustment   */
+
+        vuint16_t BITERE_LINK:1; /* Enable ch-to-ch link on minor complete */
+        vuint16_t BITER:15; /* Starting major iteration count         */
+        vuint16_t BWC:2; /* Bandwidth & Priority Elevation control */
+        vuint16_t MAJORLINKCH:6; /* Link channel number                    */
+        vuint16_t DONE:1; /* Channel done                           */
+        vuint16_t ACTIVE:1; /* Channel active                         */
+        vuint16_t MAJORE_LINK:1; /* Enable ch-to-ch link on major complete */
+        vuint16_t E_SG:1; /* Enable scatter/gather processing       */
+        vuint16_t D_REQ:1; /* Disable hardware request (ERQRL bit)   */
+        vuint16_t INT_HALF:1; /* interrupt on Major loop half complete  */
+        vuint16_t INT_MAJ:1; /* interrupt on major loop complete       */
+        vuint16_t START:1; /* Chanel start                           */
+
+    }; /* End of Standard TCD tag                                           */
+
+
+
+  /* (2) - ML_TCD (Channel Linking OFF, Minor Loop mapping Enabled          */
+  /*      (EMLM = 1)                                                        */
+    struct EDMA_TCD_MLMIRROR_tag {
+
+        vuint32_t SADDR; /* Source address                         */
+
+        vuint16_t SMOD:5; /* Source address modulo                  */
+        vuint16_t SSIZE:3; /* Source data transfer size              */
+        vuint16_t DMOD:5; /* Destination address modulo             */
+        vuint16_t DSIZE:3; /* Destination data transfer size         */
+        vint16_t SOFF; /* Source address signed offset           */
+
+        vuint32_t SMLOE:1; /* Source minor loop offset enabled       */
+        vuint32_t DMLOE:1; /* Destination minor loop offset enable   */
+        vuint32_t MLOFF:20; /* Minor loop offset                      */
+        vuint32_t NBYTES:10; /* Inner "minor" byte transfer count      */
+
+        vint32_t SLAST; /* Last source address adjustment         */
+
+        vuint32_t DADDR; /* Destination address                    */
+
+        vuint16_t CITERE_LINK:1; /* Enable ch-to-ch link on minor complete */
+        vuint16_t CITER:15; /* Current Major iteration count          */
+        vint16_t DOFF; /* Destination address signed offset      */
+
+        vint32_t DLAST_SGA; /* Last desitination address adjustment   */
+
+        vuint16_t BITERE_LINK:1; /* Enable ch-to-ch link on minor complete */
+        vuint16_t BITER:15; /* Starting major iteration count         */
+        vuint16_t BWC:2; /* Bandwidth & Priority Elevation control */
+        vuint16_t MAJORLINKCH:6; /* Link channel number                    */
+        vuint16_t DONE:1; /* Channel done                           */
+        vuint16_t ACTIVE:1; /* Channel active                         */
+        vuint16_t MAJORE_LINK:1; /* Enable ch-to-ch link on major complete */
+        vuint16_t E_SG:1; /* Enable scatter/gather processing       */
+        vuint16_t D_REQ:1; /* Disable hardware request (ERQRL bit)   */
+        vuint16_t INT_HALF:1; /* interrupt on Major loop half complete  */
+        vuint16_t INT_MAJ:1; /* interrupt on major loop complete       */
+        vuint16_t START:1; /* Chanel start                           */
+
+    }; /* End of EDMA_TCD_MLMIRROR_tag                                      */
+
+
+
+  /* (3) - CL_TCD (Channel Linking Enabled, Minor Loop mapping OFF          */
+  /*       (CITERE_LINK = BITERE_LINK = 1)                                  */
+    struct EDMA_TCD_CHLINK_tag {
+
+        vuint32_t SADDR; /* Source address                         */
+
+        vuint16_t SMOD:5; /* Source address modulo                  */
+        vuint16_t SSIZE:3; /* Source data transfer size              */
+        vuint16_t DMOD:5; /* Destination address modulo             */
+        vuint16_t DSIZE:3; /* Destination data transfer size         */
+        vint16_t SOFF; /* Source address signed offset           */
+
+        vuint32_t NBYTES; /* Inner "minor" byte transfer count      */
+
+        vint32_t SLAST; /* Last source address adjustment         */
+
+        vuint32_t DADDR; /* Destination address                    */
+
+        vuint16_t CITERE_LINK:1; /* Enable ch-to-ch link on minor complete */
+        vuint16_t CITERLINKCH:6; /* Link channel number                    */
+        vuint16_t CITER:9; /* Current Major iteration count          */
+        vint16_t DOFF; /* Destination address signed offset      */
+
+        vint32_t DLAST_SGA; /* Last desitination address adjustment   */
+
+        vuint16_t BITERE_LINK:1; /* Enable ch-to-ch link on minor complete */
+        vuint16_t BITERLINKCH:6; /* Link channel number                    */
+        vuint16_t BITER:9; /* Starting Major iteration count         */
+        vuint16_t BWC:2; /* Bandwidth & Priority Elevation control */
+        vuint16_t MAJORLINKCH:6; /* Link channel number                    */
+        vuint16_t DONE:1; /* Channel done                           */
+        vuint16_t ACTIVE:1; /* Channel active                         */
+        vuint16_t MAJORE_LINK:1; /* Enable ch-to-ch link on major complete */
+        vuint16_t E_SG:1; /* Enable scatter/gather processing       */
+        vuint16_t D_REQ:1; /* Disable hardware request (ERQRL bit)   */
+        vuint16_t INT_HALF:1; /* interrupt on Major loop half complete  */
+        vuint16_t INT_MAJ:1; /* interrupt on major loop complete       */
+        vuint16_t START:1; /* Chanel start                           */
+
+    }; /* end of EDMA_TCD_CHLINK_tag                                        */
+
+
+
+  /* (4) - CL_TCD (Channel Linking Enabled, Minor Loop mapping Enabled      */
+  /*       (CITERE_LINK = BITERE_LINK = 1, EMLM = 1)                        */
+    struct EDMA_TCD_MLMIRROR_CHLINK_tag {
+
+        vuint32_t SADDR; /* Source address                         */
+
+        vuint16_t SMOD:5; /* Source address modulo                  */
+        vuint16_t SSIZE:3; /* Source data transfer size              */
+        vuint16_t DMOD:5; /* Destination address modulo             */
+        vuint16_t DSIZE:3; /* Destination data transfer size         */
+        vint16_t SOFF; /* Source address signed offset           */
+
+        vuint32_t SMLOE:1; /* Source minor loop offset enabled       */
+        vuint32_t DMLOE:1; /* Destination minor loop offset enable   */
+        vuint32_t MLOFF:20; /* Minor loop offset                      */
+        vuint32_t NBYTES:10; /* Inner "minor" byte transfer count      */
+
+        vint32_t SLAST; /* Last source address adjustment         */
+
+        vuint32_t DADDR; /* Destination address                    */
+
+        vuint16_t CITERE_LINK:1; /* Enable ch-to-ch link on minor complete */
+        vuint16_t CITERLINKCH:6; /* Link channel number                    */
+        vuint16_t CITER:9; /* Current Major iteration count          */
+        vint16_t DOFF; /* Destination address signed offset      */
+
+        vint32_t DLAST_SGA; /* Last desitination address adjustment   */
+
+        vuint16_t BITERE_LINK:1; /* Enable ch-to-ch link on minor complete */
+        vuint16_t BITERLINKCH:6; /* Link channel number                    */
+        vuint16_t BITER:9; /* Starting Major iteration count         */
+        vuint16_t BWC:2; /* Bandwidth & Priority Elevation control */
+        vuint16_t MAJORLINKCH:6; /* Link channel number                    */
+        vuint16_t DONE:1; /* Channel done                           */
+        vuint16_t ACTIVE:1; /* Channel active                         */
+        vuint16_t MAJORE_LINK:1; /* Enable ch-to-ch link on major complete */
+        vuint16_t E_SG:1; /* Enable scatter/gather processing       */
+        vuint16_t D_REQ:1; /* Disable hardware request (ERQRL bit)   */
+        vuint16_t INT_HALF:1; /* interrupt on Major loop half complete  */
+        vuint16_t INT_MAJ:1; /* interrupt on major loop complete       */
+        vuint16_t START:1; /* Chanel start                           */
+
+    }; /* end of EDMA_TCD_MLMIRROR_CHLINK_tag                               */
+
+
+
+
+struct EDMA_tag {
+
+    union { /* Control (Base+0x0000)                        */
+        vuint32_t R;
+        struct {
+            vuint32_t:14;
+            vuint32_t CX:1;
+            vuint32_t ECX:1;
+            vuint32_t:2; /* vuint32_t GRP3PRI:2; (Not implemented B3M)    */
+            vuint32_t:2; /* vuint32_t GRP2PRI:2; (Not implemented B3M)    */
+            vuint32_t:2; /* vuint32_t GRP1PRI:2; (Not implemented B3M)    */
+            vuint32_t GRP0PRI:2;
+            vuint32_t EMLM:1;
+            vuint32_t CLM:1;
+            vuint32_t HALT:1;
+            vuint32_t HOE:1;
+            vuint32_t ERGA:1;
+            vuint32_t ERCA:1;
+            vuint32_t EDBG:1;
+            vuint32_t EBW:1;
+        } B;
+    } CR;
+
+    union { /* Error Status (Base+0x0004)                   */
+        vuint32_t R;
+        struct {
+            vuint32_t VLD:1;
+            vuint32_t:14;
+            vuint32_t:1; /* vuint32_t ECX:1; (Not implemented B3M)         */
+            vuint32_t:1; /* vuint32_t GPE:1; (Not implemented B3M)         */
+            vuint32_t CPE:1;
+            vuint32_t ERRCHN:6;
+            vuint32_t SAE:1;
+            vuint32_t SOE:1;
+            vuint32_t DAE:1;
+            vuint32_t DOE:1;
+            vuint32_t NCE:1;
+            vuint32_t SGE:1;
+            vuint32_t SBE:1;
+            vuint32_t DBE:1;
+        } B;
+    } ESR;
+
+    vuint8_t eDMA_reserved0[4]; /* Reserved 4 bytes (Base+0x0008-0x000B)    */
+
+    union { /* Enable Request Low Ch31..0 (Base+0x000C)     */
+        vuint32_t R;
+        struct {
+            vuint32_t ERQ31:1;
+            vuint32_t ERQ30:1;
+            vuint32_t ERQ29:1;
+            vuint32_t ERQ28:1;
+            vuint32_t ERQ27:1;
+            vuint32_t ERQ26:1;
+            vuint32_t ERQ25:1;
+            vuint32_t ERQ24:1;
+            vuint32_t ERQ23:1;
+            vuint32_t ERQ22:1;
+            vuint32_t ERQ21:1;
+            vuint32_t ERQ20:1;
+            vuint32_t ERQ19:1;
+            vuint32_t ERQ18:1;
+            vuint32_t ERQ17:1;
+            vuint32_t ERQ16:1;
+            vuint32_t ERQ15:1;
+            vuint32_t ERQ14:1;
+            vuint32_t ERQ13:1;
+            vuint32_t ERQ12:1;
+            vuint32_t ERQ11:1;
+            vuint32_t ERQ10:1;
+            vuint32_t ERQ09:1;
+            vuint32_t ERQ08:1;
+            vuint32_t ERQ07:1;
+            vuint32_t ERQ06:1;
+            vuint32_t ERQ05:1;
+            vuint32_t ERQ04:1;
+            vuint32_t ERQ03:1;
+            vuint32_t ERQ02:1;
+            vuint32_t ERQ01:1;
+            vuint32_t ERQ00:1;
+        } B;
+    } ERQRL;
+
+    vuint8_t eDMA_reserved1[4]; /* Reserved 4 bytes (Base+0x0010-0x0013)    */
+
+    union { /* nable Error Interrupt Low (Base+0x0014)      */
+        vuint16_t R;
+        struct {
+            vuint32_t EEI31:1;
+            vuint32_t EEI30:1;
+            vuint32_t EEI29:1;
+            vuint32_t EEI28:1;
+            vuint32_t EEI27:1;
+            vuint32_t EEI26:1;
+            vuint32_t EEI25:1;
+            vuint32_t EEI24:1;
+            vuint32_t EEI23:1;
+            vuint32_t EEI22:1;
+            vuint32_t EEI21:1;
+            vuint32_t EEI20:1;
+            vuint32_t EEI19:1;
+            vuint32_t EEI18:1;
+            vuint32_t EEI17:1;
+            vuint32_t EEI16:1;
+            vuint32_t EEI15:1;
+            vuint32_t EEI14:1;
+            vuint32_t EEI13:1;
+            vuint32_t EEI12:1;
+            vuint32_t EEI11:1;
+            vuint32_t EEI10:1;
+            vuint32_t EEI09:1;
+            vuint32_t EEI08:1;
+            vuint32_t EEI07:1;
+            vuint32_t EEI06:1;
+            vuint32_t EEI05:1;
+            vuint32_t EEI04:1;
+            vuint32_t EEI03:1;
+            vuint32_t EEI02:1;
+            vuint32_t EEI01:1;
+            vuint32_t EEI00:1;
+        } B;
+    } EEIRL;
+
+    union { /* DMA Set Enable Request (Base+0x0018)         */
+        vuint8_t R;
+        struct {
+            vuint8_t NOP:1;
+            vuint8_t SERQ:7;
+        } B;
+    } SERQR;
+
+    union { /* DMA Clear Enable Request (Base+0x0019)       */
+        vuint8_t R;
+        struct {
+            vuint8_t:1; /* vuint8_t NOP:1;  */
+            vuint8_t CERQ:7;
+        } B;
+    } CERQR;
+
+    union { /* DMA Set Enable Error Interrupt (Base+0x001A) */
+        vuint8_t R;
+        struct {
+            vuint8_t:1; /* vuint8_t NOP:1;   */
+            vuint8_t SEEI:7;
+        } B;
+    } SEEIR;
+
+    union { /* DMA Clr Enable Error Interrupt (Base+0x001B) */
+        vuint8_t R;
+        struct {
+            vuint8_t:1;
+            vuint8_t CEEI:7;
+        } B;
+    } CEEIR;
+
+    union { /* DMA Clear Interrupt Request (Base+0x001C)    */
+        vuint8_t R;
+        struct {
+            vuint8_t:1; /* vuint8_t NOP:1;  */
+            vuint8_t CINT:7;
+        } B;
+    } CIRQR;
+
+    union { /* DMA Clear error (Base+0x001D)                */
+        vuint8_t R;
+        struct {
+            vuint8_t:1; /* vuint8_t NOP:1;  */
+            vuint8_t CERR:7;
+        } B;
+    } CERR;
+
+    union { /* DMA Set Start Bit (Base+0x001E)              */
+        vuint8_t R;
+        struct {
+            vuint8_t:1; /* vuint8_t NOP:1; */
+            vuint8_t SSB:7;
+        } B;
+    } SSBR;
+
+    union { /* DMA Clear Done Status Bit (Base+0x001F)      */
+        vuint8_t R;
+        struct {
+            vuint8_t:1; /* vuint8_t NOP:1;  */
+            vuint8_t CDSB:7;
+        } B;
+    } CDSBR;
+
+    vuint8_t eDMA_reserved2[4]; /* Reserved 4 bytes (Base+0x0020-0x0023)    */
+
+    union { /* DMA Interrupt Req Low Ch31..0 (+0x0024)      */
+        vuint32_t R;
+        struct {
+            vuint32_t INT31:1;
+            vuint32_t INT30:1;
+            vuint32_t INT29:1;
+            vuint32_t INT28:1;
+            vuint32_t INT27:1;
+            vuint32_t INT26:1;
+            vuint32_t INT25:1;
+            vuint32_t INT24:1;
+            vuint32_t INT23:1;
+            vuint32_t INT22:1;
+            vuint32_t INT21:1;
+            vuint32_t INT20:1;
+            vuint32_t INT19:1;
+            vuint32_t INT18:1;
+            vuint32_t INT17:1;
+            vuint32_t INT16:1;
+            vuint32_t INT15:1;
+            vuint32_t INT14:1;
+            vuint32_t INT13:1;
+            vuint32_t INT12:1;
+            vuint32_t INT11:1;
+            vuint32_t INT10:1;
+            vuint32_t INT09:1;
+            vuint32_t INT08:1;
+            vuint32_t INT07:1;
+            vuint32_t INT06:1;
+            vuint32_t INT05:1;
+            vuint32_t INT04:1;
+            vuint32_t INT03:1;
+            vuint32_t INT02:1;
+            vuint32_t INT01:1;
+            vuint32_t INT00:1;
+        } B;
+    } IRQRL;
+
+    vuint8_t eDMA_reserved3[4]; /* Reserved 4 bytes (Base+0x0028-0x002B)    */
+
+    union { /* DMA Error Low Ch31..0 (Base+0x002C)          */
+        vuint32_t R;
+        struct {
+            vuint32_t ERR31:1;
+            vuint32_t ERR30:1;
+            vuint32_t ERR29:1;
+            vuint32_t ERR28:1;
+            vuint32_t ERR27:1;
+            vuint32_t ERR26:1;
+            vuint32_t ERR25:1;
+            vuint32_t ERR24:1;
+            vuint32_t ERR23:1;
+            vuint32_t ERR22:1;
+            vuint32_t ERR21:1;
+            vuint32_t ERR20:1;
+            vuint32_t ERR19:1;
+            vuint32_t ERR18:1;
+            vuint32_t ERR17:1;
+            vuint32_t ERR16:1;
+            vuint32_t ERR15:1;
+            vuint32_t ERR14:1;
+            vuint32_t ERR13:1;
+            vuint32_t ERR12:1;
+            vuint32_t ERR11:1;
+            vuint32_t ERR10:1;
+            vuint32_t ERR09:1;
+            vuint32_t ERR08:1;
+            vuint32_t ERR07:1;
+            vuint32_t ERR06:1;
+            vuint32_t ERR05:1;
+            vuint32_t ERR04:1;
+            vuint32_t ERR03:1;
+            vuint32_t ERR02:1;
+            vuint32_t ERR01:1;
+            vuint32_t ERR00:1;
+        } B;
+    } ERL;
+
+    vuint8_t eDMA_reserved4[4]; /* Reserved 4 bytes (Base+0x0030-0x0033)    */
+
+    union { /* DMA Hardware Request Stat Low (Base+0x0034)  */
+        vuint32_t R;
+        struct {
+            vuint32_t HRS31:1;
+            vuint32_t HRS30:1;
+            vuint32_t HRS29:1;
+            vuint32_t HRS28:1;
+            vuint32_t HRS27:1;
+            vuint32_t HRS26:1;
+            vuint32_t HRS25:1;
+            vuint32_t HRS24:1;
+            vuint32_t HRS23:1;
+            vuint32_t HRS22:1;
+            vuint32_t HRS21:1;
+            vuint32_t HRS20:1;
+            vuint32_t HRS19:1;
+            vuint32_t HRS18:1;
+            vuint32_t HRS17:1;
+            vuint32_t HRS16:1;
+            vuint32_t HRS15:1;
+            vuint32_t HRS14:1;
+            vuint32_t HRS13:1;
+            vuint32_t HRS12:1;
+            vuint32_t HRS11:1;
+            vuint32_t HRS10:1;
+            vuint32_t HRS09:1;
+            vuint32_t HRS08:1;
+            vuint32_t HRS07:1;
+            vuint32_t HRS06:1;
+            vuint32_t HRS05:1;
+            vuint32_t HRS04:1;
+            vuint32_t HRS03:1;
+            vuint32_t HRS02:1;
+            vuint32_t HRS01:1;
+            vuint32_t HRS00:1;
+        } B;
+    } HRSL;
+
+    vuint8_t eDMA_reserved5[200]; /* Reserved 200 bytes (Base+0x0038-0x00FF)*/
+
+    union { /* Channel n Priority (Base+0x0100-0x011F)      */
+        vuint8_t R;
+        struct {
+            vuint8_t ECP:1;
+            vuint8_t DPA:1;
+            vuint8_t GRPPRI:2;
+            vuint8_t CHPRI:4;
+        } B;
+    } CPR[32];
+
+    vuint8_t eDMA_reserved6[3808]; /* Reserved 3808 bytes (+0x0120-0x0FFF)  */
+
+
+    union { /* 4 different TCD definitions depending on operating mode    */
+
+        /* Default TCD (Channel Linking and Minor Loop Maping disabled)     */
+        struct EDMA_TCD_STD_tag TCD[32];
+
+        /* ML_TCD (Channel Linking disabled, Minor Loop Mapping enabled)    */
+        struct EDMA_TCD_MLMIRROR_tag ML_TCD[32];
+
+        /* CL_TCD (Channel Linking enabled, Minor Loop Mapping disabled)    */
+        struct EDMA_TCD_CHLINK_tag CL_TCD[32];
+
+        /* MLCL_TCD (Channel Linking enabled, Minor Loop Mapping enabled)   */
+        struct EDMA_TCD_MLMIRROR_CHLINK_tag MLCL_TCD[32];
+    };
+
+}; /* end of EDMA_tag */
+/*************************************************************************/
+/*                          MODULE : INTC                                */
+/*************************************************************************/
+
+struct INTC_tag {
+
+    union { /* INTC Module Configuration (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t:18;
+            vuint32_t VTES_PRC1:1;
+            vuint32_t:4;
+            vuint32_t HVEN_PRC1:1;
+            vuint32_t:2;
+            vuint32_t VTES_PRC0:1;
+            vuint32_t:4;
+            vuint32_t HVEN_PRC0:1;
+        } B;
+    } MCR;
+
+    vuint8_t INTC_reserved0[4]; /* reserved 4 bytes (Base+0x0004-0x0007) */
+
+    union { /* INTC Current Priority Proc0 (Z4) (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t:28;
+            vuint32_t PRI:4;
+        } B;
+    } CPR_PRC0;
+
+    union { /* INTC Current Priority Proc1 (Z0) (Base+0x000C) */
+        vuint32_t R;
+        struct {
+            vuint32_t:28;
+            vuint32_t PRI:4;
+        } B;
+    } CPR_PRC1;
+
+    union { /* INTC Interrupt Acknowledge Proc0 (Z4) (Base+0x0010) */
+        vuint32_t R;
+        struct {
+            vuint32_t VTBA_PRC0:21;
+            vuint32_t INTVEC_PRC0:9;
+            vuint32_t:2;
+        } B;
+    } IACKR_PRC0;
+
+    union { /* INTC Interrupt Acknowledge Proc1 (Z0) (Base+0x0014) */
+        vuint32_t R;
+        struct {
+            vuint32_t VTBA_PRC1:21;
+            vuint32_t INTVEC_PRC1:9;
+            vuint32_t:2;
+        } B;
+    } IACKR_PRC1;
+
+    union { /* INTC End Of Interrupt Proc0 (Z4) (Base+0x0018) */
+        vuint32_t R;
+        struct {
+            vuint32_t:32;
+        } B;
+    } EOIR_PRC0;
+
+    union { /* INTC End Of Interrupt Proc1 (Z0) (Base+0x001C) */
+        vuint32_t R;
+        struct {
+            vuint32_t:32;
+        } B;
+    } EOIR_PRC1;
+
+    union { /* INTC Software Set/Clear Interrupt0-7 (+0x0020-0x0027) */
+        vuint8_t R;
+        struct {
+            vuint8_t:6;
+            vuint8_t SET:1;
+            vuint8_t CLR:1;
+        } B;
+    } SSCIR[8];
+
+    vuint8_t INTC_reserved1[24]; /* Reserved 24 bytes (Base+0x0028-0x003F) */
+
+    union { /* INTC Priority Select (Base+0x0040-0x0157) */
+        vuint8_t R;
+        struct {
+            vuint8_t PRC_SEL:2;
+            vuint8_t:2;
+            vuint8_t PRI:4;
+        } B;
+    } PSR[279];
+
+}; /* end of INTC_tag */
+/****************************************************************************/
+/*          MODULE : FEC (Fast Ethernet Controller)                         */
+/****************************************************************************/
+struct FEC_tag {
+
+    vuint8_t FEC_reserved0[4100]; /*Reserved 4100 bytes (Base+0x0000-0x0103)*/
+
+    union { /* FEC Interrupt Event (Base+0x1004) */
+        vuint32_t R;
+        struct {
+            vuint32_t HBERR:1;
+            vuint32_t BABR:1;
+            vuint32_t BABT:1;
+            vuint32_t GRA:1;
+            vuint32_t TXF:1;
+            vuint32_t TXB:1;
+            vuint32_t RXF:1;
+            vuint32_t RXB:1;
+            vuint32_t MII:1;
+            vuint32_t EBERR:1;
+            vuint32_t LC:1;
+            vuint32_t RL:1;
+            vuint32_t UN:1;
+            vuint32_t:19;
+        } B;
+    } EIR;
+
+    union { /*  Interrupt Mask (Base+0x1008)  */
+        vuint32_t R;
+        struct {
+            vuint32_t HBERR:1;
+            vuint32_t BABR:1;
+            vuint32_t BABT:1;
+            vuint32_t GRA:1;
+            vuint32_t TXF:1;
+            vuint32_t TXB:1;
+            vuint32_t RXF:1;
+            vuint32_t RXB:1;
+            vuint32_t MII:1;
+            vuint32_t EBERR:1;
+            vuint32_t LC:1;
+            vuint32_t RL:1;
+            vuint32_t UN:1;
+            vuint32_t:19;
+        } B;
+    } EIMR;
+
+    vuint8_t FEC_reserved1[4]; /* Reserved 4 Bytes (Base+0x100C-0x100F) */
+
+    union { /*  FEC Receive Descriptor Active (Base+0x1010) */
+        vuint32_t R;
+        struct {
+            vuint32_t:7;
+            vuint32_t R_DES_ACTIVE:1;
+            vuint32_t:24;
+        } B;
+    } RDAR;
+
+    union { /*  FEC TX Descriptor Active (Base+0x1014)  */
+        vuint32_t R;
+        struct {
+            vuint32_t:7;
+            vuint32_t X_DES_ACTIVE:1;
+            vuint32_t:24;
+        } B;
+    } TDAR;
+
+    vuint8_t FEC_reserved2[12]; /* Reserved 12 Bytes (Base+0x1018-0x1023) */
+
+    union { /*  FEC Ethernet Control (Base+0x1024) */
+        vuint32_t R;
+        struct {
+            vuint32_t:30;
+            vuint32_t ETHER_EN:1;
+            vuint32_t RESET:1;
+        } B;
+    } ECR;
+
+    vuint8_t FEC_reserved3[24]; /* Reserved 24 Bytes (Base+0x1028-0x103F) */
+
+    union { /* FEC Management Frame (Base+0x1040) */
+        vuint32_t R;
+        struct {
+            vuint32_t ST:2;
+            vuint32_t OP:2;
+            vuint32_t PA:5;
+            vuint32_t RA:5;
+            vuint32_t TA:2;
+            vuint32_t DATA:16;
+        } B;
+    } MDATA;
+
+    union { /* FEC MII Speed Control (Base+0x1044) */
+        vuint32_t R;
+        struct {
+            vuint32_t:24;
+            vuint32_t DIS_PREAMBLE:1;
+            vuint32_t MII_SPEED:6;
+            vuint32_t:1;
+        } B;
+    } MSCR;
+
+    vuint8_t FEC_reserved4[28]; /* Reserved 28 Bytes (Base+0x1048-0x1063) */
+
+    union { /* FEC MIB Control (Base+0x1064) */
+        vuint32_t R;
+        struct {
+            vuint32_t MIB_DISABLE:1;
+            vuint32_t MIB_IDLE:1;
+            vuint32_t:30;
+        } B;
+    } MIBC;
+
+    vuint8_t FEC_reserved5[28]; /* Reserved 28 Bytes (Base+0x1068-0x1083) */
+
+    union { /* FEC Receive Control (Base+0x1084) */
+        vuint32_t R;
+        struct {
+            vuint32_t:5;
+            vuint32_t MAX_FL:11;
+            vuint32_t:10;
+            vuint32_t FCE:1;
+            vuint32_t BC_REJ:1;
+            vuint32_t PROM:1;
+            vuint32_t MII_MODE:1;
+            vuint32_t DRT:1;
+            vuint32_t LOOP:1;
+        } B;
+    } RCR;
+
+    vuint8_t FEC_reserved6[60]; /* Reserved 60 Bytes (Base+0x1088-0x10C3) */
+
+    union { /* FEC Transmit Control (Base+0x10C4) */
+        vuint32_t R;
+        struct {
+            vuint32_t:27;
+            vuint32_t RFC_PAUSE:1;
+            vuint32_t TFC_PAUSE:1;
+            vuint32_t FDEN:1;
+            vuint32_t HBC:1;
+            vuint32_t GTS:1;
+        } B;
+    } TCR;
+
+    vuint8_t FEC_reserved7[28]; /* Reserved 28 Bytes (Base+0x10C8-0x10E3) */
+
+    union { /* FEC Physical Address Low (Base+0x10E4) */
+        vuint32_t R;
+        struct {
+            vuint32_t PADDR1:32;
+        } B;
+    } PALR;
+
+    union { /* FEC Physical Address High (Base+0x10E8) */
+        vuint32_t R;
+        struct {
+            vuint32_t PADDR2:16;
+            vuint32_t TYPE:16;
+        } B;
+    } PAUR;
+
+    union { /* Opcode/Pause Duration (Base+0x10EC) */
+        vuint32_t R;
+        struct {
+            vuint32_t OPCODE:16;
+            vuint32_t PAUSE_DUR:16;
+        } B;
+    } OPD;
+
+    vuint8_t FEC_reserved8[40]; /* Reserved 40 Bytes (Base+0x10F0-0x1117) */
+
+    union { /*FEC Descriptor Individual Upper Addr (+0x1118)*/
+        vuint32_t R;
+        struct {
+             vuint32_t IADDR1:32;
+        } B;
+    } IAUR;
+
+    union { /*FEC Descriptor Individual Lower Addr (+0x111C)*/
+        vuint32_t R;
+        struct {
+            vuint32_t IADDR2:32;
+        } B;
+    } IALR;
+
+    union { /* FEC Descriptor Group Upper Addr (Base+0x1120)*/
+        vuint32_t R;
+        struct {
+            vuint32_t GADDR1:32;
+        } B;
+    } GAUR;
+
+    union { /* FEC Descriptor Group Lower Addr (Base+0x1124)*/
+        vuint32_t R;
+        struct {
+            vuint32_t GADDR2:32;
+        } B;
+    } GALR;
+
+    vuint8_t FEC_reserved9[28]; /* Reserved 28 Bytes (Base+0x1128-0x1143) */
+
+    union { /* FEC FIFO Transmit FIFO Watermark (+0x1144) */
+        vuint32_t R;
+        struct {
+            vuint32_t:30;
+            vuint32_t X_WMRK:2;
+        } B;
+    } TFWR;
+
+    vuint8_t FEC_reserved10[4]; /* Reserved 4 Bytes (Base+0x1148-0x114B) */
+
+    union { /* FEC FIFO Receive Bound (Base+0x114C) */
+        vuint32_t R;
+        struct {
+            vuint32_t:22;
+            vuint32_t R_BOUND:8;
+            vuint32_t:2;
+        } B;
+    } FRBR;
+
+    union { /* FEC FIFO Receive FIFO Start (Base+0x1150) */
+        vuint32_t R;
+        struct {
+            vuint32_t:22;
+            vuint32_t R_FSTART:8;
+            vuint32_t:2;
+        } B;
+    } FRSR;
+
+    vuint8_t FEC_reserved11[44]; /* Reserved 44 Bytes (Base+0x1154-0x117F) */
+
+    union { /* FEC Receive Descriptor Ring Start (+0x1180) */
+        vuint32_t R;
+        struct {
+            vuint32_t R_DES_START:30;
+            vuint32_t:2;
+        } B;
+    } ERDSR;
+
+    union { /* FEC Transmit Descriptor Ring Start (+0x1184) */
+        vuint32_t R;
+        struct {
+            vuint32_t X_DES_START:30;
+            vuint32_t:2;
+        } B;
+    } ETDSR;
+
+    union { /* FEC Max Receive Buffer Size (Base+0x1188) */
+        vuint32_t R;
+        struct {
+            vuint32_t:21;
+            vuint32_t R_BUF_SIZE:7;
+            vuint32_t:4;
+        } B;
+    } EMRBR;
+
+    vuint8_t FEC_reserved12[116]; /*Reserved 116 Bytes (Base+0x118C-0x11FF) */
+
+
+    /* --- FEC MIB Counters Registers Below (Base+0x12000) --- */
+
+    union { /* MIB Count frames not counted correctly (Base+0x1200)*/
+        vuint32_t R;
+    } RMON_T_DROP;
+
+    union { /* MIB RMON Tx packet count (Base+0x1204) */
+        vuint32_t R;
+    } RMON_T_PACKETS;
+
+    union { /* MIB RMON Tx Broadcast Packets (Base+0x1208) */
+        vuint32_t R;
+    } RMON_T_BC_PKT;
+
+    union { /* MIB RMON Tx Multicast Packets (Base+0x120C) */
+        vuint32_t R;
+    } RMON_T_MC_PKT;
+
+    union { /* MIB RMON Tx Packets w CRC/Align err (+0x1210)*/
+        vuint32_t R;
+    } RMON_T_CRC_ALIGN;
+
+    union { /* MIB RMON Tx Packets < 64 bytes, good crc (+0x1214)*/
+        vuint32_t R;
+    } RMON_T_UNDERSIZE;
+
+    union { /* RMON Tx Packets > MAX_FL bytes, good crc (+0x1218) */
+        vuint32_t R;
+    } RMON_T_OVERSIZE;
+
+    union { /* MIB RMON Tx Packets < 64 bytes, bad crc (+0x121C) */
+        vuint32_t R;
+    } RMON_T_FRAG;
+
+    union { /* MIB RMON Tx Packets > MAX_FL bytes, bad crc (+0x1220) */
+        vuint32_t R;
+    } RMON_T_JAB;
+
+    union { /* MIB RMON Tx collision count (Base+0x1224)*/
+        vuint32_t R;
+    } RMON_T_COL;
+
+    union { /* MIB RMON Tx 64 byte packets (Base+0x1228) */
+        vuint32_t R;
+    } RMON_T_P64;
+
+    union { /* MIB RMON Tx 65 to 127 byte packets (+0x122C) */
+        vuint32_t R;
+    } RMON_T_P65TO127;
+
+    union { /* MIB RMON Tx 128 to 255 byte packets (+0x1230)*/
+        vuint32_t R;
+    } RMON_T_P128TO255;
+
+    union { /* MIB RMON Tx 256 to 511 byte packets (+0x1234)*/
+        vuint32_t R;
+    } RMON_T_P256TO511;
+
+    union { /* MIB RMON Tx 512 to 1023 byte packets (+0x1238)*/
+        vuint32_t R;
+    } RMON_T_P512TO1023;
+
+    union { /* MIB RMON Tx 1024 to 2047 byte packets (+0x123C)*/
+        vuint32_t R;
+    } RMON_T_P1024TO2047;
+
+    union { /* MIB RMON Tx packets w > 2048 bytes (+0x1240) */
+        vuint32_t R;
+    } RMON_T_P_GTE2048;
+
+    union { /* MIB RMON Tx Octets (Base+0x1244) */
+        vuint32_t R;
+    } RMON_T_OCTETS;
+
+    union { /* MIB Count of frames not counted correct (+0x1248)*/
+        vuint32_t R;
+    } IEEE_T_DROP;
+
+    union { /* MIB Frames Transmitted OK  (Base+124C) */
+        vuint32_t R;
+    } IEEE_T_FRAME_OK;
+
+    union { /* MIB Frames Tx'd with Single Collision (+0x1250)*/
+        vuint32_t R;
+    } IEEE_T_1COL;
+
+    union { /* MIB Frames Tx'd with mult Collision (+0x1254)*/
+        vuint32_t R;
+    } IEEE_T_MCOL;
+
+    union { /* MIB Frames Tx'd after Deferral Delay (+0x1258)*/
+        vuint32_t R;
+    } IEEE_T_DEF;
+
+    union { /* MIB Frames Tx'd with Late Collision (+0x125C)*/
+        vuint32_t R;
+    } IEEE_T_LCOL;
+
+    union { /* MIB Frames Tx'd with Excessive Collisions (+0x1260)*/
+        vuint32_t R;
+    } IEEE_T_EXCOL;
+
+    union { /* MIB Frames Tx'd with Tx FIFO Underrun (+0x1264)*/
+        vuint32_t R;
+    } IEEE_T_MACERR;
+
+    union { /* MIB Frames Tx'd with Carrier Sense Error (+0x1268) */
+        vuint32_t R;
+    } IEEE_T_CSERR;
+
+    union { /* MIB Frames Tx'd with SQE Error (Base+0x126C) */
+        vuint32_t R;
+    } IEEE_T_SQE;
+
+    union { /* MIB Flow Control Pause frames tx'd (+0x1270) */
+        vuint32_t R;
+    } IEEE_T_FDXFC;
+
+    union { /* MIB Octet count for Frames Tx'd w/o Error (+0x1274)*/
+        vuint32_t R;
+    } IEEE_T_OCTETS_OK;
+
+    vuint8_t FEC_reserved13[8]; /*Reserved 12 Bytes (Base+0x1278-0x127F) */
+
+    union { /* MIB RMON # frames not counted correct (+0x1280) */
+        vuint32_t R;
+    } RMON_R_DROP;
+
+    union { /* MIB RMON Rx packet count (Base+0x1284) */
+        vuint32_t R;
+    } RMON_R_PACKETS;
+
+    union { /* MIB RMON Rx Broadcast Packets (Base+0x1288) */
+        vuint32_t R;
+    } RMON_R_BC_PKT;
+
+    union { /* MIB RMON Rx Multicast Packets (Base+0x128C) */
+        vuint32_t R;
+    } RMON_R_MC_PKT;
+
+    union { /* MIB RMON Rx Packets w CRC/Align error (+0x1290)*/
+        vuint32_t R;
+    } RMON_R_CRC_ALIGN;
+
+    union { /* MIB RMON Rx Packets < 64 bytes, good crc (+0x1294)*/
+        vuint32_t R;
+    } RMON_R_UNDERSIZE;
+
+    union { /* MIB RMON Rx Packets > MAX_FL bytes, good crc (+0x1298)*/
+        vuint32_t R;
+    } RMON_R_OVERSIZE;
+
+    union { /* MIB RMON Rx Packets < 64 bytes, bad crc (+0x129C)*/
+        vuint32_t R;
+    } RMON_R_FRAG;
+
+    union { /* MIB RMON Rx Packets > MAX_FL bytes, bad crc (0x12A0)*/
+        vuint32_t R;
+    } RMON_R_JAB;
+
+    vuint8_t FEC_reserved14[4]; /*Reserved 4 Bytes (Base+0x12A4-0x12A7) */
+
+    union { /* MIB RMON Rx 64 byte packets (Base+0x12A8) */
+        vuint32_t R;
+    } RMON_R_P64;
+
+    union { /* MIB RMON Rx 65 to 127 byte packets (+0x12AC) */
+        vuint32_t R;
+    } RMON_R_P65TO127;
+
+    union { /* MIB RMON Rx 128 to 255 byte packets (+0x12B0)*/
+        vuint32_t R;
+    } RMON_R_P128TO255;
+
+    union { /* MIB RMON Rx 256 to 511 byte packets (+0x12B4)*/
+        vuint32_t R;
+    } RMON_R_P256TO511;
+
+    union { /* MIB RMON Rx 512 to 1023 byte packets (+0x12B8)*/
+        vuint32_t R;
+    } RMON_R_P512TO1023;
+
+    union { /* MIB RMON Rx 1024 to 2047 byte packets (+0x12BC)*/
+        vuint32_t R;
+    } RMON_R_P1024TO2047;
+
+    union { /* MIB RMON Rx packets w > 2048 bytes (+0x12C0) */
+        vuint32_t R;
+    } RMON_R_P_GTE2048;
+
+    union { /* MIB RMON Rx Octets (Base+0x12C4) */
+        vuint32_t R;
+    } RMON_R_OCTETS;
+
+    union { /* MIB Count of frames not counted correctly (+0x12C8)*/
+        vuint32_t R;
+    } IEEE_R_DROP;
+
+    union { /* MIB Frames Received OK (Base+0x12CC) */
+        vuint32_t R;
+    } IEEE_R_FRAME_OK;
+
+    union { /* MIB Frames Received with CRC Error (+0x12D0) */
+        vuint32_t R;
+    } IEEE_R_CRC;
+
+    union { /* MIB Frames Received Alignment Error (+0x12D4)*/
+        vuint32_t R;
+    } IEEE_R_ALIGN;
+
+    union { /* MIB Receive Fifo Overflow count (+0x12D8) */
+        vuint32_t R;
+    } IEEE_R_MACERR;
+
+    union { /* MIB Flow Control Pause frames Rx'd (+0x12DC) */
+        vuint32_t R;
+    } IEEE_R_FDXFC;
+
+    union { /* MIB Octet count for Frames Rcvd w/o Error (+0x12E0)*/
+        vuint32_t R;
+    } IEEE_R_OCTETS_OK;
+
+
+}; /* end of FEC_tag */
+/****************************************************************************/
+/*                          MODULE : DSPI                                   */
+/****************************************************************************/
+struct DSPI_tag{
+
+    union { /* DSPI Module Configuraiton (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t MSTR:1;
+            vuint32_t CONT_SCKE:1;
+            vuint32_t DCONF:2;
+            vuint32_t FRZ:1;
+            vuint32_t MTFE:1;
+            vuint32_t PCSSE:1;
+            vuint32_t ROOE:1;
+            vuint32_t :2; /* Chip selects 6,7 not bonded out on B3M */
+            vuint32_t PCSIS5:1;
+            vuint32_t PCSIS4:1;
+            vuint32_t PCSIS3:1;
+            vuint32_t PCSIS2:1;
+            vuint32_t PCSIS1:1;
+            vuint32_t PCSIS0:1;
+            vuint32_t :1;
+            vuint32_t MDIS:1;
+            vuint32_t DIS_TXF:1;
+            vuint32_t DIS_RXF:1;
+            vuint32_t CLR_TXF:1;
+            vuint32_t CLR_RXF:1;
+            vuint32_t SMPL_PT:2;
+            vuint32_t :6;
+            vuint32_t PES:1;
+            vuint32_t HALT:1;
+        } B;
+    } MCR;
+
+    vuint8_t DSPI_reserved00[4]; /* Reserved 4 bytes (Base+0x0004-0x0007) */
+
+    union { /* DSPI Transfer Count (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t TCNT:16;
+            vuint32_t :16;
+        } B;
+    } TCR;
+
+    union { /* DSPI Clock & Tranfer Attrib 0-5 (+0x000C-0x0020) */
+        vuint32_t R;
+        struct {
+            vuint32_t DBR:1;
+            vuint32_t FMSZ:4;
+            vuint32_t CPOL:1;
+            vuint32_t CPHA:1;
+            vuint32_t LSBFE:1;
+            vuint32_t PCSSCK:2;
+            vuint32_t PASC:2;
+            vuint32_t PDT:2;
+            vuint32_t PBR:2;
+            vuint32_t CSSCK:4;
+            vuint32_t ASC:4;
+            vuint32_t DT:4;
+            vuint32_t BR:4;
+        } B;
+    } CTAR[6];
+
+    vuint8_t DSPI_reserved0[8]; /* Reserved 8 bytes (Base+0x0024-0x002B) */
+
+    union { /* DSPI Status (Base+0x002C) */
+        vuint32_t R;
+        struct {
+            vuint32_t TCF:1;
+            vuint32_t TXRXS:1;
+            vuint32_t :1;
+            vuint32_t EOQF:1;
+            vuint32_t TFUF:1;
+            vuint32_t :1;
+            vuint32_t TFFF:1;
+            vuint32_t :2;
+            vuint32_t DPEF:1; /* New on Bolero 3M */
+            vuint32_t SPEF:1; /* New on Bolero 3M */
+            vuint32_t DDIF:1; /* New on Bolero 3M */
+            vuint32_t RFOF:1;
+            vuint32_t :1;
+            vuint32_t RFDF:1;
+            vuint32_t :1;
+            vuint32_t TXCTR:4;
+            vuint32_t TXNXTPTR:4;
+            vuint32_t RXCTR:4;
+            vuint32_t POPNXTPTR:4;
+        } B;
+    } SR;
+
+    union { /* DSPI DMA/Int Request Select & Enable (+0x0030) */
+        vuint32_t R;
+        struct {
+            vuint32_t TCFRE:1;
+            vuint32_t :2;
+            vuint32_t EOQFRE:1;
+            vuint32_t TFUFRE:1;
+            vuint32_t :1;
+            vuint32_t TFFFRE:1;
+            vuint32_t TFFFDIRS:1;
+            vuint32_t :1;
+            vuint32_t DPEFRE:1; /* New on Bolero 3M */
+            vuint32_t SPEFRE:1; /* New on Bolero 3M */
+            vuint32_t DDIFRE:1; /* New on Bolero 3M */
+            vuint32_t RFOFRE:1;
+            vuint32_t :1;
+            vuint32_t RFDFRE:1;
+            vuint32_t RFDFDIRS:1;
+            vuint32_t :16;
+        } B;
+    } RSER;
+
+    union { /* DSPI Push TX FIFO (Base+0x0034) */
+        vuint32_t R;
+        struct {
+            vuint32_t CONT:1;
+            vuint32_t CTAS:3;
+            vuint32_t EOQ:1;
+            vuint32_t CTCNT:1;
+            vuint32_t PE:1; /* New on Bolero 3M */
+            vuint32_t PP:1; /* New on Bolero 3M */
+            vuint32_t :2; /* PCS 7..6 not implemented on B3M */
+            vuint32_t PCS5:1;
+            vuint32_t PCS4:1;
+            vuint32_t PCS3:1;
+            vuint32_t PCS2:1;
+            vuint32_t PCS1:1;
+            vuint32_t PCS0:1;
+            vuint32_t TXDATA:16;
+        } B;
+    } PUSHR;
+
+    union { /* DSPI Pop RX FIFO (Base+0x0038)             */
+        vuint32_t R;
+        struct {
+            vuint32_t RXDATA:32; /* Changed t0 32-bit data on B3M        */
+        } B;
+    } POPR;
+
+    union { /* DSPI Transmit FIFO 0-3 (Base+0x003C-0x0048)*/
+        vuint32_t R;
+        struct { /* This is MASTER mode config for B3M    */
+            vuint32_t TXCMD:16; /* replace with TXDATA for B3M slave mode*/
+            vuint32_t TXDATA:16;
+        } B;
+    } TXFR[4];
+
+    vuint8_t DSPI_reserved1[48]; /* Reserved 48 bytes (Base+0x004C-0x007B) */
+
+    union { /* DSPI Receive FIFO 0-3 (Base+0x007C-0x0088) */
+        vuint32_t R;
+        struct {
+            vuint32_t RXDATA:32; /* Changed to 32-bit data on B3M        */
+        } B;
+    } RXFR[4];
+
+    vuint8_t DSPI_reserved2[48]; /* Reserved 48 bytes (Base+0x008C-0x00BB) */
+
+    union { /* DSPI DSI Configuration (Base+0x00BC) */
+        vuint32_t R;
+        struct {
+            vuint32_t MTOE:1;
+            vuint32_t FMSZ4:1; /* New on Bolero 3M */
+            vuint32_t MTOCNT:6;
+            vuint32_t :3;
+            vuint32_t TSBC:1; /* New on Bolero 3M */
+            vuint32_t TXSS:1;
+            vuint32_t TPOL:1;
+            vuint32_t TRRE:1;
+            vuint32_t CID:1;
+            vuint32_t DCONT:1;
+            vuint32_t DSICTAS:3;
+            vuint32_t DMS:1; /* New on Bolero 3M */
+            vuint32_t PES:1; /* New on Bolero 3M */
+            vuint32_t PE:1; /* New on Bolero 3M */
+            vuint32_t PP:1; /* New on Bolero 3M */
+            vuint32_t :2; /* PCS 7..6 not implemented on B3M */
+            vuint32_t DPCS5:1;
+            vuint32_t DPCS4:1;
+            vuint32_t DPCS3:1;
+            vuint32_t DPCS2:1;
+            vuint32_t DPCS1:1;
+            vuint32_t DPCS0:1;
+        } B;
+    } DSICR;
+
+    union { /* DSPI DSI Serialization Data (Base+0x00C0) */
+        vuint32_t R;
+        struct {
+            vuint32_t SER_DATA:32; /* Changed to 32-bit data on B3M */
+        } B;
+    } SDR;
+
+    union { /* DSPI ALT DSI Serialization Data (Base+0x00C4) */
+        vuint32_t R;
+        struct {
+            vuint32_t ASER_DATA:32; /* Changed to 32-bit data on B3M */
+        } B;
+    } ASDR;
+
+    union { /* DSPI DSI Transmit Comparison (Base+0x00C8) */
+        vuint32_t R;
+        struct {
+            vuint32_t COMP_DATA:32; /* Changed to 32-bit data on B3M */
+        } B;
+    } COMPR;
+
+    union { /* DSPI DSI Deserialization Data (Base+0x00CC) */
+        vuint32_t R;
+        struct {
+            vuint32_t DESER_DATA:32; /* Changed to 32-bit data on B3M */
+        } B;
+    } DDR;
+
+    union { /* DSPI DSI Configuration 1 (Base+0x00D0)    */
+        vuint32_t R; /* NB this reg was missing from 1.5M header! */
+        struct {
+            vuint32_t :3;
+            vuint32_t TSBCNT:5;
+            vuint32_t :6;
+            vuint32_t DSE1:1;
+            vuint32_t DSE0:1;
+            vuint32_t :8;
+            vuint32_t :1; /* vuint32_t DPCS1_7:1; (Not implemented on B3m)*/
+            vuint32_t :1; /* vuint32_t DPCS1_6:1; (Not implemented on B3m)*/
+            vuint32_t DPCS1_5:1;
+            vuint32_t DPCS1_4:1;
+            vuint32_t DPCS1_3:1;
+            vuint32_t DPCS1_2:1;
+            vuint32_t DPCS1_1:1;
+            vuint32_t DPCS1_0:1;
+        } B;
+    } DSICR1;
+
+    union { /* DSPI DSI Serialisation Source (Base+0x00D4) */
+        vuint32_t R;
+        struct {
+            vuint32_t SS:32; /* All bits avail for B3M */
+        } B;
+    } SSR;
+
+    vuint8_t DSPI_reserved4[16]; /* Reserved 16 bytes (Base+0x00D8-0x00E7) */
+
+    union { /* DSPI DSI Deserialised Data Interrupt Mask (+0x00E8) */
+        vuint32_t R;
+        struct {
+            vuint32_t MASK:32; /* 32-bit for B3M */
+        } B;
+    } DIMR;
+
+    union { /* DSPI DSI Deserialised Data Poloarity Int (+0x00E8) */
+        vuint32_t R;
+        struct {
+            vuint32_t DP:32; /* 32-bit for B3M */
+        } B;
+    } DPIR;
+
+}; /* end of DSPI_tag */
+/****************************************************************************/
+/*                          MODULE : FlexCAN                                */
+/****************************************************************************/
+struct FLEXCAN_BUF_t{
+
+    union { /* FLEXCAN MBx Control & Status (Offset+0x0080) */
+        vuint32_t R;
+        struct {
+            vuint32_t :4;
+            vuint32_t CODE:4;
+            vuint32_t :1;
+            vuint32_t SRR:1;
+            vuint32_t IDE:1;
+            vuint32_t RTR:1;
+            vuint32_t LENGTH:4;
+            vuint32_t TIMESTAMP:16;
+        } B;
+    } CS;
+
+    union { /* FLEXCAN MBx Identifier (Offset+0x0084) */
+        vuint32_t R;
+        struct {
+            vuint32_t PRIO:3;
+            vuint32_t STD_ID:11;
+            vuint32_t EXT_ID:18;
+        } B;
+    } ID;
+
+    union { /* FLEXCAN MBx Data 0..7 (Offset+0x0088) */
+        vuint8_t B[8]; /* Data buffer in Bytes (8 bits) */
+        vuint16_t H[4]; /* Data buffer in Half-words (16 bits) */
+        vuint32_t W[2]; /* Data buffer in words (32 bits) */
+        vuint32_t R[2]; /* Data buffer in words (32 bits) */
+    } DATA;
+
+}; /* end of FLEXCAN_BUF_t */
+
+
+struct FLEXCAN_RXFIFO_t{ /* RxFIFO Configuration */
+
+    union { /* RxFIFO Control & Status (Offset+0x0080) */
+        vuint32_t R;
+        struct {
+            vuint32_t :9;
+            vuint32_t SRR:1;
+            vuint32_t IDE:1;
+            vuint32_t RTR:1;
+            vuint32_t LENGTH:4;
+            vuint32_t TIMESTAMP:16;
+        } B;
+    } CS;
+
+    union { /* RxFIFO Identifier (Offset+0x0084) */
+        vuint32_t R;
+        struct {
+            vuint32_t :3;
+            vuint32_t STD_ID:11;
+            vuint32_t EXT_ID:18;
+        } B;
+    } ID;
+
+    union { /* RxFIFO Data 0..7 (Offset+0x0088) */
+        vuint8_t B[8]; /* Data buffer in Bytes (8 bits) */
+        vuint16_t H[4]; /* Data buffer in Half-words (16 bits) */
+        vuint32_t W[2]; /* Data buffer in words (32 bits) */
+        vuint32_t R[2]; /* Data buffer in words (32 bits) */
+    } DATA;
+
+    vuint8_t FLEXCAN_RX_reserved0[80]; /* Reserved 80 bytes (+0x0090-0x00DF)*/
+
+    union { /* RxFIFO ID Table 0..7 (+0x00E0-0x00FC) */
+        vuint32_t R;
+    } IDTABLE[8];
+
+}; /* end of FLEXCAN_RXFIFO_t */
+
+
+struct FLEXCAN_tag{
+
+    union { /* FLEXCAN Module Configuration (Base+0x0000) */
+        vuint32_t R;
+        struct {
+            vuint32_t MDIS:1;
+            vuint32_t FRZ:1;
+            vuint32_t FEN:1;
+            vuint32_t HALT:1;
+            vuint32_t NOTRDY:1;
+            vuint32_t WAKMSK:1;
+            vuint32_t SOFTRST:1;
+            vuint32_t FRZACK:1;
+            vuint32_t SUPV:1;
+            vuint32_t SLFWAK:1;
+            vuint32_t WRNEN:1;
+            vuint32_t LPMACK:1;
+            vuint32_t WAKSRC:1;
+            vuint32_t DOZE:1;
+            vuint32_t SRXDIS:1;
+            vuint32_t BCC:1;
+            vuint32_t :2;
+            vuint32_t LPRIO_EN:1;
+            vuint32_t AEN:1;
+            vuint32_t :2;
+            vuint32_t IDAM:2;
+            vuint32_t :2;
+            vuint32_t MAXMB:6;
+        } B;
+    } MCR;
+
+    union { /* FLEXCAN Control (Base+0x0004) */
+        vuint32_t R;
+        struct {
+            vuint32_t PRESDIV:8;
+            vuint32_t RJW:2;
+            vuint32_t PSEG1:3;
+            vuint32_t PSEG2:3;
+            vuint32_t BOFFMSK:1;
+            vuint32_t ERRMSK:1;
+            vuint32_t CLKSRC:1;
+            vuint32_t LPB:1;
+            vuint32_t TWRNMSK:1;
+            vuint32_t RWRNMSK:1;
+            vuint32_t :2;
+            vuint32_t SMP:1;
+            vuint32_t BOFFREC:1;
+            vuint32_t TSYN:1;
+            vuint32_t LBUF:1;
+            vuint32_t LOM:1;
+            vuint32_t PROPSEG:3;
+        } B;
+    } CR;
+
+    union { /* FLEXCAN Free Running Timer (Base+0x0008) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t TIMER:16;
+        } B;
+     } TIMER;
+
+    vuint8_t FLEXCAN_reserved0[4]; /* reserved 4 bytes (Base+0x000C-0x000F) */
+
+    union { /* FLEXCAN RX Global Mask (Base+0x0010) */
+        vuint32_t R;
+        struct {
+            vuint32_t MI:32;
+        } B;
+     } RXGMASK;
+
+    /*  --- Following 2 registers are included for legacy purposes only --- */
+
+    union { /* FLEXCAN RX 14 Mask (Base+0x0014) */
+        vuint32_t R;
+        struct {
+            vuint32_t MI:32;
+        } B;
+     } RX14MASK;
+
+    union { /* FLEXCAN RX 15 Mask (Base+0x0018) */
+        vuint32_t R;
+        struct {
+            vuint32_t MI:32;
+        } B;
+     } RX15MASK;
+
+    /*  --- */
+
+    union { /* FLEXCAN Error Counter (Base+0x001C) */
+        vuint32_t R;
+        struct {
+            vuint32_t :16;
+            vuint32_t RXECNT:8;
+            vuint32_t TXECNT:8;
+        } B;
+    } ECR;
+
+    union { /* FLEXCAN Error & Status (Base+0x0020) */
+        vuint32_t R;
+        struct {
+            vuint32_t :14;
+            vuint32_t TWRNINT:1;
+            vuint32_t RWRNINT:1;
+            vuint32_t BIT1ERR:1;
+            vuint32_t BIT0ERR:1;
+            vuint32_t ACKERR:1;
+            vuint32_t CRCERR:1;
+            vuint32_t FRMERR:1;
+            vuint32_t STFERR:1;
+            vuint32_t TXWRN:1;
+            vuint32_t RXWRN:1;
+            vuint32_t IDLE:1;
+            vuint32_t TXRX:1;
+            vuint32_t FLTCONF:2;
+            vuint32_t :1;
+            vuint32_t BOFFINT:1;
+            vuint32_t ERRINT:1;
+            vuint32_t WAKINT:1;
+        } B;
+    } ESR;
+
+    union { /* FLEXCAN Interruput Masks H (Base+0x0024) */
+        vuint32_t R;
+        struct {
+            vuint32_t BUF63M:1;
+            vuint32_t BUF62M:1;
+            vuint32_t BUF61M:1;
+            vuint32_t BUF60M:1;
+            vuint32_t BUF59M:1;
+            vuint32_t BUF58M:1;
+            vuint32_t BUF57M:1;
+            vuint32_t BUF56M:1;
+            vuint32_t BUF55M:1;
+            vuint32_t BUF54M:1;
+            vuint32_t BUF53M:1;
+            vuint32_t BUF52M:1;
+            vuint32_t BUF51M:1;
+            vuint32_t BUF50M:1;
+            vuint32_t BUF49M:1;
+            vuint32_t BUF48M:1;
+            vuint32_t BUF47M:1;
+            vuint32_t BUF46M:1;
+            vuint32_t BUF45M:1;
+            vuint32_t BUF44M:1;
+            vuint32_t BUF43M:1;
+            vuint32_t BUF42M:1;
+            vuint32_t BUF41M:1;
+            vuint32_t BUF40M:1;
+            vuint32_t BUF39M:1;
+            vuint32_t BUF38M:1;
+            vuint32_t BUF37M:1;
+            vuint32_t BUF36M:1;
+            vuint32_t BUF35M:1;
+            vuint32_t BUF34M:1;
+            vuint32_t BUF33M:1;
+            vuint32_t BUF32M:1;
+        } B;
+    } IMRH;
+
+    union { /* FLEXCAN Interruput Masks L (Base+0x0028) */
+        vuint32_t R;
+        struct {
+            vuint32_t BUF31M:1;
+            vuint32_t BUF30M:1;
+            vuint32_t BUF29M:1;
+            vuint32_t BUF28M:1;
+            vuint32_t BUF27M:1;
+            vuint32_t BUF26M:1;
+            vuint32_t BUF25M:1;
+            vuint32_t BUF24M:1;
+            vuint32_t BUF23M:1;
+            vuint32_t BUF22M:1;
+            vuint32_t BUF21M:1;
+            vuint32_t BUF20M:1;
+            vuint32_t BUF19M:1;
+            vuint32_t BUF18M:1;
+            vuint32_t BUF17M:1;
+            vuint32_t BUF16M:1;
+            vuint32_t BUF15M:1;
+            vuint32_t BUF14M:1;
+            vuint32_t BUF13M:1;
+            vuint32_t BUF12M:1;
+            vuint32_t BUF11M:1;
+            vuint32_t BUF10M:1;
+            vuint32_t BUF09M:1;
+            vuint32_t BUF08M:1;
+            vuint32_t BUF07M:1;
+            vuint32_t BUF06M:1;
+            vuint32_t BUF05M:1;
+            vuint32_t BUF04M:1;
+            vuint32_t BUF03M:1;
+            vuint32_t BUF02M:1;
+            vuint32_t BUF01M:1;
+            vuint32_t BUF00M:1;
+        } B;
+    } IMRL;
+
+    union { /* FLEXCAN Interruput Flag H (Base+0x002C) */
+        vuint32_t R;
+        struct {
+            vuint32_t BUF63I:1;
+            vuint32_t BUF62I:1;
+            vuint32_t BUF61I:1;
+            vuint32_t BUF60I:1;
+            vuint32_t BUF59I:1;
+            vuint32_t BUF58I:1;
+            vuint32_t BUF57I:1;
+            vuint32_t BUF56I:1;
+            vuint32_t BUF55I:1;
+            vuint32_t BUF54I:1;
+            vuint32_t BUF53I:1;
+            vuint32_t BUF52I:1;
+            vuint32_t BUF51I:1;
+            vuint32_t BUF50I:1;
+            vuint32_t BUF49I:1;
+            vuint32_t BUF48I:1;
+            vuint32_t BUF47I:1;
+            vuint32_t BUF46I:1;
+            vuint32_t BUF45I:1;
+            vuint32_t BUF44I:1;
+            vuint32_t BUF43I:1;
+            vuint32_t BUF42I:1;
+            vuint32_t BUF41I:1;
+            vuint32_t BUF40I:1;
+            vuint32_t BUF39I:1;
+            vuint32_t BUF38I:1;
+            vuint32_t BUF37I:1;
+            vuint32_t BUF36I:1;
+            vuint32_t BUF35I:1;
+            vuint32_t BUF34I:1;
+            vuint32_t BUF33I:1;
+            vuint32_t BUF32I:1;
+        } B;
+    } IFRH;
+
+    union { /* FLEXCAN Interruput Flag l (Base+0x0030) */
+        vuint32_t R;
+        struct {
+            vuint32_t BUF31I:1;
+            vuint32_t BUF30I:1;
+            vuint32_t BUF29I:1;
+            vuint32_t BUF28I:1;
+            vuint32_t BUF27I:1;
+            vuint32_t BUF26I:1;
+            vuint32_t BUF25I:1;
+            vuint32_t BUF24I:1;
+            vuint32_t BUF23I:1;
+            vuint32_t BUF22I:1;
+            vuint32_t BUF21I:1;
+            vuint32_t BUF20I:1;
+            vuint32_t BUF19I:1;
+            vuint32_t BUF18I:1;
+            vuint32_t BUF17I:1;
+            vuint32_t BUF16I:1;
+            vuint32_t BUF15I:1;
+            vuint32_t BUF14I:1;
+            vuint32_t BUF13I:1;
+            vuint32_t BUF12I:1;
+            vuint32_t BUF11I:1;
+            vuint32_t BUF10I:1;
+            vuint32_t BUF09I:1;
+            vuint32_t BUF08I:1;
+            vuint32_t BUF07I:1;
+            vuint32_t BUF06I:1;
+            vuint32_t BUF05I:1;
+            vuint32_t BUF04I:1;
+            vuint32_t BUF03I:1;
+            vuint32_t BUF02I:1;
+            vuint32_t BUF01I:1;
+            vuint32_t BUF00I:1;
+        } B;
+    } IFRL; /* Interruput Flag Register */
+
+    vuint8_t FLEXCAN_reserved1[76]; /*Reserved 76 bytes (Base+0x0034-0x007F)*/
+
+/****************************************************************************/
+/* Use either Standard Buffer Structure OR RX FIFO and Buffer Structure     */
+/****************************************************************************/
+    /* Standard Buffer Structure */
+    struct FLEXCAN_BUF_t BUF[64];
+
+    /* RX FIFO and Buffer Structure */
+    /*struct FLEXCAN_RXFIFO_t RXFIFO; */
+    /*struct FLEXCAN_BUF_t BUF[56];   */
+/****************************************************************************/
+
+    vuint8_t FLEXCAN_reserved2[1024]; /*Reserved 1024 (Base+0x0480-0x087F)*/
+
+    union { /* FLEXCAN RX Individual Mask (Base+0x0880-0x097F) */
+        vuint32_t R;
+        struct {
+          vuint32_t MI:32;
+        } B;
+    } RXIMR[64];
+
+}; /* end of FLEXCAN_tag */
+/****************************************************************************/
+/*                          MODULE : DMAMUX                                 */
+/****************************************************************************/
+struct DMAMUX_tag {
+
+    union { /* DMAMUX Channel Configuration (Base+0x0000-0x000F) */
+        vuint8_t R;
+        struct {
+            vuint8_t ENBL:1;
+            vuint8_t TRIG:1;
+            vuint8_t SOURCE:6;
+        } B;
+    } CHCONFIG[32];
+
+}; /* end of DMAMUX_tag */
+/****************************************************************** 
+| defines and macros (scope: module-local) 
+|-----------------------------------------------------------------*/
+/* Define instances of modules (in address order) */
+
+#define CFLASH_0  (*(volatile struct CFLASH_tag *)      0xC3F88000UL)
+#define DFLASH    (*(volatile struct DFLASH_tag *)      0xC3F8C000UL)
+#define SIU       (*(volatile struct SIU_tag *)         0xC3F90000UL)
+#define WKUP      (*(volatile struct WKUP_tag *)        0xC3F94000UL)
+#define EMIOS_0   (*(volatile struct EMIOS_tag *)       0xC3FA0000UL)
+#define EMIOS_1   (*(volatile struct EMIOS_tag *)       0xC3FA4000UL)
+#define CFLASH_1  (*(volatile struct CFLASH_tag *)      0xC3FB0000UL)
+#define SSCM      (*(volatile struct SSCM_tag *)        0xC3FD8000UL)
+#define ME        (*(volatile struct ME_tag *)          0xC3FDC000UL)
+#define CGM       (*(volatile struct CGM_tag *)         0xC3FE0000UL)
+#define RGM       (*(volatile struct RGM_tag *)         0xC3FE4000UL)
+#define PCU       (*(volatile struct PCU_tag *)         0xC3FE8000UL)
+#define RTC       (*(volatile struct RTC_tag *)         0xC3FEC000UL)
+#define PIT       (*(volatile struct PIT_tag *)         0xC3FF0000UL)
+#define STCU      (*(volatile struct STCU_tag *)        0xC3FF4000UL)
+#define ADC_0     (*(volatile struct ADC0_tag *)        0xFFE00000UL)
+#define ADC_1     (*(volatile struct ADC1_tag *)        0xFFE04000UL)
+#define I2C       (*(volatile struct I2C_tag *)         0xFFE30000UL)
+#define LINFLEX_0 (*(volatile struct LINFLEX_MS_tag *)  0xFFE40000UL)
+#define LINFLEX_1 (*(volatile struct LINFLEX_M_tag *)   0xFFE44000UL)
+#define LINFLEX_2 (*(volatile struct LINFLEX_M_tag *)   0xFFE48000UL)
+#define LINFLEX_3 (*(volatile struct LINFLEX_M_tag *)   0xFFE4C000UL)
+#define LINFLEX_4 (*(volatile struct LINFLEX_M_tag *)   0xFFE50000UL)
+#define LINFLEX_5 (*(volatile struct LINFLEX_M_tag *)   0xFFE54000UL)
+#define LINFLEX_6 (*(volatile struct LINFLEX_M_tag *)   0xFFE58000UL)
+#define LINFLEX_7 (*(volatile struct LINFLEX_M_tag *)   0xFFE5C000UL)
+#define CTU       (*(volatile struct CTU_tag *)         0xFFE64000UL)
+#define CANSP     (*(volatile struct CANSP_tag *)       0xFFE70000UL)
+#define XBAR      (*(volatile struct XBAR_tag *)        0xFFF04000UL)
+#define MPU       (*(volatile struct MPU_tag *)         0xFFF10000UL)
+#define CSE       (*(volatile struct CSE_tag *)         0xFFF1C000UL)
+#define SEMA4     (*(volatile struct SEMA4_tag *)       0xFFF24000UL)
+#define SWT       (*(volatile struct SWT_tag *)         0xFFF38000UL)
+#define STM       (*(volatile struct STM_tag *)         0xFFF3C000UL)
+#define ECSM      (*(volatile struct ECSM_tag *)        0xFFF40000UL)
+#define EDMA      (*(volatile struct EDMA_tag *)        0xFFF44000UL)
+#define INTC      (*(volatile struct INTC_tag *)        0xFFF48000UL)
+#define FEC       (*(volatile struct FEC_tag *)         0xFFF4C000UL)
+#define DSPI_0    (*(volatile struct DSPI_tag *)        0xFFF90000UL)
+#define DSPI_1    (*(volatile struct DSPI_tag *)        0xFFF94000UL)
+#define DSPI_2    (*(volatile struct DSPI_tag *)        0xFFF98000UL)
+#define DSPI_3    (*(volatile struct DSPI_tag *)        0xFFF9C000UL)
+#define DSPI_4    (*(volatile struct DSPI_tag *)        0xFFFA0000UL)
+#define DSPI_5    (*(volatile struct DSPI_tag *)        0xFFFA4000UL)
+#define DSPI_6    (*(volatile struct DSPI_tag *)        0xFFFA8000UL)
+#define DSPI_7    (*(volatile struct DSPI_tag *)        0xFFFAC000UL)
+#define LINFLEX_8 (*(volatile struct LINFLEX_M_tag *)   0xFFFB0000UL)
+#define LINFLEX_9 (*(volatile struct LINFLEX_M_tag *)   0xFFFB4000UL)
+#define CAN_0     (*(volatile struct FLEXCAN_tag *)     0xFFFC0000UL)
+#define CAN_1     (*(volatile struct FLEXCAN_tag *)     0xFFFC4000UL)
+#define CAN_2     (*(volatile struct FLEXCAN_tag *)     0xFFFC8000UL)
+#define CAN_3     (*(volatile struct FLEXCAN_tag *)     0xFFFCC000UL)
+#define CAN_4     (*(volatile struct FLEXCAN_tag *)     0xFFFD0000UL)
+#define CAN_5     (*(volatile struct FLEXCAN_tag *)     0xFFFD4000UL)
+#define DMAMUX    (*(volatile struct DMAMUX_tag *)      0xFFFDC000UL)
+
+// Flexray is NOT added to this header. Expected use is that Flexray is used with drivers. 
+
+
+
+#ifdef __MWERKS__
+#pragma pop
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif 
+
+/* End of file */ 

+ 156 - 0
BMS Master/Project_Headers/MPC5646C_HWInit.h

@@ -0,0 +1,156 @@
+/*
+ * FILE : MPC564xBC_HWInit.h
+ * Contains the declarations for device initialization. 
+ */
+ 
+#ifndef _MPC564xBC_HWINIT_H_
+#define _MPC564xBC_HWINIT_H_
+
+/*----------------------------------------------------------------------------*/
+/* Includes                                                                   */
+/*----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************/
+/* MPC564xBC derivative specific hardware initialization */
+/*******************************************************/ 
+__asm void INIT_Derivative(void); 
+
+/*----------------------------------------------------------------------------*/
+/* MMU Table Entries Defines                                                  */
+/*----------------------------------------------------------------------------*/
+/**
+ * Generate MMU Assist 0 value from the parameters provided.
+ * In accordance with the PowerPC Zen core specification the TLBSEL value 
+ * is always set to 01b to maintain future compatibility.
+ *
+ */
+#define MAS0_VALUE(eselcam) ((unsigned long)(0x10000000 | (eselcam << 16)))
+
+/** 
+ * Generate MMU Assist 1 value from the parameters provided
+ *
+ * parameter valid:   1 if the MMU entry is valid, otherwise \c 0 (invalid).
+ * parameter iprot:   Invalidation protection value
+ * parameter tid:     the translation ID
+ * parameter ts:      the translation space value
+ * parameter tsize:   the translation size
+ */
+#define MAS1_VALUE(valid, iprot, tid, ts, tsize) \
+          ((unsigned long)((valid << 31) | (iprot << 30) | (tid << 16) | (ts << 12) | (tsize << 7)))
+
+/** Translation address space. This bit is compared with the IS or DS fields
+	of the MSR (depending on the type of access) to determine if this TLB
+	entry may be used for translation.
+*/
+#define TS_ON  1
+#define TS_OFF 0
+
+/** V TLB valid bit */
+#define V_INVALID 0
+#define V_VALID   1
+
+/** IPROT TLB Invalidate protect bit */
+#define IPROT_NOTPROTECTED 0
+#define IPROT_PROTECTED    1
+
+ /** Translation ID defines the TID as global and matches all process IDs */
+#define TID_GLOBAL          0
+
+/** Translation size */
+#define TSIZE_1KB			0
+#define TSIZE_2KB			1
+#define TSIZE_4KB           2
+#define TSIZE_8KB			3
+#define TSIZE_16KB          4
+#define TSIZE_32KB          5
+#define TSIZE_64KB          6
+#define TSIZE_128KB         7
+#define TSIZE_256KB         8
+#define TSIZE_512KB         9
+#define TSIZE_1MB           10
+#define TSIZE_2MB           11
+#define TSIZE_4MB         	12
+#define TSIZE_8MB         	13
+#define TSIZE_16MB         	14
+#define TSIZE_32MB         	15
+#define TSIZE_64MB         	16
+#define TSIZE_128MB       	17
+#define TSIZE_256MB        	18
+#define TSIZE_512MB        	19
+#define TSIZE_1GB        	20
+#define TSIZE_2GB        	21
+#define TSIZE_4GB        	22
+
+/**
+ * Generate MMU Assist 2 value from the parameters provided
+ *
+ * Effective Page Number (start address of logical memory region) 
+ * must be computed directly in the assembly code.
+ * 
+ * parameter   epn: effective page number
+ * parameter   vle: VLE flag
+ * parameter   w:   Write-through Required
+ * parameter   i:   Cache Inhibited
+ * parameter   m:   Memory Coherence Required
+ * parameter   g:   Guarded
+ * parameter   e:   Endianness
+ */
+#define MAS2_VALUE(epn, vle, w, i, m, g, e) \
+  ((unsigned long)((epn << 12) | (vle << 5) | (w << 4) | (i << 3) | (m << 2) | (g << 1) | (e)))
+
+/** MAS2[VLE]: Book E mode */
+#define BOOK_E_MODE         0
+/** MAS2[VLE]: VLE mode */
+#define VLE_MODE            1
+
+/** MAS2[W]: Update data in the cache only */
+#define WRITE_BACK          0
+/** MAS2[W]: All stores performed are written through to memory */
+#define WRITE_THROUGH       1
+
+/** MAS2[I]: The page is considered cacheable */
+#define CACHEABLE           0
+/** MAS2[I]: The page is cache-inhibited */
+#define CACHE_INHIBIT       1
+
+/** MAS2[M]: Memory Coherence is not-required */
+#define MEM_COHERENCE_NREQ  0
+/** MAS2[M]: Memory Coherence is required */
+#define MEM_COHENRECE_REQ   1
+
+/** MAS2[G]: Access to page is not guarded */
+#define NOT_GUARDED         0
+/** MAS2[G]: All loads and stores are performed without speculation */
+#define GUARDED             1
+
+/** MAS2[E]: Page is accessed in big-endian order */
+#define BIG_ENDIAN          0
+/** MAS2[E]: Page is accessed in little-endian order */
+#define LITTLE_ENDIAN       1
+ 
+/**
+ * Generate MMU Assist 3 flags from the parameters provided
+ *
+ * Real Page Number (start address of physical memory region) 
+ * must be computed directly in the assembly code
+ *
+ * parameter rpn: real page number
+ * parameter permissions:  Permission bits
+ */
+#define MAS3_VALUE(rpn, permissions) \
+	((unsigned long)((rpn << 12) | permissions))
+
+/** MAS3[U/S{XWR}]: Read. Write and Execute permission */
+#define READ_WRITE_EXECUTE  0x3f
+/** MAS3[U/S{XWR}]: Read and Execute permission */
+#define READ_EXECUTE        0x33
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 76 - 0
BMS Master/Project_Headers/MultitaskOS.h

@@ -0,0 +1,76 @@
+//##############################################################################
+//
+// FILE:	MultitaskOS.h
+//
+// TITLE:	Real Time 1 ms Generator
+//
+//
+//##############################################################################
+//
+//==============================================================================
+// Change History:
+//==============================================================================
+// Datum:   | Name | Version:| Change / Cause:                            | No
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 002
+//------------------------------------------------------------------------------
+// 05.07.13 |  VR  |   1.1   | Change for ReilingOS                       | 001
+//------------------------------------------------------------------------------
+// 02.05.12 |  TM  |   1.0   | New Build                                  | 000
+//==============================================================================
+//==============================================================================
+// Comment Change / Cause:
+//==============================================================================
+// Change: 003                                                           // 003
+//----------------------
+//                                                       
+//
+//==============================================================================
+// Change: 002                                                           // 002
+//----------------------
+//                                           
+//
+//==============================================================================
+// Change: 001                                                           // 001
+//----------------------
+// 
+//
+//==============================================================================
+
+#ifndef __MULTITASKOS_H__
+#define __MULTITASKOS_H__
+
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+
+// ***** Defines ***************************************************************
+    #define SYSCLK_KHZ 120000
+
+
+    
+// ***** External Variables ****************************************************    
+extern	uint32_t	Global_1msCounter;
+extern	uint32_t	Global_1msCounterCopy;
+extern	uint32_t	Global_1msCounterDelta;
+extern  uint32_t    gISO_R;
+
+
+
+// ***** Function Prototypes ***************************************************
+void	MultitaskOS_init	(void);
+void	ISR_Timer_OS		(void);
+
+
+
+#ifdef __cplusplus
+    }
+#endif
+
+    
+    
+#endif  /* ifndef*/

+ 59 - 0
BMS Master/Project_Headers/RelaisLEDs.h

@@ -0,0 +1,59 @@
+//==============================================================================
+// Purpose:     DigitalOutput-Ansteuerung
+//
+// Created on:  21.09.2012 by IPE
+//
+// History
+//		21.09.2012 neu, T.Maurer
+//==============================================================================
+
+#ifndef __RelaisLEDs_H__
+#define __RelaisLEDs_H__
+
+
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+//==============================================================================
+// Include files
+
+
+//Master-Board LED-Pins
+//MPC-RM S.75ff
+#define PIN_REGNR_LED1		158	//Port PJ[14] = PCR[158]
+#define PIN_REGNR_LED2		159	//PJ[15] = PCR[159]
+#define PIN_REGNR_LED3		160	//PK[0] = PCR[160] // high == Power Relais disconnected low = Power-Relais Connected
+#define PIN_REGNR_LED4		4	//PA[4] = PCR[4]	// high = no Error Low = Error
+
+//Master-Board HighSide-Switches Out-Pins
+#define PIN_REGNR_HS1	80	//PF[0]
+#define PIN_REGNR_HS2	81	//PF[1]
+#define PIN_REGNR_HS3	82	//PF[2]
+#define PIN_REGNR_HS4	83	//PF[3]
+#define PIN_REGNR_HS5	84	//PF[4]
+#define PIN_REGNR_HS6	85	//PF[5]
+#define PIN_REGNR_HS7	86	//PF[6]
+#define PIN_REGNR_HS8	87	//PF[7]
+//Master-Board Relais-Switches Out-Pins
+#define PIN_REGNR_RELAIS_PLUS	144	//PJ[0]
+#define PIN_REGNR_RELAIS_PRECHA 145	//PJ[1]
+#define PIN_REGNR_RELAIS_SLAVE	146	//PJ[2]
+#define PIN_REGNR_PWR_SUPPLY	107 //PG[11]        
+
+
+//ISO Inputs
+#define PIN_REGNR_MHS		22		// PB[6] (ADC3) = PCR[108]
+#define PIN_REGNR_OKHS		23		// PB[7] (ADC4) = PCR[109]    
+    
+//API
+extern void RelaisLEDs_init();
+extern uint8_t RelaisLEDs_TM_update(uint8_t tick);	//TestMode
+
+#ifdef __cplusplus
+    }
+#endif
+
+
+#endif  /* ifndef*/

+ 50 - 0
BMS Master/Project_Headers/TempSensorSpi.h

@@ -0,0 +1,50 @@
+// ----------------------------------------------------------------------------
+// TEempSensorSpi.h - 
+// ----------------------------------------------------------------------------
+// Beschreibung:	Temperatur-Sensor (TMP121) mit SPI-IF
+//					HW: BMS-Master, IPE 362-02-02R0
+// Revision:		27. Juni 2012, neu	Maurer, IPE
+// ----------------------------------------------------------------------------
+
+#ifndef _TEMPSENS_H_
+#define _TEMPSENS_H_
+
+
+typedef struct {
+	enum {Idle=0,Read_1,Read_2} FsmState;
+	enum {No_Task,Read} TaskTrigger;   // NoTask to No_Task
+	int16_t value;
+	uint8_t num_data;
+	uint8_t i_databyte;
+	uint8_t valueIsNew;
+	union {
+		uint8_t R;
+		struct {
+			uint8_t FSM_TO:1;
+			uint8_t rsvd:6;
+			} B;
+	} Flags;
+} TempMessStatus_t;
+//Datentyp zum speichern des Status des Moduls
+
+
+// API
+
+extern void TempMess_init (void);
+//Aufruf der SPI-Config und Initialisierung des Status-Structs
+
+extern void TempMess_update(void);
+//ruft FSM_update() auf. Der Aufruf muss getaktet sein (1ms), damit der
+//Fsm-TimeOut funktioniert.
+
+extern int8_t TempMess_poll_Value(int16_t *target);
+//Ueberprueft, ob ein neuer Messwert zur Verfuegung steht und schreibt ihn
+//in *target. Der 12-bit-Wert des Sensors wird auf 8-bit "abgeschnitten"
+//-> Aufloesung = 1°, Messbereich: -55°..+150°
+//return -1 , wenn kein neuer Wert vorhanden ist
+//return 0 , wenn ein neuer Wert geschrieben wurde
+
+extern int8_t TempMess_triggerRead(void);
+//Trigger, zum Starten einer Wandlung
+
+#endif  /* ifndef*/

+ 33 - 0
BMS Master/Project_Headers/UartToUsb.h

@@ -0,0 +1,33 @@
+//==============================================================================
+// Purpose:    Uart->USB-Schnittstelle (FTDI) auf dem BMS-MasterBoard
+//
+// Created on:  11.07.2012 by KIT-IPE (Fachgr.: Blank)
+//
+// History
+//		11.07.2012 neu, T. Maurer
+//==============================================================================
+
+#ifndef __UARTTOUSB_H__
+#define __UARTTOUSB_H__
+
+// Globale Datentypen
+
+
+//API
+
+extern int8_t UartToUsb_init();
+//a) Ausschalten des FTDI-Resets: durch High-Setzen des Out-Ports
+//b) Aufruf der LIN_init()
+//return Returnwert von LIN_init()
+
+//extern int8_t UartToUsb_update();
+
+extern int8_t UartToUsb_push(const int16_t data);
+//Byte auf Uart schreiben
+//return Returnwert von LIN_push()
+
+extern int8_t UartToUsb_pop(int16_t *const data);
+//Byte von Uart abholen
+//return Returnwert von LIN_pop()
+
+#endif /*ifndef*/

+ 122 - 0
BMS Master/Project_Headers/typedefs.h

@@ -0,0 +1,122 @@
+/**************************************************************************
+ * FILE NAME: $RCSfile: typedefs.h,v $       COPYRIGHT (c) Freescale 2005 *
+ * DESCRIPTION:                                     All Rights Reserved   *
+ * This file defines all of the data types for the Motorola header file.  *
+ *========================================================================*
+ * ORIGINAL AUTHOR: Jeff Loeliger (r12110)                                *
+ * $Log: typedefs.h,v $
+ * Revision 1.1  2010/07/21 13:28:05  dmihail1
+ * Add to DataBase: 'runtime' folder
+ * See: MTWX40737, MTWX40738, MTWX40743, MTWX42016
+ *
+ * Revision 1.7  2007/05/02 22:46:00  dfreeland
+ * Use latest web version
+ *
+ * Revision 1.4  2006/03/27 09:59:34  r47354
+ * change __GHS__ to __ghs__. As per bug 13213
+ *
+ * Revision 1.3  2005/02/22 13:09:38  r47354
+ * Fix copyright date.
+ *
+ * Revision 1.2  2004/11/17 12:43:12  r12110
+ * -Removed #ifdef DEBUG from around initial comment block.
+ *
+ * Revision 1.1  2004/11/17 12:38:48  r12110
+ * -Initial version checked into CVS.
+ * -Updated copyright from Motorola to Freescale.
+ *
+ *........................................................................*
+ * 0.1   J. Loeliger  17/Feb/03    Initial version of file.               *
+ * 0.2   J. Loeliger  06/Mar/03    Added DCC support.                     *
+ * 0.3   J. Loeliger  07/May/03    Change to fully use ISO data types.    *
+ * 0.4   J. Loeliger  17/Jun/03    Change name to motint.h and merge      *
+ *                                  MPC5500 and MAC7100 files.            *
+ * 0.5   J. Loeliger  04/Nov/03    Changed name to typedefs.h.            *
+ * 0.6   J. Loeliger  09/May/04    Changed to support GHS and GCC.        *
+ **************************************************************************/
+
+#ifndef _TYPEDEFS_H_
+#define _TYPEDEFS_H_
+
+#ifdef __MWERKS__    //Metrowerk CodeWarrior
+    #include <stdint.h>
+
+    // Standard typedefs used by header files, based on ISO C standard
+    typedef volatile int8_t vint8_t;
+    typedef volatile uint8_t vuint8_t;
+
+    typedef volatile int16_t vint16_t;
+    typedef volatile uint16_t vuint16_t;
+
+    typedef volatile int32_t vint32_t;
+    typedef volatile uint32_t vuint32_t;
+
+#else
+#ifdef __ghs__    //GreenHills
+    #include <stdint.h>
+
+    // Standard typedefs used by header files, based on ISO C standard
+    typedef volatile int8_t vint8_t;
+    typedef volatile uint8_t vuint8_t;
+
+    typedef volatile int16_t vint16_t;
+    typedef volatile uint16_t vuint16_t;
+
+    typedef volatile int32_t vint32_t;
+    typedef volatile uint32_t vuint32_t;
+
+#else
+
+    // This is needed for compilers that don't have a stdint.h file
+
+    typedef signed char int8_t;
+    typedef unsigned char uint8_t;
+    typedef volatile signed char vint8_t;
+    typedef volatile unsigned char vuint8_t;
+
+    typedef signed short int16_t;
+    typedef unsigned short uint16_t;
+    typedef volatile signed short vint16_t;
+    typedef volatile unsigned short vuint16_t;
+
+    typedef signed int int32_t;
+    typedef unsigned int uint32_t;
+    typedef volatile signed int vint32_t;
+    typedef volatile unsigned int vuint32_t;
+
+#endif
+#endif
+#endif
+
+/*********************************************************************
+ *
+ * Copyright:
+ *	Freescale Semiconductor, INC. All Rights Reserved.
+ *  You are hereby granted a copyright license to use, modify, and
+ *  distribute the SOFTWARE so long as this entire notice is
+ *  retained without alteration in any modified and/or redistributed
+ *  versions, and that such modified versions are clearly identified
+ *  as such. No licenses are granted by implication, estoppel or
+ *  otherwise under any patents or trademarks of Freescale
+ *  Semiconductor, Inc. This software is provided on an "AS IS"
+ *  basis and without warranty.
+ *
+ *  To the maximum extent permitted by applicable law, Freescale
+ *  Semiconductor DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
+ *  INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
+ *  PARTICULAR PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
+ *  REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
+ *  AND ANY ACCOMPANYING WRITTEN MATERIALS.
+ *
+ *  To the maximum extent permitted by applicable law, IN NO EVENT
+ *  SHALL Freescale Semiconductor BE LIABLE FOR ANY DAMAGES WHATSOEVER
+ *  (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+ *  BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER
+ *  PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
+ *
+ *  Freescale Semiconductor assumes no responsibility for the
+ *  maintenance and support of this software
+ *
+ ********************************************************************/
+
+

+ 27 - 0
BMS Master/Project_Headers/utils.h

@@ -0,0 +1,27 @@
+//==============================================================================
+// Purpose:     Allg. Makros und Defs.
+//
+// Created on:  04.05.2012 by IPE
+//
+// History
+//		04.05.2012 neu, T.Maurer
+//==============================================================================
+
+#ifndef __UTILS_H__
+#define __UTILS_H__
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+#define CHECKBIT(REG,BIT) 	REG & (1<<BIT) ? 1:0
+#define SETBIT(REG,BIT) 	REG |= (1<<BIT)
+#define CLEARBIT(REG,BIT) 	REG &= ~(1<<BIT)
+#define	TOGGLEBIT(REG,BIT) 	REG ^= (1<<BIT)		
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif  /* ifndef*/

+ 425 - 0
BMS Master/Project_Settings/Startup_Code/MPC5646C_HWInit.c

@@ -0,0 +1,425 @@
+
+/*
+ *
+ * FILE : MPC564xBC_HWInit.c
+ *
+ * DESCRIPTION:
+ *  This file contains all MPC564xBC derivative needed initializations, 
+ *  and all initializations for the MPC564xBC boards which are supported.
+ *  This includes setting up the External Bus Interface to allow access
+ *  to memory on the external bus, and ensuring there is a valid entry in
+ *  the MMU for the external memory access.
+ */
+
+/*----------------------------------------------------------------------------*/
+/* Includes                                                                   */
+/*----------------------------------------------------------------------------*/
+
+#include "MPC5646C.h"       /* MPC55xx platform development header            */
+#include "MPC5646C_HWInit.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************/
+/* MPC564xBC derivative specific hardware initialization */
+/*******************************************************/
+
+/*----------------------------------------------------------------------------*/
+/* Function declarations                                                      */
+/*----------------------------------------------------------------------------*/
+
+/* All these functions must be located in the initial 4KB memory window (.init) 
+	and implemented "nofralloc" so as to not use the stack */
+
+/* Memory initialization */
+__declspec(section ".init") __asm void INIT_Derivative(void);
+
+/* Write one MMU Table Entry */
+__declspec(section ".init") __asm void WriteMMUTableEntry( void );
+
+/* Initialize the needed MMU Table entries */
+__declspec(section ".init") __asm void __initMMU(void);
+
+/* Configures the SWT */
+__declspec(section ".init") __asm void cfg_WATCHDOG(void);
+
+/* Configures the platform flash register. */
+__declspec(section ".init") __asm void __FlashConfig(void);
+
+/* This macro allows to use C defined address with the inline assembler */
+#define MAKE_HLI_COMPATIBLE(hli_name, c_expr) enum { hli_name=/*lint -e30*/((int)(c_expr)) };
+
+
+/*----------------------------------------------------------------------------*/
+/* Function implementations                                                   */
+/*----------------------------------------------------------------------------*/
+
+/* Symbol L2SRAM_LOCATION is defined in the application linker command file (.lcf) 
+   It is defined to the start of the L2SRAM of the MPC564xBC. 
+*/
+/*lint -esym(752, L2SRAM_LOCATION) */
+extern long L2SRAM_LOCATION;  
+
+/* Symbol L2SRAM_CNT is defined in the application linker command file (.lcf)
+   It represents the how many writes with stmw,128 bytes each, are needed to cover
+   the whole L2SRAM.
+*/
+extern long L2SRAM_CNT;
+
+/**************************************************************************/
+/* FUNCTION     : cfg_WATCHDOG                                            */
+/* PURPOSE      : This function configures the WATCHDOG					  */
+/*                SEQUENCE:                                               */
+/*                - Disable watchdog, 								      */
+/**************************************************************************/
+MAKE_HLI_COMPATIBLE(SR_WSC_1, 50464)
+MAKE_HLI_COMPATIBLE(SR_WSC_2, 55592)
+MAKE_HLI_COMPATIBLE(CR_VALUE, 0x8000010A)
+
+/** Address of the SWT SR */
+MAKE_HLI_COMPATIBLE(SWT_SR, &SWT.SR.R)
+/** Address of the SWT CR */
+MAKE_HLI_COMPATIBLE(SWT_CR, &SWT.CR.R)
+
+__asm void cfg_WATCHDOG(void)
+{
+	nofralloc
+
+	/* Clear the soft lock bit SWT_CR.SLKSWT_CR: */
+	/* SR --> 0x0000c520 */
+    lis r4, 0
+    ori r4, r4, SR_WSC_1@l
+    lis r3, SWT_SR@ha
+    stw r4, SWT_SR@l(r3)
+    /* SR --> 0x0000d928 */
+    lis r4, 0
+    ori r4, r4, SR_WSC_2@l
+    stw r4, SWT_SR@l(r3)
+
+    /* Disable watchdog, SWT.CR.WEN = 0*/
+    lis r4, CR_VALUE@h
+    ori r4, r4, CR_VALUE@l
+    lis r3, SWT_CR@ha
+    stw r4, SWT_CR@l(r3)
+
+	blr
+}
+
+/** PFCR0 */
+MAKE_HLI_COMPATIBLE(PFCR0, &CFLASH_0.PFCR0.R)
+//bit 0 -> bit 31
+//B02_APC  = 0b00000, Accesses may be initiated on consecutive (back-to-back) cycles
+//B02_WWSC = 0b00001, Write: 1 additional wait-state is added
+//B02_RWSC = 0b00101, >100 MHz - 120 MHz, APC =RWSC=5 (default reset)
+//B02_RWWC[2:1] = 0b11, Generate a bus stall for a read while write/erase, disable the stall notification interrupt,disable the abort + abort notification interrupt (reset default)
+//B02_P1_BCFG = 0b11,The buffers are partitioned into two groups with buffers 0,1,2 allocated for instruction fetches and buffer 3 for data accesses.(reset default)
+//B02_P1_DPFE = 0b0 (reset default)
+//B02_P1_IPFE = 0b1 (reset default)
+//B02_P1_PFLM = 0b10 (reset default)
+//B02_P1_BFE  = 0b1 (reset default)
+//B02_RWWC0   = 0b1 (reset default)
+//B02_P0_BCFG = 0b11 (reset default)
+//B02_P0_DPFE = 0b0 (reset default)
+//B02_P0_IPFE = 0b1 (reset default)
+//B02_P0_PFLM = 0b10 (reset default)
+//B02_P0_BFE  = 0b1 (reset default)
+MAKE_HLI_COMPATIBLE(FLASH_DATA0, 0x4BEDED) 
+// reset value 0x294BEDED
+
+/** PFCR1 */
+MAKE_HLI_COMPATIBLE(PFCR1, &CFLASH_0.PFCR1.R)
+//bit 0 -> bit 31
+//B1_APC    = 0b00000 Accesses may be initiated on consecutive (back-to-back) cycles
+//B1_WWSC   = 0b00001 write: 1 additional wait-state is added
+//B1_RWSC   = 0b00101 >100 MHz - 120 MHz, APC =RWSC=5
+//B1_RWWC2:1= 0b11 Generate a bus stall for a read while write/erase, disable the stall notification interrupt,disable the abort + abort notification interrupt (reset default)
+//0b000000
+//B1_P1_BFE = 0b1 Bank1, Port 1 Buffer Enable (reset default)
+//B1_RWWC0  = 0b1 Generate a bus stall for a read while write/erase, disable the stall notification interrupt,disable the abort + abort notification interrupt (reset default)
+//0b000000
+//B1_P0_BFE = 0b1 Bank1, Port 0 Buffer Enable (reset default)
+MAKE_HLI_COMPATIBLE(FLASH_DATA1, 0x4B8181)
+// reset value 0x6b5b8181
+
+MAKE_HLI_COMPATIBLE(__FlashConfigInstrCount, 16)
+__asm void __FlashConfig(void) 
+{
+	nofralloc
+	/* configure code flash PFCR0 */
+	lis r4, PFCR0@h
+	ori r4, r4, PFCR0@l
+	lis r3, FLASH_DATA0@h
+	ori r3, r3, FLASH_DATA0@l
+	stw r3, 0(r4) /* stw r3,(0)r4 machine code: writes r3 contents to addr in r4 */
+	mbar 0 /* msync machine code: ensure prior store completed */
+
+	/* configure code flash PFCR1 */
+	lis r4, PFCR1@h
+	ori r4, r4, PFCR1@l
+	lis r3, FLASH_DATA1@h
+	ori r3, r3, FLASH_DATA1@l
+	stw r3, 0(r4) /* stw r3,(0)r4 machine code: writes r3 contents to addr in r4 */
+	mbar 0 /* mbar machine code: ensure prior store completed */
+	blr
+	nop
+	nop
+	nop
+}
+
+/**
+ * TLB_Entry_15: default page for running the initialization code, TS=1, 4GB, cache inhibited,
+ * not guarded, big endian.
+ */
+MAKE_HLI_COMPATIBLE(TLB_Entry_15_MAS0, MAS0_VALUE(15))
+MAKE_HLI_COMPATIBLE(TLB_Entry_15_MAS1, MAS1_VALUE(V_VALID, IPROT_NOTPROTECTED, TID_GLOBAL, TS_ON, TSIZE_4GB))
+MAKE_HLI_COMPATIBLE(TLB_Entry_15_MAS1_INVALID, MAS1_VALUE(V_INVALID, IPROT_NOTPROTECTED, TID_GLOBAL, TS_ON, TSIZE_4GB))
+#if __option(vle)
+MAKE_HLI_COMPATIBLE(TLB_Entry_15_MAS2, MAS2_VALUE(0, VLE_MODE, WRITE_BACK, CACHE_INHIBIT, MEM_COHERENCE_NREQ, NOT_GUARDED, BIG_ENDIAN))
+#else
+MAKE_HLI_COMPATIBLE(TLB_Entry_15_MAS2, MAS2_VALUE(0, BOOK_E_MODE, WRITE_BACK, CACHE_INHIBIT, MEM_COHERENCE_NREQ, NOT_GUARDED, BIG_ENDIAN))
+#endif
+MAKE_HLI_COMPATIBLE(TLB_Entry_15_MAS3, MAS3_VALUE(0, READ_WRITE_EXECUTE))
+
+__asm void INIT_Derivative(void) 
+{
+nofralloc
+
+	/* Create initialization memory space required in order to create
+	TLB entries for FLASH or RAM. */
+	lis r3, TLB_Entry_15_MAS0@h
+	ori r3, r3, TLB_Entry_15_MAS0@l
+	lis r4, TLB_Entry_15_MAS1@h
+	ori r4, r4, TLB_Entry_15_MAS1@l
+	xor r5, r5, r5
+	mr r6, r5
+	ori r5, r5, TLB_Entry_15_MAS2@l
+	ori r6, r6, TLB_Entry_15_MAS3@l
+
+    mtspr 624, r3
+    mtspr 625, r4
+    mtspr 626, r5
+    mtspr 627, r6
+    
+    /* prefetch instruction to this point. */
+    isync
+    tlbwe
+    /* make sure isntructions and data are fetched from the new context. */
+    msync
+    isync
+
+    /* force this TLB entry to be used for translation */
+    mfmsr r10
+    /* save state */
+    mr r3, r10
+    /* set IS=1, DS=1 */
+    ori r3, r3, 0x20
+    isync
+    /* mtmsr does execution synchronization.*/
+    mtmsr r3
+    /* Required after changing MSR.IS, and MSR.DS so the prefetched instructions
+     will be discarded and all subsequent instructions will use the TLB 15 context.
+     */
+    isync
+
+    /* create device specific MMU entries */
+   	mflr	r26
+   	bl __initMMU
+   	mtlr	r26
+   	
+	/* Disable the software watch dog. */
+	mflr	r26
+	bl cfg_WATCHDOG
+	mtlr	r26
+
+	/* MPC564xBC L2SRAM initialization code */
+#if defined(ROM_VERSION)
+    /* SRAM initialization code*/
+    lis r11,L2SRAM_LOCATION@h
+    ori r11,r11,L2SRAM_LOCATION@l
+
+    /* Loops to cover L2SRAM, stmw allows 128 bytes (32 GPRS x 4 bytes) writes */
+    lis r12,L2SRAM_CNT@h
+    ori r12,r12,L2SRAM_CNT@l
+    mtctr r12
+
+    init_l2sram_loop:
+        stmw r0, 0(r11)        /* Write 32 GPRs to SRAM*/
+        addi r11,r11,128      /* Inc the ram ptr; 32 GPRs * 4 bytes = 128B */
+        bdnz init_l2sram_loop /* Loop for 48k of SRAM */
+
+   	// init platform flash registers from RAM - please see reference manual
+    lis r3,__FlashConfig@h
+  	ori r3,r3,__FlashConfig@l
+
+  	lis r4, __FlashConfigInstrCount@h
+    ori r4, r4, __FlashConfigInstrCount@l
+    mtctr r4
+    lis r5, L2SRAM_LOCATION@h
+
+    mflr r26 /* save LR */
+    mtlr r5 /* set LR <- __FlashConfig*/
+
+    /* copy function code to RAM */
+    copy:
+    lwz r6, 0(r3)
+    stw r6, 0(r5)
+    addi r3, r3, 4
+    addi r5, r5, 4
+    bdnz copy /* decrement CTR */
+    blrl /* goto copyied __FlashConfig in RAM */
+    mtlr r26 /* restore LR */
+#endif
+    
+    /* restore msr */
+    mtmsr r10
+    /* execute all instructions and discard the prefetched instructions */
+    isync
+
+    /* invalidated initialization TLB entry 15 */
+	lis r3, TLB_Entry_15_MAS0@h
+	ori r3, r3, TLB_Entry_15_MAS0@l
+	lis r4, TLB_Entry_15_MAS1_INVALID@h
+	ori r4, r4, TLB_Entry_15_MAS1_INVALID@l
+	mtspr 624, r3
+    mtspr 625, r4
+    tlbwe
+    
+    /* make sure isntructions and data are fetched from the new context. */
+    isync
+    msync
+
+    blr
+}
+
+/* Initialize the needed MMU Table entries */
+
+/* FLASH: TLB entry 0, Base address = 0x0000_0000, 16 MB, protected, guarded, cache on, big-endian, all access */
+MAKE_HLI_COMPATIBLE(TLB_Entry_0_MAS0, MAS0_VALUE(0))
+MAKE_HLI_COMPATIBLE(TLB_Entry_0_MAS1, MAS1_VALUE(V_VALID, IPROT_PROTECTED, TID_GLOBAL, TS_OFF, TSIZE_16MB))
+#if __option(vle)
+MAKE_HLI_COMPATIBLE(TLB_Entry_0_MAS2, MAS2_VALUE(0, VLE_MODE, WRITE_BACK, CACHEABLE, MEM_COHERENCE_NREQ, GUARDED, BIG_ENDIAN))
+#else
+MAKE_HLI_COMPATIBLE(TLB_Entry_0_MAS2, MAS2_VALUE(0, BOOK_E_MODE, WRITE_BACK, CACHEABLE, MEM_COHERENCE_NREQ, GUARDED, BIG_ENDIAN))
+#endif
+MAKE_HLI_COMPATIBLE(TLB_Entry_0_MAS3, MAS3_VALUE(0, READ_WRITE_EXECUTE))
+
+/* SRAM: TLB entry 1, Base address = 0x4000_0000, 256K, not protected, not guarded, cache off, big-endian, all access */
+MAKE_HLI_COMPATIBLE(TLB_Entry_1_MAS0, MAS0_VALUE(1))
+MAKE_HLI_COMPATIBLE(TLB_Entry_1_MAS1, MAS1_VALUE(V_VALID, IPROT_NOTPROTECTED, TID_GLOBAL, TS_OFF, TSIZE_256KB))
+#if __option(vle)
+MAKE_HLI_COMPATIBLE(TLB_Entry_1_MAS2, MAS2_VALUE(0x40000, VLE_MODE, WRITE_BACK, CACHE_INHIBIT, MEM_COHERENCE_NREQ, NOT_GUARDED, BIG_ENDIAN))
+#else
+MAKE_HLI_COMPATIBLE(TLB_Entry_1_MAS2, MAS2_VALUE(0x40000, BOOK_E_MODE, WRITE_BACK, CACHE_INHIBIT, MEM_COHERENCE_NREQ, NOT_GUARDED, BIG_ENDIAN))
+#endif
+MAKE_HLI_COMPATIBLE(TLB_Entry_1_MAS3, MAS3_VALUE(0x40000, READ_WRITE_EXECUTE))
+
+/* Peripheral bridge 1: TLB entry 2 Base address = 0xC000_0000, 64M, not protected, not guarded, cache off, big-endian, all access */
+MAKE_HLI_COMPATIBLE(TLB_Entry_2_MAS0, MAS0_VALUE(2))
+MAKE_HLI_COMPATIBLE(TLB_Entry_2_MAS1, MAS1_VALUE(V_VALID, IPROT_NOTPROTECTED, TID_GLOBAL, TS_OFF, TSIZE_64MB))
+#if __option(vle)
+MAKE_HLI_COMPATIBLE(TLB_Entry_2_MAS2, MAS2_VALUE(0xC0000, VLE_MODE, WRITE_BACK, CACHE_INHIBIT, MEM_COHERENCE_NREQ, NOT_GUARDED, BIG_ENDIAN))
+#else
+MAKE_HLI_COMPATIBLE(TLB_Entry_2_MAS2, MAS2_VALUE(0xC0000, BOOK_E_MODE, WRITE_BACK, CACHE_INHIBIT, MEM_COHERENCE_NREQ, NOT_GUARDED, BIG_ENDIAN))
+#endif
+MAKE_HLI_COMPATIBLE(TLB_Entry_2_MAS3, MAS3_VALUE(0xC0000, READ_WRITE_EXECUTE))
+
+/* Peripheral bridge 0 + BAM: TLB entry 3 Base address = 0xFFE0_0000, 2M, not protected, not guarded, cache off, big-endian, all access */
+MAKE_HLI_COMPATIBLE(TLB_Entry_3_MAS0, MAS0_VALUE(3))
+MAKE_HLI_COMPATIBLE(TLB_Entry_3_MAS1, MAS1_VALUE(V_VALID, IPROT_NOTPROTECTED, TID_GLOBAL, TS_OFF, TSIZE_2MB))
+#if __option(vle)
+MAKE_HLI_COMPATIBLE(TLB_Entry_3_MAS2, MAS2_VALUE(0xFFE00, VLE_MODE, WRITE_BACK, CACHE_INHIBIT, MEM_COHERENCE_NREQ, NOT_GUARDED, BIG_ENDIAN))
+#else
+MAKE_HLI_COMPATIBLE(TLB_Entry_3_MAS2, MAS2_VALUE(0xFFE00, BOOK_E_MODE, WRITE_BACK, CACHE_INHIBIT, MEM_COHERENCE_NREQ, NOT_GUARDED, BIG_ENDIAN))
+#endif
+MAKE_HLI_COMPATIBLE(TLB_Entry_3_MAS3, MAS3_VALUE(0xFFE00, READ_WRITE_EXECUTE))
+
+__asm void __initMMU(void)
+{
+nofralloc
+
+     mflr     r27
+
+     /* Configure FLASH page on TLB entry 0 */
+     lis r3, TLB_Entry_0_MAS0@h
+     ori r3, r3, TLB_Entry_0_MAS0@l
+     lis r4, TLB_Entry_0_MAS1@h
+     ori r4, r4, TLB_Entry_0_MAS1@l
+     lis r5, TLB_Entry_0_MAS2@h
+     ori r5, r5, TLB_Entry_0_MAS2@l
+     lis r6, TLB_Entry_0_MAS3@h
+     ori r6, r6, TLB_Entry_0_MAS3@l
+     bl WriteMMUTableEntry
+
+     /* Configure RAM page on TLB entry 1 */
+     lis r3, TLB_Entry_1_MAS0@h
+     ori r3, r3, TLB_Entry_1_MAS0@l
+     lis r4, TLB_Entry_1_MAS1@h
+     ori r4, r4, TLB_Entry_1_MAS1@l
+     lis r5, TLB_Entry_1_MAS2@h
+     ori r5, r5, TLB_Entry_1_MAS2@l
+     lis r6, TLB_Entry_1_MAS3@h
+     ori r6, r6, TLB_Entry_1_MAS3@l
+     bl WriteMMUTableEntry 
+
+     /* Peripheral bridge 0 on TLB entry 2 */
+     lis r3, TLB_Entry_2_MAS0@h
+     ori r3, r3, TLB_Entry_2_MAS0@l
+     lis r4, TLB_Entry_2_MAS1@h
+     ori r4, r4, TLB_Entry_2_MAS1@l
+     lis r5, TLB_Entry_2_MAS2@h
+     ori r5, r5, TLB_Entry_2_MAS2@l
+     lis r6, TLB_Entry_2_MAS3@h
+     ori r6, r6, TLB_Entry_2_MAS3@l
+     bl WriteMMUTableEntry
+
+     /* Peripheral bridge 0 on TLB entry 3 */
+     lis r3, TLB_Entry_3_MAS0@h
+     ori r3, r3, TLB_Entry_3_MAS0@l
+     lis r4, TLB_Entry_3_MAS1@h
+     ori r4, r4, TLB_Entry_3_MAS1@l
+     lis r5, TLB_Entry_3_MAS2@h
+     ori r5, r5, TLB_Entry_3_MAS2@l
+     lis r6, TLB_Entry_3_MAS3@h
+     ori r6, r6, TLB_Entry_3_MAS3@l
+     bl WriteMMUTableEntry
+
+     mtlr r27
+
+     blr
+}
+
+/* Write one MMU Table Entry:               */
+/* r3, r4, r5 and r6 must hold              */
+/* the values of MAS0, MAS1, MAS2 and MAS3  */
+__asm void WriteMMUTableEntry( void )
+{ 
+nofralloc
+
+    /* Write MMU Assist Register 0 (MAS0); SPR 624 */
+    mtspr   624, r3
+    /* Write MMU Assist Register 1 (MAS1); SPR 625 */
+    mtspr   625, r4
+    /* Write MMU Assist Register 2 (MAS2); SPR 626 */
+    mtspr   626, r5
+    /* Write MMU Assist Register 3 (MAS3); SPR 627 */
+    mtspr   627, r6
+    /* Write the table entry */
+
+    /* All instruction will complete here in current context. */
+    //isync
+
+    tlbwe
+
+    /* synchronize instruction fetches and data accesses in respect
+     with the new created TLB entry. */
+    msync
+    isync
+
+    blr
+}
+
+#ifdef __cplusplus
+}
+#endif

+ 19 - 0
BMS Master/Project_Settings/Startup_Code/MPC5646C_Startup.c

@@ -0,0 +1,19 @@
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+__declspec(section ".init") extern void __startup(int argc, char **argv, char **envp);				/* primary entry point */
+extern asm void __start(register int argc, register char **argv, register char **envp);
+
+#ifdef __cplusplus
+}
+#endif
+
+asm void __startup(register int argc, register char **argv, register char **envp)
+{
+	nofralloc /* explicitly no stack */
+
+	// call standard application initialization
+	bl __start
+}

+ 106 - 0
BMS Master/Project_Settings/Startup_Code/MPC5646C_init_flash.c

@@ -0,0 +1,106 @@
+
+/*
+ *
+ * FILE : MPC55xx_init.c
+ *
+ * DESCRIPTION:
+ *  This file contains the MPC55xx derivative needed initializations. 
+ *  usr_init() is called by the startup code of the application at initialization time
+ *  You can add needed hardware initializations here.
+ *  This file also contains the RCHW and Reset Vector setup:
+/*  The chip is by default setup to boot from internal Flash and the watchdog is disabled.
+ */
+
+#include "Exceptions.h"     /* IVPR and default exception handlers setup */
+#include "IntcInterrupts.h" /* INTC Interrupts Requests configuration */
+#include "MPC5646C_HWInit.h"
+
+#pragma section code_type ".init"
+
+#define INIT_DERIVATIVE_INTERNAL_SETUP 1
+#define INIT_EXTERNAL_BUS_INTERFACE_SETUP 0
+
+#ifndef INIT_DERIVATIVE_INTERNAL_SETUP
+#pragma error INIT_DERIVATIVE_INTERNAL_SETUP should be defined !
+#endif
+
+#ifndef INIT_EXTERNAL_BUS_INTERFACE_SETUP
+#pragma error INIT_EXTERNAL_BUS_INTERFACE_SETUP should be defined !
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern __asm void __startup();
+__asm void usr_init();
+/*lint -esym(752,__start) */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*****************************************************************/
+/* usr_init():                                                   */
+/*   Define here the needed hardware initializations at startup  */
+
+__asm void usr_init()
+{
+    /* Add needed hardware initializations in this function */
+    nofralloc
+
+    mflr     r30                         /* Save off return address in NV reg */
+
+#if INIT_DERIVATIVE_INTERNAL_SETUP==1
+    bl      INIT_Derivative              /* Derivative specific hardware initializations */
+#endif
+#if INIT_EXTERNAL_BUS_INTERFACE_SETUP==1
+    bl      INIT_ExternalBusAndMemory    /* Set up access to external memory (inc. chip select and MMU) */
+#endif
+    bl      EXCEP_InitExceptionHandlers   /* Set up Default Exception handling */
+    bl      INTC_InitINTCInterrupts       /* Set up INTC Interrupts Requests handling */
+
+    mtlr    r30                          /* Get saved return address */
+
+    blr
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**************************************************************/
+/* RCHW and Reset Vector setup:                               */
+/*   The chip is by default setup to boot from internal Flash */
+/*   and the watchdog is disabled.                            */ 
+
+typedef void (*resetfuncptr)(void);
+
+#pragma push /* Save the current state */
+#pragma section sconst_type ".__bam_bootarea"
+extern const unsigned long bam_rchw;
+extern const resetfuncptr bam_resetvector;
+
+/* RCHW_VALUE Flags */
+#define RCHW_WTE 0x0400L        /* Enable Watchdog */
+#define RCHW_VLE 0x0100L        /* Enable Variable Length Encoding*/
+#define RCHW_PS0_32BITS 0x0000L /* Boot from External Bus CS0, 32-bit CS0 port size. */
+#define RCHW_PS0_16BITS 0x0200L /* Boot from External Bus CS0, 16-bit CS0 port size. */
+#define RCHW_BOOTIDENTIFIER 0x005AL
+
+/* Used RCHW value: boot from internal flash, watchdog disabled */
+#if VLE_IS_ON == 1
+#define RCHW_VALUE RCHW_BOOTIDENTIFIER|RCHW_PS0_32BITS|RCHW_VLE
+#else
+#define RCHW_VALUE RCHW_BOOTIDENTIFIER|RCHW_PS0_32BITS 
+#endif
+
+const unsigned long bam_rchw = (RCHW_VALUE)<<16;
+const resetfuncptr bam_resetvector = __startup;
+
+#pragma pop
+
+#ifdef __cplusplus
+}
+#endif
+

+ 70 - 0
BMS Master/Project_Settings/Startup_Code/MPC5646C_init_ram.c

@@ -0,0 +1,70 @@
+
+/*
+ *
+ * FILE : MPC55xx_init_debug.c
+ *
+ * DESCRIPTION:
+ *  This file contains the MPC55xx derivative needed initializations. 
+ *  MPC55xx_init_debug.c is only used when willing to debug in RAM. Otherwise, 
+ *  MPC55xx_init.c shall be used.
+ *  usr_init() is called by the startup code of the application at initialization time
+ *  You can add needed hardware initializations here.
+ */
+
+#include "Exceptions.h"     /* IVPR and default exception handlers setup */
+#include "IntcInterrupts.h" /* INTC Interrupts Requests configuration */
+#include "MPC5646C_HWInit.h"
+
+#pragma section code_type ".init"
+
+#define INIT_DERIVATIVE_INTERNAL_SETUP 0
+#define INIT_EXTERNAL_BUS_INTERFACE_SETUP 0
+
+#ifndef INIT_DERIVATIVE_INTERNAL_SETUP
+#pragma error INIT_DERIVATIVE_INTERNAL_SETUP should be defined !
+#endif
+
+#ifndef INIT_EXTERNAL_BUS_INTERFACE_SETUP
+#pragma error INIT_EXTERNAL_BUS_INTERFACE_SETUP should be defined !
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern __asm void __start();
+__asm void usr_init();
+/*lint -esym(752,__start) */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*****************************************************************/
+/* usr_init():                                                   */
+/*   Define here the needed hardware initializations at startup  */
+
+__asm void usr_init()
+{
+    /* Add needed hardware initializations in this function */
+
+    nofralloc
+
+    mflr     r30                         /* Save off return address in NV reg */
+
+#if INIT_DERIVATIVE_INTERNAL_SETUP==1
+    bl      INIT_Derivative              /* Derivative specific hardware initializations */
+#endif
+#if INIT_EXTERNAL_BUS_INTERFACE_SETUP==1
+    bl      INIT_ExternalBusAndMemory    /* Set up access to external memory (inc. chip select and MMU) */
+#endif
+    bl      EXCEP_InitExceptionHandlers   /* Set up Default Exception handling */
+    bl      INTC_InitINTCInterrupts       /* Set up INTC Interrupts Requests handling */
+
+    mtlr    r30                          /* Get saved return address */
+    
+    blr
+}
+
+
+

+ 864 - 0
BMS Master/Project_Settings/Startup_Code/__ppc_eabi_init.c

@@ -0,0 +1,864 @@
+/***************************************************************************/
+/*
+
+FILE
+	__ppc_eabi_init.c
+	$Date: 2012/11/02 13:29:27 $
+	$Revision: 1.3 $
+	
+DESCRIPTION
+
+	Use this file for C or C++.  Contains calls to initialize memory pools
+	for use with malloc/free, exceptions and static initializers.  If your
+	project does not use exceptions, then the initialization code for them 
+	is stripped out.  If they are used, the linker will add them 
+	automatically.  A C-only program will be a little smaller (160 bytes) 
+	with __ppc_eabi_init.c.
+
+	Interface for board-level initialization and user-level initialization.
+	
+	If hardware initialization and pre-main user initialization are required,
+	copy this file to your project directory and customize it (instead of
+	customizing __start.c).
+	
+	Note that __init_hardware should not write on the stack until the
+	memory controller is properly configured.
+
+	
+	void __init_hardware(void)
+	
+		Initialize the hardware, including the memory controller.
+	
+	void __init_user(void)
+	
+		Allow the user to perform initialization before calling main().
+	
+	void __init_cpp(void)
+	
+		CodeWarrior C++ initialization before calling main().  Calls
+		constructors of which the cpp exception handling initialization
+		is the first constructor, if exceptions are used.
+	
+	void __fini_cpp(void)
+	
+		Calls destructors.
+	
+	void _ExitProcess(void)
+ 		
+ 		This function simply stalls the debugger.  You may want to rewrite this
+ 		function if you are using an OS.
+	
+ 	abort and exit
+ 
+ 	In order to correctly implement the required startup/termination sequence for
+ 	C and C++ programs, we need to have an exit() routine that can be called by
+ 	the program startup code. The exit() routine is supposed to
+ 
+ 		(1)	call any functions registered via atexit()
+ 		(2) call destructors for any global objects
+ 		(3)	flush any unwritten buffers, close any open files, etc.
+ 		(4) terminates the program
+ 
+ 	We don't, however, want to require the ANSI C library for every CodeWarrior
+ 	program, since it drags in lots of code that may not be needed.
+ 
+ 	Instead we provide a dummy exit() function which simply calls the destructors
+ 	and terminates the program. We assume that any program which uses atexit()
+ 	or <stdio.h> and which requires those cleanup behaviors will have linked with
+ 	the ANSI C library, whose definition of exit() will override the one here.
+ 
+ 	We similarly define a dummy abort() function (which is called by the default
+ 	terminate() handler).
+ 
+ 	Programs which rely on the proper ANSI C/C++ behavior must use the ANSI C
+ 	library, and order it in the CodeWarrior project or command-line so that
+ 	its definitions supersede these definitions in the runtime support library.
+
+COPYRIGHT	
+	(c) 2002-2006 Freescale Semiconductor, Inc.
+	All rights reserved.
+
+HISTORY
+	97 APR 17 LLY	Created.
+	97 JUN 24 MEA	Added support for C++ and malloc memory heaps.
+	97 JUN 26 MEA	Made C and C++ versions of this file.  Added abort and exit.
+	97 JUL 17 SCM	Customized for MPC821 ADS board.
+	97 JUL 20 MEA	Changed __exit to _ExitProcess so as not to conflict with EWL.
+					_ExitProcess added to this file; removed form __start.c.
+	99 JAN 22 MEA	Removed exception handing to __init_cpp_exceptions.c for use
+					with 2.2.2 compiler (post Release 4).  Put prototypes for
+					exit and abort within extern "C" to avoid name-mangling.
+        2012 NOV 02 CH  Add __SPE__ macro
+
+*/
+/***************************************************************************/
+
+#pragma exceptions off
+#pragma ANSI_strict off
+#pragma only_std_keywords off
+
+#define ALLOC_ADDITIONAL_HEAPS 0
+#include "MPC5646C.h"
+
+
+
+
+
+
+#include <__ppc_eabi_init.h>
+#include <__ppc_eabi_linker.h>		/* linker-generated symbol declarations */
+#if ALLOC_ADDITIONAL_HEAPS
+#include <pool_alloc.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static void __init_cpp(void);
+static void __fini_cpp(void);
+typedef void (*voidfunctionptr) (void);	/* ptr to function returning void */
+__declspec(section ".init") extern voidfunctionptr _ctors[];
+__declspec(section ".init") extern voidfunctionptr _dtors[];
+__declspec(weak) extern void abort(void);
+__declspec(weak) extern void exit(int status);
+extern void usr_init();
+__declspec(section ".init") static int __get_runtime_linktime_delta(void);
+__declspec(section ".init") static int __get_linktime_address(void);
+__declspec(section ".init") static void __mwerks_fixup_relocations(void);
+void FlashConfig(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/***************************************************************************/
+/*
+ *	__init_hardware
+ *
+ *	Initialize the processor and board.
+ *
+ *	Note: this function must not access memory until the memory controller
+ *	is initialized.  Using "fralloc" (frame allocate) or writing this
+ *	function in C will cause this routine to break because writing into
+ *	stack memory is not valid until after usr_init returns.
+ */
+/***************************************************************************/
+
+asm void __init_hardware(void)
+{
+	/*
+	 *	Initialize board unless running with MWDebug.
+	 *	Uncomment the initialization below if running standalone. 
+	 *	You may need to perform other initializations.
+	 */
+	nofralloc
+
+   /*
+	* If we are using Hardware  floating point we need to make sure
+ 	* to enable the FP bit in the  MSR
+ 	*/	
+
+#if __option(floatingpoint)==1 &&  __option(sfp_emulation)==0
+ 	mfmsr r3
+ 	ori  r3,r3,0x00002000
+ 	mtmsr r3
+#endif
+
+   /*
+	* If we have selected Altivec Programming Model we need to make sure
+ 	* to enable the Altivec bit in the  MSR
+ 	*/	
+
+#if __VEC__
+ 	mfmsr r3
+	oris r3,r3,0x0200
+ 	mtmsr r3
+#endif	
+
+   /*
+	* Enable the MSR[SPE] bit for e500/Zen
+ 	*/	
+
+#if (defined (__PPCZen__) && defined(__SPE__)) || defined(__PPCe500__) || defined(__PPCe500v2__)
+	mfmsr r3
+	oris   r3,r3,0x0200
+	mtmsr r3
+#endif
+
+	/*
+	 *	When customizing, be aware that the memory controller may not be
+	 *	configured.
+	 */
+
+#if defined(ROM_VERSION) || defined(CACHE_VERSION) || defined(CALL_USR_INIT)
+	mflr	r31						/* save off return address in NV reg */
+	bl		usr_init				/* init board hardware */
+	mtlr	r31						/* get saved return address */
+#endif
+
+	blr
+}
+
+#if ALLOC_ADDITIONAL_HEAPS
+static void AllocMoreHeaps(void)
+{
+	/*
+	 *	By default, we EWL's allocation (malloc/free) even with C++.
+	 *	If you have declared a heap size in the Project Pref panel,
+	 *	a defaull heap will be created the first time you call
+	 *	malloc.  You can add more calls to init_alloc to create additional
+	 *	heaps.
+	 */
+	init_alloc(some_address1, some_size1);
+	init_alloc(some_address2, some_size2);
+}
+#endif
+void FlashConfig(void) 
+{
+		unsigned int mem_write_code [] = {
+
+		#if __option(vle)
+			/*for processors which support VLE only or for 'VLE on' option*/
+    		0xD0344400, /* stw r3,(0)r4 machine code: writes r3 contents to addr in r4 then se_nop*/
+    		0x7C0006AC, /* mbar machine code: ensure prior store completed */
+    		0x44000004  /* blr machine code: branches to return address in link register */
+		#else
+   			0x90640000, /* stw r3,(0)r4 machine code: writes r3 contents to addr in r4 */
+   			0x7C0006AC, /* mbar machine code: ensure prior store completed */
+   			0x4E800020  /* blr machine code: branches to return address in link register */
+		#endif // __option(vle)
+
+			};
+	
+
+typedef void (*mem_write_code_ptr_t)(unsigned int, unsigned int);
+
+  #if defined(FLASH_REG) 
+  (*((mem_write_code_ptr_t)mem_write_code)) 	/* cast mem_write_code as func ptr*/
+                                 /* * de-references func ptr, i.e. converts to func*/
+     (FLASH_DATA,            /* which passes integer (in r3) */
+      (unsigned int)&FLASH_REG);
+  #endif      
+      
+  #if defined(FLASH_REG2)
+  	(*((mem_write_code_ptr_t)mem_write_code)) 	/* cast mem_write_code as func ptr*/
+                                 /* * de-references func ptr, i.e. converts to func*/
+     (FLASH_DATA2,            /* which passes integer (in r3) */
+      (unsigned int)&FLASH_REG2);
+  #endif 
+ 
+}
+
+asm void __init_user(void)
+{
+	fralloc
+	/*
+	 *	Allocate additional heaps.
+	 */
+#if ALLOC_ADDITIONAL_HEAPS
+	bl		AllocMoreHeaps
+#endif
+
+	/*
+	 *	initialization of static initializers
+	 */
+#if (defined(__cplusplus) || defined(__VEC__) || defined(__SPE__)) && !defined(DO_NOT_LOAD_CTORS_DTORS)
+	bl		__init_cpp
+#endif
+	bl FlashConfig
+	/*
+	 *	Add your initializations here.
+	 */
+	frfree
+	blr
+}
+
+#if defined(__cplusplus) || defined(__VEC__) || defined(__SPE__)
+static void __init_cpp(void)
+{
+	voidfunctionptr *constructor;
+
+	/*
+	 *	call static initializers
+	 */
+	for (constructor = _ctors; *constructor; constructor++) {
+		(*constructor)();
+	}
+}
+
+static void __fini_cpp(void)
+{
+	voidfunctionptr *destructor;
+
+	/*
+	 *	call destructors
+	 */
+	for (destructor = _dtors; *destructor; destructor++) {
+		(*destructor)();
+	}
+}
+#endif
+
+extern void abort(void)
+{
+	_ExitProcess();
+}
+
+extern void exit(int status)
+{
+	#pragma unused(status)
+
+#if (defined(__cplusplus) || defined(__VEC__)) && !defined(DO_NOT_LOAD_CTORS_DTORS)
+	__fini_cpp();
+#endif
+	_ExitProcess();
+}
+
+
+/*
+ *	_ExitProcess
+ *
+ *	PowerPC EABI Runtime termination
+ */
+asm void _ExitProcess(void)
+{
+	nofralloc
+
+#if VLE_ON
+	/* the inline assembler can not translate this instruction */
+	se_illegal							/* arbitrary break trap for halt */
+#else
+	opword 0x00454E44					/* arbitrary break trap for halt */
+#endif
+}
+
+/****************************************************************************/
+/*
+ *	__flush_cache
+ *
+ *	For the given memory range, forces all modified data cache contents to be 
+ *	written to memory and invalidates the associated instruction cache
+ *	entries.
+ *	
+ */
+/****************************************************************************/
+asm void __flush_cache(register void *address, register unsigned int size)
+{
+#pragma unused (address, size)
+	/* r3 is address, r4 is size */
+	nofralloc
+
+#if !defined( __PPC555__ ) && !defined( __PPC56X__ )
+#if VLE_ON
+	/* the inline assembler can not translate 2 instructions into 1 */
+	e_li    r5,0xFFFFFFF1
+#else
+	lis		r5, 0xffff
+	ori		r5, r5, 0xfff1
+#endif
+	and		r5, r5, r3				/* make address 8-byte aligned		*/
+	subf	r3, r5, r3				/* get unaligned-aligned difference	*/
+	add		r4, r4, r3				/* increase size accordingly		*/
+
+rept:
+/*
+** Note: If no data cache, then just invalidate the instruction
+** cache entry.
+**
+** The MPC 5xx processors do not have data cache.
+*/
+#if !defined( __PPC505__ ) && !defined( __PPC509__ )
+
+#if !defined(__PPCGENERIC__)
+	dcbst	0,r5
+#endif
+
+#endif
+
+#if defined(__PPCZen__) || defined(__PPCe500__) || defined(__PPCe500v2__)
+#if VLE_ON
+	se_isync
+#else
+	msync
+#endif
+#else
+	sync
+#endif
+
+	
+#if !defined(__PPCGENERIC__)
+	icbi	0,r5
+#endif
+
+	addic	r5,r5,0x8
+	subic.	r4,r4,0x8
+	bge		rept
+	isync
+#endif
+	blr
+}
+
+#if __option(sda_pic_pid)
+/* The following functions are used with SDA PIC/PID support.  						*/
+/* __init_registers and __init_data will overload weak versions found in __start.c	*/
+
+/***************************************************************************
+*** Requirements for SDA PIC/PID ***
+
+The basic requirement for SDA PIC/PID is that the startup code (.init) and
+the segments .sdata and .sdata2 all maintain their link time address 
+relationship at runtime.  In other words if the link time addresses are:
+.init = 0x00002000
+.sdata2 = 0x00003000
+.sdata = 0x00004000
+but that .init somehow is executed at 0x00002500, then those link time 
+addresses must all increment by 0x00000500 for their runtime addresses.  
+Any segment that does not maintain the address relationship at runtime is 
+considered external and must be addressed with absolute addresses.  
+Segments that do maintain their link time address relationship at runtime 
+are considered internal and must be addressed with pc and sda relative 
+addressing.  More on external and internal segments, below.
+
+Having .init, .sdata2 and .sdata, as well as other internal segments, end
+up at runtime without the link time relationship is not detected in this
+runtime but it is at least technically possible for someone to modify the
+runtime to support this, at least for a specific application.
+
+*** Internal and External segments and references ***
+
+At link time, the linker determines whether code and data segments are 
+external or internal.  Internal segments reference their data as far or 
+near offsets of the small data registers r2 and r13.  Their code 
+references are normally pc relative, but if far code references are 
+required, they also use offsets of the small data registers.  Internal
+segments can also reference code and data in other internal segments
+with the same addressing that they would use for their own code ad data.
+By default, all segments in your application are considered internal with 
+one exception listed below.
+
+External segments are segments that are at absolute addresses.  
+Segments with a name like .abs.xxxxxxxx, where xxxxxxxx is a hex address
+are considered external.  External segments reference their data with 
+absolute addressing and code references within the segment can be pc 
+relative or absolute.  Any other segment must use absolute references 
+to reference code or data in external segments.  External segments must 
+reference an internal segment with small data registers for code and data.
+
+Akin to external segments are external symbol references.  These are 
+symbols, usually linker generated symbols, that are determined to be not 
+within any segment in your application.  They will be referenced with
+absolute addressing.  All symbols in an external segment are considered
+to be external symbol references.
+
+The ldf has 2 mechanisms for you to override the linker's defaults:
+1.  The MEMORY directive now supports 
+addr_mode = external | internal // default is internal
+addr_mode is ignored unless you have chosen the SDA PIC/PID ABI in the EPPC 
+Target Pref panel.
+
+2. New directives INTERNAL_SYMBOL and EXTERNAL_SYMBOL can be used to force
+the addressing of global symbols.  These directives are of the 
+form XXXL_SYMBOL { sym1, sym2, symN } where the symbols are the link time
+symbol names (mangled for c++).
+
+The auto-generated linker defined start and end symbols for loadable 
+segments are internal if they are addresses into internal segments and 
+external if they are for external segments.  All other linker defined 
+symbols you create in a lcf are considered external unless you redefine
+them with INTERNAL_SYMBOL.  The linker also defines some linker defined 
+symbols for its own use and they have the following default settings:
+
+_stack_addr [top of the stack - comes from pref panel settings] external
+_stack_end [bottom of the stack - comes from pref panel settings] external
+_heap_addr [bottom of the heap - comes from pref panel settings] external
+_heap_end [top of the heap - comes from pref panel settings] external
+// the next two need to be treated as internal to be EABI compliant so
+// you may not redefine them.
+_SDA_BASE_ [.sdata + 0x00008000] internal
+_SDA2_BASE_ [.sdata2 + 0x00008000] internal
+// The previous small data pointers rely on the small data registers being
+// properly initialized before being accessible.  However, it is hard to
+// initialize those pointers without accessing them as absolutes.
+// The following two symbols are external versions of _SDA_BASE_ and
+// _SDA2_BASE_ which can be used as absolutes.  You may not redefine them.
+_ABS_SDA_BASE_ [.sdata + 0x00008000] external
+_ABS_SDA2_BASE_ [.sdata2 + 0x00008000] external
+// the following are numbers, not addresses and they must be treated
+// as external.  You may not redefine them.
+_nbfunctions [number of functions in program - deprecated] external
+SIZEOF_HEADERS [size of the segment headers in a linux app] external
+
+Especially note that the stack and heap linker generated symbols are
+external.  It may be more practical in a SDA PIC/PID application to
+make the heap and stack be contiguous with an internal segment and
+define them as internal.
+
+*** Uses for SDA PIC/PID ***
+
+The runtime was developed for 3 different situations:
+
+1. All code and data segments are internal.  The simplest case would be
+for all segments to use the same MEMORY directive and to have all of the 
+bss type segments at the end.  In such a simple case, the application could
+be converted to a binary file and linked into another application which
+could copy it to ram and jump to its entry point.
+
+2. All of the essential segments are internal and therefore moveable but 
+there may be some external segments which are absolute.  This situation is 
+probably difficult to test but you can download the entire application
+to the chip and at least debug it at its link time addresses.
+
+3. Like 2, there are internal and external segments but the application is 
+linked as a ROM image - the application does not need to be flashed to
+ROM, however.  It is possible to change the ROM Image Address to be an
+address into RAM and have the debugger download the image to the RAM 
+address.  Alternatively, you could have the ROM image converted to a bin
+file and link it into another application as in 1, above.  The structures 
+used in __init_data(), _rom_copy_info and __bss_init_info, have been 
+modified for SDA PIC/PID to have an extra field which tells the runtime 
+where the segment is internal or external so that the internal segments 
+will be copied to position relative addresses and the external segments 
+will be copied to absolute addresses.
+
+*** Compiler/Linker support for SDA Addressing ***
+You build a SDA PIC/PID application by selecting SDA PIC/PID in the ABI
+popup in the EPPC Target Preference panel.  When you chose that, the 
+compiler will define a simple that you can use to guard PIC/PID source.
+
+#if __option(sda_pic_pid) // is true if you have chosen SDA PIC/PID ABI
+
+If you then link, the linker will generate a table for the runtime files
+__ppc_eabi_init.cpp/__ppc_eabi_init.c to use.  If your application has
+absolute addressing relocations (which it would by default) you will
+probably get linker warnings telling you that those relocations may
+cause a problem.  If that happens, you have two choices.  You can change
+the Code Model popup in the EPPC Target Preference panel to be
+SDA Based PIC/PID Addressing for all of your sources and libraries, and/or
+check the Tune Relocations checkbox in the EPPC Target Preference panel.
+This new option is only available for the EABI and SDA PIC/PID ABIs.  For
+EABI it changes 14 bit branch relocations to 24 bit branch relocations
+only if they can not reach the calling site from the original relocation.
+For SDA PIC/PID, it changes absolute addressed references of data from
+code to use a small data register instead of r0 and changes absolute
+code to code refernces to use the pc relative relocations.  In general,
+this will work well for normnal compiled code.  It is always possible
+to link in an assembly file that does not behave in a standard way.
+
+Whether you use the Code Model SDA Based PIC/PID Addressing or not,
+#pragma section has been modified to accept far_sda_rel for the data_mode
+and code_mode options.  If you leave those options out, the compiler
+will you the Code Model to determine the appropriate modes.
+
+Absolute Addressing defaults to data_mode = far_abs and code_mode = pc_rel.
+SDA Based PIC/PID Addressing defaults to data_mode = far_sda_rel and
+code_mode = pc_rel.
+
+***************************************************************************/
+
+/***************************************************************************/
+/*
+ *	__get_runtime_linktime_delta
+ *
+ *	Assumes that r13 and r2 are initialized correctly and that they always
+ *	stay in the same relationship to each other.
+ *
+ *	Utility function to get difference between runtime and linktime addresses.
+ *
+ */
+/***************************************************************************/
+static asm int __get_runtime_linktime_delta(void)
+{
+	nofralloc
+    /* _ABS_SDA_BASE_, generated by the linker, is the same value as 		 	*/
+	/* _SDA_BASE_ but forces the linker to treat it as absolutetly addressed 	*/
+	/* and not to substitute r13 for r0.  We therefore end up with r3 exactly 	*/
+	/* as calculated at linktime. 												*/
+	addis	r3, r0, _ABS_SDA_BASE_@ha
+	addi	r3, r3, _ABS_SDA_BASE_@l
+   	/* Subtract the runtime from the linktime address.							*/
+   	sub		r3,r13,r3
+	blr
+}
+
+/***************************************************************************/
+/*
+ *	__mwerks_fixup_relocations
+ *
+ *	Modify initialized pointers in the data sections to reflect correct
+ *	runtime addresses.  The linker created a table, _f_mwerks_fixup, of 
+ *	offsets into the data sections that need modification.  This function
+ *	loads the pointer at that offset and applies the runtime/linktime
+ *	delta.  We wait to call this function until after __init_data.
+ *
+ */
+/***************************************************************************/
+static asm void __mwerks_fixup_relocations(void)
+{
+	nofralloc
+	
+	/* r13, r2, and r1 have their correct runtime values.						*/
+
+    mflr    r0
+
+   	/* If runtime and linktime addresses are the same, no fixup is necessary.	*/
+   	bl		__get_runtime_linktime_delta
+    cmpli   cr0,r3,0
+    beq     no_fixup
+
+	/* Initialize runtime addresses of the fixup table.  _f_mwerks_fixup is the	*/
+	/* beginning of the table and _e_mwerks_fixup is the end.  Note that r0 	*/
+	/* will get converted to r13 or r2 by the linker. 							*/
+    addis   r5,r0,_f_mwerks_fixup@ha
+    addis   r4,r0,_e_mwerks_fixup@ha
+    addi    r5,r5,_f_mwerks_fixup@l
+    addi    r4,r4,_e_mwerks_fixup@l
+
+    /* Compute number of entries ((_e_mwerks_fixup - _f_mwerks_fixup) / 4).		*/
+    subf    r6,r5,r4			
+    /* If there are no entries, bail.											*/
+    cmpli   cr0,r6,0
+    beq     no_fixup
+    srwi    r6,r6,2
+    mtctr   r6
+	/* We use pre-increment, so move to first real entry - 4.					*/
+    subi    r5,r5,4
+fixup_loop:
+	/* Load address of relocation.												*/
+    lwzu    r6,4(r5)
+    /* Update address using SDA delta.											*/
+    add     r6,r6,r3
+    /* Load value at relocation.												*/
+    lwz	    r7,0(r6)
+    /* Update value using SDA delta.											*/
+    add     r7,r7,r3
+    /* Store updated value.														*/
+    stw	    r7,0(r6)
+    bdnz    fixup_loop
+no_fixup:
+    mtlr    r0
+    blr
+}
+
+/***************************************************************************/
+/*
+ *	__init_registers
+ *
+ *	Initialize PowerPC EABI Registers
+ *
+ *	Note: this function is guaranteed to not reference any memory; the memory
+ *	controller may not be initialized.
+ *
+ *	we now overload the function in the event that the user wants pic pid
+ *
+ */
+/***************************************************************************/
+asm extern void __init_registers(void)
+{
+	nofralloc						/* see above on usage of nofralloc */
+
+    mflr    r0
+
+	/* _ABS_SDA_BASE_, generated by the linker, is the same value as 		 	*/
+	/* _SDA_BASE_ but forces the linker to treat it as absolutetly addressed 	*/
+	/* and not to substitute r13 for r0.  We therefore end up with r13 exactly 	*/
+	/* as calculated at linktime. 												*/
+	addis	r13, r0, _ABS_SDA_BASE_@ha
+	addi	r13, r13, _ABS_SDA_BASE_@l
+
+	/* _ABS_SDA2_BASE_, generated by the linker, is the same value as 		 	*/
+	/* _SDA2_BASE_ but forces the linker to treat it as absolutetly addressed 	*/
+	/* and not to substitute r2 for r0.  We therefore end up with r2 exactly 	*/
+	/* as calculated at linktime. 												*/
+	addis	r2, r0, _ABS_SDA2_BASE_@ha
+	addi	r2, r2, _ABS_SDA2_BASE_@l
+   
+	/* Grab the runtime address of __get_linktime_address.  The bcl will put	*/
+	/* __get_linktime_address into LR. */
+	bcl 	20,31,__get_linktime_address
+entry __get_linktime_address
+	/* Move runtime address of __get_linktime_address from LR to r4. */
+	mflr	r4
+
+	/* Grab the linktime address of __get_linktime_address.  Note that r0 will	*/
+	/* get converted to r13 or r2 by the linker but because r13 and r2 may not	*/
+	/* reflect the their runtime values yet, r3 might not equal r4.				*/
+    addis   r3,r0,__get_linktime_address@ha
+    addi    r3,r3,__get_linktime_address@l
+    
+   	/* Subtract the runtime from the linktime address.							*/
+   	sub		r3,r4,r3
+   	/* If runtime and linktime addresses are the same, no fixup is necessary.	*/
+    cmpli   cr0,r3,0
+    beq     no_fixup
+
+   	/* Add the delta into small data pointers so they will reflect the current 	*/
+   	/* position of code and data.												*/
+   	add		r13,r13,r3
+   	add		r2,r2,r3
+no_fixup:
+
+	/* Initialize runtime address of _stack_addr.  Note that r0 will			*/
+	/* get converted to r13 or r2 by the linker if _stack_addr is 				*/
+	/* treated as an internal symbol (default is external).						*/
+	addis	r1, r0, _stack_addr@ha
+	addi	r1, r1, _stack_addr@l
+    mtlr    r0
+
+	blr
+}
+
+/***************************************************************************/
+/*
+ *	__init_data
+ *
+ *	Initialize all (RAM) data sections, copying ROM sections as necessary.
+ *
+ *	dst			destination RAM address
+ *	size		number of bytes to zero
+ *
+ *	we now overload the function in the event that the user wants pic pid
+ *
+ */
+/***************************************************************************/
+extern void __init_data(void)
+{
+	__pic_rom_copy_info *dci;
+	__pic_bss_init_info *bii;
+	int					delta = __get_runtime_linktime_delta();
+	unsigned int		size;
+	unsigned char 		*ram_addr;		/* address in ram (executing address) */
+	unsigned char 		*ram_end;		/* end address in ram (executing address) */
+	unsigned char 		*rom_addr;		/* address in rom */
+	unsigned char 		*rom_end;		/* end address in rom */
+	int					internal;
+		
+	/* for sda pic pid, if ram_end and ram_addr are swapped so that ram_end < ram_addr, 		*/
+	/* then segment is internal, otherwise it is external.  for eabi, addresses are external 	*/
+
+	dci = _pic_rom_copy_info;
+	while (1) {
+		if (dci->rom_addr == 0 && dci->ram_addr == 0 && dci->ram_end == 0) break;
+		internal = (dci->rom_end < dci->rom_addr);
+		if (internal) {
+			rom_addr = dci->rom_end + delta;
+			rom_end = dci->rom_addr + delta;
+		} else {
+			rom_addr = dci->rom_addr;
+			rom_end = dci->rom_end;
+		}
+		internal = (dci->ram_end < dci->ram_addr);
+		if (internal) {
+			ram_addr = dci->ram_end + delta;
+			ram_end = dci->ram_addr + delta;
+		} else {
+			ram_addr = dci->ram_addr;
+			ram_end = dci->ram_end;
+		}
+		size = (unsigned int) (ram_end - ram_addr);
+ 		__copy_rom_section(ram_addr, rom_addr, size);
+ 		dci++;
+	}
+ 
+ 	/* Initialize with zeros: */
+
+	bii = _pic_bss_init_info;
+	while (1) {
+		if (bii->ram_addr == 0 && bii->ram_end == 0) break;
+		internal = (bii->ram_end < bii->ram_addr);
+		if (internal) {
+			ram_addr = bii->ram_end + delta;
+			ram_end = bii->ram_addr + delta;
+		} else {
+			ram_addr = bii->ram_addr;
+			ram_end = bii->ram_end;
+		}
+		size = (unsigned int) (ram_end - ram_addr);
+ 		__init_bss_section(ram_addr, size);
+ 		bii++;
+	}
+	
+	/* now that data is copied to ram, we can fix up initialized pointers */
+	__mwerks_fixup_relocations();	
+}
+
+/***************************************************************************/
+/*
+ *	__exception_info_constants
+ *
+ *	Called from __init_cpp_exceptions.cpp
+ *
+ *	info		address of linker generated exception table info
+ *	R2			address of variable to hold the value in r2
+ *
+ *	we now overload the function in the event that the user wants pic pid
+ *
+ */
+/***************************************************************************/
+extern void __exception_info_constants(void **info, char **R2)
+{
+	register char *temp;				/* r2 register contents								*/
+
+	asm {
+		mr      temp,r2
+	}
+	*R2 = temp;
+	
+	*info = _pic_eti_init_info;
+}
+
+/***************************************************************************/
+/*
+ *	__find_exception_addresses
+ *
+ *	Called from ExceptionPPC.cp
+ *
+ *	info		address of linker generated exception table info
+ *	returnaddr	address within a code segment
+ *	returnaddr	address within a code segment
+ *	ex_start	address of variable to hold address of exception table info
+ *	ex_end		address of variable to hold end address of exception table info
+ *
+ *	we now overload the function in the event that the user wants pic pid
+ *
+ */
+/***************************************************************************/
+extern int __find_exception_addresses(void *info, char *returnaddr, void **ex_start, void **ex_end)
+{
+	__pic_eti_init_info	*eti_info = (__pic_eti_init_info*)info;
+	unsigned char		*start;			/* address */
+	unsigned char		*end;			/* end address */
+	int					internal;
+	int					delta = __get_runtime_linktime_delta();
+	
+	while (1) {
+		if (eti_info->code_end - eti_info->code_start == 0) break;
+		internal = (eti_info->code_end < eti_info->code_start);
+		if (internal) {
+			start = eti_info->code_end + delta;
+			end = eti_info->code_start + delta;
+		} else {
+			start = eti_info->code_start;
+			end = eti_info->code_end;
+		}
+		if((unsigned char*)returnaddr>=start && (unsigned char*)returnaddr<end) {
+			internal = (eti_info->eti_end < eti_info->eti_start);
+			if (internal) {
+				start = eti_info->eti_end + delta;
+				end = eti_info->eti_start + delta;
+			} else {
+				start = eti_info->eti_start;
+				end = eti_info->eti_end;
+			}
+			*ex_start = start;
+			*ex_end = end;
+			return(1);
+		}
+ 		eti_info++;
+	}
+	
+	return(0);
+}
+
+
+#endif

+ 1054 - 0
BMS Master/Sources/BMS_CAN0_Mail_Box.c

@@ -0,0 +1,1054 @@
+///##############################################################################
+//
+// FILE:	BMS_CAN0_Mail_Box.c
+//
+// TITLE:	CAN 0 
+//			- Module Configuration
+//			- Mailbox Definition
+//			- Mailbox Load 
+//				uint16_t CAN0_init		( void )
+//			- Mailbox Check
+//				uint16_t CAN0_update	( void )
+//
+//
+//##############################################################################
+//
+//==============================================================================
+// Change History:
+//==============================================================================
+// Datum:   | Name | Version:| Change / Cause:                            | No
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 002
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 001
+//------------------------------------------------------------------------------
+// 05.07.13 |  VR  |   1.0   | New Build                                  | 000
+//==============================================================================
+//==============================================================================
+// Comment Change / Cause:
+//==============================================================================
+// Change: 003                                                           // 003
+//----------------------
+//                                                       
+//
+//==============================================================================
+// Change: 002                                                           // 002
+//----------------------
+//                                           
+//
+//==============================================================================
+// Change: 001                                                           // 001
+//----------------------
+// 
+//
+//==============================================================================
+
+#include "BMS_Master.h"
+
+volatile uint16_t CAN_ID_count[51] = {	0,0,0,0,0,0,0,0,0,0,
+										0,0,0,0,0,0,0,0,0,0,
+										0,0,0,0,0,0,0,0,0,0,
+										0,0,0,0,0,0,0,0,0,0,
+										0,0,0,0,0,0,0,0,0,0,
+										0					};
+
+static uint8_t Master_Rx0_buff[8]= {0,0,0,0,0,0,0,0};
+static uint8_t Master_Rx1_buff[8]= {0,0,0,0,0,0,0,0};
+static uint8_t Master_Rx2_buff[8]= {0,0,0,0,0,0,0,0};
+static uint8_t Master_Rx3_buff[8]= {0,0,0,0,0,0,0,0};
+static uint8_t Master_Rx4_buff[8]= {0,0,0,0,0,0,0,0};
+static uint8_t Master_Rx5_buff[8]= {0,0,0,0,0,0,0,0};
+static uint8_t Master_Rx6_buff[8]= {0,0,0,0,0,0,0,0};
+static uint8_t Master_Rx7_buff[8]= {0,0,0,0,0,0,0,0};
+
+
+
+// ****** Config CAN Modul ********************************************************
+CAN_CONFIG CAN_0_Config = {
+	&CAN_0,
+	CAN0_PortB0_1,
+	TxPushPull,         //enum {TxPushPull=0,Tx_OpenDrain}	TxPortType;
+	RxMask_Individual,	//RxMaskType
+	0xFFFFFFFF,		//uint32_t GlobalRxMask
+	CANBaud_500kHz_OSC_40MHz
+};
+
+
+
+// ****** MailBox Master Ctrl **************************************************
+
+// Mailbox for contacting Slave 0
+CAN_MAILBOX CAN0_MB_MASTER0_BMS_100= {
+	&CAN_0_Config,
+	0,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x100		// ID
+};
+
+// Mailbox for contacting Slave 1
+CAN_MAILBOX CAN0_MB_MASTER1_BMS_110= {
+	&CAN_0_Config,
+	1,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x110		// ID
+};
+
+// Mailbox for contacting Slave 2
+CAN_MAILBOX CAN0_MB_MASTER2_BMS_120= {
+	&CAN_0_Config,
+	2,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x120		// ID
+};
+
+// Mailbox for contacting Slave 3
+CAN_MAILBOX CAN0_MB_MASTER3_BMS_130= {
+	&CAN_0_Config,
+	3,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x130		// ID
+};
+
+// Mailbox for contacting Slave 4
+CAN_MAILBOX CAN0_MB_MASTER4_BMS_140= {
+	&CAN_0_Config,
+	4,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x140		// ID
+};
+
+// Mailbox for contacting Slave 5
+CAN_MAILBOX CAN0_MB_MASTER5_BMS_150= {
+	&CAN_0_Config,
+	5,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x150		// ID
+};
+
+// Mailbox for contacting Slave 6
+CAN_MAILBOX CAN0_MB_MASTER6_BMS_160= {
+	&CAN_0_Config,
+	6,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x160		// ID
+};
+
+// Mailbox for contacting Slave 7
+CAN_MAILBOX CAN0_MB_MASTER7_BMS_170= {
+	&CAN_0_Config,
+	7,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x170		// ID
+};
+
+// Mailbox for contacting Slave 8
+CAN_MAILBOX CAN0_MB_MASTER8_BMS_180= {
+	&CAN_0_Config,
+	8,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x180		// ID
+};
+
+// Mailbox for contacting Slave 9
+CAN_MAILBOX CAN0_MB_MASTER9_BMS_190= {
+	&CAN_0_Config,
+	9,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x190		// ID
+};
+
+// Mailbox for contacting Slave 10
+CAN_MAILBOX CAN0_MB_MASTER10_BMS_1a0= {
+	&CAN_0_Config,
+	10,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x1a0		// ID
+};
+
+// Mailbox for contacting Slave 11
+CAN_MAILBOX CAN0_MB_MASTER11_BMS_1b0= {
+	&CAN_0_Config,
+	11,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x1b0		// ID
+};
+
+// Mailbox for contacting Slave 12
+CAN_MAILBOX CAN0_MB_MASTER12_BMS_1c0= {
+	&CAN_0_Config,
+	12,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x1c0		// ID
+};
+
+// Mailbox for contacting Slave 13
+CAN_MAILBOX CAN0_MB_MASTER13_BMS_1d0= {
+	&CAN_0_Config,
+	13,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x1d0		// ID
+};
+
+// Mailbox for contacting Slave 14
+CAN_MAILBOX CAN0_MB_MASTER14_BMS_1e0= {
+	&CAN_0_Config,
+	14,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x1e0		// ID
+};
+
+// Mailbox for contacting Slave 15 = UI-Board
+CAN_MAILBOX CAN0_MB_MASTER15_BMS_1f0= {
+	&CAN_0_Config,
+	15,			// uint8_t MBNumber		//0..64 Number of Message Buffer
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x1f0		// ID
+};
+
+
+
+
+
+// *** structure to access Mailboxes by number *** //
+
+CAN_MAILBOX* MB_Container[16]={
+		&CAN0_MB_MASTER0_BMS_100,
+		&CAN0_MB_MASTER1_BMS_110,
+		&CAN0_MB_MASTER2_BMS_120,
+		&CAN0_MB_MASTER3_BMS_130,
+		&CAN0_MB_MASTER4_BMS_140,
+		&CAN0_MB_MASTER5_BMS_150,
+		&CAN0_MB_MASTER6_BMS_160,
+		&CAN0_MB_MASTER7_BMS_170,
+		&CAN0_MB_MASTER8_BMS_180,
+		&CAN0_MB_MASTER9_BMS_190,
+		&CAN0_MB_MASTER10_BMS_1a0,
+		&CAN0_MB_MASTER11_BMS_1b0,
+		&CAN0_MB_MASTER12_BMS_1c0,
+		&CAN0_MB_MASTER13_BMS_1d0,
+		&CAN0_MB_MASTER14_BMS_1e0,
+		&CAN0_MB_MASTER15_BMS_1f0		
+};
+
+// *** structure to access Request Telegrams by number
+MASTER_X_BMS_TELEGRAM TelegramTxContainer[16];
+
+
+
+// ****** MailBox Slave Response  **************************************************
+
+// Slave X Telegram 0
+CAN_MAILBOX CAN_MB_SlaveX0_2X0 = {
+	&CAN_0_Config,
+	16,			// uint8_t MBNumber		//0..64
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFC3FFFFF, // uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x200		// ID
+};
+
+// Slave X Telegram 1
+CAN_MAILBOX CAN_MB_SlaveX1_2X1 = {
+	&CAN_0_Config,
+	17,			// uint8_t MBNumber		//0..64
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFC3FFFFF, // uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x201		// ID
+};
+
+// Slave X Telegram 2
+CAN_MAILBOX CAN_MB_SlaveX2_2X2 = {
+	&CAN_0_Config,
+	18,			// uint8_t MBNumber		//0..64
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFC3FFFFF, // uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x202		// ID
+};
+
+// Slave X Telegram 3
+CAN_MAILBOX CAN_MB_SlaveX3_2X3 = {
+	&CAN_0_Config,
+	19,			// uint8_t MBNumber		//0..64
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFC3FFFFF, // uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x203		// ID
+};
+
+// Slave X Telegram 4
+CAN_MAILBOX CAN_MB_SlaveX4_2X4 = {
+	&CAN_0_Config,
+	20,			// uint8_t MBNumber		//0..64
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFC3FFFFF, // uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x204		// ID
+};
+
+// Slave X Telegram 5
+CAN_MAILBOX CAN_MB_SlaveX5_2X5 = {
+	&CAN_0_Config,
+	21,			// uint8_t MBNumber		//0..64
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFC3FFFFF, // uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x205		// ID
+};
+
+// Slave X Telegram 6
+CAN_MAILBOX CAN_MB_SlaveX6_2X6 = {
+	&CAN_0_Config,
+	22,			// uint8_t MBNumber		//0..64
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFC3FFFFF, // uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x206		// ID
+};
+
+// Slave X Telegram 7
+CAN_MAILBOX CAN_MB_SlaveX7_2X7 = {
+	&CAN_0_Config,
+	23,			// uint8_t MBNumber		//0..64
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFC3FFFFF, // uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x207		// ID
+};
+
+
+
+// ****** MailBox UI_Master Response  **************************************************
+
+CAN_MAILBOX CAN_MB_UI_MASTER_2F7 = {
+	&CAN_0_Config,
+	24,			// uint8_t MBNumber		//0..64
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFFFFFFFF, // uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x2FF		// ID
+};
+
+
+// ***** Mailboxes for automatic CAN ID initialization
+
+// Mailboxes for CAN initialisierung
+
+
+CAN_MAILBOX CAN_TxMB_System300 = {
+	&CAN_0_Config,
+	25,			// uint8_t MBNumber		//0..15
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x300		// ID
+};
+
+CAN_MAILBOX CAN_TxMB_System30A = {
+	&CAN_0_Config,
+	26,			// uint8_t MBNumber		//0..15
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x30A		// ID
+};
+
+CAN_MAILBOX CAN_TxMB_Master0A = {
+	&CAN_0_Config,
+	27,			// uint8_t MBNumber		//0..15
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x10A		// ID
+};
+
+// ****** CAN_RxMB_Slave_0A_Master **************************************************
+CAN_MAILBOX CAN_RxMB_Slave_0A_Master = {
+	&CAN_0_Config,
+	28,			// uint8_t MBNumber		//0..15
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFFFFFFFF, // uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x20A		// ID
+};
+
+
+
+// Mailboxes for Programming serial Number 
+
+// ****** CAN_RxMB_System308 **************************************************
+CAN_MAILBOX CAN_RxMB_System308 = {
+	&CAN_0_Config,
+	29,			// uint8_t MBNumber		//0..15
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFFFFFFFF, // uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x308		// ID
+};
+
+// ****** CAN_RxMB_System309 **************************************************
+CAN_MAILBOX CAN_RxMB_System309 = {
+	&CAN_0_Config,
+	30,			// uint8_t MBNumber		//0..15
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFFFFFFFF, // uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x309		// ID
+};
+
+
+
+
+
+// ***** CAN0_init *************************************************************
+uint16_t CAN0_init( void )
+{
+	uint16_t ReturnVal = CAN_OK;
+	
+	if (CAN_Init(&CAN_0_Config) == CAN_OK) 
+	{
+		// init Tx Message Boxes
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER0_BMS_100);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER1_BMS_110);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER2_BMS_120);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER3_BMS_130);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER4_BMS_140);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER5_BMS_150);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER6_BMS_160);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER7_BMS_170);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER8_BMS_180);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER9_BMS_190);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER10_BMS_1a0);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER11_BMS_1b0);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER12_BMS_1c0);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER13_BMS_1d0);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER14_BMS_1e0);
+		ReturnVal += CAN_Init_Mailbox(&CAN0_MB_MASTER15_BMS_1f0);
+		
+		
+		// init Rx Message Boxes
+		ReturnVal += CAN_Init_Mailbox(&CAN_MB_SlaveX0_2X0 );
+		ReturnVal += CAN_Init_Mailbox(&CAN_MB_SlaveX1_2X1 );
+		ReturnVal += CAN_Init_Mailbox(&CAN_MB_SlaveX2_2X2 );
+		ReturnVal += CAN_Init_Mailbox(&CAN_MB_SlaveX3_2X3 );
+		ReturnVal += CAN_Init_Mailbox(&CAN_MB_SlaveX4_2X4 );
+		ReturnVal += CAN_Init_Mailbox(&CAN_MB_SlaveX5_2X5 );
+		ReturnVal += CAN_Init_Mailbox(&CAN_MB_SlaveX6_2X6 );
+		ReturnVal += CAN_Init_Mailbox(&CAN_MB_SlaveX7_2X7 );
+		
+		// init tx mailboxes for automatic can id search
+		
+		CAN_Init_Mailbox(&CAN_TxMB_System300 );
+		CAN_Init_Mailbox(&CAN_TxMB_System30A );
+		CAN_Init_Mailbox(&CAN_TxMB_Master0A);
+		
+		// init rx mailboxes for automatic can id search
+		CAN_Init_Mailbox(&CAN_RxMB_Slave_0A_Master );
+		CAN_Init_Mailbox(&CAN_RxMB_System308 );
+		CAN_Init_Mailbox(&CAN_RxMB_System309);
+
+
+
+	}
+	return ReturnVal;
+}
+
+uint16_t CAN0_init_telegrams(MASTER_X_BMS_TELEGRAM* telegram_ptr,uint8_t nrOfSlaves) {
+	int i;
+	if(nrOfSlaves > CAN0_MAX_NR_OF_SLAVES) {
+		return FALSE;
+	}
+
+	for(i=0;i<nrOfSlaves;i++) {
+		telegram_ptr->Values.MasterAlive=0;
+		telegram_ptr->Values.SetMode=BMS_SLAVE_RUN ;
+		telegram_ptr->Values.BalancingCell0_7=0;
+		telegram_ptr->Values.BalancingCell8_15=0;
+		telegram_ptr->Values.BalancingCell16_23=0;		
+		telegram_ptr++;
+	}
+	return TRUE;
+}
+
+uint16_t CAN0_rx_test() {
+	SET_OUTPIN(PIN_REGNR_LED1); // set LED 1 
+	
+	// check if Interrupt Flag 1 register is set, if true CAN Message has arrived
+	if( CHECKBIT( CAN_0.IFRL.R, 16 )) {	
+		SETBIT( CAN_0.IFRL.R, 16);		// Clear Interrupt Flag 1 register by writing '1'
+		CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX0_2X0,&Master_Rx0_buff[0]);
+		CAN_ID_count[16]++;
+	}
+	
+	if( CHECKBIT( CAN_0.IFRL.R, 17 )) {	
+		SETBIT( CAN_0.IFRL.R, 17);		// Clear Interrupt Flag 1 register by writing '1'
+		CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX1_2X1,&Master_Rx1_buff[0]);
+		CAN_ID_count[17]++;
+	}
+	
+	if( CHECKBIT( CAN_0.IFRL.R, 18 )) {	
+		SETBIT( CAN_0.IFRL.R, 18);		// Clear Interrupt Flag 1 register by writing '1'
+		CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX2_2X2,&Master_Rx2_buff[0]);
+		CAN_ID_count[18]++;
+	}
+	
+	if( CHECKBIT( CAN_0.IFRL.R, 19 )) {	
+		SETBIT( CAN_0.IFRL.R, 19);		// Clear Interrupt Flag 1 register by writing '1'
+		CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX3_2X3,&Master_Rx3_buff[0]);
+		CAN_ID_count[19]++;
+	}
+	
+	if( CHECKBIT( CAN_0.IFRL.R, 20 )) {	
+		SETBIT( CAN_0.IFRL.R, 20);		// Clear Interrupt Flag 1 register by writing '1'
+		CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX4_2X4,&Master_Rx4_buff[0]);
+		CAN_ID_count[20]++;
+	}
+	
+	if( CHECKBIT( CAN_0.IFRL.R, 21 )) {	
+		SETBIT( CAN_0.IFRL.R, 21);		// Clear Interrupt Flag 1 register by writing '1'
+		CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX5_2X5,&Master_Rx5_buff[0]);
+		CAN_ID_count[21]++;
+	}
+	
+	if( CHECKBIT( CAN_0.IFRL.R, 22 )) {	
+		SETBIT( CAN_0.IFRL.R, 22);		// Clear Interrupt Flag 1 register by writing '1'
+		CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX6_2X6,&Master_Rx6_buff[0]);
+		CAN_ID_count[22]++;
+	}
+	
+	if( CHECKBIT( CAN_0.IFRL.R, 23 )) {	
+		SETBIT( CAN_0.IFRL.R, 23);		// Clear Interrupt Flag 1 register by writing '1'
+		CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX7_2X7,&Master_Rx7_buff[0]);
+		CAN_ID_count[23]++;
+	}
+	
+	CLEAR_OUTPIN(PIN_REGNR_LED1);  //clear LED 1
+	return CAN_OK;	
+		
+}
+
+uint16_t CAN0_tx_test(uint8_t slave_nr,uint8_t *four_byte_field) {
+	int8_t ReturnResult;
+	ReturnResult = CAN_Write(MB_Container[slave_nr], four_byte_field);
+	return ReturnResult;
+}
+
+//// ***** CAN0_update ***********************************************************
+uint16_t CAN0_update( void ) {
+	return 0;
+}
+
+
+
+// **** Check for recived Can Ids
+uint32_t CAN0_check_serial_nr_rec_Can_init(MASTER_CAN0_STRUCT_t*s ,uint8_t SlaveNr) {
+	
+	if( CHECKBIT( CAN_0.IFRL.R, 28 )) {												// CAN_Rx_SlaveXA_Master
+		SETBIT( CAN_0.IFRL.R, 28 );													// IFR clear
+		CAN_Read( &CAN_RxMB_Slave_0A_Master, &(s->startupConfig.SlaveConfig[SlaveNr].SerialNr[0]) );	
+		return TRUE;
+	}
+	return FALSE;
+	
+}
+
+// ***** CAN_Tx_System30A ********************************************************
+uint16_t CAN_Tx_System30A( uint8_t *pSERNr )
+{
+	uint16_t   	ReturnResult = CAN_OK;
+	
+	ReturnResult = CAN_Write( &CAN_TxMB_System30A, pSERNr );
+		
+	return ReturnResult;
+}
+
+
+uint16_t CAN0_check_if_slave_rec(BMS_CAN0_SLAVE_t* Slave) {
+	uint16_t recTelegrams=0; // number of received telegrams
+
+	// ordenary Slave
+	if(Slave->SlaveType==SLAVE) {	
+		// check if Interrupt Flag 1 register is set, if true CAN Message has arrived
+		if( CHECKBIT( CAN_0.IFRL.R, 16 ) ) {	
+			SETBIT( CAN_0.IFRL.R, 16);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX0_2X0,&Master_Rx0_buff[0]);
+			Slave->SlaveTelegramsRecFlag |= (1<<0) ; //set flag to indicate that telegram 0 has been received
+			saveSlaveX0_Master_telegram(Slave);
+			CAN_ID_count[16]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 17 )) {	
+			SETBIT( CAN_0.IFRL.R, 17);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX1_2X1,&Master_Rx1_buff[0]);
+			Slave->SlaveTelegramsRecFlag |= (1<<1) ; //set flag to indicate that telegram 1 has been received
+			saveSlaveX1_Master_telegram(Slave);
+			CAN_ID_count[17]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 18 )) {	
+			SETBIT( CAN_0.IFRL.R, 18);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX2_2X2,&Master_Rx2_buff[0]);
+			Slave->SlaveTelegramsRecFlag |= (1<<2) ; //set flag to indicate that telegram 2 has been received
+			saveSlaveX2_Master_telegram(Slave);
+			CAN_ID_count[18]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 19 )) {	
+			SETBIT( CAN_0.IFRL.R, 19);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX3_2X3,&Master_Rx3_buff[0]);
+			Slave->SlaveTelegramsRecFlag |= (1<<3) ; //set flag to indicate that telegram 3 has been received
+			saveSlaveX3_Master_telegram(Slave);
+			CAN_ID_count[19]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 20 )) {	
+			SETBIT( CAN_0.IFRL.R, 20);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX4_2X4,&Master_Rx4_buff[0]);
+			Slave->SlaveTelegramsRecFlag |= (1<<4) ; //set flag to indicate that telegram 4 has been received
+			saveSlaveX4_Master_telegram(Slave);
+			CAN_ID_count[20]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 21 )) {	
+			SETBIT( CAN_0.IFRL.R, 21);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX5_2X5,&Master_Rx5_buff[0]);
+			Slave->SlaveTelegramsRecFlag |= (1<<5) ; //set flag to indicate that telegram 5 has been received
+			saveSlaveX5_Master_telegram(Slave);
+			CAN_ID_count[21]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 22 )) {	
+			SETBIT( CAN_0.IFRL.R, 22);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX6_2X6,&Master_Rx6_buff[0]);
+			Slave->SlaveTelegramsRecFlag |= (1<<6) ; //set flag to indicate that telegram 6 has been received
+			saveSlaveX6_Master_telegram(Slave);
+			CAN_ID_count[22]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 23 )) {	
+			SETBIT( CAN_0.IFRL.R, 23);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX7_2X7,&Master_Rx7_buff[0]);
+			Slave->SlaveTelegramsRecFlag |= (1<<7) ; //set flag to indicate that telegram 7 has been received
+			saveSlaveX7_Master_telegram(Slave);
+			CAN_ID_count[23]++;
+			recTelegrams++;
+		}
+	}
+
+	return recTelegrams;
+}
+/*
+ * use for reset of timeout error 
+ */
+
+uint16_t CAN0_clear_all_interrupt_flags() {
+	SETBIT( CAN_0.IFRL.R, 16);	
+	SETBIT( CAN_0.IFRL.R, 17);
+	SETBIT( CAN_0.IFRL.R, 18);	
+	SETBIT( CAN_0.IFRL.R, 19);	
+	SETBIT( CAN_0.IFRL.R, 20);
+	SETBIT( CAN_0.IFRL.R, 21);	
+	SETBIT( CAN_0.IFRL.R, 22);
+	SETBIT( CAN_0.IFRL.R, 23);
+	return TRUE;
+}
+
+uint16_t CAN0_DEBUG_data_check_if_slave_rec(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_SLAVE_t* DummySlave) {
+	uint16_t recTelegrams=0; // number of received telegrams
+
+	// ordenary Slave
+	if(Slave->SlaveType==SLAVE) {	
+		// check if Interrupt Flag 1 register is set, if true CAN Message has arrived
+		if( CHECKBIT( CAN_0.IFRL.R, 16 ) ) {	
+			SETBIT( CAN_0.IFRL.R, 16);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX0_2X0,&Master_Rx0_buff[0]);
+			gen_data_generate_CAN0_RX0_Telegram(DummySlave,(SLAVE_X0_5_BMS_TELEGRAM*)&Master_Rx0_buff[0]);
+			DummySlave->SlaveAliveCnt[0]++;
+			if(DummySlave->SlaveAliveCnt[0]>7){
+				DummySlave->SlaveAliveCnt[0]=0;
+			}
+			Slave->SlaveTelegramsRecFlag |= (1<<0) ; //set flag to indicate that telegram 0 has been received
+			saveSlaveX0_Master_telegram(Slave);
+			CAN_ID_count[16]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 17 )) {	
+			SETBIT( CAN_0.IFRL.R, 17);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX1_2X1,&Master_Rx1_buff[0]);
+			gen_data_generate_CAN0_RX1_Telegram(DummySlave,(SLAVE_X0_5_BMS_TELEGRAM*)&Master_Rx1_buff[0]);
+			DummySlave->SlaveAliveCnt[1]++;
+			if(DummySlave->SlaveAliveCnt[1]>7){
+				DummySlave->SlaveAliveCnt[1]=0;
+			}
+			Slave->SlaveTelegramsRecFlag |= (1<<1) ; //set flag to indicate that telegram 1 has been received
+			saveSlaveX1_Master_telegram(Slave);
+			CAN_ID_count[17]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 18 )) {	
+			SETBIT( CAN_0.IFRL.R, 18);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX2_2X2,&Master_Rx2_buff[0]);
+			gen_data_generate_CAN0_RX2_Telegram(DummySlave,(SLAVE_X0_5_BMS_TELEGRAM*)&Master_Rx2_buff[0]);
+			DummySlave->SlaveAliveCnt[2]++;
+			if(DummySlave->SlaveAliveCnt[2]>7){
+				DummySlave->SlaveAliveCnt[2]=0;
+			}
+			Slave->SlaveTelegramsRecFlag |= (1<<2) ; //set flag to indicate that telegram 2 has been received
+			saveSlaveX2_Master_telegram(Slave);
+			CAN_ID_count[18]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 19 )) {	
+			SETBIT( CAN_0.IFRL.R, 19);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX3_2X3,&Master_Rx3_buff[0]);
+			gen_data_generate_CAN0_RX3_Telegram(DummySlave,(SLAVE_X0_5_BMS_TELEGRAM*)&Master_Rx3_buff[0]);
+			DummySlave->SlaveAliveCnt[3]++;
+			if(DummySlave->SlaveAliveCnt[3]>7){
+				DummySlave->SlaveAliveCnt[3]=0;
+			}
+			Slave->SlaveTelegramsRecFlag |= (1<<3) ; //set flag to indicate that telegram 3 has been received
+			saveSlaveX3_Master_telegram(Slave);
+			CAN_ID_count[19]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 20 )) {	
+			SETBIT( CAN_0.IFRL.R, 20);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX4_2X4,&Master_Rx4_buff[0]);
+			gen_data_generate_CAN0_RX4_Telegram(DummySlave,(SLAVE_X0_5_BMS_TELEGRAM*)&Master_Rx4_buff[0]);
+			DummySlave->SlaveAliveCnt[4]++;
+			if(DummySlave->SlaveAliveCnt[4]>7){
+				DummySlave->SlaveAliveCnt[4]=0;
+			}
+			Slave->SlaveTelegramsRecFlag |= (1<<4) ; //set flag to indicate that telegram 4 has been received
+			saveSlaveX4_Master_telegram(Slave);
+			CAN_ID_count[20]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 21 )) {	
+			SETBIT( CAN_0.IFRL.R, 21);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX5_2X5,&Master_Rx5_buff[0]);
+			gen_data_generate_CAN0_RX5_Telegram(DummySlave,(SLAVE_X0_5_BMS_TELEGRAM*)&Master_Rx5_buff[0]);
+			DummySlave->SlaveAliveCnt[5]++;
+			if(DummySlave->SlaveAliveCnt[5]>7){
+				DummySlave->SlaveAliveCnt[5]=0;
+			}
+			Slave->SlaveTelegramsRecFlag |= (1<<5) ; //set flag to indicate that telegram 5 has been received
+			saveSlaveX5_Master_telegram(Slave);
+			CAN_ID_count[21]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 22 )) {	
+			SETBIT( CAN_0.IFRL.R, 22);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX6_2X6,&Master_Rx6_buff[0]);
+			gen_data_generate_CAN0_RX6_Telegram(DummySlave,(SLAVE_X6_BMS_TELEGRAM*)&Master_Rx6_buff[0]);
+			DummySlave->SlaveAliveCnt[6]++;
+			if(DummySlave->SlaveAliveCnt[6]>7){
+				DummySlave->SlaveAliveCnt[6]=0;
+			}
+			Slave->SlaveTelegramsRecFlag |= (1<<6) ; //set flag to indicate that telegram 6 has been received
+			saveSlaveX6_Master_telegram(Slave);
+			CAN_ID_count[22]++;
+			recTelegrams++;
+		}
+		
+		if( CHECKBIT( CAN_0.IFRL.R, 23 )) {	
+			SETBIT( CAN_0.IFRL.R, 23);		// Clear Interrupt Flag 1 register by writing '1'
+			CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX7_2X7,&Master_Rx7_buff[0]);
+			gen_data_generate_CAN0_RX7_Telegram(DummySlave,(SLAVE_X7_BMS_TELEGRAM*)&Master_Rx7_buff[0]);
+			DummySlave->SlaveAliveCnt[7]++;
+			if(DummySlave->SlaveAliveCnt[7]>7){
+				DummySlave->SlaveAliveCnt[7]=0;
+			}
+			Slave->SlaveTelegramsRecFlag |= (1<<7) ; //set flag to indicate that telegram 7 has been received
+			saveSlaveX7_Master_telegram(Slave);
+			CAN_ID_count[23]++;
+			recTelegrams++;
+		}
+	}
+
+	return recTelegrams;
+}
+
+uint16_t CAN0_DEBUG_slave_check_if_slave_rec(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_SLAVE_t* DummySlave) {
+	// just copy data from dummy slave
+	uint8_t i;
+	for(i=0;i<CAN0_MAX_NR_OF_SLAVES-1;i++) {
+		Slave->CellTemp[i]=DummySlave->CellTemp[i];
+		Slave->CellVoltage[i]=DummySlave->CellVoltage[i];
+	}
+	Slave->HeatSinkTemp=DummySlave->HeatSinkTemp;
+	Slave->SlaveError=DummySlave->SlaveError;
+	Slave->SlaveMode=DummySlave->SlaveMode;
+	Slave->SlaveTelegramsRecFlag=CAN0_ALL_TELEGRAMS_REC;
+	
+	
+}
+
+uint8_t CAN0_check_if_UI_Board_rec(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_UI_t* UI_Board) {
+	uint8_t recTelegrams=0;
+	if( CHECKBIT( CAN_0.IFRL.R, 23 )) {	
+		SETBIT( CAN_0.IFRL.R, 23);		// Clear Interrupt Flag 1 register by writing '1'
+		CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX7_2X7,&Master_Rx7_buff[0]);
+		Slave->SlaveTelegramsRecFlag |= (1<<7) ; //set flag to indicate that telegram 7 has been received
+		saveSlaveUI_Master_telegram(Slave,UI_Board);
+		CAN_ID_count[23]++;
+		recTelegrams++;
+		return TRUE;
+	}	
+	return FALSE;
+}
+
+uint8_t CAN0_DEBUG_data_check_if_UI_Board_rec(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_SLAVE_t* DummySlave,BMS_CAN0_UI_t* UI_Board,BMS_CAN0_UI_t* Dummy_UI_Board) {
+	uint8_t recTelegrams=0;
+	if( CHECKBIT( CAN_0.IFRL.R, 23 )) {	
+		SETBIT( CAN_0.IFRL.R, 23);		// Clear Interrupt Flag 1 register by writing '1'
+		CAN_Rx_readout_Mailbox(&CAN_MB_SlaveX7_2X7,&Master_Rx7_buff[0]);
+		gen_data_generate_CAN0_UI_Telegram(DummySlave,Dummy_UI_Board,(SLAVE_UI_BMS_TELEGRAM*)&Master_Rx7_buff[0]);
+		Slave->SlaveTelegramsRecFlag |= (1<<7) ; //set flag to indicate that telegram 7 has been received
+		saveSlaveUI_Master_telegram(Slave,UI_Board);
+		CAN_ID_count[23]++;
+		recTelegrams++;
+		return TRUE;
+	}		
+}
+
+uint8_t CAN0_DEBUG_slave_check_if_UI_Board_rec(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_SLAVE_t* DummySlave,BMS_CAN0_UI_t* UI_Board,BMS_CAN0_UI_t* Dummy_UI_Board) {
+	uint8_t recTelegrams=0;
+		UI_Board->Ibatt=Dummy_UI_Board->Ibatt;
+		UI_Board->Ubatt=Dummy_UI_Board->Ubatt;
+		UI_Board->Checksum=Dummy_UI_Board->Checksum;
+	return TRUE;
+}
+
+
+uint16_t saveSlaveX0_Master_telegram(BMS_CAN0_SLAVE_t* Slave){
+	SLAVE_X0_5_BMS_TELEGRAM* tel_ptr= (SLAVE_X0_5_BMS_TELEGRAM*)&Master_Rx0_buff[0];
+	Slave->SlaveAliveCnt[0]=(uint8_t)(tel_ptr->SlaveAlive);
+	Slave->CellVoltage[0]=(tel_ptr->Vcell0);
+	Slave->CellVoltage[1]=tel_ptr->Vcell1;
+	Slave->CellVoltage[2]=tel_ptr->Vcell2;
+	Slave->CellVoltage[3]=tel_ptr->Vcell3;
+	return TRUE;
+}
+
+uint16_t saveSlaveX1_Master_telegram(BMS_CAN0_SLAVE_t* Slave){
+	SLAVE_X0_5_BMS_TELEGRAM* tel_ptr= (SLAVE_X0_5_BMS_TELEGRAM*)&Master_Rx1_buff[0];
+	Slave->SlaveAliveCnt[1]=(uint8_t)(tel_ptr->SlaveAlive);
+	Slave->CellVoltage[4]=(tel_ptr->Vcell0);
+	Slave->CellVoltage[5]=tel_ptr->Vcell1;
+	Slave->CellVoltage[6]=tel_ptr->Vcell2;
+	Slave->CellVoltage[7]=tel_ptr->Vcell3;
+	return TRUE;
+}
+
+uint16_t saveSlaveX2_Master_telegram(BMS_CAN0_SLAVE_t* Slave){
+	SLAVE_X0_5_BMS_TELEGRAM* tel_ptr= (SLAVE_X0_5_BMS_TELEGRAM*)&Master_Rx2_buff[0];
+	Slave->SlaveAliveCnt[2]=(uint8_t)(tel_ptr->SlaveAlive);
+	Slave->CellVoltage[8]=(tel_ptr->Vcell0);
+	Slave->CellVoltage[9]=tel_ptr->Vcell1;
+	Slave->CellVoltage[10]=tel_ptr->Vcell2;
+	Slave->CellVoltage[11]=tel_ptr->Vcell3;
+	return TRUE;
+}
+
+uint16_t saveSlaveX3_Master_telegram(BMS_CAN0_SLAVE_t* Slave){
+	SLAVE_X0_5_BMS_TELEGRAM* tel_ptr= (SLAVE_X0_5_BMS_TELEGRAM*)&Master_Rx3_buff[0];
+	Slave->SlaveAliveCnt[3]=(uint8_t)(tel_ptr->SlaveAlive);
+	Slave->CellVoltage[12]=(tel_ptr->Vcell0);
+	Slave->CellVoltage[13]=tel_ptr->Vcell1;
+	Slave->CellVoltage[14]=tel_ptr->Vcell2;
+	Slave->CellVoltage[15]=tel_ptr->Vcell3;
+	return TRUE;
+}
+
+uint16_t saveSlaveX4_Master_telegram(BMS_CAN0_SLAVE_t* Slave){
+	SLAVE_X0_5_BMS_TELEGRAM* tel_ptr= (SLAVE_X0_5_BMS_TELEGRAM*)&Master_Rx4_buff[0];
+	Slave->SlaveAliveCnt[4]=(uint8_t)(tel_ptr->SlaveAlive);
+	Slave->CellVoltage[16]=(tel_ptr->Vcell0);
+	Slave->CellVoltage[17]=tel_ptr->Vcell1;
+	Slave->CellVoltage[18]=tel_ptr->Vcell2;
+	Slave->CellVoltage[19]=tel_ptr->Vcell3;
+	return TRUE;
+}
+
+uint16_t saveSlaveX5_Master_telegram(BMS_CAN0_SLAVE_t* Slave){
+	SLAVE_X0_5_BMS_TELEGRAM* tel_ptr= (SLAVE_X0_5_BMS_TELEGRAM*)&Master_Rx5_buff[0];
+	Slave->SlaveAliveCnt[5]=(uint8_t)(tel_ptr->SlaveAlive);
+	Slave->CellVoltage[20]=(tel_ptr->Vcell0);
+	Slave->CellVoltage[21]=tel_ptr->Vcell1;
+	Slave->CellVoltage[22]=tel_ptr->Vcell2;
+	Slave->CellVoltage[23]=tel_ptr->Vcell3;
+	return TRUE;
+}
+
+uint16_t saveSlaveX6_Master_telegram(BMS_CAN0_SLAVE_t* Slave){
+	SLAVE_X6_BMS_TELEGRAM* tel_ptr= (SLAVE_X6_BMS_TELEGRAM*)&Master_Rx6_buff[0];
+	Slave->SlaveAliveCnt[6]=(uint8_t)(tel_ptr->SlaveAlive);
+	Slave->SlaveMode=tel_ptr->SlaveMode;
+	Slave->SlaveError=tel_ptr->SlaveError;
+	return TRUE;
+}
+
+uint16_t saveSlaveX7_Master_telegram(BMS_CAN0_SLAVE_t* Slave){
+	SLAVE_X7_BMS_TELEGRAM* tel_ptr= (SLAVE_X7_BMS_TELEGRAM*)&Master_Rx7_buff[0];
+	uint8_t MuxCounter = tel_ptr->MuxCounter;
+	Slave->SlaveAliveCnt[7]=(uint8_t)(tel_ptr->SlaveAlive);
+	Slave->HeatSinkTemp=tel_ptr->TempHeatSink;
+	Slave->CellTemp[MuxCounter*4+0]=tel_ptr->TempSens0;
+	Slave->CellTemp[MuxCounter*4+1]=tel_ptr->TempSens1;
+	Slave->CellTemp[MuxCounter*4+2]=tel_ptr->TempSens2;
+	Slave->CellTemp[MuxCounter*4+3]=tel_ptr->TempSens3;	
+	return TRUE;
+}
+
+uint16_t saveSlaveUI_Master_telegram(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_UI_t* UI_Board){
+	Slave->SlaveAliveCnt[0]=Master_Rx7_buff[0] >> 5;
+	Slave->SlaveMode=Master_Rx7_buff[0] & 0x1F;
+	UI_Board->Ubatt=(Master_Rx7_buff[1] << 8 )+ Master_Rx7_buff[2];
+	UI_Board->Ibatt=(Master_Rx7_buff[3] << 8 )+ Master_Rx7_buff[4];
+	UI_Board->Checksum=Master_Rx7_buff[7];	
+	return TRUE;
+}
+
+
+
+// ***** End BMS_CAN0_Mail_Box.c ***********************************************

+ 627 - 0
BMS Master/Sources/BMS_CAN0_Tools.c

@@ -0,0 +1,627 @@
+///##############################################################################
+//
+// FILE:	BMS_CAN0_Tools.c
+//
+// TITLE:	CAN 0 
+//			CAN_Tx_Balance
+//			check_and_save_Voltage
+//			check_and_save_Status
+//			check_and_save_UI
+//			check_and_save_Temperature
+//			check_Voltage_Border
+//			check_Status_Border
+//			check_UI_Border
+//			check_Temperature_Border
+//			Sum_Cell_Voltage
+//			Test_MAX_LOAD_CELL_VOLTAGE
+//			Search_MIN_CELL_VOLTAGE
+//			Test_Slave_Presents
+//
+//
+//##############################################################################
+//
+//==============================================================================
+// Change History:
+//==============================================================================
+// Datum:   | Name | Version:| Change / Cause:                            | No
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 002
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 001
+//------------------------------------------------------------------------------
+// 20.04.12 |  TM  |   1.0   | New Build                                  | 000
+//==============================================================================
+//==============================================================================
+// Comment Change / Cause:
+//==============================================================================
+// Change: 003                                                           // 003
+//----------------------
+//                                                       
+//
+//==============================================================================
+// Change: 002                                                           // 002
+//----------------------
+//                                           
+//
+//==============================================================================
+// Change: 001                                                           // 001
+//----------------------
+//  
+//
+//==============================================================================
+
+#include "BMS_Master.h"
+
+
+// ***** Functions for startup *********************************************
+
+
+uint16_t CAN_Tx_MasterX_BMS(MASTER_CAN0_STRUCT_t* s, uint8_t SlaveNummer, uint8_t MasterAlive, uint8_t SetMode, uint32_t Balancer )
+{
+	uint8_t  	Data[MAX_SLAVES];
+	uint16_t   	ReturnResult = CAN_OK;
+	
+	Balancer++;
+	
+	Data[0]  = SetMode + (MasterAlive<<5);
+	Data[1]  = 0;
+	Data[2]  = 0;
+	Data[3]  = 0;
+	Data[4]  = 0;
+	Data[5]  = 0;
+	Data[6]  = 0;
+	Data[7]  = 0;
+	
+	ReturnResult = CAN_Write(s->Slave[SlaveNummer].TxMailbox_ptr , &Data[0] );
+
+	return ReturnResult;
+}
+
+// ***** CAN_Tx_System300 ********************************************************
+uint16_t CAN_Tx_System300( uint16_t IDSEARCH )
+{
+	uint8_t  	cIDSEARCH[8] = {'I','D','S','E','A','R','C','H'};
+	uint8_t     cSERNRPRG[8] = {'S','E','R','N','R','P','R','G'};
+	
+	uint16_t   	ReturnResult = CAN_OK;
+	
+	if(IDSEARCH)
+		ReturnResult = CAN_Write( &CAN_TxMB_System300, &(cIDSEARCH[0]) );
+	else
+		ReturnResult = CAN_Write( &CAN_TxMB_System300, &cSERNRPRG[0] );
+		
+	return ReturnResult;
+}
+
+
+// ***** Functions for normal operation ************************************
+uint16_t CAN_Rx_readout_Mailbox(CAN_MAILBOX *p_MBox,uint8_t *eight_byte_field) {
+	
+	
+	if( CAN_Read(p_MBox, eight_byte_field) != CAN_ERROR ) {
+		return 1;
+	}
+	else {
+		return 0;
+	}
+	
+}
+
+
+
+// ***** CAN_Tx_MasterXA ********************************************************
+uint16_t CAN_Tx_MasterXA()
+{
+	uint8_t  	Data[8] = {0,0,0,0,0,0,0,0};
+	uint16_t   	ReturnResult = CAN_OK;
+	
+	ReturnResult = CAN_Write( &CAN_TxMB_Master0A, &Data[0] );
+		
+	return ReturnResult;
+}
+
+//uint16_t	CAN0_tx_send_request_telegram(uint8_t slaveNr) {
+//	MASTER_X_BMS_TELEGRAM* tel_ptr=&TelegramTxContainer[slaveNr];
+//	CAN_MAILBOX* mailbox_ptr=MB_Container[slaveNr];
+//	
+//	CAN_Write(mailbox_ptr,&(tel_ptr->Byte[0]));
+//	tel_ptr->Values.MasterAlive++;
+//}
+
+uint16_t	CAN0_tx_send_request_telegram(BMS_CAN0_SLAVE_t* Slave,uint8_t MasterAlive) {
+	// create Slave Tx Telegram
+	Slave->TxTelegram_ptr->Values.BalancingCell0_7=Slave->Balance_Cell_0_7;
+	Slave->TxTelegram_ptr->Values.BalancingCell8_15=Slave->Balance_Cell_8_15;
+	Slave->TxTelegram_ptr->Values.BalancingCell16_23=Slave->Balance_Cell_16_23;
+	Slave->TxTelegram_ptr->Values.MasterAlive= MasterAlive;
+	Slave->TxTelegram_ptr->Values.SetMode=Slave->Set_Mode;
+	// 
+	
+	
+	
+	CAN_Write(Slave->TxMailbox_ptr,&(Slave->TxTelegram_ptr->Byte[0]));
+	
+}
+
+uint16_t	CAN0_is_state_active(uint8_t* activeSlaves,uint8_t nrOfActiveSlaves,uint8_t nrOfCurrentSlave) {
+	uint8_t i;
+	for(i=0;i<nrOfActiveSlaves;i++) {
+		if(activeSlaves[i] == nrOfCurrentSlave) {
+			return TRUE;
+		}
+	}
+	return FALSE;
+	
+}
+
+// ***** CAN_Tx_Balance ********************************************************
+uint16_t CAN_Tx_Balance( uint16_t i)
+{
+	uint32_t	Buffer;
+	uint8_t  	Data[MAX_SLAVES];
+	uint16_t   	ReturnResult = CAN_OK;
+	
+
+	Buffer   = gBSD.Balancer.Balancing_OnOff_Flags[i];
+	Data[0]  = (uint8_t)(Buffer & 0xFF);					//Balancing 0-7
+	Buffer >>= 8;
+	Data[1]  = (uint8_t)(Buffer & 0xFF);					//Balancing 8-15
+	Buffer >>= 8;
+	Data[2]  = (uint8_t)(Buffer & 0xFF);					//Balancing 16-20
+	
+	Data[3]  = gBSD.Balancer.FanCtrl.R[i];					//Luefter
+	
+	Data[4]  = gBSD.Balancer.Relais_OnOff[i];				//Relais
+		
+	//ReturnResult = CAN_Write( &CAN_TxMB_BalancingCtrl_100+i, &Data[0] ); Turned off
+
+	return ReturnResult;
+}
+
+
+
+// ***** check_and_save_Voltage ************************************************
+void check_and_save_Voltage( CAN_MAILBOX *p_MBox, uint16_t SlaveNr, uint16_t SlaveOffset )
+{
+	uint8_t		Data[8];											// Receive Dummy
+	uint16_t	i;													// RowCounter
+	uint16_t	j;													// CellOffset
+	
+	
+	if( CAN_Read(p_MBox, &Data[0] ) != CAN_ERROR )
+	{
+		i = gBSD.w_Voltage;											// RowCounter
+		j = MAX_SLAVE_CELLS * SlaveNr + SlaveOffset * 4;			// CellOffset
+		gBSE.CountVoltage |= ( 1 << ( 6 * SlaveNr + SlaveOffset ) );	// MSG No Bit
+		
+		
+		gBSD.CellVoltage[i][j] = (uint16_t)((Data[0]<<8) + Data[1]);
+		gBSE.ErrorCell[j] = check_Voltage_Border( i, j );	j++;
+		
+		gBSD.CellVoltage[i][j] = (uint16_t)((Data[2]<<8) + Data[3]);
+		gBSE.ErrorCell[j] = check_Voltage_Border( i, j );	j++;
+		
+		gBSD.CellVoltage[i][j] = (uint16_t)((Data[4]<<8) + Data[5]);
+		gBSE.ErrorCell[j] = check_Voltage_Border( i, j );	j++;
+		
+		gBSD.CellVoltage[i][j] = (uint16_t)((Data[6]<<8) + Data[7]);
+		gBSE.ErrorCell[j] = check_Voltage_Border( i, j );
+			
+		if( gBSE.CountVoltage >= MAX_COUNT_MSG_VOLTAGE )			// All Voltage MSG of all Slaves complete
+		{
+			gBSE.CountVoltage = 0;									// restart Voltage MSG Scan
+						
+			gBSD.r_Voltage = i;										// W will be new R
+			i++;													// fetch next row
+			if( i >= MAX_COUNT_VOLTAGE )							// check Overrun write Index
+				i = 0;
+			gBSD.w_Voltage = i;										// new W
+		}
+	}
+}
+
+
+
+// ***** check_and_save_Status *************************************************
+void check_and_save_Status( CAN_MAILBOX *p_MBox, uint16_t SlaveNr )
+{
+	uint8_t		Data[8];
+	uint16_t	i;													// RowCounter
+	uint16_t	j;													// CellOffset
+	
+	
+	if( CAN_Read( p_MBox, &Data[0] ) != CAN_ERROR )
+	{
+		i = gBSD.w_Status;											// RowCounter
+		j = SlaveNr;												// CellOffset
+		gBSE.CountStatus |= ( 1 << SlaveNr );						// MSG No Bit
+		
+		
+		gBSD.Slave_Status[i][j].StatusFlags.R     = (uint16_t)((Data[0]<<8) + Data[1]);
+		gBSD.Slave_Status[i][j].LTC_PEC_FailCount = Data[2];
+		gBSD.Slave_Status[i][j].HeatSink_Temp     = (int8_t)Data[3];
+		gBSD.Slave_Status[i][j].SelfTest_Flags.R  = (uint16_t)((Data[4]<<8) + Data[5]);
+				
+		gBSE.ErrorSlave[j] = check_Status_Border( i, j );
+		
+		if( gBSE.CountStatus >= MAX_COUNT_MSG_STATUS )				// All Status MSG of all Slaves complete
+		{
+			gBSE.CountStatus = 0;									// restart Status MSG Scan
+			
+			gBSD.r_Status = i;										// W will be new R
+			i++;													// fetch next row
+			if( i >= MAX_COUNT_STATUS )								// check Overrun write Index
+				i = 0;		
+			gBSD.w_Status = i;										// new W
+		}
+	}
+}
+
+
+
+// ***** check_and_save_UI *****************************************************
+void check_and_save_UI( CAN_MAILBOX *p_MBox )
+{
+	static 	uint8_t		Data[8];									// Receive Dummy
+			uint8_t		CS;											// Checksum
+			uint16_t	i;											// RowCounter
+	
+				
+	if( CAN_Read( p_MBox, Data ) != CAN_ERROR )
+	{
+		i = gBSD.w_UI;												// RowCounter
+		
+		gBSD.BlockVoltage[i] = (uint16_t)((Data[0]<<8) + Data[1]);
+		gBSD.BlockCurrent[i] = ( int16_t)((Data[2]<<8) + Data[3]);;
+		gBSD.BlockCounter[i] = Data[6];
+		CS		 			 = Data[0] ^ Data[1] ^  Data[2] ^  Data[3] ^ Data[4] ^ Data[5] ^ Data[6] ^ 0x00;
+		
+		gBSE.ErrorBMS = 0;
+		if( Data[7] != CS )
+			gBSE.ErrorBMS |= ERROR_UI_PEC_NOK;
+		
+//!!		gBSE.ErrorBMS |= check_UI_Border( i );
+		
+		if( !gBSE.ErrorBMS )
+		{
+			gBSD.BlockCurrentSum -= gBSD.BlockCurrent[i];			// Integral of Current
+			Data[0] = (uint8_t)((gBSD.BlockCurrentSum & 0xFF000000)>> 24);
+			Data[1] = (uint8_t)((gBSD.BlockCurrentSum & 0x00FF0000)>> 16);
+			Data[2] = (uint8_t)((gBSD.BlockCurrentSum & 0x0000FF00)>> 8);
+			Data[3] = (uint8_t) (gBSD.BlockCurrentSum & 0x000000FF);
+			Fram_S.Flags.B.JobFinished = 0;
+			FRAM_trigger_write(0, &Data[0], 4);
+		}
+		
+        gBSD.r_UI = i;												// W will be new R
+		i++;														// fetch next row
+		if( i == MAX_COUNT_UI )										// check Overrun write Index
+			i = 0;
+		gBSD.w_UI = i;												// new W
+	}
+}
+
+
+
+// ***** check_and_save_Temperature ********************************************
+void check_and_save_Temperature( CAN_MAILBOX *p_MBox, uint16_t SlaveNr, uint16_t SlaveOffset)
+{
+	uint8_t		Data[8];											// Receive Dummy
+	uint16_t	i;													// RowCounter
+	uint16_t	j;													// CellOffset
+	
+
+	if( CAN_Read(p_MBox, Data ) != CAN_ERROR )
+	{
+		i = gBSD.w_Temperature;										// RowCounter
+		j = MAX_SLAVE_CELLS * SlaveNr + SlaveOffset * 8;			// CellOffset
+		gBSE.CountTemperature |= ( 1 << ( 3 * SlaveNr + SlaveOffset ) );	// MSG No Bit
+		
+
+		gBSD.CellTemperature[i][j] = (int8_t) Data[0];
+		gBSE.ErrorCell[j] = check_Temperature_Border( i, j ); j++;
+		
+		gBSD.CellTemperature[i][j] = (int8_t) Data[1];
+		gBSE.ErrorCell[j] = check_Temperature_Border( i, j ); j++;
+		
+		gBSD.CellTemperature[i][j] = (int8_t) Data[2];
+		gBSE.ErrorCell[j] = check_Temperature_Border( i, j ); j++;
+		
+		gBSD.CellTemperature[i][j] = (int8_t) Data[3];
+		gBSE.ErrorCell[j] = check_Temperature_Border( i, j ); j++;
+		
+		gBSD.CellTemperature[i][j] = (int8_t) Data[4];
+		gBSE.ErrorCell[j] = check_Temperature_Border( i, j ); j++;
+		
+		gBSD.CellTemperature[i][j] = (int8_t) Data[5];
+		gBSE.ErrorCell[j] = check_Temperature_Border( i, j ); j++;
+		
+		gBSD.CellTemperature[i][j] = (int8_t) Data[6];
+		gBSE.ErrorCell[j] = check_Temperature_Border( i, j ); j++;
+		
+		gBSD.CellTemperature[i][j] = (int8_t) Data[7];
+		gBSE.ErrorCell[j] = check_Temperature_Border( i, j );
+	
+		if( gBSE.CountTemperature >= MAX_COUNT_MSG_TEMPERATURE )	// All Temperature MSG of all Slaves complete
+		{
+			gBSE.CountTemperature = 0;								// restart Temperature MSG Scan
+			
+			gBSD.r_Temperature = i;									// W will be new R
+			i++;													// fetch next row
+			if( i == MAX_COUNT_TEMPERATURE )						// check Overrun write Index
+				i = 0;
+			gBSD.w_Temperature = i;									// new W
+		}
+	}
+}
+
+
+
+// ***** check_Voltage_Border **************************************************
+int16_t check_Voltage_Border( uint16_t Row, uint16_t Index )
+{
+	int16_t		ReturnResult = CAN_OK;
+	uint16_t	i;
+	uint32_t	Average = 0;
+	
+	
+	if(gCANErrorInsert == 1)                                   //!! 1.5-3
+		gBSD.CellVoltage[Row][Index] = MIN_CELL_VOLTAGE_TEST;
+	
+	if(gCANErrorInsert == 2)                                   //!! 1.5-3  
+		gBSD.CellVoltage[Row][Index] = MAX_CELL_VOLTAGE_TEST;
+	
+		
+	if( gBSD.CellVoltage[Row][Index] < PRE_CELL_LOW_VOLTAGE )
+	{
+		ReturnResult += ERROR_PRE_CELL_LOW_VOLTAGE;
+		gErrorEvent |= EEV__DEGRADATION;
+	}
+			
+	if( gBSD.CellVoltage[Row][Index] > MAX_CELL_VOLTAGE )
+	{
+		ReturnResult += ERROR_MAX_CELL_VOLTAGE;
+		gErrorEvent |= EEV__SHUT_DOWN_CHARGE;
+	}
+	
+	if( gBSD.CellVoltage[Row][Index] < MIN_CELL_VOLTAGE )
+	{
+		ReturnResult += ERROR_MIN_CELL_VOLTAGE;
+		gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+	}
+	
+	if( Row >= MAX_AVE)											// after 4 Rows start delta check
+	{
+		for(i=0; i<MAX_AVE; i++)								
+			Average += gBSD.CellVoltage[Row-i-1][Index];		// add 4 Rows together
+		Average = Average >> MAX_AVE_SHIFT;						// Average of 4 Rows
+		
+		if(gCANErrorInsert == 3)                                   //!! 1.5-3  
+			gBSD.CellVoltage[Row][Index] = DELTA_CELL_VOLTAGE_TEST;
+	
+		if(gBSD.CellVoltage[Row][Index] < ( Average - DELTA_CELL_VOLTAGE ))
+		{
+			ReturnResult += ERROR_DELTA_CELL_VOLTAGE;
+			gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+		}
+		else
+			if( gBSD.CellVoltage[Row][Index] > ( Average + DELTA_CELL_VOLTAGE ) )
+			{
+				ReturnResult += ERROR_DELTA_CELL_VOLTAGE;
+				gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+			}
+	}
+
+	return ReturnResult;
+}
+
+
+
+// ***** check_Status_Border ***************************************************
+int16_t check_Status_Border( uint16_t Row, uint16_t Index )
+{
+	int16_t		ReturnResult = CAN_OK;
+
+	if(gCANErrorInsert == 7)                                   //!! 1.5-3
+		gBSD.Slave_Status[Row][Index].HeatSink_Temp = MAX_HEATSINK_TEMPERATURE_TEST;
+	
+	if( gBSD.Slave_Status[Row][Index].HeatSink_Temp > MAX_HEATSINK_TEMPERATURE )
+	{
+		ReturnResult += ERROR_MAX_HEATSINK_TEMPERATURE;
+		gErrorEvent |= EEV__SHUT_DOWN_CHARGE;
+	}
+	
+	if( gBSD.Slave_Status[Row][Index].StatusFlags.R & 0x7C00 )	// CAN Rx/Tx Overrun/Warning/Passiv
+	{
+		ReturnResult += ERROR_SLAVE_CAN;
+		gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+	}
+	
+	if( gBSD.Slave_Status[Row][Index].StatusFlags.R & 0x0003 )	// LTC1/2 Temperature < -40°C
+	{
+		ReturnResult += ERROR_MIN_LTC_TEMP;
+		gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+	}
+	
+	if( gBSD.Slave_Status[Row][Index].StatusFlags.R & 0x003C )	// LTC1/2 Temperature > +80°C / THSD
+	{
+		ReturnResult += ERROR_MAX_LTC_TEMP;
+		gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+	}
+	
+	if( gBSD.Slave_Status[Row][Index].StatusFlags.R & 0x00C0 )	// LTC TimeOut / PEC_NOK
+	{	
+		ReturnResult += ERROR_SLAVE_PEC;
+		gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+	}
+	
+    if( gBSD.Slave_Status[Row][Index].SelfTest_Flags.R )		// Any SelfTest Error Flag
+	{
+		ReturnResult += ERROR_SLAVE_SELFTEST;
+		gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+	}
+
+	return ReturnResult;
+}
+
+
+
+// ***** check_UI_Border *******************************************************
+int16_t check_UI_Border( uint16_t Row  )
+{
+	uint16_t	Vbat 		 = 0;
+	int16_t		ReturnResult = CAN_OK;
+
+    if(Global_1msCounter > (DELAY_START+DELAY_START) )
+      Vbat = Sum_Cell_Voltage( Row );
+    else
+	  Vbat = 4250;
+    
+	if(gCANErrorInsert == 8)                                   //!! 1.5-3
+		Vbat = MIN_UI_VOLTAGE_TEST;	
+	
+	if(gCANErrorInsert == 9)                                   //!! 1.5-3
+		Vbat = MAX_UI_VOLTAGE_TEST;
+	
+	if( Vbat < MIN_UI_VOLTAGE )
+	{
+		ReturnResult += ERROR_MIN_UI_VOLTAGE;
+		gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+	}
+	else
+		if( Vbat > MAX_UI_VOLTAGE )
+		{
+			ReturnResult += ERROR_MAX_UI_VOLTAGE;
+			gErrorEvent |= EEV__SHUT_DOWN_CHARGE;
+		}
+	
+	if( gBSD.BlockCurrent[Row] < MIN_UI_LOAD_CURRENT )
+	{
+		ReturnResult += ERROR_MIN_UI_CURRENT;			// Load => +
+		gErrorEvent |= EEV__SHUT_DOWN_CHARGE;
+	}
+	else
+		if( gBSD.BlockCurrent[Row] > MAX_UI_DRIVE_CURRENT )
+		{
+			ReturnResult += ERROR_MAX_UI_CURRENT;		// Drive => -
+			gErrorEvent |= EEV__DEGRADATION;
+		}
+	
+	if( Row )
+		if( gBSD.BlockCounter[Row] )
+			if( gBSD.BlockCounter[Row] != (gBSD.BlockCounter[Row-1] + 1) )
+			{
+				ReturnResult += ERROR_UI_PEC_NOK;
+				gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+			}
+
+	return ReturnResult;
+}
+
+
+
+// ***** check_Temperature_Border **********************************************
+int16_t check_Temperature_Border( uint16_t Row, uint16_t Index )
+{
+	int16_t		ReturnResult = CAN_OK;
+	
+	
+	if(gCANErrorInsert == 4)                                   //!! 1.5-3
+		gBSD.CellTemperature[Row][Index] = MAX_CELL_TEMPERATURE_TEST;
+	
+	if(gCANErrorInsert == 5)                                   //!! 1.5-3
+		gBSD.CellTemperature[Row][Index] = MIN_CELL_TEMPERATURE_TEST;
+	
+	if( gBSD.CellTemperature[Row][Index] < MIN_CELL_TEMPERATURE )
+	{
+		ReturnResult += ERROR_MIN_CELL_TEMPERATURE;
+		gErrorEvent |= EEV__SHUT_DOWN_CHARGE;
+	}
+	
+	if( gBSD.CellTemperature[Row][Index] > PRE_CELL_OVERHEAT )
+	{
+		ReturnResult += ERROR_PRE_CELL_OVERHEAT;
+		gErrorEvent |= EEV__DEGRADATION;
+	}
+		
+	if( gBSD.CellTemperature[Row][Index] > MAX_CELL_TEMPERATURE )
+	{
+		ReturnResult += ERROR_MAX_CELL_TEMPERATURE;
+		gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+	}
+	
+	if( Row )													// at last 2 Temperatures to compare
+	{
+		if(gCANErrorInsert == 6)                                //!! 1.5-3
+			gBSD.CellTemperature[Row][Index-1] += DELTA_CELL_TEMPERATURE_TEST;
+		
+		if(gBSD.CellTemperature[Row][Index] < ( gBSD.CellTemperature[Row-1][Index] - DELTA_CELL_TEMPERATURE ))
+		{
+			ReturnResult += ERROR_DELTA_CELL_TEMPERATURE;
+			gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+		}
+		else
+			if( gBSD.CellTemperature[Row][Index] > ( gBSD.CellTemperature[Row-1][Index] + DELTA_CELL_TEMPERATURE ) )
+			{
+				ReturnResult += ERROR_DELTA_CELL_TEMPERATURE;
+				gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+			}
+	}
+
+	return ReturnResult;
+}
+
+
+
+// ***** Sum_Cell_Voltage ******************************************************
+uint16_t Sum_Cell_Voltage( uint16_t Row )
+{
+	uint32_t	ReturnResult = 0;
+	uint16_t	i;
+	
+	for( i=0; i<MAX_CELLS; i++)
+		ReturnResult += (uint32_t)gBSD.CellVoltage[Row][i];
+	
+	ReturnResult /= 100;
+	
+	return (uint16_t)ReturnResult;
+}
+
+
+
+// ***** Test_MAX_LOAD_CELL_VOLTAGE ********************************************
+uint16_t Test_MAX_LOAD_CELL_VOLTAGE( uint16_t Row )
+{
+	uint16_t	ReturnResult = CAN_OK;
+	uint16_t	i;
+	
+	for( i=0; i<MAX_CELLS; i++)
+	{
+		if( gBSD.CellVoltage[Row][i] > MAX_LOAD_CELL_VOLTAGE )
+		{
+			ReturnResult = ERROR_MAX_LOAD_CELL_VOLTAGE;		// one Error is enough
+			break;
+		}
+	}
+	
+	return ReturnResult;
+}
+
+
+
+// ***** Search_MIN_CELL_VOLTAGE ********************************************
+uint16_t Search_MIN_CELL_VOLTAGE( uint16_t Row )
+{
+	uint16_t	ReturnResult = MAX_CELL_VOLTAGE;
+	uint16_t	i;
+	
+	for( i=0; i<MAX_CELLS; i++)
+		if( gBSD.CellVoltage[Row][i] < ReturnResult )
+			ReturnResult = gBSD.CellVoltage[Row][i];
+	
+	return ReturnResult;
+}
+
+
+
+// ***** End BMS_CAN0_Tools.c **************************************************

+ 168 - 0
BMS Master/Sources/BMS_CAN0_gen_test_data.c

@@ -0,0 +1,168 @@
+/*
+ * BMS_CAN0_gen_test_data.c
+ * @brief functions to generate fake values to test startup and error routines without actual CAN commuication
+ *  Created on: May 17, 2016
+ *      Author: uacqk
+ */
+
+
+
+#include "BMS_Master.h"
+/*
+ * @brief function to generate a fake slave with fake data
+ * @param s pointer to fake slave structure
+ * @param default_voltage voltage to initialize cells
+ * @param default_temperature to initialize cells
+ * @param default_UBat voltage measured by UI-Board
+ * @param default_UBat current measured by UI-Board
+ */
+void gen_data_initSlave(MASTER_CAN0_STRUCT_t* s, uint16_t default_voltage, int8_t default_temperature, uint16_t default_Ubat, uint16_t default_Ibat) {
+	uint8_t slaveNr=0;
+	uint8_t cellNr=0;
+	uint8_t telegramNr=0;
+	BMS_CAN0_SLAVE_t* Slave;
+	for(slaveNr=0;slaveNr<CAN0_MAX_NR_OF_SLAVES;slaveNr++) {
+		Slave=&(s->Slave[slaveNr]);
+		for(cellNr=0;cellNr<MAX_SLAVE_CELLS;cellNr++) {
+			Slave->CellVoltage[cellNr]=default_voltage;
+			Slave->CellTemp[cellNr]=default_temperature;
+		}
+		for(telegramNr=0;telegramNr<CAN0_NR_OF_TELEGRAMS;telegramNr++) {
+			Slave->SlaveAliveCnt[telegramNr]=0;
+		}
+		Slave->HeatSinkTemp=default_temperature;
+		Slave->Set_Mode=BMS_SLAVE_RUN;
+		Slave->SlaveError=0;
+		Slave->SlaveMode=BMS_SLAVE_RUN;
+		Slave->MuxCounter=0;
+
+	}
+	s->UI_Board.Checksum=0;
+	s->UI_Board.Ubatt=default_Ubat;
+	s->UI_Board.Ibatt=default_Ibat;		
+}
+
+void gen_data_setUbatt(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t slaveNr=0;
+	BMS_CAN0_SLAVE_t* Slave;
+	uint16_t Uges=0;
+	uint8_t cellNr=0;
+	for(slaveNr=0;slaveNr<CAN0_MAX_NR_OF_SLAVES-1;slaveNr++){
+		
+		if(s->Slave[slaveNr].SlaveConnectionState != NOT_CONNECTED) {
+			Slave=&(s->Slave[slaveNr]);
+			for(cellNr=0;cellNr<MAX_SLAVE_CELLS;cellNr++) {
+				if(Slave->CellConnectionState[cellNr]==CELL_CONNECTED) {
+					Uges+=Slave->CellVoltage[cellNr];
+				}
+			}
+		}
+	}
+	s->UI_Board.Ubatt=Uges;
+}
+
+/*
+ * @brief function to fill CAN RX Buffer 0 with test data
+ * @param	s pointer to test data
+ * @param   rx_ptr pointer to data receive Buffer
+ */
+void gen_data_generate_CAN0_RX0_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X0_5_BMS_TELEGRAM* rx_ptr) {
+
+
+	rx_ptr->SlaveAlive=(Slave->SlaveAliveCnt[0]);
+	rx_ptr->Vcell0=Slave->CellVoltage[0] >> 3;
+	rx_ptr->Vcell1=Slave->CellVoltage[1];
+	rx_ptr->Vcell2=Slave->CellVoltage[2];
+	rx_ptr->Vcell3=Slave->CellVoltage[3];
+}
+
+/*
+ * @brief function to fill CAN RX Buffer 0 with test data
+ * @param	s pointer to test data
+ * @param   rx_ptr pointer to data receive Buffer
+ */
+void gen_data_generate_CAN0_RX1_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X0_5_BMS_TELEGRAM* rx_ptr) {
+	rx_ptr->SlaveAlive=Slave->SlaveAliveCnt[1];
+	rx_ptr->Vcell0=Slave->CellVoltage[4] >> 3;
+	rx_ptr->Vcell1=Slave->CellVoltage[5];
+	rx_ptr->Vcell2=Slave->CellVoltage[6];
+	rx_ptr->Vcell3=Slave->CellVoltage[7];
+}
+/*
+ * @brief function to fill CAN RX Buffer 0 with test data
+ * @param	s pointer to test data
+ * @param   rx_ptr pointer to data receive Buffer
+ */
+void gen_data_generate_CAN0_RX2_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X0_5_BMS_TELEGRAM* rx_ptr) {
+	rx_ptr->SlaveAlive=Slave->SlaveAliveCnt[2];
+	rx_ptr->Vcell0=Slave->CellVoltage[8] >> 3;
+	rx_ptr->Vcell1=Slave->CellVoltage[9];
+	rx_ptr->Vcell2=Slave->CellVoltage[10];
+	rx_ptr->Vcell3=Slave->CellVoltage[11];
+}
+/*
+ * @brief function to fill CAN RX Buffer 0 with test data
+ * @param	s pointer to test data
+ * @param   rx_ptr pointer to data receive Buffer
+ */
+void gen_data_generate_CAN0_RX3_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X0_5_BMS_TELEGRAM* rx_ptr) {
+	rx_ptr->SlaveAlive=Slave->SlaveAliveCnt[3];
+	rx_ptr->Vcell0=Slave->CellVoltage[12]>> 3;
+	rx_ptr->Vcell1=Slave->CellVoltage[13];
+	rx_ptr->Vcell2=Slave->CellVoltage[14];
+	rx_ptr->Vcell3=Slave->CellVoltage[15];
+}
+
+/*
+ * @brief function to fill CAN RX Buffer 0 with test data
+ * @param	s pointer to test data
+ * @param   rx_ptr pointer to data receive Buffer
+ */
+void gen_data_generate_CAN0_RX4_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X0_5_BMS_TELEGRAM* rx_ptr) {
+	rx_ptr->SlaveAlive=Slave->SlaveAliveCnt[4];
+	rx_ptr->Vcell0=Slave->CellVoltage[16]>> 3;
+	rx_ptr->Vcell1=Slave->CellVoltage[17];
+	rx_ptr->Vcell2=Slave->CellVoltage[18];
+	rx_ptr->Vcell3=Slave->CellVoltage[19];
+}
+
+/*
+ * @brief function to fill CAN RX Buffer 0 with test data
+ * @param	s pointer to test data
+ * @param   rx_ptr pointer to data receive Buffer
+ */
+void gen_data_generate_CAN0_RX5_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X0_5_BMS_TELEGRAM* rx_ptr) {
+	rx_ptr->SlaveAlive=Slave->SlaveAliveCnt[5];
+	rx_ptr->Vcell0=Slave->CellVoltage[20]>> 3;
+	rx_ptr->Vcell1=Slave->CellVoltage[21];
+	rx_ptr->Vcell2=Slave->CellVoltage[22];
+	rx_ptr->Vcell3=Slave->CellVoltage[23];
+}
+
+void gen_data_generate_CAN0_RX6_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X6_BMS_TELEGRAM* rx_ptr) {
+	rx_ptr->SlaveAlive=Slave->SlaveAliveCnt[6];
+	rx_ptr->SlaveError=Slave->SlaveError;
+	rx_ptr->SlaveMode=Slave->SlaveMode;
+}
+
+void gen_data_generate_CAN0_RX7_Telegram(BMS_CAN0_SLAVE_t* Slave,SLAVE_X7_BMS_TELEGRAM* rx_ptr) {
+	uint8_t MuxCounter=rx_ptr->MuxCounter;
+	rx_ptr->SlaveAlive=Slave->SlaveAliveCnt[7];
+	rx_ptr->TempHeatSink=Slave->HeatSinkTemp;
+	rx_ptr->TempSens0=Slave->CellTemp[MuxCounter*4+0];
+	rx_ptr->TempSens1=Slave->CellTemp[MuxCounter*4+1];
+	rx_ptr->TempSens2=Slave->CellTemp[MuxCounter*4+2];
+	rx_ptr->TempSens3=Slave->CellTemp[MuxCounter*4+3];	                            
+}
+
+
+
+void gen_data_generate_CAN0_UI_Telegram(BMS_CAN0_SLAVE_t* Slave,BMS_CAN0_UI_t* UI_Board,SLAVE_UI_BMS_TELEGRAM* rx_ptr){
+	rx_ptr->Checksum=UI_Board->Checksum;
+	rx_ptr->Ibatt=UI_Board->Ibatt;
+	rx_ptr->Ubatt=UI_Board->Ubatt;
+	rx_ptr->UIAlive=Slave->SlaveAliveCnt[0];
+	rx_ptr->UIMode=Slave->SlaveMode;
+
+}
+

+ 212 - 0
BMS Master/Sources/BMS_CAN1_Mail_Box.c

@@ -0,0 +1,212 @@
+///##############################################################################
+//
+// FILE:	BMS_CAN1_Mail_Box.c
+//
+// TITLE:	CAN 1 
+//			- Module Configuration
+//			- Mailbox Definition
+//			- Mailbox Load 
+//				uint16_t CAN1_init		( void )
+//			- Mailbox Check
+//				uint16_t CAN1_update	( void )
+//
+//
+//##############################################################################
+//
+//==============================================================================
+// Change History:
+//==============================================================================
+// Datum:   | Name | Version:| Change / Cause:                            | No
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 002
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 001
+//------------------------------------------------------------------------------
+// 31.07.13 |  VR  |   1.0   | New Build                                  | 000
+//==============================================================================
+//==============================================================================
+// Comment Change / Cause:
+//==============================================================================
+// Change: 003                                                           // 003
+//----------------------
+//                                                       
+//
+//==============================================================================
+// Change: 002                                                           // 002
+//----------------------
+//                                           
+//
+//==============================================================================
+// Change: 001                                                           // 001
+//----------------------
+// 
+//
+//==============================================================================
+
+#include "BMS_Master.h"
+
+
+
+// ****** Config CAN Modul ********************************************************
+CAN_CONFIG CAN_1_Config = {
+	&CAN_1,
+	CAN1_PortC10_11,
+	TxPushPull,         //enum {TxPushPull=0,Tx_OpenDrain}	TxPortType;
+	RxMask_Individual,	//RxMaskType
+	0xFFFFFFFF,			//uint32_t GlobalRxMask
+	CANBaud_500kHz_OSC_40MHz
+};
+
+
+
+// ****** MailBox BMS to RCT Inverter 0 *************************************************
+CAN_MAILBOX CAN_Tx0_RCT_INVERTER = {
+	&CAN_1_Config,
+	0,			// uint8_t MBNumber		//0..15
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x100		// ID
+};
+
+// ****** MailBox BMS to RCT Inverter 1 *************************************************
+CAN_MAILBOX CAN_Tx1_RCT_INVERTER = {
+	&CAN_1_Config,
+	1,			// uint8_t MBNumber		//0..15
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x101		// ID
+};
+
+// ****** MailBox RCT Inverter  *************************************************
+CAN_MAILBOX CAN_Rx_RCT_INVERTER = {
+	&CAN_1_Config,
+	2,			// uint8_t MBNumber		//0..15
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	SHORT_ID,	// 11 Bit ID
+	0x102		// ID
+};
+
+
+
+
+// ***** CAN1_init *************************************************************
+uint16_t CAN1_init( void )
+{
+	uint16_t ReturnVal = CAN_OK;
+	
+	if(CAN_Init(&CAN_1_Config) == CAN_OK) 
+	{
+		ReturnVal += CAN_Init_Mailbox( &CAN_Tx0_RCT_INVERTER);		
+		ReturnVal += CAN_Init_Mailbox( &CAN_Tx1_RCT_INVERTER);
+		ReturnVal += CAN_Init_Mailbox( &CAN_Rx_RCT_INVERTER);
+	}
+	return ReturnVal;
+}
+
+uint16_t CAN1_init_tx_structure(BMS_CAN1_INVERTER_TX* tx_struct) {
+	tx_struct->Values.maxBatteryChargeCurrent.valueId		=CAN1_TX_MAX_BATTERY_CHARGE_CURRENT_ID;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.maxBatteryChargeCurrent.valueId));
+	tx_struct->Values.maxBatteryChargeCurrent.value			=0;
+	
+	tx_struct->Values.maxBatteryChargeVoltage.valueId		=CAN1_TX_MAX_BATTERY_CHARGE_VOLTAGE_ID;	
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.maxBatteryChargeVoltage.valueId));
+	tx_struct->Values.maxBatteryChargeVoltage.value			=0;
+	
+	tx_struct->Values.minBatteryDischargeVoltage.valueId	=CAN1_TX_MIN_BATTERY_DISCHARGE_VOLTAGE_ID;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.minBatteryDischargeVoltage.valueId));
+	tx_struct->Values.minBatteryDischargeVoltage.value		=0;
+	
+	tx_struct->Values.maxBatteryDischargeCurrent.valueId	=CAN1_TX_MAX_BATTERY_DISCHARGE_CURRENT_ID;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.maxBatteryDischargeCurrent.valueId));
+	tx_struct->Values.maxBatteryDischargeCurrent.value		=0;
+	
+	tx_struct->Values.batteryCurrent.valueId				=CAN1_TX_BATTERY_CURRENT_ID;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.batteryCurrent.valueId));
+	tx_struct->Values.batteryCurrent.value					=0;
+	
+	tx_struct->Values.batteryCapacity.valueId				=CAN1_TX_BATTERY_CAPACITY	;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.batteryCapacity.valueId));
+	tx_struct->Values.batteryCapacity.value					=0;
+	
+	tx_struct->Values.batterySOC.valueId					=CAN1_TX_BATTERY_SOC_ID;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.batterySOC.valueId));
+	tx_struct->Values.batterySOC.value						=0;
+	
+	tx_struct->Values.batterySOCtarget.valueId				=CAN1_TX_BATTERY_SOC_TARGET_ID;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.batterySOCtarget.valueId));
+	tx_struct->Values.batterySOCtarget.value				=0;
+	
+	tx_struct->Values.batterySOH.valueId					=CAN1_TX_BATTERY_SOH;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.batterySOH.valueId));
+	tx_struct->Values.batterySOH.value						=0;
+	
+	tx_struct->Values.batteryVoltage.valueId				=CAN1_TX_BATTERY_VOLTAGE_ID;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.batteryVoltage.valueId));
+	tx_struct->Values.batteryVoltage.value					=0;
+	
+	tx_struct->Values.batteryTemperature.valueId			=CAN1_TX_BATTERY_TEMPERATURE;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.batteryTemperature.valueId));
+	tx_struct->Values.batteryTemperature.value				=0;		
+	
+	tx_struct->Values.batteryStatus.valueId					=CAN1_TX_BATTERY_STATUS;	
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.batteryStatus.valueId	));
+	tx_struct->Values.batteryStatus.globalBatteryStatus		=0;
+	tx_struct->Values.batteryStatus.errorCode				=0;
+	tx_struct->Values.batteryStatus.byte6					=0;
+	tx_struct->Values.batteryStatus.byte7					=0;
+	
+	tx_struct->Values.batteryMode.valueId					=CAN1_TX_BATTERY_MODE;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.batteryMode.valueId));
+	tx_struct->Values.batteryMode.value						=0;
+	
+	tx_struct->Values.batteryModeExtra.valueId				=CAN1_TX_BATTERY_STATUS_EXTRA;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.batteryModeExtra.valueId));
+	tx_struct->Values.batteryModeExtra.value						=1;
+	shuffle_lsb_msb_can1((uint8_t*)&(tx_struct->Values.batteryModeExtra.value));
+}
+
+
+
+// ***** CAN1_update ***********************************************************
+uint16_t CAN1_update( void )
+{
+// ****** MailBox BRUSA to BMS *************************************************
+//	if( CHECKBIT( CAN_1.IFRL.R, 1 )) {							// NLG5_ST 		0x610
+//		SETBIT( CAN_1.IFRL.R, 1 );								// IFR clear
+//		check_and_save_NLG5_ST( &CAN_RxMB_NLG5_ST_610 );
+//	}
+//	 
+//	if( CHECKBIT( CAN_1.IFRL.R, 2 )) {							// NLG5_ACT_I 	0x611
+//		SETBIT( CAN_1.IFRL.R, 2 );								// IFR clear
+//	}
+//	
+//	if( CHECKBIT( CAN_1.IFRL.R, 3 )) {							// NLG5_ACT_II 	0x612
+//	 	SETBIT( CAN_1.IFRL.R, 3 );								// IFR clear
+//	}
+// 
+//	if( CHECKBIT( CAN_1.IFRL.R, 4 )) {							// NLG5_TEMP 	0x613
+//		SETBIT( CAN_1.IFRL.R, 4 );								// IFR clear
+//	}
+//	 
+//	if( CHECKBIT( CAN_1.IFRL.R, 5 )) {							// NLG5_ERR 	0x614
+//		SETBIT( CAN_1.IFRL.R, 5 );								// IFR clear
+//	}
+	
+	return CAN_OK;
+}
+
+
+
+// ***** End BMS_CAN1_Mail_Box.c ***********************************************

+ 163 - 0
BMS Master/Sources/BMS_CAN1_Tools.c

@@ -0,0 +1,163 @@
+///##############################################################################
+//
+// FILE:	BMS_CAN1_Tools.c
+//
+// TITLE:	CAN 1 
+//			CAN_Tx_NLG5_CTL_618
+//			check_and_save_NLG5_ST
+//
+//
+//##############################################################################
+//
+//==============================================================================
+// Change History:
+//==============================================================================
+// Datum:   | Name | Version:| Change / Cause:                            | No
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 002
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 001
+//------------------------------------------------------------------------------
+// 31.07.13 |  VR  |   1.0   | New Build                                  | 000
+//==============================================================================
+//==============================================================================
+// Comment Change / Cause:
+//==============================================================================
+// Change: 003                                                           // 003
+//----------------------
+//                                                       
+//
+//==============================================================================
+// Change: 002                                                           // 002
+//----------------------
+//                                           
+//
+//==============================================================================
+// Change: 001                                                           // 001
+//----------------------
+// 
+//
+//==============================================================================
+
+#include "BMS_Master.h"
+
+
+//quick and dirty loesung
+//extern CAN_MAILBOX CAN_Tx0_RCT_INVERTER;
+//extern CAN_MAILBOX CAN_Tx1_RCT_INVERTER; 
+//extern CAN_MAILBOX CAN_Rx_RCT_INVERTER;
+
+// ***** CAN_Tx_NLG5_CTL ********************************************************
+uint16_t CAN_Tx_NLG5_CTL_618( void )
+{
+	uint8_t  	Data[7];
+	uint16_t   	ReturnResult = CAN_OK;
+
+
+	Data[0]  = (uint8_t)(0x80);										// CAN enable
+	Data[1]  = (uint8_t)((NLG5_MAINS_CURRENT >> 8) & 0xFF);			// Mains Current Maximum
+	Data[2]  = (uint8_t)(NLG5_MAINS_CURRENT & 0xFF);				
+	Data[3]  = (uint8_t)((NLG5_OUTPUT_VOLTAGE >> 8) & 0xFF);			// Output Voltage Command
+	Data[4]  = (uint8_t)(NLG5_OUTPUT_VOLTAGE & 0xFF);				
+	Data[5]  = (uint8_t)((NLG5_OUTPUT_CURRENT >> 8) & 0xFF);			// Output Current Command
+	Data[6]  = (uint8_t)(NLG5_OUTPUT_CURRENT & 0xFF);				
+		
+	//ReturnResult = CAN_Write( &CAN_TxMB_NLG5_CTL_618, &Data[0] );
+
+	return ReturnResult;
+}
+
+int16_t CAN1_tx_Data_to_Inverter(uint32_t timestamp,BMS_CAN1_INVERTER_TX* data) {
+	int16_t   	ReturnResult = CAN_OK;
+	//uint8_t		test[8]= {0,0,0,0,0,0,0,0};
+	ReturnResult +=CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.maxBatteryChargeCurrent),Global_1msCounter);
+	ReturnResult +=CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.maxBatteryChargeVoltage),Global_1msCounter);
+	ReturnResult +=CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.maxBatteryDischargeCurrent),Global_1msCounter);
+	ReturnResult +=CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.minBatteryDischargeVoltage),Global_1msCounter);
+	ReturnResult +=CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batteryCurrent),Global_1msCounter);
+	ReturnResult +=CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batteryVoltage),Global_1msCounter);
+	ReturnResult +=CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batterySOCtarget),Global_1msCounter);
+	ReturnResult +=CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batterySOC),Global_1msCounter);
+	ReturnResult +=CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batteryCapacity),Global_1msCounter);
+	ReturnResult +=CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batteryTemperature),Global_1msCounter);
+	ReturnResult +=CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batterySOH),Global_1msCounter);
+	ReturnResult +=CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batteryStatus),Global_1msCounter);
+	//ReturnResult =CAN_Write(&CAN_Tx0_RCT_INVERTER,test);
+	return ReturnResult;
+}
+
+uint32_t delay_CAN1_ms(uint32_t timestamp,uint32_t delay_ms) {
+	while(timestamp + delay_ms >Global_1msCounter) {
+		// do nothing
+	}
+	return Global_1msCounter;
+}
+
+int16_t CAN1_request_float_value(uint32_t timestamp,float* value,uint32_t requestId) {
+	static BMS_CAN1_INVERTER_REQUEST request_telegram;
+	static BMS_CAN1_INVERTER_FLOAT_t received_telegram;	
+	int16_t   	ReturnResult = CAN_OK;
+	request_telegram.valueId=CAN1_TX_REQUESTED_VALUE_ID_ID ;
+	request_telegram.requestId=requestId;
+	ReturnResult =CAN_Write(&CAN_Tx1_RCT_INVERTER, (uint8_t*)&request_telegram);
+	if(ReturnResult != CAN_OK) {
+		return CAN_ERROR;
+	}
+	// wait 2ms for response
+	while(timestamp + CAN1_TX_TIMEOUT >= Global_1msCounter) {
+		if(CHECKBIT( CAN_1.IFRL.R, 2 )) {
+			// answer received
+			ReturnResult = CAN_Read(&CAN_Rx_RCT_INVERTER, (uint8_t*)&received_telegram);
+			*value=received_telegram.value;
+			return CAN_OK;
+		}
+	return CAN_ERROR;	
+	}
+}
+
+int16_t CAN1_send_request_telegram(uint32_t requestId) {
+	static BMS_CAN1_INVERTER_REQUEST request_telegram;
+	int16_t   	ReturnResult = CAN_OK;
+	request_telegram.valueId=CAN1_TX_REQUESTED_VALUE_ID_ID ;
+	request_telegram.requestId=requestId;
+	
+	shuffle_lsb_msb_can1((uint8_t*)&(request_telegram.valueId));
+	shuffle_lsb_msb_can1((uint8_t*)&(request_telegram.requestId));
+	ReturnResult =CAN_Write(&CAN_Tx1_RCT_INVERTER, (uint8_t*)&request_telegram);
+	return ReturnResult;
+}
+
+uint16_t CAN1_wait_for_response(float* value) {
+	static BMS_CAN1_INVERTER_FLOAT_t received_telegram;	
+	int16_t   	ReturnResult = CAN_OK;
+	if(CHECKBIT( CAN_1.IFRL.R, 2 )) {
+		// answer received
+		ReturnResult = CAN_Read(&CAN_Rx_RCT_INVERTER, (uint8_t*)&received_telegram);
+		shuffle_lsb_msb_can1((uint8_t*)&(received_telegram.value));
+		*value=received_telegram.value;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
+
+// ***** check_and_save_NLG5_ST ************************************************
+void check_and_save_NLG5_ST( CAN_MAILBOX *p_MBox )
+{
+	uint8_t		Data[8];											// Receive Dummy
+	NLG5_ST_t	gNLG5_ST;
+	
+	
+	if( CAN_Read(p_MBox, &Data[0] ) != CAN_ERROR )
+	{
+		gNLG5_ST.NLG5_STB1.R = ( uint8_t )Data[0];
+		gNLG5_ST.NLG5_STB2.R = ( uint8_t )Data[1];
+		gNLG5_ST.NLG5_STB3.R = ( uint8_t )Data[2];
+		gNLG5_ST.NLG5_STB4   =            Data[3];
+	}
+}
+
+
+
+// ***** End BMS_CAN1_Tools.c **************************************************

+ 172 - 0
BMS Master/Sources/BMS_CAN2_Mail_Box.c

@@ -0,0 +1,172 @@
+///##############################################################################
+//
+// FILE:	BMS_CAN2_Mail_Box.c
+//
+// TITLE:	CAN 2 
+//			- Module Configuration
+//			- Mailbox Definition
+//			- Mailbox Load 
+//				uint16_t CAN2_init		( void )
+//			- Mailbox Check
+//				uint16_t CAN2_update	( void )
+//
+//
+//##############################################################################
+//
+//==============================================================================
+// Change History:
+//==============================================================================
+// Datum:   | Name | Version:| Change / Cause:                            | No
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 002
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 001
+//------------------------------------------------------------------------------
+// 31.07.13 |  VR  |   1.0   | New Build                                  | 000
+//==============================================================================
+//==============================================================================
+// Comment Change / Cause:
+//==============================================================================
+// Change: 003                                                           // 003
+//----------------------
+//                                                       
+//
+//==============================================================================
+// Change: 002                                                           // 002
+//----------------------
+//                                           
+//
+//==============================================================================
+// Change: 001                                                           // 001
+//----------------------
+// 
+//
+//==============================================================================
+
+#include "BMS_Master.h"
+
+
+
+// ****** Config CAN Modul ********************************************************
+CAN_CONFIG CAN_2_Config = {
+	&CAN_2,
+	CAN2_PortE8_9,
+	TxPushPull,         //enum {TxPushPull=0,Tx_OpenDrain}	TxPortType;
+	RxMask_Individual,	//RxMaskType
+	0xFFFFFFFF,		//uint32_t GlobalRxMask
+	CANBaud_250kHz_OSC_40MHz
+};
+
+
+
+// ****** MailBox BMU_DICO *****************************************************
+CAN_MAILBOX CAN_TxMB_BMU_DICO_18FF9F1E = {
+	&CAN_2_Config,
+	0,			// uint8_t MBNumber		//0..15
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	LONG_ID,	// 29 Bit ID
+	0x18FF9F1E	// ID
+};
+
+// ****** MailBox BMU1_EVCU1 ***************************************************
+CAN_MAILBOX CAN_TxMB_BMU1_EVCU1_18FF9E1E = {
+	&CAN_2_Config,
+	1,			// uint8_t MBNumber		//0..15
+	MB_Tx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	4,			// uint8_t DataBytes
+	0,			// uint8_t InterruptEnable
+	0xFFFFFFFF,	// uint32_t AcceptMask
+	LONG_ID,	// 29 Bit ID
+	0x18FF9E1E	// ID
+};
+
+
+
+// ****** MailBox DICO1_EVCU ***************************************************
+CAN_MAILBOX CAN_RxMB_DICO1_EVCU_18FF8F03 = {
+	&CAN_2_Config,
+	2,			// uint8_t MBNumber		//0..15
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFFFFFFFF, // uint32_t AcceptMask
+	LONG_ID,	// 29 Bit ID
+	0x18FF8F03	// ID
+};
+
+// ****** MailBox DICO2_EVCU ***************************************************
+CAN_MAILBOX CAN_RxMB_DICO2_EVCU_18FF8D03 = {
+	&CAN_2_Config,
+	3,			// uint8_t MBNumber		//0..15
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes
+	0,			// uint8_t Interrupt
+	0xFFFFFFFF, // uint32_t AcceptMask
+	LONG_ID,	// 29 Bit ID
+	0x18FF8D03	// ID
+};
+
+// ****** MailBox EVCU1_BMU ***************************************************
+CAN_MAILBOX CAN_RxMB_EVCU1_BMU_0CFF3D27 = {
+	&CAN_2_Config,
+	4,			// uint8_t MBNumber		//0..15
+	MB_Rx,		// uint8_t Direction
+	0,			// uint8_t RemoteEn
+	8,			// uint8_t DataBytes   //!! 1.5-0 // von 2 auf 8 wegen BaSyTec
+	0,			// uint8_t Interrupt
+	0xFFFFFFFF, // uint32_t AcceptMask
+	LONG_ID,	// 29 Bit ID
+	0x0CFF3D27	// ID
+};
+
+
+
+// ***** CAN2_init *************************************************************
+uint16_t CAN2_init( void )
+{
+	uint16_t ReturnVal = CAN_OK;
+	
+	if( CAN_Init(&CAN_2_Config) == CAN_OK ) 
+	{
+		ReturnVal += CAN_Init_Mailbox(&CAN_TxMB_BMU_DICO_18FF9F1E);
+		ReturnVal += CAN_Init_Mailbox(&CAN_TxMB_BMU1_EVCU1_18FF9E1E);
+		
+		ReturnVal += CAN_Init_Mailbox(&CAN_RxMB_DICO1_EVCU_18FF8F03);
+		ReturnVal += CAN_Init_Mailbox(&CAN_RxMB_DICO2_EVCU_18FF8D03);
+		ReturnVal += CAN_Init_Mailbox(&CAN_RxMB_EVCU1_BMU_0CFF3D27);
+	}
+	return ReturnVal;
+}
+
+
+
+// ***** CAN2_update ***********************************************************
+uint16_t CAN2_update( void )
+{
+	if( CHECKBIT( CAN_2.IFRL.R, 2 )) {							// DICO1 EVCU 0x18FF8F03
+		SETBIT( CAN_2.IFRL.R, 2 );								// IFR clear
+		check_and_save_DICO1_EVCU( &CAN_RxMB_DICO1_EVCU_18FF8F03 );
+	}
+	 
+	if( CHECKBIT( CAN_2.IFRL.R, 3 )) {							// DICO2 EVCU 0x18FF8D03
+		SETBIT( CAN_2.IFRL.R, 3 );								// IFR clear
+		check_and_save_DICO2_EVCU( &CAN_RxMB_DICO2_EVCU_18FF8D03 );
+	}
+	
+	if( CHECKBIT( CAN_2.IFRL.R, 4 )) {							// EVCU1 BMU 0x0CFF3D27
+	 	SETBIT( CAN_2.IFRL.R, 4 );								// IFR clear
+	 	check_and_save_EVCU1_BMU( &CAN_RxMB_EVCU1_BMU_0CFF3D27 );
+	}
+	return CAN_OK;
+}
+
+
+
+// ***** End BMS_CAN2_Mail_Box.c ***********************************************

+ 220 - 0
BMS Master/Sources/BMS_CAN2_Tools.c

@@ -0,0 +1,220 @@
+///##############################################################################
+//
+// FILE:	BMS_CAN2_Tools.c
+//
+// TITLE:	CAN 2 
+//			CAN_Tx_BMU_DICO
+//			CAN_Tx_BMU1_EVCU1
+//			check_and_save_Status
+//			check_and_save_UI
+//			check_and_save_Temperature
+//			check_Voltage_Border
+//			check_Status_Border
+//			check_UI_Border
+//			check_Temperature_Border
+//			Sum_Cell_Voltage
+//			Test_MAX_LOAD_CELL_VOLTAGE
+//			Search_MIN_CELL_VOLTAGE
+//			Test_Slave_Presents
+//
+//
+//##############################################################################
+//
+//==============================================================================
+// Change History:
+//==============================================================================
+// Datum:   | Name | Version:| Change / Cause:                            | No
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 002
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 001
+//------------------------------------------------------------------------------
+// 31.07.13 |  TM  |   1.0   | New Build                                  | 000
+//==============================================================================
+//==============================================================================
+// Comment Change / Cause:
+//==============================================================================
+// Change: 003                                                           // 003
+//----------------------
+//                                                       
+//
+//==============================================================================
+// Change: 002                                                           // 002
+//----------------------
+//                                           
+//
+//==============================================================================
+// Change: 001                                                           // 001
+//----------------------
+// 
+//
+//==============================================================================
+
+#include "BMS_Master.h"
+extern asm void __startup(register int argc, register char **argv, register char **envp);
+
+
+
+
+
+
+// ***** CAN_Tx_BMU1_EVCU1 *******************************************************
+uint16_t CAN_Tx_BMU1_EVCU1( void )
+{
+	uint8_t  	Data[4];
+	uint16_t   	ReturnResult = CAN_OK;
+	uint16_t    gISO_R_Dummy;
+	
+	
+	Data[0] = MF__STANDBY;										// Default Mode: StandBy
+		
+	if( gEvent >= EV__DRIVE_START_1 )
+		if( gEvent <= EV__SHUT_DOWN_DRIVE )
+			Data[0] = MF__DRIVE;								// Drive
+	
+	if( gEvent >= EV__CHARGE )
+		if( gEvent <= EV__SHUT_DOWN_CHARGE )
+			Data[0] = MF__CHARGE;								// Charge
+	
+	if( gErrorEvent )
+		Data[0] = MF__ERROR;									// Error	
+			
+	Data[1] = 0;
+	if( gBSD.BlockVoltage[gBSD.r_UI] > 4608 )					// 70% MAX_UI_VOLTAGE
+		Data[1] |= MF__END_OF_CHARGE;							// End of Charge
+
+
+//  Erweiterung ISO in BMUI_EVCU
+	
+    gISO_R_Dummy = (unsigned short)(gISO_R >> 1);				// ISO/2 cause 2^17 Bit
+    Data[2]      = (unsigned char)gISO_R_Dummy;			       	// Low Byte first		
+    Data[3]      = (unsigned char)(gISO_R_Dummy >> 8);          // High Byte second
+	
+	//ReturnResult = CAN_Write( &CAN_TxMB_BMU1_EVCU1_18FF9E1E, &Data[0] );
+
+	return ReturnResult;
+}
+
+
+
+// ***** check_and_save_DICO1_EVCU *********************************************
+uint16_t check_and_save_DICO1_EVCU( CAN_MAILBOX *p_MBox )
+{
+	uint8_t			Data[8];									// Receive Dummy
+	DICO1_EVCU_t	DICO1_EVCU;
+	
+	if( CAN_Read(p_MBox, &Data[0] ) != CAN_ERROR )
+	{
+		DICO1_EVCU.b_StatusByte_1_DCU.R 		= Data[0];
+		DICO1_EVCU.b_StatusByte_2_DCU.R 		= Data[1];
+		DICO1_EVCU.rpmSys						= (uint16_t)((Data[2]<<8) + Data[3]);
+		DICO1_EVCU.tqRefSys 					= Data[4];
+		DICO1_EVCU.tqSys 						= Data[5];
+		DICO1_EVCU.powerBR_fb 					= Data[6];
+		DICO1_EVCU.b_ErrorBufferIndication.R	= Data[7];
+		
+		if( gEvent == EV__STAND_BY )							// switch out of StandBy only
+		{
+			if( DICO1_EVCU.b_StatusByte_2_DCU.B.b_PC_Rq )		// PreCharge Contractor Request
+				gEvent = EV__DRIVE_START_1;
+				
+			if( DICO1_EVCU.b_StatusByte_2_DCU.B.b_MC_Rq )		// Main Contractor Request
+				gEvent = EV__DRIVE_START_3;
+		}
+	}	
+}
+
+
+
+// ***** check_and_save_DICO2_EVCU *********************************************
+uint16_t check_and_save_DICO2_EVCU( CAN_MAILBOX *p_MBox )
+{
+	uint8_t			Data[8];									// Receive Dummy
+	DICO2_EVCU_t	DICO2_EVCU;
+	
+	if( CAN_Read(p_MBox, &Data[0] ) != CAN_ERROR )
+	{
+		DICO2_EVCU.b_DiagnosticInverter1.R	= Data[0];
+		DICO2_EVCU.b_DiagnosticInverter2.R	= Data[1];
+		DICO2_EVCU.b_DiagnosticInverter3.R	= Data[2];
+		DICO2_EVCU.b_Current_HEV_Mode.R		= Data[3];
+		DICO2_EVCU.powerGenerator1Fb 		= (uint16_t)((Data[4]<<8) + Data[5]);
+		DICO2_EVCU.rpmGenerator1Fb			= (uint16_t)((Data[6]<<8) + Data[7]);
+		
+		if( DICO2_EVCU.b_DiagnosticInverter2.B.emergency_MC_Off )	// Emergency Main Contractor Off
+		{
+			gErrorEvent |= EEV__SHUT_DOWN_EMERGENCY;
+		}
+	}	
+}
+
+
+
+// ***** check_and_save_EVCU1_BMU *********************************************
+uint16_t check_and_save_EVCU1_BMU( CAN_MAILBOX *p_MBox )
+{
+	uint8_t		Data[8];											// Receive Dummy
+
+	
+	if( CAN_Read(p_MBox, &Data[0] ) != CAN_ERROR )
+	{
+		if(Data[7])
+		   gCANErrorInsert = Data[7];                               //!! 1.5-3
+		else
+		{
+			gCANErrorInsert = 0;
+		
+	    	Data[0] &= 0x03;											// Mask first two Bit for Mode Request
+		
+	    	switch( Data[0] )
+	    	{
+				case MR__STANDBY :
+					if( gEvent > EV__INITIALISE )
+					{
+						if( gEvent < EV__CHARGE )
+							gEvent = EV__SHUT_DOWN_DRIVE;
+						else
+							gEvent = EV__SHUT_DOWN_CHARGE;
+					}
+					if( gEvent == EV__STAND_BY)
+					{
+						if( READ_INPIN( PIN_REGNR_RELAIS_PRECHA ))
+							gEvent = EV__SHUT_DOWN_DRIVE;
+						if( READ_INPIN( PIN_REGNR_RELAIS_SLAVE ))
+							gEvent = EV__SHUT_DOWN_CHARGE;
+					}
+					break;
+				
+				case MR__DRIVE :
+					if( gEvent == EV__STAND_BY )						// switch out of StandBy only
+					if( READ_INPIN( PIN_REGNR_RELAIS_PRECHA ))
+						gEvent = EV__DRIVE_START_3;
+					else
+						gEvent = EV__DRIVE_START_1;
+				break;
+				
+				case MR__CHARGE :
+					if( gEvent == EV__STAND_BY )						// switch out of StandBy only
+					{
+						if( !READ_INPIN( PIN_REGNR_RELAIS_PRECHA ))     // not during DRIVE Start Sequence
+							gEvent =  EV__CHARGE;
+					}
+					break;
+				
+				default :
+				break;
+	    	}
+	    	if( Data[1] )
+	    	{
+                ME.MCTL.R = 0x00005AF0;             // Software Reset (Functional Reset)
+                ME.MCTL.R = 0x0000A50F;
+                while (ME.IS.B.I_MTC != 1) {}       /* Wait Until transition completed      */
+                    ME.IS.B.I_MTC = 1;              /* Clear flag                           */   
+    		}
+		}
+	}	
+}
+
+
+
+// ***** End BMS_CAN2_Tools.c **************************************************

+ 201 - 0
BMS Master/Sources/BMS_Can_ID_init.c

@@ -0,0 +1,201 @@
+/*
+ * BMS_Can_ID_init.c
+ *
+ *  Created on: Nov 30, 2016
+ *      Author: le8041
+ */
+
+#include "BMS_Master.h"
+
+/*
+ * reads startup config from FRAM and copies it into RAM
+ */
+
+uint32_t BMS_Can_ID_init_init_startupConfig (MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	uint16_t FRAM_Slave_Can_Id_valid;
+	s->startupConfig.state.Bit.SOC_Initialized=FALSE;
+	read_fram_word(&FRAM_Slave_Can_Id_valid,3,BMS_SLAVE_CAN_ID_VALID);       // read VALID Flag from FRAM
+	s->startupConfig.state.Bit.Slave_Can_Id_valid=FRAM_Slave_Can_Id_valid;   // store VALID Flag to DRAM
+	s->startupConfig.fsmState=BMS_CAN_ID_SEARCH_INIT;
+	
+	for(i=0;i<CAN0_MAX_NR_OF_SLAVES;i++) {
+		s->startupConfig.SlaveConfig[i].CanId=0;
+		s->startupConfig.SlaveConfig[i].SerialNr[0]='N';
+	}
+	return TRUE;
+}
+
+uint32_t BMS_Can_ID_init_recofigure_CAN_IDs(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t SlaveNummer;
+	uint8_t MasterAlive=0;
+	uint8_t SetMode = 16; // This is stand By mode
+	uint32_t Balancer = 0; // no balancing during startup
+	uint32_t StartTime =0;
+	uint16_t IDSEARCH = 1;
+//	uint16_t LFT;
+	uint8_t k=0;
+	
+	uint8_t  RxSlave=0;
+	
+	//Give CAN IDs to Slaves
+	
+	//Step 0 Bring all Slaves to Reset Mode
+	for(SlaveNummer=0;SlaveNummer<CAN0_MAX_NR_OF_SLAVES -1;SlaveNummer++)
+	{
+		// schreibe Telegram im Reset Mode an alle möglichen Slaves CAn ID 0x100 - 0x1F0
+		CAN_Tx_MasterX_BMS(s, SlaveNummer, MasterAlive, SetMode, Balancer );  //SetMode(X) = 0b00001 (=StandBy), Balancer = 0 (=OFF)
+		StartTime = Global_1msCounter;
+		while( (Global_1msCounter-StartTime) < 200 )
+		{};	//wait 200ms
+	}
+	
+	//Step A
+	//Transmit cstring "IDSEARCH" to Slave over CAN IDE 0x300 
+	CAN_Tx_System300( IDSEARCH );	//start
+	
+	
+	StartTime = Global_1msCounter;
+	while( (Global_1msCounter-StartTime) < 20 )
+	{} //wait 20ms
+	
+	SlaveNummer=0;
+	//Step B
+	// Transmitt Zero String over CAN ID 10A
+	// Slave Answers with Serial Number
+	do {
+		RxSlave = 0;
+		// schicke Master Telegram an CAN ID 0
+		CAN_Tx_MasterXA();
+		StartTime = Global_1msCounter;
+		while( ((Global_1msCounter-StartTime)<5000 ) && (SlaveNummer < 16) )   //0.23ms * 2^16
+		{
+			//warte auf Antwort von Slave
+			if( CAN0_check_serial_nr_rec_Can_init(s ,SlaveNummer))    //CAN_Rx_SlaveXA_Master
+			{	
+				// Slave hat mit serien nummer geantwortet
+				// here convert Short form of Slave ID to Long Form
+				// to be done
+//				LFT = (uint16_t)gSerNrShort[gAnzSlave][0] + ( (uint16_t)gSerNrShort[gAnzSlave][1] << 8); 
+//				gSerNrLong[gAnzSlave][ 0] = (uint8_t)((LFT % 10) + 0x30); LFT = LFT / 10;
+//				gSerNrLong[gAnzSlave][ 1] = (uint8_t)((LFT % 10) + 0x30); LFT = LFT / 10;
+//				gSerNrLong[gAnzSlave][ 2] = (uint8_t)((LFT % 10) + 0x30); LFT = LFT / 10;
+//				gSerNrLong[gAnzSlave][ 3] = (uint8_t)((LFT % 10) + 0x30);
+//				gSerNrLong[gAnzSlave][ 4] =  gSerNrShort[gAnzSlave][2];
+//				gSerNrLong[gAnzSlave][ 5] = (gSerNrShort[gAnzSlave][3] % 10) + 0x30;
+//				gSerNrLong[gAnzSlave][ 6] = (gSerNrShort[gAnzSlave][3] / 10) + 0x30;
+//				gSerNrLong[gAnzSlave][ 7] =  gSerNrShort[gAnzSlave][4]; // das hier enthält die CAN ID
+//				gSerNrLong[gAnzSlave][ 8] = (gSerNrShort[gAnzSlave][5] % 10) + 0x30;
+//				gSerNrLong[gAnzSlave][ 9] = (gSerNrShort[gAnzSlave][5] / 10) + 0x30;
+//				gSerNrLong[gAnzSlave][10] =  0x30;
+//				gSerNrLong[gAnzSlave][11] =  gSerNrShort[gAnzSlave][6];
+				
+				// !! here copy to FRAM !!
+				SlaveNummer++;
+				RxSlave++;
+			}
+		}
+		
+		for(k=SlaveNummer-RxSlave; k<SlaveNummer; k++)
+		{
+			StartTime = Global_1msCounter;
+			s->startupConfig.SlaveConfig[k].SerialNr[7]=(k<<4); // damit aus CAN IC 3 can ID 0x30 wird
+			CAN_Tx_System30A( &(s->startupConfig.SlaveConfig[k].SerialNr[0]) );// übertrage Seriennummer + CAN ID an Slave
+			while( (Global_1msCounter-StartTime) < 20 )
+			{} //wait 20ms
+		}
+	} while( RxSlave );	
+	
+	// Set Slave Config Accordingly
+	
+	for(k=0;k<SlaveNummer;k++) {
+		s->Slave[k].SlaveConnectionState=CONNECTED;
+	}
+	
+	// calculate max Battery voltage
+	s->startupConfig.maxBatteryVoltage = (float)(SlaveNummer * MAX_SLAVE_CELLS * BMS_SLAVE_MAX_CELL_VOLTAGE / 1000.0) ;
+	// calculate min Battery voltage
+	s->startupConfig.minBatteryVoltage = (float)(SlaveNummer * MAX_SLAVE_CELLS * BMS_SLAVE_MIN_CELL_VOLTAGE /1000.0);
+	
+}
+
+uint32_t BMS_Can_ID_init_fsm (MASTER_CAN0_STRUCT_t* s) {
+	uint16_t Adr_FRAM = BMS_SERNR;
+	uint16_t FRAM_NrOfSlaves;
+	uint8_t  FRAM_BMS_SERNR;
+	uint8_t *ptrFRAM;
+	uint8_t  SlaveNr;
+	uint8_t  CompStatus;
+	uint8_t  i;
+	
+	switch (s->startupConfig.fsmState) {
+		case BMS_CAN_ID_SEARCH_INIT:
+			if(s->startupConfig.state.Bit.Slave_Can_Id_valid == TRUE) {
+				// CAN Ids valid
+				s->startupConfig.fsmState=BMS_CAN_ID_SEARCH_CHECK_COMMUNICATION;
+				return BMS_CAN_ID_INIT_RETURN_RUNNING;
+			}
+			else {
+				s->startupConfig.fsmState=BMS_CAN_ID_SEARCH_RECONFIGURE_CAN0_IDS;
+				return BMS_CAN_ID_INIT_RETURN_RUNNING;
+			}
+		break;
+		case BMS_CAN_ID_SEARCH_CHECK_COMMUNICATION:
+			// not implemented yet
+			BMS_Can_ID_init_recofigure_CAN_IDs(s);                  // Complete ID scan first
+			s->NrOfSlaves= get_nr_of_connected_slaves(s);           // get NrOfSlaves from actual scan
+			read_fram_word(&FRAM_NrOfSlaves,3,BMS_SLAVE_ANZ);       // read NrOfSlaves from FRAM (past scan)
+			if(FRAM_NrOfSlaves != s->NrOfSlaves)                    // if actual and past scan not match
+				return BMS_CAN_ID_INIT_RETURN_ERROR;                // show error
+			
+			for(SlaveNr=0; SlaveNr<FRAM_NrOfSlaves; SlaveNr++){     // for all Slave present
+				ptrFRAM = (uint8_t *)BMS_SERNR;                     // Pointer to Start of SERNR Data
+				while( ptrFRAM < (uint8_t *)((BMS_SERNR + (8 * BMS_SERNR)))){ // loop 
+					CompStatus = TRUE;
+					for(i=0; i<8; i++){
+						read_fram_byte(&FRAM_BMS_SERNR,3,(const volatile unsigned short)ptrFRAM);
+						if(s->startupConfig.SlaveConfig[SlaveNr].SerialNr[i] != FRAM_BMS_SERNR)
+							CompStatus=FALSE;
+						ptrFRAM++;
+					}
+					if( CompStatus == TRUE){
+						ptrFRAM = (uint8_t *) (BMS_SERNR + (8 * BMS_SERNR));
+					}
+				}
+				if(CompStatus == FALSE)
+					return BMS_CAN_ID_INIT_RETURN_ERROR;
+			}
+			s->startupConfig.state.Bit.Slave_Can_Id_valid = TRUE;
+			write_fram_word(s->startupConfig.state.Bit.Slave_Can_Id_valid,3,BMS_SLAVE_CAN_ID_VALID);			
+			write_fram_word(s->NrOfSlaves,3,BMS_SLAVE_ANZ);
+			for(SlaveNr=0; SlaveNr<s->NrOfSlaves; SlaveNr++){
+				for(i=0; i<8; i++){
+					write_fram_byte(s->startupConfig.SlaveConfig[SlaveNr].SerialNr[i],3,Adr_FRAM);
+			        Adr_FRAM++;
+			    }
+			} 
+			return BMS_CAN_ID_INIT_RETURN_COMPLETE;
+		break;
+		case BMS_CAN_ID_SEARCH_RECONFIGURE_CAN0_IDS:
+			// start CAN ID reconfiguration
+			BMS_Can_ID_init_recofigure_CAN_IDs(s);
+			s->NrOfSlaves= get_nr_of_connected_slaves(s);
+			s->startupConfig.state.Bit.Slave_Can_Id_valid = TRUE;
+            write_fram_word(s->startupConfig.state.Bit.Slave_Can_Id_valid,3,BMS_SLAVE_CAN_ID_VALID);			
+            write_fram_word(s->NrOfSlaves,3,BMS_SLAVE_ANZ);
+            for(SlaveNr=0; SlaveNr<s->NrOfSlaves; SlaveNr++){
+               for(i=0; i<8; i++){
+            	   write_fram_byte(s->startupConfig.SlaveConfig[SlaveNr].SerialNr[i],3,Adr_FRAM);
+            	   Adr_FRAM++;
+               }
+            } 
+			return BMS_CAN_ID_INIT_RETURN_COMPLETE;
+		break;
+		default:
+			return BMS_CAN_ID_INIT_RETURN_ERROR;
+		break;
+	}
+}
+
+
+

+ 856 - 0
BMS Master/Sources/BMS_Cell_Config.c

@@ -0,0 +1,856 @@
+/*
+ * BMS_Cell_Config.c
+ *
+ *  Created on: May 27, 2016
+ *      Author: uacqk
+ */
+
+#include "BMS_Master.h"
+
+BMS_SLAVE_CONFIGURATION_t cellConfig[CAN0_MAX_NR_OF_SLAVES];
+
+// Slave Board 0
+void initCellConfig(BMS_SLAVE_CONFIGURATION_t* cellConfig) {
+	// SLAVE 0   
+	cellConfig->slaveNr=0;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+
+	
+	cellConfig->tempSensConnectionState[0]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+	// Slave 1
+	cellConfig++;
+	cellConfig->slaveNr=1;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+
+	
+	cellConfig->tempSensConnectionState[0]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+	// Slave 2
+	cellConfig++;
+	cellConfig->slaveNr=2;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+
+	
+	cellConfig->tempSensConnectionState[0]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+	// Slave 3
+	cellConfig++;
+	cellConfig->slaveNr=3;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+
+	
+	cellConfig->tempSensConnectionState[0]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+	// Slave 4
+	cellConfig++;
+	cellConfig->slaveNr=4;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=		CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=		CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=		CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=		CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=		CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=		CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=		CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=		CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=		CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=		CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=	CELL_CONNECTED;
+	
+	cellConfig->tempSensConnectionState[0]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_NOT_CONNECTED;
+	
+	// Slave 5
+	cellConfig++;
+	cellConfig->slaveNr=5;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+	
+	cellConfig->tempSensConnectionState[0]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=	TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_NOT_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_NOT_CONNECTED;
+	
+	// Slave 6
+	cellConfig++;
+	cellConfig->slaveNr=6;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+	
+	cellConfig->tempSensConnectionState[0]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+	
+	// Slave 7
+	cellConfig++;
+	cellConfig->slaveNr=7;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+	
+	cellConfig->tempSensConnectionState[0]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+	
+	// Slave 8
+	cellConfig++;
+	cellConfig->slaveNr=8;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+	
+	cellConfig->tempSensConnectionState[0]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+	
+	// Slave 9
+	cellConfig++;
+	cellConfig->slaveNr=9;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+	
+	cellConfig->tempSensConnectionState[0]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+	
+	// Slave 10
+	cellConfig++;
+	cellConfig->slaveNr=10;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+	
+	cellConfig->tempSensConnectionState[0]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+	
+	// Slave 11
+	cellConfig++;
+	cellConfig->slaveNr=11;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+	
+	cellConfig->tempSensConnectionState[0]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+	
+	// Slave 12
+	cellConfig++;
+	cellConfig->slaveNr=12;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+	
+	cellConfig->tempSensConnectionState[0]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+	
+	// Slave 13
+	cellConfig++;
+	cellConfig->slaveNr=13;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+	
+	cellConfig->tempSensConnectionState[0]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+	// Slave 14
+	cellConfig++;
+	cellConfig->slaveNr=14;
+	cellConfig->connectionSate=NOT_CONNECTED;
+	cellConfig->type=SLAVE;
+	cellConfig->cellConnectionState[0]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[1]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[2]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[3]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[4]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[5]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[6]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[7]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[8]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[9]=	CELL_CONNECTED;
+	cellConfig->cellConnectionState[10]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[11]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[12]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[13]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[14]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[15]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[16]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[17]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[18]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[19]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[20]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[21]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[22]=CELL_CONNECTED;
+	cellConfig->cellConnectionState[23]=CELL_CONNECTED;
+	
+	cellConfig->tempSensConnectionState[0]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[1]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[2]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[3]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[4]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[5]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[6]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[7]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[8]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[9]=	TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[10]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[11]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[12]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[13]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[14]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[15]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[16]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[17]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[18]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[19]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[20]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[21]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[22]=TEMP_SENSOR_CONNECTED;
+	cellConfig->tempSensConnectionState[23]=TEMP_SENSOR_CONNECTED;
+	
+}
+
+void initUiConfig(BMS_UI_CONFIGURATION_t* uiConfig) {
+	uiConfig->connectionSate=CONNECTED;
+	uiConfig->slaveNr=15;
+	uiConfig->type=UI;
+}
+

+ 265 - 0
BMS Master/Sources/BMS_Clear_Error_States.c

@@ -0,0 +1,265 @@
+/*
+ * BMS_Clear_Error_States.c
+ *
+ *  Created on: Nov 8, 2016
+ *      Author: le8041
+ */
+
+#include "BMS_Master.h"
+
+uint32_t BMS_Clear_Error_Buffer(MASTER_CAN0_STRUCT_t* s,uint8_t ErrorClass) {
+	uint8_t i;
+	if(ErrorClass == BMS_ERROR_CLASS_1) {
+		// go though Error buffer 1 and check if Errors still apply 
+		// if no clear Error Flag
+		for(i=0;i<s->ErrorBuffer.ES1_ErrorCounter;i++) {
+			if(s->ErrorBuffer.ES1_Error[i].Word & 0x00000001) {
+				// Error still applies
+				if(s->ErrorBuffer.ES1_Error[i].Master.SubsystemNr==BMS_ERROR_MASTER_ID) {
+					// Error is master Error
+					BMS_Clear_Error_State_Master(s,&(s->ErrorBuffer.ES1_Error[i]),i,ErrorClass); 
+				}
+				else if(s->ErrorBuffer.ES1_Error[i].Master.SubsystemNr==BMS_ERROR_UI_ID) {
+					// Error is UI Error
+					
+				}
+				else{
+					// Error is Slave Error
+					BMS_Clear_Error_State_Slave(s,&(s->ErrorBuffer.ES1_Error[i])) ;
+				}
+			}
+		}
+	}
+	
+	else if(ErrorClass == BMS_ERROR_CLASS_2) {
+		// go though Error buffer 2 and check if Errors still apply 
+		// if no clear Error Flag
+		for(i=0;i<s->ErrorBuffer.ES2_ErrorCounter;i++) {
+			if(s->ErrorBuffer.ES2_Error[i].Word & 0x00000001) {
+				// Error still applies
+				if(s->ErrorBuffer.ES2_Error[i].Master.SubsystemNr==BMS_ERROR_MASTER_ID) {
+					// Error is master Error
+					BMS_Clear_Error_State_Master(s,&(s->ErrorBuffer.ES2_Error[i]),i,ErrorClass); 
+				}
+				else if(s->ErrorBuffer.ES2_Error[i].Master.SubsystemNr==BMS_ERROR_UI_ID) {
+					// Error is UI Error
+					
+				}
+				else{
+					// Error is Slave Error
+					BMS_Clear_Error_State_Slave(s,&(s->ErrorBuffer.ES2_Error[i])) ;
+				}
+			}
+		}
+	}
+	
+	else {
+		// go though Error buffer 3 and check if Errors still apply 
+		// if no clear Error Flag
+		for(i=0;i<s->ErrorBuffer.ES3_ErrorCounter;i++) {
+			if(s->ErrorBuffer.ES3_Error[i].Word & 0x00000001) {
+				// Error still applies
+				if(s->ErrorBuffer.ES3_Error[i].Master.SubsystemNr==BMS_ERROR_MASTER_ID) {
+					// Error is master Error
+					BMS_Clear_Error_State_Master(s,&(s->ErrorBuffer.ES3_Error[i]),i,ErrorClass); 
+				}
+				else if(s->ErrorBuffer.ES3_Error[i].Master.SubsystemNr==BMS_ERROR_UI_ID) {
+					// Error is UI Error
+					
+				}
+				else{
+					// Error is Slave Error
+					
+				}
+			}
+		}
+	}
+	return TRUE;
+}
+
+/*
+ * @brief check if error still applies, if no return false if yes return true and invalidate error
+ */
+uint32_t BMS_Clear_Error_State_Master(MASTER_CAN0_STRUCT_t* s,BMS_ERROR_STATE_t* error_state,uint8_t Error_nr,uint8_t Error_class) {
+	uint8_t SlaveSelect;
+	if(error_state->Master.ErrorCode==BMS_ERROR_STACK_MASTER_UMIN_1) {
+		// check if Umin1 error still applies
+		if(s->inverterState.startupPwr >20 ) {
+			// PV Supplies more than 20W Start recharging battery
+			// give inverter time to start charging battery
+			if(Error_class ==BMS_ERROR_CLASS_1) {
+				// use Error class 1
+				if(s->ErrorBuffer.ES1_Error_Recovery[Error_nr].recoveryPending== FALSE) {
+					// not yet trying to recover from Error
+					s->ErrorBuffer.ES1_Error_Recovery[Error_nr].recoveryPending= TRUE;
+					s->ErrorBuffer.ES1_Error_Recovery[Error_nr].recoveryTimestamp =Global_1msCounter ;
+					return TRUE;
+				}
+				else {
+					// System already trying to recover from error
+					if(s->inverterState.inverterIsCharging == TRUE) {
+						// system is charging => Error can be completely revoked
+						error_state->Master.active=0;
+						s->ErrorBuffer.ES1_Error_Recovery[Error_nr].recoveryPending= FALSE;
+						return TRUE;
+					}
+					else if(s->ErrorBuffer.ES1_Error_Recovery[Error_nr].recoveryPending== TRUE) {
+						// check if timeout occured
+						if(s->ErrorBuffer.ES1_Error_Recovery[Error_nr].recoveryTimestamp +BMS_ERROR_RESTORE_TIMEOUT < Global_1msCounter) {
+							// timeout occured
+							error_state->Master.active=1;
+							s->ErrorBuffer.ES1_Error_Recovery[Error_nr].recoveryPending= FALSE;
+							return FALSE;
+						}
+						else {
+							// no timeout;
+							return TRUE;
+						}
+					}
+				}
+			}
+			else if(Error_class ==BMS_ERROR_CLASS_2) {
+				// use Error class 2
+				// up date if umin1 should become error class 2
+				return FALSE;
+			}
+			else {
+				// Error class 3 has no recovery function
+				error_state->Master.active=1;
+				return FALSE;
+			}
+
+			return FALSE;
+		}
+		else {
+			error_state->Master.active=1;
+			return FALSE;
+		}
+	}
+	else if(error_state->Master.ErrorCode==BMS_ERROR_STACK_MASTER_UMIN_2 ) {
+		// check if Umin2 error still applies
+		if(s->inverterState.startupPwr >20 ) {
+			// PV Supplies more than 20W Start recharging battery
+			// give inverter time to start charging battery
+			if(Error_class ==BMS_ERROR_CLASS_2) {
+				// use Error class 2
+				if(s->ErrorBuffer.ES2_Error_Recovery[Error_nr].recoveryPending== FALSE) {
+					// not yet trying to recover from Error
+					s->ErrorBuffer.ES2_Error_Recovery[Error_nr].recoveryPending= TRUE;
+					s->ErrorBuffer.ES2_Error_Recovery[Error_nr].recoveryTimestamp =Global_1msCounter ;
+					return TRUE;
+				}
+				else {
+					// System already trying to recover from error
+					if(s->inverterState.inverterIsCharging == TRUE) {
+						// system is charging => Error can be completely revoked
+						error_state->Master.active=0;
+						s->ErrorBuffer.ES2_Error_Recovery[Error_nr].recoveryPending= FALSE;
+						return TRUE;
+					}
+					else if(s->ErrorBuffer.ES2_Error_Recovery[Error_nr].recoveryPending== TRUE) {
+						// check if timeout occured
+						if(s->ErrorBuffer.ES2_Error_Recovery[Error_nr].recoveryTimestamp +BMS_ERROR_RESTORE_TIMEOUT < Global_1msCounter) {
+							// timeout occured
+							error_state->Master.active=1;
+							s->ErrorBuffer.ES2_Error_Recovery[Error_nr].recoveryPending= FALSE;
+							return FALSE;
+						}
+						else {
+							// no timeout;
+							return TRUE;
+						}
+					}
+				}
+			}
+			else {
+				// Error class 3 has no recovery function
+				error_state->Master.active=1;
+				return FALSE;
+			}
+
+			return FALSE;
+		}
+		
+	}
+	else if(error_state->Master.ErrorCode==BMS_ERROR_STACK_MASTER_UMIN_3) {
+		// check if Umin1 error still applies
+		// error state can only removed from external technician
+		return FALSE;
+	}
+	else if(error_state->Master.ErrorCode==BMS_ERROR_STACK_MASTER_UMAX_2) {
+		// check if Umax2 error still applies
+		if(s->maxCellVoltage <= BMS_SOC_UMAX_2) {
+			// error no longer applies
+			error_state->Master.active=0;
+			return TRUE;
+		}
+		else {
+			return FALSE;
+		}
+	}
+	else if(error_state->Master.ErrorCode==BMS_ERROR_STACK_MASTER_I_MAX_DISCHARGE_OP) {
+		// not clear how to revoke error because relais are open and therefore current is 0A
+		
+		error_state->Master.active=0;
+		return TRUE;
+		
+	}
+	else if(error_state->Master.ErrorCode==BMS_ERROR_STACK_MASTER_I_MAX_CHARGE_OP) {
+		// not clear how to revoke error because relais are open and therefore current is 0A
+		
+		error_state->Master.active=0;
+		return TRUE;
+		
+	}
+	else if( error_state->Master.ErrorCode==BMS_ERROR_STACK_MASTER_EXTERN_CAN_ERROR) {
+		// simply revoke Error when no more Timeouts are detected
+		if(s->CAN1_fsmStruct.timeoutCyclesCnt==0) {
+			error_state->Master.active = 0;
+			return TRUE;
+		}
+		return FALSE;
+	}
+
+	
+	else{
+		// invalid state
+		return FALSE;
+	}
+	
+}
+
+/*
+ * @brief check if error still applies, if no return false if yes return true and invalidate error
+ */
+uint32_t BMS_Clear_Error_State_Slave(MASTER_CAN0_STRUCT_t* s,BMS_ERROR_STATE_t* error_state) {
+	uint8_t SlaveSelect;
+	 if(error_state->Slave.ErrorType == BMS_ERROR_STACK_SLAVE_CAN_ERROR) {
+		 	 SlaveSelect=error_state->Slave.SubsystemNr;
+			if(s->Slave[SlaveSelect].SlaveCanCommuniationError.FailedComCnt==0) {
+				// connection is good again
+				error_state->Slave.active=0;
+				return TRUE;
+			}
+			else {
+				return FALSE;
+			}
+	}
+	else{
+		// invalid state
+		return FALSE;
+	}
+}
+
+
+
+uint32_t BMS_Clear_Error_init_recovery_struct(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	for(i=0;i<BMS_ERROR_ERROR_STACK_SIZE;i++) {
+		s->ErrorBuffer.ES1_Error_Recovery[i].recoveryPending=0;
+		s->ErrorBuffer.ES1_Error_Recovery[1].recoveryTimestamp=0;
+		s->ErrorBuffer.ES2_Error_Recovery[i].recoveryPending=0;
+		s->ErrorBuffer.ES2_Error_Recovery[1].recoveryTimestamp=0;
+	}
+	
+}

+ 347 - 0
BMS Master/Sources/BMS_Error_Stack.c

@@ -0,0 +1,347 @@
+/*
+ * BMS_Error_Stack.c
+ *
+ *  Created on: Oct 10, 2016
+ *      Author: le8041
+ */
+
+#include "BMS_Master.h"
+
+
+uint32_t ErrorStackPushSlaveError(MASTER_CAN0_STRUCT_t* s,uint8_t slaveNr,uint32_t ErrorCode,uint8_t CellNr,uint8_t ErrorClass) {
+	BMS_ERROR_STATE_t TempError;
+	TempError.Slave.CellNr=CellNr;
+	TempError.Slave.ErrorType=ErrorCode;
+	TempError.Slave.SubsystemNr=slaveNr;
+	TempError.Slave.active=TRUE;
+	if(ErrorClass==BMS_ERROR_CLASS_1) {
+		if (ErrorStackCheckBufferForError(s,TempError.Word,ErrorClass)) {
+			// Error has already been stored
+			return TRUE;
+		}
+		// Error has not been recorded yet
+		s->ErrorBuffer.ES1_Error[s->ErrorBuffer.ES1_ErrorCounter].Word=TempError.Word;
+		// write FRAM
+		write_fram_write_error(TempError.Word,BMS_ERROR_CLASS_1,s->ErrorBuffer.ES1_ErrorCounter);
+		s->ErrorBuffer.ES1_ErrorCounter++;
+		return TRUE;
+	}
+	else if(ErrorClass == BMS_ERROR_CLASS_2){
+		// write Error Buffer 2
+		if (ErrorStackCheckBufferForError(s,TempError.Word,ErrorClass)) {
+			// Error has already been stored
+			return TRUE;
+		}
+		// Error has not been recorded yet
+		s->ErrorBuffer.ES2_Error[s->ErrorBuffer.ES2_ErrorCounter].Word=TempError.Word;
+		// write FRAM
+		write_fram_write_error(TempError.Word,BMS_ERROR_CLASS_2,s->ErrorBuffer.ES2_ErrorCounter);
+		s->ErrorBuffer.ES2_New_Error=TRUE;
+		s->ErrorBuffer.ES2_ErrorCounter++;
+		return TRUE;
+	}
+	else {
+		// write Error Buffer 3
+		if (ErrorStackCheckBufferForError(s,TempError.Word,ErrorClass)) {
+			// Error has already been stored
+			return TRUE;
+		}
+		// Error has not been recorded yet
+		s->ErrorBuffer.ES3_Error[s->ErrorBuffer.ES3_ErrorCounter].Word=TempError.Word;
+		// write FRAM
+		write_fram_write_error(TempError.Word,BMS_ERROR_CLASS_3,s->ErrorBuffer.ES3_ErrorCounter);
+		s->ErrorBuffer.ES3_ErrorCounter++;
+		return TRUE;	
+	}
+	return TRUE;
+}
+
+uint32_t ErrorStackPushUiError(MASTER_CAN0_STRUCT_t* s,uint32_t ErrorCode,uint8_t ErrorClass) {
+	BMS_ERROR_STATE_t TempError;
+		TempError.UI.ErrorCode=ErrorCode;
+		TempError.UI.SubsystemNr=BMS_ERROR_UI_ID;
+		TempError.UI.active=TRUE;
+		if(ErrorClass==BMS_ERROR_CLASS_1) {
+			if (ErrorStackCheckBufferForError(s,TempError.Word,ErrorClass)) {
+				// Error has already been stored
+				return TRUE;
+			}
+			// Error has not been recorded yet
+			s->ErrorBuffer.ES1_Error[s->ErrorBuffer.ES1_ErrorCounter].Word=TempError.Word;
+			// write FRAM
+			write_fram_write_error(TempError.Word,BMS_ERROR_CLASS_1,s->ErrorBuffer.ES1_ErrorCounter);
+			s->ErrorBuffer.ES1_ErrorCounter++;
+			return TRUE;
+		}
+		else if(ErrorClass == BMS_ERROR_CLASS_2){
+			// write Error Buffer 2
+			if (ErrorStackCheckBufferForError(s,TempError.Word,ErrorClass)) {
+				// Error has already been stored
+				return TRUE;
+			}
+			// Error has not been recorded yet
+			s->ErrorBuffer.ES2_Error[s->ErrorBuffer.ES2_ErrorCounter].Word=TempError.Word;
+			// write FRAM
+			write_fram_write_error(TempError.Word,BMS_ERROR_CLASS_2,s->ErrorBuffer.ES2_ErrorCounter);
+			s->ErrorBuffer.ES2_ErrorCounter++;
+			return TRUE;
+		}
+		else {
+			// write Error Buffer 3
+			if (ErrorStackCheckBufferForError(s,TempError.Word,ErrorClass)) {
+				// Error has already been stored
+				return TRUE;
+			}
+			// Error has not been recorded yet
+			s->ErrorBuffer.ES3_Error[s->ErrorBuffer.ES3_ErrorCounter].Word=TempError.Word;
+			// write FRAM
+			write_fram_write_error(TempError.Word,BMS_ERROR_CLASS_3,s->ErrorBuffer.ES3_ErrorCounter);
+			s->ErrorBuffer.ES3_ErrorCounter++;
+			return TRUE;	
+		}
+		return TRUE;
+}
+
+uint32_t ErrorStackPushMasterError(MASTER_CAN0_STRUCT_t* s,uint32_t ErrorCode,uint8_t ErrorClass) {
+	BMS_ERROR_STATE_t TempError;
+		TempError.Master.ErrorCode=ErrorCode;
+		TempError.Master.SubsystemNr=BMS_ERROR_MASTER_ID;
+		TempError.Master.active=TRUE;
+		
+		
+		if(ErrorClass==BMS_ERROR_CLASS_1) {
+			if (ErrorStackCheckBufferForError(s,TempError.Word,ErrorClass)) {
+				// Error has already been stored
+				return TRUE;
+			}
+			// Error has not been recorded yet
+			s->ErrorBuffer.ES1_Error[s->ErrorBuffer.ES1_ErrorCounter].Word=TempError.Word;
+			// write FRAM
+			write_fram_write_error(TempError.Word,BMS_ERROR_CLASS_1,s->ErrorBuffer.ES1_ErrorCounter);
+			s->ErrorBuffer.ES1_ErrorCounter++;
+			return TRUE;
+		}
+		else if(ErrorClass == BMS_ERROR_CLASS_2){
+			// write Error Buffer 2
+			if (ErrorStackCheckBufferForError(s,TempError.Word,ErrorClass)) {
+				// Error has already been stored
+				return TRUE;
+			}
+			// Error has not been recorded yet
+			s->ErrorBuffer.ES2_Error[s->ErrorBuffer.ES2_ErrorCounter].Word=TempError.Word;
+			// write FRAM
+			write_fram_write_error(TempError.Word,BMS_ERROR_CLASS_2,s->ErrorBuffer.ES2_ErrorCounter);
+			// set new error flag
+			s->ErrorBuffer.ES2_New_Error=TRUE;
+			s->ErrorBuffer.ES2_ErrorCounter++;
+			return TRUE;
+		}
+		else {
+			// write Error Buffer 3
+			if (ErrorStackCheckBufferForError(s,TempError.Word,ErrorClass)) {
+				// Error has already been stored
+				return TRUE;
+			}
+			// Error has not been recorded yet
+			s->ErrorBuffer.ES3_Error[s->ErrorBuffer.ES3_ErrorCounter].Word=TempError.Word;
+			// write FRAM
+			write_fram_write_error(TempError.Word,BMS_ERROR_CLASS_3,s->ErrorBuffer.ES3_ErrorCounter);
+			s->ErrorBuffer.ES3_ErrorCounter++;
+			return TRUE;	
+		}
+		return TRUE;
+}
+
+uint32_t ErrorStackGenerateStatusPkg(uint8_t* targetBuffer,uint8_t* ErrorCode) {
+	uint32_t id=CAN1_TX_BATTERY_STATUS;
+	uint8_t* id_addr=(uint8_t*)&id;
+	// generate ID
+	shuffle_lsb_msb_can1((uint8_t*)&id);
+	targetBuffer[0]=id_addr[0];
+	targetBuffer[1]=id_addr[1];
+	targetBuffer[2]=id_addr[2];
+	targetBuffer[3]=id_addr[3];
+	targetBuffer[4]=ErrorCode[3];
+	targetBuffer[5]=ErrorCode[2];
+	targetBuffer[6]=ErrorCode[1];
+	targetBuffer[7]=ErrorCode[0];
+	return TRUE;
+}
+
+/*
+ * @brief check if error is already in Error buffer
+ * @return True if error is already stroed
+ * @return FALSE errhr has not been stred yet
+ */
+
+uint32_t ErrorStackCheckBufferForError(MASTER_CAN0_STRUCT_t* s,uint32_t ErrorWord,uint8_t ErrorClass) {
+	uint8_t i;
+	if(ErrorClass==BMS_ERROR_CLASS_1) {
+		// check Error Buffer 1
+		for(i=0;i<(s->ErrorBuffer.ES1_ErrorCounter);i++ ) {
+			if(s->ErrorBuffer.ES1_Error[i].Word == ErrorWord) {
+				return TRUE; // Error has been detected before
+			}
+		}
+		return FALSE;
+	}
+	else if(ErrorClass==BMS_ERROR_CLASS_2) {
+		// check Error Buffer 2
+		for(i=0;i<(s->ErrorBuffer.ES2_ErrorCounter);i++ ) {
+			if(s->ErrorBuffer.ES2_Error[i].Word == ErrorWord) {
+				return TRUE; // Error has been detected before
+			}
+		}
+		return FALSE;
+	}
+	else  {
+		// check Error Buffer 3
+		//get Error Code from latest entry		
+		for(i=0;i<(s->ErrorBuffer.ES3_ErrorCounter);i++ ) {
+			if(s->ErrorBuffer.ES3_Error[i].Word == ErrorWord) {
+				return TRUE; // Error has been detected before
+			}
+		}
+		return FALSE;
+	}
+}
+
+/*
+ * @brief check if active errors  remain
+ * @return true = error is active
+ * @return false = error not active
+ */
+
+uint32_t ErrorStackCheckForActiveErrors(MASTER_CAN0_STRUCT_t* s,uint8_t ErrorClass) {
+	uint8_t i;
+	if(ErrorClass==BMS_ERROR_CLASS_1) {
+		for(i=0;i<s->ErrorBuffer.ES1_ErrorCounter;i++) {
+			if(s->ErrorBuffer.ES1_Error[i].Word & 0x00000001) {
+				// Error is active
+				if(s->ErrorBuffer.ES1_Error_Recovery[i].recoveryPending == FALSE) {
+					return TRUE;
+				}
+				else {
+					// error recovery is in progress
+					// return no error
+					if(s->ErrorBuffer.ES1_Error[i].Master.SubsystemNr==BMS_ERROR_MASTER_ID) {
+						// Error is master Error
+						BMS_Clear_Error_State_Master(s,&(s->ErrorBuffer.ES1_Error[i]),i,ErrorClass); 
+					}
+					else if(s->ErrorBuffer.ES1_Error[i].Master.SubsystemNr==BMS_ERROR_UI_ID) {
+							// Error is UI Error						
+					}
+					else{
+						// Error is Slave Error
+						BMS_Clear_Error_State_Slave(s,&(s->ErrorBuffer.ES1_Error[i])) ;
+					}
+					return FALSE;
+				}
+			}
+		}
+		// no Active Error
+		return FALSE;
+	}
+	else if(ErrorClass==BMS_ERROR_CLASS_2) {
+		for(i=0;i<s->ErrorBuffer.ES2_ErrorCounter;i++) {
+			if(s->ErrorBuffer.ES2_Error[i].Word & 0x00000001) {
+				// Error is active
+				if(s->ErrorBuffer.ES2_Error_Recovery[i].recoveryPending == FALSE || s->ErrorBuffer.ES2_New_Error == TRUE) {
+					return TRUE;
+				}
+				else {
+					// error recovery is in progress
+					// return no error
+					if(s->ErrorBuffer.ES2_Error[i].Master.SubsystemNr==BMS_ERROR_MASTER_ID) {
+						// Error is master Error
+						BMS_Clear_Error_State_Master(s,&(s->ErrorBuffer.ES2_Error[i]),i,ErrorClass); 
+					}
+					else if(s->ErrorBuffer.ES2_Error[i].Master.SubsystemNr==BMS_ERROR_UI_ID) {
+							// Error is UI Error						
+					}
+					else{
+						// Error is Slave Error
+						BMS_Clear_Error_State_Slave(s,&(s->ErrorBuffer.ES2_Error[i])) ;
+					}
+					return FALSE;
+				}
+			}
+		}
+		// no Active Error
+		return FALSE;		
+	}
+	else {
+		for(i=0;i<s->ErrorBuffer.ES3_ErrorCounter;i++) {
+			if(s->ErrorBuffer.ES3_Error[i].Word & 0x00000001) {
+				// Error is active
+				return TRUE;
+			}
+		}
+		// no Active Error
+		return FALSE;		
+	}
+	
+}
+uint32_t ErrorStackClearBuffer(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	for(i=0;i<BMS_ERROR_ERROR_STACK_SIZE;i++) {
+		s->ErrorBuffer.ES1_Error[i].Word=0;
+		s->ErrorBuffer.ES2_Error[i].Word=0;
+		s->ErrorBuffer.ES3_Error[i].Word=0;
+	}
+}
+
+/*
+ * @ brief check if error recovery is pending
+ * if pending return TRUE else return FALSE
+ */
+uint32_t ErrorStackCheckifUmin1ErrorRecoveryPending(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	for(i=0;i< BMS_ERROR_ERROR_STACK_SIZE;i++) {
+		if(s->ErrorBuffer.ES1_Error[i].Master.active && s->ErrorBuffer.ES1_Error[i].Master.ErrorCode==BMS_ERROR_STACK_MASTER_UMIN_1 ) {
+			if(s->ErrorBuffer.ES1_Error_Recovery[i].recoveryPending==TRUE) {
+				return TRUE;
+			}
+		}
+	}
+	// no pending umin1 error recovery
+	return FALSE;
+}
+
+/*
+ * @ brief check if error recovery is pending
+ * if pending return TRUE else return FALSE
+ */
+uint32_t ErrorStackCheckifUmin2ErrorRecoveryPending(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	for(i=0;i< BMS_ERROR_ERROR_STACK_SIZE;i++) {
+		if(s->ErrorBuffer.ES2_Error[i].Master.active && s->ErrorBuffer.ES2_Error[i].Master.ErrorCode==BMS_ERROR_STACK_MASTER_UMIN_2 ) {
+			if(s->ErrorBuffer.ES2_Error_Recovery[i].recoveryPending==TRUE) {
+				return TRUE;
+			}
+		}
+	}
+	// no pending umin1 error recovery
+	return FALSE;
+}
+
+/*
+ * @ brief check if error recovery is pending
+ * if pending return TRUE else return FALSE
+ */
+uint32_t ErrorStackCheckifAnyErrorRecoveryPending(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	for(i=0;i< BMS_ERROR_ERROR_STACK_SIZE;i++) {
+		if(s->ErrorBuffer.ES1_Error_Recovery[i].recoveryPending==TRUE) {
+			return TRUE;
+		}
+		if(s->ErrorBuffer.ES2_Error_Recovery[i].recoveryPending==TRUE) {
+			return TRUE;
+		}
+	}
+	// no pending umin1 error recovery
+	return FALSE;
+}
+
+
+

+ 88 - 0
BMS Master/Sources/BMS_Inverter_status.c

@@ -0,0 +1,88 @@
+/*
+ * BMS_Inverter_status.c
+ *
+ *  Created on: Nov 17, 2016
+ *      Author: le8041
+ */
+
+#include "BMS_Master.h"
+
+
+uint32_t BMS_RCT_init_fsm(MASTER_CAN0_STRUCT_t* s) {
+	s->inverterState.state=RCT_INV_INACTIVE;
+	s->inverterState.inverterCanOnline=FALSE;
+	s->inverterState.startupPwr=0;
+	return TRUE;
+}
+
+/*
+ * @brief describes state of RCT inverter for Error recovery reasons
+ */
+uint32_t BMS_RCT_Inverter_fsm (MASTER_CAN0_STRUCT_t* s) {
+	switch (s->inverterState.state) {
+		case RCT_INV_INACTIVE:
+			// Battery is not charging
+			s->inverterState.inverterIsCharging=FALSE;
+			// Inverter is off no relais connected and no communication and expected power has been updated
+			if(s->inverterState.inverterCanOnline== TRUE && s->inverter.rxStruct.expectedInputPower > -1) {
+				// Inverter has answered a CAN Telegram => CAN is connected
+				s->inverterState.state=RCT_INV_CAN_CONNECTED;
+				s->inverterState.startupPwr=s->inverter.rxStruct.expectedInputPower;
+				return TRUE;
+			}
+			else{
+				// do nothing and wait wait for can connection 
+				return TRUE;
+			}
+			return TRUE;
+		break;
+		case RCT_INV_CAN_CONNECTED:
+			// Can is connected relais are open
+			// Battery is not charging
+			s->inverterState.inverterIsCharging=FALSE;
+			if(s->inverterState.inverterCanOnline== FALSE) {
+				// inverter communication has failed
+				s->inverterState.state=RCT_INV_INACTIVE;
+				return TRUE;
+			}
+			else if(s->relayState.HS_closed==TRUE && s->relayState.LS_closed ==TRUE) {
+				// relays are connected now
+				s->inverterState.state=RCT_INV_RELALY_CONNECTED;
+				return TRUE;
+			}
+			else {
+				//noting happended Wait
+				return TRUE;
+			}
+			return TRUE;
+		break;	
+		case RCT_INV_RELALY_CONNECTED:
+			
+			if(s->inverterState.inverterCanOnline== FALSE) {
+				// inverter has been turned off or can communicatin has failed
+				s->inverter.rxStruct.expectedInputPower = -1;
+				s->inverterState.state=RCT_INV_INACTIVE;
+				return TRUE;
+			}
+			else if(s->relayState.HS_closed==FALSE && s->relayState.LS_closed ==FALSE) {
+				// error has oaaured and relays have been opend
+				s->inverterState.state=RCT_INV_CAN_CONNECTED;
+				return TRUE;
+			}
+			else {
+				// nothing happend inverter fully operational
+				s->inverterState.startupPwr=s->inverter.rxStruct.DCinputA_power + s->inverter.rxStruct.DCinputB_power;
+				if(BMS_set_Error_check_if_stable_charge(s)) {
+					// Battery is discharign
+					s->inverterState.inverterIsCharging=TRUE;
+				}
+				else {
+					s->inverterState.inverterIsCharging=FALSE;
+				}
+				return TRUE;
+			}
+			
+			return TRUE;
+		break;
+	}
+}

+ 2029 - 0
BMS Master/Sources/BMS_Master.c

@@ -0,0 +1,2029 @@
+//##############################################################################
+//
+// FILE:	BMS_Master.c
+//
+// TITLE:	Functions of BMS_Master
+//            void		BMS_Init_BSD	( void );
+//            void		BMS_Init_BSE	( void );
+//            void		SwitchRelais	( uint8_t, uint8_t );
+//            void		SetBalancer		( void );
+//	          uint16_t	BMS_Do			( void );
+//
+//
+//##############################################################################
+
+//==============================================================================
+// Historie:
+//==============================================================================
+// Datum:   | Name | Version:| Aenderungsgrund:                          | rev.:
+//------------------------------------------------------------------------------
+//          |  SB  | 2.1    |  Implementaion of Balancing and SoC Estimator                                         | 003   
+//------------------------------------------------------------------------------
+//          |  SB  |  2.0   | Adaptation for RCT	                                           | 002   
+//------------------------------------------------------------------------------
+// 01.07.13 |  VR  |   1.1   | Rearrange Code for IAA Bus                | 001 
+//------------------------------------------------------------------------------
+// 20.04.10 |  TM  |   1.0   | Start Code for Master Test                | 000
+//==============================================================================
+
+#include "BMS_Master.h"
+
+
+
+// ***** Global Data ***********************************************************
+extern uint32_t 	Global_1msCounter; 
+extern BSE_t		gBSE;
+extern BSD_t		gBSD;
+
+
+
+
+
+
+// ***** SwitchRelais **********************************************************
+void SwitchRelais( uint8_t Relais, uint8_t OnOff )
+{
+	if( Relais == LS_RELAIS )
+	{
+		if(OnOff)
+			SET_OUTPIN( PIN_REGNR_RELAIS_SLAVE );
+		else
+			CLEAR_OUTPIN( PIN_REGNR_RELAIS_SLAVE);
+	}
+	
+	if( Relais == HS_RELAIS)
+	{
+		if(OnOff) {
+			SET_OUTPIN( PIN_REGNR_RELAIS_PLUS );
+			SET_OUTPIN(PIN_REGNR_LED3);
+		}
+		else{
+			CLEAR_OUTPIN( PIN_REGNR_RELAIS_PLUS );
+			CLEAR_OUTPIN(PIN_REGNR_LED3);
+		}
+	}
+	
+	if( Relais == PRE_CHARGE_RELAIS )
+	{
+		if(OnOff)
+			SET_OUTPIN( PIN_REGNR_RELAIS_PRECHA );
+		else
+			CLEAR_OUTPIN( PIN_REGNR_RELAIS_PRECHA );
+	}
+	if( Relais ==PWR_SUPPLY ) {
+		if(OnOff)
+			SET_OUTPIN( PIN_REGNR_PWR_SUPPLY );
+		else
+			CLEAR_OUTPIN( PIN_REGNR_PWR_SUPPLY );
+	}
+
+}
+
+
+
+
+
+
+
+
+
+uint16_t init_master_CAN0_fsm(MASTER_CAN0_STRUCT_t* s,BMS_SLAVE_CONFIGURATION_t* cellConfig,BMS_UI_CONFIGURATION_t* uiConfig) {
+	uint8_t slaveNr;
+	uint8_t i;
+	uint16_t stateActive;
+	//go thought all connected Slaves
+	for(slaveNr=0;slaveNr<CAN0_MAX_NR_OF_SLAVES-1;slaveNr++) {
+			
+			// set slave Type
+			s->Slave[slaveNr].SlaveType=cellConfig[slaveNr].type;
+			s->Slave[slaveNr].TxMailbox_ptr=MB_Container[slaveNr];
+			s->Slave[slaveNr].TxTelegram_ptr=&TelegramTxContainer[slaveNr];
+			s->Slave[slaveNr].SlaveConnectionState=cellConfig[slaveNr].connectionSate;
+			
+			// set initial Voltage and Temp value to 0xffff = not initialzied
+			
+			for(i=0;i<MAX_SLAVE_CELLS;i++) {
+				s->Slave[slaveNr].CellVoltage[i]=0xffff;
+				s->Slave[slaveNr].CellTemp[i]=-51;
+				s->Slave[slaveNr].CellConnectionState[i]=cellConfig[slaveNr].cellConnectionState[i];
+				s->Slave[slaveNr].TempSensConnectionState[i]=cellConfig[slaveNr].tempSensConnectionState[i];
+			}
+			s->Slave[slaveNr].HeatSinkTemp=-51;
+			
+			// set slave alive cnt to 0xff fot not initialized
+			for(i=0;i<CAN0_NR_OF_TELEGRAMS;i++) {
+				s->Slave[slaveNr].SlaveAliveCnt[i]=0xff;
+			}
+			
+			// set slave Status to 0xff for Not initialized
+			s->Slave[slaveNr].SlaveMode=0xff;
+			// no Errors
+			s->Slave[slaveNr].SlaveError =0 ;
+			
+			// first State Running mode
+			s->Slave[slaveNr].Set_Mode = BMS_SLAVE_RUN ;
+			// No Balancing
+			s->Slave[slaveNr].Balance_Cell_0_7=0;
+			s->Slave[slaveNr].Balance_Cell_8_15=0;
+			s->Slave[slaveNr].Balance_Cell_16_23=0;
+			
+			// set Slave Error to 0
+			s->Slave[slaveNr].SlaveCanCommuniationError.FailedComCnt=0;
+			s->Slave[slaveNr].SlaveCanCommuniationError.SlaveErrorCounterRegister=0;
+			s->Slave[slaveNr].SlaveCanCommuniationError.SlaveErrorStateRegister=0;
+			s->Slave[slaveNr].SlaveCanCommuniationError.WrongAliveCnt=0;
+			
+			s->Slave[slaveNr].MasterAliveCnt=0;
+			s->Slave[slaveNr].maxCellTemp=0;
+			s->Slave[slaveNr].minCellTemp=0;			
+		}
+	
+	// init UI
+	
+	s->Slave[15].SlaveType=uiConfig->type;
+	s->Slave[15].TxMailbox_ptr=MB_Container[15];
+	s->Slave[15].TxTelegram_ptr=&TelegramTxContainer[15];
+	s->Slave[15].SlaveConnectionState=uiConfig->connectionSate;
+	
+	s->Slave[15].SlaveMode=0xff;
+	// no Errors
+	s->Slave[15].SlaveError =0 ;
+	
+	// first State Running mode
+	s->Slave[15].Set_Mode = BMS_SLAVE_RUN ;
+
+	
+	// set Slave Error to 0
+	s->Slave[15].SlaveCanCommuniationError.FailedComCnt=0;
+	s->Slave[15].SlaveCanCommuniationError.SlaveErrorCounterRegister=0;
+	s->Slave[15].SlaveCanCommuniationError.SlaveErrorStateRegister=0;
+	s->Slave[15].SlaveCanCommuniationError.WrongAliveCnt=0;
+	
+		
+	// set State to INIT
+	s->FsmState=INIT;
+	s->slaveSelect=0;
+	s->transmission_pending=FALSE;
+	s->cycleCounter=0;
+	s->cycleTimestamp=0;
+	s->StateOfCharge=40*60*60*1000; // 40Ah in mAs
+	s->allValuesInitialized = FALSE;
+	s->startCan1Comm=FALSE;
+	s->balancerState=BMS_BALANCE_INIT;
+	
+
+	s->SoC_initialized=FALSE;
+	s->SoC_outside=0;
+	s->maxHeatSinkTemp=0;
+	s->NrOfSlaves= get_nr_of_connected_slaves(s);
+	
+	s->CAN1_fsmStruct.fsmState=CAN1_FSM_INIT;
+	s->CAN1_fsmStruct.highPrioMsgNr=0;
+	s->CAN1_fsmStruct.lowPrioMsgNr=0;
+	s->CAN1_fsmStruct.requestTelegramNr=0;
+	s->CAN1_fsmStruct.timeoutCyclesCnt=0;
+	s->CAN1_fsmStruct.receivedTelegrams=0;
+	s->CAN1_fsmStruct.fastRequestFsmRunning=FALSE;
+	s->CAN1_fsmStruct.slowRequestFsmRunning=FALSE;
+	s->CAN1_fsmStruct.fastRxState=CAN1_FAST_RX_FSM_REQUEST_BATTERY_CURRENT;
+	s->CAN1_fsmStruct.nrOfRecCurrentSamples=0;
+	
+	s->FsmErrorState=ERROR_INIT;
+	//s->ErrorStack.ErrorNr=0;
+	//s->RunMode=RUN_MODE_INIT;
+	s->ErrorFlags=0;
+	// celar Error Buffers
+	ErrorStackClearBuffer(s); 
+	
+	// set Operation fsms to idle
+	s->RunMode.OperationMode=OP_MODE_INIT;
+	s->RunMode.ErrorState1fsm=ES1_FSM_INIT;
+	s->RunMode.ErrorState2fsm=ES2_FSM_INIT;
+	s->RunMode.ErrorState3fsm=ES3_FSM_INIT;
+	// init master temp sensor
+	s->masterTemp=18;
+	s->MasterTempSensState=BMS_MASTER_TEMP_SENSOR_INITIATE_MEASUREMENT;
+	s->inverterState.state=RCT_INV_INACTIVE;
+	s->inverterState.inverterCanOnline=FALSE;
+	s->inverterState.inverterIsCharging=FALSE;
+	s->inverterState.startupPwr=0;
+	
+	// assign impossible values to be able to check if values have been initialized
+	s->inverter.rxStruct.expectedInputPower=-1;
+	s->inverter.rxStruct.DCinputA_power=-1;
+	s->inverter.rxStruct.DCinputB_power=-1;
+	
+	BMS_Clear_Error_init_recovery_struct(s);//clear recovery struct
+	s->ErrorBuffer.ES2_New_Error=0;
+	s->relayState.HS_closed=0;
+	s->relayState.LS_closed=0;
+	s->relayState.PRECHARGE_closed=0;
+	s->relayState.reseved=0;
+	
+	s->reset_test_timestamp=0;
+
+	BMS_RCT_init_fsm(s);
+	initUIFifo(s);
+}
+	
+
+
+void set_slave_cell_connection_state(MASTER_CAN0_STRUCT_t* s,uint8_t slaveNr,CELL_STATE_t* cell_state){
+	uint8_t i;
+	for(i=0;i<MAX_SLAVE_CELLS;i++) {
+		s->Slave[slaveNr].CellConnectionState[i]=cell_state[i];
+	}
+}
+
+void set_slave_temp_connection_state(MASTER_CAN0_STRUCT_t* s,uint8_t slaveNr,TEMP_SENSOR_STATE_t* temp_state){
+	uint8_t i;
+	for(i=0;i<MAX_SLAVE_CELLS;i++) {
+		s->Slave[slaveNr].TempSensConnectionState[i]=temp_state[i];
+	}
+}
+
+uint8_t check_slave_data(MASTER_CAN0_STRUCT_t* s,
+		BMS_CAN0_SLAVE_t* Slave,
+		BMS_CAN0_SLAVE_t* tempSlave,
+		int8_t overTemp_charge,
+		int8_t overTemp_discharge,
+		int8_t underTemp_charge,
+		int8_t underTemp_discharge,
+		uint16_t overVoltage,uint16_t underVoltage) {
+	uint8_t i;
+	uint8_t error_status=BMS_SLAVE_DATA_OK;
+	uint16_t current=s->UI_Board.Ibatt*10;
+	
+	// Check Slave Mode
+	if(tempSlave->SlaveMode==BMS_SLAVE_RUN) {
+		// everything OK
+		
+		
+		//check Slave Alive Counter
+		
+		//if Failed communication counter is grater than 0  the communication
+		//attempt last Cycle failed and the alive counters are out of sync
+		if(tempSlave->SlaveCanCommuniationError.FailedComCnt>0) {
+			//
+			for(i=0;i<CAN0_NR_OF_TELEGRAMS;i++) {
+				Slave->SlaveAliveCnt[i]=tempSlave->SlaveAliveCnt[i];
+			}
+			tempSlave->SlaveCanCommuniationError.FailedComCnt=0;
+		}
+		//compare all Slave Alive Counter
+		else{
+			for(i=0;i<CAN0_NR_OF_TELEGRAMS;i++) {
+				if(	(tempSlave->SlaveAliveCnt[i] == Slave->SlaveAliveCnt[i] + 1) ||
+					(Slave->SlaveAliveCnt[i] ==0x7 && tempSlave->SlaveAliveCnt[i] ==0) ) {
+					// Slave Alive Counter == OK
+					Slave->SlaveAliveCnt[i]=tempSlave->SlaveAliveCnt[i];
+					Slave->SlaveCanCommuniationError.WrongAliveCnt=0;
+				}
+				else {
+					// slave Alive Counter didn't change or made bigger steps
+				
+					Slave->SlaveCanCommuniationError.WrongAliveCnt++;
+					if(Slave->SlaveCanCommuniationError.WrongAliveCnt>=CAN0_MAX_NR_OF_FAILED_COM) {
+						error_status|=BMS_SLAVE_DATA_ERROR_ALIVE_TIMEOUT;
+						// set CAN ERROR
+						ErrorStackPushMasterError(s,BMS_ERROR_STACK_SLAVE_CAN_ERROR,BMS_ERROR_CLASS_1);
+						return error_status;
+					}
+					for(i=0;i<CAN0_NR_OF_TELEGRAMS;i++) {
+						Slave->SlaveAliveCnt[i]=tempSlave->SlaveAliveCnt[i];
+					}
+					error_status |=BMS_SALVE_DATA_ERROR_ALIVE_CNT;
+					return error_status;
+
+				}
+			}
+		}
+		
+		// check voltages
+		// discard uninitialized values 0xff and Bypassed cells
+		for(i=0;i<MAX_SLAVE_CELLS;i++){
+			if(tempSlave->CellConnectionState[i]==CELL_BYPASSED) {
+				// no cell == no voltage 
+				tempSlave->CellVoltage[i]=0;
+			}
+			else if(tempSlave->CellConnectionState[i]==CELL_CONNECTED && tempSlave->CellVoltage[i]>= 0xfff8 ) {
+				// not initialized cells
+				//TODO decide upon signed unsigned representation
+				// use old value
+				tempSlave->CellVoltage[i]= Slave->CellVoltage[i];
+				
+			}
+			if( (tempSlave->CellVoltage[i] >= overVoltage || tempSlave->CellVoltage[i] <= underVoltage) 
+				&& tempSlave->CellConnectionState[i]==CELL_CONNECTED) {
+				//copy Slave to record current Errors
+				*Slave=*tempSlave;
+				error_status |=BMS_SLAVE_DATA_ERROR_VOLTAGE_LIMIT;
+				
+				// Write Error Stack
+				if(tempSlave->CellVoltage[i] >= overVoltage ) {
+					
+					ErrorStackPushSlaveError(s,s->slaveSelect,BMS_ERROR_STACK_SLAVE_OVER_VOLTAGE,i,BMS_ERROR_CLASS_3);
+					error_status |=BMS_SLAVE_DATA_ERROR_OVER_VOLTAGE;
+				}
+				else {
+					
+					ErrorStackPushSlaveError(s,s->slaveSelect,BMS_ERROR_STACK_SLAVE_UNDER_VOLTAGE,i,BMS_ERROR_CLASS_3);
+					error_status |=BMS_SLAVE_DATA_ERROR_UNDER_VOLTAGE;
+				}
+				
+				return error_status;
+			}
+			
+		}
+		
+		if(tempSlave->HeatSinkTemp >= BMS_ERROR_THRESHOLD_T_HEATSINK_MAX || tempSlave->HeatSinkTemp <= BMS_ERROR_THRESHOLD_T_HEATSINK_MIN){
+			//copy Slave to record current Errors
+			*Slave=*tempSlave;
+			error_status |=BMS_SLAVE_DATA_ERROR_HEAT_SINK_LIMIT;
+			// Write Error Stack
+			if(tempSlave->HeatSinkTemp >= BMS_ERROR_THRESHOLD_T_HEATSINK_MAX  ) {
+				// Has to be defined
+				
+			}
+			else {
+				// has to be defined
+			}
+			return error_status;
+		}
+		
+		//check cell temperatures		
+		for(i=0;i<MAX_SLAVE_CELLS;i++){
+			
+			if (tempSlave->CellTemp[i] > -40) {
+				//toDo: QUICKFIX FOR INITIALIZED SENSORS
+				
+				if(current < -100 ) {
+					// battery is charged
+					if( (tempSlave->CellTemp[i] >= overTemp_charge || tempSlave->CellTemp[i] <= underTemp_charge) 
+						&& tempSlave->TempSensConnectionState[i] ==TEMP_SENSOR_CONNECTED) {
+						//copy Slave to record current Errors
+						*Slave=*tempSlave;
+						error_status |=BMS_SLAVE_DATA_ERROR_TEMP_LIMIT;
+						
+						// Write Error Stack
+						if(tempSlave->CellTemp[i] >= overTemp_charge  ) {
+							ErrorStackPushSlaveError(s,s->slaveSelect,BMS_ERROR_STACK_SLAVE_OVER_TEMP_CHARGE,i,BMS_ERROR_CLASS_3);
+							
+						}
+						else {
+							ErrorStackPushSlaveError(s,s->slaveSelect,BMS_ERROR_STACK_SLAVE_UNDER_TEMP_CHARGE,i,BMS_ERROR_CLASS_3);
+						}
+						return error_status;
+					}	
+				}
+				else {
+					// battery is discharged
+					if( (tempSlave->CellTemp[i] >= overTemp_discharge || tempSlave->CellTemp[i] <= underTemp_discharge) 
+						&& tempSlave->TempSensConnectionState[i] ==TEMP_SENSOR_CONNECTED) {
+						//copy Slave to record current Errors
+						*Slave=*tempSlave;
+						error_status |=BMS_SLAVE_DATA_ERROR_TEMP_LIMIT;
+						
+						// Write Error Stack
+						if(tempSlave->CellTemp[i] >= overTemp_discharge  ) {
+							ErrorStackPushSlaveError(s,s->slaveSelect,BMS_ERROR_STACK_SLAVE_OVER_TEMP_DISCHARGE,i,BMS_ERROR_CLASS_3);
+							
+						}
+						else {
+							ErrorStackPushSlaveError(s,s->slaveSelect,BMS_ERROR_STACK_SLAVE_UNDER_TEMP_DISCHARGE,i,BMS_ERROR_CLASS_3);
+						}
+						return error_status;
+					}						
+				}
+			}
+		}
+		
+
+	
+		*Slave=*tempSlave;
+		return error_status; //everything should be ok
+	}
+}
+
+uint8_t check_UI_data(BMS_CAN0_SLAVE_t* Slave, BMS_CAN0_SLAVE_t* tempSlave,BMS_CAN0_UI_t* ui,BMS_CAN0_UI_t* tempUI) {
+	// todo Check Alive Cnt
+	// Check Over current etc
+	uint8_t i=0;
+	
+	if(tempUI->Ibatt > 50) {
+		i++;
+	}
+	
+	ui->Ubatt=tempUI->Ubatt;
+	ui->Ibatt=tempUI->Ibatt;
+	ui->Checksum=tempUI->Checksum;
+	return BMS_SLAVE_DATA_OK;
+}
+
+/**
+ * @brief calculate Voltage of Slave Board By adding cell voltages
+ */
+uint32_t calc_block_voltage(BMS_CAN0_SLAVE_t* Slave) {
+	uint32_t blockVoltage=0;
+	uint8_t i=0;
+	for(i=0;i<MAX_SLAVE_CELLS;i++) {
+		if(Slave->CellConnectionState[i]==CELL_CONNECTED) {
+			blockVoltage += Slave->CellVoltage[i];
+		}
+	}
+	return blockVoltage;
+}
+
+/**
+ * @brief calculate min and Max Voltage of Block
+ */
+uint32_t calc_min_max_voltage_slave(BMS_CAN0_SLAVE_t* Slave) {
+	uint16_t minV=Slave->CellVoltage[0];
+	uint16_t maxV=Slave->CellVoltage[0];
+	uint8_t i=0;
+	for(i=0;i<MAX_SLAVE_CELLS;i++) {
+		if(Slave->CellConnectionState[i]==CELL_CONNECTED) {
+			if(minV >= Slave->CellVoltage[i]) {
+				minV = Slave->CellVoltage[i];	
+			}
+			if(maxV <= Slave->CellVoltage[i]) {
+				maxV = Slave->CellVoltage[i];	
+			}			
+		}
+
+	}
+	Slave->minCellVoltage=minV;
+	Slave->maxCellVoltage=maxV;
+	return TRUE;
+}
+
+/**
+ * @brief calculate min and Max Voltage of System
+ */
+uint32_t calc_min_max_voltage_system(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t slave_nr=0;
+	uint16_t minV=BMS_SLAVE_MAX_CELL_VOLTAGE;
+	uint16_t maxV=BMS_SLAVE_MIN_CELL_VOLTAGE;
+	BMS_CAN0_SLAVE_t* Slave;
+	for(slave_nr=0;slave_nr<CAN0_MAX_NR_OF_SLAVES -1 ;slave_nr++) {
+		if(s->Slave[slave_nr].SlaveConnectionState != NOT_CONNECTED ) {
+			//slave is connected
+			Slave=&(s->Slave[slave_nr]);
+			if(Slave->maxCellVoltage >=maxV ) {
+				maxV = Slave->maxCellVoltage;
+			}
+			if(Slave->minCellVoltage <= minV) {
+				minV = Slave->minCellVoltage;
+			}
+		}
+	}
+	s->minCellVoltage=minV;
+	s->maxCellVoltage=maxV;
+	return TRUE;
+}
+
+/*
+ * set balancing register for cell_nr 
+ */
+uint32_t balance_cell(BMS_CAN0_SLAVE_t* Slave,uint8_t cell_nr) {
+	if( cell_nr <8) {
+		Slave->Balance_Cell_0_7|= (1<<cell_nr);
+		return TRUE;
+	}
+	else if(cell_nr <16) {
+		Slave->Balance_Cell_8_15|=(1<<(cell_nr-8));
+		return TRUE;
+	}
+	else {
+		Slave->Balance_Cell_16_23|=(1<<(cell_nr-16));
+		return TRUE;		
+	}
+	
+	return FALSE;
+}
+
+/**
+ * go though all slaves, destinguish slaves to balance and set Balancearray
+ */
+uint32_t set_balancer(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t slave_nr=0;
+	uint8_t cell_nr=0;
+	BMS_CAN0_SLAVE_t* Slave;
+	
+	for(slave_nr=0;slave_nr < CAN0_MAX_NR_OF_SLAVES -1 ;slave_nr++) {	// -1 because slave 15 is UI
+		if(s->Slave[slave_nr].SlaveConnectionState != NOT_CONNECTED) {
+			// slave is connected
+			Slave=&(s->Slave[slave_nr]);
+			
+			
+			if(Slave->maxCellVoltage - s->minCellVoltage > SLAVE_BALANCE_MIN_DELTA_U_MV) {
+				// blancing neccessay
+				for(cell_nr=0;cell_nr <MAX_SLAVE_CELLS;cell_nr++) {
+					if(Slave->CellConnectionState[cell_nr]==CELL_CONNECTED) {
+						// cell is connected
+						if(Slave->CellVoltage[cell_nr] - s->minCellVoltage > SLAVE_BALANCE_MIN_DELTA_U_MV) {
+							// cell has to be balanced
+							balance_cell(Slave,cell_nr);
+						}
+					}
+				}
+			}
+			else {
+				// no need to balance				
+			}
+
+		}
+		
+	}
+	
+}
+
+/**
+ * set all balance registers to off
+ */
+uint32_t set_balancer_off(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t slave_nr=0;
+	BMS_CAN0_SLAVE_t* Slave;
+	for(slave_nr=0;slave_nr < CAN0_MAX_NR_OF_SLAVES -1 ;slave_nr++) {
+		Slave=&(s->Slave[slave_nr]);
+		Slave->Balance_Cell_0_7=0;
+		Slave->Balance_Cell_16_23=0;
+		Slave->Balance_Cell_8_15=0;		
+	}
+	return TRUE;
+}
+
+
+/**
+ * @brief set min and Max Cell Temperature
+ *  */
+
+uint32_t set_block_min_max_temp(BMS_CAN0_SLAVE_t* Slave){
+	uint8_t	i;
+	int8_t maxTemp=25;
+	int8_t minTemp=25;
+	for(i=0;i<MAX_SLAVE_CELLS;i++) {
+		if(Slave->TempSensConnectionState[i]==TEMP_SENSOR_CONNECTED){
+			if(Slave->CellTemp[i] > maxTemp) {
+				maxTemp=Slave->CellTemp[i];
+			}
+			if(Slave->CellTemp[i] < minTemp) {
+				minTemp=Slave->CellTemp[i];
+			}
+		}
+	}
+	Slave->maxCellTemp=maxTemp;
+	Slave->minCellTemp=minTemp;
+}
+
+/**
+ * @brief set min and Max Cell Temperature of System
+ *  */
+
+uint32_t set_system_min_max_temp(MASTER_CAN0_STRUCT_t* s){
+	uint8_t	i;
+	int8_t maxTemp=25;
+	int8_t minTemp=25;
+	BMS_CAN0_SLAVE_t* Slave;
+	
+	for(i=0;i<CAN0_MAX_NR_OF_SLAVES;i++) {
+		if(s->Slave[i].SlaveConnectionState!=NOT_CONNECTED && s->Slave[i].SlaveType == SLAVE) {
+			Slave=&(s->Slave[i]);
+			if(Slave->maxCellTemp > maxTemp) {
+				maxTemp=Slave->maxCellTemp;
+			}
+			if(Slave->minCellTemp < minTemp) {
+				minTemp=Slave->minCellTemp;
+			}
+		}
+	}
+	s->maxCellTemp=maxTemp;
+	s->minCellTemp=minTemp;
+}
+
+uint32_t set_system_min_max_heatsink_temp(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	int8_t maxTemp=25;
+	int8_t minTemp=25;
+	BMS_CAN0_SLAVE_t* Slave;
+	
+	for(i=0;i<CAN0_MAX_NR_OF_SLAVES;i++) {
+		if(s->Slave[i].SlaveConnectionState!=NOT_CONNECTED &&s->Slave[i].SlaveType == SLAVE) {
+			Slave=&(s->Slave[i]);
+			if(Slave->HeatSinkTemp > maxTemp) {
+				maxTemp=Slave->HeatSinkTemp;
+			}
+			if(Slave->HeatSinkTemp < minTemp) {
+				minTemp=Slave->HeatSinkTemp;
+			}
+		}
+	}
+	s->maxHeatSinkTemp=maxTemp;
+	s->minHeatSinkTemp=minTemp;
+	
+	return 0;
+}
+
+/**
+ * @brief calculate Voltage of System by adding block voltages
+ */
+uint32_t calc_system_voltage(MASTER_CAN0_STRUCT_t* s) {
+	uint32_t systemVoltage=0;
+	uint8_t i=0;
+	for(i=0;i<CAN0_MAX_NR_OF_SLAVES;i++) {
+		if(s->Slave[i].SlaveConnectionState!=NOT_CONNECTED && s->Slave[i].SlaveType == SLAVE ) {
+			systemVoltage += s->Slave[i].BlockVoltage;
+		}
+	}
+	return systemVoltage;
+}
+
+/**
+ * @bief calculate SOC by simple coulomb counting
+ */
+void calc_system_SoC(MASTER_CAN0_STRUCT_t* s) {
+	s->StateOfCharge = s->StateOfCharge - s->UI_Board.Ibatt*10 *200; // t=200ms ibatt in 10mA steps
+}
+
+/**
+ * @brief convert inverter data into correct data types
+ */
+void refresh_inverter_tx_data(MASTER_CAN0_STRUCT_t* s) {
+	BMS_CAN1_INVERTER_TX* inv=&(s->inverter.txStruct);
+	inv->Values.batteryCapacity.value=36.0;
+	shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.batteryCapacity.value));
+	inv->Values.batteryCurrent.value=( (float)(s->UI_Board.Ibatt) )/100 ;
+	shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.batteryCurrent.value));
+	inv->Values.batterySOC.value=s->SoC_estimator.SoC_percentage_smooth;
+	shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.batterySOC.value));
+	inv->Values.batterySOCtarget.value=(float)-1.0;
+	shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.batterySOCtarget.value));
+	inv->Values.batterySOH.value=(float)1.0;
+	shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.batterySOH.value));
+	inv->Values.batteryStatus.byte6=0;
+	shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.batteryStatus.byte6));
+	inv->Values.batteryTemperature.value=(float)s->maxCellTemp;
+	shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.batteryTemperature.value));
+	inv->Values.batteryVoltage.value=( (float)(s->systemVoltage)) /1000.0;
+	shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.batteryVoltage.value));
+	inv->Values.maxBatteryChargeCurrent.value=s->SoC_estimator.MaxBatteryChargeCurrent;
+	shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.maxBatteryChargeCurrent.value));
+	inv->Values.maxBatteryChargeVoltage.value=s->startupConfig.maxBatteryVoltage;
+	shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.maxBatteryChargeVoltage.value));
+	inv->Values.maxBatteryDischargeCurrent.value=s->SoC_estimator.MaxBatteryDischargeCurrent;
+	shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.maxBatteryDischargeCurrent.value));
+	inv->Values.minBatteryDischargeVoltage.value=s->startupConfig.minBatteryVoltage;
+	shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.minBatteryDischargeVoltage.value));
+	
+	if(s->relayState.HS_closed == TRUE && s->relayState.LS_closed == TRUE && s->relayState.PRECHARGE_closed == TRUE) {
+		inv->Values.batteryModeExtra.value = 0;
+		
+	}
+	else {
+		inv->Values.batteryModeExtra.value = 1;
+		shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.batteryModeExtra.value));
+	}
+	//inv->Values.batteryMode.value=(uint32_t)(s->RunMode);
+	//shuffle_lsb_msb_can1((uint8_t*)&(inv->Values.batteryMode.value));
+}
+
+void shuffle_lsb_msb_can1(uint8_t* value) {
+	uint8_t tempValue[4];
+	tempValue[3]=value[0];
+	tempValue[2]=value[1];
+	tempValue[1]=value[2];
+	tempValue[0]=value[3];
+	
+	value[0]=tempValue[0];
+	value[1]=tempValue[1];
+	value[2]=tempValue[2];
+	value[3]=tempValue[3];
+}
+
+
+uint8_t check_if_all_values_are_initialized(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t slaveNr;
+	uint8_t cellNr;
+	for(slaveNr=0;slaveNr<CAN0_MAX_NR_OF_SLAVES-1;slaveNr++){
+		if(s->Slave[slaveNr].SlaveConnectionState != NOT_CONNECTED) {
+			for(cellNr=0;cellNr<MAX_SLAVE_CELLS;cellNr++) {
+				if(s->Slave[slaveNr].CellConnectionState[cellNr]==CELL_CONNECTED) {
+					if(s->Slave[slaveNr].CellVoltage[cellNr] == 0xffff) {
+						return FALSE;
+					}
+				}
+				if(s->Slave[slaveNr].TempSensConnectionState[cellNr] == TEMP_SENSOR_CONNECTED) {
+					if(s->Slave[slaveNr].CellTemp[cellNr] == -1) {
+						return FALSE;
+					}
+				}
+			}
+		}
+		
+	}
+	return TRUE;
+}
+
+/**
+ * @brief Handles communication with Slave-Boards over CAN0 interface
+ * @param	s pointer to state variable
+ * @param	time	current timestamp in ms
+ * 
+ * Master_CAN0_fsm is a finite state machine which handles the commuinication between Master and Slave boards.
+ * It requests Data from the Slaves by sending an Request telegram, and saves the received data in the
+ * provided MASTER_CAN0_STRUCT. It records CAN BUS Errors and hands these information to the Master_CAN0_ERROR_fsm. 
+ */	
+uint16_t Master_CAN0_fsm(MASTER_CAN0_STRUCT_t* s,uint32_t time) {
+	CAN_CONFIG *config;
+	int8_t can_state=CAN_OK;
+	uint8_t data_state=0;
+	uint8_t ui_state=FALSE;
+	switch(s->FsmState) {
+		case INIT:
+			s->slaveSelect=0;
+			s->cycleTimestamp=time;
+			s->FsmState=CHECK_IF_SLAVE_ACTIVE;
+			s->cycleCounter++;
+			return TRUE;
+		break;
+		case CHECK_IF_SLAVE_ACTIVE:
+			// transmitt data to Inverter
+				if(s->SoC_initialized==TRUE && s->allValuesInitialized ==TRUE) {
+					//Master_CAN1_Inverter_fsm( s,&(s->CAN1_fsmStruct)) ;
+					Master_CAN1_select_comm_mode ( s,&(s->CAN1_fsmStruct)) ;
+				}
+				// Update Master temp sensor
+				readMasterTempSensorFsm(s);
+			s->timestamp=Global_1msCounter;
+			if(s->Slave[s->slaveSelect].SlaveConnectionState == NOT_CONNECTED) {
+				s->FsmState=WAIT_FOR_NEXT_SLAVE_TIMESLOT;
+				s->slaveSelect++;		// ignore and go to next slave
+				if(s->slaveSelect>=CAN0_MAX_NR_OF_SLAVES) {
+					s->slaveSelect=0;
+					s->FsmState=WAIT_FOR_NEXT_COMMUNICATION_CYCLE;
+				}
+				return TRUE;
+			}
+			else{
+				s->Slave[s->slaveSelect].SlaveTelegramsRecFlag=0;	// no Telegrams recoredet yet
+				s->FsmState=SEND_REQUEST_TELEGRAM;
+				
+				return TRUE;
+			}
+		break;	
+		case SEND_REQUEST_TELEGRAM:
+			s->transmission_pending=TRUE;
+			CAN0_tx_send_request_telegram(&(s->Slave[s->slaveSelect]),s->Slave[s->slaveSelect].MasterAliveCnt);
+			s->Slave[s->slaveSelect].MasterAliveCnt++;
+			if(s->Slave[s->slaveSelect].MasterAliveCnt >=CAN0_NR_OF_TELEGRAMS) {
+				s->Slave[s->slaveSelect].MasterAliveCnt=0;
+			}
+			
+			if(s->Slave[s->slaveSelect].SlaveType==SLAVE) {
+				s->tempSlave=s->Slave[s->slaveSelect];
+			}
+			else {
+				s->tempSlave=s->Slave[s->slaveSelect];
+				s->temp_UI_Board=s->UI_Board;
+			}
+			s->FsmState=WAIT_FOR_SLAVE_RESPONSE;
+			return TRUE;
+		break;
+		case WAIT_FOR_SLAVE_RESPONSE:
+			config= s->tempSlave.TxMailbox_ptr->p_CAN_Config;
+			//can_state=CAN_Check_error_Register(config);
+			if(s->tempSlave.SlaveType==SLAVE) {
+				if(s->tempSlave.SlaveConnectionState == CONNECTED) {
+					// real slave with real Sensors
+					CAN0_check_if_slave_rec(&(s->tempSlave));
+				}
+				else if(s->tempSlave.SlaveConnectionState == DEBUG_DATA_SIMULATED) {
+					// real slave with simulated Sensors
+					CAN0_DEBUG_data_check_if_slave_rec((&s->tempSlave),&(gDUMMY_data_struct.Slave[s->slaveSelect]) );
+				}
+				else{
+					// simulated Slave
+					CAN0_DEBUG_slave_check_if_slave_rec((&s->tempSlave),&(gDUMMY_data_struct.Slave[s->slaveSelect]) );
+				}
+				
+				//all Telegrams received
+				if(s->tempSlave.SlaveTelegramsRecFlag==CAN0_ALL_TELEGRAMS_REC ) {
+					//s->slaveSelect++;				
+					if(can_state == CAN_OK) {
+						// all telegrams received => reset error counter
+						if(s->slaveSelect == 3) {
+							s->FsmState= CHECK_CAN_DATA;
+						}
+						s->Slave[s->slaveSelect].SlaveCanCommuniationError.FailedComCnt=0;
+						s->FsmState= CHECK_CAN_DATA;
+						return TRUE;
+					}
+					else {
+						s->FsmState =HANDLE_CAN_ERROR;
+						return TRUE;
+					}
+				}
+
+				//timeout
+				else if(s->timestamp + CAN0_TIMEOUT_MS <=Global_1msCounter) {
+					s->FsmState =HANDLE_CAN_ERROR;
+					return TRUE;
+				}
+				// wait
+				else {
+					s->FsmState =WAIT_FOR_SLAVE_RESPONSE;
+					return TRUE;				
+				}
+			}
+			else {
+				
+				
+				if(s->tempSlave.SlaveConnectionState == CONNECTED) {
+					// real UI with real Sensors
+					ui_state=CAN0_check_if_UI_Board_rec( &(s->tempSlave) ,&(s->temp_UI_Board));
+				}
+				else if(s->tempSlave.SlaveConnectionState == DEBUG_DATA_SIMULATED) {
+					// real UI with simulated Sensors
+					ui_state=CAN0_DEBUG_data_check_if_UI_Board_rec(&(s->tempSlave),
+							&(gDUMMY_data_struct.Slave[s->slaveSelect]),
+							&(s->temp_UI_Board),
+							&(gDUMMY_data_struct.UI_Board));
+				}
+				else{
+					// simulated UI
+					ui_state=CAN0_DEBUG_slave_check_if_UI_Board_rec(&(s->tempSlave),
+							&(gDUMMY_data_struct.Slave[s->slaveSelect]),
+							&(s->temp_UI_Board),
+							&(gDUMMY_data_struct.UI_Board));
+				}
+				
+				if(ui_state==TRUE) {
+					//s->slaveSelect++;
+					if(can_state==CAN_OK) {
+						s->FsmState= CHECK_CAN_DATA;
+						return TRUE;
+					}
+					else {
+						s->FsmState =HANDLE_CAN_ERROR;
+						return TRUE;
+					}
+					//return TRUE;					
+				}
+				//timeout
+				else if(s->timestamp + CAN0_TIMEOUT_MS <=time) {
+					s->FsmState =HANDLE_CAN_ERROR;
+					return TRUE;
+				}
+				// wait
+				else {
+					s->FsmState =WAIT_FOR_SLAVE_RESPONSE;
+					return TRUE;				
+				}				
+			}
+		break;
+		case CHECK_CAN_DATA:
+				// check if rx data is correct
+			
+			if(s->tempSlave.SlaveType ==SLAVE ) {
+				
+				s->ErrorFlags=check_slave_data(s,&(s->Slave[s->slaveSelect]),
+						&(s->tempSlave),
+						BMS_SLAVE_MAX_TEMP,
+						BMS_ERROR_THRESHOLD_T_DISCHARGE_MAX,
+						BMS_SLAVE_MIN_TEMP,
+						BMS_ERROR_THRESHOLD_T_DISCHARGE_MIN,
+						BMS_SLAVE_MAX_CELL_VOLTAGE,
+						BMS_SLAVE_MIN_CELL_VOLTAGE);
+
+				if(s->ErrorFlags & BMS_SLAVE_DATA_ERROR_ALIVE_TIMEOUT) {
+					s->FsmState =SHUT_DOWN_BMS;
+					return TRUE;
+				}
+				
+				if(s->ErrorFlags & BMS_SLAVE_DATA_ERROR_OVER_VOLTAGE) {
+					s->FsmState =SHUT_DOWN_BMS;
+					return TRUE;
+				}		
+				if(s->ErrorFlags & BMS_SLAVE_DATA_ERROR_UNDER_VOLTAGE) {
+					s->FsmState =SHUT_DOWN_BMS;
+					return TRUE;
+				}	
+				if((s->ErrorFlags & BMS_SLAVE_DATA_ERROR_TEMP_LIMIT) && (s->allValuesInitialized == TRUE)) {
+					s->FsmState =SHUT_DOWN_BMS;
+					return TRUE;
+				}
+				if(s->ErrorFlags & BMS_SLAVE_DATA_ERROR_HEAT_SINK_LIMIT) {
+					s->FsmState =SHUT_DOWN_BMS;
+					return TRUE;
+				}
+				if(s->ErrorFlags & BMS_SLAVE_DATA_ERROR_BOARD_ELECTRONIC) {
+					s->FsmState =SHUT_DOWN_BMS;
+					return TRUE;
+				}
+				else {
+					// everything ok
+					
+				}
+				
+				
+				
+			
+				
+			}
+			else {
+				data_state=check_UI_data(&(s->Slave[s->slaveSelect]),
+						&(s->tempSlave),
+						&(s->UI_Board),
+						&(s->temp_UI_Board));	
+				
+				if(s->allValuesInitialized==FALSE) {
+					s->allValuesInitialized=check_if_all_values_are_initialized(s);
+				}
+				
+
+				
+				// Check for "Soft" Errors and set Error states
+				
+
+				
+				
+			}
+			s->transmission_pending=FALSE;
+			
+			s->FsmState= DO_CALCULATIONS;
+			return TRUE;
+		break;
+		case DO_CALCULATIONS:
+			// calculate SoC SoH ?
+			if(s->Slave[s->slaveSelect].SlaveType==SLAVE) {
+				// calculate Slave Voltage
+				s->Slave[s->slaveSelect].BlockVoltage=calc_block_voltage(&(s->Slave[s->slaveSelect]));
+				// set min max Temp
+				set_block_min_max_temp(&(s->Slave[s->slaveSelect]));
+				// set min max Voltage
+				calc_min_max_voltage_slave(&(s->Slave[s->slaveSelect]));
+				
+				s->slaveSelect++;
+				s->FsmState=WAIT_FOR_NEXT_SLAVE_TIMESLOT;
+				return TRUE;
+			}
+			else {
+				
+				
+				
+				// UI-Platine
+				// calc SoC
+				s->systemVoltage=calc_system_voltage(s);
+				calc_min_max_voltage_system(s);
+				set_system_min_max_temp(s);
+				// update UI FIFO
+				popUIFiFo(s); 
+				
+				BMS_Set_Error_Check_voltage_inconsitency(s);
+				
+				// check if System voltage is too high
+				if(s->allValuesInitialized ==TRUE) {
+					// Check Umin 1 Umin2 Umin3
+					BMS_Set_Error_check_Voltage_level_min(s);
+					// Check Umax 1 and Umax 2
+					BMS_Set_Error_check_Voltage_level_max(s) ;
+					BMS_Set_Error_check_System_voltage_level_max(s);
+					
+					// check if CHECK Imax 
+					BMS_Set_Error_Check_derating(s); 
+					
+					
+					// make balancing decisions
+					Master_Balancer_fsm(s);
+				}
+				// if in Winter MOde get SoC from FRAM
+//				if(s->SoC_initialized==TRUE && s->allValuesInitialized ==FALSE && s->RunMode== RUN_MODE_WINTER) {
+//					bms_SoC_init_estimator_FRAM(&(s->SoC_estimator), s->maxCellVoltage);
+//				}
+				// calculate SoC of higest and Lowest Cell
+				if(s->SoC_initialized==FALSE && s->allValuesInitialized ==TRUE) {
+					set_system_min_max_heatsink_temp(s);
+					//set initial SoC
+					if(s->startupConfig.state.Bit.SOC_Initialized) {
+						// get initial SOC From FRAM
+						 bms_SoC_init_estimator_FRAM(&(s->SoC_estimator), s->maxCellVoltage);
+					}
+					else {
+						bms_SoC_init_estimator(&(s->SoC_estimator), s->maxCellVoltage) ;
+					}
+					initSoCFifo(s);
+					s->SoC_initialized=TRUE;
+					s->FsmState=RUNNING_MODE_FSM;
+				}
+				else if(s->SoC_initialized==TRUE && s->allValuesInitialized ==TRUE) {
+					set_system_min_max_heatsink_temp(s);
+					
+					// calc SoC 
+					
+					while(s->SoC_estimator.state != BMS_SOC_READY) {
+						bms_SoC_running_fsm( &(s->SoC_estimator),s->UI_Board.Ibatt*10 ,s->maxCellVoltage,s->minCellVoltage,s->minCellTemp,s->maxCellTemp); 
+					}	
+					s->SoC_estimator.state = BMS_SOC_IDLE   ;		
+					
+					// if soc is at 100% set SoC initialized Flag
+					if(s->SoC_estimator.SoC_percentage_smooth > 0.9999) {
+						s->startupConfig.state.Bit.SOC_Initialized=1;
+						write_fram_set_startup_state(s);
+					}
+					// write SoC to FRAM
+					else if(s->startupConfig.state.Bit.SOC_Initialized==1) {
+						write_fram_set_SoC(s->SoC_estimator.SoC_percentage_smooth);
+					}
+					s->slaveSelect=0;
+					
+					// transmitt data to Inverter
+					if(s->SoC_initialized==TRUE && s->allValuesInitialized ==TRUE) {
+						refresh_inverter_tx_data(s);
+						//Master_CAN1_Inverter_fsm( s,&(s->CAN1_fsmStruct)) ;
+					}
+					// set running Mode
+					
+					// update inverter state
+					BMS_RCT_Inverter_fsm (s);
+					s->FsmState=RUNNING_MODE_FSM;
+					return TRUE;
+				}
+				else {
+					// nothing happend yet
+					s->FsmState=RUNNING_MODE_FSM;
+					return TRUE;
+				}
+	
+			}
+			return TRUE;
+		break;
+		case RUNNING_MODE_FSM:
+			// set running Mode
+			RunningModeFSM(s) ;
+			s->FsmState=WAIT_FOR_NEXT_COMMUNICATION_CYCLE;
+			return TRUE;
+		break;
+		case HANDLE_CAN_ERROR:
+			// delete interrupt flags
+			CAN0_clear_all_interrupt_flags();
+				// handle CAN Errors
+			config= s->tempSlave.TxMailbox_ptr->p_CAN_Config;
+			//can_state=CAN_Check_error_Register(config);			
+			// all telegrams received, can telegrams disturbed
+			if(s->tempSlave.SlaveTelegramsRecFlag==CAN0_ALL_TELEGRAMS_REC ) {
+				// Telegram values could be disturbed => reject all received Data
+				// Don't use newly received data => ignore tempSlave
+				s->Slave[s->slaveSelect].SlaveCanCommuniationError.FailedComCnt++;
+				if(s->Slave[s->slaveSelect].SlaveCanCommuniationError.FailedComCnt >=CAN0_MAX_NR_OF_FAILED_COM) {
+					s->FsmState=SHUT_DOWN_BMS;
+					
+					//write Error
+					ErrorStackPushSlaveError(s,s->slaveSelect,BMS_ERROR_STACK_SLAVE_CAN_ERROR,0,BMS_ERROR_CLASS_2);
+					return TRUE;
+				}
+				s->FsmState=DO_CALCULATIONS;
+				return TRUE;
+				
+			}
+			// telegrams missing, CAN Channel Ok
+			else{
+				if(can_state == CAN_OK) {
+					// CAN BUS OK, Slave is not reacting
+					// Don't use newly received data
+					s->Slave[s->slaveSelect].SlaveCanCommuniationError.FailedComCnt++;
+					if(s->Slave[s->slaveSelect].SlaveCanCommuniationError.FailedComCnt >=CAN0_MAX_NR_OF_FAILED_COM) {
+						//write Error
+						ErrorStackPushSlaveError(s,s->slaveSelect,BMS_ERROR_STACK_SLAVE_CAN_ERROR,0,BMS_ERROR_CLASS_2);
+						s->FsmState=SHUT_DOWN_BMS;
+						s->reset_test_timestamp=Global_1msCounter;
+						return TRUE;
+					}
+					s->FsmState=DO_CALCULATIONS;
+					return TRUE;				
+				}
+				else{
+					// CAN BUS ERROR, telegrams not coming thought
+					// Don't use newly received data
+					s->Slave[s->slaveSelect].SlaveCanCommuniationError.FailedComCnt++;
+					if(s->Slave[s->slaveSelect].SlaveCanCommuniationError.FailedComCnt >=CAN0_MAX_NR_OF_FAILED_COM) {
+						//write Error
+						ErrorStackPushSlaveError(s,s->slaveSelect,BMS_ERROR_STACK_SLAVE_CAN_ERROR,0,BMS_ERROR_CLASS_2);
+						s->reset_test_timestamp=Global_1msCounter;
+						s->FsmState=SHUT_DOWN_BMS;
+						return TRUE;
+					}
+					s->FsmState=DO_CALCULATIONS;
+					return TRUE;
+				}
+			}
+
+			return TRUE;
+		break;
+		case WAIT_FOR_NEXT_SLAVE_TIMESLOT:
+			// next timesolt ready
+			
+			if(s->timestamp +CAN0_RASTER_MS <= time) {
+				s->FsmState= CHECK_IF_SLAVE_ACTIVE;
+				return TRUE;
+				}
+			//wait
+			else{
+				s->FsmState=WAIT_FOR_NEXT_SLAVE_TIMESLOT;
+				return TRUE;
+			}
+		break;
+		case SEND_RECEIVE_INVERTER_DATA:
+			// send data to inverter and Wait for response
+			//CAN1_tx_Data_to_Inverter(time,&(s->inverter.txStruct));
+			//request DC INPUT VOLTAGE
+			//CAN1_request_float_value(Global_1msCounter,&(s->inverter.rxStruct.DCinputA_power),CAN1_RX_DC_INPUT_A_VOLTAGE);
+			s->startCan1Comm=TRUE;
+			s->FsmState=WAIT_FOR_NEXT_COMMUNICATION_CYCLE;
+			return TRUE;	
+		break;	
+		case WAIT_FOR_NEXT_COMMUNICATION_CYCLE:
+			if(s->cycleTimestamp +CAN0_COMM_CYCLE_MS <= time) {
+				s->FsmState= INIT;
+				return TRUE;
+				}
+			else {
+				s->FsmState=WAIT_FOR_NEXT_COMMUNICATION_CYCLE;
+				return TRUE;
+			}
+			return TRUE; 	
+		break;
+		case SHUT_DOWN_BMS:
+				// Something went horribly wrong, turn off system
+			SwitchRelais( LS_RELAIS, 0);
+			SwitchRelais( PRE_CHARGE_RELAIS, 0);
+			SwitchRelais( HS_RELAIS, 0);
+			s->relayState.HS_closed=FALSE;
+			s->relayState.LS_closed=FALSE;
+			s->relayState.PRECHARGE_closed=FALSE;
+			CLEAR_OUTPIN(PIN_REGNR_LED4);	// set LED4 to 0 to indicate that an Error has occured 
+			
+			//write_fram_word(BMS_STARTUP_ERROR_MODE_3,3,BMS_STARTUP_MODE_ADDR);
+			// go to Error	Mode
+			
+			// continue communication cycles
+			s->FsmState=DO_CALCULATIONS;
+			
+			return TRUE;
+		break;
+		default:
+			return FALSE;
+		break;
+	}
+	return FALSE;
+}
+	
+
+
+
+uint16_t init_master_operation_fsm(BMS_MASTER_OPERATION_t* opFsm) {
+	opFsm->FsmState=MASTER_OPERATION_INIT;
+	opFsm->timestamp=0;
+
+	return TRUE;
+}
+
+
+
+
+uint16_t Master_CAN1_fsm_init(MASTER_CAN1_STRUCT_t* can1Fsm) {
+	can1Fsm->delay =3;
+	can1Fsm->fsmState=CAN1_INIT;
+	can1Fsm->txMsgNr=0;
+	return TRUE;
+}
+
+/*
+ * 
+ */
+uint32_t Master_CAN1_select_comm_mode (MASTER_CAN0_STRUCT_t* s,MASTER_CAN1_INVERTER_STRUCT_t* fsmStruct) {
+	if(fsmStruct->slowRequestFsmRunning == TRUE) {
+		// slow requests are running => wait till requests are complete
+		Master_CAN1_Inverter_fsm(s,fsmStruct);
+		// set fast request running flag for faast request asap
+		fsmStruct->fastRequestFsmRunning=TRUE;
+		return TRUE;
+	}
+	else if(s->Slave[s->slaveSelect].SlaveType== UI || fsmStruct->fastRequestFsmRunning==TRUE) {
+		// commuincation with UI is about to begin or fast request flag is set
+		// this means 250ms tick is reached => initiate fast request if possible
+		Master_CAN1_Fast_request_fsm (s,fsmStruct);
+		return TRUE;
+	}
+	else {
+		// nothing special run normal fsm
+		Master_CAN1_Inverter_fsm(s,fsmStruct);
+		return TRUE;
+	}
+}
+/*
+ * handles request of battery current and battery voltage from inverter
+ * which have to be sampled regulatly
+ */
+uint32_t Master_CAN1_Fast_request_fsm (MASTER_CAN0_STRUCT_t* s,MASTER_CAN1_INVERTER_STRUCT_t* fsmStruct) {
+	switch(fsmStruct->fastRxState) {
+		case CAN1_FAST_RX_FSM_REQUEST_BATTERY_CURRENT:
+			// request battery current from inverter
+			fsmStruct->nrOfRecCurrentSamples++;
+			CAN1_send_request_telegram(CAN1_RX_BATTERY_CURRENT);
+			fsmStruct->fastRequestFsmRunning=TRUE;
+			fsmStruct->fastRxState=CAN1_FAST_RX_FSM_REQUEST_BATTERY_VOLTAGE;
+			return TRUE;
+		break;	
+		case CAN1_FAST_RX_FSM_REQUEST_BATTERY_VOLTAGE:
+			// readout battery current and request battery voltage
+			if(CAN1_wait_for_response(&(s->inverter.rxStruct.batteryCurrent)) == TRUE ) {
+				// battery current received
+				pushInverterCurrentFIFO(s);
+				// compare UI Current and Inverter Current
+				if(fsmStruct->nrOfRecCurrentSamples > UI_CURRENT_FIFO_SIZE) {
+					// BMS_Set_Error_Check_current_consitency(s); //compare current of UI with Inverter
+				}
+			}
+			else {
+				// no response in 10ms => timeout
+				// go to normal communication fsm
+				fsmStruct->fastRxState = CAN1_FAST_RX_FSM_REQUEST_BATTERY_CURRENT;
+				fsmStruct->fastRequestFsmRunning=FALSE;
+				return TRUE;
+			}
+			// request battery voltage
+			CAN1_send_request_telegram(CAN1_RX_BATTERY_VOLTAGE);
+			fsmStruct->fastRxState =CAN1_FAST_RX_FSM_REQUEST_COMPLETE;
+			return TRUE;
+		break;
+		case CAN1_FAST_RX_FSM_REQUEST_COMPLETE:
+			// readout voltage
+			if(CAN1_wait_for_response(&(s->inverter.rxStruct.batteryVoltage)) == TRUE ) {
+				// battery voltage received
+			}
+			else {
+				// no response in 10ms => timeout
+				// go to normal communication fsm
+				fsmStruct->fastRxState = CAN1_FAST_RX_FSM_REQUEST_BATTERY_CURRENT;
+				fsmStruct->fastRequestFsmRunning=FALSE;
+				return TRUE;
+			}		
+			// fast requests done
+			fsmStruct->fastRxState = CAN1_FAST_RX_FSM_REQUEST_BATTERY_CURRENT;
+			fsmStruct->fastRequestFsmRunning=FALSE;	
+			return TRUE;
+		break;
+	}
+}
+
+
+
+uint32_t Master_CAN1_Inverter_fsm(MASTER_CAN0_STRUCT_t* s,MASTER_CAN1_INVERTER_STRUCT_t* fsmStruct) {
+	BMS_CAN1_INVERTER_TX* data = &(s->inverter.txStruct);
+	BMS_CAN1_INVERTER_CELL_DATA_t txPkg;
+	float* rx_ptr=&(s->inverter.rxStruct.expectedInputPower); 	// points to rx_address to sotre inverter value
+	uint8_t eightBitBuff[8]= {0,0,0,0,0,0,0,0} ;
+	switch(fsmStruct->fsmState) {
+		case CAN1_FSM_INIT:
+			// reset Message counters
+			fsmStruct->highPrioMsgNr=0;
+			fsmStruct->lowPrioMsgNr=0;
+			fsmStruct->requestTelegramNr=0;
+			fsmStruct->timeoutCyclesCnt=0;
+
+			
+			// check if all Values are initialized 
+			// if yes start transmitting
+			if(s->allValuesInitialized == TRUE) {
+				fsmStruct->fsmState=CAN1_FSM_SEND_HIGH_PRIO_DATA;
+				return TRUE;
+			}
+			// not all values are initialized
+			//=> stay in INIT state
+			return TRUE;
+		break;
+		case CAN1_FSM_SEND_HIGH_PRIO_DATA:
+			// rx process complete
+			fsmStruct->slowRequestFsmRunning=FALSE;
+			
+			// transmit high priority data, which is
+			// maximum charge Current
+			// maximum Charge Voltage
+			// maximum Discharge Current
+			// minimum Discharge Voltage
+			// battery Current
+			// battery Voltage
+			// Battery SoC
+			// Battery Capacity
+			// Battery Temperature
+			// Battery SoH
+			// Battery Status
+			// Battery SoC Target
+			
+			if(fsmStruct->highPrioMsgNr == 0) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.maxBatteryChargeCurrent),Global_1msCounter);
+			}
+			else if(fsmStruct->highPrioMsgNr == 1) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.maxBatteryChargeVoltage),Global_1msCounter);
+			}
+			else if(fsmStruct->highPrioMsgNr == 2) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.maxBatteryDischargeCurrent),Global_1msCounter);
+			}
+			else if(fsmStruct->highPrioMsgNr == 3) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.minBatteryDischargeVoltage),Global_1msCounter);
+			}
+			else if(fsmStruct->highPrioMsgNr == 4) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batteryCurrent),Global_1msCounter);
+			}
+			else if(fsmStruct->highPrioMsgNr == 5) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batteryVoltage),Global_1msCounter);
+			}
+			else if(fsmStruct->highPrioMsgNr == 7) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batterySOC),Global_1msCounter);
+			}
+			else if(fsmStruct->highPrioMsgNr == 8) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batteryCapacity),Global_1msCounter);
+			}
+			else if(fsmStruct->highPrioMsgNr == 9) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batteryTemperature),Global_1msCounter);
+			}
+			else if(fsmStruct->highPrioMsgNr == 10) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batterySOH),Global_1msCounter);
+			}
+			else if(fsmStruct->highPrioMsgNr == 11) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batterySOCtarget),Global_1msCounter);
+			}
+			else if(fsmStruct->highPrioMsgNr == 12) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batteryMode),Global_1msCounter);
+			}
+			else if(fsmStruct->highPrioMsgNr == 13) {
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batteryModeExtra),Global_1msCounter);
+			}
+			
+			// increment high prio msg cnt
+			fsmStruct->highPrioMsgNr++ ;
+			
+			// if all high prio msg are transmitted start transmitting low prio msg
+			if(fsmStruct->highPrioMsgNr > 13) {
+				fsmStruct->highPrioMsgNr=0;
+				// reset error cnt to start with error 1 again
+				fsmStruct->transmitErrorNrEs1=0;
+				fsmStruct->transmitErrorNrEs2=0;
+				fsmStruct->transmitErrorNrEs3=0;
+				fsmStruct->fsmState=CAN1_FSM_SEND_ES_1;
+				return TRUE;
+			}
+			else {
+				// continue Transmitting high Prio Msg
+				fsmStruct->fsmState=CAN1_FSM_SEND_HIGH_PRIO_DATA;
+				return TRUE;
+			}
+		break;
+		case CAN1_FSM_SEND_ES_1:
+			// send Error Calls 1 Errors
+			
+			if( !ErrorStackCheckForActiveErrors(s,BMS_ERROR_CLASS_1) && !ErrorStackCheckForActiveErrors(s,BMS_ERROR_CLASS_2) && ErrorStackCheckForActiveErrors(s,BMS_ERROR_CLASS_3) ) {
+				// no Error has occured Transmitt everything ok
+				CLEAR_OUTPIN(PIN_REGNR_LED4);
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(data->Values.batteryStatus),Global_1msCounter);
+				fsmStruct->fsmState=CAN1_FSM_SEND_LOW_PRIO_DATA;
+				return TRUE;
+			}
+			
+			else if(ErrorStackCheckForActiveErrors(s,BMS_ERROR_CLASS_3) && fsmStruct->transmitErrorNrEs3 < BMS_ERROR_ERROR_STACK_SIZE) {
+				// transmitt ES 3 Errors
+				// check if Error is active
+				SET_OUTPIN(PIN_REGNR_LED4);
+				while(s->ErrorBuffer.ES3_Error[fsmStruct->transmitErrorNrEs3].Master.active == 0){
+					// Error no ,longer Active go to next entry
+					fsmStruct->transmitErrorNrEs3++;
+					if(fsmStruct->transmitErrorNrEs3 >=BMS_ERROR_ERROR_STACK_SIZE) {
+						
+						return TRUE;
+					}
+				}
+				ErrorStackGenerateStatusPkg(eightBitBuff,(uint8_t*)&(s->ErrorBuffer.ES3_Error[fsmStruct->transmitErrorNrEs3]));
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, eightBitBuff,Global_1msCounter);
+				fsmStruct->transmitErrorNrEs3++;
+				return TRUE;
+			}
+			
+			else if(ErrorStackCheckForActiveErrors(s,BMS_ERROR_CLASS_2) && fsmStruct->transmitErrorNrEs2 < BMS_ERROR_ERROR_STACK_SIZE) {
+				// transmitt ES 2 Errors
+				// check if Error is active
+				SET_OUTPIN(PIN_REGNR_LED4);
+				while(s->ErrorBuffer.ES2_Error[fsmStruct->transmitErrorNrEs2].Master.active == 0){
+					// Error no ,longer Active go to next entry
+					fsmStruct->transmitErrorNrEs2++;
+					if(fsmStruct->transmitErrorNrEs2 >=BMS_ERROR_ERROR_STACK_SIZE) {
+						
+						return TRUE;
+					}
+				}
+				ErrorStackGenerateStatusPkg(eightBitBuff,(uint8_t*)&(s->ErrorBuffer.ES2_Error[fsmStruct->transmitErrorNrEs2]));
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, eightBitBuff,Global_1msCounter);
+				fsmStruct->transmitErrorNrEs2++;
+				return TRUE;
+			}
+			else if(ErrorStackCheckForActiveErrors(s,BMS_ERROR_CLASS_1) && fsmStruct->transmitErrorNrEs1 < BMS_ERROR_ERROR_STACK_SIZE) {
+				// transmitt ES 1 Errors
+				// check if Error is active
+				SET_OUTPIN(PIN_REGNR_LED4);
+				while(s->ErrorBuffer.ES1_Error[fsmStruct->transmitErrorNrEs1].Master.active == 0){
+					// Error no ,longer Active go to next entry
+					fsmStruct->transmitErrorNrEs1++;
+					if(fsmStruct->transmitErrorNrEs1 >=BMS_ERROR_ERROR_STACK_SIZE) {
+						
+						return TRUE;
+					}					
+				}
+				ErrorStackGenerateStatusPkg(eightBitBuff,(uint8_t*)&(s->ErrorBuffer.ES1_Error[fsmStruct->transmitErrorNrEs1]));
+				CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, eightBitBuff,Global_1msCounter);
+				fsmStruct->transmitErrorNrEs1++;
+				return TRUE;
+			}
+			else {
+				fsmStruct->fsmState=CAN1_FSM_SEND_LOW_PRIO_DATA;
+				return TRUE;
+			}
+		break;
+		case CAN1_FSM_SEND_LOW_PRIO_DATA:
+			// send low Priority data which is
+			// Cell temperature and Cell Voltages
+			generateCellInfoPkg(s, fsmStruct->lowPrioMsgNr,&txPkg);
+			CAN_Write_dataset(&CAN_Tx0_RCT_INVERTER, (uint8_t*)&(txPkg),Global_1msCounter);
+			fsmStruct->lowPrioMsgNr++ ;
+			if(fsmStruct->lowPrioMsgNr >= (s->NrOfSlaves)*MAX_SLAVE_CELLS) {
+				// start with cell nr 0 again
+				fsmStruct->lowPrioMsgNr=0;
+				fsmStruct->fsmState=CAN1_FSM_SEND_REQUEST_DATA;
+				fsmStruct->requestTelegramNr=0;
+				return TRUE;
+			}
+			fsmStruct->fsmState=CAN1_FSM_SEND_LOW_PRIO_DATA;
+			return TRUE;	
+		break;
+		case CAN1_FSM_SEND_REQUEST_DATA:
+			// request data from RCT Inverter
+			// Set flag so request process cant be interrupted 
+			fsmStruct->slowRequestFsmRunning=TRUE;
+			if(fsmStruct->requestTelegramNr==0) {
+				CAN1_send_request_telegram(CAN1_RX_TOTAL_DC_PWR);
+				fsmStruct->fsmState= CAN1_FSM_WAIT_FOR_RESPONSE;
+				return TRUE;
+			}
+			else if(fsmStruct->requestTelegramNr==1) {
+				CAN1_send_request_telegram(CAN1_RX_DC_INPUT_A_POWER);
+				fsmStruct->fsmState= CAN1_FSM_WAIT_FOR_RESPONSE;
+				return TRUE;				
+			}
+			else if(fsmStruct->requestTelegramNr==2) {
+				CAN1_send_request_telegram(CAN1_RX_DC_INPUT_B_POWER);
+				fsmStruct->fsmState= CAN1_FSM_WAIT_FOR_RESPONSE;
+				return TRUE;						
+			}
+			else if(fsmStruct->requestTelegramNr==3) {
+				CAN1_send_request_telegram(CAN1_RX_DC_INPUT_A_POWER);
+				fsmStruct->fsmState= CAN1_FSM_WAIT_FOR_RESPONSE;
+				return TRUE;						
+			}
+			else if(fsmStruct->requestTelegramNr==4) {
+				CAN1_send_request_telegram(CAN1_RX_DC_INPUT_B_POWER);
+				fsmStruct->fsmState= CAN1_FSM_WAIT_FOR_RESPONSE;
+				return TRUE;						
+			}
+			else {
+				// you should not be here
+				fsmStruct->fsmState=CAN1_FSM_SEND_HIGH_PRIO_DATA;
+				return TRUE;
+			}
+		break;	
+		case CAN1_FSM_WAIT_FOR_RESPONSE:
+			// to be updateted for more values
+			if(fsmStruct->requestTelegramNr==0) {
+				rx_ptr=&(s->inverter.rxStruct.expectedInputPower);
+			}
+			else if(fsmStruct->requestTelegramNr==1) {
+				rx_ptr=&(s->inverter.rxStruct.DCinputA_power);
+			}
+			else if(fsmStruct->requestTelegramNr==2)  {
+				rx_ptr=&(s->inverter.rxStruct.DCinputB_power);
+			}
+			else if(fsmStruct->requestTelegramNr==3)  {
+				// not valid anymore
+				rx_ptr=&(s->inverter.rxStruct.DCinputA_power);
+			}
+			else {
+				// not valid anymore
+				rx_ptr=&(s->inverter.rxStruct.DCinputB_power);
+			}
+			if(CAN1_wait_for_response(rx_ptr) == TRUE ) {	
+				fsmStruct->requestTelegramNr++;
+				fsmStruct->receivedTelegrams++;
+				if(fsmStruct->requestTelegramNr >=CAN1_NR_OF_REQUEST_TELEGRAMS) {
+					fsmStruct->fsmState=CAN1_FSM_SEND_HIGH_PRIO_DATA;
+					fsmStruct->timeoutCyclesCnt=0;
+					s->inverterState.inverterCanOnline= TRUE;
+					return TRUE;
+				}
+				else {
+					fsmStruct->fsmState=CAN1_FSM_SEND_REQUEST_DATA;
+					fsmStruct->timeoutCyclesCnt=0;
+					s->inverterState.inverterCanOnline= TRUE;
+					return TRUE;				
+				}
+			}
+			else{
+				fsmStruct->timeoutCyclesCnt++;
+			}
+			
+			if(fsmStruct->timeoutCyclesCnt >5) {
+				// timeout
+				fsmStruct->receivedTelegrams=0;
+				//fsmStruct->timeoutCyclesCnt=0;
+				
+				// set Error
+				BMS_Set_Error_CAN1_Timeout(s) ;
+				// set inverter fsm to can out 
+				s->inverterState.inverterCanOnline= FALSE;
+				fsmStruct->fsmState=CAN1_FSM_SEND_HIGH_PRIO_DATA;
+				return TRUE;
+			}
+				// wait another 10ms for response
+			return TRUE;
+		break;
+		default :
+			// you should not be here	
+			return FALSE;
+		break;
+			
+	}
+}
+
+/*
+ * @brief generate a pkg with value ID (32bit) Cell Index (8-bit) voltage (16 bit) temperature (8-bit)
+ */
+uint32_t generateCellInfoPkg(MASTER_CAN0_STRUCT_t* s, uint8_t cellIndex,BMS_CAN1_INVERTER_CELL_DATA_t* txPkg) {
+	// collect information
+	int8_t cellTemp;
+	uint16_t cellVoltage;
+	uint8_t SlaveNr;
+	uint8_t cellNr;
+	uint8_t payload[4];
+	
+	
+	uint32_t valueId=CAN1_TX_CELL_STATUS;
+	
+	// shuffle Bits for correct Order
+	shuffle_lsb_msb_can1((uint8_t*)&valueId);
+	
+	SlaveNr = cellIndex/ (MAX_SLAVE_CELLS); // Slave Nr 0...14
+	cellNr = cellIndex - SlaveNr * MAX_SLAVE_CELLS ;// cellNr 0... 24
+	
+	cellVoltage = s->Slave[SlaveNr].CellVoltage[cellNr];
+	
+	if(s->Slave[SlaveNr].TempSensConnectionState[cellNr] == TEMP_SENSOR_CONNECTED) {
+		cellTemp = s->Slave[SlaveNr].CellTemp[cellNr] ;
+	}
+	else {
+		// if temp sensor not connected transmit -51 deg
+		cellTemp = -51 ;
+	}
+	payload[0]=cellIndex;
+	payload[1]= cellVoltage >> 8;
+	payload[2]= cellVoltage & 0xFF;
+	payload[3]= (uint8_t)cellTemp;
+	
+	shuffle_lsb_msb_can1((uint8_t*)&(payload[0]));
+	
+	txPkg->valueId=valueId;
+	txPkg->payload= (payload[0] << 24) + (payload[1] << 16) + (payload[2] << 8) + payload[3] ;
+}
+
+
+uint32_t Master_Balancer_fsm(MASTER_CAN0_STRUCT_t* s) {
+	switch(s->balancerState) {
+		case BMS_BALANCE_INIT:
+				if(s->allValuesInitialized== TRUE && (s->maxCellVoltage >=BMS_SLAVE_MAX_BALANCE_VOLTAGE)) {
+					// cellvoltage of system too high => no Balancing
+					s->balancerState=BMS_BALANCE_OFF;
+				}
+				else if(s->SoC_estimator.SoC_percentage_smooth <= BMS_SLAVE_MIN_BALANCE_SOC) {
+					// SoC under 80% do not balance
+					s->balancerState=BMS_BALANCE_OFF;
+				}
+				else if(s->maxHeatSinkTemp >= BMS_SLAVE_MAX_BALANCE_HEATSINK_TEMP) {
+					// Heatsink too hot => do not balance
+					s->balancerState=BMS_BALANCE_OFF;
+				}
+				else if(s->allValuesInitialized== TRUE && (s->UI_Board.Ibatt > BMS_SLAVE_BATTERY_CHARGE_THERESOLD) ) {
+					// battery discharging => no Balancing
+					s->balancerState=BMS_BALANCE_OFF;
+				}
+				else if(s->allValuesInitialized== TRUE && (s->UI_Board.Ibatt < BMS_SLAVE_BATTERY_CHARGE_THERESOLD)) {
+					// ready for balancing
+					s->balancerState=BMS_BALANCE_GET_VOLTAGE;
+				}
+
+				else {
+					// do nothing
+				}
+			
+			return TRUE;
+		break;
+		case BMS_BALANCE_GET_VOLTAGE:
+				// decide Which cells to balance
+				if(s->UI_Board.Ibatt < BMS_SLAVE_BATTERY_CHARGE_THERESOLD) {
+					set_balancer(s);
+					s->balancerState=BMS_BALANCE_BALANCE_CELLS;
+				}
+				else {
+					set_balancer_off(s) ;
+					s->balancerState=BMS_BALANCE_OFF;
+				}
+			return TRUE;
+		break;
+		case BMS_BALANCE_BALANCE_CELLS:
+			// turn off balancing to obtain uneffected cell voltages	
+			if(s->UI_Board.Ibatt < BMS_SLAVE_BATTERY_CHARGE_THERESOLD) {
+				set_balancer_off(s) ;
+				s->balancerState=BMS_BALANCE_COOL;
+			}
+			else {
+				set_balancer_off(s) ;
+				s->balancerState=BMS_BALANCE_OFF;
+			}
+			return TRUE;
+		break;
+		case BMS_BALANCE_COOL:
+			// uneffected cell voltages are now available
+			if(s->UI_Board.Ibatt < BMS_SLAVE_BATTERY_CHARGE_THERESOLD) {
+				s->balancerState=BMS_BALANCE_INIT;
+			}
+			else {
+				set_balancer_off(s) ;
+				s->balancerState=BMS_BALANCE_OFF;
+			}			
+			return TRUE;
+		break;
+		case BMS_BALANCE_OFF:
+				set_balancer_off(s) ;
+			if(s->UI_Board.Ibatt < BMS_SLAVE_BATTERY_CHARGE_THERESOLD) {
+				s->balancerState=BMS_BALANCE_INIT;
+			}	
+			s->balancerState=BMS_BALANCE_INIT;
+			return TRUE;
+		break;	
+		
+			
+	
+	}
+	
+}
+
+uint8_t get_nr_of_connected_slaves(MASTER_CAN0_STRUCT_t* s){
+	uint8_t i=0;
+	uint8_t nr=0;
+	for(i=0;i<CAN0_MAX_NR_OF_SLAVES-1;i++) {
+		if(s->Slave[i].SlaveConnectionState== CONNECTED) {
+			nr++;
+		}
+	}
+	return nr;
+}
+
+uint32_t RunningModeFSM(MASTER_CAN0_STRUCT_t* s){
+
+	
+	// check for active Error States
+	if(ErrorStackCheckForActiveErrors(s,BMS_ERROR_CLASS_3) || s->RunMode.ErrorState3fsm != ES3_FSM_INIT) {
+		// handle Error Class 3
+		BMS_Master_ES3_fsm(s);
+		return TRUE;
+	}
+	else if(ErrorStackCheckForActiveErrors(s,BMS_ERROR_CLASS_2) || s->RunMode.ErrorState2fsm != ES2_FSM_INIT) {
+		// handle Error Class 2
+		BMS_Master_ES2_fsm(s);
+		return TRUE;
+	}
+	else if(ErrorStackCheckForActiveErrors(s,BMS_ERROR_CLASS_1) || s->RunMode.ErrorState1fsm != ES1_FSM_INIT) {
+		// handle Error Class 1
+		BMS_Master_ES1_fsm(s);
+		return TRUE;
+	}
+	
+	else {
+		// normal operation
+		OPModeFSM( s );
+	return TRUE;
+	}
+
+}
+
+uint32_t OPModeFSM(MASTER_CAN0_STRUCT_t* s){
+	float SoC=s->SoC_estimator.SoC_percentage_smooth;
+	switch(s->RunMode.OperationMode) {
+		case OP_MODE_INIT:
+			// just jump to checkup startup conditions
+			s->RunMode.OperationMode=OP_MODE_CHECK_STARTUP_CONDITIONS;
+			
+			CLEAR_OUTPIN(PIN_REGNR_LED4);
+			return TRUE;
+		break;
+		case OP_MODE_CHECK_STARTUP_CONDITIONS:
+			if(s->allValuesInitialized==TRUE) {
+				// all values initalized and no error occured
+				// => Startup conditions apply => start startup
+				s->RunMode.OperationModeTimestamp=Global_1msCounter;
+				s->RunMode.OperationMode=OP_MODE_SET_PRECHARGE_RELAY;
+				s->RunMode.onCounter=0;
+				return TRUE;
+			}
+			else {
+				// wait till all values are initialiezd
+				s->RunMode.OperationMode=OP_MODE_CHECK_STARTUP_CONDITIONS;
+				return TRUE;
+			}
+		break;
+		case OP_MODE_SET_PRECHARGE_RELAY:
+			// set Low Side and Precharge Relais
+			s->relayState.LS_closed=TRUE;
+			s->relayState.PRECHARGE_closed=TRUE;
+			SwitchRelais( LS_RELAIS, 1);
+			SwitchRelais( PRE_CHARGE_RELAIS, 1);			
+			if(s->RunMode.OperationModeTimestamp + 3000 <= Global_1msCounter) {
+				s->RunMode.OperationMode=OP_MODE_SET_MAIN_RELAY;
+				return TRUE;
+			}
+			else {
+				s->RunMode.OperationMode= OP_MODE_SET_PRECHARGE_RELAY;
+				return TRUE;
+			}
+		break;
+		case OP_MODE_SET_MAIN_RELAY:
+			// Switch Highside relais
+			SwitchRelais( HS_RELAIS, 1);
+			s->relayState.HS_closed=TRUE;
+			s->RunMode.OperationMode=OP_MODE_NORMAL;
+			return TRUE;
+		break;
+		case OP_MODE_NORMAL:
+			// do nothing until SoC becomes low
+			s->RunMode.onCounter++;
+			if ( SoC < BMS_SOC_LOW_MARK) {
+				s->RunMode.OperationMode=OP_MODE_SOC_LOW;
+				return TRUE;
+			}
+			else {
+				s->RunMode.OperationMode=OP_MODE_NORMAL;
+				return TRUE;
+			}				
+			return TRUE;
+		break;
+		case OP_MODE_SOC_LOW:
+			s->RunMode.onCounter++;
+			// do nothing until SoC becomes high again
+			if ( SoC > BMS_SOC_LOW_MARK) {
+				s->RunMode.OperationMode=OP_MODE_NORMAL;
+				return TRUE;
+			}
+			else {
+				s->RunMode.OperationMode=OP_MODE_SOC_LOW;
+				return TRUE;
+			}	
+		break;	
+		default:
+			// something went horribly wrong
+			return FALSE;
+		break;
+	}
+	
+}
+/*
+ * @brief Statemachine which handles Class 1 Errors
+ */
+
+uint32_t BMS_Master_ES1_fsm(MASTER_CAN0_STRUCT_t* s){
+	switch (s->RunMode.ErrorState1fsm) {
+		case ES1_FSM_INIT:
+			s->RunMode.ErrorState1fsm=ES1_FSM_CHECK_IF_ERROR_VALID;
+			return TRUE;
+		break;
+		case ES1_FSM_CHECK_IF_ERROR_VALID:
+			// Try to clear Error
+			BMS_Clear_Error_Buffer(s,BMS_ERROR_CLASS_1);
+
+			
+			if(ErrorStackCheckForActiveErrors(s,BMS_ERROR_CLASS_1)) {
+				// Error still active
+				// Don't do anything
+				
+			}
+			else {
+				// No Error
+				s->RunMode.ErrorState1fsm=ES1_FSM_ERROR_REVOKED;
+			}
+			return TRUE;
+		break;
+		case ES1_FSM_ERROR_REVOKED:
+			// No More Errors apply startup system again
+			s->RunMode.OperationMode=OP_MODE_INIT;
+			// set Fsm Back to INIT
+			s->RunMode.ErrorState1fsm=ES1_FSM_INIT;
+			return TRUE;
+		break;
+	}
+}
+
+uint32_t BMS_Master_ES2_fsm(MASTER_CAN0_STRUCT_t* s){
+	switch(s->RunMode.ErrorState2fsm) {
+		case ES2_FSM_INIT:
+			// save time for Timeout timer
+			s->RunMode.ErrorState2Timestamp=Global_1msCounter;
+			if(s->ErrorBuffer.ES2_New_Error==FALSE) {
+				// System had power cycle, Try to fix Error
+				s->RunMode.ErrorState2fsm=ES2_FSM_CHECK_IF_ERROR_VALID;
+			}
+			else {
+				// no restart => wait timeout then kill system
+				s->RunMode.ErrorState2fsm=ES2_FSM_WAIT_FOR_SHUTDOWN;
+			}
+			return TRUE;
+		break;
+		case ES2_FSM_CHECK_IF_ERROR_VALID:
+			// Try to clear Error
+			BMS_Clear_Error_Buffer(s,BMS_ERROR_CLASS_2);
+			if(!ErrorStackCheckForActiveErrors(s,BMS_ERROR_CLASS_2)) {
+				// all Errors cleared
+				s->RunMode.ErrorState2fsm=ES2_FSM_ERROR_REVOKED;
+			}
+			else if(s->RunMode.ErrorState2Timestamp + BMS_ERROR_FSM_ES2_TIMEOUT < Global_1msCounter ) {
+				// Timeout shutdown system
+				s->RunMode.ErrorState2fsm=ES2_FSM_SYSTEM_SHUTDOWN;
+			}
+			else{
+				// do nothing an wait for timeout or error to be cleared
+			}
+			return TRUE;
+		break;
+		case ES2_FSM_WAIT_FOR_SHUTDOWN:
+			// wait timeout
+			if(s->RunMode.ErrorState2Timestamp + BMS_ERROR_FSM_ES2_TIMEOUT < Global_1msCounter ) {
+				// timeout
+				s->RunMode.ErrorState2fsm=ES2_FSM_SYSTEM_SHUTDOWN;
+				return TRUE;
+			}
+			else {
+				// wait and do nothing
+				return TRUE;
+			}
+			return TRUE;
+		break;
+		case ES2_FSM_ERROR_REVOKED:
+			// no more Errors in the system => Start normal Operation again
+			s->RunMode.ErrorState2fsm=ES2_FSM_INIT;
+			s->RunMode.OperationMode=OP_MODE_INIT;
+			return TRUE;
+		break;
+		case ES2_FSM_SYSTEM_SHUTDOWN:
+			// Turn off power Supply
+			SwitchRelais( PWR_SUPPLY, 1);
+			// now System should be dead
+			while (1) {
+				// loop for ever
+				SwitchRelais( PWR_SUPPLY, 1);
+			}
+			
+			break;
+		return TRUE;
+	}
+}
+
+/*
+ * @brief handle error class 3
+ * Todo System repair tool not implemented yet
+ */
+uint32_t BMS_Master_ES3_fsm(MASTER_CAN0_STRUCT_t* s) {
+	switch(s->RunMode.ErrorState3fsm){
+		case ES3_FSM_INIT:
+			// save timestamp for timeout
+			s->RunMode.ErrorState3Timestamp=Global_1msCounter;
+			s->RunMode.ErrorState3fsm=ES3_FSM_CONNECT_TO_SERVICE_TOOL;
+			return TRUE;
+		break;
+		case ES3_FSM_CONNECT_TO_SERVICE_TOOL:
+			// not fully implemented yet
+			// just shut down system after timeout
+			if(s->RunMode.ErrorState3Timestamp + BMS_ERROR_FSM_ES3_TIMEOUT < Global_1msCounter ) {
+				// Shut down System
+				s->RunMode.ErrorState3fsm=ES3_FSM_SYSTEM_SHUTDOWN;
+			}
+			else {
+				// wait
+			}
+			return TRUE;
+		break;
+		case ES3_FSM_SYSTEM_SHUTDOWN:
+			// Turn off power Supply
+			SwitchRelais( PWR_SUPPLY, 1);
+			// now System should be dead
+			while (1) {
+				// loop for ever
+				SwitchRelais( PWR_SUPPLY, 1);
+			}
+			return TRUE;
+		break;
+			
+	
+	}
+}
+
+/*
+ * @brief check if connected Inverter has enough power to charge battery and recover from Wintermode 
+ */
+
+int32_t checkIfInverterHasPower(MASTER_CAN0_STRUCT_t* s) {
+	if((s->inverter.rxStruct.expectedInputPower) > BMS_WINTER_MODE_RECOVER_PWR) {
+		return TRUE;
+	}
+	else {
+		return FALSE;
+	}
+}
+
+/*
+ * @brief read Temp sensor on master Board
+ */
+uint32_t readMasterTempSensorFsm(MASTER_CAN0_STRUCT_t* s) {
+	switch(s->MasterTempSensState) {
+		case BMS_MASTER_TEMP_SENSOR_INITIATE_MEASUREMENT:
+			//  trigger measurement
+			if(TempMess_triggerRead() == 0) {
+				// measurement triggered got to next state
+				s->MasterTempSensState=BMS_MASTER_TEMP_SENSOR_UPDATE_MEASUREMENT;
+			}
+			return TRUE;
+		break;
+		case BMS_MASTER_TEMP_SENSOR_UPDATE_MEASUREMENT:
+			TempMess_update();
+			if(TempMess_poll_Value(&(s->masterTemp)) == 0) {
+				// readout succesfull go back to triggering measurement
+				s->MasterTempSensState=BMS_MASTER_TEMP_SENSOR_INITIATE_MEASUREMENT;
+			}
+			return TRUE;
+		break;
+	}
+}
+
+/*
+ * @brief clear fifos 
+ */
+
+uint32_t initUIFifo(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	for(i=0;i<UI_VOLTAGE_FIFO_SIZE;i++) {
+		s->UI_Board.UbattFiFo[i]=0;
+		s->UI_Board.SystemVoltageFiFo[i]=0;
+	}
+	for(i=0;i<UI_CURRENT_FIFO_SIZE;i++) {
+		s->UI_Board.IbattFiFo[i]=0;
+		s->UI_Board.Ibatt_Inverter_FIFO[i]=0;
+	}
+	return TRUE;
+}
+
+uint32_t popUIFiFo(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	
+	for(i=UI_VOLTAGE_FIFO_SIZE-1;i>0;i--) {
+		s->UI_Board.UbattFiFo[i]=s->UI_Board.UbattFiFo[i-1];
+	}
+	s->UI_Board.UbattFiFo[0]=s->UI_Board.Ubatt;
+	
+	for(i=UI_VOLTAGE_FIFO_SIZE-1;i>0;i--) {
+		s->UI_Board.SystemVoltageFiFo[i]=s->UI_Board.SystemVoltageFiFo[i-1];
+	}
+	s->UI_Board.SystemVoltageFiFo[0]=(s->systemVoltage);
+	
+	for(i=UI_CURRENT_FIFO_SIZE-1;i>0;i--) {
+		s->UI_Board.IbattFiFo[i]=s->UI_Board.IbattFiFo[i-1];
+	}
+	s->UI_Board.IbattFiFo[0]=s->UI_Board.Ibatt;
+}
+
+uint32_t pushInverterCurrentFIFO(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	for(i=UI_CURRENT_FIFO_SIZE-1;i>0;i--) {
+		s->UI_Board.Ibatt_Inverter_FIFO[i]=s->UI_Board.Ibatt_Inverter_FIFO[i-1];
+	}
+	s->UI_Board.Ibatt_Inverter_FIFO[0]=s->inverter.rxStruct.batteryCurrent;
+	
+//	if(s->inverter.rxStruct.batteryCurrent > 100 ||  s->inverter.rxStruct.batteryCurrent < -100) {
+//		// fake value
+//		i++ ; // break here
+//	}
+	return TRUE;
+}
+
+
+// *** End BMS_Master.c ******************************************************

+ 447 - 0
BMS Master/Sources/BMS_Set_Error_States.c

@@ -0,0 +1,447 @@
+/*
+ * BMS_Set_Error_States.c
+
+ *
+ *  Created on: Nov 8, 2016
+ *      Author: le8041
+ */
+
+#include "BMS_Master.h"
+
+/*
+ * @brief check if Battery is charged or discharged
+ * return true if discharged false if charged
+ */
+uint32_t BMS_set_Error_check_if_stable_discharge(MASTER_CAN0_STRUCT_t* s) {
+	// stable when mean value is bigger than -150mA
+	uint8_t i;
+	int16_t Current=0;
+	for(i=0;i<UI_CURRENT_FIFO_SIZE;i++) {
+		Current=Current + s->UI_Board.IbattFiFo[i] ;
+	}
+	
+	Current = (Current*10) /UI_CURRENT_FIFO_SIZE ;
+	
+	if(Current > -150) {
+		// stable discharge
+		return TRUE;
+	}
+	
+	//stable discharge
+	return FALSE;
+	
+}
+/*
+ * @brief ceck if battery is charged stable over given amount of samples
+ */
+uint32_t BMS_set_Error_check_if_stable_charge(MASTER_CAN0_STRUCT_t* s) {
+	// stable when all values of FiFo are greater than -150
+	uint8_t i;
+	for(i=0;i<UI_CURRENT_FIFO_SIZE;i++) {
+		if(s->UI_Board.IbattFiFo[i] *10 > -150) {
+			// no stable charge
+			return FALSE;
+		}
+	}
+	
+	//stable charge
+	return TRUE;
+	
+}
+/*
+ * @brief check voltage levels Umin1 Umin2 Umin3 and set Error states accordingly
+ * return True if everything is of return false if error occured
+ */
+uint32_t BMS_Set_Error_check_Voltage_level_min(MASTER_CAN0_STRUCT_t* s){
+	uint16_t Umin;
+	float PvPwrAvailable;
+	Umin=s->minCellVoltage;
+	PvPwrAvailable=s->inverter.rxStruct.expectedInputPower;
+	
+	if(Umin < BMS_SOC_UMIN_3  ) {
+		// Voltage level below Umin3 
+		// Kill Relays
+		s->relayState.HS_closed=FALSE;
+		s->relayState.LS_closed=FALSE;
+		s->relayState.PRECHARGE_closed=FALSE;
+		SwitchRelais( LS_RELAIS, 0);
+		SwitchRelais( PRE_CHARGE_RELAIS, 0);
+		SwitchRelais( HS_RELAIS, 0);
+		// set Error state 3 - should be alse set directly after test of Slave Voltage in Salve
+		ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_UMIN_3,BMS_ERROR_CLASS_3);
+		return FALSE;
+	}
+	else if(Umin < BMS_SOC_UMIN_2 && BMS_set_Error_check_if_stable_discharge(s) && !ErrorStackCheckifUmin2ErrorRecoveryPending(s)  ) {
+		// Voltage level below Umin2 and Battery is discharged 
+		// Kill Relays
+		SwitchRelais( LS_RELAIS, 0);
+		SwitchRelais( PRE_CHARGE_RELAIS, 0);
+		SwitchRelais( HS_RELAIS, 0);
+		s->relayState.HS_closed=FALSE;
+		s->relayState.LS_closed=FALSE;
+		s->relayState.PRECHARGE_closed=FALSE;
+		
+		// set Error state 2
+		ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_UMIN_2,BMS_ERROR_CLASS_2);
+		return FALSE;
+	}
+	else if(Umin < BMS_SOC_UMIN_1 &&  BMS_set_Error_check_if_stable_discharge(s) && !ErrorStackCheckifUmin1ErrorRecoveryPending(s)   ) {
+		// Voltage Level below Umin1 and battery is discharged
+		// Kill Relays
+		SwitchRelais( LS_RELAIS, 0);
+		SwitchRelais( PRE_CHARGE_RELAIS, 0);
+		SwitchRelais( HS_RELAIS, 0);
+		s->relayState.HS_closed=FALSE;
+		s->relayState.LS_closed=FALSE;
+		s->relayState.PRECHARGE_closed=FALSE;
+		// set Error state 1
+		
+		
+		ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_UMIN_1,BMS_ERROR_CLASS_1);
+		return FALSE;		
+	}
+	else {
+		// everything is ok
+		return TRUE;
+	}	
+}
+
+/*
+ * @brief check  max voltage level
+ */
+
+uint32_t BMS_Set_Error_check_Voltage_level_max(MASTER_CAN0_STRUCT_t* s) {
+	uint16_t Umax=s->maxCellVoltage;
+	
+	if(Umax > BMS_SOC_UMAX_3) {
+		// set Error State 1
+		// Kill Relays
+		SwitchRelais( LS_RELAIS, 0);
+		SwitchRelais( PRE_CHARGE_RELAIS, 0);
+		SwitchRelais( HS_RELAIS, 0);
+		s->relayState.HS_closed=FALSE;
+		s->relayState.LS_closed=FALSE;
+		s->relayState.PRECHARGE_closed=FALSE;
+		// set Error state 2
+		ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_UMAX_3,BMS_ERROR_CLASS_3);
+		return FALSE;
+	}
+
+
+	
+	else if(Umax > BMS_SOC_UMAX_2) {
+		// set Error State 1
+		// Kill Relays
+		SwitchRelais( LS_RELAIS, 0);
+		SwitchRelais( PRE_CHARGE_RELAIS, 0);
+		SwitchRelais( HS_RELAIS, 0);
+		s->relayState.HS_closed=FALSE;
+		s->relayState.LS_closed=FALSE;
+		s->relayState.PRECHARGE_closed=FALSE;
+		// set Error state 2
+		ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_UMAX_2,BMS_ERROR_CLASS_1);
+		return FALSE;
+	}
+	else if(Umax > BMS_SOC_UMAX_1 ) {
+		// set Error State 0 not implemented yet
+		// TODO return TRUE; everything is ok
+		return TRUE;
+	}
+	
+	else {
+		// everything is ok
+		return TRUE;
+	}
+	
+	
+}
+
+
+
+/*
+ * @brief check if system exceeds maximum System Voltage in case customer plays around with the system
+ */
+
+uint32_t BMS_Set_Error_check_System_voltage_level_max(MASTER_CAN0_STRUCT_t* s) {
+	uint32_t Uges=s->systemVoltage;
+	if(Uges >BMS_ERROR_THRESHOLD_UMAX_SYSTEM) {
+		// Kill Relays
+		SwitchRelais( LS_RELAIS, 0);
+		SwitchRelais( PRE_CHARGE_RELAIS, 0);
+		SwitchRelais( HS_RELAIS, 0);
+		s->relayState.HS_closed=FALSE;
+		s->relayState.LS_closed=FALSE;
+		s->relayState.PRECHARGE_closed=FALSE;
+		// set Error state 3
+		ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_UMAX_SYSTEM,BMS_ERROR_CLASS_3);
+		return FALSE;
+	}
+	else {
+		//everything is ok
+		return TRUE;
+	}
+
+}
+
+/*
+ *@brief do linear interpolation
+ */
+float BMS_Set_Error_linear_interpolate(float x1,float x2,float x,float y1,float y2) {
+	// solve linear eq  y1= m*x1 + b
+	//					y2= m*x2 + b
+	float m = 	(y2-y1)/(float)(x2-x1);
+	float b =	y1 - m*(float)(x1);
+	
+	//
+	return m*(float)(x) + b;
+ }
+
+/*
+ * 
+ */
+float BMS_Set_Error_generate_Fcn(float* x_values,float* y_values,uint8_t NrOfPoints, float x) {
+	uint8_t i;
+	if(x < x_values[0]) {
+		// value is to the left of the described area => return left most value
+		return y_values[0];
+	}
+	else if( x> x_values[NrOfPoints -1] ) {
+		// value is to the right of the described area => return right most value
+		return y_values[NrOfPoints -1];
+	}
+	
+	// find left x_value to x
+	for(i=0;i< NrOfPoints; i++) {
+		if(x_values[i] <= x && x_values[i+1] >= x ) {
+			// x is between x_value[i] and x_value[i+1]
+			return BMS_Set_Error_linear_interpolate(x_values[i],x_values[i+1],x,y_values[i],y_values[i+1]);
+		}
+	}
+}
+
+uint32_t BMS_Set_Error_Check_derating(MASTER_CAN0_STRUCT_t* s) {
+	float Current = (float)(s->UI_Board.Ibatt*10);
+
+	float minTemp = (float)s->minCellTemp;
+	float maxTemp = (float)s->maxCellTemp;
+	float SoC = s->SoC_estimator.SoC_percentage_smooth_FiFo[5];
+	float capacity = 26.0 ; // capacity 26.0 Ah
+	float temp_discharge_x[4]={0,25,40,55};
+	float temp_discharge_y[4]={0.3,1.1,1.1,0};
+	float temp_charge_x[5]={-5,0,25,40,50};
+	float temp_charge_y[5]={0.3,0.6,1.1,1.1,0};
+	
+	float SoC_charge_x[5]={0,0.8,0.95,0.999,1};
+	float SoC_charge_y[5]={25,25,2.5,2.5,0};
+	
+	float SoC_discharge_x[5]={0,0.001,0.05,0.2,1};
+	float SoC_discharge_y[5]={0,2.5,2.5,25,25};
+	
+	s->currentLimits.I_max_charge_temp_max = BMS_Set_Error_generate_Fcn(temp_charge_x,temp_charge_y,5,maxTemp)*25*1000;
+	s->currentLimits.I_max_charge_temp_min = BMS_Set_Error_generate_Fcn(temp_charge_x,temp_charge_y,5,minTemp)*25*1000;
+	s->currentLimits.I_max_charge_SoC      = BMS_Set_Error_generate_Fcn(SoC_charge_x,SoC_charge_y,5,SoC)*1000 *1.1 ;
+	
+	s->currentLimits.I_max_discharge_temp_max 	= BMS_Set_Error_generate_Fcn(temp_discharge_x,temp_discharge_y,4,maxTemp)*25*1000;
+	s->currentLimits.I_max_discharge_temp_min 	= BMS_Set_Error_generate_Fcn(temp_discharge_x,temp_discharge_y,4,minTemp)*25*1000;
+	s->currentLimits.I_max_discharge_SoC		= BMS_Set_Error_generate_Fcn(SoC_discharge_x,SoC_discharge_y,5,SoC)*1000 *1.1 ;	
+
+	if(Current < -100) {
+		// Battery is charged
+		
+		// check temperature derating at tmin
+		// check if low temperature is violated 
+		if((-1)*Current > s->currentLimits.I_max_charge_temp_min) {
+			// current to high
+			ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_I_MAX_CHARGE_OP,BMS_ERROR_CLASS_1);
+			// Kill Relays
+			SwitchRelais( LS_RELAIS, 0);
+			SwitchRelais( PRE_CHARGE_RELAIS, 0);
+			SwitchRelais( HS_RELAIS, 0);
+			s->relayState.HS_closed=FALSE;
+			s->relayState.LS_closed=FALSE;
+			s->relayState.PRECHARGE_closed=FALSE;
+			return FALSE;
+		}
+		// check temperature derating at tmax
+		// check if low temperature is violated 
+		else if((-1)*Current > s->currentLimits.I_max_charge_temp_max ) {
+			// current too high
+			ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_I_MAX_CHARGE_OP,BMS_ERROR_CLASS_1);
+			// Kill Relays
+			SwitchRelais( LS_RELAIS, 0);
+			SwitchRelais( PRE_CHARGE_RELAIS, 0);
+			SwitchRelais( HS_RELAIS, 0);
+			s->relayState.HS_closed=FALSE;
+			s->relayState.LS_closed=FALSE;
+			s->relayState.PRECHARGE_closed=FALSE;
+			return FALSE;
+		}
+		// check SoC derating // normal derating curve + 10%
+		else if((-1)*Current > s->currentLimits.I_max_charge_SoC) {
+			// current too high
+			ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_I_MAX_CHARGE_OP,BMS_ERROR_CLASS_1);
+			// Kill Relays
+			SwitchRelais( LS_RELAIS, 0);
+			SwitchRelais( PRE_CHARGE_RELAIS, 0);
+			SwitchRelais( HS_RELAIS, 0);
+			s->relayState.HS_closed=FALSE;
+			s->relayState.LS_closed=FALSE;
+			s->relayState.PRECHARGE_closed=FALSE;
+			return FALSE;
+		}
+		else {
+			// derating is ok
+			return TRUE;
+		}				
+	}
+	else if(Current > 100) {
+		// Battery is discharged
+		
+		// check temperature derating at tmin
+		// check if low temperature is violated 
+		if(Current > s->currentLimits.I_max_discharge_temp_min ) {
+			// current to high
+			ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_I_MAX_DISCHARGE_OP,BMS_ERROR_CLASS_1);
+			// Kill Relays
+			SwitchRelais( LS_RELAIS, 0);
+			SwitchRelais( PRE_CHARGE_RELAIS, 0);
+			SwitchRelais( HS_RELAIS, 0);
+			s->relayState.HS_closed=FALSE;
+			s->relayState.LS_closed=FALSE;
+			s->relayState.PRECHARGE_closed=FALSE;
+			return FALSE;
+		}
+		// check temperature derating at tmax
+		// check if low temperature is violated 
+		else if(Current > s->currentLimits.I_max_discharge_temp_max ) {
+			// current too high
+			ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_I_MAX_DISCHARGE_OP,BMS_ERROR_CLASS_1);
+			// Kill Relays
+			SwitchRelais( LS_RELAIS, 0);
+			SwitchRelais( PRE_CHARGE_RELAIS, 0);
+			SwitchRelais( HS_RELAIS, 0);
+			s->relayState.HS_closed=FALSE;
+			s->relayState.LS_closed=FALSE;
+			s->relayState.PRECHARGE_closed=FALSE;
+			return FALSE;
+		}
+		// check SoC derating // normal derating curve + 10%
+		else if(Current > s->currentLimits.I_max_discharge_SoC) {
+			// current too high
+			ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_I_MAX_DISCHARGE_OP,BMS_ERROR_CLASS_1);
+			// Kill Relays
+			SwitchRelais( LS_RELAIS, 0);
+			SwitchRelais( PRE_CHARGE_RELAIS, 0);
+			SwitchRelais( HS_RELAIS, 0);
+			s->relayState.HS_closed=FALSE;
+			s->relayState.LS_closed=FALSE;
+			s->relayState.PRECHARGE_closed=FALSE;
+			return FALSE;
+		}
+		else {
+			// derating is ok
+			return TRUE;
+		}				
+	}
+	
+	else {
+		// nothing happens
+		return TRUE;
+	}	
+	return TRUE;
+}
+
+uint32_t BMS_Set_Error_CAN1_Timeout(MASTER_CAN0_STRUCT_t* s) {
+	// CAN 1 Timeout Has occured
+	ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_EXTERN_CAN_ERROR,BMS_ERROR_CLASS_1);
+	// Kill Relays
+	SwitchRelais( LS_RELAIS, 0);
+	SwitchRelais( PRE_CHARGE_RELAIS, 0);
+	SwitchRelais( HS_RELAIS, 0);
+	s->relayState.HS_closed=FALSE;
+	s->relayState.LS_closed=FALSE;
+	s->relayState.PRECHARGE_closed=FALSE;
+	
+	return TRUE;
+	
+}
+
+/*
+ * @brief check if current mesured by UI is consitent wit current measured by Inverter
+ */
+uint32_t BMS_Set_Error_Check_current_consitency(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i=0;
+	float I_av_ui =0 ;
+	float I_av_inverter =0;
+	
+	for(i=0; i<UI_CURRENT_FIFO_SIZE;i++) {
+		I_av_ui = I_av_ui + (float)(s->UI_Board.IbattFiFo[i]);
+	}
+	
+	I_av_ui = I_av_ui *10; // convert to mA
+	I_av_ui = I_av_ui /UI_CURRENT_FIFO_SIZE ; // calc mean
+	
+	for(i=0;i<UI_CURRENT_FIFO_SIZE;i++ ) {
+		I_av_inverter = I_av_inverter + s->UI_Board.Ibatt_Inverter_FIFO[i];
+	}
+	I_av_inverter = I_av_inverter *1000 /UI_CURRENT_FIFO_SIZE ; // convert to mA and calc mean
+	
+	// compare
+	s->UiInverterInconsistency = bms_SoC_get_norm(I_av_inverter) - bms_SoC_get_norm(I_av_ui) ;
+	
+	if( s->UiInverterInconsistency  > BMS_MAX_CURRENT_INCONSITENCY_MA || s->UiInverterInconsistency <( (-1) * BMS_MAX_CURRENT_INCONSITENCY_MA) ) {
+		// error has occured
+		ErrorStackPushUiError(s,BMS_ERROR_STACK_UI_CURRENT_INCONSIST,BMS_ERROR_CLASS_1);
+		// Kill Relays
+		SwitchRelais( LS_RELAIS, 0);
+		SwitchRelais( PRE_CHARGE_RELAIS, 0);
+		SwitchRelais( HS_RELAIS, 0);
+		s->relayState.HS_closed=FALSE;
+		s->relayState.LS_closed=FALSE;
+		s->relayState.PRECHARGE_closed=FALSE;
+		return TRUE;
+	
+	}
+	return TRUE;
+}
+
+/*
+ * @brief check if Voltage measured by UI and by Summation of Slaves are equal
+ */
+
+uint32_t BMS_Set_Error_Check_voltage_inconsitency(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i=0;
+	uint32_t addedCellVoltage_mean=0;
+	uint32_t UI_Board_voltage_mean=0;
+	
+	for(i=0;i<UI_VOLTAGE_FIFO_SIZE;i++) {
+		addedCellVoltage_mean = addedCellVoltage_mean + s->UI_Board.SystemVoltageFiFo[i];
+		UI_Board_voltage_mean = UI_Board_voltage_mean + s->UI_Board.UbattFiFo[i];				
+	}
+	addedCellVoltage_mean = addedCellVoltage_mean /UI_VOLTAGE_FIFO_SIZE ; // voltage in mV
+	UI_Board_voltage_mean = UI_Board_voltage_mean *100 / UI_VOLTAGE_FIFO_SIZE ;
+	
+	s->UiSlaveInconsistency = bms_SoC_get_norm((float)addedCellVoltage_mean - (float)UI_Board_voltage_mean) ;
+	
+	// if voltage error is bigger than threshold and All relais are closed kill relays
+	if((s->UiSlaveInconsistency > (float)addedCellVoltage_mean * 0.05 && s->RunMode.onCounter > UI_VOLTAGE_FIFO_SIZE* CAN0_MAX_NR_OF_SLAVES) &&
+			(s->relayState.HS_closed==TRUE &&		s->relayState.LS_closed==TRUE && s->relayState.PRECHARGE_closed==TRUE) ){
+		ErrorStackPushUiError(s,BMS_ERROR_STACK_UI_VOLTAGE_INCONSIST,BMS_ERROR_CLASS_1);
+		// Kill Relays
+		SwitchRelais( LS_RELAIS, 0);
+		SwitchRelais( PRE_CHARGE_RELAIS, 0);
+		SwitchRelais( HS_RELAIS, 0);
+		s->relayState.HS_closed=FALSE;
+		s->relayState.LS_closed=FALSE;
+		s->relayState.PRECHARGE_closed=FALSE;
+		s->RunMode.onCounter=0;
+		return TRUE;
+		
+	}
+	
+	return TRUE;
+}
+
+
+
+

+ 822 - 0
BMS Master/Sources/BMS_SoC_estimator.c

@@ -0,0 +1,822 @@
+/*
+ * BMS_SoC_estimator.c
+ *
+ *  Created on: Jul 18, 2016
+ *      Author: le8041
+ */
+
+
+/**
+* @file BMS_SoC_estimator.c
+* @brief SoC Estimator as implemented on embedded System
+*/
+#include "BMS_Master.h"
+
+
+
+
+
+static float const_Ri_charge[BMS_SOC_NR_OF_RI_POINTS]={2.0,2.700}; 
+static int8_t const_Ri_charge_temp[BMS_SOC_NR_OF_RI_POINTS]={10,20};
+
+static float const_Ri_discharge[BMS_SOC_NR_OF_RI_POINTS]= {2.692E-3,2.700E-3};
+static int8_t const_Ri_discharge_temp[BMS_SOC_NR_OF_RI_POINTS] = {10,20};
+
+
+/*
+* @brief setting initial SoC soly dependend from the Battery voltage
+* @param voltage Cell Voltage
+*/
+
+
+float calc_start_SoC(uint16_t voltage) {
+	// set initial Look up Table
+	uint8_t LutSize=6;
+	uint8_t i=0;
+	float offset;
+	MASTER_SOC_ESTIMATOR_INIT_SOC_LUT_t  init_SoC_Lut[6]; 
+	init_SoC_Lut[0].SoC=0;
+	init_SoC_Lut[0].OCV=2900;
+	init_SoC_Lut[1].SoC=0.0665;
+	init_SoC_Lut[1].OCV=3166;
+	init_SoC_Lut[2].SoC=0.285;
+	init_SoC_Lut[2].OCV=3281;
+	init_SoC_Lut[3].SoC=0.6621;
+	init_SoC_Lut[3].OCV=3320;
+	init_SoC_Lut[4].SoC=0.94;
+	init_SoC_Lut[4].OCV=3379;
+	init_SoC_Lut[5].SoC=1.0;
+	init_SoC_Lut[5].OCV=3450;
+	
+	
+	// calc SoC from Current
+	
+	if( voltage <= init_SoC_Lut[0].OCV) {
+		// SoC is 0
+		return  init_SoC_Lut[0].SoC;
+	}
+	
+	if( voltage >= init_SoC_Lut[5].OCV) {
+		// SoC is 1
+		return  init_SoC_Lut[5].SoC;
+	}
+	
+	for(i=0;i< LutSize-1;i++) {
+		// SoC is between 0 and 1
+		// find area in SoC LUT
+		if(init_SoC_Lut[i].OCV <= voltage && init_SoC_Lut[i+1].OCV >= voltage) {
+			// SoC area between i and i+1
+			// linear interpolation of SoC
+			offset=( init_SoC_Lut[i+1].SoC - init_SoC_Lut[i].SoC) / (init_SoC_Lut[i+1].OCV - init_SoC_Lut[i].OCV ) *  (voltage -  init_SoC_Lut[i].OCV );
+			
+			return (offset + init_SoC_Lut[i].SoC);
+		}
+		
+	}
+	
+	return -1;
+}
+
+/*
+* @brief set initial Constants for SoC estimation Algorithm
+* @param cell_SoC pointer to SoC estimation struct
+* @param voltage cell voltage for dertermination of initial SoC after System power up
+*/
+
+int32_t bms_SoC_init_estimator(MASTER_SOC_ESTIMATOR_t* cell_SoC, uint16_t voltage) {
+	uint8_t i;
+	cell_SoC->capacity=26.0; // initial capacity 25.0 Ah
+	cell_SoC->delta_t = 0.25;  // intergration constant in seconds
+	
+	
+	cell_SoC->delta_t =  cell_SoC->delta_t /(60*60) ;  // integration constant in hours
+
+	// set initial SoC
+	cell_SoC->SoC_percentage=calc_start_SoC(voltage) ;
+	cell_SoC->SoC_percentage_smooth= cell_SoC->SoC_percentage;
+	cell_SoC->SoC_Ah=  cell_SoC->SoC_percentage * cell_SoC->capacity ;
+	
+	// set charge thresholds
+	cell_SoC->ChargeThreshold.Ri_charge= 2.0 ; // Ri in mOhm
+	cell_SoC->ChargeThreshold.U_bat_max=3450;
+	cell_SoC->ChargeThreshold.U_ocv_correct=3379;
+	cell_SoC->ChargeThreshold.U_ocv_SoC=0.94	;
+	// set discharge thresholgs
+	cell_SoC->DischargeThreshold.Ri_discharge =2.7; // Ri in mOhm 
+	cell_SoC->DischargeThreshold.U_bat_min=2900;
+	cell_SoC->DischargeThreshold.U_ocv_correct=3166;
+	cell_SoC->DischargeThreshold.U_ocv_SoC=0.0665;
+	// set initail Derating
+	cell_SoC->MaxBatteryChargeCurrent=bms_calc_charge_derating(cell_SoC->SoC_percentage);
+	cell_SoC->MaxBatteryDischargeCurrent=bms_calc_discharge_derating(cell_SoC->SoC_percentage);
+	
+	cell_SoC->state=BMS_SOC_IDLE;
+	cell_SoC->flags=0;
+	cell_SoC->ChargeRelaxationWaitCnt=0;
+	cell_SoC->DischargeRelaxationWaitCnt=0; 
+	cell_SoC->ChargeSmoothFlags=0;
+	cell_SoC->Ocv_calc=voltage;
+
+	return 0;
+	
+}
+
+/*
+* @brief set initial Constants for SoC estimation Algorithm
+* @param cell_SoC pointer to SoC estimation struct
+* @param voltage cell voltage for dertermination of initial SoC after System power up
+*/
+
+int32_t bms_SoC_init_estimator_FRAM(MASTER_SOC_ESTIMATOR_t* cell_SoC, uint16_t voltage) {
+	float SoC=50.0;
+	cell_SoC->capacity=26.0; // initial capacity 25.0 Ah
+	cell_SoC->delta_t = 0.25;  // intergration constant in seconds
+	//read_fram_float(&SoC,10,BMS_STARTUP_SOC);
+	SoC= read_fram_get_SoC();
+	
+	cell_SoC->delta_t =  cell_SoC->delta_t /(60*60) ;  // integration constant in hours
+
+	// set initial SoC
+	cell_SoC->SoC_percentage=SoC ;
+	cell_SoC->SoC_percentage_smooth= cell_SoC->SoC_percentage;
+	cell_SoC->SoC_Ah=  cell_SoC->SoC_percentage * cell_SoC->capacity ;
+	
+	// set charge thresholds
+	cell_SoC->ChargeThreshold.Ri_charge= 2.0 ; // Ri in mOhm
+	cell_SoC->ChargeThreshold.U_bat_max=3450;
+	cell_SoC->ChargeThreshold.U_ocv_correct=3379;
+	cell_SoC->ChargeThreshold.U_ocv_SoC=0.94	;
+	// set discharge thresholgs
+	cell_SoC->DischargeThreshold.Ri_discharge =2.7; // Ri in mOhm 
+	cell_SoC->DischargeThreshold.U_bat_min=2900;
+	cell_SoC->DischargeThreshold.U_ocv_correct=3166;
+	cell_SoC->DischargeThreshold.U_ocv_SoC=0.0665;
+	// set initail Derating
+	cell_SoC->MaxBatteryChargeCurrent=bms_calc_charge_derating(cell_SoC->SoC_percentage);
+	cell_SoC->MaxBatteryDischargeCurrent=bms_calc_discharge_derating(cell_SoC->SoC_percentage);
+	
+	cell_SoC->state=BMS_SOC_IDLE;
+	cell_SoC->flags=0;
+	cell_SoC->ChargeRelaxationWaitCnt=0;
+	cell_SoC->DischargeRelaxationWaitCnt=0; 
+	cell_SoC->ChargeSmoothFlags=0;
+	cell_SoC->Ocv_calc=voltage;
+
+	return 0;
+	
+}
+
+/*
+* @brief finite State machien for the estimation of the State of charge
+* @param est pointer to estimator struct
+* @param I_batt current in mA
+* @param U_batt_max maximum Cell Voltage in System in mV
+* @param U_batt_min minimum Cell Voltage in System in mV
+* @param temp_batt temperature of battery
+*/
+
+uint32_t bms_SoC_running_fsm(MASTER_SOC_ESTIMATOR_t* est, int16_t I_batt, uint16_t U_batt_max,uint16_t U_batt_min, int8_t temp_min, int8_t temp_max) {
+	
+	uint16_t OCV; // Open Clamp Voltage according to battery Model
+	float R_i=0;
+	switch(est->state) {
+		case BMS_SOC_IDLE:
+			// idle state
+			// check if battery is charged, discharged or resting
+
+			if(I_batt < -1*BMS_SOC_MIN_CURRENT_MA) {
+				//I_bat < 0 => Battery is charged
+				est->state=BMS_SOC_CHARGE;
+				return 0;
+			}
+			else if(I_batt > BMS_SOC_MIN_CURRENT_MA) {
+				//I_bat > 0 => Battery is discharged
+				est->state=BMS_SOC_DISCHARGE;
+				return 0;
+			}
+			else {
+				// Battery is at rest
+				est->state=BMS_SOC_REST;
+				return 0;
+			}			
+			
+			return -1;
+		break;
+		case BMS_SOC_CHARGE:
+			// Battery is charged
+			// if Battery has been discharged to 0% SoC remove Discharge Flag
+			if(est->flags==BMS_SOC_FLAG_SOC_0 && est->SoC_percentage > est->DischargeThreshold.U_ocv_SoC) {
+				est->flags=0;		
+			}
+			
+			if(est->flags==BMS_SOC_FLAG_SOC_LOW && est->SoC_percentage > est->DischargeThreshold.U_ocv_SoC) {
+				// clear BMS_SOC_LOW flage
+				est->flags=0;
+			}
+			if(est->ChargeSmoothFlags==  BMS_SOC_DISCHARGE_SMOOTH_01 &&  est->SoC_percentage >0.01) {
+				// 	 clear BMS_SOC_DISCHARGE_SMOOTH_01 flage 
+				est->ChargeSmoothFlags=0;
+			}
+			// calculate OCV
+			// ToDo: add temperature dependency of Ri 
+			R_i=est->ChargeThreshold.Ri_charge;
+			OCV=   U_batt_max - R_i * (-1)*(float)I_batt/1000; // I_batt is negative ;
+			est->Ocv_calc = OCV;
+			// Check in Which Area SoC is
+			if(est->flags==BMS_SOC_FLAG_SOC_100) {
+				// SoC = 100% has been reached keep SoC at 100% until discharging starts;
+				// => do nothing
+				est->state=BMS_SOC_CHARGE_SMOOTHING;
+				return 0;
+			}
+
+			else if(U_batt_max >  est->ChargeThreshold.U_bat_max) {
+				// if Cell voltage is higer than a threshold battery is considered fully charged
+				// comparison with cell voltage is necessary because battery model might not be accurate enought
+				est->state=BMS_SOC_CHARGE_AREA_FULL;
+				return 0;
+			}
+			if(est->ChargeSmoothFlags==  BMS_SOC_CHARGE_SMOOTH_99) {
+				// SoC => 99% wait till U_bat max is reached
+				est->state=BMS_SOC_CHARGE_SMOOTHING;
+				return 0;
+			}
+			
+			else if(OCV > est->ChargeThreshold.U_ocv_correct) {
+				// open clamp Voltage is higer than threshold
+				// => Battery is nearly fully charged => SoC from columb counting has to be updated
+				// Wait for 20 Seconds for update of SoC
+				est->state=BMS_SOC_CHARGE_WAIT_FOR_RELAXATION;
+				return 0;
+			}
+			else {
+				// no special Area to take care of
+				// proceed with columb counting
+				est->state=BMS_SOC_CHARGE_C_CNT;
+				// no more need to wait for relaxation
+				est->ChargeRelaxationWaitCnt=0;
+				return 0;
+			}
+			return -1;	
+		break;
+		case BMS_SOC_CHARGE_AREA_FULL:
+			// battery is considered full
+			// set SoC to 100%
+			est->SoC_percentage=1.0;
+			est->SoC_Ah=est->capacity;
+			// set maximum charge current to 0
+			est->MaxBatteryChargeCurrent=0;
+			// set Flag to prevent SOC from falling in case of relaxation
+			est->flags=BMS_SOC_FLAG_SOC_100;
+			est->state=BMS_SOC_READY;
+			return 0;
+		break;
+		case BMS_SOC_CHARGE_WAIT_FOR_RELAXATION:
+			// wait a couple of seconds for Relaxation to prevent 
+			// unjustified update of SoC
+			est->ChargeRelaxationWaitCnt++;
+			
+			if(est->ChargeRelaxationWaitCnt > 100) {
+				est->state=	BMS_SOC_CHARGE_AREA_HIGH;
+			}
+			else {
+				est->state= BMS_SOC_CHARGE_C_CNT;
+			}
+			return 0;
+		break;	
+		case BMS_SOC_CHARGE_AREA_HIGH:
+			// open clamp Voltage is higer than threshold
+			// => Battery is nearly fully charged => SoC from columb counting has to be updated	
+			// set SoC predefined Value
+			if(est->flags!=BMS_SOC_FLAG_SOC_HIGH) {
+				// save old SoC value for Smoothing
+				est->SoC_Ah_smooth=est->SoC_Ah;
+				est->SoC_percentage_smooth=est->SoC_percentage;
+				
+				// update SoC value
+				est->SoC_percentage=est->ChargeThreshold.U_ocv_SoC;
+				est->SoC_Ah=est->SoC_percentage * est->capacity;
+				// set high flag to indicate that SoC has already been updated
+				est->flags=BMS_SOC_FLAG_SOC_HIGH;
+			}
+			// continue columb cnt
+			est->state=BMS_SOC_CHARGE_C_CNT;
+			return 0;	
+		break;
+		case  BMS_SOC_CHARGE_C_CNT: 
+			// calculate SoC using coulumb counting
+			est->SoC_Ah=est->SoC_Ah +  est->delta_t* (-1)*(float)I_batt/1000 ;
+			est->SoC_percentage=est->SoC_Ah/est->capacity;
+			est->state=BMS_SOC_CHARGE_SMOOTHING;
+			return 0;
+		break;
+		case BMS_SOC_CHARGE_SMOOTHING:
+			// prevents jumps in SoC 
+			if(est->flags == BMS_SOC_FLAG_SOC_100) {
+				est->ChargeSmoothFlags=0;
+				est->SoC_percentage_smooth=est->SoC_percentage ;
+				est->state=BMS_SOC_READY;  
+				return 0;							   ; 
+			}
+			else if(est->SoC_percentage > 0.99 && est->flags != BMS_SOC_FLAG_SOC_100) {
+				// keep SoC at 99,5% until U_bat Max is reached
+				if(est->ChargeSmoothFlags != BMS_SOC_CHARGE_SMOOTH_99){
+					est->ChargeSmoothFlags=  BMS_SOC_CHARGE_SMOOTH_99;
+					est->SoC_percentage_smooth=est->SoC_percentage;
+					est->SoC_Ah_smooth=est->SoC_Ah;
+				}
+				else {
+					// do nothing	
+				}
+				est->state=BMS_SOC_CHARGE_DERATE;  
+				return 0;
+			}
+			else if(est->SoC_percentage >= est->ChargeThreshold.U_ocv_SoC && est->flags != BMS_SOC_FLAG_SOC_HIGH && est->ChargeSmoothFlags != BMS_SOC_CHARGE_SMOOTH_OVERSHOOT) {
+				 // Overshoot event has occured
+				 // this means that the SoC estimated by coulumb counting is higher than
+				 // the SoC based on the OCV => implement slowed coulumb cnt
+				 
+				 // save SoC
+				 est->SoC_Ah_smooth=est->SoC_Ah;
+				 est->SoC_percentage_smooth=est->SoC_percentage;
+				 // Set Flag to indicate that overshoot correction is enabled
+				 est->ChargeSmoothFlags=BMS_SOC_CHARGE_SMOOTH_OVERSHOOT;
+				 est->state=BMS_SOC_CHARGE_DERATE;  
+				return 0;
+			}
+			else if( est->ChargeSmoothFlags == BMS_SOC_CHARGE_SMOOTH_OVERSHOOT) {
+				// Smooth out overshoot by slowed down coulumb counting
+				est->SoC_Ah_smooth=est->SoC_Ah_smooth + est->delta_t* (-1)*(float)I_batt/1000*0.5 ;
+				est->SoC_percentage_smooth=est->SoC_Ah_smooth/est->capacity;
+				
+				if( bms_SoC_get_norm(est->SoC_percentage_smooth - est->SoC_percentage) <= 0.001) {
+					// if Error is smaller than 0.5 % stopp correction
+					est->ChargeSmoothFlags=0;
+					est->SoC_percentage_smooth=est->SoC_percentage;
+					est->SoC_Ah_smooth=est->SoC_Ah;  
+					
+				}
+				est->state=BMS_SOC_CHARGE_DERATE;  
+				return 0;
+			}
+			else if( est->flags == BMS_SOC_FLAG_SOC_HIGH && est->ChargeSmoothFlags !=BMS_SOC_CHARGE_SMOOTH_UNDERSHOOT) {
+				// Undershoot event hast occured
+				// this means that SoC estimated by coulumb counting is lower
+				// than SoC based on the OCV => implement faster coulumb cnt
+				
+				 // Set Flag to indicate that undershoot correction is enabled
+				 est->ChargeSmoothFlags=BMS_SOC_CHARGE_SMOOTH_UNDERSHOOT;
+				 est->state=BMS_SOC_CHARGE_DERATE;  
+				 return 0;
+			}
+			else if( est->flags == BMS_SOC_FLAG_SOC_HIGH && est->ChargeSmoothFlags ==BMS_SOC_CHARGE_SMOOTH_UNDERSHOOT) {
+				// smooth out under shoot by speeding up coulumb counting
+				est->SoC_Ah_smooth=est->SoC_Ah_smooth + est->delta_t* (-1)*(float)I_batt/1000*4 ;
+				est->SoC_percentage_smooth=est->SoC_Ah_smooth/est->capacity;
+				if( bms_SoC_get_norm(est->SoC_percentage_smooth - est->SoC_percentage) <= 0.001) {
+					// if Error is smaller than 0.1 % stopp correction
+					est->ChargeSmoothFlags=0;
+					est->SoC_percentage_smooth=est->SoC_percentage;
+					 est->SoC_Ah_smooth=est->SoC_Ah;  
+				}
+				est->state=BMS_SOC_CHARGE_DERATE;  
+				return 0;
+			}
+			else {
+				est->SoC_Ah_smooth=est->SoC_Ah;
+				est->SoC_percentage_smooth=est->SoC_percentage; 
+				est->state=BMS_SOC_CHARGE_DERATE;  
+				return 0;
+			}
+			return 0;
+		break;	
+		case BMS_SOC_CHARGE_DERATE:
+			// derate SoC depending on the SoC and temperature
+			bms_set_derating(est, temp_min, temp_max);
+			est->state=BMS_SOC_READY;
+			return 0;	
+		break;
+		case BMS_SOC_DISCHARGE:
+			// Battery is discharged
+			// if Battery has been charged to 100% SoC remove charge Flag
+			
+			// no more need to wait for relaxation at charging
+			est->ChargeRelaxationWaitCnt=0;
+				
+			if(est->flags==BMS_SOC_FLAG_SOC_100 && est->SoC_percentage < est->ChargeThreshold.U_ocv_SoC) {
+				est->flags=0;		
+			}
+			
+			if(est->flags==BMS_SOC_FLAG_SOC_HIGH && est->SoC_percentage < est->ChargeThreshold.U_ocv_SoC) {
+				// clear BMS_SOC_HIGH flag
+				est->flags=0;
+			}
+			
+			if(est->ChargeSmoothFlags==  BMS_SOC_CHARGE_SMOOTH_99 &&  est->SoC_percentage <0.99) {
+				// 	 clear BMS_SOC_DISCHARGE_SMOOTH_01 flage 
+				est->ChargeSmoothFlags=0;
+			}
+			// calculate OCV
+			// ToDo: add temperature dependency of Ri 
+			R_i=est->DischargeThreshold.Ri_discharge;
+			OCV=   U_batt_min + R_i *(float)I_batt/1000; // I_batt is positive ;
+			est->Ocv_calc = OCV;
+			if(est->flags==BMS_SOC_FLAG_SOC_0) {
+				// SoC = 0% has been reached keep SoC at 0% until charging starts;
+				// => do nothing
+				est->state=BMS_SOC_DISCHARGE_SMOOTHING;
+				return 0;
+			}
+			else if(U_batt_min <  est->DischargeThreshold.U_bat_min ) {
+				// if Cell voltage is lower than a threshold battery is considered fully discharged
+				// comparison with cell voltage is necessary because battery model might not be accurate enought
+				est->state=BMS_SOC_DISCHARGE_AREA_EMPTY;
+				return 0;
+			}
+			else if(est->ChargeSmoothFlags==  BMS_SOC_DISCHARGE_SMOOTH_01) {
+				// SoC => 99% wait till U_bat max is reached
+				est->state=BMS_SOC_CHARGE_SMOOTHING;
+				return 0;
+			}
+			else if(OCV < est->DischargeThreshold.U_ocv_correct)  {
+				// open clamp Voltage is lower than threshold
+				// => Battery is nearly fully discharged => SoC from columb counting has to be updated
+				est->state=BMS_SOC_DISCHARGE_WAIT_FOR_RELAXATION;
+				return 0;
+			}
+			else {
+				// no special Area to take care of
+				// proceed with columb counting
+				est->state=BMS_SOC_DISCHARGE_C_CNT;
+				
+				est->DischargeRelaxationWaitCnt=0;
+				return 0;
+			}
+			return 0;
+		break;
+		case BMS_SOC_DISCHARGE_AREA_EMPTY:
+			// Battery is considered empty => Set SoC to 0%
+			est->SoC_percentage=0;
+			est->SoC_Ah=0;
+			// set Maximum discharge Current to 0
+			est->MaxBatteryDischargeCurrent =0;
+			// set empty flag
+			est->flags=BMS_SOC_FLAG_SOC_0;
+			est->state=BMS_SOC_DISCHARGE_SMOOTHING;
+			return 0;
+		break;
+		case BMS_SOC_DISCHARGE_WAIT_FOR_RELAXATION: 
+			// wait a couple of seconds for Relaxation to prevent 
+			// unjustified update of SoC
+			est->DischargeRelaxationWaitCnt++;
+			
+			if(est->DischargeRelaxationWaitCnt > 100) {
+				est->state=	BMS_SOC_DISCHARGE_AREA_LOW;
+			}
+			else {
+				est->state= BMS_SOC_DISCHARGE_C_CNT;
+			}
+			return 0;			
+		break;
+		case  BMS_SOC_DISCHARGE_AREA_LOW:
+			// open clamp Voltage is lower than threshold
+			// => Battery is nearly fully dicharged => SoC from columb counting has to be updated
+
+			// set SoC predefined Value	
+			if(est->flags!=BMS_SOC_FLAG_SOC_LOW) {
+				// save SoC for Smoothing
+				est->SoC_Ah_smooth=est->SoC_Ah;
+				est->SoC_percentage_smooth=est->SoC_percentage;
+				est->SoC_percentage=est->DischargeThreshold.U_ocv_SoC;
+				est->SoC_Ah=est->SoC_percentage * est->capacity;
+				// set LOW flag to indicate that SoC has already been updated
+				est->flags=BMS_SOC_FLAG_SOC_LOW;
+			}
+			// continue columb cnt
+			est->state=BMS_SOC_DISCHARGE_C_CNT;
+			return 0;
+		break;
+		case BMS_SOC_DISCHARGE_C_CNT:
+			// calculate SoC using coulumb counting  
+			est->SoC_Ah=est->SoC_Ah - est->delta_t* (float)I_batt/1000;
+			est->SoC_percentage=  est->SoC_Ah/est->capacity;
+			est->state=BMS_SOC_DISCHARGE_SMOOTHING;
+			return 0;
+		break;
+		case BMS_SOC_DISCHARGE_SMOOTHING:
+			// prevents jumps in SoC 
+			if(est->flags == BMS_SOC_FLAG_SOC_0) {
+				est->ChargeSmoothFlags=0;
+				est->SoC_percentage_smooth=est->SoC_percentage ;
+				est->state=BMS_SOC_READY;  
+				return 0;							   ; 
+			}
+			else if(est->SoC_percentage <= 0.01 && est->flags != BMS_SOC_FLAG_SOC_0) {
+				// keep SoC at 0,5% until U_bat Max is reached
+				if(est->ChargeSmoothFlags != BMS_SOC_DISCHARGE_SMOOTH_01){
+					est->ChargeSmoothFlags=  BMS_SOC_DISCHARGE_SMOOTH_01;
+					est->SoC_percentage_smooth=est->SoC_percentage;
+					est->SoC_Ah_smooth=est->SoC_Ah;
+				}
+				else {
+					// do nothing	
+				}
+				est->state=BMS_SOC_DISCHARGE_DERATE;  
+				return 0;
+			}
+			else if(est->SoC_percentage <= est->DischargeThreshold.U_ocv_SoC && est->flags != BMS_SOC_FLAG_SOC_LOW && est->ChargeSmoothFlags != BMS_SOC_DISCHARGE_SMOOTH_OVERSHOOT) {
+				 // Overshoot event has occured
+				 // this means that the SoC estimated by coulumb counting is lower than
+				 // the SoC based on the OCV => implement slowed coulumb cnt
+				 
+				 // save SoC
+				 est->SoC_Ah_smooth=est->SoC_Ah;
+				 est->SoC_percentage_smooth=est->SoC_percentage;
+				 // Set Flag to indicate that overshoot correction is enabled
+				 est->ChargeSmoothFlags=BMS_SOC_DISCHARGE_SMOOTH_OVERSHOOT;
+				 est->state=BMS_SOC_DISCHARGE_DERATE;  
+				return 0;
+			}
+			else if( est->ChargeSmoothFlags == BMS_SOC_DISCHARGE_SMOOTH_OVERSHOOT) {
+				// Smooth out overshoot by slowed down coulumb counting
+				est->SoC_Ah_smooth=est->SoC_Ah_smooth - est->delta_t*(float)I_batt/1000*0.5 ;
+				est->SoC_percentage_smooth=est->SoC_Ah_smooth/est->capacity;
+				
+				if( bms_SoC_get_norm(est->SoC_percentage_smooth - est->SoC_percentage) <= 0.001) {
+					// if Error is smaller than 0.1 % stopp correction
+					est->ChargeSmoothFlags=0;
+					est->SoC_percentage_smooth=est->SoC_percentage;
+					est->SoC_Ah_smooth=est->SoC_Ah;
+					
+				}
+				est->state=BMS_SOC_DISCHARGE_DERATE;  
+				return 0;
+			}
+			else if( est->flags == BMS_SOC_FLAG_SOC_LOW && est->ChargeSmoothFlags !=BMS_SOC_DISCHARGE_SMOOTH_UNDERSHOOT) {
+				// Undershoot event has occured
+				// this means that SoC estimated by coulumb counting is higher
+				// than SoC based on the OCV => implement faster coulumb cnt
+				
+				 // Set Flag to indicate that undershoot correction is enabled
+				 est->ChargeSmoothFlags=BMS_SOC_DISCHARGE_SMOOTH_UNDERSHOOT;
+				 est->state=BMS_SOC_CHARGE_DERATE;  
+				 return 0;
+			}
+			else if( est->flags == BMS_SOC_FLAG_SOC_LOW && est->ChargeSmoothFlags ==BMS_SOC_DISCHARGE_SMOOTH_UNDERSHOOT) {
+				// smooth out under shoot by speeding up coulumb counting
+				est->SoC_Ah_smooth=est->SoC_Ah_smooth - est->delta_t*(float)I_batt/1000*4 ;
+				est->SoC_percentage_smooth=est->SoC_Ah_smooth/est->capacity;
+				if( bms_SoC_get_norm(est->SoC_percentage_smooth - est->SoC_percentage) <= 0.001) {
+					// if Error is smaller than 0.1 % stopp correction
+					est->ChargeSmoothFlags=0;
+					est->SoC_percentage_smooth=est->SoC_percentage;
+					est->SoC_Ah_smooth=est->SoC_Ah;
+				}
+				est->state=BMS_SOC_DISCHARGE_DERATE;  
+				return 0;
+			}
+			else {
+				est->SoC_percentage_smooth=est->SoC_percentage;
+				est->SoC_Ah_smooth=est->SoC_Ah;  
+				est->state=BMS_SOC_DISCHARGE_DERATE;  
+				return 0;
+			}
+			return 0;
+		break;			
+		case BMS_SOC_DISCHARGE_DERATE:
+			// derate SoC depending on the SoC and temperature
+			bms_set_derating(est, temp_min, temp_max);
+			est->state=BMS_SOC_READY; 
+			return 0;
+		break;
+		case BMS_SOC_REST:
+			// no charging or discharging => do nothing
+			est->state=BMS_SOC_READY;
+			return 0;
+		break;
+		case BMS_SOC_READY:
+			// SoC Estimation complete  do nothing
+			
+			// push FIFO
+			pushSoCFiFo(est); 
+			return 0;
+		break;
+		
+		
+	}
+	
+}
+
+/*
+ * set all SOC FIFO entries to start value;
+ * SoC FIFO necessary to give inverter time to react to derating and Master to transmit Derating info to inverter
+ */
+uint32_t initSoCFifo(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	for(i=0;i<SOC_SMOOTH_FIFO_SIZE;i++) {
+		s->SoC_estimator.SoC_percentage_smooth_FiFo[i]=s->SoC_estimator.SoC_percentage_smooth ;
+	}
+	return TRUE;
+}
+uint32_t pushSoCFiFo(MASTER_SOC_ESTIMATOR_t* est) {
+	uint8_t i;
+	for(i=SOC_SMOOTH_FIFO_SIZE-1;i>0;i--) {
+		est->SoC_percentage_smooth_FiFo[i]=est->SoC_percentage_smooth_FiFo[i-1];
+	}
+	est->SoC_percentage_smooth_FiFo[0]=est->SoC_percentage_smooth;
+	return TRUE;
+}
+
+
+	
+
+
+
+float bms_SoC_get_norm(float value) {
+	if(value >=0) {
+		return value;
+	}
+	else {
+		return value * (-1);
+	}
+}
+
+/*
+ * @brief set Derating
+ */
+uint32_t bms_set_derating(MASTER_SOC_ESTIMATOR_t* est, int8_t minTemp, int8_t maxTemp) {
+	float derating_charge_temp_high;
+	float derating_charge_temp_low;
+	float derating_charge_SoC;
+	float output_derate;
+	
+	float derating_discharge_temp_high;
+	float derating_discharge_temp_low;
+	float derating_discharge_SoC;
+
+	// charging
+	derating_charge_SoC=bms_calc_charge_derating(est->SoC_percentage_smooth);
+	derating_charge_temp_high=bms_calc_charge_temp_derating(maxTemp);
+	derating_charge_temp_low=bms_calc_charge_temp_derating(minTemp);
+	
+	// lowest current is choosen to be set as max charge current
+	
+	if(derating_charge_temp_low < derating_charge_temp_high) {
+		output_derate = derating_charge_temp_low;
+	}
+	else{
+		output_derate =derating_charge_temp_high;
+	}
+	
+	if(output_derate > derating_charge_SoC ) {
+		output_derate = derating_charge_SoC;
+	}
+	est->MaxBatteryChargeCurrent=output_derate;
+	
+	// discharging
+	derating_discharge_SoC= bms_calc_discharge_derating(est->SoC_percentage_smooth);
+	derating_discharge_temp_high = bms_calc_discharge_temp_derating(maxTemp);
+	derating_discharge_temp_low = bms_calc_discharge_temp_derating(minTemp);
+	
+	// lowest current is choosen to be set as max charge current
+	
+	if(derating_discharge_temp_low < derating_discharge_temp_high) {
+		output_derate = derating_discharge_temp_low;
+	}
+	else{
+		output_derate =derating_discharge_temp_high;
+	}
+	
+	if(output_derate > derating_discharge_SoC ) {
+		output_derate = derating_discharge_SoC;
+	}
+	
+	est->MaxBatteryDischargeCurrent=output_derate;
+	
+	return 0;
+}
+
+float bms_calc_charge_derating(float SoC) {
+	float delta_I=0;
+	float I_C_10=2.5;	// Current at C tens
+	float delta_I_max= BMS_SLAVE_MAX_CURRENT_A - I_C_10 ;
+	float delta_SoC = 0.15; // Linear interpolation region from 80 to 95 %
+	if( SoC <= 0.8) {
+		//return maximum allowed current
+		return 	BMS_SLAVE_MAX_CURRENT_A ;
+	}
+	else if( SoC > 0.8 && SoC < 0.95) {
+		//return linear interpolation between max aurrent and C/10
+		delta_I=  (delta_I_max * (0.95 - SoC)) / (delta_SoC);
+		return I_C_10 + delta_I;
+	}
+	else if( SoC >= 0.95 && SoC < 0.999){
+		// finish loading with C/10
+		return   I_C_10 ;
+	}
+	else{
+		return 0;	
+	}
+	return -1;
+	
+}
+
+float bms_calc_discharge_derating(float SoC) {
+	float delta_I=0;
+	float I_C_10=2.5;	// Current at C tens
+	float delta_I_max= BMS_SLAVE_MAX_CURRENT_A - I_C_10 ;
+	float delta_SoC = 0.15; // Linear interpolation region from 20 to 5 %
+	if( SoC >= 0.2) {
+		//return maximum allowed current
+		return 	BMS_SLAVE_MAX_CURRENT_A ;
+	}
+	else if( SoC < 0.2 && SoC > 0.05) {
+		//return linear interpolation between max aurrent and C/10
+		delta_I=  (delta_I_max * ( SoC - 0.05)) / (delta_SoC);
+		return I_C_10 + delta_I;
+	}
+	else if(SoC <= 0.05 && SoC > 0.001) {
+		// finish discharging with C/10
+		return   I_C_10 ;
+	}
+	else {
+		// 
+		return 0;
+	}
+	return -1;
+	
+}
+
+/*
+ * @ brief derate maximum charge current
+ */
+float bms_calc_charge_temp_derating(int8_t Temp) {
+	float maxCurrent;
+	float I_C1=25.0; // Current at C1 = 25A
+	// calc derated current for min temperature
+	if( Temp <= -5) {
+		maxCurrent= I_C1*0.2;
+		return maxCurrent;
+	}
+	else if(Temp > -5 && Temp <=0) {
+		maxCurrent=linear_interpolate(-5,0,Temp,I_C1*0.2,I_C1*0.5);
+		return maxCurrent;
+	}
+	else if(Temp >0 && Temp <=25) {
+		maxCurrent=linear_interpolate(0,25,Temp,I_C1*0.5,I_C1);
+		return maxCurrent;
+	}
+	else if(Temp> 25 && Temp <=35) {
+		maxCurrent=I_C1;
+		return maxCurrent;
+	}
+	else if(Temp> 35 && Temp <= 45) {
+		maxCurrent=linear_interpolate(35,45,Temp,I_C1,0);
+		return maxCurrent;
+	}
+	else{
+		return 0;
+	}
+}
+
+/*
+ * @ brief derate maximum discharge current 
+ */
+float bms_calc_discharge_temp_derating(int8_t Temp) {
+	float maxCurrent;
+	float I_C1=25.0; // Current at C1 = 25A
+	// calc derated current for min temperature
+	if( Temp <= 0) {
+		maxCurrent= I_C1*0.2;
+		return maxCurrent;
+	}
+	else if(Temp > 0 && Temp <=25) {
+		maxCurrent=linear_interpolate(0,25,Temp,I_C1*0.2,I_C1);
+		return maxCurrent;
+	}
+	else if(Temp >25 && Temp <=40) {
+		maxCurrent=I_C1;
+		return maxCurrent;
+	}
+	else if(Temp> 40 && Temp <=45) {
+		maxCurrent=I_C1=linear_interpolate(40,45,Temp,I_C1,0);
+		return maxCurrent;
+	}
+	else{
+		return 0;
+	}
+	
+}
+
+/*
+ *@brief do linear interpolation
+ */
+float linear_interpolate(int8_t x1,int8_t x2,int8_t x,float y1,float y2) {
+	// solve linear eq  y1= m*x1 + b
+	//					y2= m*x2 + b
+	float m = 	(y2-y1)/(float)(x2-x1);
+	float b =	y1 - m*(float)(x1);
+	
+	//
+	return m*(float)(x) + b;
+ }

+ 287 - 0
BMS Master/Sources/BMS_Startup.c

@@ -0,0 +1,287 @@
+/*
+ * BMS_Startup.c
+ *
+ *  Created on: Oct 19, 2016
+ *      Author: le8041
+ */
+
+#include "BMS_Master.h"
+
+
+/*
+ * @brief writes 8 bit byte to FRAM
+ */
+
+uint32_t write_fram_byte(uint8_t byte,uint32_t timeout,const vuint16_t Addr) {
+	uint32_t timestamp=Global_1msCounter;
+	FRAM_trigger_write(Addr, (vuint8_t *const)&byte,1);
+	while(Fram_S.Flags.B.JobFinished ==0 ) {
+		FRAM_update(0);
+		if(timestamp + timeout < Global_1msCounter) {
+			// timeout
+			return FALSE;
+		}
+	}
+	
+	Fram_S.Flags.B.JobFinished =0;
+	return TRUE;
+}
+ 
+/*
+ * @brief writes 16bit word to FRAM
+ */
+
+uint32_t write_fram_word(uint16_t word,uint32_t timeout,const vuint16_t Addr) {
+	uint32_t timestamp=Global_1msCounter;
+	FRAM_trigger_write(Addr, (vuint8_t *const)&word,2);
+	while(Fram_S.Flags.B.JobFinished ==0 ) {
+		FRAM_update(0);
+		if(timestamp + timeout < Global_1msCounter) {
+			// timeout
+			return FALSE;
+		}
+	}
+	
+	Fram_S.Flags.B.JobFinished =0;
+	return TRUE;
+}
+
+/*
+ * @brief writes 32bit float to FRAM
+ */
+
+uint32_t write_fram_float(float float_value,uint32_t timeout,const vuint16_t Addr) {
+	uint32_t timestamp=Global_1msCounter;
+	FRAM_trigger_write(Addr, (vuint8_t *const)&float_value,4);
+	while(Fram_S.Flags.B.JobFinished ==0 ) {
+		FRAM_update(0);
+		if(timestamp + timeout < Global_1msCounter) {
+			// timeout
+			return FALSE;
+		}
+	}
+	
+	Fram_S.Flags.B.JobFinished =0;
+	return TRUE;
+}
+
+/*
+ * @brief writes 32bit word to FRAM
+ */
+
+uint32_t write_fram_uint32(uint32_t word,uint32_t timeout,const vuint16_t Addr) {
+	uint32_t timestamp=Global_1msCounter;
+	FRAM_trigger_write(Addr, (vuint8_t *const)&word,4);
+	while(Fram_S.Flags.B.JobFinished ==0 ) {
+		FRAM_update(0);
+		if(timestamp + timeout < Global_1msCounter) {
+			// timeout
+			return FALSE;
+		}
+	}
+	
+	Fram_S.Flags.B.JobFinished =0;
+	return TRUE;
+}
+
+uint32_t read_fram_byte(uint8_t* word,uint32_t timeout,const vuint16_t Addr) {
+	uint32_t timestamp=Global_1msCounter;
+	FRAM_trigger_read(Addr, (vuint8_t *const)word,2);
+	while(Fram_S.Flags.B.JobFinished ==0 ) {
+		FRAM_update(0);
+		if(timestamp + timeout < Global_1msCounter) {
+			// timeout
+			return FALSE;
+		}
+	}
+	
+	Fram_S.Flags.B.JobFinished =0;
+	return TRUE;
+}
+
+uint32_t read_fram_word(uint16_t* word,uint32_t timeout,const vuint16_t Addr) {
+	uint32_t timestamp=Global_1msCounter;
+	FRAM_trigger_read(Addr, (vuint8_t *const)word,2);
+	while(Fram_S.Flags.B.JobFinished ==0 ) {
+		FRAM_update(0);
+		if(timestamp + timeout < Global_1msCounter) {
+			// timeout
+			return FALSE;
+		}
+	}
+	
+	Fram_S.Flags.B.JobFinished =0;
+	return TRUE;
+}
+
+uint32_t read_fram_uint32(uint32_t* word,uint32_t timeout,const vuint16_t Addr) {
+	uint32_t timestamp=Global_1msCounter;
+	FRAM_trigger_read(Addr, (vuint8_t *const)word,4);
+	while(Fram_S.Flags.B.JobFinished ==0 ) {
+		FRAM_update(0);
+		if(timestamp + timeout < Global_1msCounter) {
+			// timeout
+			return FALSE;
+		}
+	}
+	
+	Fram_S.Flags.B.JobFinished =0;
+	return TRUE;
+}
+
+
+
+uint32_t read_fram_float(float* word,uint32_t timeout,const vuint16_t Addr) {
+	uint32_t timestamp=Global_1msCounter;
+	FRAM_trigger_read(Addr, (vuint8_t *const)word,4);
+	while(Fram_S.Flags.B.JobFinished ==0 ) {
+		FRAM_update(0);
+		if(timestamp + timeout < Global_1msCounter) {
+			// timeout
+			return FALSE;
+		}
+	}
+	
+	Fram_S.Flags.B.JobFinished =0;
+	return TRUE;
+}
+
+
+
+uint32_t read_fram_get_startup_state(MASTER_CAN0_STRUCT_t* s) {
+	uint32_t ret;
+	ret = read_fram_word(&(s->startupConfig.state.word),5,BMS_STARTUP_MODE_ADDR);
+	if(ret == FALSE) {
+		// FRAM READ FAIL
+		s->startupConfig.state.word=0;
+		return FALSE;
+	}
+	else {
+		return TRUE;
+	}
+}
+
+
+
+float read_fram_get_SoC() {
+	float SoC=-1.0;
+	read_fram_float(&SoC,3,BMS_STARTUP_SOC) ;
+	return SoC;
+}
+
+uint32_t write_fram_set_SoC(float SoC) {
+	return write_fram_float(SoC,3,BMS_STARTUP_SOC); 
+}
+
+uint32_t write_fram_set_startup_state(MASTER_CAN0_STRUCT_t* s) {
+	return write_fram_word(s->startupConfig.state.word,3,BMS_STARTUP_MODE_ADDR);
+}
+
+uint32_t write_fram_clear_startup_state() {
+	return write_fram_word((0),5,BMS_STARTUP_MODE_ADDR);
+}
+
+uint32_t write_fram_write_error(uint32_t Error,uint8_t ErrorLevel,uint8_t ErrorNr) {
+	uint16_t addr;
+	if(ErrorLevel == BMS_ERROR_CLASS_1) {
+		// write Error Buffer 1
+		addr=BMS_ERROR_BUFFER1_OFFSET+sizeof(uint32_t)*ErrorNr;
+		return write_fram_uint32(Error,5,addr);
+	}
+	else if( ErrorLevel == BMS_ERROR_CLASS_2) {
+		// write Error Buffer 2
+		addr=BMS_ERROR_BUFFER2_OFFSET+sizeof(uint32_t)*ErrorNr;
+		return write_fram_uint32(Error,5,addr);
+	}
+	else {
+		// write Error Buffer 3
+		addr=BMS_ERROR_BUFFER3_OFFSET+sizeof(uint32_t)*ErrorNr;
+		return write_fram_uint32(Error,5,addr);
+	}
+}
+
+
+uint32_t read_fram_read_error_buffer(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	uint32_t Error;
+	uint16_t addr;
+	uint32_t return_value=0;
+	// read Error buffer 1
+	addr=BMS_ERROR_BUFFER1_OFFSET;
+	for(i=0;i<BMS_ERROR_ERROR_STACK_SIZE;i++) {
+		return_value=read_fram_uint32(&(s->ErrorBuffer.ES1_Error[i].Word),5,addr) ;
+		// increment Pointer
+		addr=addr+sizeof(Error);
+		// check if last Error entry reached
+		if(s->ErrorBuffer.ES1_Error[i].Word == 0) {
+			// no errors any more
+			s->ErrorBuffer.ES1_ErrorCounter=i;
+			break;
+		}
+	}
+	
+	// read Error buffer 2
+	addr=BMS_ERROR_BUFFER2_OFFSET;
+	for(i=0;i<BMS_ERROR_ERROR_STACK_SIZE;i++) {
+		return_value=read_fram_uint32(&(s->ErrorBuffer.ES2_Error[i].Word),5,addr) ;
+		// increment Pointer
+		addr=addr+sizeof(Error);
+		// check if last Error entry reached
+		if(s->ErrorBuffer.ES2_Error[i].Word == 0) {
+			// no errors any more
+			s->ErrorBuffer.ES2_ErrorCounter=i;
+			break;
+		}
+	}
+	
+	// read Error buffer 3
+	addr=BMS_ERROR_BUFFER3_OFFSET;
+	for(i=0;i<BMS_ERROR_ERROR_STACK_SIZE;i++) {
+		return_value=read_fram_uint32(&(s->ErrorBuffer.ES3_Error[i].Word),5,addr) ;
+		// increment Pointer
+		addr=addr+sizeof(Error);
+		// check if last Error entry reached
+		if(s->ErrorBuffer.ES3_Error[i].Word == 0) {
+			// no errors any more
+			s->ErrorBuffer.ES3_ErrorCounter=i;
+			break;
+		}
+	}
+}
+
+uint32_t write_fram_clear_error_buffer(MASTER_CAN0_STRUCT_t* s) {
+	uint8_t i;
+	uint32_t Error;
+	uint16_t addr;
+	uint32_t Return_Value;
+	uint32_t test=100;
+	// clear Error buffer 1
+	addr=BMS_ERROR_BUFFER1_OFFSET;
+	for(i=0;i<BMS_ERROR_ERROR_STACK_SIZE;i++) {
+		Return_Value=write_fram_uint32(0,5,addr) ;
+		
+		read_fram_uint32(&test,5,addr) ;
+		addr=addr+sizeof(uint32_t);
+	}
+	
+	// read Error buffer 2
+	addr=BMS_ERROR_BUFFER2_OFFSET;
+	for(i=0;i<BMS_ERROR_ERROR_STACK_SIZE;i++) {
+		Return_Value=write_fram_uint32(0,5,addr) ;
+		addr=addr+sizeof(uint32_t);
+	}
+	
+	// read Error buffer 3
+	addr=BMS_ERROR_BUFFER3_OFFSET;
+	for(i=0;i<BMS_ERROR_ERROR_STACK_SIZE;i++) {
+		Return_Value=write_fram_uint32(0,5,addr) ;
+		addr=addr+sizeof(uint32_t);
+	}
+}
+	
+
+
+
+
+
+

+ 107 - 0
BMS Master/Sources/BoardPeripherals.c

@@ -0,0 +1,107 @@
+#include "BMS_Master.h"
+
+
+
+#define TEST_TIMEOUT	10000
+
+extern uint32_t Global_1msCounter; 
+static vuint32_t TimeStamp;
+
+static void init_BoardIO();
+
+static const Board_Status Board_Status_INIT = {{0},0};
+Board_Status Board_S;	//globaler BoardStatus
+
+
+
+void BoardPeriph_init()
+{
+	RelaisLEDs_init();
+//	IMess_init();
+//	IMess_URef_init();
+	TempMess_init();
+//	UartToUsb_init();
+	//init FRAM
+	Board_S = Board_Status_INIT;
+	Board_S.FRAM_Flags.B.init_ok = (FRAM_init()>=0) ? 1:0;
+}
+
+
+
+void BoardPeriph_test_init()
+{
+	TimeStamp = Global_1msCounter;
+	FRAM_trigger_Test();
+}
+
+
+
+int8_t BoardPeriph_test_update_polled()
+{
+	static uint8_t state = 0;
+	static int8_t FRAM_result = 0;
+	static uint32_t old_Global_1msCounter = 0;
+	uint8_t tick = 0;
+	int8_t result = 0;
+	
+	if (Global_1msCounter != old_Global_1msCounter) tick = 1;
+	
+	switch (state) {
+		case 0:
+			if ( RelaisLEDs_TM_update(tick) == 1 )
+				state = 1;
+			break;
+		case 1: 
+		{
+			FRAM_update(tick);
+			if (FRAM_result == 0) {
+				FRAM_result = FRAM_Test_update();
+				if (FRAM_result > 0) Board_S.FRAM_Flags.B.test_ok = 1;
+				else if (FRAM_result < 0) Board_S.FRAM_Flags.B.test_fail = 1;
+			}
+			result = FRAM_result;
+//			Board_S.test_time = Global_1msCounter - TimeStamp;
+//			if ( Board_S.test_time >= TEST_TIMEOUT ) return -100;
+			break;
+		}
+	}
+	old_Global_1msCounter = Global_1msCounter;
+	
+	return result;
+}
+
+
+
+void BoardPeriph_update_1ms()
+{
+//	IMess_update();
+//	IMess_URef_update();
+	TempMess_update();
+}
+
+
+
+void BoardPeriph_update_polled()
+{
+	static uint32_t old_Global_1msCounter = 0;
+	uint8_t tick = 0;
+	if (Global_1msCounter != old_Global_1msCounter) {
+		tick = 1;
+	}
+	
+	FRAM_update(tick);
+	CAN0_update();
+	
+	old_Global_1msCounter = Global_1msCounter;
+}
+
+
+
+/*
+void do_Testroutine()
+{
+	FRAM_do_Test();
+	ADC_do_Test();
+	IMessLEM_do_Test();
+	TempADC_do_Test();
+}*/

+ 292 - 0
BMS Master/Sources/DSPI.c

@@ -0,0 +1,292 @@
+//==============================================================================
+// Purpose:    SPI Interface für das DSPI-Modul des MPC5646
+//
+// Created on:  20.04.2012 by IPE
+//
+// History
+//		20.04.2012 neu, T.Maurer
+//==============================================================================
+
+
+#include "BMS_Master.h"
+
+
+
+/*
+const DSPI_config_t SPI_1_Config = {
+	&DSPI_1,
+	DSPI_Slave,
+	16,	//FrameSize
+	DSPI_ClassicFormat,
+	DSPI_Baud15MHz,
+	0,
+	0,
+	0,
+	1,
+	DSPI1_PortE4
+};
+*/
+
+
+
+const DSPI_config_t SPI_6_Config = {
+	&DSPI_6,
+	DSPI_Master,
+	16,	//FrameSize
+	DSPI_ClassicFormat,
+	DSPI_Baud2MHz,
+	4,
+	4,
+	10,
+	1,
+	CS_Cont_ON,	//enum{CS_Cont_ON, CS_Cont_OFF};
+	DSPI6_PortG14
+};
+
+
+
+// ----------------------------------------------------------------------------
+
+int8_t DSPI_init(DSPI_config_t *const Config) 
+{
+	volatile struct DSPI_tag *p_DSPI;
+	p_DSPI = Config->p_Modul;
+
+  // -------------------------------------------------------------------
+  // DSPI_0.MCR.R = 0x80010001;     // Configure DSPI_0 as master, and HALT the DSPI module für reg configuration //
+
+	p_DSPI->MCR.B.MSTR 			= (Config->MaSlv_Mode==DSPI_Master) ? 1:0;		// 1: Master Mode, 0:Slave Mode
+	p_DSPI->MCR.B.CONT_SCKE		= 0;		// 0: Continuous serial clock: disabled
+	p_DSPI->MCR.B.DCONF			= 0b00;		// 00: SPI Mode, 01 DSI Mode, 10:CSI Mode
+	p_DSPI->MCR.B.FRZ			= 0b0;		// FREEZE: 0; if Freeze=1, tx will be stopped on next frame tx in DEBUG
+	p_DSPI->MCR.B.MTFE 			= (Config->TimingFormat==DSPI_ModifiedFormat) ? 1:0;		// Modified Timing Format Enable; 0: disabled
+	p_DSPI->MCR.B.PCSSE			= 0b0;		// Peripheral chip select strobe enable; 0:0  CS5_x is used as the Peripheral chip select 5 signal
+	p_DSPI->MCR.B.ROOE			= 0b0;		// Recieve FIFO Overflow Overwrite; 0: incoming data is ignored, 1: Incoming data is shifted in register
+
+	p_DSPI->MCR.B.PCSIS5		= (Config->Std_CS_Mask & 32) ? 1:0;		// Peripheral Chip Select 5 inactive state: 0: inactiv CS=low
+	p_DSPI->MCR.B.PCSIS4		= (Config->Std_CS_Mask & 16) ? 1:0;		// Peripheral Chip Select 4 inactive state: 0: inactiv CS=low
+ 	p_DSPI->MCR.B.PCSIS3		= (Config->Std_CS_Mask & 8) ? 1:0;		// Peripheral Chip Select 3 inactive state: 0: inactiv CS=low
+	p_DSPI->MCR.B.PCSIS2		= (Config->Std_CS_Mask & 4) ? 1:0;		// Peripheral Chip Select 2 inactive state: 0: inactiv CS=low
+	p_DSPI->MCR.B.PCSIS1		= (Config->Std_CS_Mask & 2) ? 1:0;		// Peripheral Chip Select 1 inactive state: 0: inactiv CS=low
+	p_DSPI->MCR.B.PCSIS0		= (Config->Std_CS_Mask & 1) ? 1:0;		// Peripheral Chip Select 0 inactive state: 1: inactiv CS=HIGH
+  
+	p_DSPI->MCR.B.MDIS			= 0b0;		// Module diable; 0:Enable DSPI CLKs; 1 Allow external logic to disable DSPI CLKs
+	p_DSPI->MCR.B.DIS_TXF		= 0b0;		// Disable Receive FIFO; 0 TX FIFO enabled; 1: simplified double buffered SPI
+	p_DSPI->MCR.B.DIS_RXF		= 0b0;		// Disable Receive FIFO; 0 RX FIFO enabled; 1: simplified double buffered SPI
+
+	p_DSPI->MCR.B.CLR_TXF		= 0b0;		// Clear TX FIFO, used to flush TX_FIFO: writing a 1: Clear TX FIFO Counter
+	p_DSPI->MCR.B.CLR_RXF		= 0b0;		// Clear RX FIFO, used to flush RX_FIFO: writing a 1: Clear RX FIFO Counter
+	p_DSPI->MCR.B.SMPL_PT		= 0b00;		// Sample Point in modified transfers 00: rising SLK
+
+	p_DSPI->MCR.B.PES			= 0b0;		// Parity Error Stop, 0: SPI transmission continues on error
+	p_DSPI->MCR.B.HALT			= 0b1;		// 1: Stop Transfers, 0:start transfers
+
+	// -------------------------------------------------------------------  
+	//DSPI_0.CTAR[0].R 			= 0x780A7727; 		// Configure CTAR0, Clock and Transfer Attributes  //
+
+	if (Config->FrameSize==0) return -1;
+	p_DSPI->CTAR[0].B.FMSZ 	= Config->FrameSize-1;	// FMSZ:	0b0111:	8Bit (7+1) werden übertragen Frame Size
+	p_DSPI->CTAR[0].B.CPOL 	= 0b0;	 	// CPOL:	0b0  	Clock Polarity 0-SCK active High
+	p_DSPI->CTAR[0].B.CPHA 	= 0b0;	 	// CPHA:	0b0  	Clock Phase 0 captue data on leading edge, change on following edge
+	p_DSPI->CTAR[0].B.LSBFE 	= 0b0;   	// LSBFE:	0b0     LSB first enable: 0 MSB fisrt
+	
+	//Delays
+	if (Config->AfterSCK_Delay_Cycles < 16) {
+		p_DSPI->CTAR[0].B.PASC 		= 0;  	// PASC :	0b00	After SCK Delay Prescaler 00: value is 1
+		p_DSPI->CTAR[0].B.ASC 		= Config->AfterSCK_Delay_Cycles;	// ASC  :	0b0111	After Serial Clock Scaler, is the delay between the last Clk on the negation of PCS
+	}
+	else return -1;
+	if (Config->CStoSCK_Delay_Cycles < 16) {
+		p_DSPI->CTAR[0].B.PCSSCK 	= 0;  	// PCSSCK:	0b00    PCS to SCK Delay: 00 value is 1     
+		p_DSPI->CTAR[0].B.CSSCK 	= Config->CStoSCK_Delay_Cycles;	// CSSCK:	0b0111	CS to SCK Delay Scaler, The CS to SCK Delay is the delay between the assertion of PCS and the first edge of SCK
+	}
+	else return -1;
+	if (Config->DelayAfterTransfer_Cycles < 16) {
+		p_DSPI->CTAR[0].B.PDT 		= 0;  	// PDT	 :	0b10	Delay after transfer Prescaler, Delay between CS signal and PCS of next frame (prescaler) 10:value is 5
+		p_DSPI->CTAR[0].B.DT 		= Config->DelayAfterTransfer_Cycles;	// DT:		0b0010  Delay after transfer (time between CS at the end of the frame and the assertion of PCS of next frame)
+	}
+	else return -1;
+	
+	//BaudRate
+	if (Config->Baud_Setting==DSPI_Baud15MHz) {
+		p_DSPI->CTAR[0].B.DBR = 0b0;	 	// DBR: 	0b0:	Double Baud Rate:0x0 
+		p_DSPI->CTAR[0].B.PBR = 0b00;  		// PBR	 :	0b01 	BaudRatePrescaler: 00 -> 2,  01 -> 3
+		p_DSPI->CTAR[0].B.BR  = 0b0000;		// BR:		0b0001	BaudRateScaler; SCK baud rate= f_sys/PBR*(1+DBR)/BR, 0001: value is 4
+											// 					fsys=60MHZ Peripheral 2 Settings und PBR=3,BR=4: 5MHZ Serial Port Frequency
+	}
+	else if (Config->Baud_Setting==DSPI_Baud5MHz) {
+		p_DSPI->CTAR[0].B.DBR = 0b0;	 	// DBR: 	0b0:	Double Baud Rate:0x0 
+		p_DSPI->CTAR[0].B.PBR = 0b01;  		// PBR	 :	0b01 	BaudRatePrescaler: 01 - value is 3
+		p_DSPI->CTAR[0].B.BR  = 0b0001;		// BR:		0b0001	BaudRateScaler; 0000->2,0001->4; SCK baud rate= f_sys/PBR*(1+DBR)/BR, 0001: value is 4
+											// 					fsys=60MHZ Peripheral 2 Settings und PBR=3,BR=4: 5MHZ Serial Port Frequency
+	}
+	else if (Config->Baud_Setting==DSPI_Baud2MHz) {
+		p_DSPI->CTAR[0].B.DBR = 0b0;	 	// DBR: 	0b0:	Double Baud Rate:0x0 
+		p_DSPI->CTAR[0].B.PBR = 0b10;	  	// PBR	 :	0b01 	BaudRatePrescaler: 01 - value is 3
+		p_DSPI->CTAR[0].B.BR  = 0b0010;		// BR:		0b0001	BaudRateScaler; 0000->2,0001->4; SCK baud rate= f_sys/PBR*(1+DBR)/BR, 0001: value is 4
+											// 					fsys=60MHZ Peripheral 2 Settings und PBR=3,BR=4: 5MHZ Serial Port Frequency
+	}
+	// -------------------------------------------------------------------  
+	p_DSPI->MCR.B.HALT = 0x0;	     		// Exit HALT mode: go from STOPPED to RUNNING state, die Initialisierung nur im Halt Mode//
+
+	// -------------------------------------------------------------------  
+
+	// configure port pins for DSPI
+	if (p_DSPI==(&DSPI_0) && Config->Port==DSPI0_PortA12) {
+		SIU.PCR[12].R = 0x0103;        		// Config pad as DSPI_0 SIN input,   PA[12], FRAM DOUT 
+		SIU.PCR[13].R = 0x0604;        		// Config pad as DSPI_0 SOUT output, PA[13], FRAM DIN 
+		SIU.PCR[14].R = 0x0604;        		// Config pad as DSPI_0 SCK output,  PA[14], FRAM SCLK 
+		SIU.PCR[15].R = 0x0604;        		// Config pad as DSPI_0 CS0 output, PA[15], FRAM CS 	
+		SIU.PSMI[5].R = 0b000;		 		// select PCR[14] as SCK0_0, Fehler in Registerbeschreibung und MPC5646 Reference Manual?
+		SIU.PSMI[6].R = 0b001;		 		// select PCR[15] as CS0_0
+	}
+	else if (p_DSPI==(&DSPI_1) && Config->Port==DSPI1_PortE4) {
+		SIU.PCR[68].R = 0x0903;        		// MPC56xxB: Config pad as DSPI_1 SCK input, PE[4] //
+		SIU.PSMI[7].R = 1;             		// MPC56xxB: Select PCR 68 for DSPI_1 SCK input //
+		SIU.PCR[36].R = 0x0103;        		// MPC56xxB: Config pad as DSPI_1 SIN input, , PC[4] //
+		SIU.PSMI[8].R = 0;             		// MPC56xxB: Select PCR 36 for DSPI_1 SIN input //
+		SIU.PCR[37].R = 0x0604;        		// MPC56xxB: Config pad as DSPI_1 SOUT output, PC[5]//
+		SIU.PCR[69].R = 0x0903;        		// MPC56xxB: Config pad as DSPI_1 PCS0/SS input, PE[5] //
+		SIU.PSMI[9].R = 2;             		// MPC56xxB: Selec PCR 69 for DSPI_1 SS input //
+	}
+	else if (p_DSPI==(&DSPI_2) && Config->Port==DSPI2_PortC12) {
+		SIU.PCR[44].R  = 0x0103;       		// Config pad as DSPI_2 SIN input,   PC[12], TEMP DOUT 
+		SIU.PCR[45].R  = 0x0A04;       		// Config pad as DSPI_2 SOUT output, PC[13], n.u.,		AF2
+		SIU.PCR[46].R  = 0x0A04;        	// Config pad as DSPI_2 SCK output,  PC[15], TEMP SCLK,	AF2 
+		SIU.PSMI[10].R = 0b000;		 		// select PCR[46] as SCK_2
+		SIU.PCR[47].R  = 0x0A04;        	// Config pad as DSPI_2 CS0 output, PA[14], TEMP CS,	AF2 	
+		SIU.PSMI[12].R = 0b000;		 		// select PCR[47] as CS0_2
+	}
+	else if (p_DSPI==(&DSPI_3) && Config->Port==DSPI3_PortG2) {
+		SIU.PCR[98].R  = 0x0A04;        	// Config pad as DSPI_3 SOUT output, PG[2], AF2
+		SIU.PCR[99].R  = 0x0A04;        	// Config pad as DSPI_3 CS0 output,  PG[3], AF2 	
+		SIU.PCR[100].R = 0x0A04;        	// Config pad as DSPI_3 SCK output,  PG[4]	AF2 
+		SIU.PSMI[32].R = 0b0000;		 	// select PCR[100] as SCK_3
+		SIU.PSMI[34].R = 0b0000;		 	// select PCR[99] as CS0_3
+	}
+	else if (p_DSPI==(&DSPI_4) && Config->Port==DSPI4_PortK9) {
+		SIU.PCR[170].R = 0x0604;        	// Config pad as DSPI_4 SOUT output, AF1
+		SIU.PCR[169].R = 0x0102;        	// Config pad as DSPI_4 SIN input,  
+		SIU.PCR[171].R = 0x0604;        	// Config pad as DSPI_4 SCK output, AF1 
+		SIU.PCR[172].R = 0x0604;        	// Config pad as DSPI_4 CS_4 output, AF1
+		SIU.PSMI[35].R = 0b0011;        	// Select PCR 171 for SCK_4
+		SIU.PSMI[36].R = 0b0010;        	// Select PCR 169 for SIN_4 
+		SIU.PSMI[37].R = 0b0100;        	// Select PCR 172 for CS0_4 
+	}
+	else if (p_DSPI==(&DSPI_6) && Config->Port==DSPI6_PortG14) {
+		SIU.PCR[110].R = 0x0103;        	// Config pad as DSPI_6 SIN input,   PG[14], TEMP DOUT,	 
+		SIU.PCR[111].R = 0x0A04;        	// Config pad as DSPI_6 SOUT output, PG[15], n.u., 		AF2
+		SIU.PCR[79].R  = 0x0E04;        	// Config pad as DSPI_6 SCK_6 output,PE[15], TEMP CS,	AF3 	
+		SIU.PCR[107].R = 0x0E04;        	// Config pad as DSPI_6 CS0 output,  PG[11], TEMP SCLK,	AF3 
+	}
+	else return -1;
+	
+	return 0;
+}
+
+
+
+/*
+int8_t DSPI_check_and_read(DSPI_config_t *const p_Config, uint32_t *data) {
+	volatile struct DSPI_tag *p_DSPI;
+	p_DSPI = p_Config->p_Modul;
+	
+	p_DSPI->SR.B.RFDF=1;	//clear
+	if (p_DSPI->SR.B.RFDF==1) {  // Wait for Receive FIFO Drain Flag = 1 
+		*data = p_DSPI->POPR.R;   // Read data received by master SPI 
+		p_DSPI->SR.R = 0x90020000;    //     Clear TCF, RDRF, EOQ flags by writing 1
+		return 1;	//Nachricht empfangen
+	}
+	else return 0; //keine Nachricht
+}
+*/
+
+
+
+int8_t DSPI_push(DSPI_config_t *const p_Config, uint16_t data, uint8_t isEOQ)
+{
+	volatile struct DSPI_tag *p_DSPI;
+	uint32_t push_tmp = 0;
+	
+	p_DSPI = p_Config->p_Modul;
+	
+	p_DSPI->SR.B.TFFF = 1;	//TFFF zurücksetzen
+	if ( ! p_DSPI->SR.B.TFFF ) return -1;	//Fifo voll?
+	
+	if (isEOQ) {	//Letztes Byte/Wort des Frames?
+		push_tmp |= 0x08000000;	//EOQ End Of Queue
+	}
+	else {
+	 	if (p_Config->CS_Cont==CS_Cont_ON)
+ 			push_tmp |= 0x80000000;
+	}
+	push_tmp |= (p_Config->Std_CS_Mask << 16); //ChipSelect
+	push_tmp |= data;
+	
+	p_DSPI->PUSHR.R = push_tmp;
+	
+	return 0;
+	
+	/*	DSPI_0.PUSHR.B.CONT		= 0;							// Cont. CS enable between TX (0: CS is switch into idle after TX)
+	DSPI_0.PUSHR.B.CTAS		= 0b000;							// No. of CTAR Reg. selected
+	DSPI_0.PUSHR.B.EOQ		= 0b1;								// End of Queue (1: Last Data to be TX)
+	DSPI_0.PUSHR.B.CTCNT	= 0b0;								// Clear TX Counter (0: do not clear counter)
+	DSPI_0.PUSHR.B.PE		= 0b0;								// Parity enable (0: no parity)
+	DSPI_0.PUSHR.B.PP		= 0b0;								// Parity Polarity (0: even)
+	// ::2
+	DSPI_0.PUSHR.B.PCS5		= 0b0;								// 1: Assert peripheral Chip select
+	DSPI_0.PUSHR.B.PCS4		= 0b0;								// 1: Assert peripheral Chip select
+	DSPI_0.PUSHR.B.PCS3		= 0b0;								// 1: Assert peripheral Chip select
+	DSPI_0.PUSHR.B.PCS2		= 0b0;								// 1: Assert peripheral Chip select
+	DSPI_0.PUSHR.B.PCS1		= 0b0;								// 1: Assert peripheral Chip select
+	DSPI_0.PUSHR.B.PCS0		= 0b1;								// 1: Assert peripheral Chip select
+	DSPI_0.PUSHR.B.TXDATA	= TxDataDAC;						// TX Data to be transmitted
+*/
+}
+
+
+
+int8_t DSPI_pop(DSPI_config_t *const p_Config, volatile uint16_t *const data)
+{
+	volatile struct DSPI_tag *p_DSPI;
+	p_DSPI = p_Config->p_Modul;
+	
+	p_DSPI->SR.B.RFDF=1;	//clear
+	if ( ! p_DSPI->SR.B.RFDF ) return -1;	//Fifo leer?
+	*data = (vuint16_t)(p_DSPI->POPR.R & 0xFFFF);
+	p_DSPI->SR.B.RFDF = 1;	//Drain-Flag zurücksetzen
+	return 0;
+}
+
+
+
+int8_t DSPI_init_Tx(DSPI_config_t *const p_Config)
+{
+	volatile struct DSPI_tag *p_DSPI;
+	p_DSPI = p_Config->p_Modul;
+	if ( p_DSPI->SR.B.TXCTR != 0 ) return -1;
+	p_DSPI->SR.B.EOQF = 1;	//EOQ-Flag löschen
+	p_DSPI->SR.B.TCF = 1;	//EOQ-Flag löschen
+	return 0;
+}
+
+
+
+int8_t DSPI_Clear_RxFifo(DSPI_config_t *const p_Config)
+{
+	volatile struct DSPI_tag *p_DSPI;
+	uint32_t dummy;
+	p_DSPI = p_Config->p_Modul;
+	while (p_DSPI->SR.B.RXCTR != 0) {
+		dummy = p_DSPI->POPR.R;
+	}
+	p_DSPI->SR.B.RFDF = 1;	//Drain-Flag zurücksetzen
+	/*
+	if (p_DSPI->SR.B.RXCTR != 0) {
+		p_DSPI->MCR.B.CLR_RXF = 1;
+		p_DSPI->SR.B.RFDF = 1;	//Drain-Flag zurücksetzen
+		return 1;	//Fifo gelöscht
+	}*/
+	
+	return 0; //keine Nachricht im Fifo
+}

+ 241 - 0
BMS Master/Sources/Device.c

@@ -0,0 +1,241 @@
+#include "BMS_Master.h"
+
+
+
+extern uint32_t __IVPR_VALUE; /* Interrupt Vector Prefix value from link file*/
+extern uint32_t IntcIsrVectorTable[];
+
+
+#define CHIPVERSION	F1
+
+
+
+void init_Device()
+{
+	//--INIT-----------------------------------------------
+	// (1) Disable Watchdog --------------------------
+	disableWatchdog(); /* Disable watchdog */
+	// -----------------------------------------------
+
+	INTC_InstallINTCInterruptHandler(&ISR_Timer_OS,59,10);	//irq(PIT0) = 59
+	INTC_InitINTCInterrupts();
+	Asm_initIrqVectors();
+    INTC.PSR[4].R = 2;		          /* Software interrupt 4 IRQ priority = 2 */
+	INTC.CPR_PRC0.B.PRI = 1;          /* Single Core: Lower INTC's current priority */
+		
+	/* (2) - Configure modes and activate all clock for all peripherals      */ 
+	initMODE();
+
+	/* (3) - Configure system clock dividers for 120Mhz Fsys                 */
+	CGM.Z0_DCR.B.DIV = 0x1;       /* Z0 clock divider to divide by 2        */
+	CGM.FLASH_DCR.B.DIV = 0x1;    /* Flash register interface /2 (default)  */
+	ECSM.MUDCR.B.RAM_WS=0x1;      /* RAM Wait states to divide by 2         */
+
+	/* (4) - Set system clock to 120MHz based on 40Mhz XTAL                  */
+	setPLL();                     /* Also enables CLKOUT On PA[0]           */     
+
+	initINTC();
+}
+
+
+
+/* ----------------------------- */
+/* Initialize Modes              */
+/* ----------------------------- */
+void initMODE()
+{            
+    ME.MER.R = 0x000025FF;          /* Enable all modes                     */
+    ME.RUNPC[0].R = 0x000000FE; 	/* Enable all peripherals in all modes  */
+    
+   /* Enable system clock for all peripherals assuming 120MHz system clock  */
+    CGM.SC_DC0.R = 0x83;          	/* Max 32MHz. Closest is 30MHz, Div+1=4 */
+    CGM.SC_DC1.R = 0x81;          	/* Max 64MHz. Closest is 60MHz, Div+1=2 */
+    CGM.SC_DC2.R = 0x81;          	/* Max 64MHz. Closest is 60MHz, Div+1=2 */
+
+    /* Re-enter DRUN mode to update the clock configuration                 */
+    ME.MCTL.R = 0x30005AF0;         /* DRUN Mode & Key                      */
+    ME.MCTL.R = 0x3000A50F;         /* DRUN Mode & Key                      */
+    while (ME.IS.B.I_MTC != 1) {}   /* Wait Until transition completed      */
+    ME.IS.B.I_MTC = 1;              /* Clear flag                           */   
+   
+    //CAN 
+    ME.RUNPC[1].R = 0x00000018; 	/* Peri. Cfg. 1 settings: only run in DRUN & RUN0 mode */
+    ME.PCTL[16].R = 0x01;           /* MPC56xxB/P/S FlexCAN0:select ME.RUNPC[1] */	
+//  ME.PCTL[17].R = 0x01;           /* MPC56xxB/S FlexCAN1:  select ME.RUNPC[1] */	
+    ME.PCTL[68].R = 0x01;           /* MPC56xxB/S SIUL:      select ME.RUNPC[1] */	
+    ME.PCTL[91].R = 0x01;           /* MPC56xxB/S RTC/API:   select ME.RUNPC[1] */	
+    ME.PCTL[92].R = 0x01;           /* MPC56xxB/S PIT_RTI:   select ME.RUNPC[1] */	
+    ME.PCTL[4].R = 0x01;           	/* MPC56xxB/S DSPI0:     select ME.RUNPC[1] */	
+    ME.PCTL[5].R = 0x01;           	/* MPC56xxB/S DSPI1:     select ME.RUNPC[1] */	
+    ME.PCTL[48].R = 0x01;           /* MPC56xxB/S LINFLEX0:  select ME.RUNPC[1] */	
+    ME.PCTL[49].R = 0x01;           /* MPC56xxB/S LINFLEX1:  select ME.RUNPC[1] */	
+}
+
+
+
+void init_Mode_and_Clock()
+{
+	//--PLL--
+	//Nur einstellen, wenn PLL nicht Sysclk
+	//F_vco = F_xtal * NDIV/(IDIF+1) = 256...512
+	//F_PLL_outclk = F_vco / 2^(ODIF+1)
+	CGM.FMPLL_CR.B.IDF= 3; /* Divide by 4 */
+	CGM.FMPLL_CR.B.ODF= 1; /* Divide by 4 */
+	CGM.FMPLL_CR.B.NDIV=48; /* Multiply 48 */
+	
+	/* Switch on external osc in DRUN mode */
+	ME.DRUN.B.FXOSC0ON=1;
+	//Set PLL to Soure in DRUN
+	ME.DRUN.B.SYSCLK=4;
+	
+	ME.MCTL.R = 0x30005AF0; /* Mode & Key */
+	ME.MCTL.R = 0x3000A50F; /* Mode & Key inverted */
+	while(ME.GS.B.S_MTRANS == 1) {} /* Wait for mode transition complete */
+	/* Error trap - if current mode is not DRUM (eg safe mode), then loop */
+	while(ME.GS.B.S_CURRENTMODE != 3) {}
+
+	/* Wait for external OSC to stabilize */
+	while(ME.GS.B.S_FXOSC != 1) {}
+
+	// wait for PLL to lock
+	while(CGM.FMPLL_CR.B.S_LOCK==0) {}
+	
+	/* Enable CLKOUT pin so clock frequency can be verified */
+	CGM.OC_EN.B.EN=1; 		/* Enable Output clock */
+	CGM.OCDS_SC.R =0x23; 	/* And seclect output as system clock / 4 */
+	SIU.PCR[0].R = 0x0A04; 	/* PA0 ALT2 function (Clkout), MAX SRC */
+}
+
+
+
+/* ----------------------------- */
+/* PLL to 120Mhz (40Mhz xtal) */
+/* ----------------------------- */
+void setPLL()
+{
+	/* Note - in example code below the flow is: */
+	/* Switch on osc, change mode and wait for osc ON */
+	/* Configure and enable PLL, change mode and wait for PLL to lock */
+	/* Set clock source as PLL, change mode and check clock is PLL */
+	/* */
+
+	/* However, do not actually have to do all 3 mode changes. Can */
+	/* switch on osc, enable PLL and Set PLL as clock source THEN do a */
+	/* single mode change. The ME module must be smart enough to look */
+	/* at which bits are set and see if it's a valid combination of */
+	/* bits. However, if there is an issue, there is no way of seeing */
+	/* what caused the problem! */
+#ifdef EVALBOARD
+	/* Switch on external osc in DRUN mode */
+	ME.DRUN.B.FXOSC0ON=1;
+#else
+	//MasterBoard
+	CGM.FXOSC_CTL.B.OSCBYP=1;
+	ME.DRUN.B.FXOSC0ON=1;
+#endif
+	/* Re-Enter DRUN mode (mode=0x3) to activate change */
+	ME.MCTL.R = 0x30005AF0; /* Mode & Key */
+	ME.MCTL.R = 0x3000A50F; /* Mode & Key inverted */
+	while(ME.GS.B.S_MTRANS == 1) {} /* Wait for mode transition complete */
+
+	/* Error trap - if current mode is not DRUM (eg in safe mode), then loop */
+	while(ME.GS.B.S_CURRENTMODE != 3) {}
+
+	/* Wait for external OSC to stabilize */
+	while(ME.GS.B.S_FXOSC != 1) {}
+
+	/* Select External OSC as the FMPLL Reference Clock Source */
+#if CHIPVERSION == F1
+	CGM.AC0_SC.B.SELCTL = 0x0;
+#elif CHIPVERSION == F0
+	CGM.AC0_SC.B.SELCTL = 0x1;
+#else
+	#error Device.c: Keine gültige Cipversion ausgewählt
+#endif
+
+	/* Configure PLL for 120MHz with 40MHz xtal */
+	/* PLL frequency = (40 * NDIV) / (IDF * ODF) */
+	/* VCO (PLL * ODF) must be between 256 and 512MHz */
+	/* */
+	/* For 120Mhz Output: */
+
+	/* ODF deliviers are 2, 4, 8, 16. /4 gives VCO of 480 (in range) */
+	/* With ODF = 2, NDIV = 12xIDF. Chose IDF =5, therefore NDIV = 60 */
+	CGM.FMPLL_CR.B.IDF=0x4; /* Divide by 5 */
+	CGM.FMPLL_CR.B.ODF=0x1; /* Divide by 4 */
+	CGM.FMPLL_CR.B.NDIV=60; /* Divide by 60 */
+	/* Enable PLL in DRUN mode. */
+	ME.DRUN.B.FMPLLON = 1;
+
+	/* Re-Enter DRUN mode (mode=0x3) to activate change */
+	ME.MCTL.R = 0x30005AF0; /* Mode & Key */
+	ME.MCTL.R = 0x3000A50F; /* Mode & Key inverted */
+
+	while(ME.GS.B.S_MTRANS == 1) {} /* Wait for mode transition complete */
+	/* Error trap - if current mode is not DRUM (eg safe mode), then loop */
+	while(ME.GS.B.S_CURRENTMODE != 3) {}
+	/* wait for PLL to lock (will not lock until re-enter DRUN mode */
+	while(CGM.FMPLL_CR.B.S_LOCK==0) {}
+	/* Finally set system clock to be PLL in DRUN mode */
+	ME.DRUN.B.SYSCLK=0x4;
+
+	/* Re-Enter DRUN mode (mode=0x3) to activate change */
+	// Application Code
+	// Getting started with the MPC564xB/C Microcontroller, Rev. 0, 12/2010
+	// 20 Freescale Semiconductor, Inc.
+	ME.MCTL.R = 0x30005AF0; /* Mode & Key */
+	ME.MCTL.R = 0x3000A50F; /* Mode & Key inverted */
+	while(ME.GS.B.S_MTRANS == 1) {} /* Wait for mode transition complete */
+
+	/* Error trap - if current mode is not DRUM (eg safe mode), then loop */
+	while(ME.GS.B.S_CURRENTMODE != 3) {}
+
+	/* Final check - ensure ME_GS reports clock as system PLL (0x4) */
+	while(ME.GS.B.S_SYSCLK != 4) {} /* fail if stuck here */
+
+	/* Enable CLKOUT pin so clock frequency can be verified */
+	CGM.OC_EN.B.EN=1; 		/* Enable Output clock */
+	CGM.OCDS_SC.R =0x23; 	/* And seclect output as system clock / 4 */
+	SIU.PCR[0].R = 0x0A04; 	/* PA0 ALT2 function (Clkout), MAX SRC */
+}
+
+
+
+void disableWatchdog()
+{
+  SWT.SR.R = 0x0000c520;     /* Write keys to clear soft lock bit */
+  SWT.SR.R = 0x0000d928; 
+  SWT.CR.R = 0x8000010A;     /* Clear watchdog enable (WEN) */
+}        
+
+
+
+void initINTC()
+{	
+  INTC.MCR.B.HVEN_PRC0 = 1;       /* 0 -> SW vector mode */
+  INTC.MCR.B.VTES_PRC0 = 0;       /* Single core: Use default vector table 4B offsets */
+  INTC.IACKR_PRC0.R = 2;    /* MPC555x: INTC ISR table base */
+  INTC.PSR[59].R = 4;           /* PIT 0 interrupt vector with priority 1 */
+  INTC.PSR[0].R = 3;		/* Software interrupt 0 IRQ priority = 2 */
+  INTC.PSR[1].R = 2;		/* Software interrupt 1 IRQ priority = 2 */
+  INTC.PSR[2].R = 1;		/* Software interrupt 2 IRQ priority = 2 */
+}
+
+
+
+void enableIrq()
+{
+  INTC.CPR_PRC0.B.PRI = 0;          /* Single Core: Lower INTC's current priority */
+  asm(" wrteei 1");	    	   /* Enable external interrupts */
+}
+
+
+
+void Asm_initIrqVectors( void )
+{
+  asm(" lis r3, __IVPR_VALUE@h");   /* IVPR value is passed from link file */
+  asm(" ori r3, r3, __IVPR_VALUE@l"); 
+  asm(" mtivpr  r3");
+  asm(" li r3, 0x40");  
+  asm(" mtivor4 r3");  							 
+}

+ 489 - 0
BMS Master/Sources/FRAM.c

@@ -0,0 +1,489 @@
+// ----------------------------------------------------------------------------
+// FRAM.c - 
+// ----------------------------------------------------------------------------
+// Beschreibung:	FRAM mit SPI-IF
+//
+// Revision:		02. Juli 2012, neu	Maurer, IPE
+//					19. Juli 2012, +Polling-Betrieb der FSM
+// ----------------------------------------------------------------------------
+
+#include "BMS_Master.h"
+
+
+
+FramStatus_t Fram_S;
+
+
+static const FramStatus_t Fram_S_INIT = {Fram_Idle,NoTask,0,0,(uint8_t*)0,0,0,0};
+
+
+
+static int8_t FRAM_FSM_update(uint8_t tick);
+static int8_t FRAM_get_SuccessState();
+
+
+DSPI_config_t FRAM_SPI_conf = {
+	&DSPI_0,
+	DSPI_Master,
+	8,	//FrameSize
+	DSPI_ClassicFormat,
+	DSPI_Baud2MHz,
+	2,	//uint8_t CStoSCK_Delay_Cycles;	//nur MasterMode;
+	2,	//uint8_t AfterSCK_Delay_Cycles;	//nur MasterMode;
+	0,	//uint8_t DelayAfterTransfer_Cycles;	//nur MasterMode;
+	1,
+	CS_Cont_ON,	//enum{CS_Cont_ON, CS_Cont_OFF};
+	DSPI0_PortA12
+} ;
+
+
+//==================================================================================================
+//API
+
+
+
+
+
+int8_t FRAM_init(void)
+{
+	int8_t ret;
+	ret = DSPI_init(&FRAM_SPI_conf);
+	
+//	SIU.PCR[153].R	= 0x0302;	// FRAM_WP;act Low		PJ[9] Output enable, input enable, Weak PU/PD enable, Weak PD selected
+//	SIU.PCR[154].R	= 0x0303;	// FRAM_HOLD;act. Low	PJ[10] Output enable, input enable, Weak PU/PD enable, Weak PU selected
+	SIU.PCR[153].B.OBE = 1;	// FRAM_WP;act Low		PJ[9] Output enable,
+	SIU.PCR[154].B.OBE = 1;	// FRAM_HOLD;act. Low	PJ[10] Output enable
+	
+	SET_OUTPIN(153);		// set PJ[9],	/WP = 1 (switch off HW Write Protection of FRAM)
+	SET_OUTPIN(154);		// set PJ[10],	/hold = 1 (do not hold the FRAM)
+	
+	Fram_S = Fram_S_INIT;
+	return ret;
+}
+
+
+
+int8_t FRAM_update(uint8_t tick)
+{ 
+	return FRAM_FSM_update(tick);
+}
+
+
+
+int8_t FRAM_trigger_write(const vuint16_t Addr, vuint8_t *const data, const vuint8_t num_data)
+{
+	if (num_data < 1) return -1;
+	if (Fram_S.FsmState != Fram_Idle) return -2;
+//	if (Fram_S.FramTest_state != 0) return -3;
+	
+	Fram_S.TaskTrigger = RamWrite;
+	Fram_S.Addr = Addr;
+	Fram_S.datastart = data;
+	Fram_S.num_data = num_data;
+		
+	return 0;
+}
+
+
+
+int8_t FRAM_trigger_read(const vuint16_t Addr, vuint8_t *const data, vuint8_t num_data)
+{
+	if (num_data < 1) return -1;
+	if (Fram_S.FsmState != Fram_Idle) return -2;
+//	if (Fram_S.FramTest_state != 0) return -3;
+
+	Fram_S.TaskTrigger = RamRead;
+	Fram_S.Addr = Addr;
+	Fram_S.datastart = data;
+	Fram_S.num_data = num_data;
+		
+	return 0;
+}
+
+
+
+int8_t FRAM_trigger_Test()
+{
+	if (Fram_S.FsmState != Fram_Idle) return -1;
+	Fram_S.TaskTrigger = RamTest;	
+	return 0;
+}
+
+
+
+int8_t FRAM_Test_update()
+{
+	#define NUM_DATA	10
+	#define DATA_1		0xCC
+	#define DATA_2		0x33
+	static vuint8_t data[NUM_DATA];
+	uint8_t i = 0;
+		
+	switch (Fram_S.FramTest_state)	{
+		case 0:
+			if (Fram_S.TaskTrigger == RamTest) {
+				Fram_S.TaskTrigger = NoTask;
+				for (i=0;i<NUM_DATA;i++) data[i] = DATA_1;
+				if (FRAM_trigger_write(0, &data[0], NUM_DATA) < 0) return -1;
+				Fram_S.FramTest_state = 1;
+			}
+			break;
+		case 1:
+			if (FRAM_get_SuccessState() < 0) {
+				Fram_S.FramTest_state = 0;
+				return -2;
+			}
+			if (FRAM_get_SuccessState() > 0) {
+				Fram_S.FramTest_state = 0;
+				for (i=0;i<NUM_DATA;i++) data[i] = 0;
+				if (FRAM_trigger_read(0, data, NUM_DATA) < 0) return -3;
+				Fram_S.FramTest_state = 2;
+			}
+			break;
+		case 2:
+			if (FRAM_get_SuccessState() < 0) {
+				Fram_S.FramTest_state = 0;
+				return -4;
+			}
+			if (FRAM_get_SuccessState() > 0) {
+				Fram_S.FramTest_state = 0;
+				for (i=0;i<NUM_DATA;i++) if ( data[i] != DATA_1 ) return -5;
+				for (i=0;i<NUM_DATA;i++) data[i] = DATA_2;
+				if (FRAM_trigger_write(0, &data[0], NUM_DATA) < 0) return -6;
+				Fram_S.FramTest_state = 3;
+			}
+			break;
+		case 3:
+			if (FRAM_get_SuccessState() < 0) {
+				Fram_S.FramTest_state = 0;
+				return -7;
+			}
+			if (FRAM_get_SuccessState() > 0) {
+				for (i=0;i<NUM_DATA;i++) data[i] = 0;
+				FRAM_trigger_read(0, &data[0], NUM_DATA);
+				Fram_S.FramTest_state += 1;
+			}
+			break;
+		case 4:
+			if (FRAM_get_SuccessState() < 0) {
+				Fram_S.FramTest_state = 0;
+				return -8;
+			}
+			if (FRAM_get_SuccessState() > 0) {
+				Fram_S.FramTest_state = 0;
+				for (i=0;i<NUM_DATA;i++) if (data[i] != DATA_2) return -9;
+				return 1;	//Test erfolgreich
+			}
+			break;
+	}
+	return 0;
+	#undef NUM_DATA
+	#undef DATA_1
+	#undef DATA_2
+}
+
+
+
+//==================================================================================
+static int8_t FRAM_push(uint16_t data, uint8_t isEOQ)
+{
+	return DSPI_push(&FRAM_SPI_conf, data, isEOQ);
+}
+
+
+
+static int8_t FRAM_pop(vuint16_t *dataptr)
+{
+	return DSPI_pop(&FRAM_SPI_conf, dataptr);
+}
+
+
+
+//-----------------------------------------------------------------------
+typedef enum {noEOQ=0, withEOQ} EOQbool_t;
+
+typedef struct {
+	vuint8_t *datastart;
+	uint16_t i_data;
+	uint16_t i_read;
+	uint16_t i_dummy;
+	uint16_t num_data;
+	EOQbool_t EOQbool;
+	uint8_t busy;
+} Seqnce_Status_t;
+
+
+
+static volatile Seqnce_Status_t Seqnce_S;
+
+
+
+static int8_t FRAM_Seqnce_init(){
+	Seqnce_S.datastart = 0;
+	Seqnce_S.num_data = 0;
+	Seqnce_S.i_data = 0;
+	Seqnce_S.i_read = 0;
+	Seqnce_S.i_dummy = 0;
+	Seqnce_S.EOQbool = noEOQ;
+	Seqnce_S.busy = 0;
+	return 0;
+}
+
+
+
+static int8_t FRAM_Seqnce_try_load(vuint8_t *data, uint16_t num_data, EOQbool_t EOQbool)
+{
+	if (Seqnce_S.busy) return -1;
+	Seqnce_S.datastart = data;
+	Seqnce_S.num_data = num_data;
+	Seqnce_S.i_data = 0;
+	Seqnce_S.i_read = 0;
+	Seqnce_S.EOQbool = EOQbool;
+	Seqnce_S.busy = 1;
+	return 0;
+}
+
+
+
+static int8_t FRAM_get_SuccessState()
+{
+	if (Fram_S.TaskTrigger == NoTask) {
+		if (Fram_S.Flags.B.FSM_TO) return -1;
+		if (Fram_S.Flags.B.JobFinished) return 1;
+	}
+	return 0;
+}
+
+
+
+static int8_t FRAM_Seqnce_try_push()
+{
+	uint16_t cnt_sent = 0;
+	uint8_t  isEOQ    = 0;
+	
+	while (Seqnce_S.i_data < Seqnce_S.num_data)    // transmit still running
+	{
+		if ( Seqnce_S.i_data == (Seqnce_S.num_data-1) && Seqnce_S.EOQbool==withEOQ ) // last Byte transmit
+		{
+			isEOQ = 1;
+		}
+		
+		if ( FRAM_push((uint16_t)(Seqnce_S.datastart[Seqnce_S.i_data]) & 0xFF, isEOQ) < 0 ) 
+		{
+			if ( cnt_sent==0 ) 
+				return -1; //nothing sent
+			else 
+				return 0;	//sent but not finished
+		}
+		else 
+		{
+			cnt_sent++;
+			Seqnce_S.i_data++;
+		}
+	}
+	//end of data
+	Seqnce_S.busy = 0;
+	return 1;	//1 = finished
+}
+
+
+
+static int8_t FRAM_Seqnce_load_forDummies(vuint8_t *datastart,uint16_t num_data)
+{
+//	if (Seqnce_S.busy) return -1;
+	Seqnce_S.datastart = datastart;
+	Seqnce_S.num_data = num_data;
+	Seqnce_S.i_data = 0;
+	Seqnce_S.i_read = 0;
+	Seqnce_S.i_dummy = 0;
+	Seqnce_S.busy = 1;
+	return 0;
+}
+
+
+
+static int8_t FRAM_Seqnce_try_pushDummies()
+{
+	uint16_t cnt_sent = 0;
+	uint8_t  isEOQ    = 0;
+	
+	while (Seqnce_S.i_data < Seqnce_S.num_data)   // while transmit still running
+	{
+	    if ( Seqnce_S.i_data == (Seqnce_S.num_data-1) ) // last Byte transmit?
+	    {
+			isEOQ = 1;
+		}
+		
+	    if ( FRAM_push(Seqnce_S.i_data, isEOQ) < 0 ) 
+		{
+			return 0;	//sent but not finished
+		}
+		else 
+		{
+			Seqnce_S.i_data++;
+			cnt_sent++;
+			if (cnt_sent>=4) 
+				return 0; //nothing sent
+		}
+	}
+	Seqnce_S.busy = 0;
+	return 1;	//1 = finished
+}	
+
+
+
+static int8_t FRAM_Seqnce_try_pop()
+{
+	vuint16_t data_tmp = 0;
+	
+	while (Seqnce_S.i_dummy < Fram_S.n_RxDummies) 
+	{
+		if ( FRAM_pop(&data_tmp) < 0 ) 
+			return 0;    // Error: Fifo empty
+		else 
+			Seqnce_S.i_dummy++;
+	}
+	
+	data_tmp = 4;
+	while (Seqnce_S.i_read < Seqnce_S.num_data) 
+	{
+		if ( FRAM_pop(&data_tmp) < 0 )
+			return 0;           // Error: Fifo empty
+		else 
+		{
+			Seqnce_S.datastart[Seqnce_S.i_read] = (vuint8_t)(data_tmp&0xFF);
+			Seqnce_S.i_read++;
+		}
+	}
+	//end of data
+	return 1;	//1 = finished
+}
+
+
+
+//-----------------------------------------------------------------------
+static int8_t FRAM_checkTimeOut(uint16_t Cnt, uint16_t TO_Value)
+{	
+	if (Cnt >= TO_Value) {
+		FRAM_init();
+		Fram_S.Flags.B.FSM_TO = 1;
+		return -1;
+	}
+	return 0;
+}
+
+
+
+//FRAM FSM
+static int8_t FRAM_FSM_update(uint8_t tick)
+{
+	#define FSM_TIMEOUT	6
+	static uint8_t OPCSeq[3];
+	static uint16_t StateTimeoutCnt = 0;
+	
+	if (tick == 1) StateTimeoutCnt += 1;
+	switch (Fram_S.FsmState)	{
+		case Fram_Idle:
+			if (Fram_S.TaskTrigger == RamWrite) {
+				//PushOPCs
+				//if (Fram_S.num_data == 0) return -1;
+				FRAM_SPI_conf.CS_Cont = CS_Cont_OFF;	//Select geht nach dem Byte aus
+				//Write_Enable vor jedem Schreiben auf Speicher
+				FRAM_push(WREN_OPC,0);
+				//Write-Befehl
+				FRAM_SPI_conf.CS_Cont = CS_Cont_ON;	//CS bleibt zw. den Bytes aktiv
+				OPCSeq[0] = WRITE_OPC;
+					//2Byte Adresse (= Adr. des 1.Databytes) 0..7FFFh
+				OPCSeq[1] = (uint8_t)(Fram_S.Addr>>8) & 0x7F;
+				OPCSeq[2] = (uint8_t)Fram_S.Addr & 0xFF;
+				if (FRAM_Seqnce_try_load(OPCSeq,3,noEOQ) >= 0 ) {
+					Fram_S.Flags.R = 0;
+					StateTimeoutCnt = 0;
+					Fram_S.FsmState = Fram_Write_1;
+					Fram_S.TaskTrigger = NoTask;
+				}
+			}
+			else if (Fram_S.TaskTrigger == RamRead) {
+				if (Fram_S.num_data == 0) break;
+				FRAM_SPI_conf.CS_Cont = CS_Cont_ON;
+				OPCSeq[0] = READ_OPC;
+					//2Byte Adresse (= Adr. des 1.Databytes) 0..7FFFh
+				OPCSeq[1] = (uint8_t)(Fram_S.Addr>>8) & 0x7F;
+				OPCSeq[2] = (uint8_t)Fram_S.Addr & 0xFF;
+				DSPI_Clear_RxFifo(&FRAM_SPI_conf);
+				if (FRAM_Seqnce_try_load(OPCSeq,3,noEOQ) >= 0 ) {
+					DSPI_Clear_RxFifo(&FRAM_SPI_conf);
+					StateTimeoutCnt = 0;
+					Fram_S.Flags.R = 0;
+					Fram_S.n_RxDummies = 3;
+					Fram_S.FsmState = Fram_Read_1;
+					Fram_S.TaskTrigger = NoTask;
+				}
+			}
+			break;
+		//auf den Ram Schreiben
+		case Fram_Write_1:
+			if (FRAM_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) return -1;
+			if (FRAM_Seqnce_try_push() == 1 ) {	//finished
+				FRAM_Seqnce_try_load(Fram_S.datastart,Fram_S.num_data,withEOQ);
+				StateTimeoutCnt = 0;
+				Fram_S.FsmState = Fram_Write_2;
+			}
+			break;
+		case Fram_Write_2:
+			if (FRAM_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) return -2;
+			if (FRAM_Seqnce_try_push() == 1 ) {	//finished
+				StateTimeoutCnt = 0;
+				Fram_S.FsmState = Fram_Write_3;
+			}
+			break;
+		case Fram_Write_3:
+		{
+			volatile struct DSPI_tag *p_DSPI = FRAM_SPI_conf.p_Modul;
+			if (FRAM_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) return -3;
+			if (p_DSPI->SR.B.EOQF == 1) {
+				p_DSPI->SR.B.EOQF = 1;
+				Fram_S.Flags.B.JobFinished = 1;
+				StateTimeoutCnt = 0;
+				Fram_S.FsmState = Fram_Idle;
+			}
+			break;
+		}
+		//vom Ram lesen
+		case Fram_Read_1:
+			if (FRAM_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) return -4;
+			if (FRAM_Seqnce_try_push() == 1 ) {	//finished?
+				FRAM_Seqnce_load_forDummies(Fram_S.datastart,Fram_S.num_data);
+				StateTimeoutCnt = 0;
+				Fram_S.FsmState = Fram_Read_2;
+			}
+			break;
+		case Fram_Read_2:
+			if (FRAM_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) return -6;
+			FRAM_Seqnce_try_pop();
+			if (FRAM_Seqnce_try_pushDummies() == 1 ) {	//finished
+				StateTimeoutCnt = 0;
+				Fram_S.FsmState = Fram_Read_3;
+			}
+			break;
+
+		case Fram_Read_3:
+		{
+			volatile struct DSPI_tag *p_DSPI = FRAM_SPI_conf.p_Modul;
+			if (FRAM_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) {
+//				while (1) {}
+				return -6;
+			}
+			if (FRAM_Seqnce_try_pop()==1 ) {// && p_DSPI->SR.B.EOQF == 1) {
+				p_DSPI->SR.B.EOQF = 1;
+				StateTimeoutCnt = 0;
+				Fram_S.Flags.B.JobFinished = 1;
+				Fram_S.FsmState = Fram_Idle;
+			}
+			break;
+		}
+			
+	}
+	return 0;
+	#undef FSM_TIMEOUT
+}

+ 356 - 0
BMS Master/Sources/FlexCAN.c

@@ -0,0 +1,356 @@
+//==============================================================================
+// Purpose:    allgemeines CAN Interface für FlexCAN von MPC5646
+//
+// Created on:  20.04.2012 by IPE
+//
+// History
+//		20.04.2012 neu, T.Maurer
+//		29.07.2013 CAN_Init() modified V.Reiling
+//      26.02.2016 CAN_Init() modified V.Reiling: Sample Point at 87.5%
+//==============================================================================
+
+#include "BMS_Master.h"
+
+
+//CAN - MESSAGEBOX-STATUS-CODES
+#define CAN_MBCODE_RXINACTIVE		0
+#define CAN_MBCODE_RXEMPTY			4
+#define CAN_MBCODE_RXFULL			2
+#define CAN_MBCODE_RXOVERRUN		6	//	MB war voll und wurde nicht von CPU ausgelesen
+#define CAN_MBCODE_RXBUSY			1	//	(XXX1)
+
+#define CAN_MBCODE_TXINACTIVE		8	//Grundzustand
+#define CAN_MBCODE_TXABORT			9	//ABORT muss mit MCR.AEN freigegeben werden
+#define CAN_MBCODE_TXSEND			12	//RTR=0 -> sende Data, wenn beendet: Rückkehr zu INACTIVE;
+										//RTR=1 -> sende RemoteFrame, Wenn fertig: neuer Zustand = CAN_MBCODE_RXEMPTY
+#define CAN_MBCODE_TXREMOTEWAIT		10	//warte auf Remote request und sende Data zurück (-> CAN_MBCODE_TXREMOTESEND)
+#define CAN_MBCODE_TXREMOTESEND		16	//sende Data nach Remote request, wenn beendet: Rückkehr zu CAN_MBCODE_TXREMOTEWAIT;
+
+
+//Abort Enable des Boards verwenden?
+#define CAN_AEN 	0
+
+
+//Funktionen
+int8_t CAN_Init(CAN_CONFIG *config)
+{
+	volatile struct FLEXCAN_tag *p_CAN = config->CAN_Modul; 
+	uint8_t	i;
+	
+																// Fehler-Check: CAN-Modul-Adresse vorhanden?
+	if ((p_CAN != &CAN_0) && 
+		(p_CAN != &CAN_1) && 
+		(p_CAN != &CAN_2) &&
+		(p_CAN != &CAN_3) && 
+		(p_CAN != &CAN_4) && 
+		(p_CAN != &CAN_5) )
+		return CAN_ERROR;
+																// MCR-Register, die meisten Bits koennen nur im FreezeMode beschrieben werden
+	p_CAN->MCR.B.MDIS = 0;										// Module Disable (init=1)
+	while (p_CAN->MCR.B.LPMACK) {}
+	p_CAN->MCR.B.FRZ = 1; 										// FreezeMode enable (initVal=1)
+	p_CAN->MCR.B.HALT = 1; 										// FreezeMode ON (wenn FRZ=1);(initVal=1) Clear after module-init 
+	while (!p_CAN->MCR.B.FRZACK) {}								// warte auf FreezeMode
+	
+	p_CAN->MCR.B.BCC = 1; 										// 1 = Enable Indididual RxMasking
+	if (config->RxMaskType == RxMask_Global) 
+	{
+		p_CAN->MCR.B.BCC = 0; 									// 0 = Enable Global RxMasking
+		p_CAN->RXGMASK.R = config->GlobalRxMask;				// Global Acceptance Mask (InitVal = 0xFFFF_FFFF)
+	}
+		
+	p_CAN->MCR.B.AEN = CAN_AEN; 								// Abort Enable
+	p_CAN->MCR.B.SUPV = 0;										// Freeze mode only:
+															
+	switch( config->BaudConfig )
+	{
+		case CANBaud_1000kHz_OSC_40MHz :						// @ 40m Buslength
+			p_CAN->CR.B.CLKSRC 	= 0;							// CPI-ClockSource:  0=oscillator clock (40MHz); 1=bus clock (PLL/2=60MHz)   
+			p_CAN->CR.B.PRESDIV = 1;  							// f_SerialClock = f_CPI_clock / (PRESDIV + 1)
+			p_CAN->CR.B.PROPSEG = 7; 							// Propagation Segment Time = (PROPSEG + 1) * Time-Quanta.
+			p_CAN->CR.B.PSEG1 	= 7; 							// Phase Buffer Segment 1 = (PSEG1 + 1) x Time-Quanta.
+			p_CAN->CR.B.PSEG2 	= 2;							// Phase Buffer Segment 2 = (PSEG1 + 1) x Time-Quanta.
+			p_CAN->CR.B.RJW 	= 0;							// Resync Jump Width = RJW + 1.
+			break;
+	
+		case CANBaud_500kHz_OSC_40MHz :							// @ 100m Buslength
+			p_CAN->CR.B.CLKSRC 	= 0;							// CPI-ClockSource:  0=oscillator clock (40MHz); 1=bus clock (PLL/2=60MHz)   
+			p_CAN->CR.B.PRESDIV = 4;  							// f_SerialClock = f_CPI_clock / (PRESDIV + 1)
+			p_CAN->CR.B.PROPSEG = 4; 							// Propagation Segment Time = (PROPSEG + 1) * Time-Quanta.
+			p_CAN->CR.B.PSEG1 	= 7; 							// Phase Buffer Segment 1 = (PSEG1 + 1) x Time-Quanta.
+			p_CAN->CR.B.PSEG2 	= 1;							// Phase Buffer Segment 2 = (PSEG1 + 1) x Time-Quanta.
+			p_CAN->CR.B.RJW 	= 0;							// Resync Jump Width = RJW + 1.
+			break;
+				
+		case CANBaud_250kHz_OSC_40MHz :							// @ 200m Buslength
+			p_CAN->CR.B.CLKSRC 	= 0;							// CPI-ClockSource:  0=oscillator clock (40MHz); 1=bus clock (PLL/2=60MHz)   
+			p_CAN->CR.B.PRESDIV = 9;  							// f_SerialClock = f_CPI_clock / (PRESDIV + 1)
+			p_CAN->CR.B.PROPSEG = 4; 							// Propagation Segment Time = (PROPSEG + 1) * Time-Quanta.
+			p_CAN->CR.B.PSEG1 	= 7; 							// Phase Buffer Segment 1 = (PSEG1 + 1) x Time-Quanta.
+			p_CAN->CR.B.PSEG2 	= 1;							// Phase Buffer Segment 2 = (PSEG1 + 1) x Time-Quanta.
+			p_CAN->CR.B.RJW 	= 0;							// Resync Jump Width = RJW + 1.
+			break;
+				
+		case CANBaud_125kHz_OSC_40MHz :							// @ 420m Buslength
+			p_CAN->CR.B.CLKSRC 	= 0;							// CPI-ClockSource:  0=oscillator clock (40MHz); 1=bus clock (PLL/2=60MHz)   
+			p_CAN->CR.B.PRESDIV = 19;  							// f_SerialClock = f_CPI_clock / (PRESDIV + 1)
+			p_CAN->CR.B.PROPSEG = 4; 							// Propagation Segment Time = (PROPSEG + 1) * Time-Quanta.
+			p_CAN->CR.B.PSEG1 	= 7; 							// Phase Buffer Segment 1 = (PSEG1 + 1) x Time-Quanta.
+			p_CAN->CR.B.PSEG2 	= 1;							// Phase Buffer Segment 2 = (PSEG1 + 1) x Time-Quanta.
+			p_CAN->CR.B.RJW 	= 0;							// Resync Jump Width = RJW + 1.
+			break;
+								
+		default :
+			return CAN_ERROR;
+	}
+	p_CAN->CR.B.SMP = 1;										// Sampling Mode: 0=1 Sample, 1=3 Samples
+
+	switch( config->Port )
+	{
+		case CAN0_PortB0_1 :									// Config Ports: PB0 = CAN0_Tx, PB1 = CAN0_Rx
+			SIU.PCR[16].B.OBE 	= 1;							// Output Buffer Enable = Output
+			SIU.PCR[16].B.PA 	= 1;							// Pad Output Assignment = CAN0TX
+			SIU.PCR[16].B.ODE 	= (config->TxPortType==Tx_OpenDrain)? 1:0; // Open Drain Output Enable
+			SIU.PCR[16].B.SRC 	= 1;							// Slew Rate Control = Fast
+			SIU.PCR[17].B.IBE 	= 1;							// Input Buffer Enable = Input
+			break;
+			
+		case CAN1_PortC10_11 :									// Config Ports: PC10 = CAN1_Tx, PC11 = CAN1_Rx
+			SIU.PCR[42].B.OBE 	= 1;							// Output Buffer Enable = Output
+			SIU.PCR[42].B.PA 	= 1;							// Pad Output Assignment = CAN1TX
+			SIU.PCR[42].B.ODE 	= (config->TxPortType==Tx_OpenDrain)? 1:0; // Open Drain Output Enable
+			SIU.PCR[42].B.SRC 	= 1;							// Slew Rate Control = Fast
+			SIU.PCR[43].B.IBE 	= 1;							// Input Buffer Enable = Input
+			SIU.PSMI[0].R 		= 0x01;							// Peripheral input pin selection: CAN1RX -> PCR[43]
+			break;
+			
+		case CAN2_PortE8_9 :									// Config Ports: PE8 = CAN2_Tx, PE9 = CAN2_Rx
+			SIU.PCR[72].B.OBE 	= 1;							// Output Buffer Enable = Output
+			SIU.PCR[72].B.PA 	= 1;							// Pad Output Assignment = CAN2TX
+			SIU.PCR[72].B.ODE 	= (config->TxPortType==Tx_OpenDrain)? 1:0; // Open Drain Output Enable
+			SIU.PCR[72].B.SRC 	= 1;							// Slew Rate Control = Fast
+			SIU.PCR[73].B.IBE 	= 1;							// Input Buffer Enable = Input
+			SIU.PSMI[1].R 		= 0x00;							// Peripheral input pin selection: CAN2RX -> PCR[73]
+			break;
+
+		case CAN3_PortF8_9 :									// Config Ports: PF8 = CAN3_Tx, PF9 = CAN3_Rx
+			SIU.PCR[88].B.OBE 	= 1;							// Output Buffer Enable = Output
+			SIU.PCR[88].B.PA 	= 1;							// Pad Output Assignment = CAN3TX
+			SIU.PCR[88].B.ODE 	= (config->TxPortType==Tx_OpenDrain)? 1:0; // Open Drain Output Enable
+			SIU.PCR[88].B.SRC 	= 1;							// Slew Rate Control = Fast
+			SIU.PCR[89].B.IBE 	= 1;							// Input Buffer Enable = Input
+			SIU.PSMI[2].R 		= 0x02;							// Peripheral input pin selection: CAN3RX -> PCR[89]
+			break;			
+		
+		default :
+			return CAN_ERROR;
+	}
+	
+	p_CAN->MCR.B.MAXMB 	= 55;									// Max 64 Massage Buffer	
+	for (i=0; i<64; i++)
+		p_CAN->BUF[i].CS.B.CODE = CAN_MBCODE_RXINACTIVE;   		// Inactivate all message buffers 
+		
+	p_CAN->MCR.B.HALT 	= 0; 									// FreezeModeON-Bit; Clear after module-init (init=1)
+	p_CAN->MCR.B.FRZ 	= 0; 									// FreezeMode
+
+	return CAN_OK;
+}
+
+
+
+int8_t CAN_Init_Mailbox(CAN_MAILBOX *mbox)
+{
+	volatile struct FLEXCAN_BUF_t *p_BUF;	//pointer auf einen Message Buffer
+	volatile struct FLEXCAN_tag *p_CAN = mbox->p_CAN_Config->CAN_Modul;
+	
+	if (mbox->MBNumber >= 64) return CAN_ERROR;
+	p_BUF = p_CAN->BUF + mbox->MBNumber;
+	if (p_CAN->MCR.B.LPMACK) return CAN_ERROR;	//CAN in DisableMode
+	p_CAN->MCR.B.FRZ = 1; // FreezeMode enable (initVal=1)
+	p_CAN->MCR.B.HALT = 1; // FreezeMode ON (wenn FRZ=1);(initVal=1) Clear after module-init 
+	while (!p_CAN->MCR.B.FRZACK) {}	//warte auf FreezeMode
+	
+	if (mbox->RemoteEn >= 2) return CAN_ERROR;
+	p_BUF->CS.B.RTR =  mbox->RemoteEn;           /* Data frame, not remote Tx request frame */
+	if (mbox->Direction == MB_Tx) {
+		//TX-Box
+		if (mbox->DataBytes >= 9) return CAN_ERROR;
+		p_BUF->CS.B.LENGTH = mbox->DataBytes; /* # bytes to transmit*/
+		p_BUF->CS.B.CODE = CAN_MBCODE_TXINACTIVE;
+	}
+	else if (mbox->Direction == MB_Rx) {
+		//RX-Box
+		p_BUF->CS.B.CODE = CAN_MBCODE_RXEMPTY;
+		//Individuelle Acceptance Mask
+		if (mbox->p_CAN_Config->RxMaskType == RxMask_Individual)
+			p_CAN->RXIMR[mbox->MBNumber].R = mbox->AcceptMask;
+		//MB-Interrupt-Enable
+	}
+	else return CAN_ERROR;
+		
+	if( mbox->IDE == SHORT_ID)
+	{
+		p_BUF->CS.B.IDE = 0;          	// Use standard ID length
+		p_BUF->ID.B.STD_ID = mbox->ID;
+	}
+	else
+	{
+		p_BUF->CS.B.IDE = 1;          	// Use extended ID length
+		p_BUF->ID.B.EXT_ID = (mbox->ID & 0x3FFFF);
+		p_BUF->ID.B.STD_ID = (mbox->ID >> 18);
+	}
+	
+	if (mbox->Interrupt) {
+		if (mbox->MBNumber <= 31)			
+			SETBIT(p_CAN->IMRL.R, mbox->MBNumber); // Interrupt Mask 1
+		else
+			SETBIT(p_CAN->IMRH.R, mbox->MBNumber - 32);	// Interrupt Mask 2
+	}
+
+
+	p_CAN->MCR.B.HALT = 0; // FreezeMode ON (wenn FRZ=1);(initVal=1) Clear after module-init 
+	p_CAN->MCR.B.FRZ = 0; //FreezeMode; 
+	//init Ende
+	return CAN_OK;
+}
+
+
+int8_t CAN_Write(CAN_MAILBOX *mbox, uint8_t *data)
+{
+	uint8_t i;
+	volatile struct FLEXCAN_BUF_t *p_BUF;
+	volatile struct FLEXCAN_tag *p_CAN = mbox->p_CAN_Config->CAN_Modul;
+	
+	if (p_CAN->MCR.B.NOTRDY) return CAN_ERROR;
+	p_BUF = p_CAN->BUF + mbox->MBNumber;
+	if (mbox->MBNumber >= 64) return CAN_ERROR;
+
+	p_BUF->CS.B.CODE = CAN_MBCODE_TXINACTIVE;
+	//I-Flag löschen, um die MB zu entsperren
+/*	if (mbox->MBNumber < 32)
+		p_CAN->IFRL.R = 1 << mbox->MBNumber;
+	else
+		p_CAN->IFRH.R = 1 << (mbox->MBNumber-32);  
+
+*/	p_BUF = p_CAN->BUF + mbox->MBNumber;	//pointer auf einen Message Buffer
+	
+	if( mbox->IDE == SHORT_ID)
+		p_BUF->ID.B.STD_ID = mbox->ID;
+	else
+		p_BUF->ID.B.EXT_ID = mbox->ID;
+
+	for (i=0; i<mbox->DataBytes; i++) {
+		p_BUF->DATA.B[i] = *(data+i);      /* Data to be transmitted */
+	}
+//	CAN_0.BUF[0].CS.B.SRR = 1;           /* Tx frame (not req'd for standard frame)*/
+	p_BUF->CS.B.CODE = CAN_MBCODE_TXSEND;         /* Activate msg. buf. to transmit data frame */ 
+	return CAN_OK;
+}
+
+int8_t CAN_Write_dataset(CAN_MAILBOX *mbox, uint8_t* data,uint32_t timestamp)
+{
+	uint8_t i;
+	int8_t CAN_status=CAN_OK;
+	uint8_t	 dataSetSize= mbox->DataBytes;
+	volatile struct FLEXCAN_BUF_t *p_BUF;
+	volatile struct FLEXCAN_tag *p_CAN = mbox->p_CAN_Config->CAN_Modul;
+	p_BUF = p_CAN->BUF + mbox->MBNumber;
+	while(p_BUF->CS.B.CODE !=CAN_MBCODE_TXINACTIVE) {
+		//wait
+		if(Global_1msCounter >= timestamp + CAN1_TX_TIMEOUT) {
+			return CAN_ERROR;
+		}
+	}
+	CAN_status=CAN_Write(mbox,data);
+	timestamp=Global_1msCounter;
+	if(CAN_status != CAN_OK) {
+		return CAN_ERROR;
+	}
+	
+	return CAN_OK;
+}
+
+
+
+
+int8_t CAN_Read(CAN_MAILBOX *mbox, uint8_t *data)
+{
+	uint8_t i;
+	int8_t returnval;
+	uint32_t dummy;
+	volatile struct FLEXCAN_BUF_t *p_BUF;	//pointer auf einen Message Buffer
+	volatile struct FLEXCAN_tag *p_CAN = mbox->p_CAN_Config->CAN_Modul;
+	returnval = CAN_OK;
+	
+	if (mbox->MBNumber >= 64) return CAN_ERROR;
+	p_BUF = p_CAN->BUF + mbox->MBNumber;
+	dummy = p_BUF->CS.B.CODE;	//Muss ausgelesen werden zum Lock des Puffers
+	if (p_BUF->CS.B.LENGTH > CAN_DATA_ARR_LEN) returnval = CAN_ERROR;
+	if (p_BUF->CS.B.LENGTH != mbox->DataBytes) returnval = CAN_ERROR;
+	
+	if( mbox->IDE == SHORT_ID)
+		mbox->ID = p_BUF->ID.B.STD_ID;		// copy received ID to MailBox
+	else
+		mbox->ID = p_BUF->ID.B.EXT_ID;		// copy received ID to MailBox
+	
+	for (i=0; i < p_BUF->CS.B.LENGTH; i++){
+		*(data+i) = p_BUF->DATA.B[i];
+	}
+	//Timer auslesen und I-Flag löschen, um die MB zu entsperren	
+	dummy = p_CAN->TIMER.R;
+	// Clear Int-Flag 
+	if (mbox->MBNumber < 32)
+		p_CAN->IFRL.R = 1 << mbox->MBNumber;
+	else
+		p_CAN->IFRH.R = 1 << (mbox->MBNumber-32);  
+
+	return returnval;
+}
+
+// Funktionen
+
+int8_t CAN_Abort(CAN_MAILBOX *mbox)
+{
+	volatile struct FLEXCAN_BUF_t *p_BUF;
+	volatile struct FLEXCAN_tag *p_CAN = mbox->p_CAN_Config->CAN_Modul;
+	
+	p_BUF = p_CAN->BUF + mbox->MBNumber;	//pointer auf einen Message Buffer
+	if (mbox->Direction == MB_Rx) return CAN_ERROR;
+	#if CAN_AEN == 1
+		p_BUF->CS.B.CODE = CAN_MBCODE_TXABORT;
+	#else
+		p_BUF->CS.B.CODE = CAN_MBCODE_TXINACTIVE;
+	#endif
+	return CAN_OK;
+}
+
+/**
+ * @function Check CAN Error State Register for Errors
+ * @param config	pointer to CAN Module
+ * @param	can_esr	 32 Bi vaiable for error state
+ * @return TRUE if CAN IS OK, FALSE IF Error occured
+ * 
+ */
+uint8_t CAN_Get_error_Register(CAN_CONFIG *config,uint32_t* can_esr) {
+	volatile struct FLEXCAN_tag *p_CAN = config->CAN_Modul; 
+	if(p_CAN->ESR.R == 0) {
+		return TRUE;
+	}
+	else {
+		*can_esr=p_CAN->ESR.R;
+		return FALSE;
+	}
+}
+
+/**
+ *@brief Check if CAN Errors occured
+ */
+int8_t CAN_Check_error_Register(CAN_CONFIG *config) {
+	volatile struct FLEXCAN_tag *p_CAN = config->CAN_Modul; 
+	if(p_CAN->ESR.R == 0) {
+		return CAN_OK;
+	}
+	else {
+		return CAN_ERROR;
+	}
+}

+ 98 - 0
BMS Master/Sources/IntcIsrVectors.c

@@ -0,0 +1,98 @@
+/* IntcIsrVectors.c - table of ISRs for INTC in SW vector Mode */
+/* Description:  Contains addresses for 310 ISR vectors */
+/*			     Table address gets loaded to INTC_IACKR */
+/*               Alignment: MPC551x: 2 KB after a 4KB boundary; MPC555x: 64 KB*/
+/* April 22, 2004 S. Mihalik */ 
+/* March 16, 2006 S. Mihalik - Modified for compile with Diab 5.3 */
+/* Jun 29 2006 SM - Used pragma align instead of hard coding address */
+/* Jul  5 2007 SM - alignment now done in link file; changes for MPC551x */
+/* Aug 30 2007 SM - Added pragma for CodeWarrior */
+/* Oct 01 2008 SM - Changed to use PIT1 ISR instead of eMIOS Ch 0 ISR */
+
+#include "MPC5646C.h" /* Use proper include file like mpc5510.h, mpc5554.h, mpc563m.h */
+
+void dummy (void);
+
+extern void SwIrq4ISR(void);
+extern void Pit1ISR(void);
+
+
+/* Use pragma next two lines with CodeWarrior compile */
+#pragma section data_type ".init" ".init" data_mode=far_abs  
+  uint32_t IntcIsrVectorTable[] = { 	 	 
+
+/* Use next two lines with Diab compile */
+/*#pragma section CONST ".intc_sw_isr_vector_table" */		 /* Diab compiler pragma */
+/*const uint32_t IntcIsrVectorTable[] = {   */ 
+
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&SwIrq4ISR, /* ISRs 00 - 04 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 05 - 09 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 10 - 14 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 15 - 19 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 20 - 24 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 25 - 29 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 30 - 34 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 35 - 39 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 40 - 44 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 45 - 49 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 50 - 54 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 55 - 59 */
+ (uint32_t)&Pit1ISR, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 60 - 64 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 55 - 69 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 70 - 74 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 75 - 79 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 80 - 84 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 85 - 89 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 90 - 94 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 95 - 99 */
+
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 100 - 104 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 105 - 109 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 110 - 114 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 115 - 119 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 120 - 124 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 125 - 129 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 130 - 134 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 135 - 139 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 140 - 144 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 145 - 149 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 150 - 154 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 155 - 159 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 160 - 164 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 155 - 169 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 170 - 174 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 175 - 179 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 180 - 184 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 185 - 189 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 190 - 194 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 195 - 199 */
+
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 200 - 204 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 205 - 209 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 210 - 214 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 215 - 219 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 220 - 224 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 225 - 229 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 230 - 234 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 235 - 239 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 240 - 244 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 245 - 249 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 250 - 254 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 255 - 259 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 260 - 264 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 255 - 269 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 270 - 274 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 275 - 279 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 280 - 284 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 285 - 289 */
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 290 - 294 */ 
+ (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 295 - 299 */
+ 
+ //(uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 300 - 304 */ 
+ //(uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, (uint32_t)&dummy, /* ISRs 305 - 309 */
+ };
+
+void dummy (void) {
+   while (1) {}; 			 /* Wait forever or for watchdog timeout */
+ }
+

+ 138 - 0
BMS Master/Sources/MultitaskOS.c

@@ -0,0 +1,138 @@
+//##############################################################################
+//
+// FILE:	MultitaskOS.c
+//
+// TITLE:	Real Time 1ms Generator
+//
+//			- void MultitaskOS_init	( void )
+//			- void ISR_Timer_OS		( void )
+//
+//##############################################################################
+//
+//==============================================================================
+// Change History:
+//==============================================================================
+// Datum:   | Name | Version:| Change / Cause:                            | No
+//------------------------------------------------------------------------------
+//          |      |         |                                            | 002
+//------------------------------------------------------------------------------
+// 05.07.13 |  VR  |   1.1   | Change for ReilingOS                       | 001
+//------------------------------------------------------------------------------
+// 02.05.12 |  TM  |   1.0   | New Build                                  | 000
+//==============================================================================
+//==============================================================================
+// Comment Change / Cause:
+//==============================================================================
+// Change: 003                                                           // 003
+//----------------------
+//                                                       
+//
+//==============================================================================
+// Change: 002                                                           // 002
+//----------------------
+//                                           
+//
+//==============================================================================
+// Change: 001                                                           // 001
+//----------------------
+// 
+//
+//==============================================================================
+
+#include "BMS_Master.h"
+
+	volatile uint32_t ISO_Start = 0;
+	volatile uint32_t ISO_PWM   = 0;
+	volatile uint16_t ISO_PIN   = 0;
+
+
+// ***** MultitaskOS_init ******************************************************
+void MultitaskOS_init( void )
+{
+	PIT.PITMCR.B.MDIS = 0;				// Enable Periodic Interrupt Timer
+	PIT.PITMCR.B.MDIS_RTI = 0;			// Enable Real Time Interrupt
+	PIT.PITMCR.B.FRZ = 1;				// Freeze in Debug Mode
+	
+	PIT.CH[0].LDVAL.R = SYSCLK_KHZ;		// Timeout Period 1ms 64MHz/1kHz
+	PIT.CH[0].TFLG.B.TIF = 1;           // Timer Interrupt Request Clear
+	PIT.CH[0].TCTRL.B.TIE = 1;			// Timer Interrupt Enable
+
+	PIT.CH[0].TCTRL.B.TEN = 1; 			// Timer Active
+}
+
+
+
+// ***** ISR_Timer_OS **********************************************************
+void ISR_Timer_OS( void ) 
+{
+	uint32_t ISO_CycleTime;
+	asm(" wrteei 0");					// disable Interrupts
+
+	PIT.CH[0].TFLG.B.TIF = 1;    		// CLear PIT 1 flag by writing 1
+	Global_1msCounter++;
+ 
+//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+    if( Global_1msCounter > 12000 )
+    {
+  	  if( !READ_INPIN(PIN_REGNR_OKHS) )       			// if General Error: Off, Undervoltage, Grounderror, Uniterror, Underrange
+	  {
+	    gISO_R = 0;									  	// show General Error
+	    gBSE.ErrorBMS |= ERROR_ISO_GENERAL;
+	    gErrorEvent = EEV__SHUT_DOWN_EMERGENCY;         // and load rejection
+	  }
+	  else
+	    if( READ_INPIN(PIN_REGNR_MHS) != ISO_PIN )      // PWM Signal changed ?
+	    {
+	 	  ISO_PIN = ISO_PIN?0:1;						// new PWM Signal store
+		    
+	      if( ISO_PIN )								  	// new Cycle ?
+		  {
+		    ISO_CycleTime = Global_1msCounter - ISO_Start;  // Cycle Time compute
+		    ISO_Start = Global_1msCounter;              // new Initial Value store
+			   
+		    if( ISO_CycleTime < 35)                     // 30 Hz ? >>Quickstart<<
+		    {
+			  if( ISO_CycleTime > 31 )
+			  {
+			    gISO_R = 120000;						// ISO OK?
+			    if(ISO_PWM > 4)                         // > 10%
+		        {
+		    	  gISO_R  = 0;						  	// ISO NOK
+		    	  gBSE.ErrorBMS |= ERROR_ISO_BAD;
+		    	  gErrorEvent = EEV__SHUT_DOWN_EMERGENCY;     // load rejection
+		        }
+			  }
+		    }
+		    else
+			  if( ISO_CycleTime < 102)                  // 10 Hz ? >>regular Operation<<
+			  {
+			    if( ISO_CycleTime > 98 )
+			    {
+				  if(ISO_PWM < 6)                       // yes, Duty < 6 % => Overflow
+			        gISO_R = 120000;					// yes, show Overflow
+				  else
+				    gISO_R = ( 90 * 1200 ) / ( ISO_PWM - 5 ) - 1200;
+					
+				  if(gCANErrorInsert == 14)                                   //!! 1.5-3
+					  gISO_R = MIN_ISO_R_TEST;	
+				  
+				  if( gISO_R < MIN_ISO_R)               // ISO-R low
+				  {
+					gBSE.ErrorBMS |= ERROR_ISO_LOW;
+				    gErrorEvent = EEV__SHUT_DOWN_EMERGENCY;   // load rejection
+				  }
+			    } 
+		      }
+		    }
+	        else                                        // Duty End
+	    	  ISO_PWM = Global_1msCounter - ISO_Start;  // Duty store
+         }
+    }
+//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+	
+	asm(" wrteei 1");					// enable Interrupts
+}
+
+
+
+// ***** End MultitaskOS.c *****************************************************

+ 136 - 0
BMS Master/Sources/RelaisLEDs.c

@@ -0,0 +1,136 @@
+//==============================================================================
+// Purpose:     DigitalOutput-Ansteuerung
+//
+// Created on:  21.09.2012 by IPE
+//
+// History
+//		21.09.2012 neu, T.Maurer
+//==============================================================================
+
+#include "BMS_Master.h"
+
+
+static void switch_allRelais(uint8_t isON);
+static void switch_allLEDs(uint8_t isON);
+static void switch_allHsSwitches(uint8_t isON);
+
+
+void RelaisLEDs_init()
+{
+	//Init ISOMETER
+	SIU.PCR[PIN_REGNR_MHS].R  = 0x0100;		//Input
+	SIU.PCR[PIN_REGNR_OKHS].R = 0x0100;		//Input
+	
+	//Init LEDs
+	SIU.PCR[PIN_REGNR_LED1].R = 0x0200;		//Output
+	SIU.PCR[PIN_REGNR_LED2].R = 0x0200;		//Output
+	SIU.PCR[PIN_REGNR_LED3].R = 0x0200;		//Output
+	SIU.PCR[PIN_REGNR_LED4].R = 0x0200;		//Output
+	
+	//Init HS-Switches
+	SIU.PCR[PIN_REGNR_HS1].R	= 0x0302;		// HS_IN_test1; 		PF[0] Output enable, input enable, Weak PU/PD enable, Weak PD selected
+	SIU.PCR[PIN_REGNR_HS2].R	= 0x0302;		// HS_IN_test2; 		PF[1] Output enable, input enable, Weak PU/PD enable, Weak PD selected
+	SIU.PCR[PIN_REGNR_HS3].R	= 0x0302;		// HS_IN_test3; 		PF[2] Output enable, input enable, Weak PU/PD enable, Weak PD selected
+	SIU.PCR[PIN_REGNR_HS4].R	= 0x0302;		// HS_IN_test4; 		PF[3] Output enable, input enable, Weak PU/PD enable, Weak PD selected
+	SIU.PCR[PIN_REGNR_HS5].R	= 0x0302;		// HS_IN_test5; 		PF[4] Output enable, input enable, Weak PU/PD enable, Weak PD selected
+	SIU.PCR[PIN_REGNR_HS6].R	= 0x0302;		// HS_IN_test6; 		PF[5] Output enable, input enable, Weak PU/PD enable, Weak PD selected
+	SIU.PCR[PIN_REGNR_HS7].R	= 0x0302;		// HS_IN_test7; 		PF[6] Output enable, input enable, Weak PU/PD enable, Weak PD selected
+	SIU.PCR[PIN_REGNR_HS8].R	= 0x0302;		// HS_IN_test8; 		PF[7] Output enable, input enable, Weak PU/PD enable, Weak PD selected
+
+	//Init RelaisSwitches
+	SIU.PCR[PIN_REGNR_RELAIS_PLUS].R	= 0x0302;		// HS_IN_test1; 		PF[0] Output enable, input enable, Weak PU/PD enable, Weak PD selected
+	SIU.PCR[PIN_REGNR_RELAIS_PRECHA].R	= 0x0302;		// HS_IN_test2; 		PF[1] Output enable, input enable, Weak PU/PD enable, Weak PD selected
+	SIU.PCR[PIN_REGNR_RELAIS_SLAVE].R	= 0x0302;		// HS_IN_test3; 		PF[2] Output enable, input enable, Weak PU/PD enable, Weak PD selected
+	
+	//Init PWR SUpply relais
+	SIU.PCR[PIN_REGNR_PWR_SUPPLY].R = 0x0302;
+	switch_allLEDs(0);
+}
+
+
+
+uint8_t RelaisLEDs_TM_update(uint8_t tick)	//TestMode
+{
+	static uint8_t state = 0;
+	static uint16_t msek = 0;
+	if (tick)
+	{
+		msek+=1;
+		if (state == 0) {
+			switch_allRelais(1);
+			switch_allLEDs(1);
+			switch_allHsSwitches(1);
+			if (msek > 3000) {
+				state = 1;
+			}
+		}
+		else {
+//			switch_allRelais(0);
+			switch_allLEDs(0);
+			switch_allHsSwitches(0);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+//--------------------------------------------------------------
+
+static void switch_allRelais(uint8_t isON)
+{
+	if ( isON == 0 ) {
+		CLEAR_OUTPIN(PIN_REGNR_RELAIS_PLUS);
+		CLEAR_OUTPIN(PIN_REGNR_RELAIS_PRECHA);
+		CLEAR_OUTPIN(PIN_REGNR_RELAIS_SLAVE);
+	}
+	else {
+		SET_OUTPIN(PIN_REGNR_RELAIS_PLUS);
+		SET_OUTPIN(PIN_REGNR_RELAIS_PRECHA);
+		SET_OUTPIN(PIN_REGNR_RELAIS_SLAVE);
+	}
+}
+
+static void switch_allLEDs(uint8_t isON)
+{
+	if ( isON == 0 ) {
+		CLEAR_OUTPIN(PIN_REGNR_LED1);
+		CLEAR_OUTPIN(PIN_REGNR_LED2);
+		CLEAR_OUTPIN(PIN_REGNR_LED3);
+		CLEAR_OUTPIN(PIN_REGNR_LED4);
+	}
+	else {
+		SET_OUTPIN(PIN_REGNR_LED1);
+		SET_OUTPIN(PIN_REGNR_LED2);
+		SET_OUTPIN(PIN_REGNR_LED3);
+		SET_OUTPIN(PIN_REGNR_LED4);
+	}
+}
+
+
+static void switch_allHsSwitches(uint8_t isON)
+{
+	if ( isON == 0 ) {
+		CLEAR_OUTPIN(PIN_REGNR_HS1);
+		CLEAR_OUTPIN(PIN_REGNR_HS2);
+		CLEAR_OUTPIN(PIN_REGNR_HS3);
+		CLEAR_OUTPIN(PIN_REGNR_HS4);
+		CLEAR_OUTPIN(PIN_REGNR_HS5);
+		CLEAR_OUTPIN(PIN_REGNR_HS6);
+		CLEAR_OUTPIN(PIN_REGNR_HS7);
+		CLEAR_OUTPIN(PIN_REGNR_HS8);
+	}
+	else {
+		SET_OUTPIN(PIN_REGNR_HS1);
+		SET_OUTPIN(PIN_REGNR_HS2);
+		SET_OUTPIN(PIN_REGNR_HS3);
+		SET_OUTPIN(PIN_REGNR_HS4);
+		SET_OUTPIN(PIN_REGNR_HS5);
+		SET_OUTPIN(PIN_REGNR_HS6);
+		SET_OUTPIN(PIN_REGNR_HS7);
+		SET_OUTPIN(PIN_REGNR_HS8);
+	}
+}
+
+
+
+

+ 10 - 0
BMS Master/Sources/SOC_estimator.c

@@ -0,0 +1,10 @@
+/*
+ * SOC_estimator.c
+
+ *
+ *  Created on: Jul 6, 2016
+ *      Author: le8041
+ */
+
+
+

+ 136 - 0
BMS Master/Sources/TempSensorSpi.c

@@ -0,0 +1,136 @@
+// ----------------------------------------------------------------------------
+// TempSensorSpi.c - 
+// ----------------------------------------------------------------------------
+// Beschreibung:	Auswertung eines Temperatursensors mit
+//					Spi-Kommunikation
+//					HW: BMS-Master, IPE 362-02-02R0
+// Revision:		11. Juni 2012, neu,	T. Maurer, IPE
+// ----------------------------------------------------------------------------
+
+#include "BMS_Master.h"
+
+
+
+DSPI_config_t TempMess_SPI_Config = {
+	&DSPI_2,
+	DSPI_Master,
+	16,	//FrameSize
+	DSPI_ClassicFormat,
+	DSPI_Baud2MHz,
+	2,  //CStoSCK_Delay_Cycles
+	1,  //AfterSCK_Delay_Cycles
+	10,
+	1,
+	CS_Cont_OFF,	//enum{CS_Cont_ON, CS_Cont_OFF};
+	DSPI2_PortC12
+};
+
+
+static volatile TempMessStatus_t TempMess_S;
+
+static const TempMessStatus_t TempMess_S_INIT = {Idle,NoTask,0,0,0,0,0};
+
+static int8_t TempMess_FSM_update(void);
+
+//-----------------------------------------------------------
+// API
+
+void TempMess_init()
+{
+	DSPI_init(&TempMess_SPI_Config);
+	
+	TempMess_S = TempMess_S_INIT;
+}
+
+void TempMess_update()
+{
+	TempMess_FSM_update();
+}
+
+int8_t TempMess_poll_Value(int16_t *target)
+{
+	if ( ! TempMess_S.valueIsNew ) return -1;
+	*target = TempMess_S.value;
+	TempMess_S.valueIsNew = 0;
+	return 0;
+}
+
+int8_t TempMess_triggerRead()
+{
+	if (TempMess_S.FsmState != Idle) return -1;
+	TempMess_S.TaskTrigger = Read;
+	return 0;	
+}
+
+//-----------------------------------------------------------
+// static
+
+
+static int8_t TempMess_pushDummys()
+{
+	volatile struct DSPI_tag *p_DSPI = TempMess_SPI_Config.p_Modul;
+	if (p_DSPI->SR.B.TXCTR != 0) return -1;
+
+	if ( DSPI_push(&TempMess_SPI_Config, 0xFFFF, 1) < 0 )	return -1;
+	return 0;
+}	
+
+static int8_t TempMess_pop_AdcVal()
+{
+	uint16_t cnt_rcvd = 0;
+	uint16_t value_tmp;
+	if ( DSPI_pop(&TempMess_SPI_Config, &value_tmp) < 0 ) return -1; //nothing rcvd
+	TempMess_S.value = ((int16_t)value_tmp) >> 3;	//0.0625 Grad Auflösung
+	TempMess_S.value >>= 4;	//Umrechnung in 1 Grad-Auflösung (8-Bit)
+	return 0;	//1 = finished
+}
+
+
+static int8_t TempMess_checkTimeOut(uint16_t Cnt, uint16_t TO_Value)
+{	
+	if (Cnt >= TO_Value) {
+		TempMess_init();
+		TempMess_S.Flags.B.FSM_TO = 1;
+		return -1;
+	}
+	return 0;
+}
+
+
+//FSM
+static int8_t TempMess_FSM_update()
+{
+	#define FSM_TIMEOUT	10
+	static uint16_t StateTimeoutCnt = 0;
+	volatile struct DSPI_tag *p_DSPI = TempMess_SPI_Config.p_Modul;
+	StateTimeoutCnt += 1;
+	switch (TempMess_S.FsmState)	{
+		case Idle:
+			if (TempMess_S.TaskTrigger == Read) {
+				DSPI_Clear_RxFifo(&TempMess_SPI_Config);
+				if (TempMess_pushDummys() >= 0 ) {
+					TempMess_S.TaskTrigger = NoTask;
+					TempMess_S.FsmState = Read_1;
+					StateTimeoutCnt = 0;
+				}
+			}
+			break;
+		case Read_1:
+			if (TempMess_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) return -1;
+			if ( p_DSPI->SR.B.EOQF == 1 ) {	//finished
+				TempMess_S.FsmState = Read_2;
+				StateTimeoutCnt = 0;
+			}
+			break;
+		case Read_2:
+			if (TempMess_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) return -2;
+			if (TempMess_pop_AdcVal() >=0 ) {
+				p_DSPI->SR.B.EOQF = 1;
+				TempMess_S.valueIsNew = 1;
+				TempMess_S.FsmState = Idle;
+			}
+			break;
+	}
+	return 0;
+	#undef FSM_TIMEOUT
+}

+ 200 - 0
BMS Master/Sources/main.c

@@ -0,0 +1,200 @@
+//##############################################################################
+//
+//  BMS_Master - Battery Management System Master 
+//
+//  Firmware for 
+//	- Collecting and Checking Data of BMS_Slave and BMS_UI
+//  - Flow Control for START, STOP, LOAD and DRIVE
+//  - SOC/SOH computing
+//  - Balancer computing
+//  - Error Check
+//  - Emergency Shut Off
+//  
+//
+//  CENTRAL - FILE
+//  
+//  - void	Main( void )
+//
+// 
+//##############################################################################
+//
+//  Hardware Revision:  V1
+// 
+//  uController:        Freescale MPC5646C
+//  
+//  Autor:              M. Maurer, V. Reiling, KIT Campus Nord, IPE
+//
+//  Date:               April 2012
+//
+//  Built with:         CodeWarrior Development Studio 10.4 ( Build Id: 130425 )
+//
+//##############################################################################
+
+
+//==============================================================================
+// History:
+//==============================================================================
+// Datum:   | Name | Version:| Cause:			                         | rev.:
+//------------------------------------------------------------------------------
+// 04.05.15 |  VR  |   1.5   | Change for BaSyTec                        | 005   
+//------------------------------------------------------------------------------
+// 18.11.14 |  VR  |   1.4   | upgrade 2 CodeWarrior 10.6 id: 140329     | 004   
+//------------------------------------------------------------------------------
+// 18.03.14 |  VR  |   1.3   | Error Handling changed, Derating added    | 003   
+//------------------------------------------------------------------------------
+// 07.02.14 |  VR  |   1.2   | upgrade 2 CodeWarrior 10.5 id: 130916     | 002    
+//------------------------------------------------------------------------------
+// 05.07.13 |  VR  |   1.1   | BMS Master Project					     | 001 
+//------------------------------------------------------------------------------
+// 20.04.12 |  TM  |   1.0   | Hardware Test Code & Drivers              | 000
+//==============================================================================
+#include "BMS_Master.h"
+
+
+uint8_t const   ucMainVersion  =  0x1;
+uint8_t const   ucSubVersion   =  0x5;
+
+
+
+// ***** Global Variables *******************************************************************
+BSD_t		gBSD;							// Global Battery Management System Slave Data 
+BSE_t		gBSE;							// Global Battery Management System Slave Errors
+uint8_t     gMaxDischargeCurrent = 60;      // Maximum Discharge Current = 120A / 2A per Bit
+uint32_t	Global_1msCounter = 0;			// 1.5 Months till Overrun
+uint32_t	gEvent;							// Control of Main FSM
+uint32_t    gErrorEvent;                    // Control of Error FSM
+uint32_t    gISO_R = 0;                     // Resistance of Isolation
+uint8_t     gCANErrorInsert = 0;            // Automatic Test over CAN
+MASTER_CAN0_STRUCT_t gDUMMY_data_struct;
+
+
+
+
+
+void main(void)
+{
+	/**
+	 * @brief Main Function of BMS Master
+	 */	
+	volatile    uint16_t	Vbat 						= 0;
+	volatile 	uint16_t	StartTryCounter 			= 0;
+	volatile    uint32_t	DelayCount 					= 0;
+	volatile	uint32_t	NextEvent					= 0;
+	volatile	uint32_t	CounterCheckVoltageMSG		= 12000;
+	volatile	uint32_t	CounterCheckStatusUIMSG		= 12000;
+	volatile	uint32_t	CounterCheckTemperatureMSG	= 12000;
+	volatile	uint32_t	Counter_20ms				= 5000;
+	volatile	uint32_t	Counter_50ms				= 5000;
+	volatile	uint32_t	Counter_100ms				= 5000;
+	volatile	uint16_t	Copy_r_Voltage				= 200;
+	volatile	uint16_t	Copy_r_Status				= 200;
+	volatile	uint16_t	Copy_r_Temperature 			= 200;
+	volatile	uint16_t	Copy_r_UI         			= 200;
+	volatile    uint32_t	ErrorTimeCount              = 0;
+	static float SoC_test;
+	
+	static	uint32_t	test_timestamp				= 0;
+	static 	uint8_t		test_data_send[4]			= {1,2,3,4};	
+
+	static	MASTER_CAN0_STRUCT_t CAN0_fsm_state;
+	static  MASTER_CAN1_STRUCT_t CAN1_fsm_state;
+	static BMS_MASTER_OPERATION_t operation_Fsm;
+	static  uint8_t		active_states[2]= {4,15} ;
+	static BMS_SLAVE_CONFIGURATION_t cellConfig[CAN0_MAX_NR_OF_SLAVES-1];
+	static BMS_UI_CONFIGURATION_t uiConfig;
+	static uint8_t fram_test[8] ={1,2,3,4,5,6,7,8};
+	static uint8_t fram_rx_text[8] ={0,0,0,0,0,0,0,0};
+	
+	
+	
+	
+	
+				 int32_t	SOC 	 		= 0;		// State of Charge for DICO in 0.4%
+	  			uint32_t	BalanceOn		= 1;        // Send empty Balancing
+	  			uint32_t	i = 0;
+	  			uint32_t	j = 0;
+	  			uint32_t    test = 0;
+	  			
+	  			
+//-------------------------------------------------------------------------------------------	
+	init_Device();    						// Device.h
+	BoardPeriph_init();						// BoardPeripherals.h
+	
+	CAN0_init();							// CAN Master to Slave
+	CAN1_init();							// CAN Master to INVERTER
+	CAN1_init_tx_structure(&(CAN0_fsm_state.inverter.txStruct));
+	//CAN2_init();							// CAN Master to DICO
+
+	
+	MultitaskOS_init();						// MultitaskOS.h
+	  
+	enableIrq();							// Device.h
+  
+	BoardPeriph_test_init();				// BoardPeripherals.h
+
+	gEvent = EV__INITIALISE;				// Start Main FSM
+	gErrorEvent = EEV__NO_ERROR;            // Clear Error FSM
+	
+	SwitchRelais( PWR_SUPPLY, 0) ;// Activate PWR Supply by setting pin to low
+
+	//CAN_Tx_BMU_DICO( );
+	gen_data_initSlave(&gDUMMY_data_struct, 3600, 25, 36000, 1000); 
+	
+	initCellConfig(cellConfig);
+	initUiConfig(&uiConfig);
+	
+	CAN0_init_telegrams(&TelegramTxContainer[0],CAN0_MAX_NR_OF_SLAVES);
+	init_master_CAN0_fsm(&CAN0_fsm_state,cellConfig,&uiConfig);
+	Master_CAN1_fsm_init(&CAN1_fsm_state);
+	
+	BMS_Can_ID_init_init_startupConfig (&CAN0_fsm_state); 
+	
+	//init_master_operation_fsm(&operation_Fsm);
+	
+	// read fram start State
+
+	
+	
+
+	while(Global_1msCounter < DELAY_START)
+	{
+	}
+	
+	while(BMS_Can_ID_init_fsm (&CAN0_fsm_state) == BMS_CAN_ID_INIT_RETURN_RUNNING ) {
+		// wait
+	}
+	//write_fram_clear_startup_state(&CAN0_fsm_state); 
+	write_fram_clear_error_buffer(&CAN0_fsm_state); 
+	//write_fram_set_SoC(0.03); 
+	
+	while(Global_1msCounter < DELAY_START*2)
+	{
+	}
+
+	read_fram_get_startup_state(&CAN0_fsm_state);
+	read_fram_read_error_buffer(&CAN0_fsm_state);
+	
+	SoC_test= read_fram_get_SoC();
+	test_timestamp=Global_1msCounter ;
+	while(1) {
+		
+		Master_CAN0_fsm(&CAN0_fsm_state,Global_1msCounter);
+		//Master_operation_fsm(&CAN0_fsm_state,Global_1msCounter,&operation_Fsm);
+		
+		//Master_CAN1_fsm(&CAN0_fsm_state,&CAN1_fsm_state,Global_1msCounter);
+		//if(Global_1msCounter > 20000 + test_timestamp) {
+		//	SwitchRelais( PWR_SUPPLY, 1);
+		//}
+		
+		if (Global_1msCounter > CAN0_fsm_state.reset_test_timestamp + 3000 && CAN0_fsm_state.reset_test_timestamp > 10) {
+			test++;
+		}
+		
+	}
+	
+
+}
+
+
+
+// ***** End Main.c *************************************************************************