Create directory structure to hold the (not yet created) Keil and IAR demo projects for the SmartFusion.
diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/a2fxxxm3.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/a2fxxxm3.h
new file mode 100644
index 0000000..ab389e0
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/a2fxxxm3.h
@@ -0,0 +1,1102 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ *  SmartFusion A2FxxxM3 Cortex Microcontroller Software Interface - Peripheral

+ *  Access Layer.

+ *

+ *  This file describes the interrupt assignment and peripheral registers for

+ *  the SmartFusion A2FxxxM3 familly of devices. 

+ *

+ * SVN $Revision: 2331 $

+ * SVN $Date: 2010-02-26 12:02:06 +0000 (Fri, 26 Feb 2010) $

+ */

+#ifndef __A2FXXXM3_H__

+#define __A2FXXXM3_H__

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/*

+ * ==========================================================================

+ * ---------- Interrupt Number Definition -----------------------------------

+ * ==========================================================================

+ */

+

+typedef enum IRQn

+{

+/******  Cortex-M3 Processor Exceptions Numbers *********************************************************/

+  NonMaskableInt_IRQn             = -14,      /*!< 2 Non Maskable Interrupt                             */

+  HardFault_IRQn                  = -13,      /*!< 2 Hard Fault Interrupt                               */

+  MemoryManagement_IRQn           = -12,      /*!< 4 Cortex-M3 Memory Management Interrupt              */

+  BusFault_IRQn                   = -11,      /*!< 5 Cortex-M3 Bus Fault Interrupt                      */

+  UsageFault_IRQn                 = -10,      /*!< 6 Cortex-M3 Usage Fault Interrupt                    */

+  SVCall_IRQn                     = -5,       /*!< 11 Cortex-M3 SV Call Interrupt                       */

+  DebugMonitor_IRQn               = -4,       /*!< 12 Cortex-M3 Debug Monitor Interrupt                 */

+  PendSV_IRQn                     = -2,       /*!< 14 Cortex-M3 Pend SV Interrupt                       */

+  SysTick_IRQn                    = -1,       /*!< 15 Cortex-M3 System Tick Interrupt                   */

+

+/******  SmartFusion specific Interrupt Numbers *********************************************************/

+  WdogWakeup_IRQn                 = 0,        /*!< WatchDog wakeup interrupt                            */

+  BrownOut_1_5V_IRQn              = 1,        /*!< Supply dropped below 1.5V                            */

+  BrownOut_3_3V_IRQn              = 2,        /*!< Supply dropped below 1.5V                            */

+  RTC_Match_IRQn                  = 3,        /*!< RTC match interrupt                                  */

+  RTCIF_Pub_IRQn                  = 4,        /*!< RTC interface push button interrupt                  */

+  EthernetMAC_IRQn                = 5,        /*!< Ethernet MAC interrupt                               */

+  IAP_IRQn                        = 6,        /*!< In Application Programming (IAP) interrupt           */

+  ENVM0_IRQn                      = 7,        /*!< eNVM0 operation completion interrupt                 */

+  ENVM1_IRQn                      = 8,        /*!< eNVM1 operation completion interrupt                 */

+  DMA_IRQn                        = 9,        /*!< Peripheral DMA interrupt                             */

+  UART0_IRQn                      = 10,       /*!< UART0 interrupt                                      */

+  UART1_IRQn                      = 11,       /*!< UART1 interrupt                                      */

+  SPI0_IRQn                       = 12,       /*!< SPI0 interrupt                                       */

+  SPI1_IRQn                       = 13,       /*!< SP1 interrupt                                        */

+  I2C0_IRQn                       = 14,       /*!< I2C0 interrupt                                       */

+  I2C0_SMBAlert_IRQn              = 15,       /*!< I2C0 SMBus Alert interrupt                           */

+  I2C0_SMBus_IRQn                 = 16,       /*!< I2C0 SMBus Suspend interrupt                         */

+  I2C1_IRQn                       = 17,       /*!< I2C1 interrupt                                       */

+  I2C1_SMBAlert_IRQn              = 18,       /*!< I2C1 SMBus Alert interrupt                           */

+  I2C1_SMBus_IRQn                 = 19,       /*!< I2C1 SMBus Suspend interrupt                         */

+  Timer1_IRQn                     = 20,       /*!< Timer1 interrupt                                     */

+  Timer2_IRQn                     = 21,       /*!< Timer2 interrupt                                     */

+  PLL_Lock_IRQn                   = 22,       /*!< PLL lock interrupt                                   */

+  PLL_LockLost_IRQn               = 23,       /*!< PLL loss of lock interrupt                           */

+  CommError_IRQn                  = 24,       /*!< Communications Matrix error interrupt                */

+  Fabric_IRQn                     = 31,       /*!< FPGA fabric interrupt                                */

+  GPIO0_IRQn                      = 32,       /*!< GPIO 0 interrupt                                     */

+  GPIO1_IRQn                      = 33,       /*!< GPIO 1 interrupt                                     */

+  GPIO2_IRQn                      = 34,       /*!< GPIO 2 interrupt                                     */

+  GPIO3_IRQn                      = 35,       /*!< GPIO 3 interrupt                                     */

+  GPIO4_IRQn                      = 36,       /*!< GPIO 4 interrupt                                     */

+  GPIO5_IRQn                      = 37,       /*!< GPIO 5 interrupt                                     */

+  GPIO6_IRQn                      = 38,       /*!< GPIO 6 interrupt                                     */

+  GPIO7_IRQn                      = 39,       /*!< GPIO 7 interrupt                                     */

+  GPIO8_IRQn                      = 40,       /*!< GPIO 8 interrupt                                     */

+  GPIO9_IRQn                      = 41,       /*!< GPIO 9 interrupt                                     */

+  GPIO10_IRQn                     = 42,       /*!< GPIO 10 interrupt                                    */

+  GPIO11_IRQn                     = 43,       /*!< GPIO 11 interrupt                                    */

+  GPIO12_IRQn                     = 44,       /*!< GPIO 12 interrupt                                    */

+  GPIO13_IRQn                     = 45,       /*!< GPIO 13 interrupt                                    */

+  GPIO14_IRQn                     = 46,       /*!< GPIO 14 interrupt                                    */

+  GPIO15_IRQn                     = 47,       /*!< GPIO 15 interrupt                                    */

+  GPIO16_IRQn                     = 48,       /*!< GPIO 16 interrupt                                    */

+  GPIO17_IRQn                     = 49,       /*!< GPIO 17 interrupt                                    */

+  GPIO18_IRQn                     = 50,       /*!< GPIO 18 interrupt                                    */

+  GPIO19_IRQn                     = 51,       /*!< GPIO 19 interrupt                                    */

+  GPIO20_IRQn                     = 52,       /*!< GPIO 20 interrupt                                    */

+  GPIO21_IRQn                     = 53,       /*!< GPIO 21 interrupt                                    */

+  GPIO22_IRQn                     = 54,       /*!< GPIO 22 interrupt                                    */

+  GPIO23_IRQn                     = 55,       /*!< GPIO 23 interrupt                                    */

+  GPIO24_IRQn                     = 56,       /*!< GPIO 24 interrupt                                    */

+  GPIO25_IRQn                     = 57,       /*!< GPIO 25 interrupt                                    */

+  GPIO26_IRQn                     = 58,       /*!< GPIO 26 interrupt                                    */

+  GPIO27_IRQn                     = 59,       /*!< GPIO 27 interrupt                                    */

+  GPIO28_IRQn                     = 60,       /*!< GPIO 28 interrupt                                    */

+  GPIO29_IRQn                     = 61,       /*!< GPIO 29 interrupt                                    */

+  GPIO30_IRQn                     = 62,       /*!< GPIO 30 interrupt                                    */

+  GPIO31_IRQn                     = 63,       /*!< GPIO 31 interrupt                                    */

+  ACE_PC0_Flag0_IRQn              = 64,       /*!< ACE SSE program counter 0 flag 0 interrupt           */

+  ACE_PC0_Flag1_IRQn              = 65,       /*!< ACE SSE program counter 0 flag 1 interrupt           */

+  ACE_PC0_Flag2_IRQn              = 66,       /*!< ACE SSE program counter 0 flag 2 interrupt           */

+  ACE_PC0_Flag3_IRQn              = 67,       /*!< ACE SSE program counter 0 flag 3 interrupt           */

+  ACE_PC1_Flag0_IRQn              = 68,       /*!< ACE SSE program counter 1 flag 0 interrupt           */

+  ACE_PC1_Flag1_IRQn              = 69,       /*!< ACE SSE program counter 1 flag 1 interrupt           */

+  ACE_PC1_Flag2_IRQn              = 70,       /*!< ACE SSE program counter 1 flag 2 interrupt           */

+  ACE_PC1_Flag3_IRQn              = 71,       /*!< ACE SSE program counter 1 flag 3 interrupt           */

+  ACE_PC2_Flag0_IRQn              = 72,       /*!< ACE SSE program counter 2 flag 0 interrupt           */

+  ACE_PC2_Flag1_IRQn              = 73,       /*!< ACE SSE program counter 2 flag 1 interrupt           */

+  ACE_PC2_Flag2_IRQn              = 74,       /*!< ACE SSE program counter 2 flag 2 interrupt           */

+  ACE_PC2_Flag3_IRQn              = 75,       /*!< ACE SSE program counter 2 flag 3 interrupt           */

+  ACE_ADC0_DataValid_IRQn         = 76,       /*!< ACE ADC0 data valid interrupt                        */

+  ACE_ADC1_DataValid_IRQn         = 77,       /*!< ACE ADC1 data valid interrupt		     			*/

+  ACE_ADC2_DataValid_IRQn         = 78,       /*!< ACE ADC2 data valid interrupt		     			*/

+  ACE_ADC0_CalDone_IRQn           = 79,       /*!< ACE ADC0 calibration done interrupt                  */

+  ACE_ADC1_CalDone_IRQn           = 80,       /*!< ACE ADC1 calibration done interrupt                  */

+  ACE_ADC2_CalDone_IRQn           = 81,       /*!< ACE ADC2 calibration done interrupt                  */

+  ACE_ADC0_CalStart_IRQn          = 82,       /*!< ACE ADC0 calibration start interrupt                 */

+  ACE_ADC1_CalStart_IRQn          = 83,       /*!< ACE ADC1 calibration start interrupt                 */

+  ACE_ADC2_CalStart_IRQn          = 84,       /*!< ACE ADC2 calibration start interrupt                 */

+  ACE_Comp0_Fall_IRQn             = 85,       /*!< ACE comparator 0 falling under reference interrupt   */

+  ACE_Comp1_Fall_IRQn             = 86,       /*!< ACE comparator 1 falling under reference interrupt   */

+  ACE_Comp2_Fall_IRQn             = 87,       /*!< ACE comparator 2 falling under reference interrupt   */

+  ACE_Comp3_Fall_IRQn             = 88,       /*!< ACE comparator 3 falling under reference interrupt   */

+  ACE_Comp4_Fall_IRQn             = 89,       /*!< ACE comparator 4 falling under reference interrupt   */

+  ACE_Comp5_Fall_IRQn             = 90,       /*!< ACE comparator 5 falling under reference interrupt   */

+  ACE_Comp6_Fall_IRQn             = 91,       /*!< ACE comparator 6 falling under reference interrupt   */

+  ACE_Comp7_Fall_IRQn             = 92,       /*!< ACE comparator 7 falling under reference interrupt   */

+  ACE_Comp8_Fall_IRQn             = 93,       /*!< ACE comparator 8 falling under reference interrupt   */

+  ACE_Comp9_Fall_IRQn             = 94,       /*!< ACE comparator 9 falling under reference interrupt   */

+  ACE_Comp10_Fall_IRQn            = 95,       /*!< ACE comparator 10 falling under reference interrupt  */

+  ACE_Comp11_Fall_IRQn            = 96,       /*!< ACE comparator 11 falling under reference interrupt  */

+  ACE_Comp0_Rise_IRQn             = 97,       /*!< ACE comparator 0 rising over reference interrupt     */

+  ACE_Comp1_Rise_IRQn             = 98,       /*!< ACE comparator 1 rising over reference interrupt     */

+  ACE_Comp2_Rise_IRQn             = 99,       /*!< ACE comparator 2 rising over reference interrupt     */

+  ACE_Comp3_Rise_IRQn             = 100,      /*!< ACE comparator 3 rising over reference interrupt     */

+  ACE_Comp4_Rise_IRQn             = 101,      /*!< ACE comparator 4 rising over reference interrupt     */

+  ACE_Comp5_Rise_IRQn             = 102,      /*!< ACE comparator 5 rising over reference interrupt     */

+  ACE_Comp6_Rise_IRQn             = 103,      /*!< ACE comparator 6 rising over reference interrupt     */

+  ACE_Comp7_Rise_IRQn             = 104,      /*!< ACE comparator 7 rising over reference interrupt     */

+  ACE_Comp8_Rise_IRQn             = 105,      /*!< ACE comparator 8 rising over reference interrupt     */

+  ACE_Comp9_Rise_IRQn             = 106,      /*!< ACE comparator 9 rising over reference interrupt     */

+  ACE_Comp10_Rise_IRQn            = 107,      /*!< ACE comparator 10 rising over reference interrupt    */

+  ACE_Comp11_Rise_IRQn            = 108,      /*!< ACE comparator 11 rising over reference interrupt    */

+  ACE_ADC0_FifoFull_IRQn          = 109,      /*!< ACE ADC0 FIFO full interrupt                         */

+  ACE_ADC0_FifoAFull_IRQn         = 110,      /*!< ACE ADC0 FIFO almost full interrupt                  */

+  ACE_ADC0_FifoEmpty_IRQn         = 111,      /*!< ACE ADC0 FIFO empty interrupt                        */

+  ACE_ADC1_FifoFull_IRQn          = 112,      /*!< ACE ADC1 FIFO full interrupt                         */

+  ACE_ADC1_FifoAFull_IRQn         = 113,      /*!< ACE ADC1 FIFO almost full interrupt                  */

+  ACE_ADC1_FifoEmpty_IRQn         = 114,      /*!< ACE ADC1 FIFO empty interrupt                        */

+  ACE_ADC2_FifoFull_IRQn          = 115,      /*!< ACE ADC2 FIFO full interrupt                         */

+  ACE_ADC2_FifoAFull_IRQn         = 116,      /*!< ACE ADC2 FIFO almost full interrupt                  */

+  ACE_ADC2_FifoEmpty_IRQn         = 117,      /*!< ACE ADC2 FIFO empty interrupt                        */

+  ACE_PPE_Flag0_IRQn              = 118,      /*!< ACE post processing engine flag 0 interrupt          */

+  ACE_PPE_Flag1_IRQn              = 119,      /*!< ACE post processing engine flag 1 interrupt          */

+  ACE_PPE_Flag2_IRQn              = 120,      /*!< ACE post processing engine flag 2 interrupt          */

+  ACE_PPE_Flag3_IRQn              = 121,      /*!< ACE post processing engine flag 3 interrupt          */

+  ACE_PPE_Flag4_IRQn              = 122,      /*!< ACE post processing engine flag 4 interrupt          */

+  ACE_PPE_Flag5_IRQn              = 123,      /*!< ACE post processing engine flag 5 interrupt          */

+  ACE_PPE_Flag6_IRQn              = 124,      /*!< ACE post processing engine flag 6 interrupt          */

+  ACE_PPE_Flag7_IRQn              = 125,      /*!< ACE post processing engine flag 7 interrupt          */

+  ACE_PPE_Flag8_IRQn              = 126,      /*!< ACE post processing engine flag 8 interrupt          */

+  ACE_PPE_Flag9_IRQn              = 127,      /*!< ACE post processing engine flag 9 interrupt          */

+  ACE_PPE_Flag10_IRQn             = 128,      /*!< ACE post processing engine flag 10 interrupt         */

+  ACE_PPE_Flag11_IRQn             = 129,      /*!< ACE post processing engine flag 11 interrupt         */

+  ACE_PPE_Flag12_IRQn             = 130,      /*!< ACE post processing engine flag 12 interrupt         */

+  ACE_PPE_Flag13_IRQn             = 131,      /*!< ACE post processing engine flag 13 interrupt         */

+  ACE_PPE_Flag14_IRQn             = 132,      /*!< ACE post processing engine flag 14 interrupt         */

+  ACE_PPE_Flag15_IRQn             = 133,      /*!< ACE post processing engine flag 15 interrupt         */

+  ACE_PPE_Flag16_IRQn             = 134,      /*!< ACE post processing engine flag 16 interrupt         */

+  ACE_PPE_Flag17_IRQn             = 135,      /*!< ACE post processing engine flag 17 interrupt         */

+  ACE_PPE_Flag18_IRQn             = 136,      /*!< ACE post processing engine flag 18 interrupt         */

+  ACE_PPE_Flag19_IRQn             = 137,      /*!< ACE post processing engine flag 19 interrupt         */

+  ACE_PPE_Flag20_IRQn             = 138,      /*!< ACE post processing engine flag 20 interrupt         */

+  ACE_PPE_Flag21_IRQn             = 139,      /*!< ACE post processing engine flag 21 interrupt         */

+  ACE_PPE_Flag22_IRQn             = 140,      /*!< ACE post processing engine flag 22 interrupt         */

+  ACE_PPE_Flag23_IRQn             = 141,      /*!< ACE post processing engine flag 23 interrupt         */

+  ACE_PPE_Flag24_IRQn             = 142,      /*!< ACE post processing engine flag 24 interrupt         */

+  ACE_PPE_Flag25_IRQn             = 143,      /*!< ACE post processing engine flag 25 interrupt         */

+  ACE_PPE_Flag26_IRQn             = 144,      /*!< ACE post processing engine flag 26 interrupt         */

+  ACE_PPE_Flag27_IRQn             = 145,      /*!< ACE post processing engine flag 27 interrupt         */

+  ACE_PPE_Flag28_IRQn             = 146,      /*!< ACE post processing engine flag 28 interrupt         */

+  ACE_PPE_Flag29_IRQn             = 147,      /*!< ACE post processing engine flag 29 interrupt         */

+  ACE_PPE_Flag30_IRQn             = 148,      /*!< ACE post processing engine flag 30 interrupt         */

+  ACE_PPE_Flag31_IRQn             = 149       /*!< ACE post processing engine flag 31 interrupt         */

+} IRQn_Type;

+

+

+/*

+ * ==========================================================================

+ * ----------- Processor and Core Peripheral Section ------------------------

+ * ==========================================================================

+ */

+

+/* Configuration of the Cortex-M3 Processor and Core Peripherals */

+#define __MPU_PRESENT             1           /*!< SmartFusion includes a MPU                       */

+#define __NVIC_PRIO_BITS          5           /*!< SmartFusion uses 5 Bits for the Priority Levels  */

+#define __Vendor_SysTickConfig    0           /*!< Set to 1 if different SysTick Config is used     */

+

+

+#include "core_cm3.h"                         /* Cortex-M3 processor and core peripherals           */

+#include "system_a2fxxxm3.h"                  /* SmartFusion System                                 */

+

+/******************************************************************************/

+/*                Device Specific Peripheral registers structures             */

+/******************************************************************************/

+#if defined   ( __CC_ARM   )

+  /* Enable anonymous unions when building using Keil-MDK */

+  #pragma anon_unions

+#endif

+/*----------------------------------------------------------------------------*/

+/*----------------------------------- UART -----------------------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    union

+    {

+        __I  uint8_t    RBR;

+        __O  uint8_t    THR;

+        __IO uint8_t    DLR;

+             uint32_t   RESERVED0;

+    };

+

+    union

+    {

+        __IO uint8_t  DMR;

+        __IO uint8_t  IER;

+             uint32_t RESERVED1;

+    };

+

+    union

+    {

+        __IO uint8_t  IIR;

+        __IO uint8_t  FCR;

+             uint32_t RESERVED2;

+    };    

+

+    __IO uint8_t  LCR;

+         uint8_t  RESERVED3;

+         uint16_t RESERVED4;

+    __IO uint8_t  MCR;

+         uint8_t  RESERVED5;

+         uint16_t RESERVED6;

+    __I  uint8_t  LSR;

+         uint8_t  RESERVED7;

+         uint16_t RESERVED8;

+    __I  uint8_t  MSR;

+         uint8_t  RESERVED9;

+         uint16_t RESERVED10;

+    __IO uint8_t  SR;

+         uint8_t  RESERVED11;

+         uint16_t RESERVED12;

+} UART_TypeDef;

+

+/*------------------------------------------------------------------------------

+ *

+ */

+typedef struct

+{

+         uint32_t RESERVED0[32];

+         

+    __IO uint32_t IER_ERBFI;

+    __IO uint32_t IER_ETBEI;

+    __IO uint32_t IER_ELSI;

+    __IO uint32_t IER_EDSSI;

+    

+         uint32_t RESERVED1[28];

+    

+    __IO uint32_t FCR_ENABLE;

+    __IO uint32_t FCR_CLEAR_RX_FIFO;

+    __IO uint32_t FCR_CLEAR_TX_FIFO;

+    __IO uint32_t FCR_RXRDY_TXRDYN_EN;

+    __IO uint32_t FCR_RESERVED0;

+    __IO uint32_t FCR_RESERVED1;

+    __IO uint32_t FCR_RX_TRIG0;

+    __IO uint32_t FCR_RX_TRIG1;

+      

+         uint32_t RESERVED2[24];

+    

+    __IO uint32_t LCR_WLS0;

+    __IO uint32_t LCR_WLS1;

+    __IO uint32_t LCR_STB;

+    __IO uint32_t LCR_PEN;

+    __IO uint32_t LCR_EPS;

+    __IO uint32_t LCR_SP;

+    __IO uint32_t LCR_SB;

+    __IO uint32_t LCR_DLAB;

+      

+         uint32_t RESERVED3[24];

+    

+    __IO uint32_t MCR_DTR;

+    __IO uint32_t MCR_RTS;

+    __IO uint32_t MCR_OUT1;

+    __IO uint32_t MCR_OUT2;

+    __IO uint32_t MCR_LOOP;

+      

+         uint32_t RESERVED4[27];

+        

+    __I  uint32_t LSR_DR;

+    __I  uint32_t LSR_OE;

+    __I  uint32_t LSR_PE;

+    __I  uint32_t LSR_FE;

+    __I  uint32_t LSR_BI;

+    __I  uint32_t LSR_THRE;

+    __I  uint32_t LSR_TEMT;

+    __I  uint32_t LSR_FIER;

+            

+         uint32_t RESERVED5[24];

+         

+    __I  uint32_t MSR_DCTS;

+    __I  uint32_t MSR_DDSR;

+    __I  uint32_t MSR_TERI;

+    __I  uint32_t MSR_DDCD;

+    __I  uint32_t MSR_CTS;

+    __I  uint32_t MSR_DSR;

+    __I  uint32_t MSR_RI;

+    __I  uint32_t MSR_DCD;

+  

+} UART_BitBand_TypeDef;

+

+/*----------------------------------------------------------------------------*/

+/*----------------------------------- I2C ------------------------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    __IO uint8_t  CTRL;

+         uint8_t  RESERVED0;

+         uint16_t RESERVED1;

+         uint8_t  STATUS;

+         uint8_t  RESERVED2;

+         uint16_t RESERVED3;

+    __IO uint8_t  DATA;

+         uint8_t  RESERVED4;

+         uint16_t RESERVED5;

+    __IO uint8_t  ADDR;

+         uint8_t  RESERVED6;

+         uint16_t RESERVED7;

+    __IO uint8_t  SMBUS;

+         uint8_t  RESERVED8;

+         uint16_t RESERVED9;

+    __IO uint8_t  FREQ;

+         uint8_t  RESERVED10;

+         uint16_t RESERVED11;

+    __IO uint8_t  GLITCHREG;

+         uint8_t  RESERVED12;

+         uint16_t RESERVED13;

+} I2C_TypeDef;

+

+/*------------------------------------------------------------------------------

+ *

+ */

+typedef struct

+{

+    uint32_t CTRL_CR0;

+    uint32_t CTRL_CR1;

+    uint32_t CTRL_AA;

+    uint32_t CTRL_SI;

+    uint32_t CTRL_STO;

+    uint32_t CTRL_STA;

+    uint32_t CTRL_ENS1;

+    uint32_t CTRL_CR2;

+    uint32_t RESERVED0[56];

+    uint32_t DATA_DIR;

+    uint32_t RESERVED1[31];

+    uint32_t ADDR_GC;

+} I2C_BitBand_TypeDef;

+

+/*----------------------------------------------------------------------------*/

+/*----------------------------------- SPI ------------------------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    __IO uint32_t CONTROL;

+    __IO uint32_t TXRXDF_SIZE;

+    __I  uint32_t STATUS;

+    __O  uint32_t INT_CLEAR;

+    __I  uint32_t RX_DATA;

+    __O  uint32_t TX_DATA;

+    __IO uint32_t CLK_GEN;

+    __IO uint32_t SLAVE_SELECT;

+    __I  uint32_t MIS;

+    __I  uint32_t RIS;

+} SPI_TypeDef;

+

+typedef struct

+{

+    __IO uint32_t CTRL_ENABLE;

+    __IO uint32_t CTRL_MASTER;

+    __IO uint32_t CTRL_MODE[2];

+    __IO uint32_t CTRL_RX_INT_EN;

+    __IO uint32_t CTRL_TX_INT_EN;

+    __IO uint32_t CTRL_RX_OVERFLOW_INT_EN;

+    __IO uint32_t CTRL_TX_UNDERRUN_INT_EN;

+    __IO uint32_t CTRL_TXRXDFCOUNT[16];

+    __IO uint32_t CTRL_SPO;

+    __IO uint32_t CTRL_SPH;

+    __IO uint32_t CTRL_RESERVED[6];

+    

+    __IO uint32_t TXRXDF_SIZE[32];

+    

+    __I  uint32_t STATUS_TX_DONE;

+    __I  uint32_t STATUS_RX_RDY;

+    __I  uint32_t STATUS_RX_CH_OV;

+    __I  uint32_t STATUS_TX_CH_UV;

+    __I  uint32_t STATUS_RX_FIFO_FULL;

+    __I  uint32_t STATUS_RX_FIFO_FULL_NEXT;

+    __I  uint32_t STATUS_RX_FIFO_EMPTY;

+    __I  uint32_t STATUS_RX_FIFO_EMPTY_NEXT;

+    __I  uint32_t STATUS_TX_FIFO_FULL;

+    __I  uint32_t STATUS_TX_FIFO_FULL_NEXT;

+    __I  uint32_t STATUS_TX_FIFO_EMPTY;

+    __I  uint32_t STATUS_TX_FIFO_EMPTY_NEXT;

+    __I  uint32_t STATUS_RESERVED[20];

+    

+    __O  uint32_t INT_CLEAR_TX_DONE;

+    __O  uint32_t INT_CLEAR_RX_RDY;

+    __O  uint32_t INT_CLEAR_RX_OVER;

+    __O  uint32_t INT_CLEAR_TX_UNDER;

+    __O  uint32_t INT_CLEAR[28];

+    

+    __I  uint32_t RX_DATA[32];

+    __O  uint32_t TX_DATA[32];

+    __IO uint32_t CLK_GEN[32];

+    __IO uint32_t SLAVE_SELECT[32];

+    __I  uint32_t MIS_TX_DONE;

+    __I  uint32_t MIS_RX_RDY;

+    __I  uint32_t MIS_RX_OVER;

+    __I  uint32_t MIS_TX_UNDER;

+    __I  uint32_t MIS[28];

+    __I  uint32_t RIS[32];

+} SPI_BitBand_TypeDef;

+

+/*----------------------------------------------------------------------------*/

+/*----------------------------------- GPIO -----------------------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    __IO uint32_t GPIO_0_CFG;

+    __IO uint32_t GPIO_1_CFG;

+    __IO uint32_t GPIO_2_CFG;

+    __IO uint32_t GPIO_3_CFG;

+    __IO uint32_t GPIO_4_CFG;

+    __IO uint32_t GPIO_5_CFG;

+    __IO uint32_t GPIO_6_CFG;

+    __IO uint32_t GPIO_7_CFG;

+    __IO uint32_t GPIO_8_CFG;

+    __IO uint32_t GPIO_9_CFG;

+    __IO uint32_t GPIO_10_CFG;

+    __IO uint32_t GPIO_11_CFG;

+    __IO uint32_t GPIO_12_CFG;

+    __IO uint32_t GPIO_13_CFG;

+    __IO uint32_t GPIO_14_CFG;

+    __IO uint32_t GPIO_15_CFG;

+    __IO uint32_t GPIO_16_CFG;

+    __IO uint32_t GPIO_17_CFG;

+    __IO uint32_t GPIO_18_CFG;

+    __IO uint32_t GPIO_19_CFG;

+    __IO uint32_t GPIO_20_CFG;

+    __IO uint32_t GPIO_21_CFG;

+    __IO uint32_t GPIO_22_CFG;

+    __IO uint32_t GPIO_23_CFG;

+    __IO uint32_t GPIO_24_CFG;

+    __IO uint32_t GPIO_25_CFG;

+    __IO uint32_t GPIO_26_CFG;

+    __IO uint32_t GPIO_27_CFG;

+    __IO uint32_t GPIO_28_CFG;

+    __IO uint32_t GPIO_29_CFG;

+    __IO uint32_t GPIO_30_CFG;

+    __IO uint32_t GPIO_31_CFG;

+    __IO uint32_t GPIO_IRQ;

+    __I  uint32_t GPIO_IN;

+    __IO uint32_t GPIO_OUT;

+} GPIO_TypeDef;

+

+typedef struct

+{

+    __IO uint32_t GPIO_0_CFG[32];

+    __IO uint32_t GPIO_1_CFG[32];

+    __IO uint32_t GPIO_2_CFG[32];

+    __IO uint32_t GPIO_3_CFG[32];

+    __IO uint32_t GPIO_4_CFG[32];

+    __IO uint32_t GPIO_5_CFG[32];

+    __IO uint32_t GPIO_6_CFG[32];

+    __IO uint32_t GPIO_7_CFG[32];

+    __IO uint32_t GPIO_8_CFG[32];

+    __IO uint32_t GPIO_9_CFG[32];

+    __IO uint32_t GPIO_10_CFG[32];

+    __IO uint32_t GPIO_11_CFG[32];

+    __IO uint32_t GPIO_12_CFG[32];

+    __IO uint32_t GPIO_13_CFG[32];

+    __IO uint32_t GPIO_14_CFG[32];

+    __IO uint32_t GPIO_15_CFG[32];

+    __IO uint32_t GPIO_16_CFG[32];

+    __IO uint32_t GPIO_17_CFG[32];

+    __IO uint32_t GPIO_18_CFG[32];

+    __IO uint32_t GPIO_19_CFG[32];

+    __IO uint32_t GPIO_20_CFG[32];

+    __IO uint32_t GPIO_21_CFG[32];

+    __IO uint32_t GPIO_22_CFG[32];

+    __IO uint32_t GPIO_23_CFG[32];

+    __IO uint32_t GPIO_24_CFG[32];

+    __IO uint32_t GPIO_25_CFG[32];

+    __IO uint32_t GPIO_26_CFG[32];

+    __IO uint32_t GPIO_27_CFG[32];

+    __IO uint32_t GPIO_28_CFG[32];

+    __IO uint32_t GPIO_29_CFG[32];

+    __IO uint32_t GPIO_30_CFG[32];

+    __IO uint32_t GPIO_31_CFG[32];

+    __IO uint32_t GPIO_IRQ[32];

+    __I  uint32_t GPIO_IN[32];

+    __IO uint32_t GPIO_OUT[32];

+} GPIO_BitBand_TypeDef;

+

+

+/*----------------------------------------------------------------------------*/

+/*----------------------------------- RTC ------------------------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    __IO uint32_t COUNTER0_REG;

+    __IO uint32_t COUNTER1_REG;

+    __IO uint32_t COUNTER2_REG;

+    __IO uint32_t COUNTER3_REG;

+    __IO uint32_t COUNTER4_REG;

+

+    __IO uint32_t RESERVED0[3];

+    

+    __IO uint32_t MATCHREG0_REG;

+    __IO uint32_t MATCHREG1_REG;

+    __IO uint32_t MATCHREG2_REG;

+    __IO uint32_t MATCHREG3_REG;

+    __IO uint32_t MATCHREG4_REG;

+

+    __IO uint32_t RESERVED1[3];

+    

+    __IO uint32_t MATCHBITS0_REG;

+    __IO uint32_t MATCHBITS1_REG;

+    __IO uint32_t MATCHBITS2_REG;

+    __IO uint32_t MATCHBITS3_REG;

+    __IO uint32_t MATCHBITS4_REG;

+

+    __IO uint32_t RESERVED2[3];

+    

+    __IO uint32_t CTRL_STAT_REG;

+} RTC_TypeDef;

+

+/*----------------------------------------------------------------------------*/

+/*---------------------------------- Timer -----------------------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    __I  uint32_t TIM1_VAL;

+    __IO uint32_t TIM1_LOADVAL;

+    __IO uint32_t TIM1_BGLOADVAL;

+    __IO uint32_t TIM1_CTRL;

+    __IO uint32_t TIM1_RIS;

+    __I  uint32_t TIM1_MIS;

+	

+    __I  uint32_t TIM2_VAL;

+    __IO uint32_t TIM2_LOADVAL;

+    __IO uint32_t TIM2_BGLOADVAL;

+    __IO uint32_t TIM2_CTRL;

+    __IO uint32_t TIM2_RIS;

+    __I  uint32_t TIM2_MIS;

+	

+    __I  uint32_t TIM64_VAL_U;

+    __I  uint32_t TIM64_VAL_L;

+    __IO uint32_t TIM64_LOADVAL_U;

+    __IO uint32_t TIM64_LOADVAL_L;

+    __IO uint32_t TIM64_BGLOADVAL_U;

+    __IO uint32_t TIM64_BGLOADVAL_L;

+    __IO uint32_t TIM64_CTRL;

+    __IO uint32_t TIM64_RIS;

+    __I  uint32_t TIM64_MIS;

+    __IO uint32_t TIM64_MODE;

+} TIMER_TypeDef;

+

+/*------------------------------------------------------------------------------

+ * Timer bit band

+ */

+typedef struct

+{

+    __I  uint32_t TIM1_VALUE_BIT[32];

+    __IO uint32_t TIM1_LOADVAL[32];

+    __IO uint32_t TIM1_BGLOADVAL[32];

+    

+    __IO uint32_t TIM1ENABLE;

+    __IO uint32_t TIM1MODE;

+    __IO uint32_t TIM1INTEN;

+    __IO uint32_t TIM1_CTRL_RESERVED[29];

+    __IO uint32_t TIM1_RIS[32];

+    __I  uint32_t TIM1_MIS[32];

+	

+    __I  uint32_t TIM2_VALUE[32];

+    __IO uint32_t TIM2_LOADVAL[32];

+    __IO uint32_t TIM2_BGLOADVAL[32];

+    

+    __IO uint32_t TIM2ENABLE;

+    __IO uint32_t TIM2MODE;

+    __IO uint32_t TIM2INTEN;

+    __IO uint32_t TIM2_CTRL[29];

+    __IO uint32_t TIM2_RIS[32];

+    __I  uint32_t TIM2_MIS[32];

+	

+    __I  uint32_t TIM64VALUEU[32];

+    __I  uint32_t TIM64VALUEL[32];

+    __IO uint32_t TIM64LOADVALUEU[32];

+    __IO uint32_t TIM64LOADVALUEL[32];

+    __IO uint32_t TIM64BGLOADVALUEU[32];

+    __IO uint32_t TIM64BGLOADVALUEL[32];

+    __IO uint32_t TIM64ENABLE;

+    __IO uint32_t TIM64MODE;

+    __IO uint32_t TIM64INTEN;

+    __IO uint32_t TIM64_CTRL[29];

+    __IO uint32_t TIM64_RIS[32];

+    __I  uint32_t TIM64_MIS[32];

+    __IO uint32_t TIM64_MODE[32];

+} TIMER_BitBand_TypeDef;

+

+/*----------------------------------------------------------------------------*/

+/*--------------------------------- Watchdog ---------------------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    __I  uint32_t WDOGVALUE;

+    __IO uint32_t WDOGLOAD;

+    __IO uint32_t WDOGMVRP;

+    __O  uint32_t WDOGREFRESH;

+    __IO uint32_t WDOGENABLE;

+    __IO uint32_t WDOGCONTROL;

+    __I  uint32_t WDOGSTATUS;

+    __IO uint32_t WDOGRIS;

+    __I  uint32_t WDOGMIS;

+} WATCHDOG_TypeDef;

+

+/*----------------------------------------------------------------------------*/

+/*----------------------------- Real Time Clock ------------------------------*/

+/*----------------------------------------------------------------------------*/

+

+/*----------------------------------------------------------------------------*/

+/*----------------------------- Peripherals DMA ------------------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    __IO uint32_t CRTL;

+    __IO uint32_t STATUS;

+    __IO uint32_t BUFFER_A_SRC_ADDR;

+    __IO uint32_t BUFFER_A_DEST_ADDR;

+    __IO uint32_t BUFFER_A_TRANSFER_COUNT;

+    __IO uint32_t BUFFER_B_SRC_ADDR;

+    __IO uint32_t BUFFER_B_DEST_ADDR;

+    __IO uint32_t BUFFER_B_TRANSFER_COUNT;

+} PDMA_Channel_TypeDef;

+

+typedef struct

+{

+    __IO uint32_t RATIO_HIGH_LOW;

+    __IO uint32_t BUFFER_STATUS;

+	     uint32_t RESERVED[6];

+    PDMA_Channel_TypeDef CHANNEL[8];

+} PDMA_TypeDef;

+

+/*----------------------------------------------------------------------------*/

+/*------------------------------ Ethernet MAC --------------------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    __IO uint32_t CSR0;

+         uint32_t RESERVED0;

+    __IO uint32_t CSR1;

+         uint32_t RESERVED1;

+    __IO uint32_t CSR2;

+         uint32_t RESERVED2;

+    __IO uint32_t CSR3;

+         uint32_t RESERVED3;

+    __IO uint32_t CSR4;

+         uint32_t RESERVED4;

+    __IO uint32_t CSR5;

+         uint32_t RESERVED5;

+    __IO uint32_t CSR6;

+         uint32_t RESERVED6;

+    __IO uint32_t CSR7;

+         uint32_t RESERVED7;

+    __IO uint32_t CSR8;

+         uint32_t RESERVED8;

+    __IO uint32_t CSR9;

+         uint32_t RESERVED9;

+         uint32_t RESERVED10;

+         uint32_t RESERVED11;

+    __IO uint32_t CSR11;

+} MAC_TypeDef;

+

+/*----------------------------------------------------------------------------*/

+/*---------------------- Analog Conversion Engine (ACE) ----------------------*/

+/*----------------------------------------------------------------------------*/

+/* Analog quad configuration */

+typedef struct

+{

+    __IO uint8_t b0;

+         uint8_t reserved0_0;

+         uint16_t reserved0_1;

+    __IO uint8_t b1;

+         uint8_t reserved1_0;

+         uint16_t reserved1_1;

+    __IO uint8_t b2;

+         uint8_t reserved2_0;

+         uint16_t reserved2_1;

+    __IO uint8_t b3;

+         uint8_t reserved3_0;

+         uint16_t reserved3_1;

+    __IO uint8_t b4;

+         uint8_t reserved4_0;

+         uint16_t reserved4_1;

+    __IO uint8_t b5;

+         uint8_t reserved5_0;

+         uint16_t reserved5_1;

+    __IO uint8_t b6;

+         uint8_t reserved6_0;

+         uint16_t reserved6_1;

+    __IO uint8_t b7;

+         uint8_t reserved7_0;

+         uint16_t reserved7_1;

+    __IO uint8_t b8;

+         uint8_t reserved8_0;

+         uint16_t reserved8_1;

+    __IO uint8_t b9;

+         uint8_t reserved9_0;

+         uint16_t reserved9_1;

+    __IO uint8_t b10;

+         uint8_t reserved10_0;

+         uint16_t reserved10_1;

+    __IO uint8_t b11;

+         uint8_t reserved11_0;

+         uint16_t reserved11_1;

+} AQ_config_t;

+

+/* ACE memory map layout */

+typedef struct

+{

+    __O  uint32_t NOP;

+    __IO uint32_t SSE_TS_CTRL;

+    __IO uint32_t ADC_SYNC_CONV;

+    __IO uint32_t ANA_COMM_CTRL;

+    __IO uint32_t DAC_SYNC_CTRL;

+    __IO uint32_t PDMA_REQUEST;

+	     uint32_t RESERVED0[10];

+    __O  uint32_t PC0_LO;

+    __O  uint32_t PC0_HI;

+    __IO uint32_t PC0_CTRL;

+    __IO uint32_t PC0_DLY;

+    __IO uint32_t ADC0_CONV_CTRL;

+    __IO uint32_t ADC0_STC;

+    __IO uint32_t ADC0_TVC;

+    __IO uint32_t ADC0_MISC_CTRL;

+    __IO uint32_t DAC0_CTRL;

+    __IO uint32_t DAC0_BYTE0;

+    __IO uint32_t DAC0_BYTE1;

+    __IO uint32_t DAC0_BYTE2;

+    __IO uint32_t LC0;

+    __O  uint32_t LC0_JMP_LO;

+    __O  uint32_t LC0_JMP_HI;

+    __O  uint32_t PC0_FLAGS;

+    __O  uint32_t PC1_LO;

+    __O  uint32_t PC1_HI;

+    __IO uint32_t PC1_CTRL;

+    __IO uint32_t PC1_DLY;

+    __IO uint32_t ADC1_CONV_CTRL;

+    __IO uint32_t ADC1_STC;

+    __IO uint32_t ADC1_TVC;

+    __IO uint32_t ADC1_MISC_CTRL;

+    __IO uint32_t DAC1_CTRL;

+    __IO uint32_t DAC1_BYTE0;

+    __IO uint32_t DAC1_BYTE1;

+    __IO uint32_t DAC1_BYTE2;

+    __IO uint32_t LC1;

+    __O  uint32_t LC1_JMP_LO;

+    __O  uint32_t LC1_JMP_HI;

+    __O  uint32_t PC1_FLAGS;

+    __O  uint32_t PC2_LO;

+    __O  uint32_t PC2_HI;

+    __IO uint32_t PC2_CTRL;

+    __IO uint32_t PC2_DLY;

+    __IO uint32_t ADC2_CONV_CTRL;

+    __IO uint32_t ADC2_STC;

+    __IO uint32_t ADC2_TVC;

+    __IO uint32_t ADC2_MISC_CTRL;

+    __IO uint32_t DAC2_CTRL;

+    __IO uint32_t DAC2_BYTE0;

+    __IO uint32_t DAC2_BYTE1;

+    __IO uint32_t DAC2_BYTE2;

+    __IO uint32_t LC2;

+    __O  uint32_t LC2_JMP_LO;

+    __O  uint32_t LC2_JMP_HI;

+    __O  uint32_t PC2_FLAGS;

+	     uint32_t RESERVED1;

+		 uint32_t RESERVED2;

+    __IO uint32_t SSE_RAM_LO_IDATA;

+    __IO uint32_t SSE_RAM_HI_IDATA;

+	     uint32_t RESERVED3[61];

+         AQ_config_t ACB_DATA[6];        

+	     uint32_t RESERVED4[59];

+    __IO uint32_t SSE_PC0;

+    __IO uint32_t SSE_PC1;

+    __IO uint32_t SSE_PC2;

+	     uint32_t RESERVED5[57];

+    __IO uint32_t SSE_DAC0_BYTES01;

+    __IO uint32_t SSE_DAC1_BYTES01;

+    __IO uint32_t SSE_DAC2_BYTES01;

+	     uint32_t RESERVED6[61];

+    __O  uint32_t SSE_ADC0_RESULTS;

+    __O  uint32_t SSE_ADC1_RESULTS;

+    __O  uint32_t SSE_ADC2_RESULTS;

+		 uint32_t RESERVED7[61];

+    __O  uint32_t SSE_PDMA_DATAIN;

+		 uint32_t RESERVED8[63];

+    __IO uint32_t SSE_RAM_DATA[512];

+    __I  uint32_t ADC0_STATUS;

+    __I  uint32_t ADC1_STATUS;

+    __I  uint32_t ADC2_STATUS;

+    __I  uint32_t COMPARATOR_STATUS;

+	     uint32_t RESERVED9[124];

+    __IO uint32_t SSE_IRQ_EN;

+    __I  uint32_t SSE_IRQ;

+    __O  uint32_t SSE_IRQ_CLR;

+    __IO uint32_t COMP_IRQ_EN;

+    __I  uint32_t COMP_IRQ;

+    __O  uint32_t COMP_IRQ_CLR;

+    __IO uint32_t PPE_FIFO_IRQ_EN;

+    __I  uint32_t PPE_FIFO_IRQ;

+    __O  uint32_t PPE_FIFO_IRQ_CLR;

+    __IO uint32_t PPE_FLAGS0_IRQ_EN;

+    __I  uint32_t PPE_FLAGS0_IRQ;

+    __O  uint32_t PPE_FLAGS0_IRQ_CLR;

+    __IO uint32_t PPE_FLAGS1_IRQ_EN;

+    __I  uint32_t PPE_FLAGS1_IRQ;

+    __O  uint32_t PPE_FLAGS1_IRQ_CLR;

+    __IO uint32_t PPE_FLAGS2_IRQ_EN;

+    __I  uint32_t PPE_FLAGS2_IRQ;

+    __O  uint32_t PPE_FLAGS2_IRQ_CLR;

+    __IO uint32_t PPE_FLAGS3_IRQ_EN;

+    __I  uint32_t PPE_FLAGS3_IRQ;

+    __O  uint32_t PPE_FLAGS3_IRQ_CLR;

+    __IO uint32_t PPE_SFFLAGS_IRQ_EN;

+    __I  uint32_t PPE_SFFLAGS_IRQ;

+    __O  uint32_t PPE_SFFLAGS_IRQ_CLR;

+    __IO uint32_t FPGA_FLAGS_SEL;

+	     uint32_t RESERVED10[39];

+    __IO uint32_t PPE_PDMA_CTRL;

+    __I  uint32_t PDMA_STATUS;

+    __IO uint32_t PPE_PDMA_DATAOUT;

+	     uint32_t RESERVED11[61];

+    __I  uint32_t PPE_NOP;

+    __IO uint32_t PPE_CTRL;

+    __IO uint32_t PPE_PC_ETC;

+    __IO uint32_t PPE_SF;

+    __IO uint32_t PPE_SCRATCH;

+         uint32_t RESERVED12;

+    __IO uint32_t ALU_CTRL;

+    __I  uint32_t ALU_STATUS;

+    __IO uint32_t ALU_A;

+         uint32_t RESERVED50;

+    __IO uint32_t ALU_B;

+         uint32_t RESERVED53;

+    __IO uint32_t ALU_C;

+         uint32_t RESERVED51;

+    __IO uint32_t ALU_D;

+         uint32_t RESERVED52;

+    __IO uint32_t ALU_E;

+         uint32_t RESERVED54;

+    __IO uint32_t PPE_FPTR;

+         uint32_t RESERVED55;

+    __IO uint32_t PPE_FLAGS0;

+    __IO uint32_t PPE_FLAGS1;

+    __IO uint32_t PPE_FLAGS2;

+    __IO uint32_t PPE_FLAGS3;

+    __IO uint32_t PPE_SFFLAGS;

+         uint32_t RESERVED13[11];

+    __IO uint32_t ADC0_FIFO_CTRL;

+    __I  uint32_t ADC0_FIFO_STATUS;

+    __IO uint32_t ADC0_FIFO_DATA;

+    __IO uint32_t ADC1_FIFO_CTRL;

+    __I  uint32_t ADC1_FIFO_STATUS;

+    __IO uint32_t ADC1_FIFO_DATA;

+    __IO uint32_t ADC2_FIFO_CTRL;

+    __I  uint32_t ADC2_FIFO_STATUS;

+    __IO uint32_t ADC2_FIFO_DATA;

+         uint32_t RESERVED14[19];

+    __I  uint32_t ADC0_FIFO_DATA_PEEK;

+    __I  uint32_t ADC0_FIFO_DATA0;

+    __I  uint32_t ADC0_FIFO_DATA1;

+    __I  uint32_t ADC0_FIFO_DATA2;

+    __I  uint32_t ADC0_FIFO_DATA3;

+    __I  uint32_t ADC1_FIFO_DATA_PEEK;

+    __I  uint32_t ADC1_FIFO_DATA0;

+    __I  uint32_t ADC1_FIFO_DATA1;

+    __I  uint32_t ADC1_FIFO_DATA2;

+    __I  uint32_t ADC1_FIFO_DATA3;

+    __I  uint32_t ADC2_FIFO_DATA_PEEK;

+    __I  uint32_t ADC2_FIFO_DATA0;

+    __I  uint32_t ADC2_FIFO_DATA1;

+    __I  uint32_t ADC2_FIFO_DATA2;

+    __I  uint32_t ADC2_FIFO_DATA3;

+		 uint32_t RESERVED15[177];  

+    __IO uint32_t PPE_RAM_DATA[512];

+} ACE_TypeDef;

+

+/*----------------------------------------------------------------------------*/

+/*------------------------ In Application Programming ------------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    __IO uint32_t IAP_IR;

+    __IO uint32_t IAP_DR2;

+    __IO uint32_t IAP_DR3;

+    __IO uint32_t IAP_DR5;

+    __IO uint32_t IAP_DR26;

+    __IO uint32_t IAP_DR32;

+    __IO uint32_t IAP_DR;

+    __IO uint32_t IAP_DR_LENGTH;

+    __IO uint32_t IAP_TAP_NEW_STATE;

+    __IO uint32_t IAP_TAP_CONTROL;

+    __I  uint32_t IAP_STATUS;

+} IAP_TypeDef;

+

+/*----------------------------------------------------------------------------*/

+/*---------------------- eNVM Special Function Registers ---------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    __IO uint32_t STATUS;

+    __IO uint32_t CONTROL;

+    __IO uint32_t ENABLE;

+         uint32_t RESERVED0;

+    __IO uint32_t CONFIG_0;

+    __IO uint32_t CONFIG_1;

+    __IO uint32_t PAGE_STATUS_0;

+    __IO uint32_t PAGE_STATUS_1;

+    __IO uint32_t SEGMENT;

+	__IO uint32_t ENVM_SELECT;

+} NVM_TypeDef;

+

+/*----------------------------------------------------------------------------*/

+/*---------------------- eNVM Special Function Registers ---------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    __IO uint32_t MSSIRQ_EN0;

+    __IO uint32_t MSSIRQ_EN1;

+    __IO uint32_t MSSIRQ_EN2;

+    __IO uint32_t MSSIRQ_EN3;

+    __IO uint32_t MSSIRQ_EN4;

+    __IO uint32_t MSSIRQ_EN5;

+    __IO uint32_t MSSIRQ_EN6;

+    __IO uint32_t MSSIRQ_EN7;

+    __I  uint32_t MSSIRQ_SRC0;

+    __I  uint32_t MSSIRQ_SRC1;

+    __I  uint32_t MSSIRQ_SRC2;

+    __I  uint32_t MSSIRQ_SRC3;

+    __I  uint32_t MSSIRQ_SRC4;

+    __I  uint32_t MSSIRQ_SRC5;

+    __I  uint32_t MSSIRQ_SRC6;

+    __I  uint32_t MSSIRQ_SRC7;

+    __IO uint32_t FIIC_MR;

+} MSS_IRQ_CTRL_TypeDef;

+

+/*----------------------------------------------------------------------------*/

+/*------------------------------ System Registers ----------------------------*/

+/*----------------------------------------------------------------------------*/

+typedef struct

+{

+    __IO uint32_t ESRAM_CR;

+    __IO uint32_t ENVM_CR;

+    __IO uint32_t ENVM_REMAP_SYS_CR;

+    __IO uint32_t ENVM_REMAP_FAB_CR;

+    __IO uint32_t FAB_PROT_SIZE_CR;

+    __IO uint32_t FAB_PROT_BASE_CR;

+    __IO uint32_t AHB_MATRIX_CR;

+    __IO uint32_t MSS_SR;

+    __IO uint32_t CLR_MSS_SR;

+    __IO uint32_t EFROM_CR;

+    __IO uint32_t IAP_CR;

+    __IO uint32_t SOFT_IRQ_CR;

+    __IO uint32_t SOFT_RST_CR;

+    __IO uint32_t DEVICE_SR;

+    __IO uint32_t SYSTICK_CR;

+    __IO uint32_t EMC_MUX_CR;

+    __IO uint32_t EMC_CS_0_CR;

+    __IO uint32_t EMC_CS_1_CR;

+    __IO uint32_t MSS_CLK_CR;

+    __IO uint32_t MSS_CCC_DIV_CR;

+    __IO uint32_t MSS_CCC_MUX_CR;

+    __IO uint32_t MSS_CCC_PLL_CR;

+    __IO uint32_t MSS_CCC_DLY_CR;

+    __IO uint32_t MSS_CCC_SR;

+    __IO uint32_t MSS_RCOSC_CR;

+    __IO uint32_t VRPSM_CR;

+    __IO uint32_t RESERVED;

+    __IO uint32_t FAB_IF_CR;

+    __IO uint32_t FAB_APB_HIWORD_DR;

+    __IO uint32_t LOOPBACK_CR;

+    __IO uint32_t MSS_IO_BANK_CR;

+    __IO uint32_t GPIN_SOURCE_CR;

+    __IO uint32_t TEST_SR;

+    __IO uint32_t RED_REP_ADDR0;

+    __I  uint32_t RED_REP_LOW_LOCS0;

+    __I  uint32_t RED_REP_HIGH_LOCS0;

+    __IO uint32_t RED_REP_ADDR1;

+    __I  uint32_t RED_REP_LOW_LOCS1;

+    __I  uint32_t RED_REP_HIGH_LOCS1;

+    __IO uint32_t FABRIC_CR;

+         uint32_t RESERVED1[24];

+    __IO uint32_t IOMUX_CR[83];

+} SYSREG_TypeDef;

+

+#define SYSREG_ENVM_SOFTRESET_MASK      (uint32_t)0x00000001

+#define SYSREG_ESRAM0_SOFTRESET_MASK    (uint32_t)0x00000002

+#define SYSREG_ESRAM1_SOFTRESET_MASK    (uint32_t)0x00000004

+#define SYSREG_EMC_SOFTRESET_MASK       (uint32_t)0x00000008

+#define SYSREG_MAC_SOFTRESET_MASK       (uint32_t)0x00000010

+#define SYSREG_PDMA_SOFTRESET_MASK      (uint32_t)0x00000020

+#define SYSREG_TIMER_SOFTRESET_MASK     (uint32_t)0x00000040

+#define SYSREG_UART0_SOFTRESET_MASK     (uint32_t)0x00000080

+#define SYSREG_UART1_SOFTRESET_MASK     (uint32_t)0x00000100

+#define SYSREG_SPI0_SOFTRESET_MASK      (uint32_t)0x00000200

+#define SYSREG_SPI1_SOFTRESET_MASK      (uint32_t)0x00000400

+#define SYSREG_I2C0_SOFTRESET_MASK      (uint32_t)0x00000800

+#define SYSREG_I2C1_SOFTRESET_MASK      (uint32_t)0x00001000

+#define SYSREG_ACE_SOFTRESET_MASK       (uint32_t)0x00002000

+#define SYSREG_GPIO_SOFTRESET_MASK      (uint32_t)0x00004000

+#define SYSREG_IAP_SOFTRESET_MASK       (uint32_t)0x00008000

+#define SYSREG_EXT_SOFTRESET_MASK       (uint32_t)0x00010000

+#define SYSREG_FPGA_SOFTRESET_MASK      (uint32_t)0x00020000

+#define SYSREG_F2M_RESET_ENABLE_MASK    (uint32_t)0x00040000        

+#define SYSREG_PADRESET_ENABLE_MASK     (uint32_t)0x00080000

+

+/******************************************************************************/

+/*                         Peripheral memory map                              */

+/******************************************************************************/

+#define UART0_BASE              0x40000000U

+#define SPI0_BASE               0x40001000U

+#define I2C0_BASE               0x40002000U

+#define MAC_BASE                0x40003000U

+#define PDMA_BASE               0x40004000U

+#define TIMER_BASE              0x40005000U

+#define WATCHDOG_BASE		    0x40006000U

+#define H2F_IRQ_CTRL_BASE       0x40007000U

+#define UART1_BASE              0x40010000U

+#define SPI1_BASE               0x40011000U

+#define I2C1_BASE               0x40012000U

+#define GPIO_BASE               0x40013000U

+#define RTC_BASE                0x40014100U

+#define FROM_BASE               0x40015000U

+#define IAP_BASE                0x40016000U

+#define ACE_BASE                0x40020000U

+#define FPGA_FABRIC_RAM_BASE    0x40040000U

+#define FPGA_FABRIC_BASE        0x40050000U

+#define ENVM_BASE               0x60000000U

+#define ENVM_REGS_BASE          0x60100000U

+#define SYSREG_BASE             0xE0042000U

+

+/******************************************************************************/

+/* bitband address calcualtion macro                             */

+/******************************************************************************/

+#define BITBAND_ADDRESS(X)  ((X & 0xF0000000U) + 0x02000000U + ((X & 0xFFFFFU) << 5))

+

+/******************************************************************************/

+/*                         Peripheral declaration                             */

+/******************************************************************************/

+#define UART0                ((UART_TypeDef *) UART0_BASE)

+#define UART0_BITBAND        ((UART_BitBand_TypeDef *) BITBAND_ADDRESS(UART0_BASE))

+#define SPI0                 ((SPI_TypeDef *) SPI0_BASE)

+#define SPI0_BITBAND         ((SPI_BitBand_TypeDef *) BITBAND_ADDRESS(SPI0_BASE))

+#define I2C0                 ((I2C_TypeDef *) I2C0_BASE)

+#define I2C0_BITBAND         ((I2C_BitBand_TypeDef *) BITBAND_ADDRESS(I2C0_BASE))

+#define MAC                  ((MAC_TypeDef *) MAC_BASE)

+#define PDMA                 ((PDMA_TypeDef *) PDMA_BASE)

+#define TIMER                ((TIMER_TypeDef *) TIMER_BASE)

+#define TIMER_BITBAND        ((TIMER_BitBand_TypeDef *) BITBAND_ADDRESS(TIMER_BASE))

+#define WATCHDOG             ((WATCHDOG_TypeDef *) WATCHDOG_BASE)

+#define MSS_IRQ_CTRL         ((MSS_IRQ_CTRL_TypeDef *) H2F_IRQ_CTRL_BASE)

+#define UART1                ((UART_TypeDef *) UART1_BASE)

+#define UART1_BITBAND        ((UART_BitBand_TypeDef *) BITBAND_ADDRESS(UART1_BASE))

+#define SPI1                 ((SPI_TypeDef *) SPI1_BASE)

+#define SPI1_BITBAND         ((SPI_BitBand_TypeDef *) BITBAND_ADDRESS(SPI1_BASE))

+#define I2C1                 ((I2C_TypeDef *) I2C1_BASE)

+#define I2C1_BITBAND         ((I2C_BitBand_TypeDef *) BITBAND_ADDRESS(I2C1_BASE))

+#define GPIO                 ((GPIO_TypeDef *) GPIO_BASE)

+#define GPIO_BITBAND         ((GPIO_BitBand_TypeDef *) BITBAND_ADDRESS(GPIO_BASE))

+#define RTC                  ((RTC_TypeDef *) RTC_BASE)

+#define FROM                 ((void *) FROM_BASE)

+#define IAP                  ((IAP_TypeDef *) IAP_BASE)

+#define ACE                  ((ACE_TypeDef *) ACE_BASE)

+#define FPGA_FABRIC_RAM      ((void *) FPGA_FABRIC_RAM_BASE)

+#define FPGA_FABRIC          ((void *) FPGA_FABRIC_BASE)

+#define ENVM                 ((void *) ENVM_BASE)

+#define ENVM_REGS            ((NVM_TypeDef *) ENVM_REGS_BASE)

+#define SYSREG               ((SYSREG_TypeDef *) SYSREG_BASE)

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif	/* __A2FXXXM3_H__ */

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.c
new file mode 100644
index 0000000..56fddc5
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.c
@@ -0,0 +1,784 @@
+/**************************************************************************//**

+ * @file     core_cm3.c

+ * @brief    CMSIS Cortex-M3 Core Peripheral Access Layer Source File

+ * @version  V1.30

+ * @date     30. October 2009

+ *

+ * @note

+ * Copyright (C) 2009 ARM Limited. All rights reserved.

+ *

+ * @par

+ * ARM Limited (ARM) is supplying this software for use with Cortex-M 

+ * processor based microcontrollers.  This file can be freely distributed 

+ * within development tools that are supporting such ARM based processors. 

+ *

+ * @par

+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED

+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF

+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.

+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR

+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.

+ *

+ ******************************************************************************/

+

+#include <stdint.h>

+

+/* define compiler specific symbols */

+#if defined ( __CC_ARM   )

+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */

+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */

+

+#elif defined ( __ICCARM__ )

+  #define __ASM           __asm                                       /*!< asm keyword for IAR Compiler          */

+  #define __INLINE        inline                                      /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */

+

+#elif defined   (  __GNUC__  )

+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */

+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */

+

+#elif defined   (  __TASKING__  )

+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */

+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */

+

+#endif

+

+

+/* ###################  Compiler specific Intrinsics  ########################### */

+

+#if defined ( __CC_ARM   ) /*------------------RealView Compiler -----------------*/

+/* ARM armcc specific functions */

+

+/**

+ * @brief  Return the Process Stack Pointer

+ *

+ * @return ProcessStackPointer

+ *

+ * Return the actual process stack pointer

+ */

+__ASM uint32_t __get_PSP(void)

+{

+  mrs r0, psp

+  bx lr

+}

+

+/**

+ * @brief  Set the Process Stack Pointer

+ *

+ * @param  topOfProcStack  Process Stack Pointer

+ *

+ * Assign the value ProcessStackPointer to the MSP 

+ * (process stack pointer) Cortex processor register

+ */

+__ASM void __set_PSP(uint32_t topOfProcStack)

+{

+  msr psp, r0

+  bx lr

+}

+

+/**

+ * @brief  Return the Main Stack Pointer

+ *

+ * @return Main Stack Pointer

+ *

+ * Return the current value of the MSP (main stack pointer)

+ * Cortex processor register

+ */

+__ASM uint32_t __get_MSP(void)

+{

+  mrs r0, msp

+  bx lr

+}

+

+/**

+ * @brief  Set the Main Stack Pointer

+ *

+ * @param  topOfMainStack  Main Stack Pointer

+ *

+ * Assign the value mainStackPointer to the MSP 

+ * (main stack pointer) Cortex processor register

+ */

+__ASM void __set_MSP(uint32_t mainStackPointer)

+{

+  msr msp, r0

+  bx lr

+}

+

+/**

+ * @brief  Reverse byte order in unsigned short value

+ *

+ * @param   value  value to reverse

+ * @return         reversed value

+ *

+ * Reverse byte order in unsigned short value

+ */

+__ASM uint32_t __REV16(uint16_t value)

+{

+  rev16 r0, r0

+  bx lr

+}

+

+/**

+ * @brief  Reverse byte order in signed short value with sign extension to integer

+ *

+ * @param   value  value to reverse

+ * @return         reversed value

+ *

+ * Reverse byte order in signed short value with sign extension to integer

+ */

+__ASM int32_t __REVSH(int16_t value)

+{

+  revsh r0, r0

+  bx lr

+}

+

+

+#if (__ARMCC_VERSION < 400000)

+

+/**

+ * @brief  Remove the exclusive lock created by ldrex

+ *

+ * Removes the exclusive lock which is created by ldrex.

+ */

+__ASM void __CLREX(void)

+{

+  clrex

+}

+

+/**

+ * @brief  Return the Base Priority value

+ *

+ * @return BasePriority

+ *

+ * Return the content of the base priority register

+ */

+__ASM uint32_t  __get_BASEPRI(void)

+{

+  mrs r0, basepri

+  bx lr

+}

+

+/**

+ * @brief  Set the Base Priority value

+ *

+ * @param  basePri  BasePriority

+ *

+ * Set the base priority register

+ */

+__ASM void __set_BASEPRI(uint32_t basePri)

+{

+  msr basepri, r0

+  bx lr

+}

+

+/**

+ * @brief  Return the Priority Mask value

+ *

+ * @return PriMask

+ *

+ * Return state of the priority mask bit from the priority mask register

+ */

+__ASM uint32_t __get_PRIMASK(void)

+{

+  mrs r0, primask

+  bx lr

+}

+

+/**

+ * @brief  Set the Priority Mask value

+ *

+ * @param  priMask  PriMask

+ *

+ * Set the priority mask bit in the priority mask register

+ */

+__ASM void __set_PRIMASK(uint32_t priMask)

+{

+  msr primask, r0

+  bx lr

+}

+

+/**

+ * @brief  Return the Fault Mask value

+ *

+ * @return FaultMask

+ *

+ * Return the content of the fault mask register

+ */

+__ASM uint32_t  __get_FAULTMASK(void)

+{

+  mrs r0, faultmask

+  bx lr

+}

+

+/**

+ * @brief  Set the Fault Mask value

+ *

+ * @param  faultMask  faultMask value

+ *

+ * Set the fault mask register

+ */

+__ASM void __set_FAULTMASK(uint32_t faultMask)

+{

+  msr faultmask, r0

+  bx lr

+}

+

+/**

+ * @brief  Return the Control Register value

+ * 

+ * @return Control value

+ *

+ * Return the content of the control register

+ */

+__ASM uint32_t __get_CONTROL(void)

+{

+  mrs r0, control

+  bx lr

+}

+

+/**

+ * @brief  Set the Control Register value

+ *

+ * @param  control  Control value

+ *

+ * Set the control register

+ */

+__ASM void __set_CONTROL(uint32_t control)

+{

+  msr control, r0

+  bx lr

+}

+

+#endif /* __ARMCC_VERSION  */ 

+

+

+

+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/

+/* IAR iccarm specific functions */

+#pragma diag_suppress=Pe940

+

+/**

+ * @brief  Return the Process Stack Pointer

+ *

+ * @return ProcessStackPointer

+ *

+ * Return the actual process stack pointer

+ */

+uint32_t __get_PSP(void)

+{

+  __ASM("mrs r0, psp");

+  __ASM("bx lr");

+}

+

+/**

+ * @brief  Set the Process Stack Pointer

+ *

+ * @param  topOfProcStack  Process Stack Pointer

+ *

+ * Assign the value ProcessStackPointer to the MSP 

+ * (process stack pointer) Cortex processor register

+ */

+void __set_PSP(uint32_t topOfProcStack)

+{

+  __ASM("msr psp, r0");

+  __ASM("bx lr");

+}

+

+/**

+ * @brief  Return the Main Stack Pointer

+ *

+ * @return Main Stack Pointer

+ *

+ * Return the current value of the MSP (main stack pointer)

+ * Cortex processor register

+ */

+uint32_t __get_MSP(void)

+{

+  __ASM("mrs r0, msp");

+  __ASM("bx lr");

+}

+

+/**

+ * @brief  Set the Main Stack Pointer

+ *

+ * @param  topOfMainStack  Main Stack Pointer

+ *

+ * Assign the value mainStackPointer to the MSP 

+ * (main stack pointer) Cortex processor register

+ */

+void __set_MSP(uint32_t topOfMainStack)

+{

+  __ASM("msr msp, r0");

+  __ASM("bx lr");

+}

+

+/**

+ * @brief  Reverse byte order in unsigned short value

+ *

+ * @param  value  value to reverse

+ * @return        reversed value

+ *

+ * Reverse byte order in unsigned short value

+ */

+uint32_t __REV16(uint16_t value)

+{

+  __ASM("rev16 r0, r0");

+  __ASM("bx lr");

+}

+

+/**

+ * @brief  Reverse bit order of value

+ *

+ * @param  value  value to reverse

+ * @return        reversed value

+ *

+ * Reverse bit order of value

+ */

+uint32_t __RBIT(uint32_t value)

+{

+  __ASM("rbit r0, r0");

+  __ASM("bx lr");

+}

+

+/**

+ * @brief  LDR Exclusive (8 bit)

+ *

+ * @param  *addr  address pointer

+ * @return        value of (*address)

+ *

+ * Exclusive LDR command for 8 bit values)

+ */

+uint8_t __LDREXB(uint8_t *addr)

+{

+  __ASM("ldrexb r0, [r0]");

+  __ASM("bx lr"); 

+}

+

+/**

+ * @brief  LDR Exclusive (16 bit)

+ *

+ * @param  *addr  address pointer

+ * @return        value of (*address)

+ *

+ * Exclusive LDR command for 16 bit values

+ */

+uint16_t __LDREXH(uint16_t *addr)

+{

+  __ASM("ldrexh r0, [r0]");

+  __ASM("bx lr");

+}

+

+/**

+ * @brief  LDR Exclusive (32 bit)

+ *

+ * @param  *addr  address pointer

+ * @return        value of (*address)

+ *

+ * Exclusive LDR command for 32 bit values

+ */

+uint32_t __LDREXW(uint32_t *addr)

+{

+  __ASM("ldrex r0, [r0]");

+  __ASM("bx lr");

+}

+

+/**

+ * @brief  STR Exclusive (8 bit)

+ *

+ * @param  value  value to store

+ * @param  *addr  address pointer

+ * @return        successful / failed

+ *

+ * Exclusive STR command for 8 bit values

+ */

+uint32_t __STREXB(uint8_t value, uint8_t *addr)

+{

+  __ASM("strexb r0, r0, [r1]");

+  __ASM("bx lr");

+}

+

+/**

+ * @brief  STR Exclusive (16 bit)

+ *

+ * @param  value  value to store

+ * @param  *addr  address pointer

+ * @return        successful / failed

+ *

+ * Exclusive STR command for 16 bit values

+ */

+uint32_t __STREXH(uint16_t value, uint16_t *addr)

+{

+  __ASM("strexh r0, r0, [r1]");

+  __ASM("bx lr");

+}

+

+/**

+ * @brief  STR Exclusive (32 bit)

+ *

+ * @param  value  value to store

+ * @param  *addr  address pointer

+ * @return        successful / failed

+ *

+ * Exclusive STR command for 32 bit values

+ */

+uint32_t __STREXW(uint32_t value, uint32_t *addr)

+{

+  __ASM("strex r0, r0, [r1]");

+  __ASM("bx lr");

+}

+

+#pragma diag_default=Pe940

+

+

+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/

+/* GNU gcc specific functions */

+

+/**

+ * @brief  Return the Process Stack Pointer

+ *

+ * @return ProcessStackPointer

+ *

+ * Return the actual process stack pointer

+ */

+uint32_t __get_PSP(void) __attribute__( ( naked ) );

+uint32_t __get_PSP(void)

+{

+  uint32_t result=0;

+

+  __ASM volatile ("MRS %0, psp\n\t" 

+                  "MOV r0, %0 \n\t"

+                  "BX  lr     \n\t"  : "=r" (result) );

+  return(result);

+}

+

+/**

+ * @brief  Set the Process Stack Pointer

+ *

+ * @param  topOfProcStack  Process Stack Pointer

+ *

+ * Assign the value ProcessStackPointer to the MSP 

+ * (process stack pointer) Cortex processor register

+ */

+void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) );

+void __set_PSP(uint32_t topOfProcStack)

+{

+  __ASM volatile ("MSR psp, %0\n\t"

+                  "BX  lr     \n\t" : : "r" (topOfProcStack) );

+}

+

+/**

+ * @brief  Return the Main Stack Pointer

+ *

+ * @return Main Stack Pointer

+ *

+ * Return the current value of the MSP (main stack pointer)

+ * Cortex processor register

+ */

+uint32_t __get_MSP(void) __attribute__( ( naked ) );

+uint32_t __get_MSP(void)

+{

+  uint32_t result=0;

+

+  __ASM volatile ("MRS %0, msp\n\t" 

+                  "MOV r0, %0 \n\t"

+                  "BX  lr     \n\t"  : "=r" (result) );

+  return(result);

+}

+

+/**

+ * @brief  Set the Main Stack Pointer

+ *

+ * @param  topOfMainStack  Main Stack Pointer

+ *

+ * Assign the value mainStackPointer to the MSP 

+ * (main stack pointer) Cortex processor register

+ */

+void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) );

+void __set_MSP(uint32_t topOfMainStack)

+{

+  __ASM volatile ("MSR msp, %0\n\t"

+                  "BX  lr     \n\t" : : "r" (topOfMainStack) );

+}

+

+/**

+ * @brief  Return the Base Priority value

+ *

+ * @return BasePriority

+ *

+ * Return the content of the base priority register

+ */

+uint32_t __get_BASEPRI(void)

+{

+  uint32_t result=0;

+  

+  __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );

+  return(result);

+}

+

+/**

+ * @brief  Set the Base Priority value

+ *

+ * @param  basePri  BasePriority

+ *

+ * Set the base priority register

+ */

+void __set_BASEPRI(uint32_t value)

+{

+  __ASM volatile ("MSR basepri, %0" : : "r" (value) );

+}

+

+/**

+ * @brief  Return the Priority Mask value

+ *

+ * @return PriMask

+ *

+ * Return state of the priority mask bit from the priority mask register

+ */

+uint32_t __get_PRIMASK(void)

+{

+  uint32_t result=0;

+

+  __ASM volatile ("MRS %0, primask" : "=r" (result) );

+  return(result);

+}

+

+/**

+ * @brief  Set the Priority Mask value

+ *

+ * @param  priMask  PriMask

+ *

+ * Set the priority mask bit in the priority mask register

+ */

+void __set_PRIMASK(uint32_t priMask)

+{

+  __ASM volatile ("MSR primask, %0" : : "r" (priMask) );

+}

+

+/**

+ * @brief  Return the Fault Mask value

+ *

+ * @return FaultMask

+ *

+ * Return the content of the fault mask register

+ */

+uint32_t __get_FAULTMASK(void)

+{

+  uint32_t result=0;

+  

+  __ASM volatile ("MRS %0, faultmask" : "=r" (result) );

+  return(result);

+}

+

+/**

+ * @brief  Set the Fault Mask value

+ *

+ * @param  faultMask  faultMask value

+ *

+ * Set the fault mask register

+ */

+void __set_FAULTMASK(uint32_t faultMask)

+{

+  __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );

+}

+

+/**

+ * @brief  Return the Control Register value

+* 

+*  @return Control value

+ *

+ * Return the content of the control register

+ */

+uint32_t __get_CONTROL(void)

+{

+  uint32_t result=0;

+

+  __ASM volatile ("MRS %0, control" : "=r" (result) );

+  return(result);

+}

+

+/**

+ * @brief  Set the Control Register value

+ *

+ * @param  control  Control value

+ *

+ * Set the control register

+ */

+void __set_CONTROL(uint32_t control)

+{

+  __ASM volatile ("MSR control, %0" : : "r" (control) );

+}

+

+

+/**

+ * @brief  Reverse byte order in integer value

+ *

+ * @param  value  value to reverse

+ * @return        reversed value

+ *

+ * Reverse byte order in integer value

+ */

+uint32_t __REV(uint32_t value)

+{

+  uint32_t result=0;

+  

+  __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );

+  return(result);

+}

+

+/**

+ * @brief  Reverse byte order in unsigned short value

+ *

+ * @param  value  value to reverse

+ * @return        reversed value

+ *

+ * Reverse byte order in unsigned short value

+ */

+uint32_t __REV16(uint16_t value)

+{

+  uint32_t result=0;

+  

+  __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );

+  return(result);

+}

+

+/**

+ * @brief  Reverse byte order in signed short value with sign extension to integer

+ *

+ * @param  value  value to reverse

+ * @return        reversed value

+ *

+ * Reverse byte order in signed short value with sign extension to integer

+ */

+int32_t __REVSH(int16_t value)

+{

+  uint32_t result=0;

+  

+  __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );

+  return(result);

+}

+

+/**

+ * @brief  Reverse bit order of value

+ *

+ * @param  value  value to reverse

+ * @return        reversed value

+ *

+ * Reverse bit order of value

+ */

+uint32_t __RBIT(uint32_t value)

+{

+  uint32_t result=0;

+  

+   __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );

+   return(result);

+}

+

+/**

+ * @brief  LDR Exclusive (8 bit)

+ *

+ * @param  *addr  address pointer

+ * @return        value of (*address)

+ *

+ * Exclusive LDR command for 8 bit value

+ */

+uint8_t __LDREXB(uint8_t *addr)

+{

+    uint8_t result=0;

+  

+   __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );

+   return(result);

+}

+

+/**

+ * @brief  LDR Exclusive (16 bit)

+ *

+ * @param  *addr  address pointer

+ * @return        value of (*address)

+ *

+ * Exclusive LDR command for 16 bit values

+ */

+uint16_t __LDREXH(uint16_t *addr)

+{

+    uint16_t result=0;

+  

+   __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );

+   return(result);

+}

+

+/**

+ * @brief  LDR Exclusive (32 bit)

+ *

+ * @param  *addr  address pointer

+ * @return        value of (*address)

+ *

+ * Exclusive LDR command for 32 bit values

+ */

+uint32_t __LDREXW(uint32_t *addr)

+{

+    uint32_t result=0;

+  

+   __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );

+   return(result);

+}

+

+/**

+ * @brief  STR Exclusive (8 bit)

+ *

+ * @param  value  value to store

+ * @param  *addr  address pointer

+ * @return        successful / failed

+ *

+ * Exclusive STR command for 8 bit values

+ */

+uint32_t __STREXB(uint8_t value, uint8_t *addr)

+{

+   uint32_t result=0;

+  

+   __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );

+   return(result);

+}

+

+/**

+ * @brief  STR Exclusive (16 bit)

+ *

+ * @param  value  value to store

+ * @param  *addr  address pointer

+ * @return        successful / failed

+ *

+ * Exclusive STR command for 16 bit values

+ */

+uint32_t __STREXH(uint16_t value, uint16_t *addr)

+{

+   uint32_t result=0;

+  

+   __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );

+   return(result);

+}

+

+/**

+ * @brief  STR Exclusive (32 bit)

+ *

+ * @param  value  value to store

+ * @param  *addr  address pointer

+ * @return        successful / failed

+ *

+ * Exclusive STR command for 32 bit values

+ */

+uint32_t __STREXW(uint32_t value, uint32_t *addr)

+{

+   uint32_t result=0;

+  

+   __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );

+   return(result);

+}

+

+

+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/

+/* TASKING carm specific functions */

+

+/*

+ * The CMSIS functions have been implemented as intrinsics in the compiler.

+ * Please use "carm -?i" to get an up to date list of all instrinsics,

+ * Including the CMSIS ones.

+ */

+

+#endif

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.h
new file mode 100644
index 0000000..e0565d7
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.h
@@ -0,0 +1,1818 @@
+/**************************************************************************//**

+ * @file     core_cm3.h

+ * @brief    CMSIS Cortex-M3 Core Peripheral Access Layer Header File

+ * @version  V1.30

+ * @date     30. October 2009

+ *

+ * @note

+ * Copyright (C) 2009 ARM Limited. All rights reserved.

+ *

+ * @par

+ * ARM Limited (ARM) is supplying this software for use with Cortex-M 

+ * processor based microcontrollers.  This file can be freely distributed 

+ * within development tools that are supporting such ARM based processors. 

+ *

+ * @par

+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED

+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF

+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.

+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR

+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.

+ *

+ ******************************************************************************/

+

+#ifndef __CM3_CORE_H__

+#define __CM3_CORE_H__

+

+/** @addtogroup CMSIS_CM3_core_LintCinfiguration CMSIS CM3 Core Lint Configuration

+ *

+ * List of Lint messages which will be suppressed and not shown:

+ *   - Error 10: \n

+ *     register uint32_t __regBasePri         __asm("basepri"); \n

+ *     Error 10: Expecting ';'

+ * .

+ *   - Error 530: \n

+ *     return(__regBasePri); \n

+ *     Warning 530: Symbol '__regBasePri' (line 264) not initialized

+ * . 

+ *   - Error 550: \n

+ *     __regBasePri = (basePri & 0x1ff); \n

+ *     Warning 550: Symbol '__regBasePri' (line 271) not accessed

+ * .

+ *   - Error 754: \n

+ *     uint32_t RESERVED0[24]; \n

+ *     Info 754: local structure member '<some, not used in the HAL>' (line 109, file ./cm3_core.h) not referenced

+ * .

+ *   - Error 750: \n

+ *     #define __CM3_CORE_H__ \n

+ *     Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced

+ * .

+ *   - Error 528: \n

+ *     static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n

+ *     Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced

+ * .

+ *   - Error 751: \n

+ *     } InterruptType_Type; \n

+ *     Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced

+ * .

+ * Note:  To re-enable a Message, insert a space before 'lint' *

+ *

+ */

+

+/*lint -save */

+/*lint -e10  */

+/*lint -e530 */

+/*lint -e550 */

+/*lint -e754 */

+/*lint -e750 */

+/*lint -e528 */

+/*lint -e751 */

+

+

+/** @addtogroup CMSIS_CM3_core_definitions CM3 Core Definitions

+  This file defines all structures and symbols for CMSIS core:

+    - CMSIS version number

+    - Cortex-M core registers and bitfields

+    - Cortex-M core peripheral base address

+  @{

+ */

+

+#ifdef __cplusplus

+ extern "C" {

+#endif 

+

+#define __CM3_CMSIS_VERSION_MAIN  (0x01)                                                       /*!< [31:16] CMSIS HAL main version */

+#define __CM3_CMSIS_VERSION_SUB   (0x30)                                                       /*!< [15:0]  CMSIS HAL sub version  */

+#define __CM3_CMSIS_VERSION       ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number       */

+

+#define __CORTEX_M                (0x03)                                                       /*!< Cortex core                    */

+

+#include <stdint.h>                           /* Include standard types */

+

+#if defined (__ICCARM__)

+  #include <intrinsics.h>                     /* IAR Intrinsics   */

+#endif

+

+

+#ifndef __NVIC_PRIO_BITS

+  #define __NVIC_PRIO_BITS    4               /*!< standard definition for NVIC Priority Bits */

+#endif

+

+

+

+

+/**

+ * IO definitions

+ *

+ * define access restrictions to peripheral registers

+ */

+

+#ifdef __cplusplus

+  #define     __I     volatile                /*!< defines 'read only' permissions      */

+#else

+  #define     __I     volatile const          /*!< defines 'read only' permissions      */

+#endif

+#define     __O     volatile                  /*!< defines 'write only' permissions     */

+#define     __IO    volatile                  /*!< defines 'read / write' permissions   */

+

+

+

+/*******************************************************************************

+ *                 Register Abstraction

+ ******************************************************************************/

+/** @addtogroup CMSIS_CM3_core_register CMSIS CM3 Core Register

+ @{

+*/

+

+

+/** @addtogroup CMSIS_CM3_NVIC CMSIS CM3 NVIC

+  memory mapped structure for Nested Vectored Interrupt Controller (NVIC)

+  @{

+ */

+typedef struct

+{

+  __IO uint32_t ISER[8];                      /*!< Offset: 0x000  Interrupt Set Enable Register           */

+       uint32_t RESERVED0[24];                                   

+  __IO uint32_t ICER[8];                      /*!< Offset: 0x080  Interrupt Clear Enable Register         */

+       uint32_t RSERVED1[24];                                    

+  __IO uint32_t ISPR[8];                      /*!< Offset: 0x100  Interrupt Set Pending Register          */

+       uint32_t RESERVED2[24];                                   

+  __IO uint32_t ICPR[8];                      /*!< Offset: 0x180  Interrupt Clear Pending Register        */

+       uint32_t RESERVED3[24];                                   

+  __IO uint32_t IABR[8];                      /*!< Offset: 0x200  Interrupt Active bit Register           */

+       uint32_t RESERVED4[56];                                   

+  __IO uint8_t  IP[240];                      /*!< Offset: 0x300  Interrupt Priority Register (8Bit wide) */

+       uint32_t RESERVED5[644];                                  

+  __O  uint32_t STIR;                         /*!< Offset: 0xE00  Software Trigger Interrupt Register     */

+}  NVIC_Type;                                               

+/*@}*/ /* end of group CMSIS_CM3_NVIC */

+

+

+/** @addtogroup CMSIS_CM3_SCB CMSIS CM3 SCB

+  memory mapped structure for System Control Block (SCB)

+  @{

+ */

+typedef struct

+{

+  __I  uint32_t CPUID;                        /*!< Offset: 0x00  CPU ID Base Register                                  */

+  __IO uint32_t ICSR;                         /*!< Offset: 0x04  Interrupt Control State Register                      */

+  __IO uint32_t VTOR;                         /*!< Offset: 0x08  Vector Table Offset Register                          */

+  __IO uint32_t AIRCR;                        /*!< Offset: 0x0C  Application Interrupt / Reset Control Register        */

+  __IO uint32_t SCR;                          /*!< Offset: 0x10  System Control Register                               */

+  __IO uint32_t CCR;                          /*!< Offset: 0x14  Configuration Control Register                        */

+  __IO uint8_t  SHP[12];                      /*!< Offset: 0x18  System Handlers Priority Registers (4-7, 8-11, 12-15) */

+  __IO uint32_t SHCSR;                        /*!< Offset: 0x24  System Handler Control and State Register             */

+  __IO uint32_t CFSR;                         /*!< Offset: 0x28  Configurable Fault Status Register                    */

+  __IO uint32_t HFSR;                         /*!< Offset: 0x2C  Hard Fault Status Register                            */

+  __IO uint32_t DFSR;                         /*!< Offset: 0x30  Debug Fault Status Register                           */

+  __IO uint32_t MMFAR;                        /*!< Offset: 0x34  Mem Manage Address Register                           */

+  __IO uint32_t BFAR;                         /*!< Offset: 0x38  Bus Fault Address Register                            */

+  __IO uint32_t AFSR;                         /*!< Offset: 0x3C  Auxiliary Fault Status Register                       */

+  __I  uint32_t PFR[2];                       /*!< Offset: 0x40  Processor Feature Register                            */

+  __I  uint32_t DFR;                          /*!< Offset: 0x48  Debug Feature Register                                */

+  __I  uint32_t ADR;                          /*!< Offset: 0x4C  Auxiliary Feature Register                            */

+  __I  uint32_t MMFR[4];                      /*!< Offset: 0x50  Memory Model Feature Register                         */

+  __I  uint32_t ISAR[5];                      /*!< Offset: 0x60  ISA Feature Register                                  */

+} SCB_Type;                                                

+

+/* SCB CPUID Register Definitions */

+#define SCB_CPUID_IMPLEMENTER_Pos          24                                             /*!< SCB CPUID: IMPLEMENTER Position */

+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFul << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */

+

+#define SCB_CPUID_VARIANT_Pos              20                                             /*!< SCB CPUID: VARIANT Position */

+#define SCB_CPUID_VARIANT_Msk              (0xFul << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */

+

+#define SCB_CPUID_PARTNO_Pos                4                                             /*!< SCB CPUID: PARTNO Position */

+#define SCB_CPUID_PARTNO_Msk               (0xFFFul << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */

+

+#define SCB_CPUID_REVISION_Pos              0                                             /*!< SCB CPUID: REVISION Position */

+#define SCB_CPUID_REVISION_Msk             (0xFul << SCB_CPUID_REVISION_Pos)              /*!< SCB CPUID: REVISION Mask */

+

+/* SCB Interrupt Control State Register Definitions */

+#define SCB_ICSR_NMIPENDSET_Pos            31                                             /*!< SCB ICSR: NMIPENDSET Position */

+#define SCB_ICSR_NMIPENDSET_Msk            (1ul << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */

+

+#define SCB_ICSR_PENDSVSET_Pos             28                                             /*!< SCB ICSR: PENDSVSET Position */

+#define SCB_ICSR_PENDSVSET_Msk             (1ul << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */

+

+#define SCB_ICSR_PENDSVCLR_Pos             27                                             /*!< SCB ICSR: PENDSVCLR Position */

+#define SCB_ICSR_PENDSVCLR_Msk             (1ul << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */

+

+#define SCB_ICSR_PENDSTSET_Pos             26                                             /*!< SCB ICSR: PENDSTSET Position */

+#define SCB_ICSR_PENDSTSET_Msk             (1ul << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */

+

+#define SCB_ICSR_PENDSTCLR_Pos             25                                             /*!< SCB ICSR: PENDSTCLR Position */

+#define SCB_ICSR_PENDSTCLR_Msk             (1ul << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */

+

+#define SCB_ICSR_ISRPREEMPT_Pos            23                                             /*!< SCB ICSR: ISRPREEMPT Position */

+#define SCB_ICSR_ISRPREEMPT_Msk            (1ul << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */

+

+#define SCB_ICSR_ISRPENDING_Pos            22                                             /*!< SCB ICSR: ISRPENDING Position */

+#define SCB_ICSR_ISRPENDING_Msk            (1ul << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */

+

+#define SCB_ICSR_VECTPENDING_Pos           12                                             /*!< SCB ICSR: VECTPENDING Position */

+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFul << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */

+

+#define SCB_ICSR_RETTOBASE_Pos             11                                             /*!< SCB ICSR: RETTOBASE Position */

+#define SCB_ICSR_RETTOBASE_Msk             (1ul << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */

+

+#define SCB_ICSR_VECTACTIVE_Pos             0                                             /*!< SCB ICSR: VECTACTIVE Position */

+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFul << SCB_ICSR_VECTACTIVE_Pos)           /*!< SCB ICSR: VECTACTIVE Mask */

+

+/* SCB Interrupt Control State Register Definitions */

+#define SCB_VTOR_TBLBASE_Pos               29                                             /*!< SCB VTOR: TBLBASE Position */

+#define SCB_VTOR_TBLBASE_Msk               (0x1FFul << SCB_VTOR_TBLBASE_Pos)              /*!< SCB VTOR: TBLBASE Mask */

+

+#define SCB_VTOR_TBLOFF_Pos                 7                                             /*!< SCB VTOR: TBLOFF Position */

+#define SCB_VTOR_TBLOFF_Msk                (0x3FFFFFul << SCB_VTOR_TBLOFF_Pos)            /*!< SCB VTOR: TBLOFF Mask */

+

+/* SCB Application Interrupt and Reset Control Register Definitions */

+#define SCB_AIRCR_VECTKEY_Pos              16                                             /*!< SCB AIRCR: VECTKEY Position */

+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFul << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */

+

+#define SCB_AIRCR_VECTKEYSTAT_Pos          16                                             /*!< SCB AIRCR: VECTKEYSTAT Position */

+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFul << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */

+

+#define SCB_AIRCR_ENDIANESS_Pos            15                                             /*!< SCB AIRCR: ENDIANESS Position */

+#define SCB_AIRCR_ENDIANESS_Msk            (1ul << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */

+

+#define SCB_AIRCR_PRIGROUP_Pos              8                                             /*!< SCB AIRCR: PRIGROUP Position */

+#define SCB_AIRCR_PRIGROUP_Msk             (7ul << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */

+

+#define SCB_AIRCR_SYSRESETREQ_Pos           2                                             /*!< SCB AIRCR: SYSRESETREQ Position */

+#define SCB_AIRCR_SYSRESETREQ_Msk          (1ul << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */

+

+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1                                             /*!< SCB AIRCR: VECTCLRACTIVE Position */

+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1ul << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */

+

+#define SCB_AIRCR_VECTRESET_Pos             0                                             /*!< SCB AIRCR: VECTRESET Position */

+#define SCB_AIRCR_VECTRESET_Msk            (1ul << SCB_AIRCR_VECTRESET_Pos)               /*!< SCB AIRCR: VECTRESET Mask */

+

+/* SCB System Control Register Definitions */

+#define SCB_SCR_SEVONPEND_Pos               4                                             /*!< SCB SCR: SEVONPEND Position */

+#define SCB_SCR_SEVONPEND_Msk              (1ul << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */

+

+#define SCB_SCR_SLEEPDEEP_Pos               2                                             /*!< SCB SCR: SLEEPDEEP Position */

+#define SCB_SCR_SLEEPDEEP_Msk              (1ul << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */

+

+#define SCB_SCR_SLEEPONEXIT_Pos             1                                             /*!< SCB SCR: SLEEPONEXIT Position */

+#define SCB_SCR_SLEEPONEXIT_Msk            (1ul << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */

+

+/* SCB Configuration Control Register Definitions */

+#define SCB_CCR_STKALIGN_Pos                9                                             /*!< SCB CCR: STKALIGN Position */

+#define SCB_CCR_STKALIGN_Msk               (1ul << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */

+

+#define SCB_CCR_BFHFNMIGN_Pos               8                                             /*!< SCB CCR: BFHFNMIGN Position */

+#define SCB_CCR_BFHFNMIGN_Msk              (1ul << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */

+

+#define SCB_CCR_DIV_0_TRP_Pos               4                                             /*!< SCB CCR: DIV_0_TRP Position */

+#define SCB_CCR_DIV_0_TRP_Msk              (1ul << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */

+

+#define SCB_CCR_UNALIGN_TRP_Pos             3                                             /*!< SCB CCR: UNALIGN_TRP Position */

+#define SCB_CCR_UNALIGN_TRP_Msk            (1ul << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */

+

+#define SCB_CCR_USERSETMPEND_Pos            1                                             /*!< SCB CCR: USERSETMPEND Position */

+#define SCB_CCR_USERSETMPEND_Msk           (1ul << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */

+

+#define SCB_CCR_NONBASETHRDENA_Pos          0                                             /*!< SCB CCR: NONBASETHRDENA Position */

+#define SCB_CCR_NONBASETHRDENA_Msk         (1ul << SCB_CCR_NONBASETHRDENA_Pos)            /*!< SCB CCR: NONBASETHRDENA Mask */

+

+/* SCB System Handler Control and State Register Definitions */

+#define SCB_SHCSR_USGFAULTENA_Pos          18                                             /*!< SCB SHCSR: USGFAULTENA Position */

+#define SCB_SHCSR_USGFAULTENA_Msk          (1ul << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */

+

+#define SCB_SHCSR_BUSFAULTENA_Pos          17                                             /*!< SCB SHCSR: BUSFAULTENA Position */

+#define SCB_SHCSR_BUSFAULTENA_Msk          (1ul << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */

+

+#define SCB_SHCSR_MEMFAULTENA_Pos          16                                             /*!< SCB SHCSR: MEMFAULTENA Position */

+#define SCB_SHCSR_MEMFAULTENA_Msk          (1ul << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */

+

+#define SCB_SHCSR_SVCALLPENDED_Pos         15                                             /*!< SCB SHCSR: SVCALLPENDED Position */

+#define SCB_SHCSR_SVCALLPENDED_Msk         (1ul << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */

+

+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14                                             /*!< SCB SHCSR: BUSFAULTPENDED Position */

+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1ul << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */

+

+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13                                             /*!< SCB SHCSR: MEMFAULTPENDED Position */

+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1ul << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */

+

+#define SCB_SHCSR_USGFAULTPENDED_Pos       12                                             /*!< SCB SHCSR: USGFAULTPENDED Position */

+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1ul << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */

+

+#define SCB_SHCSR_SYSTICKACT_Pos           11                                             /*!< SCB SHCSR: SYSTICKACT Position */

+#define SCB_SHCSR_SYSTICKACT_Msk           (1ul << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */

+

+#define SCB_SHCSR_PENDSVACT_Pos            10                                             /*!< SCB SHCSR: PENDSVACT Position */

+#define SCB_SHCSR_PENDSVACT_Msk            (1ul << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */

+

+#define SCB_SHCSR_MONITORACT_Pos            8                                             /*!< SCB SHCSR: MONITORACT Position */

+#define SCB_SHCSR_MONITORACT_Msk           (1ul << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */

+

+#define SCB_SHCSR_SVCALLACT_Pos             7                                             /*!< SCB SHCSR: SVCALLACT Position */

+#define SCB_SHCSR_SVCALLACT_Msk            (1ul << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */

+                                     

+#define SCB_SHCSR_USGFAULTACT_Pos           3                                             /*!< SCB SHCSR: USGFAULTACT Position */

+#define SCB_SHCSR_USGFAULTACT_Msk          (1ul << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */

+

+#define SCB_SHCSR_BUSFAULTACT_Pos           1                                             /*!< SCB SHCSR: BUSFAULTACT Position */

+#define SCB_SHCSR_BUSFAULTACT_Msk          (1ul << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */

+

+#define SCB_SHCSR_MEMFAULTACT_Pos           0                                             /*!< SCB SHCSR: MEMFAULTACT Position */

+#define SCB_SHCSR_MEMFAULTACT_Msk          (1ul << SCB_SHCSR_MEMFAULTACT_Pos)             /*!< SCB SHCSR: MEMFAULTACT Mask */

+

+/* SCB Configurable Fault Status Registers Definitions */

+#define SCB_CFSR_USGFAULTSR_Pos            16                                             /*!< SCB CFSR: Usage Fault Status Register Position */

+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFul << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */

+

+#define SCB_CFSR_BUSFAULTSR_Pos             8                                             /*!< SCB CFSR: Bus Fault Status Register Position */

+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFul << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */

+

+#define SCB_CFSR_MEMFAULTSR_Pos             0                                             /*!< SCB CFSR: Memory Manage Fault Status Register Position */

+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFul << SCB_CFSR_MEMFAULTSR_Pos)            /*!< SCB CFSR: Memory Manage Fault Status Register Mask */

+

+/* SCB Hard Fault Status Registers Definitions */

+#define SCB_HFSR_DEBUGEVT_Pos              31                                             /*!< SCB HFSR: DEBUGEVT Position */

+#define SCB_HFSR_DEBUGEVT_Msk              (1ul << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */

+

+#define SCB_HFSR_FORCED_Pos                30                                             /*!< SCB HFSR: FORCED Position */

+#define SCB_HFSR_FORCED_Msk                (1ul << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */

+

+#define SCB_HFSR_VECTTBL_Pos                1                                             /*!< SCB HFSR: VECTTBL Position */

+#define SCB_HFSR_VECTTBL_Msk               (1ul << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */

+

+/* SCB Debug Fault Status Register Definitions */

+#define SCB_DFSR_EXTERNAL_Pos               4                                             /*!< SCB DFSR: EXTERNAL Position */

+#define SCB_DFSR_EXTERNAL_Msk              (1ul << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */

+

+#define SCB_DFSR_VCATCH_Pos                 3                                             /*!< SCB DFSR: VCATCH Position */

+#define SCB_DFSR_VCATCH_Msk                (1ul << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */

+

+#define SCB_DFSR_DWTTRAP_Pos                2                                             /*!< SCB DFSR: DWTTRAP Position */

+#define SCB_DFSR_DWTTRAP_Msk               (1ul << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */

+

+#define SCB_DFSR_BKPT_Pos                   1                                             /*!< SCB DFSR: BKPT Position */

+#define SCB_DFSR_BKPT_Msk                  (1ul << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */

+

+#define SCB_DFSR_HALTED_Pos                 0                                             /*!< SCB DFSR: HALTED Position */

+#define SCB_DFSR_HALTED_Msk                (1ul << SCB_DFSR_HALTED_Pos)                   /*!< SCB DFSR: HALTED Mask */

+/*@}*/ /* end of group CMSIS_CM3_SCB */

+

+

+/** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick

+  memory mapped structure for SysTick

+  @{

+ */

+typedef struct

+{

+  __IO uint32_t CTRL;                         /*!< Offset: 0x00  SysTick Control and Status Register */

+  __IO uint32_t LOAD;                         /*!< Offset: 0x04  SysTick Reload Value Register       */

+  __IO uint32_t VAL;                          /*!< Offset: 0x08  SysTick Current Value Register      */

+  __I  uint32_t CALIB;                        /*!< Offset: 0x0C  SysTick Calibration Register        */

+} SysTick_Type;

+

+/* SysTick Control / Status Register Definitions */

+#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */

+#define SysTick_CTRL_COUNTFLAG_Msk         (1ul << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */

+

+#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */

+#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */

+

+#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */

+#define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */

+

+#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */

+#define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */

+

+/* SysTick Reload Register Definitions */

+#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */

+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */

+

+/* SysTick Current Register Definitions */

+#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */

+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */

+

+/* SysTick Calibration Register Definitions */

+#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */

+#define SysTick_CALIB_NOREF_Msk            (1ul << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */

+

+#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */

+#define SysTick_CALIB_SKEW_Msk             (1ul << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */

+

+#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */

+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */

+/*@}*/ /* end of group CMSIS_CM3_SysTick */

+

+

+/** @addtogroup CMSIS_CM3_ITM CMSIS CM3 ITM

+  memory mapped structure for Instrumentation Trace Macrocell (ITM)

+  @{

+ */

+typedef struct

+{

+  __O  union  

+  {

+    __O  uint8_t    u8;                       /*!< Offset:       ITM Stimulus Port 8-bit                   */

+    __O  uint16_t   u16;                      /*!< Offset:       ITM Stimulus Port 16-bit                  */

+    __O  uint32_t   u32;                      /*!< Offset:       ITM Stimulus Port 32-bit                  */

+  }  PORT [32];                               /*!< Offset: 0x00  ITM Stimulus Port Registers               */

+       uint32_t RESERVED0[864];                                 

+  __IO uint32_t TER;                          /*!< Offset:       ITM Trace Enable Register                 */

+       uint32_t RESERVED1[15];                                  

+  __IO uint32_t TPR;                          /*!< Offset:       ITM Trace Privilege Register              */

+       uint32_t RESERVED2[15];                                  

+  __IO uint32_t TCR;                          /*!< Offset:       ITM Trace Control Register                */

+       uint32_t RESERVED3[29];                                  

+  __IO uint32_t IWR;                          /*!< Offset:       ITM Integration Write Register            */

+  __IO uint32_t IRR;                          /*!< Offset:       ITM Integration Read Register             */

+  __IO uint32_t IMCR;                         /*!< Offset:       ITM Integration Mode Control Register     */

+       uint32_t RESERVED4[43];                                  

+  __IO uint32_t LAR;                          /*!< Offset:       ITM Lock Access Register                  */

+  __IO uint32_t LSR;                          /*!< Offset:       ITM Lock Status Register                  */

+       uint32_t RESERVED5[6];                                   

+  __I  uint32_t PID4;                         /*!< Offset:       ITM Peripheral Identification Register #4 */

+  __I  uint32_t PID5;                         /*!< Offset:       ITM Peripheral Identification Register #5 */

+  __I  uint32_t PID6;                         /*!< Offset:       ITM Peripheral Identification Register #6 */

+  __I  uint32_t PID7;                         /*!< Offset:       ITM Peripheral Identification Register #7 */

+  __I  uint32_t PID0;                         /*!< Offset:       ITM Peripheral Identification Register #0 */

+  __I  uint32_t PID1;                         /*!< Offset:       ITM Peripheral Identification Register #1 */

+  __I  uint32_t PID2;                         /*!< Offset:       ITM Peripheral Identification Register #2 */

+  __I  uint32_t PID3;                         /*!< Offset:       ITM Peripheral Identification Register #3 */

+  __I  uint32_t CID0;                         /*!< Offset:       ITM Component  Identification Register #0 */

+  __I  uint32_t CID1;                         /*!< Offset:       ITM Component  Identification Register #1 */

+  __I  uint32_t CID2;                         /*!< Offset:       ITM Component  Identification Register #2 */

+  __I  uint32_t CID3;                         /*!< Offset:       ITM Component  Identification Register #3 */

+} ITM_Type;                                                

+

+/* ITM Trace Privilege Register Definitions */

+#define ITM_TPR_PRIVMASK_Pos                0                                             /*!< ITM TPR: PRIVMASK Position */

+#define ITM_TPR_PRIVMASK_Msk               (0xFul << ITM_TPR_PRIVMASK_Pos)                /*!< ITM TPR: PRIVMASK Mask */

+

+/* ITM Trace Control Register Definitions */

+#define ITM_TCR_BUSY_Pos                   23                                             /*!< ITM TCR: BUSY Position */

+#define ITM_TCR_BUSY_Msk                   (1ul << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */

+

+#define ITM_TCR_ATBID_Pos                  16                                             /*!< ITM TCR: ATBID Position */

+#define ITM_TCR_ATBID_Msk                  (0x7Ful << ITM_TCR_ATBID_Pos)                  /*!< ITM TCR: ATBID Mask */

+

+#define ITM_TCR_TSPrescale_Pos              8                                             /*!< ITM TCR: TSPrescale Position */

+#define ITM_TCR_TSPrescale_Msk             (3ul << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */

+

+#define ITM_TCR_SWOENA_Pos                  4                                             /*!< ITM TCR: SWOENA Position */

+#define ITM_TCR_SWOENA_Msk                 (1ul << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */

+

+#define ITM_TCR_DWTENA_Pos                  3                                             /*!< ITM TCR: DWTENA Position */

+#define ITM_TCR_DWTENA_Msk                 (1ul << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */

+

+#define ITM_TCR_SYNCENA_Pos                 2                                             /*!< ITM TCR: SYNCENA Position */

+#define ITM_TCR_SYNCENA_Msk                (1ul << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */

+

+#define ITM_TCR_TSENA_Pos                   1                                             /*!< ITM TCR: TSENA Position */

+#define ITM_TCR_TSENA_Msk                  (1ul << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */

+

+#define ITM_TCR_ITMENA_Pos                  0                                             /*!< ITM TCR: ITM Enable bit Position */

+#define ITM_TCR_ITMENA_Msk                 (1ul << ITM_TCR_ITMENA_Pos)                    /*!< ITM TCR: ITM Enable bit Mask */

+

+/* ITM Integration Write Register Definitions */

+#define ITM_IWR_ATVALIDM_Pos                0                                             /*!< ITM IWR: ATVALIDM Position */

+#define ITM_IWR_ATVALIDM_Msk               (1ul << ITM_IWR_ATVALIDM_Pos)                  /*!< ITM IWR: ATVALIDM Mask */

+

+/* ITM Integration Read Register Definitions */

+#define ITM_IRR_ATREADYM_Pos                0                                             /*!< ITM IRR: ATREADYM Position */

+#define ITM_IRR_ATREADYM_Msk               (1ul << ITM_IRR_ATREADYM_Pos)                  /*!< ITM IRR: ATREADYM Mask */

+

+/* ITM Integration Mode Control Register Definitions */

+#define ITM_IMCR_INTEGRATION_Pos            0                                             /*!< ITM IMCR: INTEGRATION Position */

+#define ITM_IMCR_INTEGRATION_Msk           (1ul << ITM_IMCR_INTEGRATION_Pos)              /*!< ITM IMCR: INTEGRATION Mask */

+

+/* ITM Lock Status Register Definitions */

+#define ITM_LSR_ByteAcc_Pos                 2                                             /*!< ITM LSR: ByteAcc Position */

+#define ITM_LSR_ByteAcc_Msk                (1ul << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */

+

+#define ITM_LSR_Access_Pos                  1                                             /*!< ITM LSR: Access Position */

+#define ITM_LSR_Access_Msk                 (1ul << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */

+

+#define ITM_LSR_Present_Pos                 0                                             /*!< ITM LSR: Present Position */

+#define ITM_LSR_Present_Msk                (1ul << ITM_LSR_Present_Pos)                   /*!< ITM LSR: Present Mask */

+/*@}*/ /* end of group CMSIS_CM3_ITM */

+

+

+/** @addtogroup CMSIS_CM3_InterruptType CMSIS CM3 Interrupt Type

+  memory mapped structure for Interrupt Type

+  @{

+ */

+typedef struct

+{

+       uint32_t RESERVED0;

+  __I  uint32_t ICTR;                         /*!< Offset: 0x04  Interrupt Control Type Register */

+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))

+  __IO uint32_t ACTLR;                        /*!< Offset: 0x08  Auxiliary Control Register      */

+#else

+       uint32_t RESERVED1;

+#endif

+} InterruptType_Type;

+

+/* Interrupt Controller Type Register Definitions */

+#define InterruptType_ICTR_INTLINESNUM_Pos  0                                             /*!< InterruptType ICTR: INTLINESNUM Position */

+#define InterruptType_ICTR_INTLINESNUM_Msk (0x1Ful << InterruptType_ICTR_INTLINESNUM_Pos) /*!< InterruptType ICTR: INTLINESNUM Mask */

+

+/* Auxiliary Control Register Definitions */

+#define InterruptType_ACTLR_DISFOLD_Pos     2                                             /*!< InterruptType ACTLR: DISFOLD Position */

+#define InterruptType_ACTLR_DISFOLD_Msk    (1ul << InterruptType_ACTLR_DISFOLD_Pos)       /*!< InterruptType ACTLR: DISFOLD Mask */

+

+#define InterruptType_ACTLR_DISDEFWBUF_Pos  1                                             /*!< InterruptType ACTLR: DISDEFWBUF Position */

+#define InterruptType_ACTLR_DISDEFWBUF_Msk (1ul << InterruptType_ACTLR_DISDEFWBUF_Pos)    /*!< InterruptType ACTLR: DISDEFWBUF Mask */

+

+#define InterruptType_ACTLR_DISMCYCINT_Pos  0                                             /*!< InterruptType ACTLR: DISMCYCINT Position */

+#define InterruptType_ACTLR_DISMCYCINT_Msk (1ul << InterruptType_ACTLR_DISMCYCINT_Pos)    /*!< InterruptType ACTLR: DISMCYCINT Mask */

+/*@}*/ /* end of group CMSIS_CM3_InterruptType */

+

+

+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)

+/** @addtogroup CMSIS_CM3_MPU CMSIS CM3 MPU

+  memory mapped structure for Memory Protection Unit (MPU)

+  @{

+ */

+typedef struct

+{

+  __I  uint32_t TYPE;                         /*!< Offset: 0x00  MPU Type Register                              */

+  __IO uint32_t CTRL;                         /*!< Offset: 0x04  MPU Control Register                           */

+  __IO uint32_t RNR;                          /*!< Offset: 0x08  MPU Region RNRber Register                     */

+  __IO uint32_t RBAR;                         /*!< Offset: 0x0C  MPU Region Base Address Register               */

+  __IO uint32_t RASR;                         /*!< Offset: 0x10  MPU Region Attribute and Size Register         */

+  __IO uint32_t RBAR_A1;                      /*!< Offset: 0x14  MPU Alias 1 Region Base Address Register       */

+  __IO uint32_t RASR_A1;                      /*!< Offset: 0x18  MPU Alias 1 Region Attribute and Size Register */

+  __IO uint32_t RBAR_A2;                      /*!< Offset: 0x1C  MPU Alias 2 Region Base Address Register       */

+  __IO uint32_t RASR_A2;                      /*!< Offset: 0x20  MPU Alias 2 Region Attribute and Size Register */

+  __IO uint32_t RBAR_A3;                      /*!< Offset: 0x24  MPU Alias 3 Region Base Address Register       */

+  __IO uint32_t RASR_A3;                      /*!< Offset: 0x28  MPU Alias 3 Region Attribute and Size Register */

+} MPU_Type;                                                

+

+/* MPU Type Register */

+#define MPU_TYPE_IREGION_Pos               16                                             /*!< MPU TYPE: IREGION Position */

+#define MPU_TYPE_IREGION_Msk               (0xFFul << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */

+

+#define MPU_TYPE_DREGION_Pos                8                                             /*!< MPU TYPE: DREGION Position */

+#define MPU_TYPE_DREGION_Msk               (0xFFul << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */

+

+#define MPU_TYPE_SEPARATE_Pos               0                                             /*!< MPU TYPE: SEPARATE Position */

+#define MPU_TYPE_SEPARATE_Msk              (1ul << MPU_TYPE_SEPARATE_Pos)                 /*!< MPU TYPE: SEPARATE Mask */

+

+/* MPU Control Register */

+#define MPU_CTRL_PRIVDEFENA_Pos             2                                             /*!< MPU CTRL: PRIVDEFENA Position */

+#define MPU_CTRL_PRIVDEFENA_Msk            (1ul << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */

+

+#define MPU_CTRL_HFNMIENA_Pos               1                                             /*!< MPU CTRL: HFNMIENA Position */

+#define MPU_CTRL_HFNMIENA_Msk              (1ul << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */

+

+#define MPU_CTRL_ENABLE_Pos                 0                                             /*!< MPU CTRL: ENABLE Position */

+#define MPU_CTRL_ENABLE_Msk                (1ul << MPU_CTRL_ENABLE_Pos)                   /*!< MPU CTRL: ENABLE Mask */

+

+/* MPU Region Number Register */

+#define MPU_RNR_REGION_Pos                  0                                             /*!< MPU RNR: REGION Position */

+#define MPU_RNR_REGION_Msk                 (0xFFul << MPU_RNR_REGION_Pos)                 /*!< MPU RNR: REGION Mask */

+

+/* MPU Region Base Address Register */

+#define MPU_RBAR_ADDR_Pos                   5                                             /*!< MPU RBAR: ADDR Position */

+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFul << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */

+

+#define MPU_RBAR_VALID_Pos                  4                                             /*!< MPU RBAR: VALID Position */

+#define MPU_RBAR_VALID_Msk                 (1ul << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */

+

+#define MPU_RBAR_REGION_Pos                 0                                             /*!< MPU RBAR: REGION Position */

+#define MPU_RBAR_REGION_Msk                (0xFul << MPU_RBAR_REGION_Pos)                 /*!< MPU RBAR: REGION Mask */

+

+/* MPU Region Attribute and Size Register */

+#define MPU_RASR_XN_Pos                    28                                             /*!< MPU RASR: XN Position */

+#define MPU_RASR_XN_Msk                    (1ul << MPU_RASR_XN_Pos)                       /*!< MPU RASR: XN Mask */

+

+#define MPU_RASR_AP_Pos                    24                                             /*!< MPU RASR: AP Position */

+#define MPU_RASR_AP_Msk                    (7ul << MPU_RASR_AP_Pos)                       /*!< MPU RASR: AP Mask */

+

+#define MPU_RASR_TEX_Pos                   19                                             /*!< MPU RASR: TEX Position */

+#define MPU_RASR_TEX_Msk                   (7ul << MPU_RASR_TEX_Pos)                      /*!< MPU RASR: TEX Mask */

+

+#define MPU_RASR_S_Pos                     18                                             /*!< MPU RASR: Shareable bit Position */

+#define MPU_RASR_S_Msk                     (1ul << MPU_RASR_S_Pos)                        /*!< MPU RASR: Shareable bit Mask */

+

+#define MPU_RASR_C_Pos                     17                                             /*!< MPU RASR: Cacheable bit Position */

+#define MPU_RASR_C_Msk                     (1ul << MPU_RASR_C_Pos)                        /*!< MPU RASR: Cacheable bit Mask */

+

+#define MPU_RASR_B_Pos                     16                                             /*!< MPU RASR: Bufferable bit Position */

+#define MPU_RASR_B_Msk                     (1ul << MPU_RASR_B_Pos)                        /*!< MPU RASR: Bufferable bit Mask */

+

+#define MPU_RASR_SRD_Pos                    8                                             /*!< MPU RASR: Sub-Region Disable Position */

+#define MPU_RASR_SRD_Msk                   (0xFFul << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */

+

+#define MPU_RASR_SIZE_Pos                   1                                             /*!< MPU RASR: Region Size Field Position */

+#define MPU_RASR_SIZE_Msk                  (0x1Ful << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */

+

+#define MPU_RASR_ENA_Pos                     0                                            /*!< MPU RASR: Region enable bit Position */

+#define MPU_RASR_ENA_Msk                    (0x1Ful << MPU_RASR_ENA_Pos)                  /*!< MPU RASR: Region enable bit Disable Mask */

+

+/*@}*/ /* end of group CMSIS_CM3_MPU */

+#endif

+

+

+/** @addtogroup CMSIS_CM3_CoreDebug CMSIS CM3 Core Debug

+  memory mapped structure for Core Debug Register

+  @{

+ */

+typedef struct

+{

+  __IO uint32_t DHCSR;                        /*!< Offset: 0x00  Debug Halting Control and Status Register    */

+  __O  uint32_t DCRSR;                        /*!< Offset: 0x04  Debug Core Register Selector Register        */

+  __IO uint32_t DCRDR;                        /*!< Offset: 0x08  Debug Core Register Data Register            */

+  __IO uint32_t DEMCR;                        /*!< Offset: 0x0C  Debug Exception and Monitor Control Register */

+} CoreDebug_Type;

+

+/* Debug Halting Control and Status Register */

+#define CoreDebug_DHCSR_DBGKEY_Pos         16                                             /*!< CoreDebug DHCSR: DBGKEY Position */

+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFul << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */

+

+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25                                             /*!< CoreDebug DHCSR: S_RESET_ST Position */

+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1ul << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */

+

+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24                                             /*!< CoreDebug DHCSR: S_RETIRE_ST Position */

+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1ul << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */

+

+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19                                             /*!< CoreDebug DHCSR: S_LOCKUP Position */

+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1ul << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */

+

+#define CoreDebug_DHCSR_S_SLEEP_Pos        18                                             /*!< CoreDebug DHCSR: S_SLEEP Position */

+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1ul << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */

+

+#define CoreDebug_DHCSR_S_HALT_Pos         17                                             /*!< CoreDebug DHCSR: S_HALT Position */

+#define CoreDebug_DHCSR_S_HALT_Msk         (1ul << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */

+

+#define CoreDebug_DHCSR_S_REGRDY_Pos       16                                             /*!< CoreDebug DHCSR: S_REGRDY Position */

+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1ul << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */

+

+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5                                             /*!< CoreDebug DHCSR: C_SNAPSTALL Position */

+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1ul << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */

+

+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3                                             /*!< CoreDebug DHCSR: C_MASKINTS Position */

+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1ul << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */

+

+#define CoreDebug_DHCSR_C_STEP_Pos          2                                             /*!< CoreDebug DHCSR: C_STEP Position */

+#define CoreDebug_DHCSR_C_STEP_Msk         (1ul << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */

+

+#define CoreDebug_DHCSR_C_HALT_Pos          1                                             /*!< CoreDebug DHCSR: C_HALT Position */

+#define CoreDebug_DHCSR_C_HALT_Msk         (1ul << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */

+

+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0                                             /*!< CoreDebug DHCSR: C_DEBUGEN Position */

+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1ul << CoreDebug_DHCSR_C_DEBUGEN_Pos)         /*!< CoreDebug DHCSR: C_DEBUGEN Mask */

+

+/* Debug Core Register Selector Register */

+#define CoreDebug_DCRSR_REGWnR_Pos         16                                             /*!< CoreDebug DCRSR: REGWnR Position */

+#define CoreDebug_DCRSR_REGWnR_Msk         (1ul << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */

+

+#define CoreDebug_DCRSR_REGSEL_Pos          0                                             /*!< CoreDebug DCRSR: REGSEL Position */

+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1Ful << CoreDebug_DCRSR_REGSEL_Pos)         /*!< CoreDebug DCRSR: REGSEL Mask */

+

+/* Debug Exception and Monitor Control Register */

+#define CoreDebug_DEMCR_TRCENA_Pos         24                                             /*!< CoreDebug DEMCR: TRCENA Position */

+#define CoreDebug_DEMCR_TRCENA_Msk         (1ul << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */

+

+#define CoreDebug_DEMCR_MON_REQ_Pos        19                                             /*!< CoreDebug DEMCR: MON_REQ Position */

+#define CoreDebug_DEMCR_MON_REQ_Msk        (1ul << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */

+

+#define CoreDebug_DEMCR_MON_STEP_Pos       18                                             /*!< CoreDebug DEMCR: MON_STEP Position */

+#define CoreDebug_DEMCR_MON_STEP_Msk       (1ul << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */

+

+#define CoreDebug_DEMCR_MON_PEND_Pos       17                                             /*!< CoreDebug DEMCR: MON_PEND Position */

+#define CoreDebug_DEMCR_MON_PEND_Msk       (1ul << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */

+

+#define CoreDebug_DEMCR_MON_EN_Pos         16                                             /*!< CoreDebug DEMCR: MON_EN Position */

+#define CoreDebug_DEMCR_MON_EN_Msk         (1ul << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */

+

+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10                                             /*!< CoreDebug DEMCR: VC_HARDERR Position */

+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1ul << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */

+

+#define CoreDebug_DEMCR_VC_INTERR_Pos       9                                             /*!< CoreDebug DEMCR: VC_INTERR Position */

+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1ul << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */

+

+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8                                             /*!< CoreDebug DEMCR: VC_BUSERR Position */

+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1ul << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */

+

+#define CoreDebug_DEMCR_VC_STATERR_Pos      7                                             /*!< CoreDebug DEMCR: VC_STATERR Position */

+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1ul << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */

+

+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6                                             /*!< CoreDebug DEMCR: VC_CHKERR Position */

+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1ul << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */

+

+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5                                             /*!< CoreDebug DEMCR: VC_NOCPERR Position */

+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1ul << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */

+

+#define CoreDebug_DEMCR_VC_MMERR_Pos        4                                             /*!< CoreDebug DEMCR: VC_MMERR Position */

+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1ul << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */

+

+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0                                             /*!< CoreDebug DEMCR: VC_CORERESET Position */

+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1ul << CoreDebug_DEMCR_VC_CORERESET_Pos)      /*!< CoreDebug DEMCR: VC_CORERESET Mask */

+/*@}*/ /* end of group CMSIS_CM3_CoreDebug */

+

+

+/* Memory mapping of Cortex-M3 Hardware */

+#define SCS_BASE            (0xE000E000)                              /*!< System Control Space Base Address */

+#define ITM_BASE            (0xE0000000)                              /*!< ITM Base Address                  */

+#define CoreDebug_BASE      (0xE000EDF0)                              /*!< Core Debug Base Address           */

+#define SysTick_BASE        (SCS_BASE +  0x0010)                      /*!< SysTick Base Address              */

+#define NVIC_BASE           (SCS_BASE +  0x0100)                      /*!< NVIC Base Address                 */

+#define SCB_BASE            (SCS_BASE +  0x0D00)                      /*!< System Control Block Base Address */

+

+#define InterruptType       ((InterruptType_Type *) SCS_BASE)         /*!< Interrupt Type Register           */

+#define SCB                 ((SCB_Type *)           SCB_BASE)         /*!< SCB configuration struct          */

+#define SysTick             ((SysTick_Type *)       SysTick_BASE)     /*!< SysTick configuration struct      */

+#define NVIC                ((NVIC_Type *)          NVIC_BASE)        /*!< NVIC configuration struct         */

+#define ITM                 ((ITM_Type *)           ITM_BASE)         /*!< ITM configuration struct          */

+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct   */

+

+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)

+  #define MPU_BASE          (SCS_BASE +  0x0D90)                      /*!< Memory Protection Unit            */

+  #define MPU               ((MPU_Type*)            MPU_BASE)         /*!< Memory Protection Unit            */

+#endif

+

+/*@}*/ /* end of group CMSIS_CM3_core_register */

+

+

+/*******************************************************************************

+ *                Hardware Abstraction Layer

+ ******************************************************************************/

+

+#if defined ( __CC_ARM   )

+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */

+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */

+

+#elif defined ( __ICCARM__ )

+  #define __ASM           __asm                                       /*!< asm keyword for IAR Compiler          */

+  #define __INLINE        inline                                      /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */

+

+#elif defined   (  __GNUC__  )

+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */

+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */

+

+#elif defined   (  __TASKING__  )

+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */

+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */

+

+#endif

+

+

+/* ###################  Compiler specific Intrinsics  ########################### */

+

+#if defined ( __CC_ARM   ) /*------------------RealView Compiler -----------------*/

+/* ARM armcc specific functions */

+

+#define __enable_fault_irq                __enable_fiq

+#define __disable_fault_irq               __disable_fiq

+

+#define __NOP                             __nop

+#define __WFI                             __wfi

+#define __WFE                             __wfe

+#define __SEV                             __sev

+#define __ISB()                           __isb(0)

+#define __DSB()                           __dsb(0)

+#define __DMB()                           __dmb(0)

+#define __REV                             __rev

+#define __RBIT                            __rbit

+#define __LDREXB(ptr)                     ((unsigned char ) __ldrex(ptr))

+#define __LDREXH(ptr)                     ((unsigned short) __ldrex(ptr))

+#define __LDREXW(ptr)                     ((unsigned int  ) __ldrex(ptr))

+#define __STREXB(value, ptr)              __strex(value, ptr)

+#define __STREXH(value, ptr)              __strex(value, ptr)

+#define __STREXW(value, ptr)              __strex(value, ptr)

+

+

+/* intrinsic unsigned long long __ldrexd(volatile void *ptr) */

+/* intrinsic int __strexd(unsigned long long val, volatile void *ptr) */

+/* intrinsic void __enable_irq();     */

+/* intrinsic void __disable_irq();    */

+

+

+/**

+ * @brief  Return the Process Stack Pointer

+ *

+ * @return ProcessStackPointer

+ *

+ * Return the actual process stack pointer

+ */

+extern uint32_t __get_PSP(void);

+

+/**

+ * @brief  Set the Process Stack Pointer

+ *

+ * @param  topOfProcStack  Process Stack Pointer

+ *

+ * Assign the value ProcessStackPointer to the MSP 

+ * (process stack pointer) Cortex processor register

+ */

+extern void __set_PSP(uint32_t topOfProcStack);

+

+/**

+ * @brief  Return the Main Stack Pointer

+ *

+ * @return Main Stack Pointer

+ *

+ * Return the current value of the MSP (main stack pointer)

+ * Cortex processor register

+ */

+extern uint32_t __get_MSP(void);

+

+/**

+ * @brief  Set the Main Stack Pointer

+ *

+ * @param  topOfMainStack  Main Stack Pointer

+ *

+ * Assign the value mainStackPointer to the MSP 

+ * (main stack pointer) Cortex processor register

+ */

+extern void __set_MSP(uint32_t topOfMainStack);

+

+/**

+ * @brief  Reverse byte order in unsigned short value

+ *

+ * @param   value  value to reverse

+ * @return         reversed value

+ *

+ * Reverse byte order in unsigned short value

+ */

+extern uint32_t __REV16(uint16_t value);

+

+/**

+ * @brief  Reverse byte order in signed short value with sign extension to integer

+ *

+ * @param   value  value to reverse

+ * @return         reversed value

+ *

+ * Reverse byte order in signed short value with sign extension to integer

+ */

+extern int32_t __REVSH(int16_t value);

+

+

+#if (__ARMCC_VERSION < 400000)

+

+/**

+ * @brief  Remove the exclusive lock created by ldrex

+ *

+ * Removes the exclusive lock which is created by ldrex.

+ */

+extern void __CLREX(void);

+

+/**

+ * @brief  Return the Base Priority value

+ *

+ * @return BasePriority

+ *

+ * Return the content of the base priority register

+ */

+extern uint32_t __get_BASEPRI(void);

+

+/**

+ * @brief  Set the Base Priority value

+ *

+ * @param  basePri  BasePriority

+ *

+ * Set the base priority register

+ */

+extern void __set_BASEPRI(uint32_t basePri);

+

+/**

+ * @brief  Return the Priority Mask value

+ *

+ * @return PriMask

+ *

+ * Return state of the priority mask bit from the priority mask register

+ */

+extern uint32_t __get_PRIMASK(void);

+

+/**

+ * @brief  Set the Priority Mask value

+ *

+ * @param   priMask  PriMask

+ *

+ * Set the priority mask bit in the priority mask register

+ */

+extern void __set_PRIMASK(uint32_t priMask);

+

+/**

+ * @brief  Return the Fault Mask value

+ *

+ * @return FaultMask

+ *

+ * Return the content of the fault mask register

+ */

+extern uint32_t __get_FAULTMASK(void);

+

+/**

+ * @brief  Set the Fault Mask value

+ *

+ * @param  faultMask faultMask value

+ *

+ * Set the fault mask register

+ */

+extern void __set_FAULTMASK(uint32_t faultMask);

+

+/**

+ * @brief  Return the Control Register value

+ * 

+ * @return Control value

+ *

+ * Return the content of the control register

+ */

+extern uint32_t __get_CONTROL(void);

+

+/**

+ * @brief  Set the Control Register value

+ *

+ * @param  control  Control value

+ *

+ * Set the control register

+ */

+extern void __set_CONTROL(uint32_t control);

+

+#else  /* (__ARMCC_VERSION >= 400000)  */

+

+/**

+ * @brief  Remove the exclusive lock created by ldrex

+ *

+ * Removes the exclusive lock which is created by ldrex.

+ */

+#define __CLREX                           __clrex

+

+/**

+ * @brief  Return the Base Priority value

+ *

+ * @return BasePriority

+ *

+ * Return the content of the base priority register

+ */

+static __INLINE uint32_t  __get_BASEPRI(void)

+{

+  register uint32_t __regBasePri         __ASM("basepri");

+  return(__regBasePri);

+}

+

+/**

+ * @brief  Set the Base Priority value

+ *

+ * @param  basePri  BasePriority

+ *

+ * Set the base priority register

+ */

+static __INLINE void __set_BASEPRI(uint32_t basePri)

+{

+  register uint32_t __regBasePri         __ASM("basepri");

+  __regBasePri = (basePri & 0xff);

+}

+

+/**

+ * @brief  Return the Priority Mask value

+ *

+ * @return PriMask

+ *

+ * Return state of the priority mask bit from the priority mask register

+ */

+static __INLINE uint32_t __get_PRIMASK(void)

+{

+  register uint32_t __regPriMask         __ASM("primask");

+  return(__regPriMask);

+}

+

+/**

+ * @brief  Set the Priority Mask value

+ *

+ * @param  priMask  PriMask

+ *

+ * Set the priority mask bit in the priority mask register

+ */

+static __INLINE void __set_PRIMASK(uint32_t priMask)

+{

+  register uint32_t __regPriMask         __ASM("primask");

+  __regPriMask = (priMask);

+}

+

+/**

+ * @brief  Return the Fault Mask value

+ *

+ * @return FaultMask

+ *

+ * Return the content of the fault mask register

+ */

+static __INLINE uint32_t __get_FAULTMASK(void)

+{

+  register uint32_t __regFaultMask       __ASM("faultmask");

+  return(__regFaultMask);

+}

+

+/**

+ * @brief  Set the Fault Mask value

+ *

+ * @param  faultMask  faultMask value

+ *

+ * Set the fault mask register

+ */

+static __INLINE void __set_FAULTMASK(uint32_t faultMask)

+{

+  register uint32_t __regFaultMask       __ASM("faultmask");

+  __regFaultMask = (faultMask & 1);

+}

+

+/**

+ * @brief  Return the Control Register value

+ * 

+ * @return Control value

+ *

+ * Return the content of the control register

+ */

+static __INLINE uint32_t __get_CONTROL(void)

+{

+  register uint32_t __regControl         __ASM("control");

+  return(__regControl);

+}

+

+/**

+ * @brief  Set the Control Register value

+ *

+ * @param  control  Control value

+ *

+ * Set the control register

+ */

+static __INLINE void __set_CONTROL(uint32_t control)

+{

+  register uint32_t __regControl         __ASM("control");

+  __regControl = control;

+}

+

+#endif /* __ARMCC_VERSION  */ 

+

+

+

+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/

+/* IAR iccarm specific functions */

+

+#define __enable_irq                              __enable_interrupt        /*!< global Interrupt enable */

+#define __disable_irq                             __disable_interrupt       /*!< global Interrupt disable */

+

+static __INLINE void __enable_fault_irq()         { __ASM ("cpsie f"); }

+static __INLINE void __disable_fault_irq()        { __ASM ("cpsid f"); }

+

+#define __NOP                                     __no_operation            /*!< no operation intrinsic in IAR Compiler */ 

+static __INLINE  void __WFI()                     { __ASM ("wfi"); }

+static __INLINE  void __WFE()                     { __ASM ("wfe"); }

+static __INLINE  void __SEV()                     { __ASM ("sev"); }

+static __INLINE  void __CLREX()                   { __ASM ("clrex"); }

+

+/* intrinsic void __ISB(void)                                     */

+/* intrinsic void __DSB(void)                                     */

+/* intrinsic void __DMB(void)                                     */

+/* intrinsic void __set_PRIMASK();                                */

+/* intrinsic void __get_PRIMASK();                                */

+/* intrinsic void __set_FAULTMASK();                              */

+/* intrinsic void __get_FAULTMASK();                              */

+/* intrinsic uint32_t __REV(uint32_t value);                      */

+/* intrinsic uint32_t __REVSH(uint32_t value);                    */

+/* intrinsic unsigned long __STREX(unsigned long, unsigned long); */

+/* intrinsic unsigned long __LDREX(unsigned long *);              */

+

+

+/**

+ * @brief  Return the Process Stack Pointer

+ *

+ * @return ProcessStackPointer

+ *

+ * Return the actual process stack pointer

+ */

+extern uint32_t __get_PSP(void);

+

+/**

+ * @brief  Set the Process Stack Pointer

+ *

+ * @param  topOfProcStack  Process Stack Pointer

+ *

+ * Assign the value ProcessStackPointer to the MSP 

+ * (process stack pointer) Cortex processor register

+ */

+extern void __set_PSP(uint32_t topOfProcStack);

+

+/**

+ * @brief  Return the Main Stack Pointer

+ *

+ * @return Main Stack Pointer

+ *

+ * Return the current value of the MSP (main stack pointer)

+ * Cortex processor register

+ */

+extern uint32_t __get_MSP(void);

+

+/**

+ * @brief  Set the Main Stack Pointer

+ *

+ * @param  topOfMainStack  Main Stack Pointer

+ *

+ * Assign the value mainStackPointer to the MSP 

+ * (main stack pointer) Cortex processor register

+ */

+extern void __set_MSP(uint32_t topOfMainStack);

+

+/**

+ * @brief  Reverse byte order in unsigned short value

+ *

+ * @param  value  value to reverse

+ * @return        reversed value

+ *

+ * Reverse byte order in unsigned short value

+ */

+extern uint32_t __REV16(uint16_t value);

+

+/**

+ * @brief  Reverse bit order of value

+ *

+ * @param  value  value to reverse

+ * @return        reversed value

+ *

+ * Reverse bit order of value

+ */

+extern uint32_t __RBIT(uint32_t value);

+

+/**

+ * @brief  LDR Exclusive (8 bit)

+ *

+ * @param  *addr  address pointer

+ * @return        value of (*address)

+ *

+ * Exclusive LDR command for 8 bit values)

+ */

+extern uint8_t __LDREXB(uint8_t *addr);

+

+/**

+ * @brief  LDR Exclusive (16 bit)

+ *

+ * @param  *addr  address pointer

+ * @return        value of (*address)

+ *

+ * Exclusive LDR command for 16 bit values

+ */

+extern uint16_t __LDREXH(uint16_t *addr);

+

+/**

+ * @brief  LDR Exclusive (32 bit)

+ *

+ * @param  *addr  address pointer

+ * @return        value of (*address)

+ *

+ * Exclusive LDR command for 32 bit values

+ */

+extern uint32_t __LDREXW(uint32_t *addr);

+

+/**

+ * @brief  STR Exclusive (8 bit)

+ *

+ * @param  value  value to store

+ * @param  *addr  address pointer

+ * @return        successful / failed

+ *

+ * Exclusive STR command for 8 bit values

+ */

+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);

+

+/**

+ * @brief  STR Exclusive (16 bit)

+ *

+ * @param  value  value to store

+ * @param  *addr  address pointer

+ * @return        successful / failed

+ *

+ * Exclusive STR command for 16 bit values

+ */

+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);

+

+/**

+ * @brief  STR Exclusive (32 bit)

+ *

+ * @param  value  value to store

+ * @param  *addr  address pointer

+ * @return        successful / failed

+ *

+ * Exclusive STR command for 32 bit values

+ */

+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);

+

+

+

+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/

+/* GNU gcc specific functions */

+

+static __INLINE void __enable_irq(void)               { __ASM volatile ("cpsie i"); }

+static __INLINE void __disable_irq(void)              { __ASM volatile ("cpsid i"); }

+

+static __INLINE void __enable_fault_irq(void)         { __ASM volatile ("cpsie f"); }

+static __INLINE void __disable_fault_irq(void)        { __ASM volatile ("cpsid f"); }

+

+static __INLINE void __NOP(void)                      { __ASM volatile ("nop"); }

+static __INLINE void __WFI(void)                      { __ASM volatile ("wfi"); }

+static __INLINE void __WFE(void)                      { __ASM volatile ("wfe"); }

+static __INLINE void __SEV(void)                      { __ASM volatile ("sev"); }

+static __INLINE void __ISB(void)                      { __ASM volatile ("isb"); }

+static __INLINE void __DSB(void)                      { __ASM volatile ("dsb"); }

+static __INLINE void __DMB(void)                      { __ASM volatile ("dmb"); }

+static __INLINE void __CLREX(void)                    { __ASM volatile ("clrex"); }

+

+

+/**

+ * @brief  Return the Process Stack Pointer

+ *

+ * @return ProcessStackPointer

+ *

+ * Return the actual process stack pointer

+ */

+extern uint32_t __get_PSP(void);

+

+/**

+ * @brief  Set the Process Stack Pointer

+ *

+ * @param  topOfProcStack  Process Stack Pointer

+ *

+ * Assign the value ProcessStackPointer to the MSP 

+ * (process stack pointer) Cortex processor register

+ */

+extern void __set_PSP(uint32_t topOfProcStack);

+

+/**

+ * @brief  Return the Main Stack Pointer

+ *

+ * @return Main Stack Pointer

+ *

+ * Return the current value of the MSP (main stack pointer)

+ * Cortex processor register

+ */

+extern uint32_t __get_MSP(void);

+

+/**

+ * @brief  Set the Main Stack Pointer

+ *

+ * @param  topOfMainStack  Main Stack Pointer

+ *

+ * Assign the value mainStackPointer to the MSP 

+ * (main stack pointer) Cortex processor register

+ */

+extern void __set_MSP(uint32_t topOfMainStack);

+

+/**

+ * @brief  Return the Base Priority value

+ *

+ * @return BasePriority

+ *

+ * Return the content of the base priority register

+ */

+extern uint32_t __get_BASEPRI(void);

+

+/**

+ * @brief  Set the Base Priority value

+ *

+ * @param  basePri  BasePriority

+ *

+ * Set the base priority register

+ */

+extern void __set_BASEPRI(uint32_t basePri);

+

+/**

+ * @brief  Return the Priority Mask value

+ *

+ * @return PriMask

+ *

+ * Return state of the priority mask bit from the priority mask register

+ */

+extern uint32_t  __get_PRIMASK(void);

+

+/**

+ * @brief  Set the Priority Mask value

+ *

+ * @param  priMask  PriMask

+ *

+ * Set the priority mask bit in the priority mask register

+ */

+extern void __set_PRIMASK(uint32_t priMask);

+

+/**

+ * @brief  Return the Fault Mask value

+ *

+ * @return FaultMask

+ *

+ * Return the content of the fault mask register

+ */

+extern uint32_t __get_FAULTMASK(void);

+

+/**

+ * @brief  Set the Fault Mask value

+ *

+ * @param  faultMask  faultMask value

+ *

+ * Set the fault mask register

+ */

+extern void __set_FAULTMASK(uint32_t faultMask);

+

+/**

+ * @brief  Return the Control Register value

+* 

+*  @return Control value

+ *

+ * Return the content of the control register

+ */

+extern uint32_t __get_CONTROL(void);

+

+/**

+ * @brief  Set the Control Register value

+ *

+ * @param  control  Control value

+ *

+ * Set the control register

+ */

+extern void __set_CONTROL(uint32_t control);

+

+/**

+ * @brief  Reverse byte order in integer value

+ *

+ * @param  value  value to reverse

+ * @return        reversed value

+ *

+ * Reverse byte order in integer value

+ */

+extern uint32_t __REV(uint32_t value);

+

+/**

+ * @brief  Reverse byte order in unsigned short value

+ *

+ * @param  value  value to reverse

+ * @return        reversed value

+ *

+ * Reverse byte order in unsigned short value

+ */

+extern uint32_t __REV16(uint16_t value);

+

+/**

+ * @brief  Reverse byte order in signed short value with sign extension to integer

+ *

+ * @param  value  value to reverse

+ * @return        reversed value

+ *

+ * Reverse byte order in signed short value with sign extension to integer

+ */

+extern int32_t __REVSH(int16_t value);

+

+/**

+ * @brief  Reverse bit order of value

+ *

+ * @param  value  value to reverse

+ * @return        reversed value

+ *

+ * Reverse bit order of value

+ */

+extern uint32_t __RBIT(uint32_t value);

+

+/**

+ * @brief  LDR Exclusive (8 bit)

+ *

+ * @param  *addr  address pointer

+ * @return        value of (*address)

+ *

+ * Exclusive LDR command for 8 bit value

+ */

+extern uint8_t __LDREXB(uint8_t *addr);

+

+/**

+ * @brief  LDR Exclusive (16 bit)

+ *

+ * @param  *addr  address pointer

+ * @return        value of (*address)

+ *

+ * Exclusive LDR command for 16 bit values

+ */

+extern uint16_t __LDREXH(uint16_t *addr);

+

+/**

+ * @brief  LDR Exclusive (32 bit)

+ *

+ * @param  *addr  address pointer

+ * @return        value of (*address)

+ *

+ * Exclusive LDR command for 32 bit values

+ */

+extern uint32_t __LDREXW(uint32_t *addr);

+

+/**

+ * @brief  STR Exclusive (8 bit)

+ *

+ * @param  value  value to store

+ * @param  *addr  address pointer

+ * @return        successful / failed

+ *

+ * Exclusive STR command for 8 bit values

+ */

+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);

+

+/**

+ * @brief  STR Exclusive (16 bit)

+ *

+ * @param  value  value to store

+ * @param  *addr  address pointer

+ * @return        successful / failed

+ *

+ * Exclusive STR command for 16 bit values

+ */

+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);

+

+/**

+ * @brief  STR Exclusive (32 bit)

+ *

+ * @param  value  value to store

+ * @param  *addr  address pointer

+ * @return        successful / failed

+ *

+ * Exclusive STR command for 32 bit values

+ */

+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);

+

+

+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/

+/* TASKING carm specific functions */

+

+/*

+ * The CMSIS functions have been implemented as intrinsics in the compiler.

+ * Please use "carm -?i" to get an up to date list of all instrinsics,

+ * Including the CMSIS ones.

+ */

+

+#endif

+

+

+/** @addtogroup CMSIS_CM3_Core_FunctionInterface CMSIS CM3 Core Function Interface

+  Core  Function Interface containing:

+  - Core NVIC Functions

+  - Core SysTick Functions

+  - Core Reset Functions

+*/

+/*@{*/

+

+/* ##########################   NVIC functions  #################################### */

+

+/**

+ * @brief  Set the Priority Grouping in NVIC Interrupt Controller

+ *

+ * @param  PriorityGroup is priority grouping field

+ *

+ * Set the priority grouping field using the required unlock sequence.

+ * The parameter priority_grouping is assigned to the field 

+ * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used.

+ * In case of a conflict between priority grouping and available

+ * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.

+ */

+static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)

+{

+  uint32_t reg_value;

+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);                         /* only values 0..7 are used          */

+  

+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */

+  reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk);             /* clear bits to change               */

+  reg_value  =  (reg_value                       |

+                (0x5FA << SCB_AIRCR_VECTKEY_Pos) | 

+                (PriorityGroupTmp << 8));                                     /* Insert write key and priorty group */

+  SCB->AIRCR =  reg_value;

+}

+

+/**

+ * @brief  Get the Priority Grouping from NVIC Interrupt Controller

+ *

+ * @return priority grouping field 

+ *

+ * Get the priority grouping from NVIC Interrupt Controller.

+ * priority grouping is SCB->AIRCR [10:8] PRIGROUP field.

+ */

+static __INLINE uint32_t NVIC_GetPriorityGrouping(void)

+{

+  return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos);   /* read priority grouping field */

+}

+

+/**

+ * @brief  Enable Interrupt in NVIC Interrupt Controller

+ *

+ * @param  IRQn   The positive number of the external interrupt to enable

+ *

+ * Enable a device specific interupt in the NVIC interrupt controller.

+ * The interrupt number cannot be a negative value.

+ */

+static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)

+{

+  NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */

+}

+

+/**

+ * @brief  Disable the interrupt line for external interrupt specified

+ * 

+ * @param  IRQn   The positive number of the external interrupt to disable

+ * 

+ * Disable a device specific interupt in the NVIC interrupt controller.

+ * The interrupt number cannot be a negative value.

+ */

+static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)

+{

+  NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */

+}

+

+/**

+ * @brief  Read the interrupt pending bit for a device specific interrupt source

+ * 

+ * @param  IRQn    The number of the device specifc interrupt

+ * @return         1 = interrupt pending, 0 = interrupt not pending

+ *

+ * Read the pending register in NVIC and return 1 if its status is pending, 

+ * otherwise it returns 0

+ */

+static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)

+{

+  return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */

+}

+

+/**

+ * @brief  Set the pending bit for an external interrupt

+ * 

+ * @param  IRQn    The number of the interrupt for set pending

+ *

+ * Set the pending bit for the specified interrupt.

+ * The interrupt number cannot be a negative value.

+ */

+static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)

+{

+  NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */

+}

+

+/**

+ * @brief  Clear the pending bit for an external interrupt

+ *

+ * @param  IRQn    The number of the interrupt for clear pending

+ *

+ * Clear the pending bit for the specified interrupt. 

+ * The interrupt number cannot be a negative value.

+ */

+static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)

+{

+  NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */

+}

+

+/**

+ * @brief  Read the active bit for an external interrupt

+ *

+ * @param  IRQn    The number of the interrupt for read active bit

+ * @return         1 = interrupt active, 0 = interrupt not active

+ *

+ * Read the active register in NVIC and returns 1 if its status is active, 

+ * otherwise it returns 0.

+ */

+static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)

+{

+  return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */

+}

+

+/**

+ * @brief  Set the priority for an interrupt

+ *

+ * @param  IRQn      The number of the interrupt for set priority

+ * @param  priority  The priority to set

+ *

+ * Set the priority for the specified interrupt. The interrupt 

+ * number can be positive to specify an external (device specific) 

+ * interrupt, or negative to specify an internal (core) interrupt.

+ *

+ * Note: The priority cannot be set for every core interrupt.

+ */

+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

+{

+  if(IRQn < 0) {

+    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */

+  else {

+    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */

+}

+

+/**

+ * @brief  Read the priority for an interrupt

+ *

+ * @param  IRQn      The number of the interrupt for get priority

+ * @return           The priority for the interrupt

+ *

+ * Read the priority for the specified interrupt. The interrupt 

+ * number can be positive to specify an external (device specific) 

+ * interrupt, or negative to specify an internal (core) interrupt.

+ *

+ * The returned priority value is automatically aligned to the implemented

+ * priority bits of the microcontroller.

+ *

+ * Note: The priority cannot be set for every core interrupt.

+ */

+static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)

+{

+

+  if(IRQn < 0) {

+    return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M3 system interrupts */

+  else {

+    return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)]           >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */

+}

+

+

+/**

+ * @brief  Encode the priority for an interrupt

+ *

+ * @param  PriorityGroup    The used priority group

+ * @param  PreemptPriority  The preemptive priority value (starting from 0)

+ * @param  SubPriority      The sub priority value (starting from 0)

+ * @return                  The encoded priority for the interrupt

+ *

+ * Encode the priority for an interrupt with the given priority group,

+ * preemptive priority value and sub priority value.

+ * In case of a conflict between priority grouping and available

+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.

+ *

+ * The returned priority value can be used for NVIC_SetPriority(...) function

+ */

+static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)

+{

+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);          /* only values 0..7 are used          */

+  uint32_t PreemptPriorityBits;

+  uint32_t SubPriorityBits;

+

+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;

+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;

+ 

+  return (

+           ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |

+           ((SubPriority     & ((1 << (SubPriorityBits    )) - 1)))

+         );

+}

+

+

+/**

+ * @brief  Decode the priority of an interrupt

+ *

+ * @param  Priority           The priority for the interrupt

+ * @param  PriorityGroup      The used priority group

+ * @param  pPreemptPriority   The preemptive priority value (starting from 0)

+ * @param  pSubPriority       The sub priority value (starting from 0)

+ *

+ * Decode an interrupt priority value with the given priority group to 

+ * preemptive priority value and sub priority value.

+ * In case of a conflict between priority grouping and available

+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.

+ *

+ * The priority value can be retrieved with NVIC_GetPriority(...) function

+ */

+static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)

+{

+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);          /* only values 0..7 are used          */

+  uint32_t PreemptPriorityBits;

+  uint32_t SubPriorityBits;

+

+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;

+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;

+  

+  *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);

+  *pSubPriority     = (Priority                   ) & ((1 << (SubPriorityBits    )) - 1);

+}

+

+

+

+/* ##################################    SysTick function  ############################################ */

+

+#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)

+

+/**

+ * @brief  Initialize and start the SysTick counter and its interrupt.

+ *

+ * @param   ticks   number of ticks between two interrupts

+ * @return  1 = failed, 0 = successful

+ *

+ * Initialise the system tick timer and its interrupt and start the

+ * system tick timer / counter in free running mode to generate 

+ * periodical interrupts.

+ */

+static __INLINE uint32_t SysTick_Config(uint32_t ticks)

+{ 

+  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */

+                                                               

+  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */

+  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */

+  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */

+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 

+                   SysTick_CTRL_TICKINT_Msk   | 

+                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */

+  return (0);                                                  /* Function successful */

+}

+

+#endif

+

+

+

+

+/* ##################################    Reset function  ############################################ */

+

+/**

+ * @brief  Initiate a system reset request.

+ *

+ * Initiate a system reset request to reset the MCU

+ */

+static __INLINE void NVIC_SystemReset(void)

+{

+  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      | 

+                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | 

+                 SCB_AIRCR_SYSRESETREQ_Msk);                   /* Keep priority group unchanged */

+  __DSB();                                                     /* Ensure completion of memory access */              

+  while(1);                                                    /* wait until reset */

+}

+

+/*@}*/ /* end of group CMSIS_CM3_Core_FunctionInterface */

+

+

+

+/* ##################################### Debug In/Output function ########################################### */

+

+/** @addtogroup CMSIS_CM3_CoreDebugInterface CMSIS CM3 Core Debug Interface

+  Core Debug Interface containing:

+  - Core Debug Receive / Transmit Functions

+  - Core Debug Defines

+  - Core Debug Variables

+*/

+/*@{*/

+

+extern volatile int ITM_RxBuffer;                    /*!< variable to receive characters                             */

+#define             ITM_RXBUFFER_EMPTY    0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */

+

+

+/**

+ * @brief  Outputs a character via the ITM channel 0

+ *

+ * @param  ch   character to output

+ * @return      character to output

+ *

+ * The function outputs a character via the ITM channel 0. 

+ * The function returns when no debugger is connected that has booked the output.  

+ * It is blocking when a debugger is connected, but the previous character send is not transmitted. 

+ */

+static __INLINE uint32_t ITM_SendChar (uint32_t ch)

+{

+  if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)  &&      /* Trace enabled */

+      (ITM->TCR & ITM_TCR_ITMENA_Msk)                  &&      /* ITM enabled */

+      (ITM->TER & (1ul << 0)        )                    )     /* ITM Port #0 enabled */

+  {

+    while (ITM->PORT[0].u32 == 0);

+    ITM->PORT[0].u8 = (uint8_t) ch;

+  }  

+  return (ch);

+}

+

+

+/**

+ * @brief  Inputs a character via variable ITM_RxBuffer

+ *

+ * @return      received character, -1 = no character received

+ *

+ * The function inputs a character via variable ITM_RxBuffer. 

+ * The function returns when no debugger is connected that has booked the output.  

+ * It is blocking when a debugger is connected, but the previous character send is not transmitted. 

+ */

+static __INLINE int ITM_ReceiveChar (void) {

+  int ch = -1;                               /* no character available */

+

+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {

+    ch = ITM_RxBuffer;

+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */

+  }

+  

+  return (ch); 

+}

+

+

+/**

+ * @brief  Check if a character via variable ITM_RxBuffer is available

+ *

+ * @return      1 = character available, 0 = no character available

+ *

+ * The function checks  variable ITM_RxBuffer whether a character is available or not. 

+ * The function returns '1' if a character is available and '0' if no character is available. 

+ */

+static __INLINE int ITM_CheckChar (void) {

+

+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {

+    return (0);                                 /* no character available */

+  } else {

+    return (1);                                 /*    character available */

+  }

+}

+

+/*@}*/ /* end of group CMSIS_CM3_core_DebugInterface */

+

+

+#ifdef __cplusplus

+}

+#endif

+

+/*@}*/ /* end of group CMSIS_CM3_core_definitions */

+

+#endif /* __CM3_CORE_H__ */

+

+/*lint -restore */

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/mss_assert.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/mss_assert.h
new file mode 100644
index 0000000..4725d21
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/mss_assert.h
@@ -0,0 +1,48 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ * Assertion implementation.

+ *

+ * This file provides the implementation of the ASSERT macro. This file can be

+ * modified to cater for project specific requirements regarding the way

+ * assertions are handled.

+ *

+ * SVN $Revision: 1676 $

+ * SVN $Date: 2009-12-02 16:47:03 +0000 (Wed, 02 Dec 2009) $

+ */

+#ifndef __MSS_ASSERT_H_

+#define __MSS_ASSERT_H_

+

+#include <assert.h>

+

+#if defined ( __GNUC__   )

+

+#if defined(NDEBUG)

+

+#define ASSERT(CHECK)

+

+#else   /* NDEBUG */

+/*

+ * SoftConsole assertion handling

+ */

+#define ASSERT(CHECK)  \

+    do { \

+        if (!(CHECK)) \

+        { \

+            __asm volatile ("BKPT\n\t"); \

+        } \

+    } while (0);

+    

+#endif  /* NDEBUG */

+

+#else

+/*

+ * IAR Embedded Workbench or Keil assertion handling.

+ * Call C library assert function which should result in error message

+ * displayed in debugger.

+ */

+#define ASSERT(X)   assert(X)

+

+#endif

+

+#endif  /* __MSS_ASSERT_H_ */

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-envm.ld b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-envm.ld
new file mode 100644
index 0000000..1d33683
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-envm.ld
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.
+ * 
+ * SmartFusion/Cortex-M3 linker script for creating a SoftConsole downloadable
+ * debug image executing in SmartFusion internal eNVM.
+ *
+ * SVN $Revision: 1677 $
+ * SVN $Date: 2009-12-02 16:57:29 +0000 (Wed, 02 Dec 2009) $
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+	      "elf32-littlearm")
+GROUP(-lc -lgcc -lm)
+OUTPUT_ARCH(arm)
+ENTRY(Reset_Handler)
+SEARCH_DIR(.)
+__DYNAMIC  =  0;
+
+/*******************************************************************************
+ * Start of board customization.
+ *******************************************************************************/
+MEMORY
+{
+  /*
+   * WARNING: The words "SOFTCONSOLE", "FLASH", and "USE", the colon ":", and
+   *          the name of the type of flash memory are all in a specific order.
+   *          Please do not modify that comment line, in order to ensure
+   *          debugging of your application will use the flash memory correctly.
+   */
+
+  /* SOFTCONSOLE FLASH USE: actel-smartfusion-envm */
+  rom (rx)  : ORIGIN = 0x60000000, LENGTH = 256k
+  
+  /* SmartFusion internal eNVM mirrored to 0x00000000 */
+  romMirror (rx) : ORIGIN = 0x00000000, LENGTH = 256k
+
+  /* SmartFusion internal eSRAM */
+  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
+}
+
+RAM_START_ADDRESS = 0x20000000; 	/* Must be the same value MEMORY region ram ORIGIN above. */
+RAM_SIZE = 64k; 					/* Must be the same value MEMORY region ram LENGTH above. */
+MAIN_STACK_SIZE = 8k; 				/* Cortex main stack size. */
+PROCESS_STACK_SIZE	= 4k; 			/* Cortex process stack size (only available with OS extensions).*/
+
+/*******************************************************************************
+ * End of board customization.
+ *******************************************************************************/
+ 
+PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE);
+PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE);
+PROVIDE (_estack = __main_stack_start);
+PROVIDE (__mirrored_nvm = 1);   /* Indicate to startup code that NVM is mirrored to VMA address and no text copy is required. */
+
+SECTIONS
+{
+  .init :
+  {
+    *(.isr_vector)
+    *sys_boot.o(.text)
+    . = ALIGN(0x4);
+  } >romMirror AT>rom
+  
+  .text :
+  {
+    CREATE_OBJECT_SYMBOLS
+    __text_load = LOADADDR(.text);
+    __text_start = .;
+    
+    *(.text .text.* .gnu.linkonce.t.*)
+    *(.plt)
+    *(.gnu.warning)
+    *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
+
+    . = ALIGN(0x4);
+    /* These are for running static constructors and destructors under ELF.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*crtend.o(.ctors))
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*crtend.o(.dtors))
+
+    *(.rodata .rodata.* .gnu.linkonce.r.*)
+
+    *(.ARM.extab* .gnu.linkonce.armextab.*)
+    *(.gcc_except_table) 
+    *(.eh_frame_hdr)
+    *(.eh_frame)
+
+    KEEP (*(.init))
+    KEEP (*(.fini))
+
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array))
+    PROVIDE_HIDDEN (__init_array_end = .);
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(.fini_array))
+    KEEP (*(SORT(.fini_array.*)))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  } >romMirror AT>rom
+
+  /* .ARM.exidx is sorted, so has to go in its own output section.  */
+   __exidx_start = .;
+  .ARM.exidx :
+  {
+    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+  } >ram AT>rom
+  __exidx_end = .;
+  _etext = .;
+
+  .data :
+  {
+    __data_load = LOADADDR(.data);
+    _sidata = LOADADDR (.data);
+    __data_start = .;
+    _sdata = .;
+    KEEP(*(.jcr))
+    *(.got.plt) *(.got)
+    *(.shdata)
+    *(.data .data.* .gnu.linkonce.d.*)
+    . = ALIGN (4);
+  	_edata = .;
+  } >ram AT>rom
+
+  .bss :
+  {
+    __bss_start__ = . ;
+    _sbss = .;
+    *(.shbss)
+    *(.bss .bss.* .gnu.linkonce.b.*)
+    *(COMMON)
+    . = ALIGN (8);
+    __bss_end__ = .;
+    _end = .;
+    __end = _end;
+    _ebss = .;
+    PROVIDE(end = .);
+  } >ram AT>rom
+
+  .stab 0 (NOLOAD) :
+  {
+    *(.stab)
+  }
+
+  .stabstr 0 (NOLOAD) :
+  {
+    *(.stabstr)
+  }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+  .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
+  /DISCARD/ : { *(.note.GNU-stack)  }
+}
diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-esram.ld b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-esram.ld
new file mode 100644
index 0000000..85e4160
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-esram.ld
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.
+ * 
+ * SmartFusion/Cortex-M3 linker script for creating a SoftConsole downloadable
+ * debug image executing in SmartFusion internal eSRAM.
+ *
+ * SVN $Revision: 1677 $
+ * SVN $Date: 2009-12-02 16:57:29 +0000 (Wed, 02 Dec 2009) $
+ */
+
+ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+	      "elf32-littlearm")
+GROUP(-lc -lgcc -lm)
+OUTPUT_ARCH(arm)
+ENTRY(Reset_Handler)
+SEARCH_DIR(.)
+__DYNAMIC  =  0;
+
+/*******************************************************************************
+ * Start of board customization.
+ *******************************************************************************/
+MEMORY
+{
+  /* SmartFusion internal eSRAM */
+  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
+}
+
+RAM_START_ADDRESS = 0x20000000;	/* Must be the same value MEMORY region ram ORIGIN above. */
+RAM_SIZE = 64k;					/* Must be the same value MEMORY region ram LENGTH above. */
+MAIN_STACK_SIZE = 8k;			/* Cortex main stack size. */
+PROCESS_STACK_SIZE	= 4k;		/* Cortex process stack size (only available with OS extensions).*/
+
+/*******************************************************************************
+ * End of board customization.
+ *******************************************************************************/
+ 
+PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE);
+PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE);
+PROVIDE (_estack = __main_stack_start);
+PROVIDE (__mirrored_nvm = 0);   /* Indicate to startup code that NVM is not mirrored to VMA address .text copy is required. */
+
+SECTIONS
+{
+  .text :
+  {
+    CREATE_OBJECT_SYMBOLS
+    __text_load = LOADADDR(.text);
+    __text_start = .;
+    *(.isr_vector)
+    *(.text .text.* .gnu.linkonce.t.*)
+    *(.plt)
+    *(.gnu.warning)
+    *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
+
+    . = ALIGN(0x4);
+    /* These are for running static constructors and destructors under ELF.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*crtend.o(.ctors))
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*crtend.o(.dtors))
+
+    *(.rodata .rodata.* .gnu.linkonce.r.*)
+
+    *(.ARM.extab* .gnu.linkonce.armextab.*)
+    *(.gcc_except_table) 
+    *(.eh_frame_hdr)
+    *(.eh_frame)
+
+    KEEP (*(.init))
+    KEEP (*(.fini))
+
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array))
+    PROVIDE_HIDDEN (__init_array_end = .);
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(.fini_array))
+    KEEP (*(SORT(.fini_array.*)))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  } >ram
+  /* .ARM.exidx is sorted, so has to go in its own output section.  */
+   __exidx_start = .;
+  .ARM.exidx :
+  {
+    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+  } >ram
+  __exidx_end = .;
+  _etext = .;
+  PROVIDE(__text_end = .);
+
+  .data :
+  {
+    __data_load = LOADADDR (.data);
+    _sidata = LOADADDR (.data);
+    __data_start = .;
+    _sdata = .;
+    KEEP(*(.jcr))
+    *(.got.plt) *(.got)
+    *(.shdata)
+    *(.data .data.* .gnu.linkonce.d.*)
+    . = ALIGN (4);
+    _edata = .;
+  } >ram 
+
+  .bss :
+  {
+    __bss_start__ = . ;
+    _sbss = .;
+    *(.shbss)
+    *(.bss .bss.* .gnu.linkonce.b.*)
+    *(COMMON)
+    . = ALIGN (8);
+    __bss_end__ = .;
+    _end = .;
+    __end = _end;
+    _ebss = .;
+    PROVIDE(end = .);
+  } >ram 
+
+  /* 
+   * The .stack section is only specified here in order for the linker to generate
+   * an error if the ram is full.
+   */
+  .stack :
+  {
+  	. = ALIGN(4);
+    . += PROCESS_STACK_SIZE;
+    . = ALIGN(4);
+    . += MAIN_STACK_SIZE;
+    . = ALIGN(4);
+  } >ram
+  
+  .stab 0 (NOLOAD) :
+  {
+    *(.stab)
+  }
+
+  .stabstr 0 (NOLOAD) :
+  {
+    *(.stabstr)
+  }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+  .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
+  /DISCARD/ : { *(.note.GNU-stack) *(.isr_vector) }
+}
diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-external-ram.ld b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-external-ram.ld
new file mode 100644
index 0000000..b2d614d
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-external-ram.ld
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.
+ * 
+ * SmartFusion/Cortex-M3 linker script for creating a SoftConsole downloadable
+ * debug image executing in SmartFusion development board external RAM.
+ *
+ * SVN $Revision: 2014 $
+ * SVN $Date: 2010-01-20 10:37:26 +0000 (Wed, 20 Jan 2010) $
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+	      "elf32-littlearm")
+GROUP(-lc -lgcc -lm)
+OUTPUT_ARCH(arm)
+ENTRY(Reset_Handler)
+SEARCH_DIR(.)
+__DYNAMIC  =  0;
+
+/*******************************************************************************
+ * Start of board customization.
+ *******************************************************************************/
+MEMORY
+{
+  /* SmartFusion internal eSRAM */
+  esram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
+  
+  /* SmartFusion development board external RAM */
+  external_ram (rwx) : ORIGIN = 0x70000000, LENGTH = 2M
+}
+
+RAM_START_ADDRESS = 0x70000000;	/* Must be the same value MEMORY region ram ORIGIN above. */
+RAM_SIZE = 64k;					/* Must be the same value MEMORY region ram LENGTH above. */
+MAIN_STACK_SIZE = 8k;			/* Cortex main stack size. */
+PROCESS_STACK_SIZE	= 4k;		/* Cortex process stack size (only available with OS extensions).*/
+
+/*******************************************************************************
+ * End of board customization.
+ *******************************************************************************/
+ 
+PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE);
+PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE);
+PROVIDE (_estack = __main_stack_start);
+PROVIDE (__mirrored_nvm = 0);   /* Indicate to startup code that NVM is not mirrored to VMA address .text copy is required. */
+
+SECTIONS
+{
+  .init :
+  {
+    *(.isr_vector)
+    . = ALIGN(0x4);
+  } >esram
+  
+  .text :
+  {
+    CREATE_OBJECT_SYMBOLS
+    __text_load = LOADADDR(.text);
+    __text_start = .;
+    *(.text .text.* .gnu.linkonce.t.*)
+    *(.plt)
+    *(.gnu.warning)
+    *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
+
+    . = ALIGN(0x4);
+    /* These are for running static constructors and destructors under ELF.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*crtend.o(.ctors))
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*crtend.o(.dtors))
+
+    *(.rodata .rodata.* .gnu.linkonce.r.*)
+
+    *(.ARM.extab* .gnu.linkonce.armextab.*)
+    *(.gcc_except_table) 
+    *(.eh_frame_hdr)
+    *(.eh_frame)
+
+    KEEP (*(.init))
+    KEEP (*(.fini))
+
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array))
+    PROVIDE_HIDDEN (__init_array_end = .);
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(.fini_array))
+    KEEP (*(SORT(.fini_array.*)))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  } >external_ram
+  /* .ARM.exidx is sorted, so has to go in its own output section.  */
+   __exidx_start = .;
+  .ARM.exidx :
+  {
+    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+  } >external_ram
+  __exidx_end = .;
+  _etext = .;
+  PROVIDE(__text_end = .);
+
+  .data :
+  {
+    __data_load = LOADADDR (.data);
+    _sidata = LOADADDR (.data);
+    __data_start = .;
+    _sdata = .;
+    KEEP(*(.jcr))
+    *(.got.plt) *(.got)
+    *(.shdata)
+    *(.data .data.* .gnu.linkonce.d.*)
+    . = ALIGN (4);
+    _edata = .;
+  } >external_ram 
+
+  .bss :
+  {
+    __bss_start__ = . ;
+    _sbss = .;
+    *(.shbss)
+    *(.bss .bss.* .gnu.linkonce.b.*)
+    *(COMMON)
+    . = ALIGN (8);
+    __bss_end__ = .;
+    _end = .;
+    __end = _end;
+    _ebss = .;
+    PROVIDE(end = .);
+  } >external_ram 
+
+  /* 
+   * The .stack section is only specified here in order for the linker to generate
+   * an error if the esram is full.
+   */
+  .stack :
+  {
+  	. = ALIGN(4);
+    . += PROCESS_STACK_SIZE;
+    . = ALIGN(4);
+    . += MAIN_STACK_SIZE;
+    . = ALIGN(4);
+  } >external_ram
+  
+  .stab 0 (NOLOAD) :
+  {
+    *(.stab)
+  }
+
+  .stabstr 0 (NOLOAD) :
+  {
+    *(.stabstr)
+  }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+  .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
+  /DISCARD/ : { *(.note.GNU-stack) *(.isr_vector) }
+}
diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/newlib_stubs.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/newlib_stubs.c
new file mode 100644
index 0000000..3b42429
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/newlib_stubs.c
@@ -0,0 +1,247 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ * Stubs for Newlib system calls.

+ *  

+ * SVN $Revision: 2020 $

+ * SVN $Date: 2010-01-20 14:51:50 +0000 (Wed, 20 Jan 2010) $

+ */

+#include <stdlib.h>

+#include <sys/unistd.h>

+#include <sys/stat.h>

+#include <sys/times.h>

+#include <errno.h>

+#undef errno

+extern int errno;

+

+/*==============================================================================

+ * Redirection of standard output to a SmartFusion MSS UART.

+ *------------------------------------------------------------------------------

+ * A default implementation for the redirection of the output of printf() to a

+ * UART is provided as the bottom of this file. This redirection is enabled by

+ * adding the symbol/define ACTEL_STDIO_THRU_UART to your project and

+ * specifying the baud rate using the ACTEL_STDIO_BAUD_RATE define.

+ */

+#ifdef ACTEL_STDIO_THRU_UART

+#include "../../drivers/mss_uart/mss_uart.h"

+

+#ifndef ACTEL_STDIO_BAUD_RATE

+#define ACTEL_STDIO_BAUD_RATE  MSS_UART_57600_BAUD

+#endif

+

+/*------------------------------------------------------------------------------

+ * Global flag used to indicate if the UART driver needs to be initialized.

+ */

+static int g_stdio_uart_init_done = 0;

+

+#endif	/* ACTEL_STDIO_THRU_UART */

+

+/*==============================================================================

+ * Environment variables.

+ * A pointer to a list of environment variables and their values. For a minimal

+ * environment, this empty list is adequate:

+ */

+char *__env[1] = { 0 };

+char **environ = __env;

+

+/*==============================================================================

+ * Close a file.

+ */

+int _close(int file)

+{

+    return -1;

+}

+

+/*==============================================================================

+ * Transfer control to a new process.

+ */

+int _execve(char *name, char **argv, char **env)

+{

+    errno = ENOMEM;

+    return -1;

+}

+

+/*==============================================================================

+ * Exit a program without cleaning up files.

+ */

+void _exit( int code )

+{

+	/* Should we force a system reset? */

+	while( 1 )

+	{

+		;

+	}

+}

+

+/*==============================================================================

+ * Create a new process.

+ */

+int _fork(void)

+{

+    errno = EAGAIN;

+    return -1;

+}

+

+/*==============================================================================

+ * Status of an open file.

+ */

+int _fstat(int file, struct stat *st)

+{

+    st->st_mode = S_IFCHR;

+    return 0;

+}

+

+/*==============================================================================

+ * Process-ID

+ */

+int _getpid(void)

+{

+    return 1;

+}

+

+/*==============================================================================

+ * Query whether output stream is a terminal.

+ */

+int _isatty(int file)

+{

+    return 1;

+}

+

+/*==============================================================================

+ * Send a signal.

+ */

+int _kill(int pid, int sig)

+{

+    errno = EINVAL;

+    return -1;

+}

+

+/*==============================================================================

+ * Establish a new name for an existing file.

+ */

+int _link(char *old, char *new)

+{

+    errno = EMLINK;

+    return -1;

+}

+

+/*==============================================================================

+ * Set position in a file.

+ */

+int _lseek(int file, int ptr, int dir)

+{

+    return 0;

+}

+

+/*==============================================================================

+ * Open a file.

+ */

+int _open(const char *name, int flags, int mode)

+{

+    return -1;

+}

+

+/*==============================================================================

+ * Read from a file.

+ */

+int _read(int file, char *ptr, int len)

+{

+    return 0;

+}

+

+/*==============================================================================

+ * Increase program data space. As malloc and related functions depend on this,

+ * it is useful to have a working implementation. The following suffices for a

+ * standalone system; it exploits the symbol _end automatically defined by the

+ * GNU linker. 

+ */

+caddr_t _sbrk(int incr)

+{

+    extern char _end;		/* Defined by the linker */

+    static char *heap_end;

+    char *prev_heap_end;

+    char * stack_ptr;

+    

+    if (heap_end == 0)

+    {

+      heap_end = &_end;

+    }

+    

+    prev_heap_end = heap_end;

+    asm volatile ("MRS %0, msp" : "=r" (stack_ptr) );

+    if (heap_end + incr > stack_ptr)

+    {

+      write (1, "Heap and stack collision\n", 25);

+      abort ();

+    }

+  

+    heap_end += incr;

+    return (caddr_t) prev_heap_end;

+}

+

+/*==============================================================================

+ * Status of a file (by name).

+ */

+int _stat(char *file, struct stat *st)

+{

+    st->st_mode = S_IFCHR;

+    return 0;

+}

+

+/*==============================================================================

+ * Timing information for current process.

+ */

+int _times(struct tms *buf)

+{

+    return -1;

+}

+

+/*==============================================================================

+ * Remove a file's directory entry.

+ */

+int _unlink(char *name)

+{

+    errno = ENOENT;

+    return -1;

+}

+

+/*==============================================================================

+ * Wait for a child process.

+ */

+int _wait(int *status)

+{

+    errno = ECHILD;

+    return -1;

+}

+

+/*==============================================================================

+ * Write to a file. libc subroutines will use this system routine for output to

+ * all files, including stdout—so if you need to generate any output, for

+ * example to a serial port for debugging, you should make your minimal write

+ * capable of doing this.

+ */

+int _write_r( void * reent, int file, char * ptr, int len )

+{

+#ifdef ACTEL_STDIO_THRU_UART

+	/*--------------------------------------------------------------------------

+	 * Initialize the UART driver if it is the first time this function is

+	 * called.

+	 */

+	if ( !g_stdio_uart_init_done )

+	{

+		MSS_UART_init( &g_mss_uart0, ACTEL_STDIO_BAUD_RATE, (MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY));

+		g_stdio_uart_init_done = 1;

+	}

+	

+	/*--------------------------------------------------------------------------

+	 * Output text to the UART.

+	 */

+	MSS_UART_polled_tx( &g_mss_uart0, (uint8_t *)ptr, len );

+	

+	return len;

+#else	/* ACTEL_STDIO_THRU_UART */

+	return 0;

+#endif	/* ACTEL_STDIO_THRU_UART */

+}

+

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-execute-in-place.ld b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-execute-in-place.ld
new file mode 100644
index 0000000..cfaddb6
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-execute-in-place.ld
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.
+ * 
+ * SmartFusion/Cortex-M3 linker script creating an executable image for use in
+ * the Libero flow for executing code in place in internal eNVM.
+ *
+ * SVN $Revision: 1766 $
+ * SVN $Date: 2009-12-11 16:33:35 +0000 (Fri, 11 Dec 2009) $
+ */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+	      "elf32-littlearm")
+GROUP(-lc -lgcc -lm)
+OUTPUT_ARCH(arm)
+ENTRY(Reset_Handler)
+SEARCH_DIR(.)
+__DYNAMIC  =  0;
+
+/*******************************************************************************
+ * Start of board customization.
+ *******************************************************************************/
+MEMORY
+{
+  /* SmartFusion internal eNVM */
+  rom (rx) : ORIGIN = 0, LENGTH = 256k
+  
+  /* SmartFusion internal eSRAM */
+  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
+}
+
+RAM_START_ADDRESS = 0x20000000;	/* Must be the same value as MEMORY region ram ORIGIN above. */
+RAM_SIZE = 64k;					/* Must be the same value as MEMORY region ram LENGTH above. */
+MAIN_STACK_SIZE = 8k;			/* Cortex main stack size. */
+PROCESS_STACK_SIZE	= 4k;		/* Cortex process stack size (only available with OS extensions).*/
+
+/*******************************************************************************
+ * End of board customization.
+ *******************************************************************************/
+ 
+PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE);
+PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE);
+PROVIDE (_estack = __main_stack_start);
+PROVIDE (__mirrored_nvm = 0);   /* Indicate to startup code that NVM is not mirrored to VMA address .text copy is required. */
+
+SECTIONS
+{
+  .reset :
+  {
+    *(.isr_vector)
+    *sys_boot.o(.text)
+    . = ALIGN(0x4);
+  } >rom
+  
+  .text :
+  {
+    CREATE_OBJECT_SYMBOLS
+    __text_load = LOADADDR(.text);
+    __text_start = .;
+    
+    *(.text .text.* .gnu.linkonce.t.*)
+    *(.plt)
+    *(.gnu.warning)
+    *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
+
+    . = ALIGN(0x4);
+    /* These are for running static constructors and destructors under ELF.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*crtend.o(.ctors))
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*crtend.o(.dtors))
+
+    *(.rodata .rodata.* .gnu.linkonce.r.*)
+
+    *(.ARM.extab* .gnu.linkonce.armextab.*)
+    *(.gcc_except_table) 
+    *(.eh_frame_hdr)
+    *(.eh_frame)
+
+    KEEP (*(.init))
+    KEEP (*(.fini))
+
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array))
+    PROVIDE_HIDDEN (__init_array_end = .);
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(.fini_array))
+    KEEP (*(SORT(.fini_array.*)))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  } >rom
+  /* .ARM.exidx is sorted, so has to go in its own output section.  */
+   __exidx_start = .;
+  .ARM.exidx :
+  {
+    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+  } >rom
+  __exidx_end = .;
+  _etext = .;
+
+  .data :
+  {
+    __data_load = LOADADDR(.data);
+    _sidata = LOADADDR (.data);
+    __data_start = .;
+    _sdata = .;
+    KEEP(*(.jcr))
+    *(.got.plt) *(.got)
+    *(.shdata)
+    *(.data .data.* .gnu.linkonce.d.*)
+    . = ALIGN (4);
+  	_edata = .;
+  } >ram AT>rom
+
+  .bss :
+  {
+    __bss_start__ = . ;
+    _sbss = .;
+    *(.shbss)
+    *(.bss .bss.* .gnu.linkonce.b.*)
+    *(COMMON)
+    . = ALIGN (8);
+    __bss_end__ = .;
+    _end = .;
+    __end = _end;
+    _ebss = .;
+    PROVIDE(end = .);
+  } >ram AT>rom
+
+  .stab 0 (NOLOAD) :
+  {
+    *(.stab)
+  }
+
+  .stabstr 0 (NOLOAD) :
+  {
+    *(.stabstr)
+  }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+  .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
+  /DISCARD/ : { *(.note.GNU-stack)  }
+}
diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-relocate-executable.ld b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-relocate-executable.ld
new file mode 100644
index 0000000..21e613c
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-relocate-executable.ld
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.
+ * 
+ * SmartFusion/Cortex-M3 linker script creating an executable image for use in
+ * the Libero flow for relocating executable from internal eNVM to external RAM
+ * before starting execution.
+ *
+ * SVN $Revision: 1766 $
+ * SVN $Date: 2009-12-11 16:33:35 +0000 (Fri, 11 Dec 2009) $
+ */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+	      "elf32-littlearm")
+GROUP(-lc -lgcc -lm)
+OUTPUT_ARCH(arm)
+ENTRY(Reset_Handler)
+SEARCH_DIR(.)
+__DYNAMIC  =  0;
+
+/*******************************************************************************
+ * Start of board customization.
+ *******************************************************************************/
+MEMORY
+{
+  /* SmartFusion internal eNVM */
+  rom (rx) : ORIGIN = 0, LENGTH = 256k
+  
+  /* SmartFusion internal eSRAM */
+  esram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
+  
+  /* SmartFusion development board external RAM */
+  external_ram (rwx) : ORIGIN = 0x70000000, LENGTH = 2M
+}
+
+RAM_START_ADDRESS = 0x20000000;	/* Must be the same value as MEMORY region esram ORIGIN above. */
+RAM_SIZE = 64k;					/* Must be the same value as MEMORY region esram LENGTH above. */
+MAIN_STACK_SIZE = 8k;			/* Cortex main stack size. */
+PROCESS_STACK_SIZE	= 4k;		/* Cortex process stack size (only available with OS extensions).*/
+
+/*******************************************************************************
+ * End of board customization.
+ *******************************************************************************/
+ 
+PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE);
+PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE);
+PROVIDE (_estack = __main_stack_start);
+PROVIDE (__mirrored_nvm = 0);   /* Indicate to startup code that NVM is not mirrored to VMA address .text copy is required. */
+
+SECTIONS
+{
+  .reset :
+  {
+    *(.isr_vector)
+/*    *sys_boot.o(.text)*/
+    . = ALIGN(0x4);
+  } >rom
+  
+  .text :
+  {
+    CREATE_OBJECT_SYMBOLS
+    __text_load = LOADADDR(.text);
+    __text_start = .;
+    
+    *(.text .text.* .gnu.linkonce.t.*)
+    *(.plt)
+    *(.gnu.warning)
+    *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
+
+    . = ALIGN(0x4);
+    /* These are for running static constructors and destructors under ELF.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*crtend.o(.ctors))
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*crtend.o(.dtors))
+
+    *(.rodata .rodata.* .gnu.linkonce.r.*)
+
+    *(.ARM.extab* .gnu.linkonce.armextab.*)
+    *(.gcc_except_table) 
+    *(.eh_frame_hdr)
+    *(.eh_frame)
+
+    KEEP (*(.init))
+    KEEP (*(.fini))
+
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array))
+    PROVIDE_HIDDEN (__init_array_end = .);
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(.fini_array))
+    KEEP (*(SORT(.fini_array.*)))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  } >external_ram AT>rom
+  /* .ARM.exidx is sorted, so has to go in its own output section.  */
+   __exidx_start = .;
+  .ARM.exidx :
+  {
+    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+  } >external_ram AT>rom
+  __exidx_end = .;
+  _etext = .;
+
+  .data :
+  {
+    __data_load = LOADADDR(.data);
+    _sidata = LOADADDR (.data);
+    __data_start = .;
+    _sdata = .;
+    KEEP(*(.jcr))
+    *(.got.plt) *(.got)
+    *(.shdata)
+    *(.data .data.* .gnu.linkonce.d.*)
+    . = ALIGN (4);
+  	_edata = .;
+  } >esram AT>rom
+
+  .bss :
+  {
+    __bss_start__ = . ;
+    _sbss = .;
+    *(.shbss)
+    *(.bss .bss.* .gnu.linkonce.b.*)
+    *(COMMON)
+    . = ALIGN (8);
+    __bss_end__ = .;
+    _end = .;
+    __end = _end;
+    _ebss = .;
+    PROVIDE(end = .);
+  } >esram AT>rom
+
+  .stab 0 (NOLOAD) :
+  {
+    *(.stab)
+  }
+
+  .stabstr 0 (NOLOAD) :
+  {
+    *(.stabstr)
+  }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+  .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
+  /DISCARD/ : { *(.note.GNU-stack)  }
+}
diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/startup_a2fxxxm3.s b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/startup_a2fxxxm3.s
new file mode 100644
index 0000000..e9e87ad
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/startup_a2fxxxm3.s
@@ -0,0 +1,1504 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ *  SmartFusion A2FXXXM3 vector table and startup code.

+ *

+ * SVN $Revision: 2068 $

+ * SVN $Date: 2010-01-27 17:27:41 +0000 (Wed, 27 Jan 2010) $

+ */

+

+	.syntax unified

+    .cpu cortex-m3

+    .thumb

+    

+

+/*==============================================================================

+ * Vector table

+ */

+    .global     g_pfnVectors

+    .section    .isr_vector,"a",%progbits

+    .type       g_pfnVectors, %object

+    .size       g_pfnVectors, .-g_pfnVectors

+    

+g_pfnVectors:

+    .word  _estack

+    .word  Reset_Handler

+    .word  NMI_Handler

+    .word  HardFault_Handler

+    .word  MemManage_Handler

+    .word  BusFault_Handler

+    .word  UsageFault_Handler

+    .word  0

+    .word  0

+    .word  0

+    .word  0

+    .word  SVC_Handler

+    .word  DebugMon_Handler

+    .word  0

+    .word  PendSV_Handler

+    .word  SysTick_Handler

+    .word  WdogWakeup_IRQHandler

+    .word  BrownOut_1_5V_IRQHandler

+    .word  BrownOut_3_3V_IRQHandler

+    .word  RTC_Match_IRQHandler

+    .word  RTCIF_Pub_IRQHandler

+    .word  EthernetMAC_IRQHandler

+    .word  IAP_IRQHandler

+    .word  ENVM0_IRQHandler

+    .word  ENVM1_IRQHandler

+    .word  DMA_IRQHandler

+    .word  UART0_IRQHandler

+    .word  UART1_IRQHandler

+    .word  SPI0_IRQHandler

+    .word  SPI1_IRQHandler

+    .word  I2C0_IRQHandler

+    .word  I2C0_SMBAlert_IRQHandler

+    .word  I2C0_SMBus_IRQHandler

+    .word  I2C1_IRQHandler

+    .word  I2C1_SMBAlert_IRQHandler

+    .word  I2C1_SMBus_IRQHandler

+    .word  Timer1_IRQHandler

+    .word  Timer2_IRQHandler

+    .word  PLL_Lock_IRQHandler

+    .word  PLL_LockLost_IRQHandler

+    .word  CommError_IRQHandler

+    .word  0

+    .word  0

+    .word  0

+    .word  0

+    .word  0

+    .word  0

+    .word  Fabric_IRQHandler

+    .word  GPIO0_IRQHandler

+    .word  GPIO1_IRQHandler

+    .word  GPIO2_IRQHandler

+    .word  GPIO3_IRQHandler

+    .word  GPIO4_IRQHandler

+    .word  GPIO5_IRQHandler

+    .word  GPIO6_IRQHandler

+    .word  GPIO7_IRQHandler

+    .word  GPIO8_IRQHandler

+    .word  GPIO9_IRQHandler

+    .word  GPIO10_IRQHandler

+    .word  GPIO11_IRQHandler

+    .word  GPIO12_IRQHandler

+    .word  GPIO13_IRQHandler

+    .word  GPIO14_IRQHandler

+    .word  GPIO15_IRQHandler

+    .word  GPIO16_IRQHandler

+    .word  GPIO17_IRQHandler

+    .word  GPIO18_IRQHandler

+    .word  GPIO19_IRQHandler

+    .word  GPIO20_IRQHandler

+    .word  GPIO21_IRQHandler

+    .word  GPIO22_IRQHandler

+    .word  GPIO23_IRQHandler

+    .word  GPIO24_IRQHandler

+    .word  GPIO25_IRQHandler

+    .word  GPIO26_IRQHandler

+    .word  GPIO27_IRQHandler

+    .word  GPIO28_IRQHandler

+    .word  GPIO29_IRQHandler

+    .word  GPIO30_IRQHandler

+    .word  GPIO31_IRQHandler

+    .word  ACE_PC0_Flag0_IRQHandler

+    .word  ACE_PC0_Flag1_IRQHandler

+    .word  ACE_PC0_Flag2_IRQHandler

+    .word  ACE_PC0_Flag3_IRQHandler

+    .word  ACE_PC1_Flag0_IRQHandler

+    .word  ACE_PC1_Flag1_IRQHandler

+    .word  ACE_PC1_Flag2_IRQHandler

+    .word  ACE_PC1_Flag3_IRQHandler

+    .word  ACE_PC2_Flag0_IRQHandler

+    .word  ACE_PC2_Flag1_IRQHandler

+    .word  ACE_PC2_Flag2_IRQHandler

+    .word  ACE_PC2_Flag3_IRQHandler

+    .word  ACE_ADC0_DataValid_IRQHandler

+    .word  ACE_ADC1_DataValid_IRQHandler

+    .word  ACE_ADC2_DataValid_IRQHandler

+    .word  ACE_ADC0_CalDone_IRQHandler

+    .word  ACE_ADC1_CalDone_IRQHandler

+    .word  ACE_ADC2_CalDone_IRQHandler

+    .word  ACE_ADC0_CalStart_IRQHandler

+    .word  ACE_ADC1_CalStart_IRQHandler

+    .word  ACE_ADC2_CalStart_IRQHandler

+    .word  ACE_Comp0_Fall_IRQHandler

+    .word  ACE_Comp1_Fall_IRQHandler

+    .word  ACE_Comp2_Fall_IRQHandler

+    .word  ACE_Comp3_Fall_IRQHandler

+    .word  ACE_Comp4_Fall_IRQHandler

+    .word  ACE_Comp5_Fall_IRQHandler

+    .word  ACE_Comp6_Fall_IRQHandler

+    .word  ACE_Comp7_Fall_IRQHandler

+    .word  ACE_Comp8_Fall_IRQHandler

+    .word  ACE_Comp9_Fall_IRQHandler

+    .word  ACE_Comp10_Fall_IRQHandler

+    .word  ACE_Comp11_Fall_IRQHandler

+    .word  ACE_Comp0_Rise_IRQHandler

+    .word  ACE_Comp1_Rise_IRQHandler

+    .word  ACE_Comp2_Rise_IRQHandler

+    .word  ACE_Comp3_Rise_IRQHandler

+    .word  ACE_Comp4_Rise_IRQHandler

+    .word  ACE_Comp5_Rise_IRQHandler

+    .word  ACE_Comp6_Rise_IRQHandler

+    .word  ACE_Comp7_Rise_IRQHandler

+    .word  ACE_Comp8_Rise_IRQHandler

+    .word  ACE_Comp9_Rise_IRQHandler

+    .word  ACE_Comp10_Rise_IRQHandler

+    .word  ACE_Comp11_Rise_IRQHandler

+    .word  ACE_ADC0_FifoFull_IRQHandler

+    .word  ACE_ADC0_FifoAFull_IRQHandler

+    .word  ACE_ADC0_FifoEmpty_IRQHandler

+    .word  ACE_ADC1_FifoFull_IRQHandler

+    .word  ACE_ADC1_FifoAFull_IRQHandler

+    .word  ACE_ADC1_FifoEmpty_IRQHandler

+    .word  ACE_ADC2_FifoFull_IRQHandler

+    .word  ACE_ADC2_FifoAFull_IRQHandler

+    .word  ACE_ADC2_FifoEmpty_IRQHandler

+    .word  ACE_PPE_Flag0_IRQHandler

+    .word  ACE_PPE_Flag1_IRQHandler

+    .word  ACE_PPE_Flag2_IRQHandler

+    .word  ACE_PPE_Flag3_IRQHandler

+    .word  ACE_PPE_Flag4_IRQHandler

+    .word  ACE_PPE_Flag5_IRQHandler

+    .word  ACE_PPE_Flag6_IRQHandler

+    .word  ACE_PPE_Flag7_IRQHandler

+    .word  ACE_PPE_Flag8_IRQHandler

+    .word  ACE_PPE_Flag9_IRQHandler

+    .word  ACE_PPE_Flag10_IRQHandler

+    .word  ACE_PPE_Flag11_IRQHandler

+    .word  ACE_PPE_Flag12_IRQHandler

+    .word  ACE_PPE_Flag13_IRQHandler

+    .word  ACE_PPE_Flag14_IRQHandler

+    .word  ACE_PPE_Flag15_IRQHandler

+    .word  ACE_PPE_Flag16_IRQHandler

+    .word  ACE_PPE_Flag17_IRQHandler

+    .word  ACE_PPE_Flag18_IRQHandler

+    .word  ACE_PPE_Flag19_IRQHandler

+    .word  ACE_PPE_Flag20_IRQHandler

+    .word  ACE_PPE_Flag21_IRQHandler

+    .word  ACE_PPE_Flag22_IRQHandler

+    .word  ACE_PPE_Flag23_IRQHandler

+    .word  ACE_PPE_Flag24_IRQHandler

+    .word  ACE_PPE_Flag25_IRQHandler

+    .word  ACE_PPE_Flag26_IRQHandler

+    .word  ACE_PPE_Flag27_IRQHandler

+    .word  ACE_PPE_Flag28_IRQHandler

+    .word  ACE_PPE_Flag29_IRQHandler

+    .word  ACE_PPE_Flag30_IRQHandler

+    .word  ACE_PPE_Flag31_IRQHandler

+

+	

+/*==============================================================================

+ * Reset_Handler

+ */

+    .global Reset_Handler

+    .type   Reset_Handler, %function

+Reset_Handler:

+_start:

+/*------------------------------------------------------------------------------	

+ * Call CMSIS system init function.

+ * This is not actually required for SmartFusioon as all low initialisations are

+ * done as part of the system boot.

+ */

+;    ldr     r0, =SystemInit

+;    blx     r0

+    

+/*------------------------------------------------------------------------------	 

+ * Check if the executable is built for NVM LMA mirrored to VMA address.

+ * This is done for debugging executables running out of eNVM with SoftConsole.

+ * The .text section should not be copied in this case since both the LMA and

+ * VMA point at the eNVM despite the LMA and VMa having different values.

+ */

+    ldr r0, =__mirrored_nvm

+    cmp r0, #0

+    bne copy_data

+    

+/*------------------------------------------------------------------------------	 

+ * Copy code section.

+ */

+	ldr r0, =__text_load

+	ldr r1, =__text_start

+	ldr r2, =_etext

+	cmp r0, r1

+	beq copy_data

+copy_code_loop:

+	cmp r1, r2

+    itt ne

+	ldrne r3, [r0], #4

+	strne r3, [r1], #4

+	bne copy_code_loop

+

+/*------------------------------------------------------------------------------	

+ * Copy data section.

+ */

+copy_data:

+	ldr r0, =__data_load

+	ldr r1, =__data_start

+	ldr r2, =_edata

+	cmp r0, r1

+	beq clear_bss

+copy_data_loop:

+	cmp r1, r2

+    itt ne

+	ldrne r3, [r0], #4

+	strne r3, [r1], #4

+	bne copy_data_loop

+	

+/*------------------------------------------------------------------------------	

+ * Clear .bss

+ */

+clear_bss:

+	ldr r0, =0

+	ldr r1, =__bss_start__

+	ldr r2, =__bss_end__

+clear_bss_loop:

+	cmp r1, r2

+    it ne

+	strne r0, [r1], #4

+	bne clear_bss_loop

+

+/*------------------------------------------------------------------------------	

+ * Call global constructors

+ */

+call_glob_ctor:

+	ldr r0, =__libc_init_array

+    add lr, pc, #3

+ 	bx r0

+

+/*------------------------------------------------------------------------------	

+ * branch to main.

+ */

+branch_to_main: 	 

+	mov	r0, #0		/*  no arguments  */

+	mov	r1, #0		/*  no argv either */

+    ldr pc, =main

+

+ExitLoop:

+    B ExitLoop

+

+/*==============================================================================

+ * NMI_Handler

+ */

+    .weak   NMI_Handler

+    .type   NMI_Handler, %function

+NMI_Handler:

+    B .

+

+/*==============================================================================

+ * HardFault_Handler

+ */

+    .weak   HardFault_Handler

+    .type   HardFault_Handler, %function

+HardFault_Handler:

+    B .

+

+/*==============================================================================

+ * MemManage_Handler

+ */

+    .weak   MemManage_Handler

+    .type   MemManage_Handler, %function

+MemManage_Handler:

+    B .

+

+/*==============================================================================

+ * BusFault_Handler

+ */

+    .weak   BusFault_Handler

+    .type   BusFault_Handler, %function

+BusFault_Handler:

+    B .

+

+/*==============================================================================

+ * UsageFault_Handler

+ */

+    .weak   UsageFault_Handler

+    .type   UsageFault_Handler, %function

+UsageFault_Handler:

+    B .

+

+/*==============================================================================

+ * SVC_Handler

+ */

+    .weak   SVC_Handler

+    .type   SVC_Handler, %function

+SVC_Handler:

+    B .

+

+/*==============================================================================

+ * DebugMon_Handler

+ */

+    .weak   DebugMon_Handler

+    .type   DebugMon_Handler, %function

+DebugMon_Handler:

+    B .

+

+/*==============================================================================

+ * PendSV_Handler

+ */

+    .weak   PendSV_Handler

+    .type   PendSV_Handler, %function

+PendSV_Handler:

+    B .

+

+/*==============================================================================

+ * SysTick_Handler

+ */

+    .weak   SysTick_Handler

+    .type   SysTick_Handler, %function

+SysTick_Handler:

+    B .

+

+/*==============================================================================

+ * WdogWakeup_IRQHandler

+ */

+    .weak   WdogWakeup_IRQHandler

+    .type   WdogWakeup_IRQHandler, %function

+WdogWakeup_IRQHandler:

+    B .

+

+/*==============================================================================

+ * BrownOut_1_5V_IRQHandler

+ */

+    .weak   BrownOut_1_5V_IRQHandler

+    .type   BrownOut_1_5V_IRQHandler, %function

+BrownOut_1_5V_IRQHandler:

+    B .

+

+/*==============================================================================

+ * BrownOut_3_3V_IRQHandler

+ */

+    .weak   BrownOut_3_3V_IRQHandler

+    .type   BrownOut_3_3V_IRQHandler, %function

+BrownOut_3_3V_IRQHandler:

+    B .

+

+/*==============================================================================

+ * RTC_Match_IRQHandler

+ */

+    .weak   RTC_Match_IRQHandler

+    .type   RTC_Match_IRQHandler, %function

+RTC_Match_IRQHandler:

+    B .

+

+/*==============================================================================

+ * RTCIF_Pub_IRQHandler

+ */

+    .weak   RTCIF_Pub_IRQHandler

+    .type   RTCIF_Pub_IRQHandler, %function

+RTCIF_Pub_IRQHandler:

+    B .

+

+/*==============================================================================

+ * EthernetMAC_IRQHandler

+ */

+    .weak   EthernetMAC_IRQHandler

+    .type   EthernetMAC_IRQHandler, %function

+EthernetMAC_IRQHandler:

+    B .

+

+/*==============================================================================

+ * IAP_IRQHandler

+ */

+    .weak   IAP_IRQHandler

+    .type   IAP_IRQHandler, %function

+IAP_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ENVM0_IRQHandler

+ */

+    .weak   ENVM0_IRQHandler

+    .type   ENVM0_IRQHandler, %function

+ENVM0_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ENVM1_IRQHandler

+ */

+    .weak   ENVM1_IRQHandler

+    .type   ENVM1_IRQHandler, %function

+ENVM1_IRQHandler:

+    B .

+

+/*==============================================================================

+ * DMA_IRQHandler

+ */

+    .weak   DMA_IRQHandler

+    .type   DMA_IRQHandler, %function

+DMA_IRQHandler:

+    B .

+

+/*==============================================================================

+ * UART0_IRQHandler

+ */

+    .weak   UART0_IRQHandler

+    .type   UART0_IRQHandler, %function

+UART0_IRQHandler:

+    B .

+

+/*==============================================================================

+ * UART1_IRQHandler

+ */

+    .weak   UART1_IRQHandler

+    .type   UART1_IRQHandler, %function

+UART1_IRQHandler:

+    B .

+

+/*==============================================================================

+ * SPI0_IRQHandler

+ */

+    .weak   SPI0_IRQHandler

+    .type   SPI0_IRQHandler, %function

+SPI0_IRQHandler:

+    B .

+

+/*==============================================================================

+ * SPI1_IRQHandler

+ */

+    .weak   SPI1_IRQHandler

+    .type   SPI1_IRQHandler, %function

+SPI1_IRQHandler:

+    B .

+

+/*==============================================================================

+ * I2C0_IRQHandler

+ */

+    .weak   I2C0_IRQHandler

+    .type   I2C0_IRQHandler, %function

+I2C0_IRQHandler:

+    B .

+

+/*==============================================================================

+ * I2C0_SMBAlert_IRQHandler

+ */

+    .weak   I2C0_SMBAlert_IRQHandler

+    .type   I2C0_SMBAlert_IRQHandler, %function

+I2C0_SMBAlert_IRQHandler:

+    B .

+

+/*==============================================================================

+ * I2C0_SMBus_IRQHandler

+ */

+    .weak   I2C0_SMBus_IRQHandler

+    .type   I2C0_SMBus_IRQHandler, %function

+I2C0_SMBus_IRQHandler:

+    B .

+

+/*==============================================================================

+ * I2C1_IRQHandler

+ */

+    .weak   I2C1_IRQHandler

+    .type   I2C1_IRQHandler, %function

+I2C1_IRQHandler:

+    B .

+

+/*==============================================================================

+ * I2C1_SMBAlert_IRQHandler

+ */

+    .weak   I2C1_SMBAlert_IRQHandler

+    .type   I2C1_SMBAlert_IRQHandler, %function

+I2C1_SMBAlert_IRQHandler:

+    B .

+

+/*==============================================================================

+ * I2C1_SMBus_IRQHandler

+ */

+    .weak   I2C1_SMBus_IRQHandler

+    .type   I2C1_SMBus_IRQHandler, %function

+I2C1_SMBus_IRQHandler:

+    B .

+

+/*==============================================================================

+ * Timer1_IRQHandler

+ */

+    .weak   Timer1_IRQHandler

+    .type   Timer1_IRQHandler, %function

+Timer1_IRQHandler:

+    B .

+

+/*==============================================================================

+ * Timer2_IRQHandler

+ */

+    .weak   Timer2_IRQHandler

+    .type   Timer2_IRQHandler, %function

+Timer2_IRQHandler:

+    B .

+

+/*==============================================================================

+ * PLL_Lock_IRQHandler

+ */

+    .weak   PLL_Lock_IRQHandler

+    .type   PLL_Lock_IRQHandler, %function

+PLL_Lock_IRQHandler:

+    B .

+

+/*==============================================================================

+ * PLL_LockLost_IRQHandler

+ */

+    .weak   PLL_LockLost_IRQHandler

+    .type   PLL_LockLost_IRQHandler, %function

+PLL_LockLost_IRQHandler:

+    B .

+

+/*==============================================================================

+ * CommError_IRQHandler

+ */

+    .weak   CommError_IRQHandler

+    .type   CommError_IRQHandler, %function

+CommError_IRQHandler:

+    B .

+

+/*==============================================================================

+ * Fabric_IRQHandler

+ */

+    .weak   Fabric_IRQHandler

+    .type   Fabric_IRQHandler, %function

+Fabric_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO0_IRQHandler

+ */

+    .weak   GPIO0_IRQHandler

+    .type   GPIO0_IRQHandler, %function

+GPIO0_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO1_IRQHandler

+ */

+    .weak   GPIO1_IRQHandler

+    .type   GPIO1_IRQHandler, %function

+GPIO1_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO2_IRQHandler

+ */

+    .weak   GPIO2_IRQHandler

+    .type   GPIO2_IRQHandler, %function

+GPIO2_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO3_IRQHandler

+ */

+    .weak   GPIO3_IRQHandler

+    .type   GPIO3_IRQHandler, %function

+GPIO3_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO4_IRQHandler

+ */

+    .weak   GPIO4_IRQHandler

+    .type   GPIO4_IRQHandler, %function

+GPIO4_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO5_IRQHandler

+ */

+    .weak   GPIO5_IRQHandler

+    .type   GPIO5_IRQHandler, %function

+GPIO5_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO6_IRQHandler

+ */

+    .weak   GPIO6_IRQHandler

+    .type   GPIO6_IRQHandler, %function

+GPIO6_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO7_IRQHandler

+ */

+    .weak   GPIO7_IRQHandler

+    .type   GPIO7_IRQHandler, %function

+GPIO7_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO8_IRQHandler

+ */

+    .weak   GPIO8_IRQHandler

+    .type   GPIO8_IRQHandler, %function

+GPIO8_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO9_IRQHandler

+ */

+    .weak   GPIO9_IRQHandler

+    .type   GPIO9_IRQHandler, %function

+GPIO9_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO10_IRQHandler

+ */

+    .weak   GPIO10_IRQHandler

+    .type   GPIO10_IRQHandler, %function

+GPIO10_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO11_IRQHandler

+ */

+    .weak   GPIO11_IRQHandler

+    .type   GPIO11_IRQHandler, %function

+GPIO11_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO12_IRQHandler

+ */

+    .weak   GPIO12_IRQHandler

+    .type   GPIO12_IRQHandler, %function

+GPIO12_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO13_IRQHandler

+ */

+    .weak   GPIO13_IRQHandler

+    .type   GPIO13_IRQHandler, %function

+GPIO13_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO14_IRQHandler

+ */

+    .weak   GPIO14_IRQHandler

+    .type   GPIO14_IRQHandler, %function

+GPIO14_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO15_IRQHandler

+ */

+    .weak   GPIO15_IRQHandler

+    .type   GPIO15_IRQHandler, %function

+GPIO15_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO16_IRQHandler

+ */

+    .weak   GPIO16_IRQHandler

+    .type   GPIO16_IRQHandler, %function

+GPIO16_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO17_IRQHandler

+ */

+    .weak   GPIO17_IRQHandler

+    .type   GPIO17_IRQHandler, %function

+GPIO17_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO18_IRQHandler

+ */

+    .weak   GPIO18_IRQHandler

+    .type   GPIO18_IRQHandler, %function

+GPIO18_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO19_IRQHandler

+ */

+    .weak   GPIO19_IRQHandler

+    .type   GPIO19_IRQHandler, %function

+GPIO19_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO20_IRQHandler

+ */

+    .weak   GPIO20_IRQHandler

+    .type   GPIO20_IRQHandler, %function

+GPIO20_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO21_IRQHandler

+ */

+    .weak   GPIO21_IRQHandler

+    .type   GPIO21_IRQHandler, %function

+GPIO21_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO22_IRQHandler

+ */

+    .weak   GPIO22_IRQHandler

+    .type   GPIO22_IRQHandler, %function

+GPIO22_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO23_IRQHandler

+ */

+    .weak   GPIO23_IRQHandler

+    .type   GPIO23_IRQHandler, %function

+GPIO23_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO24_IRQHandler

+ */

+    .weak   GPIO24_IRQHandler

+    .type   GPIO24_IRQHandler, %function

+GPIO24_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO25_IRQHandler

+ */

+    .weak   GPIO25_IRQHandler

+    .type   GPIO25_IRQHandler, %function

+GPIO25_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO26_IRQHandler

+ */

+    .weak   GPIO26_IRQHandler

+    .type   GPIO26_IRQHandler, %function

+GPIO26_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO27_IRQHandler

+ */

+    .weak   GPIO27_IRQHandler

+    .type   GPIO27_IRQHandler, %function

+GPIO27_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO28_IRQHandler

+ */

+    .weak   GPIO28_IRQHandler

+    .type   GPIO28_IRQHandler, %function

+GPIO28_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO29_IRQHandler

+ */

+    .weak   GPIO29_IRQHandler

+    .type   GPIO29_IRQHandler, %function

+GPIO29_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO30_IRQHandler

+ */

+    .weak   GPIO30_IRQHandler

+    .type   GPIO30_IRQHandler, %function

+GPIO30_IRQHandler:

+    B .

+

+/*==============================================================================

+ * GPIO31_IRQHandler

+ */

+    .weak   GPIO31_IRQHandler

+    .type   GPIO31_IRQHandler, %function

+GPIO31_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PC0_Flag0_IRQHandler

+ */

+    .weak   ACE_PC0_Flag0_IRQHandler

+    .type   ACE_PC0_Flag0_IRQHandler, %function

+ACE_PC0_Flag0_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PC0_Flag1_IRQHandler

+ */

+    .weak   ACE_PC0_Flag1_IRQHandler

+    .type   ACE_PC0_Flag1_IRQHandler, %function

+ACE_PC0_Flag1_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PC0_Flag2_IRQHandler

+ */

+    .weak   ACE_PC0_Flag2_IRQHandler

+    .type   ACE_PC0_Flag2_IRQHandler, %function

+ACE_PC0_Flag2_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PC0_Flag3_IRQHandler

+ */

+    .weak   ACE_PC0_Flag3_IRQHandler

+    .type   ACE_PC0_Flag3_IRQHandler, %function

+ACE_PC0_Flag3_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PC1_Flag0_IRQHandler

+ */

+    .weak   ACE_PC1_Flag0_IRQHandler

+    .type   ACE_PC1_Flag0_IRQHandler, %function

+ACE_PC1_Flag0_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PC1_Flag1_IRQHandler

+ */

+    .weak   ACE_PC1_Flag1_IRQHandler

+    .type   ACE_PC1_Flag1_IRQHandler, %function

+ACE_PC1_Flag1_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PC1_Flag2_IRQHandler

+ */

+    .weak   ACE_PC1_Flag2_IRQHandler

+    .type   ACE_PC1_Flag2_IRQHandler, %function

+ACE_PC1_Flag2_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PC1_Flag3_IRQHandler

+ */

+    .weak   ACE_PC1_Flag3_IRQHandler

+    .type   ACE_PC1_Flag3_IRQHandler, %function

+ACE_PC1_Flag3_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PC2_Flag0_IRQHandler

+ */

+    .weak   ACE_PC2_Flag0_IRQHandler

+    .type   ACE_PC2_Flag0_IRQHandler, %function

+ACE_PC2_Flag0_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PC2_Flag1_IRQHandler

+ */

+    .weak   ACE_PC2_Flag1_IRQHandler

+    .type   ACE_PC2_Flag1_IRQHandler, %function

+ACE_PC2_Flag1_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PC2_Flag2_IRQHandler

+ */

+    .weak   ACE_PC2_Flag2_IRQHandler

+    .type   ACE_PC2_Flag2_IRQHandler, %function

+ACE_PC2_Flag2_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PC2_Flag3_IRQHandler

+ */

+    .weak   ACE_PC2_Flag3_IRQHandler

+    .type   ACE_PC2_Flag3_IRQHandler, %function

+ACE_PC2_Flag3_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC0_DataValid_IRQHandler

+ */

+    .weak   ACE_ADC0_DataValid_IRQHandler

+    .type   ACE_ADC0_DataValid_IRQHandler, %function

+ACE_ADC0_DataValid_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC1_DataValid_IRQHandler

+ */

+    .weak   ACE_ADC1_DataValid_IRQHandler

+    .type   ACE_ADC1_DataValid_IRQHandler, %function

+ACE_ADC1_DataValid_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC2_DataValid_IRQHandler

+ */

+    .weak   ACE_ADC2_DataValid_IRQHandler

+    .type   ACE_ADC2_DataValid_IRQHandler, %function

+ACE_ADC2_DataValid_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC0_CalDone_IRQHandler

+ */

+    .weak   ACE_ADC0_CalDone_IRQHandler

+    .type   ACE_ADC0_CalDone_IRQHandler, %function

+ACE_ADC0_CalDone_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC1_CalDone_IRQHandler

+ */

+    .weak   ACE_ADC1_CalDone_IRQHandler

+    .type   ACE_ADC1_CalDone_IRQHandler, %function

+ACE_ADC1_CalDone_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC2_CalDone_IRQHandler

+ */

+    .weak   ACE_ADC2_CalDone_IRQHandler

+    .type   ACE_ADC2_CalDone_IRQHandler, %function

+ACE_ADC2_CalDone_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC0_CalStart_IRQHandler

+ */

+    .weak   ACE_ADC0_CalStart_IRQHandler

+    .type   ACE_ADC0_CalStart_IRQHandler, %function

+ACE_ADC0_CalStart_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC1_CalStart_IRQHandler

+ */

+    .weak   ACE_ADC1_CalStart_IRQHandler

+    .type   ACE_ADC1_CalStart_IRQHandler, %function

+ACE_ADC1_CalStart_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC2_CalStart_IRQHandler

+ */

+    .weak   ACE_ADC2_CalStart_IRQHandler

+    .type   ACE_ADC2_CalStart_IRQHandler, %function

+ACE_ADC2_CalStart_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp0_Fall_IRQHandler

+ */

+    .weak   ACE_Comp0_Fall_IRQHandler

+    .type   ACE_Comp0_Fall_IRQHandler, %function

+ACE_Comp0_Fall_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp1_Fall_IRQHandler

+ */

+    .weak   ACE_Comp1_Fall_IRQHandler

+    .type   ACE_Comp1_Fall_IRQHandler, %function

+ACE_Comp1_Fall_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp2_Fall_IRQHandler

+ */

+    .weak   ACE_Comp2_Fall_IRQHandler

+    .type   ACE_Comp2_Fall_IRQHandler, %function

+ACE_Comp2_Fall_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp3_Fall_IRQHandler

+ */

+    .weak   ACE_Comp3_Fall_IRQHandler

+    .type   ACE_Comp3_Fall_IRQHandler, %function

+ACE_Comp3_Fall_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp4_Fall_IRQHandler

+ */

+    .weak   ACE_Comp4_Fall_IRQHandler

+    .type   ACE_Comp4_Fall_IRQHandler, %function

+ACE_Comp4_Fall_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp5_Fall_IRQHandler

+ */

+    .weak   ACE_Comp5_Fall_IRQHandler

+    .type   ACE_Comp5_Fall_IRQHandler, %function

+ACE_Comp5_Fall_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp6_Fall_IRQHandler

+ */

+    .weak   ACE_Comp6_Fall_IRQHandler

+    .type   ACE_Comp6_Fall_IRQHandler, %function

+ACE_Comp6_Fall_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp7_Fall_IRQHandler

+ */

+    .weak   ACE_Comp7_Fall_IRQHandler

+    .type   ACE_Comp7_Fall_IRQHandler, %function

+ACE_Comp7_Fall_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp8_Fall_IRQHandler

+ */

+    .weak   ACE_Comp8_Fall_IRQHandler

+    .type   ACE_Comp8_Fall_IRQHandler, %function

+ACE_Comp8_Fall_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp9_Fall_IRQHandler

+ */

+    .weak   ACE_Comp9_Fall_IRQHandler

+    .type   ACE_Comp9_Fall_IRQHandler, %function

+ACE_Comp9_Fall_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp10_Fall_IRQHandler

+ */

+    .weak   ACE_Comp10_Fall_IRQHandler

+    .type   ACE_Comp10_Fall_IRQHandler, %function

+ACE_Comp10_Fall_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp11_Fall_IRQHandler

+ */

+    .weak   ACE_Comp11_Fall_IRQHandler

+    .type   ACE_Comp11_Fall_IRQHandler, %function

+ACE_Comp11_Fall_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp0_Rise_IRQHandler

+ */

+    .weak   ACE_Comp0_Rise_IRQHandler

+    .type   ACE_Comp0_Rise_IRQHandler, %function

+ACE_Comp0_Rise_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp1_Rise_IRQHandler

+ */

+    .weak   ACE_Comp1_Rise_IRQHandler

+    .type   ACE_Comp1_Rise_IRQHandler, %function

+ACE_Comp1_Rise_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp2_Rise_IRQHandler

+ */

+    .weak   ACE_Comp2_Rise_IRQHandler

+    .type   ACE_Comp2_Rise_IRQHandler, %function

+ACE_Comp2_Rise_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp3_Rise_IRQHandler

+ */

+    .weak   ACE_Comp3_Rise_IRQHandler

+    .type   ACE_Comp3_Rise_IRQHandler, %function

+ACE_Comp3_Rise_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp4_Rise_IRQHandler

+ */

+    .weak   ACE_Comp4_Rise_IRQHandler

+    .type   ACE_Comp4_Rise_IRQHandler, %function

+ACE_Comp4_Rise_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp5_Rise_IRQHandler

+ */

+    .weak   ACE_Comp5_Rise_IRQHandler

+    .type   ACE_Comp5_Rise_IRQHandler, %function

+ACE_Comp5_Rise_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp6_Rise_IRQHandler

+ */

+    .weak   ACE_Comp6_Rise_IRQHandler

+    .type   ACE_Comp6_Rise_IRQHandler, %function

+ACE_Comp6_Rise_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp7_Rise_IRQHandler

+ */

+    .weak   ACE_Comp7_Rise_IRQHandler

+    .type   ACE_Comp7_Rise_IRQHandler, %function

+ACE_Comp7_Rise_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp8_Rise_IRQHandler

+ */

+    .weak   ACE_Comp8_Rise_IRQHandler

+    .type   ACE_Comp8_Rise_IRQHandler, %function

+ACE_Comp8_Rise_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp9_Rise_IRQHandler

+ */

+    .weak   ACE_Comp9_Rise_IRQHandler

+    .type   ACE_Comp9_Rise_IRQHandler, %function

+ACE_Comp9_Rise_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp10_Rise_IRQHandler

+ */

+    .weak   ACE_Comp10_Rise_IRQHandler

+    .type   ACE_Comp10_Rise_IRQHandler, %function

+ACE_Comp10_Rise_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_Comp11_Rise_IRQHandler

+ */

+    .weak   ACE_Comp11_Rise_IRQHandler

+    .type   ACE_Comp11_Rise_IRQHandler, %function

+ACE_Comp11_Rise_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC0_FifoFull_IRQHandler

+ */

+    .weak   ACE_ADC0_FifoFull_IRQHandler

+    .type   ACE_ADC0_FifoFull_IRQHandler, %function

+ACE_ADC0_FifoFull_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC0_FifoAFull_IRQHandler

+ */

+    .weak   ACE_ADC0_FifoAFull_IRQHandler

+    .type   ACE_ADC0_FifoAFull_IRQHandler, %function

+ACE_ADC0_FifoAFull_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC0_FifoEmpty_IRQHandler

+ */

+    .weak   ACE_ADC0_FifoEmpty_IRQHandler

+    .type   ACE_ADC0_FifoEmpty_IRQHandler, %function

+ACE_ADC0_FifoEmpty_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC1_FifoFull_IRQHandler

+ */

+    .weak   ACE_ADC1_FifoFull_IRQHandler

+    .type   ACE_ADC1_FifoFull_IRQHandler, %function

+ACE_ADC1_FifoFull_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC1_FifoAFull_IRQHandler

+ */

+    .weak   ACE_ADC1_FifoAFull_IRQHandler

+    .type   ACE_ADC1_FifoAFull_IRQHandler, %function

+ACE_ADC1_FifoAFull_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC1_FifoEmpty_IRQHandler

+ */

+    .weak   ACE_ADC1_FifoEmpty_IRQHandler

+    .type   ACE_ADC1_FifoEmpty_IRQHandler, %function

+ACE_ADC1_FifoEmpty_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC2_FifoFull_IRQHandler

+ */

+    .weak   ACE_ADC2_FifoFull_IRQHandler

+    .type   ACE_ADC2_FifoFull_IRQHandler, %function

+ACE_ADC2_FifoFull_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC2_FifoAFull_IRQHandler

+ */

+    .weak   ACE_ADC2_FifoAFull_IRQHandler

+    .type   ACE_ADC2_FifoAFull_IRQHandler, %function

+ACE_ADC2_FifoAFull_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_ADC2_FifoEmpty_IRQHandler

+ */

+    .weak   ACE_ADC2_FifoEmpty_IRQHandler

+    .type   ACE_ADC2_FifoEmpty_IRQHandler, %function

+ACE_ADC2_FifoEmpty_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag0_IRQHandler

+ */

+    .weak   ACE_PPE_Flag0_IRQHandler

+    .type   ACE_PPE_Flag0_IRQHandler, %function

+ACE_PPE_Flag0_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag1_IRQHandler

+ */

+    .weak   ACE_PPE_Flag1_IRQHandler

+    .type   ACE_PPE_Flag1_IRQHandler, %function

+ACE_PPE_Flag1_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag2_IRQHandler

+ */

+    .weak   ACE_PPE_Flag2_IRQHandler

+    .type   ACE_PPE_Flag2_IRQHandler, %function

+ACE_PPE_Flag2_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag3_IRQHandler

+ */

+    .weak   ACE_PPE_Flag3_IRQHandler

+    .type   ACE_PPE_Flag3_IRQHandler, %function

+ACE_PPE_Flag3_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag4_IRQHandler

+ */

+    .weak   ACE_PPE_Flag4_IRQHandler

+    .type   ACE_PPE_Flag4_IRQHandler, %function

+ACE_PPE_Flag4_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag5_IRQHandler

+ */

+    .weak   ACE_PPE_Flag5_IRQHandler

+    .type   ACE_PPE_Flag5_IRQHandler, %function

+ACE_PPE_Flag5_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag6_IRQHandler

+ */

+    .weak   ACE_PPE_Flag6_IRQHandler

+    .type   ACE_PPE_Flag6_IRQHandler, %function

+ACE_PPE_Flag6_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag7_IRQHandler

+ */

+    .weak   ACE_PPE_Flag7_IRQHandler

+    .type   ACE_PPE_Flag7_IRQHandler, %function

+ACE_PPE_Flag7_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag8_IRQHandler

+ */

+    .weak   ACE_PPE_Flag8_IRQHandler

+    .type   ACE_PPE_Flag8_IRQHandler, %function

+ACE_PPE_Flag8_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag9_IRQHandler

+ */

+    .weak   ACE_PPE_Flag9_IRQHandler

+    .type   ACE_PPE_Flag9_IRQHandler, %function

+ACE_PPE_Flag9_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag10_IRQHandler

+ */

+    .weak   ACE_PPE_Flag10_IRQHandler

+    .type   ACE_PPE_Flag10_IRQHandler, %function

+ACE_PPE_Flag10_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag11_IRQHandler

+ */

+    .weak   ACE_PPE_Flag11_IRQHandler

+    .type   ACE_PPE_Flag11_IRQHandler, %function

+ACE_PPE_Flag11_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag12_IRQHandler

+ */

+    .weak   ACE_PPE_Flag12_IRQHandler

+    .type   ACE_PPE_Flag12_IRQHandler, %function

+ACE_PPE_Flag12_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag13_IRQHandler

+ */

+    .weak   ACE_PPE_Flag13_IRQHandler

+    .type   ACE_PPE_Flag13_IRQHandler, %function

+ACE_PPE_Flag13_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag14_IRQHandler

+ */

+    .weak   ACE_PPE_Flag14_IRQHandler

+    .type   ACE_PPE_Flag14_IRQHandler, %function

+ACE_PPE_Flag14_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag15_IRQHandler

+ */

+    .weak   ACE_PPE_Flag15_IRQHandler

+    .type   ACE_PPE_Flag15_IRQHandler, %function

+ACE_PPE_Flag15_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag16_IRQHandler

+ */

+    .weak   ACE_PPE_Flag16_IRQHandler

+    .type   ACE_PPE_Flag16_IRQHandler, %function

+ACE_PPE_Flag16_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag17_IRQHandler

+ */

+    .weak   ACE_PPE_Flag17_IRQHandler

+    .type   ACE_PPE_Flag17_IRQHandler, %function

+ACE_PPE_Flag17_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag18_IRQHandler

+ */

+    .weak   ACE_PPE_Flag18_IRQHandler

+    .type   ACE_PPE_Flag18_IRQHandler, %function

+ACE_PPE_Flag18_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag19_IRQHandler

+ */

+    .weak   ACE_PPE_Flag19_IRQHandler

+    .type   ACE_PPE_Flag19_IRQHandler, %function

+ACE_PPE_Flag19_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag20_IRQHandler

+ */

+    .weak   ACE_PPE_Flag20_IRQHandler

+    .type   ACE_PPE_Flag20_IRQHandler, %function

+ACE_PPE_Flag20_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag21_IRQHandler

+ */

+    .weak   ACE_PPE_Flag21_IRQHandler

+    .type   ACE_PPE_Flag21_IRQHandler, %function

+ACE_PPE_Flag21_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag22_IRQHandler

+ */

+    .weak   ACE_PPE_Flag22_IRQHandler

+    .type   ACE_PPE_Flag22_IRQHandler, %function

+ACE_PPE_Flag22_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag23_IRQHandler

+ */

+    .weak   ACE_PPE_Flag23_IRQHandler

+    .type   ACE_PPE_Flag23_IRQHandler, %function

+ACE_PPE_Flag23_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag24_IRQHandler

+ */

+    .weak   ACE_PPE_Flag24_IRQHandler

+    .type   ACE_PPE_Flag24_IRQHandler, %function

+ACE_PPE_Flag24_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag25_IRQHandler

+ */

+    .weak   ACE_PPE_Flag25_IRQHandler

+    .type   ACE_PPE_Flag25_IRQHandler, %function

+ACE_PPE_Flag25_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag26_IRQHandler

+ */

+    .weak   ACE_PPE_Flag26_IRQHandler

+    .type   ACE_PPE_Flag26_IRQHandler, %function

+ACE_PPE_Flag26_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag27_IRQHandler

+ */

+    .weak   ACE_PPE_Flag27_IRQHandler

+    .type   ACE_PPE_Flag27_IRQHandler, %function

+ACE_PPE_Flag27_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag28_IRQHandler

+ */

+    .weak   ACE_PPE_Flag28_IRQHandler

+    .type   ACE_PPE_Flag28_IRQHandler, %function

+ACE_PPE_Flag28_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag29_IRQHandler

+ */

+    .weak   ACE_PPE_Flag29_IRQHandler

+    .type   ACE_PPE_Flag29_IRQHandler, %function

+ACE_PPE_Flag29_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag30_IRQHandler

+ */

+    .weak   ACE_PPE_Flag30_IRQHandler

+    .type   ACE_PPE_Flag30_IRQHandler, %function

+ACE_PPE_Flag30_IRQHandler:

+    B .

+

+/*==============================================================================

+ * ACE_PPE_Flag31_IRQHandler

+ */

+    .weak   ACE_PPE_Flag31_IRQHandler

+    .type   ACE_PPE_Flag31_IRQHandler, %function

+ACE_PPE_Flag31_IRQHandler:

+    B .

+

+.end

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.c
new file mode 100644
index 0000000..1b3798f
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.c
@@ -0,0 +1,199 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ *  SmartFusion A2FxxxM3 CMSIS system initialization.

+ *

+ * SVN $Revision: 2069 $

+ * SVN $Date: 2010-01-28 00:23:48 +0000 (Thu, 28 Jan 2010) $

+ */

+#include "a2fxxxm3.h"

+#include "mss_assert.h"

+

+/* System frequency (FCLK) coming out of reset is 25MHz. */

+#define RESET_SYSCLCK_FREQ      25000000uL

+

+/*

+ * SmartFusion Microcontroller Subsystem FLCK frequency.

+ * The value of SMARTFUSION_FCLK_FREQ is used to report the system's clock

+ * frequency in system's which either do not use the Actel System Boot or

+ * a version of the Actel System Boot older than 1.3.1. In eitehr of these cases

+ * SMARTFUSION_FCLK_FREQ should be defined in the projects settings to reflect

+ * the FCLK frequency selected in the Libero MSS configurator.

+ * Systems using the Actel System Boot version 1.3.1 or later do not require this

+ * define since the system's frequency is retrieved from eNVM spare pages where

+ * the MSS Configurator stored the frequency selected during hardware design/configuration.

+ */

+#ifdef SMARTFUSION_FCLK_FREQ

+#define SMARTFUSION_FCLK_FREQ_DEFINED   1

+#else

+#define SMARTFUSION_FCLK_FREQ_DEFINED   0

+#define SMARTFUSION_FCLK_FREQ    RESET_SYSCLCK_FREQ

+#endif

+

+/* Divider values for APB0, APB1 and ACE clocks. */

+#define RESET_PCLK0_DIV         4uL

+#define RESET_PCLK1_DIV         4uL

+#define RESET_ACE_DIV           4uL

+#define RESET_FPGA_CLK_DIV      4uL

+

+/* System register clock control mask and shift for PCLK dividers. */

+#define PCLK_DIV_MASK       0x00000003uL

+#define PCLK0_DIV_SHIFT     2uL

+#define PCLK1_DIV_SHIFT     4uL

+#define ACE_DIV_SHIFT       6uL

+

+/* System register MSS_CCC_DIV_CR mask and shift for GLB (FPGA fabric clock). */

+#define OBDIV_SHIFT         8uL

+#define OBDIV_MASK          0x0000001FuL

+#define OBDIVHALF_SHIFT     13uL

+#define OBDIVHALF_MASK      0x00000001uL

+

+/*

+ * Actel system boot version defines used to extract the system clock from eNVM

+ * spare pages.

+ * These defines allow detecting the presence of Actel system boot in eNVM spare

+ * pages and the version of that system boot executable and associated

+ * configuration data.

+ */

+#define SYSBOOT_KEY_ADDR        (uint32_t *)0x6008081C

+#define SYSBOOT_KEY_VALUE       0x4C544341uL

+#define SYSBOOT_VERSION_ADDR    (uint32_t *)0x60080840

+#define SYSBOOT_1_3_FCLK_ADDR   (uint32_t *)0x6008162C

+#define SYSBOOT_2_x_FCLK_ADDR   (uint32_t *)0x60081EAC

+

+/*

+ * The system boot version is stored in the least significant 24 bits of a word.

+ * The FCLK is stored in eNVM from version 1.3.1 of the system boot. We expect

+ * that the major version number of the system boot version will change if the

+ * system boot configuration data layout needs to change. 

+ */

+#define SYSBOOT_VERSION_MASK    0x00FFFFFFuL

+#define MIN_SYSBOOT_VERSION     0x00010301uL

+#define SYSBOOT_VERSION_2_X     0x00020000uL

+#define MAX_SYSBOOT_VERSION     0x00030000uL

+

+/* Standard CMSIS global variables. */

+uint32_t SystemFrequency = SMARTFUSION_FCLK_FREQ;          /*!< System Clock Frequency (Core Clock) */

+uint32_t SystemCoreClock = SMARTFUSION_FCLK_FREQ;          /*!< System Clock Frequency (Core Clock) */

+

+/* SmartFusion specific clocks. */

+uint32_t g_FrequencyPCLK0 = (SMARTFUSION_FCLK_FREQ / RESET_PCLK0_DIV);      /*!< Clock frequency of APB bus 0. */  

+uint32_t g_FrequencyPCLK1 = (SMARTFUSION_FCLK_FREQ / RESET_PCLK1_DIV);      /*!< Clock frequency of APB bus 1. */

+uint32_t g_FrequencyACE = (SMARTFUSION_FCLK_FREQ / RESET_ACE_DIV);          /*!< Clock frequency of Analog Compute Engine. */

+uint32_t g_FrequencyFPGA = (SMARTFUSION_FCLK_FREQ / RESET_FPGA_CLK_DIV);    /*!< Clock frequecny of FPGA fabric */

+

+/* Local functions */

+static uint32_t GetSystemClock( void );

+

+/***************************************************************************//**

+ * See system_a2fm3fxxx.h for details.

+ */

+void SystemInit(void)

+{

+}

+

+/***************************************************************************//**

+ *

+ */

+void SystemCoreClockUpdate (void)

+{

+    uint32_t PclkDiv0;

+    uint32_t PclkDiv1;

+    uint32_t AceDiv;

+    uint32_t FabDiv;

+

+    const uint32_t pclk_div_lut[4] = { 1uL, 2uL, 4uL, 1uL };

+

+    /* Read PCLK dividers from system registers. Multiply the value read from

+     * system register by two to get actual divider value. */

+    PclkDiv0 = pclk_div_lut[((SYSREG->MSS_CLK_CR >> PCLK0_DIV_SHIFT) & PCLK_DIV_MASK)];

+    PclkDiv1 = pclk_div_lut[((SYSREG->MSS_CLK_CR >> PCLK1_DIV_SHIFT) & PCLK_DIV_MASK)];

+    AceDiv = pclk_div_lut[((SYSREG->MSS_CLK_CR >> ACE_DIV_SHIFT) & PCLK_DIV_MASK)];

+    {

+        /* Compute the FPGA fabric frequency divider. */

+        uint32_t obdiv;

+        uint32_t obdivhalf;

+        

+        obdiv = (SYSREG->MSS_CCC_DIV_CR >> OBDIV_SHIFT) & OBDIV_MASK;

+        obdivhalf = (SYSREG->MSS_CCC_DIV_CR >> OBDIVHALF_SHIFT) & OBDIVHALF_MASK;

+        FabDiv = obdiv + 1uL;

+        if ( obdivhalf != 0uL )

+        {

+            FabDiv = FabDiv * 2uL;

+        }

+    }

+    

+    /* Retrieve FCLK from eNVM spare pages if Actel system boot programmed as part of the system. */

+    

+    /* Read system clock from eNVM spare pages. */

+    SystemCoreClock = GetSystemClock();

+    g_FrequencyPCLK0 = SystemCoreClock / PclkDiv0;

+    g_FrequencyPCLK1 = SystemCoreClock / PclkDiv1;

+    g_FrequencyACE = SystemCoreClock / AceDiv;

+    g_FrequencyFPGA = SystemCoreClock / FabDiv;

+    

+    /* Keep SystemFrequency as well as SystemCoreClock for legacy reasons. */

+    SystemFrequency = SystemCoreClock;

+}

+

+/***************************************************************************//**

+ * Retrieve the system clock frequency from eNVM spare page if available.

+ * Returns the frequency defined through SMARTFUSION_FCLK_FREQ if FCLK cannot be

+ * retrieved from eNVM spare pages.

+ * The FCLK frequency value selected in the MSS Configurator software tool is

+ * stored in eNVM spare pages as part of the Actel system boot configuration data.

+ */

+uint32_t GetSystemClock( void )

+{

+    uint32_t fclk = 0uL;

+    

+    uint32_t * p_sysboot_key = SYSBOOT_KEY_ADDR;

+    

+    if ( SYSBOOT_KEY_VALUE == *p_sysboot_key )

+    {

+        /* Actel system boot programmed, check if it has the FCLK value stored. */

+        uint32_t *p_sysboot_version = SYSBOOT_VERSION_ADDR;

+        uint32_t sysboot_version = *p_sysboot_version;

+        

+        sysboot_version &= SYSBOOT_VERSION_MASK;

+        

+        if ( sysboot_version >= MIN_SYSBOOT_VERSION )

+        {

+            /* Handle change of eNVM location of FCLK between 1.3.x and 2.x.x versions of the system boot. */

+            if ( sysboot_version < SYSBOOT_VERSION_2_X )

+            {

+                /* Read FCLK value from MSS configurator generated configuration

+                 * data stored in eNVM spare pages as part of system boot version 1.3.x

+                 * configuration tables. */

+                uint32_t *p_fclk = SYSBOOT_1_3_FCLK_ADDR;

+                fclk = *p_fclk;

+            }

+            else if ( sysboot_version < MAX_SYSBOOT_VERSION )

+            {

+                /* Read FCLK value from MSS configurator generated configuration

+                 * data stored in eNVM spare pages as part of system boot version 2.x.x

+                 * configuration tables. */

+                uint32_t *p_fclk = SYSBOOT_2_x_FCLK_ADDR;

+                fclk = *p_fclk;

+            }

+            else

+            {

+                fclk = 0uL;

+            }

+        }

+    }

+    

+    if ( 0uL == fclk )

+    {

+        /* 

+         * Could not retrieve FCLK from system boot configuration data. Fall back

+         * to using SMARTFUSION_FCLK_FREQ which must then be defined as part of

+         * project settings.

+         */

+        ASSERT( SMARTFUSION_FCLK_FREQ_DEFINED );

+        fclk = SMARTFUSION_FCLK_FREQ;

+    }

+    

+    return fclk;

+}

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.h
new file mode 100644
index 0000000..6ae0ad5
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.h
@@ -0,0 +1,49 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ *  SmartFusion A2FxxxM3 CMSIS system initialization.

+ *

+ * SVN $Revision: 2064 $

+ * SVN $Date: 2010-01-27 15:05:58 +0000 (Wed, 27 Jan 2010) $

+ */

+

+#ifndef __SYSTEM_A2FM3FXX_H__

+#define __SYSTEM_A2FM3FXX_H__

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/* Standard CMSIS global variables. */

+extern uint32_t SystemFrequency;    /*!< System Clock Frequency (Core Clock) */

+extern uint32_t SystemCoreClock;          /*!< System Clock Frequency (Core Clock) */

+

+/* SmartFusion specific clocks. */

+extern uint32_t g_FrequencyPCLK0;   /*!< Clock frequency of APB bus 0. */  

+extern uint32_t g_FrequencyPCLK1;   /*!< Clock frequency of APB bus 1. */

+extern uint32_t g_FrequencyACE;     /*!< Clock frequency of Analog Compute Engine. */

+extern uint32_t g_FrequencyFPGA;    /*!< Clock frequecny of FPGA fabric */

+

+/***************************************************************************//**

+ * The SystemInit() is a standard CMSIS function called during system startup.

+ * It is meant to perform low level hardware setup such as configuring PLLs. In

+ * the case of SmartFusion these hardware setup operations are performed by the

+ * chip boot which executed before the application started. Therefore this

+ * function does not need to perform any hardware setup.

+ */

+void SystemInit(void);

+

+/***************************************************************************//**

+ * The SystemCoreClockUpdate() is a standard CMSIS function which can be called

+ * by the application in order to ensure that the SystemCoreClock global

+ * variable contains the up to date Cortex-M3 core frequency. Calling this

+ * function also updates the global variables containing the frequencies of the

+ * APB busses connecting the peripherals and the ACE frequency.

+ */

+void SystemCoreClockUpdate(void);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.c
new file mode 100644
index 0000000..46dbf62
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.c
@@ -0,0 +1,798 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2008 Actel Corporation.  All rights reserved.

+ *

+ * SmartFusion microcontroller subsystem I2C bare metal software driver

+ * implementation.

+ *

+ * SVN $Revision: 2152 $

+ * SVN $Date: 2010-02-11 14:44:11 +0000 (Thu, 11 Feb 2010) $

+ */

+#include "i2c.h"

+#include "../../CMSIS/mss_assert.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/*------------------------------------------------------------------------------

+ * I2C transaction direction.

+ */

+#define WRITE_DIR	0

+#define READ_DIR	1

+

+/* -- TRANSACTIONS TYPES -- */

+#define NO_TRANSACTION						0

+#define MASTER_WRITE_TRANSACTION			1

+#define MASTER_READ_TRANSACTION				2

+#define MASTER_RANDOM_READ_TRANSACTION		3

+#define WRITE_SLAVE_TRANSACTION				4

+#define READ_SLAVE_TRANSACTION				5

+#define RANDOM_READ_SLAVE_TRANSACTION		6

+

+

+/* -- SMBUS H/W STATES -- */

+/* -- MASTER STATES -- */

+#define ST_START 		0x08		/* start condition sent */

+#define ST_RESTART 		0x10		/* repeated start */

+#define ST_SLAW_ACK 	0x18		/* SLA+W sent, ack received */

+#define ST_SLAW_NACK 	0x20		/* SLA+W sent, nack received */

+#define ST_TX_DATA_ACK 	0x28		/* Data sent, ACK'ed */

+#define ST_TX_DATA_NACK	0x30		/* Data sent, NACK'ed */

+#define ST_LOST_ARB 	0x38		/* Master lost arbitration */

+#define ST_SLAR_ACK 	0x40		/* SLA+R sent, ACK'ed */

+#define ST_SLAR_NACK 	0x48		/* SLA+R sent, NACK'ed */

+#define ST_RX_DATA_ACK 	0x50		/* Data received, ACK sent */

+#define ST_RX_DATA_NACK 0x58		/* Data received, NACK sent */

+

+/* -- SLAVE STATES -- */

+#define ST_SLAVE_SLAW       0x60			/* SLA+W received */

+#define ST_SLAVE_SLAR_ACK   0xA8			/* SLA+R received, ACK returned */

+#define ST_SLV_LA           0x68			/* Slave lost arbitration */

+#define ST_GCA              0x70			/* GCA received */

+#define	ST_GCA_LA           0x78			/* GCA lost arbitration */

+#define ST_RDATA            0x80			/* Data received */

+#define ST_SLA_NACK         0x88			/* Slave addressed, NACK returned */

+#define	ST_GCA_ACK          0x90			/* Previously addresses with GCA, data ACKed */

+#define ST_GCA_NACK         0x98			/* GCA addressed, NACK returned */

+#define ST_RSTOP            0xA0			/* Stop received */

+#define ST_REPEAT           0xA0			/* Repeated start received */

+#define ST_SLAR_ACKS        0xA8			/* Slave read received, ACKed */

+#define ST_SLARW_LA         0xB0			/* Arbitration lost */

+#define ST_RACK             0xB8			/* Byte sent, ACK received */

+#define ST_SLAVE_RNACK      0xC0			/* Byte sent, NACK received */

+#define ST_FINAL            0xC8			/* Final byte sent, ACK received */

+#define ST_BERR             0x00			/* Error on the bus */

+#define ST_SLV_RST          0xD8			/* Slave reset state */

+

+/*------------------------------------------------------------------------------

+ *

+ */

+static uint32_t disable_interrupts( void );

+static void restore_interrupts( uint32_t primask );

+static void mss_i2c_isr( mss_i2c_instance_t * this_i2c );

+

+/*------------------------------------------------------------------------------

+ *

+ *------------------------------------------------------------------------------

+ *

+ */

+mss_i2c_instance_t g_mss_i2c0;

+mss_i2c_instance_t g_mss_i2c1;

+

+/*------------------------------------------------------------------------------

+ * MSS_I2C_init()

+ * See "mss_i2c.h" for details of how to use this function.

+ */

+void MSS_I2C_init

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t ser_address,

+	mss_i2c_clock_divider_t ser_clock_speed

+)

+{

+    uint_fast16_t clock_speed = ser_clock_speed;

+

+    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

+

+    if ( this_i2c == &g_mss_i2c0 )

+    {

+        this_i2c->irqn = I2C0_IRQn;

+        this_i2c->hw_reg = I2C0;

+        this_i2c->hw_reg_bit = I2C0_BITBAND;

+

+        /* reset I2C0 */

+        SYSREG->SOFT_RST_CR |= SYSREG_I2C0_SOFTRESET_MASK;

+        /* Clear any previously pended I2C0 interrupt */

+        NVIC_ClearPendingIRQ( I2C0_IRQn );

+        /* Take I2C0 out of reset. */

+        SYSREG->SOFT_RST_CR &= ~SYSREG_I2C0_SOFTRESET_MASK;

+    }

+    else

+    {

+        this_i2c->irqn = I2C1_IRQn;

+        this_i2c->hw_reg = I2C1;

+        this_i2c->hw_reg_bit = I2C1_BITBAND;

+

+        /* reset I2C1 */

+        SYSREG->SOFT_RST_CR |= SYSREG_I2C1_SOFTRESET_MASK;

+        /* Clear any previously pended I2C1 interrupt */

+        NVIC_ClearPendingIRQ( I2C1_IRQn );

+        /* Take I2C1 out of reset. */

+        SYSREG->SOFT_RST_CR &= ~SYSREG_I2C1_SOFTRESET_MASK;

+    }

+

+	this_i2c->transaction = NO_TRANSACTION;

+

+	this_i2c->ser_address = ser_address;

+

+	this_i2c->tx_buffer = 0;

+	this_i2c->tx_size = 0;

+	this_i2c->tx_idx = 0;

+

+	this_i2c->rx_buffer = 0;

+	this_i2c->rx_size = 0;

+	this_i2c->rx_idx = 0;

+

+    this_i2c->status = MSS_I2C_SUCCESS;

+

+	this_i2c->random_read_addr = 0;

+

+	this_i2c->slave_write_handler = 0;

+	this_i2c->slave_mem_offset_length = 0;

+

+    this_i2c->hw_reg_bit->CTRL_ENS1 = 0x01; /* set enable bit */

+    this_i2c->hw_reg_bit->CTRL_CR2 = (clock_speed >> 2) & 0x01;

+    this_i2c->hw_reg_bit->CTRL_CR1 = (clock_speed >> 1) & 0x01;

+    this_i2c->hw_reg_bit->CTRL_CR0 = clock_speed & 0x01;

+    this_i2c->hw_reg->ADDR = this_i2c->ser_address;

+}

+

+/*------------------------------------------------------------------------------

+ * MSS_I2C_set_slave_mem_offset_length()

+ * See "mss_i2c.h" for details of how to use this function.

+ */

+void MSS_I2C_set_slave_mem_offset_length

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t offset_length

+)

+{

+    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

+

+	this_i2c->slave_mem_offset_length = offset_length;

+}

+

+/*------------------------------------------------------------------------------

+ * MSS_I2C_register_write_handler()

+ * See "mss_i2c.h" for details of how to use this function.

+ */

+void MSS_I2C_register_write_handler

+(

+	mss_i2c_instance_t * this_i2c,

+	mss_i2c_slave_wr_handler_t handler

+)

+{

+    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

+

+	this_i2c->slave_write_handler = handler;

+}

+

+/*------------------------------------------------------------------------------

+ * MSS_I2C_write()

+ * See "mss_i2c.h" for details of how to use this function.

+ */

+void MSS_I2C_write

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t serial_addr,

+	const uint8_t * write_buffer,

+	uint16_t write_size,

+    uint8_t options

+)

+{

+    volatile uint8_t stat_ctrl;

+    uint8_t serial_interrupt;

+

+	uint32_t primask;

+

+    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

+

+	primask = disable_interrupts();

+

+	this_i2c->transaction = MASTER_WRITE_TRANSACTION;

+

+	this_i2c->target_addr = serial_addr;

+	this_i2c->dir = WRITE_DIR;

+	this_i2c->tx_buffer = write_buffer;

+	this_i2c->tx_size = write_size;

+	this_i2c->tx_idx = 0;

+

+    this_i2c->status = MSS_I2C_IN_PROGRESS;

+    this_i2c->options = options;

+

+    /* Clear interrupts if required (depends on repeated starts).*/

+    serial_interrupt = this_i2c->hw_reg_bit->CTRL_SI;

+    this_i2c->hw_reg_bit->CTRL_STA = 0x01;

+

+    if ( serial_interrupt != 0 )

+    {

+        this_i2c->hw_reg_bit->CTRL_SI = 0x00;

+        NVIC_ClearPendingIRQ( this_i2c->irqn );

+    }

+

+    stat_ctrl = this_i2c->hw_reg->STATUS;

+

+    NVIC_EnableIRQ( this_i2c->irqn );

+

+    restore_interrupts( primask );

+}

+

+/*------------------------------------------------------------------------------

+ * MSS_I2C_read()

+ * See "mss_i2c.h" for details of how to use this function.

+ */

+void MSS_I2C_read

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t serial_addr,

+	uint8_t * read_buffer,

+	uint16_t read_size,

+    uint8_t options

+)

+{

+	uint32_t primask;

+

+    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

+

+	if ( read_size > 0 )

+	{

+        volatile uint8_t stat_ctrl;

+        uint8_t serial_interrupt;

+

+		primask = disable_interrupts();

+

+		this_i2c->transaction = MASTER_READ_TRANSACTION;

+

+		this_i2c->target_addr = serial_addr;

+		this_i2c->dir = READ_DIR;

+		this_i2c->rx_buffer = read_buffer;

+		this_i2c->rx_size = read_size;

+		this_i2c->rx_idx = 0;

+

+        this_i2c->status = MSS_I2C_IN_PROGRESS;

+

+        this_i2c->options = options;

+

+        /* Clear interrupts if required (depends on repeated starts).*/

+        serial_interrupt = this_i2c->hw_reg_bit->CTRL_SI;

+        this_i2c->hw_reg_bit->CTRL_STA = 0x01;

+

+        if ( serial_interrupt != 0 )

+        {

+            this_i2c->hw_reg_bit->CTRL_SI = 0x00;

+            NVIC_ClearPendingIRQ( this_i2c->irqn );

+        }

+

+        stat_ctrl = this_i2c->hw_reg->STATUS;

+

+        NVIC_EnableIRQ( this_i2c->irqn );

+

+        restore_interrupts( primask );

+	}

+}

+

+/*------------------------------------------------------------------------------

+ * MSS_I2C_write_read()

+ * See "mss_i2c.h" for details of how to use this function.

+ */

+void MSS_I2C_write_read

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t serial_addr,

+	const uint8_t * addr_offset,

+	uint16_t offset_size,

+	uint8_t * read_buffer,

+	uint16_t read_size,

+    uint8_t options

+)

+{

+    volatile uint8_t stat_ctrl;

+    uint8_t serial_interrupt;

+	uint32_t primask;

+

+    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

+

+	primask = disable_interrupts();

+

+	this_i2c->transaction = MASTER_RANDOM_READ_TRANSACTION;

+	this_i2c->target_addr = serial_addr;

+	this_i2c->dir = WRITE_DIR;

+	this_i2c->tx_buffer = addr_offset;

+	this_i2c->tx_size = offset_size;

+	this_i2c->tx_idx = 0;

+

+	this_i2c->rx_buffer = read_buffer;

+	this_i2c->rx_size = read_size;

+	this_i2c->rx_idx = 0;

+

+    this_i2c->status = MSS_I2C_IN_PROGRESS;

+    this_i2c->options = options;

+

+    /* Clear interrupts if required (depends on repeated starts).*/

+    serial_interrupt = this_i2c->hw_reg_bit->CTRL_SI;

+    this_i2c->hw_reg_bit->CTRL_STA = 0x01;

+

+    if ( serial_interrupt != 0 )

+    {

+        this_i2c->hw_reg_bit->CTRL_SI = 0x00;

+        NVIC_ClearPendingIRQ( this_i2c->irqn );

+    }

+

+    stat_ctrl = this_i2c->hw_reg->STATUS;

+

+    NVIC_EnableIRQ( this_i2c->irqn );

+

+    restore_interrupts( primask );

+}

+

+/*------------------------------------------------------------------------------

+ * MSS_I2C_set_slave_rx_buffer()

+ * See "mss_i2c.h" for details of how to use this function.

+ */

+void MSS_I2C_set_slave_rx_buffer

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t * rx_buffer,

+	uint16_t rx_size

+)

+{

+	uint32_t primask;

+

+    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

+

+	primask = disable_interrupts();

+

+	this_i2c->rx_buffer = rx_buffer;

+	this_i2c->rx_size = rx_size;

+	this_i2c->rx_idx = 0;

+

+	restore_interrupts( primask );

+}

+

+

+/*------------------------------------------------------------------------------

+ * MSS_I2C_get_status()

+ * See "mss_i2c.h" for details of how to use this function.

+ */

+mss_i2c_status_t MSS_I2C_get_status

+(

+    mss_i2c_instance_t * this_i2c

+)

+{

+    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

+

+    return this_i2c->status;

+}

+

+/*------------------------------------------------------------------------------

+ * MSS_I2C_set_slave_tx_buffer()

+ * See "mss_i2c.h" for details of how to use this function.

+ */

+void MSS_I2C_set_slave_tx_buffer

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t * tx_buffer,

+	uint16_t tx_size

+)

+{

+	uint32_t primask;

+

+    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

+

+	primask = disable_interrupts();

+

+	this_i2c->tx_buffer = tx_buffer;

+	this_i2c->tx_size = tx_size;

+	this_i2c->tx_idx = 0;

+

+	restore_interrupts( primask );

+

+	/* Set the assert acknowledge bit. */

+    this_i2c->hw_reg_bit->CTRL_AA = 0x01;

+}

+

+/*------------------------------------------------------------------------------

+ * MSS_I2C_enable_slave_rx()

+ * See "mss_i2c.h" for details of how to use this function.

+ */

+void MSS_I2C_enable_slave_rx

+(

+	mss_i2c_instance_t * this_i2c

+)

+{

+    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

+

+	/* Set the assert acknowledge bit. */

+    this_i2c->hw_reg_bit->CTRL_AA = 0x01;

+	/* accept GC addressing. */

+    this_i2c->hw_reg_bit->ADDR_GC = 0x01;

+

+    NVIC_EnableIRQ( this_i2c->irqn );

+}

+

+/*------------------------------------------------------------------------------

+ * MSS_I2C_wait_complete()

+ * See "mss_i2c.h" for details of how to use this function.

+ */

+mss_i2c_status_t MSS_I2C_wait_complete

+(

+    mss_i2c_instance_t * this_i2c

+)

+{

+    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

+

+    while ( this_i2c->status == MSS_I2C_IN_PROGRESS )

+    {

+        /* Wait for transaction to compltete.*/

+        ;

+    }

+    return this_i2c->status;

+}

+

+/*------------------------------------------------------------------------------

+ * MSS I2C interrupt service routine.

+ *------------------------------------------------------------------------------

+ * Parameters:

+ *

+ * 	mss_i2c_instance_t * this_i2c:

+ * 		Pointer to the mss_i2c_instance_t data structure holding all data related to

+ * 		the	MSS I2C instance that generated the interrupt.

+ */

+static void mss_i2c_isr

+(

+	mss_i2c_instance_t * this_i2c

+)

+{

+	volatile uint8_t status;

+	uint8_t data;

+    uint8_t hold_bus;

+    uint8_t clear_irq = 1;

+

+    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

+

+    status = this_i2c->hw_reg->STATUS;

+

+	switch( status )

+	{

+	    /************** MASTER TRANSMITTER / RECEIVER *******************/

+

+	    case ST_START: /* start has been xmt'd */

+	    case ST_RESTART: /* repeated start has been xmt'd */

+            this_i2c->hw_reg_bit->CTRL_STA = 0x0;

+            this_i2c->hw_reg->DATA = this_i2c->target_addr;

+            this_i2c->hw_reg_bit->DATA_DIR = this_i2c->dir;

+

+	    	this_i2c->tx_idx = 0;

+	    	this_i2c->rx_idx = 0;

+	    	break;

+

+	    case ST_LOST_ARB:

+			/* Set start bit.  Let's keep trying!  Don't give up! */

+            this_i2c->hw_reg_bit->CTRL_STA = 0x01;

+			break;

+

+	    /******************* MASTER TRANSMITTER *************************/

+	    case ST_SLAW_ACK:

+	    	/* call address has been xmt'd with ACK, time to send data byte and increment index. */

+            if ( this_i2c->tx_idx < this_i2c->tx_size )

+            {

+                /* load data byte */

+                this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];

+            }

+            else

+            {

+                NVIC_DisableIRQ( this_i2c->irqn );

+            }

+	    	break;

+

+	    case ST_SLAW_NACK:

+#if 0

+	    	/* SLA+W has been transmitted; not ACK has been received - let's stop. */

+            this_i2c->hw_reg_bit->CTRL_STO = 0x01;

+            this_i2c->status = MSS_I2C_FAILED;

+#endif

+	    	/* call address has been xmt'd with ACK, time to send data byte and increment index. */

+            if ( this_i2c->tx_idx < this_i2c->tx_size )

+            {

+                /* load data byte */

+                this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];

+            }

+            else

+            {

+                NVIC_DisableIRQ( this_i2c->irqn );

+            }

+			break;

+

+	    case ST_TX_DATA_ACK:

+			/* data byte has been xmt'd with ACK, time to send stop bit or repeated start. */

+			if (this_i2c->tx_idx < this_i2c->tx_size)

+			{

+                this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];

+			}

+			else if ( this_i2c->transaction == MASTER_RANDOM_READ_TRANSACTION )

+			{

+				/* We are finished sending the address offset part of a random read transaction.

+				 * It is is time to send a restart in order to change direction. */

+				 this_i2c->dir = READ_DIR;

+                 this_i2c->hw_reg_bit->CTRL_STA = 0x01;

+			}

+			else /* done sending. let's stop */

+			{

+                hold_bus = this_i2c->options & MSS_I2C_HOLD_BUS;

+                if ( hold_bus == 0 )

+                {

+                    this_i2c->hw_reg_bit->CTRL_STO = 0x01; /*xmt stop condition */

+                }

+                else

+                {

+                    NVIC_DisableIRQ( this_i2c->irqn );

+                    clear_irq = 0;

+                }

+                this_i2c->status = MSS_I2C_SUCCESS;

+			}

+			break;

+

+		  case ST_TX_DATA_NACK:

+#if 0

+			 /* data byte SENT, ACK to be received

+		     * In fact, this means we've received a NACK (This may not be

+             * obvious, but if we've rec'd an ACK then we would be in state

+             * 0x28!) hence, let's send a stop bit

+             */

+            this_i2c->hw_reg_bit->CTRL_STO = 0x01;

+            this_i2c->status = MSS_I2C_FAILED;

+#endif

+			/* data byte has been xmt'd with ACK, time to send stop bit or repeated start. */

+			if (this_i2c->tx_idx < this_i2c->tx_size)

+			{

+                this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];

+			}

+			else if ( this_i2c->transaction == MASTER_RANDOM_READ_TRANSACTION )

+			{

+				/* We are finished sending the address offset part of a random read transaction.

+				 * It is is time to send a restart in order to change direction. */

+				 this_i2c->dir = READ_DIR;

+                 this_i2c->hw_reg_bit->CTRL_STA = 0x01;

+			}

+			else /* done sending. let's stop */

+			{

+                hold_bus = this_i2c->options & MSS_I2C_HOLD_BUS;

+                if ( hold_bus == 0 )

+                {

+                    this_i2c->hw_reg_bit->CTRL_STO = 0x01; /*xmt stop condition */

+                }

+                else

+                {

+                    NVIC_DisableIRQ( this_i2c->irqn );

+                    clear_irq = 0;

+                }

+                this_i2c->status = MSS_I2C_SUCCESS;

+			}

+            break;

+

+	  /********************* MASTER (or slave?) RECEIVER *************************/

+

+	  /* STATUS codes 08H, 10H, 38H are all covered in MTX mode */

+		case ST_SLAR_ACK: /* SLA+R tx'ed. */

+			/* Let's make sure we ACK the first data byte received (set AA bit in CTRL) unless

+			 * the next byte is the last byte of the read transaction.

+             */

+			if( this_i2c->rx_size > 1 )

+			{

+                this_i2c->hw_reg_bit->CTRL_AA = 0x01;

+			}

+			else

+			{

+                this_i2c->hw_reg_bit->CTRL_AA = 0x00;

+			}

+			break;

+

+		case ST_SLAR_NACK: /* SLA+R tx'ed; let's release the bus (send a stop condition) */

+            this_i2c->hw_reg_bit->CTRL_STO = 0x01;

+            this_i2c->status = MSS_I2C_FAILED;

+			break;

+

+		case ST_RX_DATA_ACK: /* Data byte received, ACK returned */

+			/* First, get the data */

+            this_i2c->rx_buffer[this_i2c->rx_idx++] = this_i2c->hw_reg->DATA;

+

+			if( this_i2c->rx_idx >= this_i2c->rx_size - 1)

+			{

+				/* If we're at the second last byte, let's set AA to 0 so

+				 * we return a NACK at the last byte. */

+                this_i2c->hw_reg_bit->CTRL_AA = 0x00;

+			}

+			break;

+

+	    case ST_RX_DATA_NACK: /* Data byte received, NACK returned */

+            /* Get the data, then send a stop condition */

+            this_i2c->rx_buffer[this_i2c->rx_idx++] = this_i2c->hw_reg->DATA;

+

+            hold_bus = this_i2c->options &  MSS_I2C_HOLD_BUS;

+            if ( hold_bus == 0 )

+            {

+                this_i2c->hw_reg_bit->CTRL_STO = 0x01;  /*xmt stop condition */

+            }

+            else

+            {

+                NVIC_DisableIRQ( this_i2c->irqn );

+                clear_irq = 0;

+            }

+

+            this_i2c->status = MSS_I2C_SUCCESS;

+            break;

+

+		/******************** SLAVE RECEIVER **************************/

+		case ST_GCA_NACK: /* NACK after, GCA addressing */

+		case ST_SLA_NACK: /* Get Data, but also re-enable AA (assert ack) bit for future transmissions */

+			if ( this_i2c->rx_buffer != 0 )

+			{

+                this_i2c->rx_buffer[this_i2c->rx_idx] = this_i2c->hw_reg->DATA;

+			}

+            this_i2c->hw_reg_bit->CTRL_AA = 0x01;

+			break;

+

+		case ST_SLAVE_SLAW: /* SLA+W received, ACK returned */

+			this_i2c->transaction = WRITE_SLAVE_TRANSACTION;

+			this_i2c->rx_idx = 0;

+			this_i2c->random_read_addr = 0;

+#ifndef INCLUDE_SLA_IN_RX_PAYLOAD

+			/* Only break from this case if the slave address must NOT be included at the

+			 * beginning of the received write data. */

+			break;

+#endif

+		case ST_GCA_ACK: /* DATA received; ACK sent after GCA */

+		case ST_RDATA: /* DATA received; must clear DATA register */

+			if (this_i2c->rx_idx >= this_i2c->rx_size - 2)

+			{

+                this_i2c->hw_reg_bit->CTRL_AA = 0x00;   /* send a NACK when done (next reception) */

+			}

+            data = this_i2c->hw_reg->DATA;

+			this_i2c->rx_buffer[this_i2c->rx_idx++] = data;

+			this_i2c->random_read_addr = (this_i2c->random_read_addr << 8) + data;

+

+			break;

+

+		case ST_RSTOP:

+			/* STOP or repeated START occured. */

+			/* We cannot be sure if the transaction has actually completed as

+			 * this hardware state reports that either a STOP or repeated START

+			 * condition has occured. We assume that this is a repeated START

+			 * if the transaction was a write from the master to this point.*/

+			if ( this_i2c->transaction == WRITE_SLAVE_TRANSACTION )

+			{

+				if ( this_i2c->rx_idx == this_i2c->slave_mem_offset_length )

+				{

+					this_i2c->transaction = RANDOM_READ_SLAVE_TRANSACTION;

+					this_i2c->tx_idx = this_i2c->random_read_addr;

+				}

+				else

+				{

+					/* Call the slave's write transaction handler if it exists. */

+					if ( this_i2c->slave_write_handler != 0 )

+					{

+						mss_i2c_slave_handler_ret_t h_ret;

+						h_ret = this_i2c->slave_write_handler( this_i2c->rx_buffer, (uint16_t)this_i2c->rx_idx );

+						if ( MSS_I2C_REENABLE_SLAVE_RX == h_ret )

+						{

+                            this_i2c->hw_reg_bit->CTRL_AA = 0x01;

+						}

+						else

+						{

+                            this_i2c->hw_reg_bit->CTRL_AA = 0x00;

+						}

+					}

+				}

+			}

+			/* Mark any previous master write transaction as complete. */

+            this_i2c->status = MSS_I2C_SUCCESS;

+			break;

+

+		case ST_SLV_RST: /* SMBUS ONLY: timeout state. must clear interrupt */

+		case ST_SLV_LA: /* Arbitr. lost (SLA rec'd) */

+		case ST_GCA: /* General call address received, ACK returned */

+		case ST_GCA_LA: /* Arbitr. lost (GCA rec'd) */

+			/* do nothing */

+			break;

+

+		/****************** SLAVE TRANSMITTER **************************/

+		case ST_SLAVE_SLAR_ACK: /* SLA+R received, ACK returned */

+		case ST_SLARW_LA: /* Arbitration lost, and: */

+		case ST_RACK: /* Data tx'ed, ACK received */

+            if ( status == ST_SLAVE_SLAR_ACK )

+            {

+                this_i2c->transaction = READ_SLAVE_TRANSACTION;

+                this_i2c->random_read_addr = 0;

+            }

+			/* Load the data, and determine if it is the last one */

+            this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];

+			if (this_i2c->tx_idx >= this_i2c->tx_size - 1) /* last byte? */

+			{

+                this_i2c->hw_reg_bit->CTRL_AA = 0x00;

+				/* Next read transaction will result in slave's transmit buffer

+				 * being sent from the first byte. */

+				this_i2c->tx_idx = 0;

+			}

+			break;

+

+		case ST_SLAVE_RNACK:	/* Data byte has been transmitted; not-ACK has been received. */

+			/* We assume that the transaction will be stopped by the master.

+			 * Reset tx_idx so that a subsequent read will result in the slave's

+			 * transmit buffer being sent from the first byte. */

+			this_i2c->tx_idx = 0;

+			break;

+

+		case ST_FINAL: /* Last Data byte tx'ed, ACK recieved */

+		default:

+			/* do nothing */

+			break;

+	}

+

+    if ( clear_irq )

+    {

+    	/* clear interrupt. */

+        this_i2c->hw_reg_bit->CTRL_SI = 0x00;

+    }

+

+    /* Read the status register to ensure the last I2C registers write took place

+     * in a system built around a bus making use of posted writes. */

+    status = this_i2c->hw_reg->STATUS;

+}

+

+/*------------------------------------------------------------------------------

+ *

+ */

+uint32_t disable_interrupts( void )

+{

+    uint32_t primask;

+    primask = __get_PRIMASK();

+    return primask;

+}

+

+/*------------------------------------------------------------------------------

+ *

+ */

+void restore_interrupts( uint32_t primask )

+{

+    __set_PRIMASK( primask );

+}

+

+/*------------------------------------------------------------------------------

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void I2C0_IRQHandler( void )

+#else

+void I2C0_IRQHandler( void )

+#endif

+{

+	mss_i2c_isr( &g_mss_i2c0 );

+    NVIC_ClearPendingIRQ( I2C0_IRQn );

+}

+

+/*------------------------------------------------------------------------------

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void I2C1_IRQHandler( void )

+#else

+void I2C1_IRQHandler( void )

+#endif

+{

+	mss_i2c_isr( &g_mss_i2c1 );

+    NVIC_ClearPendingIRQ( I2C1_IRQn );

+}

+

+#ifdef __cplusplus

+}

+#endif

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.h
new file mode 100644
index 0000000..63220c3
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.h
@@ -0,0 +1,775 @@
+/*******************************************************************************

+ * (c) Copyright 2007-2008 Actel Corporation.  All rights reserved.

+ *

+ * SmartFusion microcontroller subsystem I2C bare metal software driver public

+ * API.

+ *

+ * SVN $Revision: 2150 $

+ * SVN $Date: 2010-02-11 14:39:24 +0000 (Thu, 11 Feb 2010) $

+ */

+/*=========================================================================*//**

+  @mainpage SmartFusion MSS I2C Bare Metal Driver.

+

+  @section intro_sec Introduction

+  The SmartFusion™ microcontroller subsystem (MSS) includes two I2C peripherals

+  for serial communication. This driver provides a set of functions for

+  controlling the MSS I2Cs as part of a bare metal system where no operating

+  system is available. These drivers can be adapted for use as part of an

+  operating system, but the implementation of the adaptation layer between this

+  driver and the operating system's driver model is outside the scope of this

+  driver.

+

+  @section hw_dependencies Hardware Flow Dependencies

+  The configuration of all features of the MSS I2Cs is covered by this driver

+  with the exception of the SmartFusion IOMUX configuration. SmartFusion allows

+  multiple non-concurrent uses of some external pins through IOMUX configuration.

+  This feature allows optimization of external pin usage by assigning external

+  pins for use by either the microcontroller subsystem or the FPGA fabric. The

+  MSS I2Cs serial signals are routed through IOMUXes to the SmartFusion device

+  external pins. These IOMUXes are automatically configured correctly by the MSS

+  configurator tool in the hardware flow when the MSS I2Cs are enabled in that

+  tool. You must ensure that the MSS I2Cs are enabled by the MSS configurator

+  tool in the hardware flow; otherwise the serial inputs and outputs will not be

+  connected to the chip's external pins. For more information on IOMUX, refer to

+  the IOMUX section of the SmartFusion Datasheet.

+  The base address, register addresses and interrupt number assignment for the

+  MSS I2C blocks are defined as constants in the SmartFusion CMSIS-PAL. You must

+  ensure that the SmartFusion CMSIS-PAL is either included in the software tool

+  chain used to build your project or is included in your project.

+

+  @section theory_op Theory of Operation

+  The MSS I2C driver functions are grouped into the following categories:

+    • Initialization and configuration functions

+    • Interrupt control

+    • I2C master operations – functions to handle write, read and write-read transactions

+    • I2C slave operations – functions to handle write, read and write-read transactions

+

+  Initialization and Configuration

+    The MSS I2C driver is initialized through a call to the MSS_I2C_init()

+    function. This function takes the MSS I2C's configuration as parameters. The

+    MSS_I2C_init() function must be called before any other MSS I2C driver

+    functions can be called. The first parameter of the MSS_I2C_init() function

+    is a pointer to one of two global data structures used by the driver to

+    store state information for each MSS I2C. A pointer to these data structures

+    is also used as first parameter to any of the driver functions to identify

+    which MSS I2C will be used by the called function. The names of these two

+    data structures are g_mss_i2c0 and g_mss_i2c1. Therefore any call to an MSS

+    I2C driver function should be of the form MSS_I2C_function_name( &g_mss_i2c0, ... )

+    or MSS_I2C_function_name( &g_mss_i2c1, ... ).

+    The MSS_I2C_init() function call for each MSS I2C also takes the I2C serial

+    address assigned to the MSS I2C and the serial clock divider to be used to

+    generate its I2C clock as configuration parameters.

+

+  Interrupt Control

+    The MSS I2C driver is interrupt driven and it enables and disables the

+    generation of interrupts by MSS I2C at various times when it is operating.

+    The driver automatically handles MSS I2C interrupts internally, including

+    enabling disabling and clearing MSS I2C interrupts in the Cortex-M3

+    interrupt controller when required.

+    The function MSS_I2C_register_write_handler() is used to register a write

+    handler function with the MSS I2C driver that it will call on completion of

+    an I2C write transaction by the MSS I2C slave. It is your responsibility to

+    create and register the implementation of this handler function that will

+    process or trigger the processing of the received data.

+  Transaction Types

+    The MSS I2C driver is designed to handle three types of I2C transaction:

+      • Write transactions

+      • Read transactions

+      • Write-read transactions

+

+    Write transaction

+      The master I2C device initiates a write transaction by sending a START bit

+      as soon as the bus becomes free. The START bit is followed by the 7-bit

+      serial address of the target slave device followed by the read/write bit

+      indicating the direction of the transaction. The slave acknowledges receipt

+      of it’s address with an acknowledge bit. The master sends data one byte at

+      a time to the slave, which must acknowledge receipt of each byte for the

+      next byte to be sent. The master sends a STOP bit to complete the transaction.

+      The slave can abort the transaction by replying with a non-acknowledge bit

+      instead of an acknowledge.

+      The application programmer can choose not to send a STOP bit at the end of

+      the transaction causing the next transaction to begin with a repeated START bit.

+

+    Read transaction

+      The master I2C device initiates a read transaction by sending a START bit

+      as soon as the bus becomes free. The START bit is followed by the 7-bit

+      serial address of the target slave device followed by the read/write bit

+      indicating the direction of the transaction. The slave acknowledges receipt

+      of it’s slave address with an acknowledge bit. The slave sends data one byte

+      at a time to the master, which must acknowledge receipt of each byte for the

+      next byte to be sent. The master sends a non-acknowledge bit following the

+      last byte it wishes to read followed by a STOP bit.

+      The application programmer can choose not to send a STOP bit at the end of

+      the transaction causing the next transaction to begin with a repeated START bit.

+

+    Write-read transaction

+      The write-read transaction is a combination of a write transaction

+      immediately followed by a read transaction. There is no STOP bit between

+      the write and read phases of a write-read transaction. A repeated START

+      bit is sent between the write and read phases.

+      The write-read transaction is typically used to send a command or offset

+      in the write transaction specifying the logical data to be transferred

+      during the read phase.

+      The application programmer can choose not to send a STOP bit at the end of

+      the transaction causing the next transaction to begin with a repeated START bit.

+

+  Master Operations

+    The application can use the MSS_I2C_write(), MSS_I2C_read() and MSS_I2C_write_read()

+    functions to initiate an I2C bus transaction. The application can then wait

+    for the transaction to complete using the MSS_I2C_wait_complete() function

+    or poll the status of the I2C transaction using the MSS_I2C_get_status()

+    function until it returns a value different from MSS_I2C_IN_PROGRESS.

+

+  Slave Operations

+    The configuration of the MSS I2C driver to operate as an I2C slave requires

+    the use of the following functions:

+      • MSS_I2C_set_slave_tx_buffer()

+      • MSS_I2C_set_slave_rx_buffer()

+      • MSS_I2C_set_slave_mem_offset_length()

+      • MSS_I2C_register_write_handler()

+      • MSS_I2C_enable_slave_rx()

+    Use of all functions is not required if the slave I2C does not need to support

+    all types of I2C read transactions. The subsequent sections list the functions

+    that must be used to support each transaction type.

+

+    Responding to read transactions

+      The following functions are used to configure the MSS I2C driver to respond

+      to I2C read transactions:

+        • MSS_I2C_set_slave_tx_buffer()

+        • MSS_I2C_enable_slave_rx()

+      The function MSS_I2C_set_slave_tx_buffer() specifies the data buffer that

+      will be transmitted when the I2C slave is the target of an I2C read

+      transaction. It is then up to the application to manage the content of that

+      buffer to control the data that will be transmitted to the I2C master as a

+      result of the read transaction.

+      The function MSS_I2C_enable_slave_rx() enables the MSS I2C hardware instance

+      to respond to I2C transactions. It must be called after the MSS I2C driver

+      has been configured to respond to the required transaction types.

+

+    Responding to write transactions

+      The following functions are used to configure the MSS I2C driver to respond

+      to I2C write transactions:

+        • MSS_I2C_set_slave_rx_buffer()

+        • MSS_I2C_register_write_handler()

+        • MSS_I2C_enable_slave_rx()

+      The function MSS_I2C_set_slave_rx_buffer() specifies the data buffer that

+      will be used to store the data received by the I2C slave when it is the

+      target an I2C  write transaction.

+      The function MSS_I2C_register_write_handler() specifies the handler function

+      that must be called on completion of the I2C write transaction. It is this

+      handler function that will process or trigger the processing of the received

+      data.

+      The function MSS_I2C_enable_slave_rx() enables the MSS I2C hardware instance

+      to respond to I2C transactions. It must be called after the MSS I2C driver

+      has been configured to respond to the required transaction types.

+

+    Responding to write-read transactions

+      The following functions are used to configure the MSS I2C driver to respond

+      to write-read transactions:

+        • MSS_I2C_set_slave_tx_buffer()

+        • MSS_I2C_set_slave_rx_buffer()

+        • MSS_I2C_set_slave_mem_offset_length()

+        • MSS_I2C_enable_slave_rx()

+      The function MSS_I2C_set_slave_mem_offset_length() specifies the number of

+      bytes expected by the I2C slave during the write phase of the write-read

+      transaction.

+      The function MSS_I2C_set_slave_tx_buffer() specifies the data that will be

+      transmitted to the I2C master during the read phase of the write-read

+      transaction. The value received by the I2C slave during the write phase of

+      the transaction will be used as an index into the transmit buffer specified

+      by this function to decide which part of the transmit buffer will be

+      transmitted to the I2C master as part of the read phase of the write-read

+      transaction.

+      The function MSS_I2C_set_slave_rx_buffer() specifies the data buffer that

+      will be used to store the data received by the I2C slave during the write

+      phase of the write-read transaction. This buffer must be at least large

+      enough to accommodate the number of bytes specified through the

+      MSS_I2C_set_slave_mem_offset_length() function.

+      The function MSS_I2C_enable_slave_rx() enables the MSS I2C hardware

+      instance to respond to I2C transactions. It must be called after the MSS

+      I2C driver has been configured to respond to the required transaction types.

+ *//*=========================================================================*/

+#ifndef I2C_H_

+#define I2C_H_

+

+#include "../../CMSIS/a2fxxxm3.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/*-------------------------------------------------------------------------*//**

+  The mss_i2c_clock_divider_t type is used to specify the divider to be applied

+  to the MSS I2C BCLK signal in order to generate the I2C clock.

+ */

+typedef enum mss_i2c_clock_divider {

+    MSS_I2C_PCLK_DIV_256 = 0,

+    MSS_I2C_PCLK_DIV_224,

+    MSS_I2C_PCLK_DIV_192,

+    MSS_I2C_PCLK_DIV_160,

+    MSS_I2C_PCLK_DIV_960,

+    MSS_I2C_PCLK_DIV_120,

+    MSS_I2C_PCLK_DIV_60,

+    MSS_I2C_BCLK_DIV_8

+} mss_i2c_clock_divider_t;

+

+/*-------------------------------------------------------------------------*//**

+  The MSS_I2C_RELEASE_BUS constant is used to specify the options parameter to

+  functions MSS_I2C_read(), MSS_I2C_write() and MSS_I2C_write_read() to indicate

+  that a STOP bit must be generated at the end of the I2C transaction to release

+  the bus.

+ */

+#define MSS_I2C_RELEASE_BUS     0x00

+

+/*-------------------------------------------------------------------------*//**

+  The MSS_I2C_HOLD_BUS constant is used to specify the options parameter to

+  functions MSS_I2C_read(), MSS_I2C_write() and MSS_I2C_write_read() to indicate

+  that a STOP bit must not be generated at the end of the I2C transaction in

+  order to retain the bus ownership. This will cause the next transaction to

+  begin with a repeated START bit and no STOP bit between the transactions.

+ */

+#define MSS_I2C_HOLD_BUS        0x01

+

+/*-------------------------------------------------------------------------*//**

+  The mss_i2c_status_t type is used to report the status of I2C transactions.

+ */

+typedef enum mss_i2c_status

+{

+    MSS_I2C_SUCCESS = 0,

+    MSS_I2C_IN_PROGRESS,

+    MSS_I2C_FAILED

+} mss_i2c_status_t;

+

+/*-------------------------------------------------------------------------*//**

+  The mss_i2c_slave_handler_ret_t type is used by slave write handler functions

+  to indicate whether the received data buffer should be released or not.

+ */

+typedef enum mss_i2c_slave_handler_ret {

+    MSS_I2C_REENABLE_SLAVE_RX = 0,

+    MSS_I2C_PAUSE_SLAVE_RX = 1

+} mss_i2c_slave_handler_ret_t;

+

+/*-------------------------------------------------------------------------*//**

+  Slave write handler functions prototype.

+  ------------------------------------------------------------------------------

+  This defines the function prototype that must be followed by MSS I2C slave

+  write handler functions. These functions are registered with the MSS I2C driver

+  through the MSS_I2C_register_write_handler() function.

+

+  Declaring and Implementing Slave Write Handler Functions:

+    Slave write handler functions should follow the following prototype:

+    mss_i2c_slave_handler_ret_t write_handler( uint8_t * data, uint16_t size );

+

+    The data parameter is a pointer to a buffer (received data buffer) holding

+    the data written to the MSS I2C slave.

+    The size parameter is the number of bytes held in the received data buffer.

+    Handler functions must return one of the following values:

+        • MSS_I2C_REENABLE_SLAVE_RX

+        • MSS_I2C_PAUSE_SLAVE_RX.

+    If the handler function returns MSS_I2C_REENABLE_SLAVE_RX, the driver will

+    release the received data buffer and allow further I2C write transactions to

+    the MSS I2C slave to take place.

+    If the handler function returns MSS_I2C_PAUSE_SLAVE_RX, the MSS I2C slave

+    will respond to subsequent write requests with a non-acknowledge bit (NACK),

+    until the received data buffer content has been processed by some other part

+    of the software application.

+    A call to MSS_I2C_enable_slave_rx() is required at some point after

+    returning MSS_I2C_PAUSE_SLAVE_RX in order to release the received data

+    buffer so it can be used to store data received by subsequent I2C write

+    transactions.

+ */

+typedef mss_i2c_slave_handler_ret_t (*mss_i2c_slave_wr_handler_t)( uint8_t *, uint16_t );

+

+/*-------------------------------------------------------------------------*//**

+  mss_i2c_instance_t

+  ------------------------------------------------------------------------------

+  There is one instance of this structure for each of the microcontroller

+  subsystem's I2Cs. Instances of this structure are used to identify a specific

+  I2C. A pointer to an instance of the mss_i2c_instance_t structure is passed as

+  the first parameter to MSS I2C driver functions to identify which I2C should

+  perform the requested operation.

+ */

+typedef struct mss_i2c_instance

+{

+	uint_fast8_t ser_address;

+	/* Transmit related info:*/

+	uint_fast8_t target_addr;

+

+	/* Current transaction type (WRITE, READ, RANDOM_READ)*/

+	uint8_t transaction;

+

+	uint_fast16_t random_read_addr;

+

+    uint8_t options;

+

+	/* I2C hardware instance identification */

+    IRQn_Type  irqn;

+    I2C_TypeDef * hw_reg;

+    I2C_BitBand_TypeDef * hw_reg_bit;

+

+	/* TX INFO: */

+	const uint8_t * tx_buffer;

+	uint_fast16_t tx_size;

+	uint_fast16_t tx_idx;

+	uint_fast8_t dir;

+

+	/* RX INFO: */

+	uint8_t * rx_buffer;

+	uint_fast16_t rx_size;

+	uint_fast16_t rx_idx;

+

+	/* status variable: */

+    volatile mss_i2c_status_t status;

+

+	/* Slave data: */

+	uint_fast8_t slave_mem_offset_length;

+	mss_i2c_slave_wr_handler_t slave_write_handler;

+

+} mss_i2c_instance_t;

+

+/*-------------------------------------------------------------------------*//**

+  This instance of mss_i2c_instance_t holds all data related to the operations

+  performed by MSS I2C 0. A pointer to g_mss_i2c0 is passed as the first

+  parameter to MSS I2C driver functions to indicate that MSS I2C 0 should

+  perform the requested operation.

+ */

+extern mss_i2c_instance_t g_mss_i2c0;

+

+/*-------------------------------------------------------------------------*//**

+  This instance of mss_i2c_instance_t holds all data related to the operations

+  performed by MSS I2C 1. A pointer to g_mss_i2c1 is passed as the first

+  parameter to MSS I2C driver functions to indicate that MSS I2C 1 should

+  perform the requested operation.

+ */

+extern mss_i2c_instance_t g_mss_i2c1;

+

+/*-------------------------------------------------------------------------*//**

+  MSS I2C initialisation routine.

+  ------------------------------------------------------------------------------

+  The MSS_I2C_init() function initializes and configures hardware and data

+  structures of one of the SmartFusion MSS I2Cs.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to an mss_i2c_instance_t structure

+    identifying the MSS I2C hardware block to be initialized. There are two such

+    data structures, g_mss_i2c0 and g_mss_i2c1, associated with MSS I2C 0 and

+    MSS I2C 1 respectively. This parameter must point to either the g_mss_i2c0

+    or g_mss_i2c1 global data structure defined within the I2C driver.

+

+  @param ser_address:

+    This parameter sets the I2C serial address being initialized. It is the I2C

+    bus address to which the MSS I2C instance will respond. Any 8 bit address is

+    allowed.

+

+  @param ser_clock_speed:

+    This parameter sets the I2C serial clock frequency. It selects the divider

+    that will be used to generate the serial clock from the APB clock. It can be

+    one of the following:

+        • MSS_I2C_PCLK_DIV_256

+        • MSS_I2C_PCLK_DIV_224

+        • MSS_I2C_PCLK_DIV_192

+        • MSS_I2C_PCLK_DIV_160

+        • MSS_I2C_PCLK_DIV_960

+        • MSS_I2C_PCLK_DIV_120

+        • MSS_I2C_PCLK_DIV_60

+        • MSS_I2C_BCLK_DIV_8

+ */

+void MSS_I2C_init

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t ser_address,

+	mss_i2c_clock_divider_t ser_clock_speed

+);

+

+/*******************************************************************************

+ *******************************************************************************

+ *

+ *                           Master specific functions

+ *

+ * The following functions are only used within an I2C master's implementation.

+ */

+

+/*-------------------------------------------------------------------------*//**

+  I2C master write function.

+  ------------------------------------------------------------------------------

+  This function initiates an I2C master write transaction. This function returns

+  immediately after initiating the transaction. The content of the write buffer

+  passed as parameter should not be modified until the write transaction

+  completes. It also means that the memory allocated for the write buffer should

+  not be freed or go out of scope before the write completes. You can check for

+  the write transaction completion using the MSS_I2C_status() function.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+  	The this_i2c parameter is a pointer to an mss_i2c_instance_t structure

+    identifying the MSS I2C hardware block that will perform the requested

+    function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,

+    associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must

+    point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined

+    within the I2C driver.

+

+  @param serial_addr:

+  	This parameter specifies the serial address of the target I2C device.

+

+  @param write_buffer:

+  	This parameter is a pointer to a buffer holding the data to be written to

+    the target I2C device.

+    Care must be taken not to release the memory used by this buffer before the

+    write transaction completes. For example, it is not appropriate to return

+    from a function allocating this buffer as an array variable before the write

+    transaction completes as this would result in the buffer's memory being

+    de-allocated from the stack when the function returns. This memory could

+    then be subsequently reused and modified causing unexpected data to be

+    written to the target I2C device.

+

+  @param write_size:

+  	Number of bytes held in the write_buffer to be written to the target I2C

+    device.

+

+ @param options:

+ 	The options parameter is used to indicate if the I2C bus should be released

+    on completion of the write transaction. Using the MSS_I2C_RELEASE_BUS

+    constant for the options parameter causes a STOP bit to be generated at the

+    end of the write transaction causing the bus to be released for other I2C

+    devices to use. Using the MSS_I2C_HOLD_BUS constant as options parameter

+    prevents a STOP bit from being generated at the end of the write

+    transaction, preventing other I2C devices from initiating a bus transaction.

+ */

+void MSS_I2C_write

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t serial_addr,

+	const uint8_t * write_buffer,

+	uint16_t write_size,

+    uint8_t options

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C master read.

+  ------------------------------------------------------------------------------

+  This function initiates an I2C master read transaction. This function returns

+  immediately after initiating the transaction.

+  The content of the read buffer passed as parameter should not be modified

+  until the read transaction completes. It also means that the memory allocated

+  for the read buffer should not be freed or go out of scope before the read

+  completes. You can check for the read transaction completion using the

+  MSS_I2C_status() function.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+  	The this_i2c parameter is a pointer to an mss_i2c_instance_t structure

+    identifying the MSS I2C hardware block that will perform the requested

+    function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,

+    associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must

+    point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined

+    within the I2C driver.

+

+  @param serial_addr:

+  	This parameter specifies the serial address of the target I2C device.

+

+  @param read_buffer

+  	Pointer to a buffer where the data received from the target device will be

+    stored.

+    Care must be taken not to release the memory used by this buffer before the

+    read transaction completes. For example, it is not appropriate to return

+    from a function allocating this buffer as an array variable before the read

+    transaction completes as this would result in the buffer's memory being

+    de-allocated from the stack when the function returns. This memory could

+    then be subsequently reallocated resulting in the read transaction

+    corrupting the newly allocated memory.

+

+  @param read_size:

+  	This parameter is the number of bytes to read from the target device. This

+    size must not exceed the size of the read_buffer buffer.

+

+  @param options:

+ 	The options parameter is used to indicate if the I2C bus should be released

+    on completion of the read transaction. Using the MSS_I2C_RELEASE_BUS

+    constant for the options parameter causes a STOP bit to be generated at the

+    end of the read transaction causing the bus to be released for other I2C

+    devices to use. Using the MSS_I2C_HOLD_BUS constant as options parameter

+    prevents a STOP bit from being generated at the end of the read transaction,

+    preventing other I2C devices from initiating a bus transaction.

+ */

+void MSS_I2C_read

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t serial_addr,

+	uint8_t * read_buffer,

+	uint16_t read_size,

+    uint8_t options

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C master write-read

+  ------------------------------------------------------------------------------

+  This function initiates an I2C write-read transaction where data is first

+  written to the target device before issuing a restart condition and changing

+  the direction of the I2C transaction in order to read from the target device.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+  	The this_i2c parameter is a pointer to an mss_i2c_instance_t structure

+    identifying the MSS I2C hardware block that will perform the requested

+    function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,

+    associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must

+    point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined

+    within the I2C driver.

+

+  @param serial_addr:

+  	This parameter specifies the serial address of the target I2C device.

+

+  @param addr_offset:

+  	This parameter is a pointer to the buffer containing the data that will be

+    sent to the slave during the write phase of the write-read transaction. This

+    data is typically used to specify an address offset specifying to the I2C

+    slave device what data it must return during the read phase of the

+    write-read transaction.

+

+  @param offset_size:

+  	This parameter specifies the number of offset bytes to be written during the

+    write phase of the write-read transaction. This is typically the size of the

+    buffer pointed to by the addr_offset parameter.

+

+  @param read_buffer:

+  	This parameter is a pointer to the buffer where the data read from the I2C

+    slave will be stored.

+

+  @param read_size:

+  	This parameter specifies the number of bytes to read from the target I2C

+    slave device. This size must not exceed the size of the buffer pointed to by

+    the read_buffer parameter.

+

+  @param options:

+ 	The options parameter is used to indicate if the I2C bus should be released

+    on completion of the write-read transaction. Using the MSS_I2C_RELEASE_BUS

+    constant for the options parameter causes a STOP bit to be generated at the

+    end of the write-read transaction causing the bus to be released for other

+    I2C devices to use. Using the MSS_I2C_HOLD_BUS constant as options parameter

+    prevents a STOP bit from being generated at the end of the write-read

+    transaction, preventing other I2C devices from initiating a bus transaction.

+ */

+void MSS_I2C_write_read

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t serial_addr,

+	const uint8_t * addr_offset,

+	uint16_t offset_size,

+	uint8_t * read_buffer,

+	uint16_t read_size,

+    uint8_t options

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C status

+  ------------------------------------------------------------------------------

+  This function indicates the current state of a MSS I2C instance.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+  	The this_i2c parameter is a pointer to an mss_i2c_instance_t structure

+    identifying the MSS I2C hardware block that will perform the requested

+    function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,

+    associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must

+    point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined

+    within the I2C driver.

+  ------------------------------------------------------------------------------

+  @return

+    The return value indicates the current state of a MSS I2C instance or the

+    outcome of the previous transaction if no transaction is in progress.

+    Possible return values are:

+      SUCCESS

+        The last I2C transaction has completed successfully.

+      IN_PROGRESS

+        There is an I2C transaction in progress.

+      FAILED

+        The last I2C transaction failed.

+

+ */

+mss_i2c_status_t MSS_I2C_get_status

+(

+    mss_i2c_instance_t * this_i2c

+);

+

+/*-------------------------------------------------------------------------*//**

+  Wait for I2C transaction completion.

+  ------------------------------------------------------------------------------

+  This function waits for the current I2C transaction to complete. The return

+  value indicates whether the last I2C transaction was successful, or is still

+  in progress, or failed.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+    The this_i2c parameter is a pointer to an mss_i2c_instance_t structure

+    identifying the MSS I2C hardware block that will perform the requested

+    function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,

+    associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must

+    point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined

+    within the I2C driver.

+  ------------------------------------------------------------------------------

+  @return

+    The return value indicates the outcome of the last I2C transaction. It can

+    be one of the following:

+      MSS_I2C_SUCCESS

+        The last I2C transaction has completed successfully.

+      MSS_I2C_IN_PROGRESS

+        The current I2C transaction is still in progress.

+      MSS_I2C_FAILED

+        The last I2C transaction failed.

+ */

+mss_i2c_status_t MSS_I2C_wait_complete

+(

+    mss_i2c_instance_t * this_i2c

+);

+

+

+/*******************************************************************************

+ *******************************************************************************

+ *

+ *                           Slave specific functions

+ *

+ * The following functions are only used within the implementation of an I2C

+ * slave device.

+ */

+

+/*-------------------------------------------------------------------------*//**

+  I2C slave transmit buffer configuration.

+  ------------------------------------------------------------------------------

+  This function specifies the memory buffer holding the data that will be sent

+  to the I2C master when this MSS I2C instance is the target of an I2C read or

+  write-read transaction.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+  	The this_i2c parameter is a pointer to an mss_i2c_instance_t structure

+    identifying the MSS I2C hardware block that will perform the requested

+    function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,

+    associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must

+    point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined

+    within the I2C driver.

+

+  @param tx_buffer:

+  	This parameter is a pointer to the memory buffer holding the data to be

+    returned to the I2C master when this MSS I2C instance is the target of an

+    I2C read or write-read transaction.

+

+  @param tx_size:

+  	Size of the transmit buffer pointed to by the tx_buffer parameter.

+ */

+void MSS_I2C_set_slave_tx_buffer

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t * tx_buffer,

+	uint16_t tx_size

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C slave receive buffer configuration.

+  ------------------------------------------------------------------------------

+  This function specifies the memory buffer that will be used by the MSS I2C

+  instance to receive data when it is a slave. This buffer is the memory where

+  data will be stored when the MSS I2C is the target of an I2C master write

+  transaction (i.e. when it is the slave).

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+  	The this_i2c parameter is a pointer to an mss_i2c_instance_t structure

+    identifying the MSS I2C hardware block that will perform the requested

+    function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,

+    associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must

+    point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined

+    within the I2C driver.

+

+  @param rx_buffer:

+  	This parameter is a pointer to the memory buffer allocated by the caller

+    software to be used as a slave receive buffer.

+

+  @param rx_size:

+  	Size of the slave receive buffer. This is the amount of memory that is

+    allocated to the buffer pointed to by rx_buffer.

+    Note:   This buffer size will indirectly specify the maximum I2C write

+            transaction length this MSS I2C instance can be the target of. This

+            is because this MSS I2C instance will respond to further received

+            bytes with a non-acknowledge bit (NACK) as soon as its receive

+            buffer is full. This will cause the write transaction to fail.

+ */

+void MSS_I2C_set_slave_rx_buffer

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t * rx_buffer,

+	uint16_t rx_size

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C slave memory offset length configuration.

+  ------------------------------------------------------------------------------

+  This function is used as part of the configuration of a MSS I2C instance for

+  operation as a slave supporting write-read transactions. It specifies the

+  number of bytes expected as part of the write phase of a write-read

+  transaction. The bytes received during the write phase of a write-read

+  transaction will be interpreted as an offset into the slave’s transmit buffer.

+  This allows random access into the I2C slave transmit buffer from a remote

+  I2C master.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+  	The this_i2c parameter is a pointer to an mss_i2c_instance_t structure

+    identifying the MSS I2C hardware block that will perform the requested

+    function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,

+    associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must

+    point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined

+    within the I2C driver.

+

+  @param offset_length:

+  	The offset_length parameter configures the number of bytes to be interpreted

+    by the MSS I2C slave as a memory offset value during the write phase of

+    write-read transactions.

+ */

+void MSS_I2C_set_slave_mem_offset_length

+(

+	mss_i2c_instance_t * this_i2c,

+	uint8_t offset_length

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C write handler registration.

+  ------------------------------------------------------------------------------

+  Register the function that will be called to process the data written to this

+  MSS I2C instance when it is the slave in an I2C write transaction.

+  Note: The write handler is not called as a result of a write-read transaction.

+        The write data of a write read transaction is interpreted as an offset

+        into the slave’s transmit buffer and handled by the driver.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+  	The this_i2c parameter is a pointer to an mss_i2c_instance_t structure

+    identifying the MSS I2C hardware block that will perform the requested

+    function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,

+    associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must

+    point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined

+    within the I2C driver.

+

+  @param handler:

+  	Pointer to the function that will process the I2C write request.

+ */

+void MSS_I2C_register_write_handler

+(

+	mss_i2c_instance_t * this_i2c,

+	mss_i2c_slave_wr_handler_t handler

+);

+

+/*-------------------------------------------------------------------------*//**

+  I2C slave receive enable.

+  ------------------------------------------------------------------------------

+  Enables the MSS I2C instance identified through the this_i2c parameter to

+  receive data when it is the target of an I2C write or write-read transaction.

+  ------------------------------------------------------------------------------

+  @param this_i2c:

+  	The this_i2c parameter is a pointer to an mss_i2c_instance_t structure

+    identifying the MSS I2C hardware block that will perform the requested

+    function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1,

+    associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must

+    point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined

+    within the I2C driver.

+ */

+void MSS_I2C_enable_slave_rx

+(

+	mss_i2c_instance_t * this_i2c

+);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /*MSS_I2C_H_*/

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.c
new file mode 100644
index 0000000..e6b9d8e
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.c
@@ -0,0 +1,536 @@
+/*****************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ *

+ * Author : Actel Application Team

+ * Rev    : 1.0.0.0

+ * Description: Device driver for the on-board OLED for SmartFusion KITS

+ *  Implementation of sample basic driver for OLED display found on Actel

+ *  SmartFusion development boards.

+ *  This code is intended as an example of using the SmartFusion I2C driver.

+ *****************************************************************************/

+

+  #include "oled.h"

+#include "../bsp_config.h"

+

+/***************************************************************************//**

+  Command definitions for the SSD300 controller inside the OLED display module.

+ */

+#define CMD_DISPLAY_OFF_SET   0xD3

+#define CMD_PANEL_ON          0xAF

+#define CMD_PANEL_OFF         0xAE

+#define CMD_DC_DC             0xAD

+#define CMD_DC_DC_DEFAULT_ON  0x8B

+#define CMD_DC_DC_OFF         0x8A

+#define CMD_DISPLAY_ALL_ON    0xA5

+#define CMD_DISPLAY_ALL_OFF   0xA4

+#define CMD_DISPLAY_NON_INV   0xA6

+#define CMD_DISPLAY_INV       0xA7

+#define CMD_ARECOL_LPM        0xD8

+#define CMD_ARECOL_MONO       0x00

+#define CMD_ARECOL_COLOR      0x30

+#define CMD_LPM_ON            0x05

+#define CMD_LPM_OFF           0x00

+#define CMD_CONTRAST          0x81

+#define CMD_MIRROR_HORI_ON    0xC8

+#define CMD_MIRROR_HORI_OFF   0xC0

+#define CMD_MIRROR_VERT_ON    0xA1

+#define CMD_MIRROR_VERT_OFF   0xA0

+#define CMD_HORI_SCRL         0x26

+#define CMD_HORI_SCRL_ON      0x2F

+#define CMD_HORI_SCRL_OFF     0x2E

+#define CMD_MUX_RATIO          0xA8

+#define CMD_MUX_RATIO_31      0x23

+

+#define CMD_PAGE_0            0xB0

+#define CMD_PAGE_1            0xB1

+#define CMD_PAGE_2            0xB2

+#define CMD_PAGE_3            0xB3

+#define CMD_PAGE_4            0xB4

+#define CMD_PAGE_5            0xB5

+

+#define CMD_LOW_NIB_COL       0x00

+#define CMD_HIGH_NIB_COL      0x10

+

+#define CMD_START_LINE        0x50

+#define CONTRAST_DEFAULT      0xFF

+#define CONTRAST_25_PERC      0x40

+#define CONTRAST_100_PERC     0xFF

+#define CONTRAST_0_PERC       0x00

+#define SCROLL_1_COLUMN       0x01

+#define SCROLL_2_COLUMN       0x02

+#define SCROLL_3_COLUMN       0x03

+#define SCROLL_4_COLUMN       0x04

+#define SCROLL_PAGE_0         0x00

+#define SCROLL_PAGE_1         0x01

+#define SCROLL_PAGE_2         0x02

+#define SCROLL_PAGE_3         0x03

+#define SCROLL_PAGE_4         0x04

+#define SCROLL_PAGE_5         0x05

+#define SCROLL_12_FRAMES      0x00

+#define SCROLL_64_FRAMES      0x01

+#define SCROLL_128_FRAMES     0x02

+#define SCROLL_256_FRAMES     0x03

+#define SCROLL_PER_STEP       0x01

+#define PAGE0_COLOR_BAG       0x92

+#define PAGE1_COLOR_BAG       0x93

+

+/***************************************************************************//**

+  OLED display I2C communication protocol control byte values. Used to indicate

+  whether the byte following the control byte is to be interpreted by the OLED

+  display as a command or data byte.

+ */

+#define  OLED_COMMAND_CODE  0x80

+#define  OLED_DATA_CODE     0xC0

+

+/***************************************************************************//**

+  I2C serial address of OLED display.

+ */

+#define OLED_SLAVE_ADDRESS    0x78

+

+/***************************************************************************//**

+  Bitmaps of the character set.

+  Each character is 5 pixels wide and 7 pixels high.

+  The table is indexed on ASCII character codes.

+ */

+#define CHARACTER_WIDTH   5

+

+const unsigned char oled_ascii_character_set[255][CHARACTER_WIDTH] =

+{

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+

+    {0x00, 0x00, 0x5F, 0x00, 0x00},

+    {0x00, 0x07, 0x00, 0x07, 0x00},

+    {0x14, 0x7F, 0x14, 0x7F, 0x14},

+    {0x24, 0x2A, 0x7F, 0x2A, 0x12},

+    {0x23, 0x13, 0x08, 0x64, 0x62},

+    {0x36, 0x49, 0x55, 0x22, 0x50},

+    {0x00, 0x05, 0x03, 0x00, 0x00},

+    {0x00, 0x1C, 0x22, 0x41, 0x00},

+    {0x00, 0x41, 0x22, 0x1C, 0x00},

+    {0x14, 0x08, 0x3E, 0x08, 0x14},

+    {0x08, 0x08, 0x3E, 0x08, 0x08},

+    {0x00, 0x50, 0x30, 0x00, 0x00},

+    {0x08, 0x08, 0x08, 0x08, 0x08},

+    {0x00, 0x60, 0x60, 0x00, 0x00},

+    {0x20, 0x10, 0x08, 0x04, 0x02},

+    {0x3E, 0x51, 0x49, 0x45, 0x3E},

+    {0x00, 0x42, 0x7F, 0x40, 0x00},

+    {0x42, 0x61, 0x51, 0x49, 0x46},

+    {0x21, 0x41, 0x45, 0x4B, 0x31},

+    {0x18, 0x14, 0x12, 0x7F, 0x10},

+    {0x27, 0x45, 0x45, 0x45, 0x39},

+    {0x3C, 0x4A, 0x49, 0x49, 0x30},

+    {0x01, 0x71, 0x09, 0x05, 0x03},

+    {0x36, 0x49, 0x49, 0x49, 0x36},

+    {0x06, 0x49, 0x49, 0x29, 0x1E},

+    {0x00, 0x36, 0x36, 0x00, 0x00},

+    {0x00, 0x56, 0x36, 0x00, 0x00},

+    {0x08, 0x14, 0x22, 0x41, 0x00},

+    {0x14, 0x14, 0x14, 0x14, 0x14},

+    {0x00, 0x41, 0x22, 0x14, 0x08},

+    {0x02, 0x01, 0x51, 0x09, 0x06},

+    {0x32, 0x49, 0x79, 0x41, 0x3E},

+    {0x7E, 0x11, 0x11, 0x11, 0x7E},

+    {0x7F, 0x49, 0x49, 0x49, 0x36},

+    {0x3E, 0x41, 0x41, 0x41, 0x22},

+    {0x7F, 0x41, 0x41, 0x22, 0x1C},

+    {0x7F, 0x49, 0x49, 0x49, 0x41},

+    {0x7F, 0x09, 0x09, 0x09, 0x01},

+    {0x3E, 0x41, 0x49, 0x49, 0x7A},

+    {0x7F, 0x08, 0x08, 0x08, 0x7F},

+    {0x00, 0x41, 0x7F, 0x41, 0x00},

+    {0x20, 0x40, 0x41, 0x3F, 0x01},

+    {0x7F, 0x08, 0x14, 0x22, 0x41},

+    {0x3F, 0x40, 0x40, 0x40, 0x40},

+    {0x7F, 0x02, 0x0C, 0x02, 0x7F},

+    {0x7F, 0x04, 0x08, 0x10, 0x7F},

+    {0x3E, 0x41, 0x41, 0x41, 0x3E},

+    {0x7F, 0x09, 0x09, 0x09, 0x06},

+    {0x3E, 0x41, 0x51, 0x21, 0x5E},

+    {0x7F, 0x09, 0x19, 0x29, 0x46},

+    {0x46, 0x49, 0x49, 0x49, 0x31},

+    {0x01, 0x01, 0x7F, 0x01, 0x01},

+    {0x3F, 0x40, 0x40, 0x40, 0x3F},

+    {0x1F, 0x20, 0x40, 0x20, 0x1F},

+    {0x3F, 0x40, 0x38, 0x40, 0x3F},

+    {0x63, 0x14, 0x08, 0x14, 0x63},

+    {0x07, 0x08, 0x70, 0x08, 0x07},

+    {0x61, 0x51, 0x49, 0x45, 0x43},

+    {0x00, 0x7F, 0x41, 0x41, 0x00},

+    {0x02, 0x04, 0x08, 0x10, 0x20},

+    {0x00, 0x41, 0x41, 0x7F, 0x00},

+    {0x04, 0x02, 0x01, 0x02, 0x04},

+    {0x40, 0x40, 0x40, 0x40, 0x40},

+    {0x00, 0x01, 0x02, 0x04, 0x00},

+    {0x20, 0x54, 0x54, 0x54, 0x78},

+    {0x7F, 0x48, 0x44, 0x44, 0x38},

+    {0x38, 0x44, 0x44, 0x44, 0x20},

+    {0x30, 0x48, 0x48, 0x50, 0x7F},

+    {0x38, 0x54, 0x54, 0x54, 0x18},

+    {0x10, 0x7E, 0x11, 0x01, 0x02},

+    {0x0C, 0x52, 0x52, 0x52, 0x3E},

+    {0x7F, 0x08, 0x04, 0x04, 0x78},

+    {0x00, 0x44, 0x7D, 0x40, 0x00},

+    {0x20, 0x40, 0x44, 0x3D, 0x00},

+    {0x7F, 0x10, 0x28, 0x44, 0x00},

+    {0x00, 0x41, 0x7F, 0x40, 0x00},

+    {0x7C, 0x04, 0x18, 0x04, 0x78},

+    {0x7C, 0x08, 0x04, 0x04, 0x78},

+    {0x38, 0x44, 0x44, 0x44, 0x38},

+    {0x7C, 0x14, 0x14, 0x14, 0x08},

+    {0x08, 0x14, 0x14, 0x18, 0x7C},

+    {0x7C, 0x08, 0x04, 0x04, 0x08},

+    {0x48, 0x54, 0x54, 0x54, 0x20},

+    {0x04, 0x3F, 0x44, 0x40, 0x20},

+    {0x3C, 0x40, 0x40, 0x20, 0x7C},

+    {0x1C, 0x20, 0x40, 0x20, 0x1C},

+    {0x3C, 0x40, 0x30, 0x40, 0x3C},

+    {0x44, 0x28, 0x10, 0x28, 0x44},

+    {0x0C, 0x50, 0x50, 0x50, 0x3C},

+    {0x44, 0x64, 0x54, 0x4C, 0x44},

+

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00},

+

+    {0x07, 0x05, 0x07, 0x00, 0x00},

+    {0x12, 0x19, 0x16, 0x00, 0x00},

+    {0x00, 0x00, 0x00, 0x00, 0x00}

+

+};

+

+#define FIRST_CHARACTER       0

+

+/***************************************************************************//**

+  The g_p_oled_i2c global variable is only used inside the OLED driver. It

+  identifies the MSS I2C block used to communicate with the OLED display.

+ */

+static mss_i2c_instance_t * g_p_oled_i2c = OLED_I2C_INSTANCE;

+

+/***************************************************************************//**

+  The OLED_set_cursor function sets the cursor position.

+

+  @param line

+  The line parameter specifies the line at which to set the cursor. It can

+  take the values:

+  - FIRST_LINE

+  - SECOND_LINE

+

+  @param char_offset

+  The char_offset paraemter specifies the character offset on a line where to

+  set the cursor location. It can be set to FIRST_CHARACTER to set the cursor

+  at the start of a line.

+ */

+void OLED_set_cursor

+(

+    uint8_t line,

+    uint8_t char_offset

+);

+/***************************************************************************//**

+  The OLED_write_string function displays the input string to the OLED panel.

+

+  @param string

+  The string parameter is a pointer to the zero-terminated to display on the

+  OLED.

+ */

+void OLED_write_string( const char *string);

+

+/***************************************************************************//**

+  The OLED_write_char function displays a single character to the display.

+

+  @param data_char

+    The data_char parameter is the ASCII code of the character to display.

+*/

+void OLED_write_char( const uint8_t data_char );

+/***************************************************************************//**

+  OLED_init()

+  See "oled.h" for details of how to use this function.

+ */

+void OLED_init(void )

+{

+    uint8_t oled_init_sequence1[] =

+    {

+        OLED_COMMAND_CODE, CMD_DISPLAY_NON_INV,

+        OLED_COMMAND_CODE, CMD_DISPLAY_ALL_OFF,

+        OLED_COMMAND_CODE, CMD_MIRROR_HORI_ON,

+        OLED_COMMAND_CODE, CMD_MIRROR_VERT_OFF,

+        OLED_COMMAND_CODE, CMD_HORI_SCRL_OFF,

+        OLED_COMMAND_CODE, CMD_CONTRAST,

+        OLED_COMMAND_CODE, CONTRAST_DEFAULT,

+        OLED_COMMAND_CODE, CMD_ARECOL_LPM,

+        OLED_COMMAND_CODE, CMD_ARECOL_MONO^CMD_LPM_OFF

+    };

+

+    uint8_t oled_init_sequence2[] =

+    {

+        OLED_COMMAND_CODE, CMD_START_LINE,

+        OLED_COMMAND_CODE, CMD_PANEL_ON

+    };

+

+    MSS_I2C_init( g_p_oled_i2c, OLED_SLAVE_ADDRESS, MSS_I2C_PCLK_DIV_60 );

+

+    MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, oled_init_sequence1, sizeof(oled_init_sequence1), MSS_I2C_RELEASE_BUS );

+    MSS_I2C_wait_complete( g_p_oled_i2c );

+

+    OLED_clear_display(BOTH_LINES);

+

+    MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, oled_init_sequence2, sizeof(oled_init_sequence2), MSS_I2C_RELEASE_BUS );

+    MSS_I2C_wait_complete( g_p_oled_i2c );

+

+    OLED_set_cursor( FIRST_LINE, FIRST_CHARACTER );

+}

+

+/***************************************************************************//**

+  OLED_clear_display()

+  See "oled.h" for details of how to use this function.

+ */

+void OLED_clear_display( oled_no_of_line LINES )

+{

+    uint8_t i, j,start_line,end_line;

+    uint8_t clear_8_columns[] =

+    {

+        OLED_DATA_CODE, 0x00,

+        OLED_DATA_CODE, 0x00,

+        OLED_DATA_CODE, 0x00,

+        OLED_DATA_CODE, 0x00,

+        OLED_DATA_CODE, 0x00,

+        OLED_DATA_CODE, 0x00,

+        OLED_DATA_CODE, 0x00,

+        OLED_DATA_CODE, 0x00

+    };

+

+    switch(LINES)

+    {

+        case FIRST_LINE:

+        {

+            start_line = FIRST_LINE;

+            end_line = FIRST_LINE;

+        }

+

+        case SECOND_LINE:

+        {

+            start_line = SECOND_LINE;

+            end_line = SECOND_LINE;

+        }

+

+        case BOTH_LINES:

+        {

+            start_line = FIRST_LINE;

+            end_line = SECOND_LINE;

+        }

+

+    }

+

+    for( j = start_line; j <= end_line; ++j )

+    {

+        OLED_set_cursor( j, FIRST_CHARACTER );

+        for( i = 0; i < 13; ++i )

+        {

+            MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, clear_8_columns, sizeof(clear_8_columns), MSS_I2C_RELEASE_BUS );

+            MSS_I2C_wait_complete( g_p_oled_i2c );

+        }

+    }

+}

+

+/***************************************************************************//**

+  OLED_set_cursor()

+  See definition of OLED_set_cursor() for details of how to use this function.

+ */

+void OLED_set_cursor

+(

+    uint8_t line,

+    uint8_t char_offset

+)

+{

+    uint8_t command_sequence[] =

+    {

+        OLED_COMMAND_CODE, CMD_LOW_NIB_COL,

+        OLED_COMMAND_CODE, CMD_HIGH_NIB_COL,

+        OLED_COMMAND_CODE, CMD_PAGE_0

+    };

+    uint8_t low_nib, high_nib;

+

+    ++char_offset;

+    char_offset *= CHARACTER_WIDTH;

+    low_nib = 0x0F & char_offset;

+    high_nib = (0xF0 & char_offset) >> 4;

+    line += 2;

+

+    command_sequence[1] |= low_nib;

+    command_sequence[3] |= high_nib;

+    command_sequence[5] |= line;

+    MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, command_sequence, sizeof(command_sequence), MSS_I2C_RELEASE_BUS );

+    MSS_I2C_wait_complete( g_p_oled_i2c );

+}

+

+/***************************************************************************//**

+  OLED_write_string()

+  See definition of OLED_write_string for details of how to use this function.

+ */

+void OLED_write_string

+(

+    const char *string

+)

+{

+  while (*string != 0)

+  {

+      OLED_write_char( *string );

+      ++string;

+  }

+}

+

+/***************************************************************************//**

+  OLED_write_char()

+  See definition of OLED_write_char()  for details of how to use this function.

+ */

+void OLED_write_char

+(

+    const uint8_t data_char

+)

+{

+    uint8_t txbuff[10];

+    uint8_t i;

+

+    for ( i = 0; i < CHARACTER_WIDTH; ++i )

+    {

+        txbuff[i * 2] = OLED_DATA_CODE;

+        txbuff[(i * 2) + 1] = oled_ascii_character_set[data_char][i];

+    }

+    MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, txbuff, sizeof(txbuff), MSS_I2C_RELEASE_BUS );

+    MSS_I2C_wait_complete( g_p_oled_i2c );

+}

+

+/***************************************************************************//**

+  OLED_horizontal_scroll()

+  See "oled.h" for details of how to use this function.

+ */

+void OLED_horizontal_scroll(struct oled_data * horiz_scroll)

+{

+    uint8_t horiz_scroll_on_off[] =

+    {

+        OLED_COMMAND_CODE, CMD_HORI_SCRL_OFF,

+    };

+

+    uint8_t horiz_scroll_setup_data[] =

+    {

+        OLED_COMMAND_CODE, CMD_HORI_SCRL,

+        OLED_COMMAND_CODE, SCROLL_PER_STEP,

+        OLED_COMMAND_CODE, SCROLL_PAGE_0,

+        OLED_COMMAND_CODE, SCROLL_12_FRAMES,

+        OLED_COMMAND_CODE, SCROLL_PAGE_1,

+    };

+    MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, horiz_scroll_on_off, sizeof(horiz_scroll_on_off), MSS_I2C_RELEASE_BUS );

+    MSS_I2C_wait_complete( g_p_oled_i2c );

+

+    if(horiz_scroll->on_off == 1)

+    {

+        horiz_scroll_setup_data[3] = horiz_scroll->column_scrool_per_step;

+        horiz_scroll_setup_data[5] = horiz_scroll->start_page;

+        horiz_scroll_setup_data[7] = horiz_scroll->time_intrval_btw_scroll_step;

+        horiz_scroll_setup_data[9] = horiz_scroll->end_page;

+        MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, horiz_scroll_setup_data, sizeof(horiz_scroll_setup_data), MSS_I2C_RELEASE_BUS );

+        MSS_I2C_wait_complete( g_p_oled_i2c );

+

+        horiz_scroll_on_off[1] = CMD_HORI_SCRL_ON;

+        MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, horiz_scroll_on_off, sizeof(horiz_scroll_on_off), MSS_I2C_RELEASE_BUS );

+        MSS_I2C_wait_complete( g_p_oled_i2c );

+    }

+}

+

+/***************************************************************************//**

+  OLED_contrast()

+  See "oled.h" for details of how to use this function.

+ */

+void OLED_contrast(uint8_t color_contrast)

+{

+    uint8_t oled_contrast[] =

+    {

+        OLED_COMMAND_CODE, CMD_CONTRAST,

+        OLED_COMMAND_CODE, CONTRAST_DEFAULT,

+    };

+

+    oled_contrast[3] = color_contrast;

+    MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, oled_contrast, sizeof(oled_contrast), MSS_I2C_RELEASE_BUS );

+    MSS_I2C_wait_complete( g_p_oled_i2c );

+

+}

+

+/***************************************************************************//**

+  OLED_write_data()

+  See "oled.h" for details of how to use this function.

+ */

+void OLED_write_data(struct oled_data* data, oled_no_of_line LINES)

+{

+    uint8_t line;

+    uint8_t char_offset;

+    char *string;

+

+    switch(LINES)

+    {

+

+        case FIRST_LINE:

+        {

+            OLED_clear_display(FIRST_LINE);

+            line = data->line1;

+            char_offset = data->char_offset1;

+            string = data->string1;

+        }

+

+        case SECOND_LINE:

+        {

+            OLED_clear_display(SECOND_LINE);

+            line = data->line2;

+            char_offset = data->char_offset2;

+           string = data->string2;

+        }

+

+        case BOTH_LINES:

+        {

+            OLED_clear_display(BOTH_LINES);

+            line = data->line1;

+            char_offset = data->char_offset1;

+            string = data->string1;

+            OLED_set_cursor(line,char_offset);

+            OLED_write_string(string);

+            line = data->line2;

+            char_offset = data->char_offset2;

+            string = data->string2;

+        }

+

+        OLED_set_cursor(line,char_offset);

+        OLED_write_string(string);

+        OLED_contrast(data->contrast_val);

+    }

+}

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.h
new file mode 100644
index 0000000..17ab4a7
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.h
@@ -0,0 +1,210 @@
+/*****************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ *

+ * Author : Actel Application Team

+ * Rev    : 1.0.0.0

+ * Description: Device driver for the on-board OLED for SmartFusion KITS

+ *  API of sample basic driver for OLED display found on Actel SmartFusion

+ *  development boards.

+ *  This code is intended as an example of using the SmartFusion I2C driver.

+ *

+ */

+#ifndef OLED_H_

+#define OLED_H_

+

+#include "i2c.h"

+

+#define OLED_HORIZ_SCROLL_ON    0x01

+#define OLED_HORIZ_SCROLL_OFF   0x00

+#define OLED_HORIZ_SCROLL_STEP  0x08

+#define OLED_CONTRAST_VAL       0xFF

+#define OLED_START_PAGE         0x01

+#define OLED_HORIZ_SCROLL_TINVL 0x00

+#define OLED_END_PAGE           0x05

+/*-------------------------------------------------------------------------*/

+/*  The oled_no_of_line type represents number of lines to be written on OLED.

+    FIRST LINE  : The OLED cursor is set to line number 1 and only 1 line is

+                  printed on OLED

+    SECOND_LINE : The OLED cursor is set to line number 2 and only 1 line is

+                  printed on OLED

+    BOTH_LINES  : The OLED cursor is set to line number 1 and line 1 and line 2

+                  are printed on OLED

+*/

+typedef enum {

+    FIRST_LINE = 0,

+    SECOND_LINE,

+    BOTH_LINES

+} oled_no_of_line;

+

+/*-------------------------------------------------------------------------*//**

+  oled_data

+  ------------------------------------------------------------------------------

+  There is one instance of this structure for OLED data. Instances of this

+  structure is used to provide the data to OLED. A pointer to an instance of

+  the oled_data structure is passed as the parameter OLED driver functions.

+ */

+struct oled_data

+{

+    /* Represents line number, where String 1 has to be printed */

+    uint8_t line1;

+    /* Represents character offset within the line1, from where String 1 has to be

+     * printed */

+    uint8_t char_offset1;

+    /* Represents line number, where String 2 has to be printed */

+    uint8_t line2;

+    /* Represents character offset within the line2, from where String 2 has to be

+     * printed */

+    uint8_t char_offset2;

+    /* String 1 holds the data to be displayed on line 1 of OLED, It has to be

+     * less that 49 characters*/

+    char    *string1;

+    /* String 1 holds the data to be displayed on line 2 of OLED, It has to be

+     * less that 49 characters*/

+    char    *string2;

+    /* Holds the contrast value to be set for String 1 and String 2 */

+    uint8_t contrast_val;

+    /* Represents ON or OFF for horizontal scrolling  */

+    uint8_t on_off;

+    /* Represents  number of coumns scrolls per step for horizontal scroll*/

+    unsigned char column_scrool_per_step;

+    /* Represents  start page for horizontal scroll*/

+    unsigned char start_page;

+    /* Represents  time interval for horizontal scroll*/

+    unsigned char time_intrval_btw_scroll_step;

+    /* Represents  end page for horizontal scroll*/

+    unsigned char end_page;

+

+};

+/***************************************************************************//**

+  The following defines can be used as parameter to the OLED_set_cursor()

+  function.

+ */

+

+/***************************************************************************//**

+  The OLED_init function initializes the OLED display.

+ */

+void vOLEDInit( void );

+void OLED_init( void );

+

+/***************************************************************************//**

+  This function(OLED_clear_display) clears the content of the display RAM

+  based on the LINES input.

+  ------------------------------------------------------------------------------

+  @param oled_no_of_line:

+      The oled_no_of_line parameter enum that holds Number of lines.

+      If FIRST_LINE is passed as parameter to this function thnen, this functions

+      clears only First line that is 0

+      If SECOND_LINE is passed as parameter to this function thnen, this functions

+      clears only Second line that is 1

+      If BOTH_LINE is passed as parameter to this function thnen, this functions

+      clears entire OLED display.

+ */

+void OLED_clear_display( oled_no_of_line LINES );

+

+/*-------------------------------------------------------------------------*//**

+  OLED Write data.

+  ------------------------------------------------------------------------------

+  This function (OLED_write_data ) writes the data to OLED basedon the

+  parameters passed to this function.

+  ------------------------------------------------------------------------------

+  @param data:

+      The data parameter is a pointer to an oled_data structure, that holds

+      different fields of data to be required for OLED (see the oled_data structure

+      definition).

+

+  @param oled_no_of_line:

+      The oled_no_of_line parameter enum that holds Number of lines.

+      If FIRST_LINE is passed as parameter to this function thnen, this functions

+      wtites string 1 at FIRST LINE

+      If SECOND_LINE is passed as parameter to this function thnen, this functions

+      wtites string 1 at SECOND LINE

+      If BOTH_LINE is passed as parameter to this function thnen, this functions

+      wtites string 1 and string 2 at FIRST LINE and SECOND LINE respectively.

+Example:

+  @code

+#include "drivers/mss_watchdog/mss_watchdog.h"

+#include "oled.h"

+#define FIRST_CHARACTER 0

+

+int main()

+{

+

+    char *string1="SmartFusion";

+    char *string2="INNOVATIVE ";

+    struct oled_data write_data;

+

+    write_data.line1 = FIRST_LINE;

+    write_data.char_offset1 = FIRST_CHARACTER;

+    write_data.string1 = string1;

+    write_data.line2 = SECOND_LINE;

+    write_data.char_offset2 = FIRST_CHARACTER;

+    write_data.string2 = string2;

+    write_data.contrast_val = 0x01;

+

+    MSS_WD_disable();

+    OLED_init();

+    OLED_write_data(&write_data,BOTH_LINES);

+    return 0;

+}

+  @endcode

+ */

+

+void OLED_write_data(struct oled_data * data, oled_no_of_line flag);

+

+/*-------------------------------------------------------------------------*//**

+  OLED Horizontal scrolling.

+  ------------------------------------------------------------------------------

+  This function (OLED_horizontal_scroll ) enbles the Horizontal scrolling.

+  ------------------------------------------------------------------------------

+  @param data:

+      The horiz_scroll parameter is a pointer to an oled_data structure, that holds

+      different fields of data to be required for OLED (see the oled_data structure

+      definition).

+Example:

+  @code

+

+int main()

+{

+

+    char *string1="SmartFusion";

+    char *string2="INNOVATIVE     ";

+    struct oled_data write_data;

+

+    write_data.line1 = FIRST_LINE;

+    write_data.char_offset1 = FIRST_CHARACTER;

+    write_data.string1 = string1;

+    write_data.line2 = SECOND_LINE;

+    write_data.char_offset2 = FIRST_CHARACTER;

+    write_data.string2 = string2;

+    write_data.contrast_val = 0x01;

+    write_data.on_off = 0x01;

+    write_data.column_scrool_per_step = 0x08;

+    write_data.start_page = 0x01;

+    write_data.time_intrval_btw_scroll_step = 0x00;

+    write_data.end_page = 0x05;

+

+    MSS_WD_disable();

+    OLED_init();

+    OLED_write_data(&write_data,BOTH_LINES);

+    OLED_horizontal_scroll(&write_data);

+    return 0;

+}

+  @endcode

+ */

+

+void OLED_horizontal_scroll(struct oled_data * horiz_scroll);

+

+/***************************************************************************//**

+  This function(OLED_contrast) sets ths conrtast to the data displayed on the

+  OLED.

+  ------------------------------------------------------------------------------

+  @param color_contrast:

+  The color_contrast parameter that holds contrast value.

+  The color_contrast values should be in the range of 1 to 256.

+ */

+void OLED_contrast(uint8_t color_contrast);

+

+#endif

+

+

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/bsp_config.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/bsp_config.h
new file mode 100644
index 0000000..79f456e
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/bsp_config.h
@@ -0,0 +1,28 @@
+/*****************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ *

+ *

+ *

+ * Author : Actel Application Team

+ * Rev    : 1.0.0.0

+ * Description: Configuration for the ON-BOARD peripherals for SmartFusion KITS.

+ *

+ *******************************************************************************/

+#ifndef BSP_CONFIG_H_

+#define BSP_CONFIG_H_

+

+#include "i2c.h"

+/* Configuration for OLED */

+#define OLED_I2C_INSTANCE    &g_mss_i2c0

+

+/* Configuration for the SPI Flash */

+#define SPI_FLASH_ON_SF_DEV_KIT  0

+#define SPI_FLASH_ON_SF_EVAL_KIT 1

+

+#define USE_DMA_FOR_SPI_FLASH 1

+#define SPI_FLASH_DMA_CHANNEL 0

+

+#endif

+

+

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_convert.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_convert.c
new file mode 100644
index 0000000..dbe1205
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_convert.c
@@ -0,0 +1,831 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ * SVN $Revision: 2905 $

+ * SVN $Date: 2010-08-20 14:03:28 +0100 (Fri, 20 Aug 2010) $

+ */

+#include "mss_ace.h"

+#include "mss_ace_configurator.h"

+#include "../../CMSIS/a2fxxxm3.h"

+#include "../../CMSIS/mss_assert.h"

+#include "../../drivers_config/mss_ace/ace_handles.h"

+#include "../../drivers_config/mss_ace/ace_config.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+extern ace_channel_desc_t g_ace_channel_desc_table[ACE_NB_OF_INPUT_CHANNELS];

+extern ace_adc_config_t g_ace_adc_config[ACE_NB_OF_ADC];

+extern const uint32_t g_ace_current_resistors[ACE_NB_OF_CURRENT_MONITORS];

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+static uint16_t convert_mV_to_ppe_value

+(

+    ace_channel_handle_t    channel_handle,

+    uint32_t                voltage

+);

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ace_init_convert(void);

+

+/*-------------------------------------------------------------------------*//**

+ * 

+ */

+#define VOLTAGE_CHANNEL     0u

+#define CURRENT_CHANNEL     1u

+#define TEMPERATURE_CHANNEL 2u

+#define INVALID_CHANNEL     0xFFu

+

+static const uint8_t channel_type_lut[] =

+{

+    VOLTAGE_CHANNEL,        /* ADC0_1P5V = 0 */

+    VOLTAGE_CHANNEL,        /* ABPS0 = 1 */

+    VOLTAGE_CHANNEL,        /* ABPS1 = 2 */

+    CURRENT_CHANNEL,        /* CM0 = 3 */

+    TEMPERATURE_CHANNEL,    /* TM0 = 4 */

+    VOLTAGE_CHANNEL,        /* ABPS2 = 5 */

+    VOLTAGE_CHANNEL,        /* ABPS3 = 6 */

+    CURRENT_CHANNEL,        /* CM1 = 7 */

+    TEMPERATURE_CHANNEL,    /* TM1 = 8 */

+    VOLTAGE_CHANNEL,        /* ADC0 = 9 */

+    VOLTAGE_CHANNEL,        /* ADC1 = 10 */

+    VOLTAGE_CHANNEL,        /* ADC2 = 11 */

+    VOLTAGE_CHANNEL,        /* ADC3 = 12 */

+    INVALID_CHANNEL,

+    INVALID_CHANNEL,

+    VOLTAGE_CHANNEL,        /* SDD0_IN = 15 */

+

+    VOLTAGE_CHANNEL,        /* ADC1_1P5V = 16 */

+    VOLTAGE_CHANNEL,        /* ABPS4 = 17 */

+    VOLTAGE_CHANNEL,        /* ABPS5 = 18 */

+    CURRENT_CHANNEL,        /* CM2 = 19 */

+    TEMPERATURE_CHANNEL,    /* TM2 = 20 */

+    VOLTAGE_CHANNEL,        /* ABPS6 = 21 */

+    VOLTAGE_CHANNEL,        /* ABPS7 = 22 */

+    CURRENT_CHANNEL,        /* CM3 = 23 */

+    TEMPERATURE_CHANNEL,    /* TM3 = 24 */

+    VOLTAGE_CHANNEL,        /* ADC4 = 25 */

+    VOLTAGE_CHANNEL,        /* ADC5 = 26 */

+    VOLTAGE_CHANNEL,        /* ADC6 = 27 */

+    VOLTAGE_CHANNEL,        /* ADC7 = 28 */

+    INVALID_CHANNEL,

+    INVALID_CHANNEL,

+    VOLTAGE_CHANNEL,        /* SDD1_IN = 31 */

+

+    VOLTAGE_CHANNEL,        /* ADC2_1P5V = 32 */

+    VOLTAGE_CHANNEL,        /* ABPS8 = 33 */

+    VOLTAGE_CHANNEL,        /* ABPS9 = 34 */

+    CURRENT_CHANNEL,        /* CM4 = 35 */

+    TEMPERATURE_CHANNEL,    /* TM4 = 36 */

+    VOLTAGE_CHANNEL,        /* ABPS10 = 37 */

+    VOLTAGE_CHANNEL,        /* ABPS11 = 38 */

+    CURRENT_CHANNEL,        /* CM5 = 39 */

+    TEMPERATURE_CHANNEL,    /* TM5 = 40 */

+    VOLTAGE_CHANNEL,        /* ADC8 = 41 */

+    VOLTAGE_CHANNEL,        /* ADC9 = 42 */

+    VOLTAGE_CHANNEL,        /* ADC10 = 43 */

+    VOLTAGE_CHANNEL,        /* ADC11 = 44 */

+    INVALID_CHANNEL,

+    INVALID_CHANNEL,

+    VOLTAGE_CHANNEL         /* SDD2_IN = 47 */

+};

+

+static const uint8_t channel_quad_lut[] =

+{

+    0xFFu,   /* ADC0_1P5V = 0 */

+    0u,      /* ABPS0 = 1 */

+    0u,      /* ABPS1 = 2 */

+    0u,      /* CM0 = 3 */

+    0u,      /* TM0 = 4 */

+    1u,      /* ABPS2 = 5 */

+    1u,      /* ABPS3 = 6 */

+    1u,      /* CM1 = 7 */

+    1u,      /* TM1 = 8 */

+    0xFFu,   /* ADC0 = 9 */

+    0xFFu,   /* ADC1 = 10 */

+    0xFFu,   /* ADC2 = 11 */

+    0xFFu,   /* ADC3 = 12 */

+    INVALID_CHANNEL,

+    INVALID_CHANNEL,

+    0xFFu,   /* SDD0_IN = 15 */

+

+    0xFFu,   /* ADC1_1P5V = 16 */

+    2u,      /* ABPS4 = 17 */

+    2u,      /* ABPS5 = 18 */

+    2u,      /* CM2 = 19 */

+    2u,      /* TM2 = 20 */

+    3u,      /* ABPS6 = 21 */

+    3u,      /* ABPS7 = 22 */

+    3u,      /* CM3 = 23 */

+    3u,      /* TM3 = 24 */

+    0xFFu,   /* ADC4 = 25 */

+    0xFFu,   /* ADC5 = 26 */

+    0xFFu,   /* ADC6 = 27 */

+    0xFFu,   /* ADC7 = 28 */

+    INVALID_CHANNEL,

+    INVALID_CHANNEL,

+    0xFFu,   /* SDD1_IN = 31 */

+

+    0xFFu,   /* ADC2_1P5V = 32 */

+    4u,      /* ABPS8 = 33 */

+    4u,      /* ABPS9 = 34 */

+    4u,      /* CM4 = 35 */

+    4u,      /* TM4 = 36 */

+    5u,      /* ABPS10 = 37 */

+    5u,      /* ABPS11 = 38 */

+    5u,      /* CM5 = 39 */

+    5u,      /* TM5 = 40 */

+    0xFFu,   /* ADC8 = 41 */

+    0xFFu,   /* ADC9 = 42 */

+    0xFFu,   /* ADC10 = 43 */

+    0xFFu,   /* ADC11 = 44 */

+    INVALID_CHANNEL,

+    INVALID_CHANNEL,

+    0xFFu    /* SDD2_IN = 47 */

+};

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#define NON_ABPS_CHANNEL    0xFFu

+#define MAX_NB_OF_APBS      12u

+

+/*-------------------------------------------------------------------------*//**

+ * Lookup of the quad to which an ABPS belongs

+ */

+static const uint8_t abps_channel_lut[] =

+{

+    NON_ABPS_CHANNEL,   /* ADC0_1P5V = 0 */

+    0u,                 /* ABPS0 = 1 */

+    0u,                 /* ABPS1 = 2 */

+    NON_ABPS_CHANNEL,   /* CM0 = 3 */

+    NON_ABPS_CHANNEL,   /* TM0 = 4 */

+    1u,                 /* ABPS2 = 5 */

+    1u,                 /* ABPS3 = 6 */

+    NON_ABPS_CHANNEL,   /* CM1 = 7 */

+    NON_ABPS_CHANNEL,   /* TM1 = 8 */

+    NON_ABPS_CHANNEL,   /* ADC0 = 9 */

+    NON_ABPS_CHANNEL,   /* ADC1 = 10 */

+    NON_ABPS_CHANNEL,   /* ADC2 = 11 */

+    NON_ABPS_CHANNEL,   /* ADC3 = 12 */

+    INVALID_CHANNEL,

+    INVALID_CHANNEL,

+    NON_ABPS_CHANNEL,   /* SDD0_IN = 15 */

+

+    NON_ABPS_CHANNEL,   /* ADC1_1P5V = 16 */

+    2u,                 /* ABPS4 = 17 */

+    2u,                 /* ABPS5 = 18 */

+    NON_ABPS_CHANNEL,   /* CM2 = 19 */

+    NON_ABPS_CHANNEL,   /* TM2 = 20 */

+    3u,                 /* ABPS6 = 21 */

+    3u,                 /* ABPS7 = 22 */

+    NON_ABPS_CHANNEL,   /* CM3 = 23 */

+    NON_ABPS_CHANNEL,   /* TM3 = 24 */

+    NON_ABPS_CHANNEL,   /* ADC4 = 25 */

+    NON_ABPS_CHANNEL,   /* ADC5 = 26 */

+    NON_ABPS_CHANNEL,   /* ADC6 = 27 */

+    NON_ABPS_CHANNEL,   /* ADC7 = 28 */

+    INVALID_CHANNEL,

+    INVALID_CHANNEL,

+    NON_ABPS_CHANNEL,   /* SDD1_IN = 31 */

+

+    NON_ABPS_CHANNEL,   /* ADC2_1P5V = 32 */

+    4u,                 /* ABPS8 = 33 */

+    4u,                 /* ABPS9 = 34 */

+    NON_ABPS_CHANNEL,   /* CM4 = 35 */

+    NON_ABPS_CHANNEL,   /* TM4 = 36 */

+    5u,                 /* ABPS10 = 37 */

+    5u,                 /* ABPS11 = 38 */

+    NON_ABPS_CHANNEL,   /* CM5 = 39 */

+    NON_ABPS_CHANNEL,   /* TM5 = 40 */

+    NON_ABPS_CHANNEL,   /* ADC8 = 41 */

+    NON_ABPS_CHANNEL,   /* ADC9 = 42 */

+    NON_ABPS_CHANNEL,   /* ADC10 = 43 */

+    NON_ABPS_CHANNEL,   /* ADC11 = 44 */

+    INVALID_CHANNEL,

+    INVALID_CHANNEL,

+    NON_ABPS_CHANNEL    /* SDD2_IN = 47 */

+};

+

+static const uint8_t abps_idx_lut[] =

+{

+    NON_ABPS_CHANNEL,   /* ADC0_1P5V = 0 */

+    0u,                 /* ABPS0 = 1 */

+    1u,                 /* ABPS1 = 2 */

+    NON_ABPS_CHANNEL,   /* CM0 = 3 */

+    NON_ABPS_CHANNEL,   /* TM0 = 4 */

+    2u,                 /* ABPS2 = 5 */

+    3u,                 /* ABPS3 = 6 */

+    NON_ABPS_CHANNEL,   /* CM1 = 7 */

+    NON_ABPS_CHANNEL,   /* TM1 = 8 */

+    NON_ABPS_CHANNEL,   /* ADC0 = 9 */

+    NON_ABPS_CHANNEL,   /* ADC1 = 10 */

+    NON_ABPS_CHANNEL,   /* ADC2 = 11 */

+    NON_ABPS_CHANNEL,   /* ADC3 = 12 */

+    INVALID_CHANNEL,

+    INVALID_CHANNEL,

+    NON_ABPS_CHANNEL,   /* SDD0_IN = 15 */

+

+    NON_ABPS_CHANNEL,   /* ADC1_1P5V = 16 */

+    4u,                 /* ABPS4 = 17 */

+    5u,                 /* ABPS5 = 18 */

+    NON_ABPS_CHANNEL,   /* CM2 = 19 */

+    NON_ABPS_CHANNEL,   /* TM2 = 20 */

+    6u,                 /* ABPS6 = 21 */

+    7u,                 /* ABPS7 = 22 */

+    NON_ABPS_CHANNEL,   /* CM3 = 23 */

+    NON_ABPS_CHANNEL,   /* TM3 = 24 */

+    NON_ABPS_CHANNEL,   /* ADC4 = 25 */

+    NON_ABPS_CHANNEL,   /* ADC5 = 26 */

+    NON_ABPS_CHANNEL,   /* ADC6 = 27 */

+    NON_ABPS_CHANNEL,   /* ADC7 = 28 */

+    INVALID_CHANNEL,

+    INVALID_CHANNEL,

+    NON_ABPS_CHANNEL,   /* SDD1_IN = 31 */

+

+    NON_ABPS_CHANNEL,   /* ADC2_1P5V = 32 */

+    8u,                 /* ABPS8 = 33 */

+    9u,                 /* ABPS9 = 34 */

+    NON_ABPS_CHANNEL,   /* CM4 = 35 */

+    NON_ABPS_CHANNEL,   /* TM4 = 36 */

+    10u,                 /* ABPS10 = 37 */

+    11u,                 /* ABPS11 = 38 */

+    NON_ABPS_CHANNEL,   /* CM5 = 39 */

+    NON_ABPS_CHANNEL,   /* TM5 = 40 */

+    NON_ABPS_CHANNEL,   /* ADC8 = 41 */

+    NON_ABPS_CHANNEL,   /* ADC9 = 42 */

+    NON_ABPS_CHANNEL,   /* ADC10 = 43 */

+    NON_ABPS_CHANNEL,   /* ADC11 = 44 */

+    INVALID_CHANNEL,

+    INVALID_CHANNEL,

+    NON_ABPS_CHANNEL    /* SDD2_IN = 47 */

+};

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+static const int8_t apbs_gain_lut[] =

+{

+    12,

+    8,

+    4,

+    2

+};

+

+static const int16_t apbs_range[] =

+{

+    15360,

+    10240,

+    5120,

+    2560

+};

+

+static uint8_t g_gdec_lut[MAX_NB_OF_APBS];

+static channel_type_t channel_type_lut_h[ACE_NB_OF_INPUT_CHANNELS];

+

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+channel_type_t

+ACE_get_channel_type

+(

+    ace_channel_handle_t    channel_handle

+)

+{

+    channel_type_t channel_type = VOLTAGE;

+    

+    ASSERT(channel_handle < ACE_NB_OF_INPUT_CHANNELS);

+    

+    if((int32_t)channel_handle < ACE_NB_OF_INPUT_CHANNELS)

+    {

+        channel_type = channel_type_lut_h[channel_handle];

+    }

+    else

+    {

+        channel_type = VOLTAGE;

+    }

+    

+    return channel_type;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+uint32_t ACE_convert_adc_input_to_mV

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                sample_value

+)

+{

+    uint32_t voltage;

+    adc_channel_id_t channel_id;

+    uint8_t adc_id;

+    

+    channel_id = g_ace_channel_desc_table[channel_handle].signal_id;

+    adc_id = (uint8_t)channel_id >> 4u;

+    voltage = ( g_ace_adc_config[adc_id].va_ref * (uint32_t)sample_value ) / g_ace_adc_config[adc_id].adc_resolution;

+    

+    return voltage;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#define PPE_SAMPLES_RESOLUTION    4095u

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ace_init_convert(void)

+{

+    uint8_t abps_idx;

+    int32_t channel;

+    uint32_t saved_pc2_ctrl;

+    

+    /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */

+    saved_pc2_ctrl = ACE->PC2_CTRL;

+    ACE->PC2_CTRL = 0u;

+    

+    /* Populate the g_gdec_lut look-up table. */

+    for(abps_idx = 0u; abps_idx < MAX_NB_OF_APBS; ++abps_idx)

+    {

+        uint8_t quad_id;

+        uint8_t acb_config_byte;

+        uint32_t channel_is_abps2;

+        

+        quad_id = abps_idx / 2u;

+        acb_config_byte = ACE->ACB_DATA[quad_id].b8;

+        channel_is_abps2 = abps_idx & 0x01uL;

+        if(channel_is_abps2)

+        {

+            /* ABPS2 */

+            g_gdec_lut[abps_idx] = (acb_config_byte >> 5u) & 0x03u;

+        }

+        else

+        {

+            /* ABPS1 */

+            g_gdec_lut[abps_idx] = (acb_config_byte >> 1u) & 0x03u;

+        }

+    }

+    

+    /* Populate the channel_type_lut_h look-up table. */

+    for(channel = 0; channel < ACE_NB_OF_INPUT_CHANNELS; ++channel)

+    {

+        uint8_t quad_id;

+        uint8_t acb_config_byte;

+        adc_channel_id_t channel_id;

+        channel_type_t channel_type;

+    

+        channel_id = g_ace_channel_desc_table[channel].signal_id;

+        quad_id = channel_quad_lut[channel_id];

+        

+        switch (channel_type_lut[channel_id])

+        {

+            case VOLTAGE_CHANNEL:

+                channel_type = VOLTAGE;

+                break;

+                

+            case CURRENT_CHANNEL:

+                ASSERT( quad_id != 0xFFu );

+                acb_config_byte = ACE->ACB_DATA[quad_id].b9;

+                if ( acb_config_byte & 0x01u )

+                {

+                    channel_type = VOLTAGE;

+                }

+                else

+                {

+                    channel_type = CURRENT;

+                }

+                break;

+            

+            case TEMPERATURE_CHANNEL:

+                ASSERT( quad_id != 0xFFu );

+                acb_config_byte = ACE->ACB_DATA[quad_id].b10;

+                if ( acb_config_byte & 0x01u )

+                {

+                    channel_type = VOLTAGE;

+                }

+                else

+                {

+                    channel_type = TEMPERATURE;

+                }

+                break;

+                

+            default:

+                ASSERT(0);

+                channel_type = VOLTAGE;

+                break;

+        }

+        

+        channel_type_lut_h[channel] = channel_type;

+    }

+    

+    /* Restore SSE PC2 operations. */

+    ACE->PC2_CTRL = saved_pc2_ctrl;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+int32_t ACE_convert_to_mV

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                sample_value

+)

+{

+    uint32_t adc_voltage;

+    int32_t voltage;

+    adc_channel_id_t channel_id;

+    uint8_t adc_id;

+    uint8_t apbs_idx;

+    

+    channel_id = g_ace_channel_desc_table[channel_handle].signal_id;

+    adc_id = (uint8_t)channel_id >> 4u;

+    adc_voltage = ( g_ace_adc_config[adc_id].va_ref * (uint32_t)sample_value ) / PPE_SAMPLES_RESOLUTION;

+    voltage = (int32_t)adc_voltage;

+

+    apbs_idx = abps_idx_lut[channel_id];

+    if ( abps_channel_lut[channel_id] != NON_ABPS_CHANNEL )

+    {

+        uint8_t gdec;

+        gdec = g_gdec_lut[apbs_idx];

+        voltage = (voltage * apbs_gain_lut[gdec]) - apbs_range[gdec];

+    }

+    return voltage;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+uint32_t ACE_convert_to_mA

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                sample_value

+)

+{

+    uint32_t current = 0u;

+    

+    ASSERT(channel_handle < ACE_NB_OF_INPUT_CHANNELS);

+    

+    if((int32_t)channel_handle < ACE_NB_OF_INPUT_CHANNELS)

+    {

+        adc_channel_id_t channel_id;

+        uint8_t current_monitor_idx;

+        

+        channel_id = g_ace_channel_desc_table[channel_handle].signal_id;

+        ASSERT(channel_id < sizeof(channel_type_lut));

+        if(CURRENT_CHANNEL == channel_type_lut[channel_id])

+        {

+            uint32_t resistor;

+            uint32_t voltage;

+            

+            /* Compute index into g_ace_current_resistors[] from the current

+             * channel number. This uses bit 2, 4 and 5 of the channel number

+             * to derive the index as follows:

+             *  channel name : channel number : index

+             *       CM0     :       0x03     :   0

+             *       CM1     :       0x07     :   1

+             *       CM2     :       0x13     :   2

+             *       CM3     :       0x17     :   3

+             *       CM4     :       0x23     :   4

+             *       CM5     :       0x27     :   5

+             */

+            current_monitor_idx

+                = (((uint8_t)channel_id & 0x04u) >> 2u) + (((uint8_t)channel_id & 0x30u) >> 3u);

+            

+            if(current_monitor_idx < (uint8_t)ACE_NB_OF_CURRENT_MONITORS)

+            {

+                /* Retrieve the current sensing external resistor value from 

+                 * the ACE configuration data generated by the ACE configurator. */

+                resistor = g_ace_current_resistors[current_monitor_idx];

+                

+                /* Compute mA current value taking into account the amplication

+                 * factor of 50 used within the current monitor hardware. */

+                voltage = ACE_convert_adc_input_to_mV(channel_handle, sample_value);

+                current = (voltage * (1000u / 50u)) / resistor;

+;

+            }

+        }

+    }

+    

+    return current;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+uint32_t ACE_convert_to_Kelvin

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                sample_value

+)

+{

+    uint32_t temperature;

+    uint32_t voltage;

+    

+    voltage = ACE_convert_adc_input_to_mV( channel_handle, sample_value );

+    

+    /* Tk = (V * 10^3) / 2.5  */

+    temperature = (voltage * 10u) / 25u;

+    

+    return temperature;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+int32_t ACE_convert_to_Celsius

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                sample_value

+)

+{

+    int32_t temperature;

+    int32_t voltage;

+    

+    voltage = (int32_t)ACE_convert_adc_input_to_mV( channel_handle, sample_value );

+    

+    /* Tk = (V * 10^3) / 2.5  */

+    /* Tc = Tk - 273.15 */

+    temperature = (voltage * 4) - 2731;

+    

+    return temperature;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+int32_t ACE_convert_to_Fahrenheit

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                sample_value

+)

+{

+    int32_t temperature;

+    

+    temperature = (int32_t)ACE_convert_to_Kelvin( channel_handle, sample_value );

+    

+    /* F = (K * 9/5) - 459.67 */

+    temperature = ((temperature * 9) / 5) - 459;

+    

+    return temperature;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+const uint8_t * ACE_get_channel_name

+(

+    ace_channel_handle_t    channel_handle

+)

+{

+    const uint8_t * p_channel_name = 0;

+    

+    if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES)

+    {

+        p_channel_name = g_ace_channel_desc_table[channel_handle].p_sz_channel_name;

+    }

+    

+    return p_channel_name;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+uint16_t ACE_convert_mV_to_adc_value

+(

+    ace_channel_handle_t    channel_handle,

+    uint32_t                voltage

+)

+{

+    uint16_t sample_value;

+    adc_channel_id_t channel_id;

+    uint8_t adc_id;

+    

+    channel_id = g_ace_channel_desc_table[channel_handle].signal_id;

+    adc_id = (uint8_t)channel_id >> 4u;

+    

+    if (voltage > g_ace_adc_config[adc_id].va_ref)

+    {

+        sample_value = g_ace_adc_config[adc_id].adc_resolution - 1u;

+    }

+    else

+    {

+        sample_value = (uint16_t)((voltage * (g_ace_adc_config[adc_id].adc_resolution - 1)) / g_ace_adc_config[adc_id].va_ref);

+    }

+    

+    return sample_value;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+static uint16_t convert_mV_to_ppe_value

+(

+    ace_channel_handle_t    channel_handle,

+    uint32_t                voltage

+)

+{

+    uint16_t sample_value;

+    adc_channel_id_t channel_id;

+    uint8_t adc_id;

+    

+    channel_id = g_ace_channel_desc_table[channel_handle].signal_id;

+    adc_id = (uint8_t)channel_id >> 4u;

+    

+    if (voltage > g_ace_adc_config[adc_id].va_ref)

+    {

+        sample_value = PPE_SAMPLES_RESOLUTION;

+    }

+    else

+    {

+        sample_value = (uint16_t)((voltage * PPE_SAMPLES_RESOLUTION) / g_ace_adc_config[adc_id].va_ref);

+    }

+    

+    return sample_value;

+}

+

+#define MAX_PPE_SAMPLE_VALUE    0x0FFFu

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+uint16_t ACE_convert_from_mV

+(

+    ace_channel_handle_t    channel_handle,

+    int32_t                 voltage

+)

+{

+    uint16_t sample_value;

+    adc_channel_id_t channel_id;

+    uint8_t adc_id;

+    uint32_t adc_voltage;

+    

+    channel_id = g_ace_channel_desc_table[channel_handle].signal_id;

+    adc_id = (uint8_t)channel_id >> 4u;

+    

+    if ( abps_channel_lut[channel_id] == NON_ABPS_CHANNEL )

+    {

+        if (voltage > 0)

+        {

+            adc_voltage = (uint32_t)voltage;

+        }

+        else

+        {

+            adc_voltage = 0u;

+        }

+    }

+    else

+    {

+        uint8_t apbs_idx;

+        uint8_t gdec;

+        

+        apbs_idx = abps_idx_lut[channel_id];

+        gdec = g_gdec_lut[apbs_idx];

+        voltage = voltage + apbs_range[gdec];

+        if (voltage > 0)

+        {

+	        adc_voltage = (uint32_t)voltage;

+	        adc_voltage = adc_voltage / (uint8_t)apbs_gain_lut[gdec];

+        }

+        else

+        {

+        	adc_voltage = 0;

+        }

+    }

+    

+    sample_value = (uint16_t)((adc_voltage * PPE_SAMPLES_RESOLUTION) / g_ace_adc_config[adc_id].va_ref);

+    

+    if (sample_value > MAX_PPE_SAMPLE_VALUE)

+    {

+        sample_value = MAX_PPE_SAMPLE_VALUE;

+    }

+    return sample_value;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+uint16_t ACE_convert_from_mA

+(

+    ace_channel_handle_t    channel_handle,

+    uint32_t                current

+)

+{

+    uint16_t sample_value;

+    uint32_t voltage;

+    uint32_t resistor = 1u;

+    

+    voltage = current * 50u * resistor;

+    sample_value = convert_mV_to_ppe_value( channel_handle, voltage );

+    

+    if (sample_value > MAX_PPE_SAMPLE_VALUE)

+    {

+        sample_value = MAX_PPE_SAMPLE_VALUE;

+    }

+    return sample_value;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+uint16_t ACE_convert_from_Kelvin

+(

+    ace_channel_handle_t    channel_handle,

+    uint32_t                temperature

+)

+{

+    uint16_t sample_value;

+    uint32_t voltage;

+    

+    voltage = (temperature * 25u) / 10u;

+    sample_value = convert_mV_to_ppe_value( channel_handle, voltage );

+    

+    if (sample_value > MAX_PPE_SAMPLE_VALUE)

+    {

+        sample_value = MAX_PPE_SAMPLE_VALUE;

+    }

+    return sample_value;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+uint16_t ACE_convert_from_Celsius

+(

+    ace_channel_handle_t    channel_handle,

+    int32_t                 temperature

+)

+{

+    uint16_t sample_value;

+    uint32_t voltage;

+    

+    temperature = temperature + 2731;

+    voltage = (uint32_t)temperature / 4u;

+    sample_value = convert_mV_to_ppe_value( channel_handle, voltage );

+    

+    if (sample_value > MAX_PPE_SAMPLE_VALUE)

+    {

+        sample_value = MAX_PPE_SAMPLE_VALUE;

+    }

+    return sample_value;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+uint16_t ACE_convert_from_Fahrenheit

+(

+    ace_channel_handle_t    channel_handle,

+    int32_t                 temperature

+)

+{

+    uint16_t sample_value;

+    uint32_t kelvin;

+    

+    temperature = temperature + 459;

+    kelvin = (uint32_t)temperature;

+    kelvin = (kelvin * 5u) / 9u;

+    

+    sample_value = ACE_convert_from_Kelvin( channel_handle, kelvin );

+    

+    if (sample_value > MAX_PPE_SAMPLE_VALUE)

+    {

+        sample_value = MAX_PPE_SAMPLE_VALUE;

+    }

+    return sample_value;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+uint16_t ACE_translate_pdma_value

+(

+    uint32_t            pdma_value,

+    adc_channel_id_t *  channel_id

+)

+{

+    uint16_t ppe_value;

+      

+    ppe_value = (pdma_value >> 8u) & 0xFFFFu;

+    if ( channel_id != 0 )

+    {

+        *channel_id = (adc_channel_id_t)((pdma_value >> 24u) & 0xFFu);

+    }

+    

+    return ppe_value;

+}

+

+#ifdef __cplusplus

+}

+#endif

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_flags.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_flags.c
new file mode 100644
index 0000000..926a80d
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_flags.c
@@ -0,0 +1,1678 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ * SVN $Revision: 2840 $

+ * SVN $Date: 2010-07-20 17:00:32 +0100 (Tue, 20 Jul 2010) $

+ */

+#include "mss_ace.h"

+#include "mss_ace_configurator.h"

+#include "../../CMSIS/a2fxxxm3.h"

+#include "../../CMSIS/mss_assert.h"

+#include "../../drivers_config/mss_ace/ace_handles.h"

+#include "../../drivers_config/mss_ace/ace_config.h"

+#include <string.h>

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+#define MAX_FULL_FLAG_NAME_LENGTH   (MAX_CHANNEL_NAME_LENGTH + MAX_FLAG_NAME_LENGTH + 1)

+

+/*-------------------------------------------------------------------------*//**

+ * Number of flag types supported.

+ * the supported flag types are:

+ *  - BASIC_THRESHOLD_OVER

+ *  - BASIC_THRESHOLD_UNDER

+ *  - STATE_FILTERED_OVER

+ *  - STATE_FILTERED_UNDER

+ *  - DUAL_HYSTERESIS_OVER

+ *  - DUAL_HYSTERESIS_UNDER

+ *  - IPMI_HYSTERESIS_OVER

+ *  - IPMI_HYSTERESIS_UNDER

+ */

+#define NB_OF_FLAG_TYPES    8

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#define THRESHOLD_FLAG0     0u

+#define THRESHOLD_FLAG1     1u

+#define THRESHOLD_FLAG2     2u

+#define THRESHOLD_FLAG3     3u

+#define THRESHOLD_FLAG4     4u

+#define THRESHOLD_FLAG5     5u

+#define THRESHOLD_FLAG6     6u

+#define THRESHOLD_FLAG7     7u

+#define THRESHOLD_FLAG8     8u

+#define THRESHOLD_FLAG9     9u

+#define THRESHOLD_FLAG10    10u

+#define THRESHOLD_FLAG11    11u

+#define THRESHOLD_FLAG12    12u

+#define THRESHOLD_FLAG13    13u

+#define THRESHOLD_FLAG14    14u

+#define THRESHOLD_FLAG15    15u

+#define THRESHOLD_FLAG16    16u

+#define THRESHOLD_FLAG17    17u

+#define THRESHOLD_FLAG18    18u

+#define THRESHOLD_FLAG19    19u

+#define THRESHOLD_FLAG20    20u

+#define THRESHOLD_FLAG21    21u

+#define THRESHOLD_FLAG22    22u

+#define THRESHOLD_FLAG23    23u

+#define THRESHOLD_FLAG24    24u

+#define THRESHOLD_FLAG25    25u

+#define THRESHOLD_FLAG26    26u

+#define THRESHOLD_FLAG27    27u

+#define THRESHOLD_FLAG28    28u

+#define THRESHOLD_FLAG29    29u

+#define THRESHOLD_FLAG30    30u

+#define THRESHOLD_FLAG31    31u

+#define NB_OF_THRESHOLD_IRQ 32u

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ace_init_flags( void );

+

+/*-------------------------------------------------------------------------*//**

+ * Flag interrupots routines function prototypes

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag0_IRQHandler( void );

+#else

+void ACE_PPE_Flag0_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag1_IRQHandler( void );

+#else

+void ACE_PPE_Flag1_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag2_IRQHandler( void );

+#else

+void ACE_PPE_Flag2_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag3_IRQHandler( void );

+#else

+void ACE_PPE_Flag3_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag4_IRQHandler( void );

+#else

+void ACE_PPE_Flag4_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag5_IRQHandler( void );

+#else

+void ACE_PPE_Flag5_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag6_IRQHandler( void );

+#else

+void ACE_PPE_Flag6_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag7_IRQHandler( void );

+#else

+void ACE_PPE_Flag7_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag8_IRQHandler( void );

+#else

+void ACE_PPE_Flag8_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag9_IRQHandler( void );

+#else

+void ACE_PPE_Flag9_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag10_IRQHandler( void );

+#else

+void ACE_PPE_Flag10_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag11_IRQHandler( void );

+#else

+void ACE_PPE_Flag11_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag12_IRQHandler( void );

+#else

+void ACE_PPE_Flag12_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag13_IRQHandler( void );

+#else

+void ACE_PPE_Flag13_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag14_IRQHandler( void );

+#else

+void ACE_PPE_Flag14_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag15_IRQHandler( void );

+#else

+void ACE_PPE_Flag15_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag16_IRQHandler( void );

+#else

+void ACE_PPE_Flag16_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag17_IRQHandler( void );

+#else

+void ACE_PPE_Flag17_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag18_IRQHandler( void );

+#else

+void ACE_PPE_Flag18_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag19_IRQHandler( void );

+#else

+void ACE_PPE_Flag19_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag20_IRQHandler( void );

+#else

+void ACE_PPE_Flag20_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag21_IRQHandler( void );

+#else

+void ACE_PPE_Flag21_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag22_IRQHandler( void );

+#else

+void ACE_PPE_Flag22_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag23_IRQHandler( void );

+#else

+void ACE_PPE_Flag23_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag24_IRQHandler( void );

+#else

+void ACE_PPE_Flag24_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag25_IRQHandler( void );

+#else

+void ACE_PPE_Flag25_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag26_IRQHandler( void );

+#else

+void ACE_PPE_Flag26_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag27_IRQHandler( void );

+#else

+void ACE_PPE_Flag27_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag28_IRQHandler( void );

+#else

+void ACE_PPE_Flag28_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag29_IRQHandler( void );

+#else

+void ACE_PPE_Flag29_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag30_IRQHandler( void );

+#else

+void ACE_PPE_Flag30_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag31_IRQHandler( void );

+#else

+void ACE_PPE_Flag31_IRQHandler( void );

+#endif

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+extern ppe_flag_desc_t g_ppe_flags_desc_table[ACE_NB_OF_PPE_FLAGS];

+#endif

+

+extern ace_channel_desc_t g_ace_channel_desc_table[ACE_NB_OF_INPUT_CHANNELS];

+

+extern ace_adc_config_t g_ace_adc_config[ACE_NB_OF_ADC];

+

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+/*-------------------------------------------------------------------------*//**

+  Lookup table indexed on flag_id_t of the index of the flag's descriptor index

+  in the flag descriptors table g_ppe_flags_desc_table[]

+ */

+static ace_flag_handle_t g_ppe_flag_handles_lut[NB_OF_PPE_FLAGS];

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+static flag_isr_t g_ppe_flags_isr_lut[NB_OF_PPE_FLAGS];

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+static global_flag_isr_t g_ppe_global_flags_isr;

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+static channel_flag_isr_t g_ppe_channel_flags_isr_lut[ACE_NB_OF_INPUT_CHANNELS];

+#endif

+

+/*-------------------------------------------------------------------------*//**

+  Intialise the ACE driver's internal data structures used by flag control

+  functions.

+ */

+void ace_init_flags( void )

+{

+    /* Ensure the generated ACE configuration files are consistent. */

+    ASSERT(NB_OF_ACE_FLAG_HANDLES == ACE_NB_OF_PPE_FLAGS);

+    

+#if (ACE_NB_OF_PPE_FLAGS > 0)    

+    {

+        uint8_t flag_idx;

+        uint8_t channel_idx;

+        

+        for ( flag_idx = 0u; flag_idx < (uint8_t)NB_OF_PPE_FLAGS; ++flag_idx )

+        {

+            g_ppe_flags_isr_lut[flag_idx] = 0;

+            g_ppe_flag_handles_lut[flag_idx] = INVALID_FLAG_HANDLE;

+        }

+    

+        for ( flag_idx = 0u; flag_idx < (uint8_t)ACE_NB_OF_PPE_FLAGS; ++flag_idx )

+        {

+            ASSERT( g_ppe_flags_desc_table[flag_idx].flag_id < NB_OF_PPE_FLAGS );

+            g_ppe_flag_handles_lut[g_ppe_flags_desc_table[flag_idx].flag_id] = (ace_flag_handle_t)flag_idx;

+        }

+        

+        for ( channel_idx = 0u; channel_idx < (uint8_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx )

+        {

+            g_ppe_channel_flags_isr_lut[channel_idx] = 0;

+        }

+        

+        g_ppe_global_flags_isr = 0u;

+    }

+#endif

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+uint32_t ACE_is_hysteresis_flag( ace_flag_handle_t   flag_handle )

+{

+    uint32_t hysteresis = 0u;

+    

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES );

+    

+    if ( g_ppe_flags_desc_table[flag_handle].flag_type >= DUAL_HYSTERESIS_OVER )

+    {

+        hysteresis = 1u;

+    }

+#endif

+    return hysteresis;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+uint32_t ACE_is_under_flag

+(

+    ace_flag_handle_t   flag_handle

+)

+{

+    uint32_t is_under = 0;

+    

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    const uint32_t flag_type_lut[NB_OF_FLAG_TYPES] =

+    {

+        0,  /* BASIC_THRESHOLD_OVER */

+        1,  /* BASIC_THRESHOLD_UNDER */

+        0,  /* STATE_FILTERED_OVER */

+        1,  /* STATE_FILTERED_UNDER */

+        0,  /* DUAL_HYSTERESIS_OVER */

+        1,  /* DUAL_HYSTERESIS_UNDER */

+        0,  /* IPMI_HYSTERESIS_OVER */

+        1,  /* IPMI_HYSTERESIS_UNDER */

+    };

+    

+    ASSERT(flag_handle < ACE_NB_OF_PPE_FLAGS);

+    if (flag_handle < ACE_NB_OF_PPE_FLAGS)

+    {

+        uint8_t flag_type;

+        flag_type = g_ppe_flags_desc_table[flag_handle].flag_type;

+        ASSERT(flag_type < NB_OF_FLAG_TYPES);

+        if (flag_type < NB_OF_FLAG_TYPES)

+        {

+            is_under = flag_type_lut[flag_type];

+        }

+    }

+#endif

+    return is_under;

+}

+

+/*-------------------------------------------------------------------------*//**

+  Mask of the threshold value bits within a PPE RAM meory location holding the

+  threshold value for a flag.

+ */

+#define PPE_RAM_THRESHOLD_MASK      0x0000FFFFuL

+

+/*-------------------------------------------------------------------------*//**

+ * TODO: handle IPMI hysteresis flags

+ */

+void ACE_set_flag_threshold

+(

+    ace_flag_handle_t   flag_handle,

+    uint16_t            new_threshold

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    uint16_t ppe_offset;

+    

+    ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES );

+    

+    if ( flag_handle < NB_OF_ACE_FLAG_HANDLES )

+    {

+    

+        ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset;

+        

+        if ( ACE_is_hysteresis_flag( flag_handle ) == 0u )

+        {

+            ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & (uint32_t)~PPE_RAM_THRESHOLD_MASK) + new_threshold;

+        }

+        else

+        {

+            uint16_t high_threshold;

+            uint16_t low_threshold;

+            ace_channel_handle_t channel_handle;

+            uint16_t hysteresis;

+            uint32_t adc_id;

+            uint16_t adc_resolution;

+            

+            high_threshold = (uint16_t)(ACE->PPE_RAM_DATA[ppe_offset] & PPE_RAM_THRESHOLD_MASK);

+            low_threshold = (uint16_t)(ACE->PPE_RAM_DATA[ppe_offset + 1u] & PPE_RAM_THRESHOLD_MASK);

+            ASSERT(high_threshold > low_threshold);

+            hysteresis = (uint16_t)(high_threshold - low_threshold) / 2u;

+            

+            channel_handle = g_ppe_flags_desc_table[flag_handle].channel_handle;

+            adc_id = (uint32_t)(g_ace_channel_desc_table[channel_handle].signal_id) >> 4u;

+            ASSERT( adc_id < (uint32_t)ACE_NB_OF_ADC );

+            

+            if ( adc_id < (uint32_t)ACE_NB_OF_ADC )

+            {

+                adc_resolution = g_ace_adc_config[adc_id].adc_resolution - 1u;

+                

+                high_threshold = new_threshold + hysteresis;

+                if ( high_threshold > adc_resolution )

+                {

+                    high_threshold = adc_resolution;

+                }

+                

+                if ( hysteresis > new_threshold )

+                {

+                    low_threshold = 1u;

+                }

+                else

+                {

+                    low_threshold = new_threshold - hysteresis;

+                }

+                

+                ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & ~PPE_RAM_THRESHOLD_MASK) + high_threshold;

+                ACE->PPE_RAM_DATA[ppe_offset + 1u] = (ACE->PPE_RAM_DATA[ppe_offset + 1u] & (uint32_t)~PPE_RAM_THRESHOLD_MASK) + low_threshold;

+            }

+        }

+    }

+#endif

+}

+

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#define FLAG_OVER_UNDER_MASK    0x01u

+#define FLAG_OVER               0x00u

+#define FLAF_UNDER              0x01

+

+void ACE_set_flag_assertion

+(

+    ace_flag_handle_t   flag_handle,

+    uint16_t            assertion_value

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    uint16_t ppe_offset;

+    

+    ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES );

+    

+    if ( flag_handle < NB_OF_ACE_FLAG_HANDLES )

+    {

+        if (ACE_is_hysteresis_flag(flag_handle))

+        {

+            uint8_t flag_direction;

+            flag_direction = g_ppe_flags_desc_table[flag_handle].flag_type & FLAG_OVER_UNDER_MASK;

+            

+            if ( FLAG_OVER == flag_direction )

+            {

+                ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset;

+            }

+            else

+            {

+                ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset + 1u;

+            }

+        }

+        else

+        {

+            ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset;

+        }

+        ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & ~PPE_RAM_THRESHOLD_MASK) + assertion_value;

+    }

+#endif

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_set_flag_deassertion

+(

+    ace_flag_handle_t   flag_handle,

+    uint16_t            assertion_value

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    uint16_t ppe_offset;

+    

+    ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES );

+    ASSERT(ACE_is_hysteresis_flag(flag_handle));

+    

+    if ((flag_handle < NB_OF_ACE_FLAG_HANDLES)  && (ACE_is_hysteresis_flag(flag_handle)))

+    {

+        uint8_t flag_direction;

+        flag_direction = g_ppe_flags_desc_table[flag_handle].flag_type & FLAG_OVER_UNDER_MASK;

+        

+        if ( FLAG_OVER == flag_direction )

+        {

+            ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset + 1u;

+        }

+        else

+        {

+            ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset;

+        }

+        

+        ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & ~PPE_RAM_THRESHOLD_MASK) + assertion_value;

+    }

+#endif

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void

+ACE_set_flag_hysteresis

+(

+    ace_flag_handle_t   flag_handle,

+    uint16_t            adc_hysteresis

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    uint16_t ppe_offset;

+    uint32_t high_threshold;

+    uint32_t low_threshold;

+    uint32_t nominal_threshold;

+    uint16_t adc_resolution;

+    uint32_t adc_id;

+    

+    ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES );

+    ASSERT(ACE_is_hysteresis_flag(flag_handle));

+    

+    if ( ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) && ( ACE_is_hysteresis_flag( flag_handle ) ) )

+    {

+        ace_channel_handle_t channel_handle;

+        

+        ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset;

+        

+        high_threshold = ACE->PPE_RAM_DATA[ppe_offset] & PPE_RAM_THRESHOLD_MASK;

+        low_threshold = ACE->PPE_RAM_DATA[ppe_offset + 1u] & PPE_RAM_THRESHOLD_MASK;

+        ASSERT(high_threshold > low_threshold);

+        nominal_threshold = (low_threshold + ((high_threshold - low_threshold) / 2u));

+        

+        channel_handle = g_ppe_flags_desc_table[flag_handle].channel_handle;

+        adc_id = (uint32_t)((uint32_t)g_ace_channel_desc_table[channel_handle].signal_id >> 4u);

+        ASSERT( adc_id < (uint32_t)ACE_NB_OF_ADC );

+        

+        if ( adc_id < (uint32_t)ACE_NB_OF_ADC )

+        {

+            adc_resolution = g_ace_adc_config[adc_id].adc_resolution;

+            

+            high_threshold = nominal_threshold + adc_hysteresis;

+            if ( high_threshold > adc_resolution )

+            {

+                high_threshold = (uint32_t)adc_resolution - 1u;

+            }

+            

+            if ( adc_hysteresis > nominal_threshold )

+            {

+                low_threshold = 1u;

+            }

+            else

+            {

+                low_threshold = nominal_threshold - adc_hysteresis;

+            }

+            

+            ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & ~PPE_RAM_THRESHOLD_MASK) + high_threshold;

+            ACE->PPE_RAM_DATA[ppe_offset + 1u] = (ACE->PPE_RAM_DATA[ppe_offset + 1u] & ~PPE_RAM_THRESHOLD_MASK) + low_threshold;

+        }

+    }

+#endif

+}

+

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void

+ACE_set_channel_hysteresis

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                adc_hysteresis

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    ace_flag_handle_t flag_handle;

+    

+    ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES );

+    

+    if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES )

+    {

+        uint16_t i;

+        

+        for( i = 0u; i < g_ace_channel_desc_table[channel_handle].nb_of_flags; ++i )

+        {

+            flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[i];

+            ACE_set_flag_hysteresis( flag_handle, adc_hysteresis );

+        }

+    }

+#endif

+}

+

+/*==============================================================================

+ *

+ */

+

+/*-------------------------------------------------------------------------*//**

+  Masking a flag_id with FLAG_BIT_OFFSET_MASK results in the offset of the 

+  flag bit within a PPE__FLAGSn register.

+ */

+#define FLAG_BIT_OFFSET_MASK       0x0000001FuL

+

+/*-------------------------------------------------------------------------*//**

+  Shifting right a flag_id by FLAG_PPE_REG_SHIFT results in identifying the

+  PPE_FLAGSn or PPE_SFFLAGS the flags belongs to.

+ */

+#define FLAG_PPE_REG_SHIFT          5u

+

+/*-------------------------------------------------------------------------*//**

+  There is a set of 5 PPE flag registers to control and report status of the PPE

+  flags resulting in the PPE flags being grouped into 5 separate flag groups at

+  the register level. Each register provides status or control for 32 flags.

+ */

+#define NB_OF_FLAG_GROUPS       5u

+#define NB_OF_FLAGS_PER_GROUP   32u

+

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+/*-------------------------------------------------------------------------*//**

+  Lookup table of the address PPE_FLAGSn registers for fast reading of PPE

+  status.

+ */

+static volatile uint32_t * const g_ppe_flags_regs_lut[NB_OF_FLAG_GROUPS] =

+{

+    &ACE->PPE_FLAGS0,

+    &ACE->PPE_FLAGS1,

+    &ACE->PPE_FLAGS2,

+    &ACE->PPE_FLAGS3,

+    &ACE->PPE_SFFLAGS

+};

+

+/*-------------------------------------------------------------------------*//**

+  Lookup table of the address of the PPE flags interrupt enable registers.

+ */

+static uint32_t volatile * const flags_irq_enable_regs_lut[NB_OF_FLAG_GROUPS] =

+{

+    &ACE->PPE_FLAGS0_IRQ_EN,

+    &ACE->PPE_FLAGS1_IRQ_EN,

+    &ACE->PPE_FLAGS2_IRQ_EN,

+    &ACE->PPE_FLAGS3_IRQ_EN,

+    &ACE->PPE_SFFLAGS_IRQ_EN

+};

+

+/*-------------------------------------------------------------------------*//**

+  Lookup table of the address of the PPE flags interrupt status registers.

+ */

+static uint32_t volatile const * const flags_irq_status_regs_lut[NB_OF_FLAG_GROUPS] =

+{

+    &ACE->PPE_FLAGS0_IRQ,

+    &ACE->PPE_FLAGS1_IRQ,

+    &ACE->PPE_FLAGS2_IRQ,

+    &ACE->PPE_FLAGS3_IRQ,

+    &ACE->PPE_SFFLAGS_IRQ

+};

+

+/*-------------------------------------------------------------------------*//**

+  Lookup table of the address of the PPE flags interrupt clearing registers.

+ */

+static uint32_t volatile * const flags_irq_clear_regs_lut[NB_OF_FLAG_GROUPS] =

+{

+    &ACE->PPE_FLAGS0_IRQ_CLR,

+    &ACE->PPE_FLAGS1_IRQ_CLR,

+    &ACE->PPE_FLAGS2_IRQ_CLR,

+    &ACE->PPE_FLAGS3_IRQ_CLR,

+    &ACE->PPE_SFFLAGS_IRQ_CLR

+};

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+static const IRQn_Type threshold_irqn_lut[NB_OF_THRESHOLD_IRQ] =

+{

+    ACE_PPE_Flag0_IRQn,

+    ACE_PPE_Flag1_IRQn,

+    ACE_PPE_Flag2_IRQn,

+    ACE_PPE_Flag3_IRQn,

+    ACE_PPE_Flag4_IRQn,

+    ACE_PPE_Flag5_IRQn,

+    ACE_PPE_Flag6_IRQn,

+    ACE_PPE_Flag7_IRQn,

+    ACE_PPE_Flag8_IRQn,

+    ACE_PPE_Flag9_IRQn,

+    ACE_PPE_Flag10_IRQn,

+    ACE_PPE_Flag11_IRQn,

+    ACE_PPE_Flag12_IRQn,

+    ACE_PPE_Flag13_IRQn,

+    ACE_PPE_Flag14_IRQn,

+    ACE_PPE_Flag15_IRQn,

+    ACE_PPE_Flag16_IRQn,

+    ACE_PPE_Flag17_IRQn,

+    ACE_PPE_Flag18_IRQn,

+    ACE_PPE_Flag19_IRQn,

+    ACE_PPE_Flag20_IRQn,

+    ACE_PPE_Flag21_IRQn,

+    ACE_PPE_Flag22_IRQn,

+    ACE_PPE_Flag23_IRQn,

+    ACE_PPE_Flag24_IRQn,

+    ACE_PPE_Flag25_IRQn,

+    ACE_PPE_Flag26_IRQn,

+    ACE_PPE_Flag27_IRQn,

+    ACE_PPE_Flag28_IRQn,

+    ACE_PPE_Flag29_IRQn,

+    ACE_PPE_Flag30_IRQn,

+    ACE_PPE_Flag31_IRQn

+};

+#endif

+

+/*-------------------------------------------------------------------------*//**

+ */

+ace_flag_handle_t

+ACE_get_flag_handle

+(

+    const uint8_t * p_sz_full_flag_name

+)

+{

+    ace_flag_handle_t flag_handle = INVALID_FLAG_HANDLE;

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    ace_flag_handle_t flag_idx;

+    

+    for ( flag_idx = (ace_flag_handle_t)0; flag_idx < NB_OF_ACE_FLAG_HANDLES; ++flag_idx )

+    {

+        if ( g_ppe_flags_desc_table[flag_idx].p_sz_flag_name != 0 )

+        {

+            int32_t diff;

+            diff = strncmp( (const char *)p_sz_full_flag_name, (const char *)g_ppe_flags_desc_table[flag_idx].p_sz_flag_name, (size_t)MAX_FULL_FLAG_NAME_LENGTH );

+            if ( 0 == diff )

+            {

+                /* flag name found. */

+                flag_handle = (ace_flag_handle_t)flag_idx;

+                break;

+            }

+        }

+    }

+#endif

+    return flag_handle;

+}

+

+/*-------------------------------------------------------------------------*//**

+ */

+int32_t

+ACE_get_flag_status

+(

+    ace_flag_handle_t   flag_handle

+)

+{

+    int32_t flag_state = UNKNOWN_FLAG;

+#if (ACE_NB_OF_PPE_FLAGS > 0)    

+    ppe_flag_id_t flag_id;

+    

+    ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES );

+    

+    if ( flag_handle < NB_OF_ACE_FLAG_HANDLES )

+    {

+        uint32_t flag_bit_offset;

+        uint32_t ppe_flag_group;

+        uint32_t flag_id_mask;

+        uint32_t flag_status;

+

+        flag_id = g_ppe_flags_desc_table[flag_handle].flag_id;

+        

+        if ( flag_id < NB_OF_PPE_FLAGS )

+        {

+            flag_bit_offset = ((uint32_t)flag_id & FLAG_BIT_OFFSET_MASK);

+            ppe_flag_group = ((uint32_t)flag_id >> FLAG_PPE_REG_SHIFT);

+            flag_id_mask = 1uL << flag_bit_offset;

+            flag_status = *(g_ppe_flags_regs_lut[ppe_flag_group]) & flag_id_mask;

+            if ( flag_status > 0u )

+            {

+                flag_state = FLAG_ASSERTED;

+            }

+            else

+            {

+                flag_state = FLAG_NOT_ASSERTED;

+            }

+        }

+

+    }

+#endif

+    return flag_state;

+}

+

+

+/*-------------------------------------------------------------------------*//**

+ */

+const uint8_t *

+ACE_get_flag_name

+(

+    ace_flag_handle_t flag_handle

+)

+{

+    const uint8_t * psz_flag_name = 0;

+#if (ACE_NB_OF_PPE_FLAGS > 0)    

+    ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES );

+    

+    if ( flag_handle < NB_OF_ACE_FLAG_HANDLES )

+    {

+        psz_flag_name = g_ppe_flags_desc_table[flag_handle].p_sz_flag_name;

+    }

+#endif

+    return psz_flag_name;

+}

+

+/*-------------------------------------------------------------------------*//**

+ */

+ace_channel_handle_t

+ACE_get_flag_channel

+(

+    ace_flag_handle_t flag_handle

+)

+{

+    ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE;

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES );

+    

+    if ( flag_handle < NB_OF_ACE_FLAG_HANDLES )

+    {

+        channel_handle = g_ppe_flags_desc_table[flag_handle].channel_handle;

+    }

+#endif

+    return channel_handle;

+}

+

+/*-------------------------------------------------------------------------*//**

+ */

+uint32_t

+ACE_get_channel_flag_count

+(

+    ace_channel_handle_t    channel_handle

+)

+{

+    uint32_t flag_count = 0;

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    ASSERT( channel_handle < ACE_NB_OF_INPUT_CHANNELS );

+    if (channel_handle < ACE_NB_OF_INPUT_CHANNELS)

+    {

+        flag_count = g_ace_channel_desc_table[channel_handle].nb_of_flags;

+    }

+#endif

+    return flag_count;

+}

+

+/*-------------------------------------------------------------------------*//**

+  

+ */

+ace_flag_handle_t

+ACE_get_channel_first_flag

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t *              iterator

+)

+{

+    ace_flag_handle_t flag_handle = INVALID_FLAG_HANDLE;

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES);

+    

+    *iterator = 0u;

+    

+    if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES)

+    {

+        if ( g_ace_channel_desc_table[channel_handle].nb_of_flags > 0u )

+        {

+            flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[*iterator];

+        }

+    }

+#endif    

+    return flag_handle;

+}

+

+/*-------------------------------------------------------------------------*//**

+  

+ */

+ace_flag_handle_t

+ACE_get_channel_next_flag

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t *              iterator

+)

+{

+    ace_flag_handle_t flag_handle = INVALID_FLAG_HANDLE;

+#if (ACE_NB_OF_PPE_FLAGS > 0)    

+    ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES);

+

+    if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES)

+    {

+        ++(*iterator);

+        

+        if ( *iterator >= g_ace_channel_desc_table[channel_handle].nb_of_flags )

+        {

+            *iterator = 0u;

+        }

+    

+        if ( g_ace_channel_desc_table[channel_handle].nb_of_flags > 0u )

+        {

+            flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[*iterator];

+        }

+    }

+#endif

+    return flag_handle;

+}

+

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_enable_channel_flags_irq

+(

+    ace_channel_handle_t channel_handle

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    uint32_t flag_idx;

+    ace_flag_handle_t flag_handle;

+    

+    ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES );

+    

+    if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES )

+    {

+        for ( flag_idx = 0u; flag_idx < g_ace_channel_desc_table[channel_handle].nb_of_flags; ++flag_idx )

+        {

+            flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[flag_idx];

+            ACE_enable_flag_irq( flag_handle );

+        }

+    }

+#endif

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_disable_channel_flags_irq

+(

+    ace_channel_handle_t channel_handle

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    uint32_t flag_idx;

+    ace_flag_handle_t flag_handle;

+    

+    ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES );

+    

+    if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES )

+    {

+        for ( flag_idx = 0u; flag_idx < g_ace_channel_desc_table[channel_handle].nb_of_flags; ++flag_idx )

+        {

+            flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[flag_idx];

+            ACE_disable_flag_irq( flag_handle );

+        }

+    }

+#endif

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_clear_channel_flags_irq

+(

+    ace_channel_handle_t channel_handle

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    uint32_t flag_idx;

+    ace_flag_handle_t flag_handle;

+    

+    ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES );

+    

+    if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES )

+    {

+        for ( flag_idx = 0u; flag_idx < g_ace_channel_desc_table[channel_handle].nb_of_flags; ++flag_idx )

+        {

+            flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[flag_idx];

+            ACE_clear_flag_irq( flag_handle );

+        }

+    }

+#endif

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_enable_flag_irq

+(

+    ace_flag_handle_t flag_handle

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES );

+    

+    if ( flag_handle < NB_OF_ACE_FLAG_HANDLES )

+    {

+        ppe_flag_id_t flag_id;

+        uint32_t flag_bit_offset;

+        uint32_t ppe_flag_group;

+        uint32_t flag_id_mask;

+        

+        flag_id = g_ppe_flags_desc_table[flag_handle].flag_id;

+        

+        ASSERT( flag_id < NB_OF_PPE_FLAGS );

+    

+        flag_bit_offset = ((uint32_t)flag_id & FLAG_BIT_OFFSET_MASK);

+        ppe_flag_group = ((uint32_t)flag_id >> FLAG_PPE_REG_SHIFT);

+        flag_id_mask = 1uL << flag_bit_offset;

+        

+        ASSERT( ppe_flag_group < NB_OF_FLAG_GROUPS );

+        

+        if ( ppe_flag_group < NB_OF_FLAG_GROUPS )

+        {

+            *(flags_irq_enable_regs_lut[ppe_flag_group]) |= flag_id_mask;

+        }

+        

+        NVIC_EnableIRQ( threshold_irqn_lut[flag_bit_offset] );

+    }

+#endif

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_disable_flag_irq

+(

+    ace_flag_handle_t flag_handle

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES );

+    

+    if ( flag_handle < NB_OF_ACE_FLAG_HANDLES )

+    {

+        ppe_flag_id_t flag_id;

+        uint32_t flag_bit_offset;

+        uint32_t ppe_flag_group;

+        uint32_t flag_id_mask;

+        

+        flag_id = g_ppe_flags_desc_table[flag_handle].flag_id;

+        

+        ASSERT( flag_id < NB_OF_PPE_FLAGS );

+    

+        flag_bit_offset = ((uint32_t)flag_id & FLAG_BIT_OFFSET_MASK);

+        ppe_flag_group = ((uint32_t)flag_id >> FLAG_PPE_REG_SHIFT);

+        flag_id_mask = 1uL << flag_bit_offset;

+        

+        ASSERT( ppe_flag_group < NB_OF_FLAG_GROUPS );

+        

+        if ( ppe_flag_group < NB_OF_FLAG_GROUPS )

+        {

+            *(flags_irq_enable_regs_lut[ppe_flag_group]) &= (uint32_t)~flag_id_mask;

+        }

+    }

+#endif

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_clear_flag_irq

+(

+    ace_flag_handle_t flag_handle

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES );

+    

+    if ( flag_handle < NB_OF_ACE_FLAG_HANDLES )

+    {

+        ppe_flag_id_t flag_id;

+        uint32_t flag_bit_offset;

+        uint32_t ppe_flag_group;

+        uint32_t flag_id_mask;

+        

+        flag_id = g_ppe_flags_desc_table[flag_handle].flag_id;

+        

+        ASSERT( flag_id < NB_OF_PPE_FLAGS );

+    

+        flag_bit_offset = ((uint32_t)flag_id & FLAG_BIT_OFFSET_MASK);

+        ppe_flag_group = ((uint32_t)flag_id >> FLAG_PPE_REG_SHIFT);

+        flag_id_mask = 1uL << flag_bit_offset;

+        

+        ASSERT( ppe_flag_group < NB_OF_FLAG_GROUPS );

+        

+        if ( ppe_flag_group < NB_OF_FLAG_GROUPS )

+        {

+            *(flags_irq_clear_regs_lut[ppe_flag_group]) |= flag_id_mask;

+        }

+    }

+#endif

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_register_flag_isr

+(

+    ace_flag_handle_t   flag_handle,

+    flag_isr_t          flag_isr

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    ppe_flag_id_t flag_id;

+    

+    ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES );

+    

+    if ( flag_handle < NB_OF_ACE_FLAG_HANDLES )

+    {

+        flag_id = g_ppe_flags_desc_table[flag_handle].flag_id;

+        

+        ASSERT( flag_id < NB_OF_PPE_FLAGS );

+        

+        if ( flag_id < NB_OF_PPE_FLAGS )

+        {

+            g_ppe_flags_isr_lut[flag_id] = flag_isr;

+        }

+    }

+#endif

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_register_channel_flags_isr

+(

+    ace_channel_handle_t    channel_handle,

+    channel_flag_isr_t      channel_flag_isr

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES );

+    

+    if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES )

+    {

+        g_ppe_channel_flags_isr_lut[channel_handle] = channel_flag_isr;

+    }

+#endif

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_register_global_flags_isr

+(

+    global_flag_isr_t  global_flag_isr

+)

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    g_ppe_global_flags_isr = global_flag_isr;

+#endif

+}

+

+

+/*==============================================================================

+ *

+ */

+ 

+/*-------------------------------------------------------------------------*//**

+ * Actual PPE flag interrupt service routines:

+ */

+

+static void process_flag_irq( uint8_t threshold_flag_id )

+{

+#if (ACE_NB_OF_PPE_FLAGS > 0)

+    uint8_t flag_group;

+    uint32_t threshold_flag_mask;

+    ppe_flag_id_t flag_id;

+    uint32_t irq_enable_reg;

+    uint32_t irq_status_reg;

+    uint32_t irq_active;

+    

+    threshold_flag_mask = 1uL << threshold_flag_id;

+    

+    

+    for ( flag_group = 0u; flag_group < NB_OF_FLAG_GROUPS; ++flag_group )

+    {

+        irq_enable_reg = *flags_irq_enable_regs_lut[flag_group];

+        irq_status_reg = *flags_irq_status_regs_lut[flag_group];

+        irq_active = threshold_flag_mask & irq_enable_reg & irq_status_reg;

+        

+        if ( irq_active )

+        {

+            ace_flag_handle_t flag_handle;

+            ace_channel_handle_t channel_handle;

+            

+            flag_id = (ppe_flag_id_t)((flag_group * NB_OF_FLAGS_PER_GROUP) + threshold_flag_id);

+            flag_handle = g_ppe_flag_handles_lut[flag_id];

+            

+            /* Call individual flag handler */

+            if ( g_ppe_flags_isr_lut[flag_id] != 0 ) 

+            {

+                g_ppe_flags_isr_lut[flag_id]( flag_handle );

+            }

+            

+            /* Call the channel flag handler. */

+            channel_handle = g_ppe_flags_desc_table[flag_handle].channel_handle;

+            if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES )

+            {

+                if ( g_ppe_channel_flags_isr_lut[channel_handle] != 0 )

+                {

+                    g_ppe_channel_flags_isr_lut[channel_handle]( flag_handle );

+                }

+            }

+            

+            /* Call the global flag handler. */

+            if ( g_ppe_global_flags_isr != 0 )

+            {

+                g_ppe_global_flags_isr( flag_handle, channel_handle );

+            }

+            

+            /* Clear the flag interrupt */

+            *flags_irq_clear_regs_lut[flag_group] |= threshold_flag_mask;

+        }

+    }

+#endif

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag0_IRQHandler( void )

+#else

+void ACE_PPE_Flag0_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG0 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag0_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag1_IRQHandler( void )

+#else

+void ACE_PPE_Flag1_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG1 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag1_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag2_IRQHandler( void )

+#else

+void ACE_PPE_Flag2_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG2 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag2_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag3_IRQHandler( void )

+#else

+void ACE_PPE_Flag3_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG3 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag3_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag4_IRQHandler( void )

+#else

+void ACE_PPE_Flag4_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG4 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag4_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag5_IRQHandler( void )

+#else

+void ACE_PPE_Flag5_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG5 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag5_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag6_IRQHandler( void )

+#else

+void ACE_PPE_Flag6_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG6 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag6_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag7_IRQHandler( void )

+#else

+void ACE_PPE_Flag7_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG7 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag7_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag8_IRQHandler( void )

+#else

+void ACE_PPE_Flag8_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG8 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag8_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag9_IRQHandler( void )

+#else

+void ACE_PPE_Flag9_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG9 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag9_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag10_IRQHandler( void )

+#else

+void ACE_PPE_Flag10_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG10 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag10_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag11_IRQHandler( void )

+#else

+void ACE_PPE_Flag11_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG11 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag11_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag12_IRQHandler( void )

+#else

+void ACE_PPE_Flag12_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG12 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag12_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag13_IRQHandler( void )

+#else

+void ACE_PPE_Flag13_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG13 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag13_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag14_IRQHandler( void )

+#else

+void ACE_PPE_Flag14_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG14 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag14_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag15_IRQHandler( void )

+#else

+void ACE_PPE_Flag15_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG15 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag15_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag16_IRQHandler( void )

+#else

+void ACE_PPE_Flag16_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG16 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag16_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag17_IRQHandler( void )

+#else

+void ACE_PPE_Flag17_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG17 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag17_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag18_IRQHandler( void )

+#else

+void ACE_PPE_Flag18_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG18 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag18_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag19_IRQHandler( void )

+#else

+void ACE_PPE_Flag19_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG19 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag19_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag20_IRQHandler( void )

+#else

+void ACE_PPE_Flag20_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG20 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag20_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag21_IRQHandler( void )

+#else

+void ACE_PPE_Flag21_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG21 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag21_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag22_IRQHandler( void )

+#else

+void ACE_PPE_Flag22_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG22 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag22_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag23_IRQHandler( void )

+#else

+void ACE_PPE_Flag23_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG23 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag23_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag24_IRQHandler( void )

+#else

+void ACE_PPE_Flag24_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG24 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag24_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag25_IRQHandler( void )

+#else

+void ACE_PPE_Flag25_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG25 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag25_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag26_IRQHandler( void )

+#else

+void ACE_PPE_Flag26_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG26 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag26_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag27_IRQHandler( void )

+#else

+void ACE_PPE_Flag27_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG27 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag27_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag28_IRQHandler( void )

+#else

+void ACE_PPE_Flag28_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG28 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag28_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag29_IRQHandler( void )

+#else

+void ACE_PPE_Flag29_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG29 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag29_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag30_IRQHandler( void )

+#else

+void ACE_PPE_Flag30_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG30 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag30_IRQn );

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void ACE_PPE_Flag31_IRQHandler( void )

+#else

+void ACE_PPE_Flag31_IRQHandler( void )

+#endif

+{

+    process_flag_irq( THRESHOLD_FLAG31 );

+    NVIC_ClearPendingIRQ( ACE_PPE_Flag31_IRQn );

+}

+

+#ifdef __cplusplus

+}

+#endif

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_sse.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_sse.c
new file mode 100644
index 0000000..eefb06b
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_sse.c
@@ -0,0 +1,306 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ * SVN $Revision: 2905 $

+ * SVN $Date: 2010-08-20 14:03:28 +0100 (Fri, 20 Aug 2010) $

+ */

+#include "mss_ace.h"

+#include "mss_ace_configurator.h"

+#include "../../drivers_config/mss_ace/ace_handles.h"

+#include "../../drivers_config/mss_ace/ace_config.h"

+

+#include "../../CMSIS/a2fxxxm3.h"

+#include "../../CMSIS/mss_assert.h"

+#include <string.h>

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+#define SSE_START       1uL

+#define SSE_STOP        0uL

+

+#define NB_OF_ANALOG_BLOCKS     3u

+#define SEE_RAM_WORD_SIZE       512

+

+#define TS_ENABLE_MASK          0x01u

+#define PPE_ENABLE_MASK         0x01u

+#define ADC_RESET_MASK          0x10u

+#define ADC_FIFO_CLR_MASK       0x04u

+#define PDMA_DATAOUT_CLR_MASK   0x04u

+

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+extern ace_procedure_desc_t g_sse_sequences_desc_table[ACE_NB_OF_SSE_PROCEDURES];

+ 

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+sse_sequence_handle_t

+ACE_get_sse_seq_handle

+(

+    const uint8_t * p_sz_sequence_name

+)

+{

+    uint16_t seq_idx;

+    sse_sequence_handle_t handle = INVALID_SSE_SEQ_HANDLE;

+    

+    for ( seq_idx = 0u;  seq_idx < (uint32_t)ACE_NB_OF_SSE_PROCEDURES; ++seq_idx )

+    {

+        if ( g_sse_sequences_desc_table[seq_idx].p_sz_proc_name != 0 )

+        {

+            int32_t diff;

+            diff = strncmp( (const char *)p_sz_sequence_name, (const char *)g_sse_sequences_desc_table[seq_idx].p_sz_proc_name, MAX_PROCEDURE_NAME_LENGTH );

+            if ( 0 == diff )

+            {

+                /* channel name found. */

+                handle = seq_idx;

+                break;

+            }

+        }

+    }

+    return handle;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+static uint32_t volatile * const sse_pc_ctrl_lut[NB_OF_ANALOG_BLOCKS] =

+{

+    &ACE->PC0_CTRL,

+    &ACE->PC1_CTRL,

+    &ACE->PC2_CTRL

+};

+

+static uint32_t volatile * const sse_pc_lo_lut[NB_OF_ANALOG_BLOCKS] =

+{

+    &ACE->PC0_LO,

+    &ACE->PC1_LO,

+    &ACE->PC2_LO

+};

+

+static uint32_t volatile * const sse_pc_hi_lut[NB_OF_ANALOG_BLOCKS] =

+{

+    &ACE->PC0_HI,

+    &ACE->PC1_HI,

+    &ACE->PC2_HI

+};

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_load_sse

+(

+    sse_sequence_handle_t  sequence

+)

+{

+    ASSERT( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES );

+    

+    if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES )

+    {

+        uint16_t i;

+        uint16_t offset;

+        const uint16_t * p_ucode;

+        

+        ASSERT( g_sse_sequences_desc_table[sequence].sse_pc_id < NB_OF_ANALOG_BLOCKS );

+        

+        if ( g_sse_sequences_desc_table[sequence].sse_pc_id < NB_OF_ANALOG_BLOCKS )

+        {

+            /* Stop relevant program counter. */

+            *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_STOP;

+            

+            /* Load microcode into SEE RAM.*/

+            p_ucode = g_sse_sequences_desc_table[sequence].sse_ucode;

+            offset = g_sse_sequences_desc_table[sequence].sse_load_offset;

+            

+            for ( i = 0u; i < g_sse_sequences_desc_table[sequence].sse_ucode_length; ++i )

+            {

+                ACE->SSE_RAM_DATA[offset + i] = (uint32_t)*p_ucode;

+                ++p_ucode;

+            }

+        }

+    }

+}

+

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_start_sse

+(

+    sse_sequence_handle_t  sequence

+)

+{

+    ASSERT( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES );

+    

+    if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES )

+    {

+        uint16_t pc;

+        

+        ASSERT( g_sse_sequences_desc_table[sequence].sse_pc_id < NB_OF_ANALOG_BLOCKS );

+        ASSERT( g_sse_sequences_desc_table[sequence].sse_load_offset < SEE_RAM_WORD_SIZE );

+    

+        pc = g_sse_sequences_desc_table[sequence].sse_load_offset;

+        

+        if ( pc < 256u )

+        {

+            *sse_pc_lo_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = pc;

+        }

+        else

+        {

+            *sse_pc_hi_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = pc - 256;

+        }

+        

+        *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_START;

+        

+        /* Enable Sample Sequencing Engine in case it was not done as part of

+         * system boot. */

+        ACE->SSE_TS_CTRL |= TS_ENABLE_MASK;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_restart_sse

+(

+    sse_sequence_handle_t  sequence

+)

+{

+    ASSERT( sequence < ACE_NB_OF_SSE_PROCEDURES );

+    ASSERT( g_sse_sequences_desc_table[sequence].sse_pc_id < NB_OF_ANALOG_BLOCKS );

+    ASSERT( g_sse_sequences_desc_table[sequence].sse_load_offset < SEE_RAM_WORD_SIZE );

+    

+    if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES )

+    {

+        uint16_t pc;

+        

+        pc = g_sse_sequences_desc_table[sequence].sse_loop_pc;

+        

+        if ( pc < 256u )

+        {

+            *sse_pc_lo_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = pc;

+        }

+        else

+        {

+            *sse_pc_hi_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = pc - 256;

+        }

+        

+        *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_START;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_stop_sse

+(

+    sse_sequence_handle_t  sequence

+)

+{

+    ASSERT( sequence < ACE_NB_OF_SSE_PROCEDURES );

+    

+    if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES )

+    {

+        /* Stop relevant program counter. */

+        *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_STOP;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_resume_sse

+(

+    sse_sequence_handle_t  sequence

+)

+{

+    ASSERT( sequence < ACE_NB_OF_SSE_PROCEDURES );

+    

+    if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES )

+    {

+        *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_START;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_enable_sse_irq

+(

+	sse_irq_id_t sse_irq_id

+)

+{

+    ASSERT( sse_irq_id < NB_OF_SSE_FLAG_IRQS );

+    

+    ACE->SSE_IRQ_EN |= 1uL << (uint32_t)sse_irq_id;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_disable_sse_irq

+(

+	sse_irq_id_t sse_irq_id

+)

+{

+    ASSERT( sse_irq_id < NB_OF_SSE_FLAG_IRQS );

+    

+    ACE->SSE_IRQ_EN &= (uint32_t)~(1uL << (uint32_t)sse_irq_id);

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_clear_sse_irq

+(

+	sse_irq_id_t sse_irq_id

+)

+{

+    ASSERT( sse_irq_id < NB_OF_SSE_FLAG_IRQS );

+    

+    ACE->SSE_IRQ_CLR |= 1uL << (uint32_t)sse_irq_id;

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_clear_sample_pipeline(void)

+{

+    uint32_t saved_sse_ctrl;

+    uint32_t saved_ppe_ctrl;

+    

+    /* Pause the Sample Sequencing Engine. */

+    saved_sse_ctrl = ACE->SSE_TS_CTRL;

+    ACE->SSE_TS_CTRL = ACE->SSE_TS_CTRL & ~((uint32_t)TS_ENABLE_MASK);

+    

+    /* Pause the Post Processing Engine. */

+    saved_ppe_ctrl = ACE->PPE_CTRL;

+    ACE->PPE_CTRL = ACE->PPE_CTRL & ~((uint32_t)PPE_ENABLE_MASK);

+    

+    /* Reset the ADCs */

+    ACE->ADC0_MISC_CTRL |= ADC_RESET_MASK;

+    ACE->ADC1_MISC_CTRL |= ADC_RESET_MASK;

+    ACE->ADC2_MISC_CTRL |= ADC_RESET_MASK;

+    

+    /* Clear ADC FIFOs */

+    ACE->ADC0_FIFO_CTRL |= ADC_FIFO_CLR_MASK;

+    ACE->ADC1_FIFO_CTRL |= ADC_FIFO_CLR_MASK;

+    ACE->ADC2_FIFO_CTRL |= ADC_FIFO_CLR_MASK;

+    

+    /* clear DMA FIFOs */

+    ACE->PPE_PDMA_CTRL |= PDMA_DATAOUT_CLR_MASK;

+    

+    /* Unpause the Post Processing Engine. */

+    ACE->PPE_CTRL = saved_ppe_ctrl;

+    

+    /* Unpause the Sample Sequencing Engine. */

+    ACE->SSE_TS_CTRL = saved_sse_ctrl;

+}

+

+#ifdef __cplusplus

+}

+#endif

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_transform.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_transform.c
new file mode 100644
index 0000000..0a44a6a
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_transform.c
@@ -0,0 +1,467 @@
+/*******************************************************************************

+ * (c) Copyright 2010 Actel Corporation.  All rights reserved.

+ *

+ *  This file contains the implementation of the functions used to dynamically

+ *  control the linear transforms applied by the ACE post processing engine to

+ *  the samples read from the SSE.

+ *

+ * SVN $Revision: 2908 $

+ * SVN $Date: 2010-08-20 16:01:28 +0100 (Fri, 20 Aug 2010) $

+ */

+

+#include "mss_ace.h"

+#include "mss_ace_configurator.h"

+#include "mtd_data.h"

+#include "envm_layout.h"

+#include "../../CMSIS/a2fxxxm3.h"

+#include "../../CMSIS/mss_assert.h"

+#include "../../drivers_config/mss_ace/ace_config.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/*

+ * The ACE_set_linear_transform() is only available when using ACE configuration

+ * files generated by Libero 9.1 or later.

+ */

+#ifdef ACE_CFG_DATA_FORMAT_VERSION

+

+/*------------------------------------------------------------------------------

+ * Masks ans shift values used to derive the ABPS ranges from the analog block

+ * configuration.

+ */

+#define ABPS1_CFG_BITS_MASK     (uint32_t)0x06

+#define ABPS1_CFG_BITS_SHIFT    (uint32_t)1

+

+#define ABPS2_CFG_BITS_MASK     (uint32_t)0x60

+#define ABPS2_CFG_BITS_SHIFT    (uint32_t)5

+

+/*------------------------------------------------------------------------------

+ * One Bit DAC definitions.

+ */

+#define OBD_CURRENT     (uint32_t)1

+#define OBD_VOLTAGE     (uint32_t)0

+

+#define OBD_MODE_MASK    (uint32_t)0x01

+#define OBD_CHOPPING_MASK    (uint32_t)0x02

+

+/*-------------------------------------------------------------------------*//**

+   Neutral factor and offset for m*x + c trnasform.

+ */

+#define NEUTRAL_M_FACTOR    0x4000

+#define NEUTRAL_C_OFFSET    0x0000

+

+/*-------------------------------------------------------------------------*//**

+  Enumearation of the various input channel types. This is used to differentiate

+  between channel types in order to extract the relevant factory calibration

+  data(m1 and c1).

+ */

+typedef enum channel_type

+{

+    ABPS1_CHAN = 0,

+    ABPS2_CHAN,

+    CMB_CHAN,

+    TMB_CHAN,

+    DIRECT_ADC_INPUT_CHAN,

+    OBDOUT_CHAN,

+    FLOATING_CHAN

+} cal_channel_type_t;

+

+/*-------------------------------------------------------------------------*//**

+  This data structure is used to store factory calibration data for a specific

+  analog input.

+ */

+typedef struct __channel_calibration_t

+{

+    uint16_t mext;

+    uint16_t m1;

+    uint16_t c1;

+} channel_calibration_t;

+

+/*-------------------------------------------------------------------------*//**

+  Local functions

+ */

+int32_t extend_sign

+(

+    uint16_t x

+);

+

+uint32_t adjust_to_24bit_ace_format

+(

+    int64_t signed48

+);

+

+uint32_t adjust_to_16bit_ace_format

+(

+    int64_t signed48

+);

+

+void get_calibration

+(

+    adc_channel_id_t channel_id,

+    channel_calibration_t * p_calibration

+);

+

+void write_transform_coefficients

+(

+    ace_channel_handle_t channel_handle,

+	uint32_t m,

+	uint32_t c

+);

+

+/*-------------------------------------------------------------------------*//**

+	  

+ */

+extern const uint8_t g_ace_external_varef_used[ACE_NB_OF_ADC];

+

+extern ace_channel_desc_t g_ace_channel_desc_table[ACE_NB_OF_INPUT_CHANNELS];

+

+extern const ppe_transforms_desc_t g_ace_ppe_transforms_desc_table[ACE_NB_OF_INPUT_CHANNELS];

+

+/*------------------------------------------------------------------------------

+ * Pointer to the manufacturing test data containing trimming information

+ * generated during manufacturing.

+ */

+static const mtd_data_t * const p_mtd_data = (mtd_data_t *)MTD_ADDRESS;

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+int16_t ACE_get_default_m_factor

+(

+    ace_channel_handle_t channel_handle

+)

+{

+    ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES );

+    

+    return g_ace_ppe_transforms_desc_table[channel_handle].m_ppe_offset;

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+int16_t ACE_get_default_c_offset

+(

+    ace_channel_handle_t channel_handle

+)

+{

+    ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES );

+    

+    return g_ace_ppe_transforms_desc_table[channel_handle].c_ppe_offset;

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+  

+  	m = m2 * m1 * mext

+	c = (m2 * c1 * mext) + (c2 * mext)

+ */

+void ACE_set_linear_transform

+(

+    ace_channel_handle_t channel_handle,

+	int16_t m2,

+	int16_t c2

+)

+{

+    adc_channel_id_t channel_id;

+	uint32_t m;

+	uint32_t c;

+	int32_t m32;

+	int64_t m64;

+	int32_t c32;

+	int64_t c64_1;

+    int64_t c64_2;

+    uint16_t m1;

+    uint16_t c1;

+    uint16_t mext;

+    

+    channel_calibration_t calibration;

+    

+    ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES );

+    

+    if(channel_handle < NB_OF_ACE_CHANNEL_HANDLES)

+    {

+        channel_id = g_ace_channel_desc_table[channel_handle].signal_id;

+        

+        get_calibration(channel_id, &calibration);

+        

+        m1 = calibration.m1;

+        c1 = calibration.c1;

+        

+        mext = calibration.mext;

+

+        /* 

+         * m = m2 * m1 * mext

+         */

+        m32 = extend_sign(m2) * extend_sign(m1);

+        m64 = (int64_t)m32 * extend_sign(mext);

+        

+        /* Convert 48-bit result to 32-bit ACE format result. */

+        m = adjust_to_16bit_ace_format(m64);

+

+        /*

+         * c = (m2 * c1 * mext) + (c2 * mext)

+         */

+        c32 = extend_sign(m2) * extend_sign(c1);

+        c64_1 = (int64_t)c32 * extend_sign(mext);

+

+        c64_2 = ((int64_t)(extend_sign(c2) * extend_sign(mext))) << 14;

+        

+        c = adjust_to_24bit_ace_format(c64_1 + c64_2);

+        

+        write_transform_coefficients(channel_handle, m, c);

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+    Extend 16-bit signed number to 32-bit signed number.

+ */

+int32_t extend_sign

+(

+    uint16_t x

+)

+{

+    int32_t y;

+    const uint32_t sign_bit_mask = 0x00008000u;

+    

+    y = (x ^ sign_bit_mask) - sign_bit_mask;

+    

+    return y;

+}

+

+/*-------------------------------------------------------------------------*//**

+  Take a 48-bit signed number, adjust it for saturation in the range -8 to

+  +7.999, translate into 24-bit ACE format.

+ */

+uint32_t adjust_to_24bit_ace_format

+(

+    int64_t signed48

+)

+{

+    int32_t ace24_format;

+    const int64_t MAX_POSITIVE = 0x00001FFFFFFFFFFFuLL; /* +7.9999 */

+    const int64_t MIN_NEGATIVE = 0xFFFF200000000000uLL; /* -8 */

+    

+    /* Check saturation. */

+    if(signed48 > MAX_POSITIVE)

+    {

+        signed48 = MAX_POSITIVE;

+    }

+    else if(signed48 < MIN_NEGATIVE)

+    {

+        signed48 = MIN_NEGATIVE;

+    }

+    

+    /* Adjust to 24-bit ACE format. */

+    ace24_format = (uint32_t)(signed48 >> 14);

+    

+    return ace24_format;

+}

+

+/*-------------------------------------------------------------------------*//**

+  Take a 48-bit signed number, adjust it for saturation in the range -8 to

+  +7.999, translate into 16-bit ACE format.

+ */

+uint32_t adjust_to_16bit_ace_format

+(

+    int64_t signed48

+)

+{

+    int32_t ace24_format;

+    const int64_t MAX_POSITIVE = 0x00001FFFFFFFFFFFuLL; /* +7.9999 */

+    const int64_t MIN_NEGATIVE = 0xFFFF200000000000uLL; /* -8 */

+    

+    /* Check saturation. */

+    if(signed48 > MAX_POSITIVE)

+    {

+        signed48 = MAX_POSITIVE;

+    }

+    else if(signed48 < MIN_NEGATIVE)

+    {

+        signed48 = MIN_NEGATIVE;

+    }

+    

+    /* Adjust to 24-bit ACE format. */

+    ace24_format = (uint32_t)(signed48 >> 20);

+    

+    return ace24_format;

+}

+

+/*-------------------------------------------------------------------------*//**

+	  

+ */

+void get_calibration

+(

+    adc_channel_id_t channel_id,

+    channel_calibration_t * p_calibration

+)

+{

+    const uint32_t channel_mask = 0x0000000F;

+    const uint32_t CMB_MUX_SEL_MASK = 0x01;

+    const uint32_t TMB_MUX_SEL_MASK = 0x01;

+    

+    const cal_channel_type_t channel_type_lut[16] =

+    {

+        FLOATING_CHAN,

+        ABPS1_CHAN,

+        ABPS2_CHAN,

+        CMB_CHAN,

+        TMB_CHAN,

+        ABPS1_CHAN,

+        ABPS2_CHAN,

+        CMB_CHAN,

+        TMB_CHAN,

+        DIRECT_ADC_INPUT_CHAN,

+        DIRECT_ADC_INPUT_CHAN,

+        DIRECT_ADC_INPUT_CHAN,

+        DIRECT_ADC_INPUT_CHAN,

+        FLOATING_CHAN,

+        FLOATING_CHAN,

+        OBDOUT_CHAN

+    };

+    

+    cal_channel_type_t channel_type;

+    uint32_t channel_nb;

+    uint32_t adc_nb;

+    uint32_t range;

+    uint32_t quad_id;

+    mtd_calibration_mc_t const * p_mc_coeff = 0;

+    

+    channel_nb = channel_id & channel_mask;

+    channel_type = channel_type_lut[channel_nb];

+    adc_nb = ((uint32_t)channel_id & 0x30u) >> 4u;

+    

+    quad_id = adc_nb * 2;

+    

+    if ( (channel_nb > 4) && (channel_nb < 9) ) { ++quad_id; }

+    

+    switch ( channel_type )

+    {

+    case ABPS1_CHAN:

+        range = (ACE->ACB_DATA[quad_id].b8 & ABPS1_CFG_BITS_MASK) >> ABPS1_CFG_BITS_SHIFT;

+        p_mc_coeff = &p_mtd_data->abps_calibration[quad_id][0][range];

+        break;

+        

+    case ABPS2_CHAN:

+        range = (ACE->ACB_DATA[quad_id].b8 & ABPS2_CFG_BITS_MASK) >> ABPS2_CFG_BITS_SHIFT;

+        p_mc_coeff = &p_mtd_data->abps_calibration[quad_id][1][range];

+        break;

+        

+    case CMB_CHAN:

+        {

+            uint32_t cmb_mux_sel = (uint32_t)ACE->ACB_DATA[quad_id].b9 & CMB_MUX_SEL_MASK;

+            if ( cmb_mux_sel == 0 )

+            {   /* current monitor */

+                p_mc_coeff = &p_mtd_data->cm_calibration[quad_id];

+            }

+            else

+            {   /* direct input */

+                p_mc_coeff = &p_mtd_data->quads_direct_input_cal[quad_id][0];

+            }

+        }

+        break;

+        

+    case TMB_CHAN:

+        {

+            uint32_t tmb_mux_sel = (uint32_t)ACE->ACB_DATA[quad_id].b10 & TMB_MUX_SEL_MASK;

+            if ( tmb_mux_sel == 0 )

+            {   /* temperature monitor */

+                p_mc_coeff = &p_mtd_data->tm_calibration[quad_id];

+            }

+            else

+            {   /* direct input */

+                p_mc_coeff = &p_mtd_data->quads_direct_input_cal[quad_id][1];

+            }

+        }

+        break;

+        

+    case DIRECT_ADC_INPUT_CHAN:

+        {

+            const uint32_t channel_to_direct_in_lut[16]

+                = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0};

+            uint32_t direct_in_id;

+            

+            direct_in_id = channel_to_direct_in_lut[channel_id & channel_mask];

+            p_mc_coeff = &p_mtd_data->adc_direct_input_cal[adc_nb][direct_in_id];

+        }

+        break;

+        

+    case OBDOUT_CHAN:

+        {

+            uint32_t obd_mode = (uint32_t)ACE->ACB_DATA[quad_id].b6 & OBD_MODE_MASK;

+            uint32_t chopping_option = (uint32_t)ACE->ACB_DATA[quad_id].b6 & OBD_CHOPPING_MASK;

+            if (obd_mode > 0)

+            {

+                obd_mode = 1;

+            }

+            if (chopping_option > 0)

+            {

+                chopping_option = 1;

+            }

+            p_mc_coeff = &p_mtd_data->obd_calibration[adc_nb][obd_mode][chopping_option];

+        }

+        break;

+       

+    case FLOATING_CHAN:

+    default:

+        /* Give neutral values is invalid channel. */

+        p_calibration->m1 = NEUTRAL_M_FACTOR;

+        p_calibration->c1 = NEUTRAL_C_OFFSET;

+        break;

+    }

+    

+    if (p_mc_coeff != 0)

+    {

+        p_calibration->m1 = p_mc_coeff->m;

+        p_calibration->c1 = p_mc_coeff->c;

+        

+    }

+    

+    /*--------------------------------------------------------------------------

+      Retrieve the value of the mext factor. This depends if external VAREF is

+      used by the ADC sampling the analog input channel.

+     */

+    if (g_ace_external_varef_used[adc_nb])

+    {

+        p_calibration->mext = p_mtd_data->global_settings.varef_m;

+    }

+    else

+    {

+        p_calibration->mext = NEUTRAL_M_FACTOR;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+  Write new m and c transform factors into the PPE RAM. The m and c factors

+  should be in 32-bit ACE number format. The factors will be merged with

+  relevant PE opcode into PPE RAM. The 32-bit factors are shifted right by one

+  byte giving a 24-bit ACE number which is then merged with an 8-bit PPE opcode

+  located in the most significant byte of the PPE RAM location.

+ */

+void write_transform_coefficients

+(

+    ace_channel_handle_t channel_handle,

+	uint32_t m,

+	uint32_t c

+)

+{

+    uint16_t m_ppe_offset;

+    uint16_t c_ppe_offset;

+    const uint32_t PPE_OPCODE_MASK = 0xFF000000u;

+    

+    m_ppe_offset = g_ace_ppe_transforms_desc_table[channel_handle].m_ppe_offset;

+    c_ppe_offset = g_ace_ppe_transforms_desc_table[channel_handle].c_ppe_offset;

+    

+    ACE->PPE_RAM_DATA[m_ppe_offset]

+        = (ACE->PPE_RAM_DATA[m_ppe_offset] & PPE_OPCODE_MASK) | (m >> 8u);

+        

+    ACE->PPE_RAM_DATA[c_ppe_offset]

+        = (ACE->PPE_RAM_DATA[c_ppe_offset] & PPE_OPCODE_MASK) | (c >> 8u);

+}

+

+#endif  /* ACE_CFG_DATA_FORMAT_VERSION */

+

+#ifdef __cplusplus

+}

+#endif

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/envm_layout.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/envm_layout.h
new file mode 100644
index 0000000..0081310
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/envm_layout.h
@@ -0,0 +1,37 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ * This file contains the addresses and size of the various blocks of data

+ * stored in eNVM.

+ *

+ * SVN $Revision: 1113 $

+ * SVN $Date: 2009-07-01 11:11:29 +0100 (Wed, 01 Jul 2009) $

+ */

+#ifndef ENVM_LAYOUT_HEADER

+#define ENVM_LAYOUT_HEADER

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/*==============================================================================

+ * Address of the manufacturing test data.

+ */

+#define MTD_ADDRESS 0x60080010

+

+/*==============================================================================

+ * MSS configuration location.

+ */

+#define MSS_CONFIG_ADDRESS        0x60081618

+

+/*==============================================================================

+ * Analog configuration location and size.

+ */

+#define ANALOG_CONFIG_ADDRESS     0x60081600

+#define ANALOG_CONFIG_BYTE_SIZE   24

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif  /* ENVM_LAYOUT_HEADER */

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.c
new file mode 100644
index 0000000..cd717f0
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.c
@@ -0,0 +1,744 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ * SVN $Revision: 2905 $

+ * SVN $Date: 2010-08-20 14:03:28 +0100 (Fri, 20 Aug 2010) $

+ */

+

+#include "mss_ace.h"

+#include "mtd_data.h"

+#include "envm_layout.h"

+#include "mss_ace_configurator.h"

+#include "../../CMSIS/a2fxxxm3.h"

+#include "../../CMSIS/mss_assert.h"

+#include "../../drivers_config/mss_ace/ace_config.h"

+#include <string.h>

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+#define START_ADC_CONVERSION    0x80uL

+

+

+/**/

+void ace_init_flags( void );

+void ace_init_convert(void);

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+void ACE_init( void )

+{

+    /* Initialize driver's internal data. */

+    ace_init_flags();

+    

+    /* Initialize the data structures used by conversion functions. */

+    ace_init_convert();

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+void ACE_start_adc

+(

+	adc_channel_id_t channel_id

+)

+{

+    ACE->ADC0_CONV_CTRL = (uint32_t)channel_id | START_ADC_CONVERSION;

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+#define ADC_DATAVALID_MASK    0x00001000uL

+#define ADC_RESULT_MASK       0x00000FFFuL

+

+static const uint32_t volatile * const adc_status_reg_lut[NB_OF_ANALOG_MODULES] =

+{

+    &ACE->ADC0_STATUS,

+    &ACE->ADC1_STATUS,

+    &ACE->ADC2_STATUS

+};

+

+uint16_t ACE_get_adc_result

+(

+    uint8_t adc_id

+)

+{

+    uint16_t result = 0u;

+    uint32_t data_valid;

+

+    ASSERT( adc_id < NB_OF_ANALOG_MODULES );

+    

+    if ( adc_id < (uint8_t)NB_OF_ANALOG_MODULES )

+    {

+        do {

+            data_valid = *adc_status_reg_lut[adc_id] & ADC_DATAVALID_MASK;

+        } while ( !data_valid );

+        

+        result = (uint16_t)(*adc_status_reg_lut[adc_id] & ADC_RESULT_MASK);

+    }

+    return result;

+}

+

+/*==============================================================================

+ =========== Sigma Delta Digital to Analog Converters (SDD) Control ============

+ =============================================================================*/

+

+#define SDD_ENABLE_MASK     0x20uL

+#define SDD_REG_SEL_MASK    0x40uL

+ 

+#define DAC0_SYNC_EN_MASK   0x10uL

+#define DAC1_SYNC_EN_MASK   0x20uL

+#define DAC2_SYNC_EN_MASK   0x40uL

+

+#define DAC0_SYNC_UPDATE    0x01uL

+#define DAC1_SYNC_UPDATE    0x02uL

+#define DAC2_SYNC_UPDATE    0x04uL

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+static volatile uint32_t * const dac_ctrl_reg_lut[NB_OF_ANALOG_MODULES] =

+{

+    &ACE->DAC0_CTRL,

+    &ACE->DAC1_CTRL,

+    &ACE->DAC1_CTRL

+};

+

+static const uint32_t dac_enable_masks_lut[NB_OF_ANALOG_MODULES] =

+{

+    DAC0_SYNC_EN_MASK,

+    DAC1_SYNC_EN_MASK,

+    DAC2_SYNC_EN_MASK

+};

+

+static volatile uint32_t * const dac_byte01_reg_lut[NB_OF_ANALOG_MODULES] =

+{

+    &ACE->SSE_DAC0_BYTES01,

+    &ACE->SSE_DAC1_BYTES01,

+    &ACE->SSE_DAC2_BYTES01,

+};

+

+static volatile uint32_t * const dac_byte2_reg_lut[NB_OF_ANALOG_MODULES] =

+{

+    &ACE->DAC0_BYTE2,

+    &ACE->DAC1_BYTE2,

+    &ACE->DAC2_BYTE2

+};

+

+/*------------------------------------------------------------------------------

+ * Pointer to the manufacturing test data containing trimming information

+ * generated during manufacturing.

+ */

+static const mtd_data_t * const p_mtd_data = (mtd_data_t *)MTD_ADDRESS;

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+#define OBD_MODE_MASK       (uint8_t)0x01

+#define OBD_CHOPPING_MASK   (uint8_t)0x02

+

+void ACE_configure_sdd

+(

+	sdd_id_t            sdd_id,

+	sdd_resolution_t    resolution,

+    uint8_t             mode,

+    sdd_update_method_t sync_update

+)

+{

+    ASSERT( sdd_id < NB_OF_SDD );

+    

+    if ( sdd_id < NB_OF_SDD )

+    {

+        const uint8_t sdd_2_quad_lut[NB_OF_SDD] = {0u, 2u, 4u};

+        uint8_t quad_id;

+        uint8_t obd_mode_idx = 1u;

+        uint8_t chopping_mode_idx = 0u;

+        uint32_t saved_pc2_ctrl;

+        

+        quad_id = sdd_2_quad_lut[sdd_id];

+        

+        /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */

+        saved_pc2_ctrl = ACE->PC2_CTRL;

+        ACE->PC2_CTRL = 0u;

+        

+        /* Select between voltage/current and RTZ modes.*/

+        ACE->ACB_DATA[quad_id].b6 = mode;

+        

+        /* Load manufacturing generated trim value. */

+        if ( (mode & OBD_MODE_MASK) > 0u )

+        {

+            obd_mode_idx = 0u;

+        }

+        if ( (mode & OBD_CHOPPING_MASK) > 0u )

+        {

+            chopping_mode_idx = 1u;

+        }

+        ACE->ACB_DATA[quad_id].b4

+            = p_mtd_data->odb_trimming[sdd_id][obd_mode_idx][chopping_mode_idx];

+        

+        /* Restore SSE PC2 operations since no ACB accesses should take place

+         * beyond this point. */

+        ACE->PC2_CTRL = saved_pc2_ctrl;

+    

+        /* Set SDD resolution. */

+        *dac_ctrl_reg_lut[sdd_id] = (uint32_t)resolution;

+        

+        /* Update SDD value through SSE_DACn_BYTES01. */

+        *dac_ctrl_reg_lut[sdd_id] |= SDD_REG_SEL_MASK;

+        

+        /* Synchronous or individual SDD update. */

+        if ( INDIVIDUAL_UPDATE == sync_update )

+        {

+            ACE->DAC_SYNC_CTRL &= ~dac_enable_masks_lut[sdd_id];

+        }

+        else

+        {

+            ACE->DAC_SYNC_CTRL |= dac_enable_masks_lut[sdd_id];

+        }

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+void ACE_enable_sdd

+(

+	sdd_id_t    sdd_id

+)

+{

+    ASSERT( sdd_id < NB_OF_SDD );

+    

+    if ( sdd_id < NB_OF_SDD )

+    {

+        *dac_ctrl_reg_lut[sdd_id] |= SDD_ENABLE_MASK;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+void ACE_disable_sdd

+(

+	sdd_id_t    sdd_id

+)

+{

+    ASSERT( sdd_id < NB_OF_SDD );

+    

+    if ( sdd_id < NB_OF_SDD )

+    {

+        *dac_ctrl_reg_lut[sdd_id] &= ~SDD_ENABLE_MASK;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+void ACE_set_sdd_value

+(

+	sdd_id_t    sdd_id,

+	uint32_t    sdd_value

+)

+{

+    ASSERT( sdd_id < NB_OF_SDD );

+    

+    if ( sdd_id < NB_OF_SDD )

+    {

+        *dac_byte2_reg_lut[sdd_id] = sdd_value >> 16;

+        *dac_byte01_reg_lut[sdd_id] = sdd_value;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+void ACE_set_sdd_value_sync

+(

+    uint32_t sdd0_value,

+    uint32_t sdd1_value,

+    uint32_t sdd2_value

+)

+{

+    uint32_t dac_sync_ctrl;

+    

+    dac_sync_ctrl = ACE->DAC_SYNC_CTRL;

+    

+    if ( SDD_NO_UPDATE != sdd0_value )

+    {

+        ACE->DAC0_BYTE2 = sdd0_value >> 16;

+        ACE->SSE_DAC0_BYTES01 = sdd0_value;

+        dac_sync_ctrl |= DAC0_SYNC_UPDATE;

+    }

+

+    if ( SDD_NO_UPDATE != sdd1_value )

+    {

+        ACE->DAC1_BYTE2 = sdd1_value >> 16;

+        ACE->SSE_DAC1_BYTES01 = sdd1_value;

+        dac_sync_ctrl |= DAC1_SYNC_UPDATE;

+    }

+

+    if ( SDD_NO_UPDATE != sdd2_value )

+    {

+        ACE->DAC2_BYTE2 = sdd2_value >> 16;

+        ACE->DAC2_BYTE1 = sdd2_value >> 8;

+        ACE->SSE_DAC2_BYTES01 = sdd2_value;

+        dac_sync_ctrl |= DAC2_SYNC_UPDATE;

+    }

+    

+    ACE->DAC_SYNC_CTRL = dac_sync_ctrl;

+}

+

+/*==============================================================================

+ ============================ Comparators Control ==============================

+ =============================================================================*/

+

+ /*

+  * SDD Analog switch mask. ACB byte 10.

+  *     0:  TMB comparator reference voltage is an ADC direct input

+  *     1:  TMB comparator reference voltage is one of the SDD outputs as

+  *         selected by DAC_MUXSEL[1:0]

+  */

+#define B10_COMP_VREF_SW_MASK   0x20u

+

+/*

+ * Comparator reference voltage multiplexer.

+ * Used to select which SDD output will be used as reference voltage for TMB

+ * comparator. These bits are only meaningful when COMP_VREF_SW is set to 1.

+ */

+#define B11_DAC_MUXSEL_MASK     0x03u

+

+/*

+ * Number of bits to shift a value of type comp_hysteresis_t to get the

+ * hysteresis to program into ACB b9 or b10.

+ */

+#define HYSTERESIS_SHIFT    6u

+

+/*

+ * Mask of hysteresis bits within ACB b9 or b10.

+ */

+#define HYSTERESIS_MASK     0xC0u

+

+/*

+ * Mask of the comparator enable bit within ACB b9 and b10.

+ */

+#define COMPARATOR_ENABLE_MASK  0x10u

+

+/*

+ * Comparator ID to Signal Conditioning Block (SCB) lookup table.

+ * USe to find which SCB a comparator belongs to.

+ */

+const uint8_t comp_id_2_scb_lut[NB_OF_COMPARATORS] =

+{

+    0u,  /* CMP0 */

+    0u,  /* CMP1 */

+    1u,  /* CMP2 */

+    1u,  /* CMP3 */

+    2u,  /* CMP4 */

+    2u,  /* CMP5 */

+    3u,  /* CMP6 */

+    3u,  /* CMP7 */

+    4u,  /* CMP8 */

+    4u,  /* CMP9 */

+    5u,  /* CMP10 */

+    5u   /* CMP11 */

+};

+

+/*-------------------------------------------------------------------------*//**

+ * This function is requred to configure comparators included in temperature

+ * monitor blocks.

+ */

+void ACE_set_comp_reference

+(

+    comparator_id_t     comp_id,

+    comp_reference_t    reference

+)

+{

+    uint8_t scb_id;

+    uint32_t odd;

+    

+    odd = (uint32_t)comp_id & 0x01uL;

+    

+    ASSERT( comp_id < NB_OF_COMPARATORS );

+    ASSERT( reference < NB_OF_COMP_REF );

+    ASSERT( odd );    /* Only Temperature block comparators have configurable reference input. */

+    

+    if ( (comp_id < NB_OF_COMPARATORS) && (reference < NB_OF_COMP_REF) && (odd) )

+    {

+        uint32_t saved_pc2_ctrl;

+        

+        scb_id = comp_id_2_scb_lut[comp_id];

+        

+        /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */

+        saved_pc2_ctrl = ACE->PC2_CTRL;

+        ACE->PC2_CTRL = 0u;

+    

+        if ( ADC_IN_COMP_REF == reference )

+        {

+            ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~B10_COMP_VREF_SW_MASK;

+            ACE->ACB_DATA[scb_id].b11 &= (uint8_t)~B11_DAC_MUXSEL_MASK;

+        }

+        else

+        {

+            ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~B10_COMP_VREF_SW_MASK;

+            ACE->ACB_DATA[scb_id].b11 = (ACE->ACB_DATA[scb_id].b11 & (uint8_t)~B11_DAC_MUXSEL_MASK) + (uint8_t)reference;

+        }

+    

+        /* Restore SSE PC2 operations since no ACB accesses should take place

+         * beyond this point. */

+        ACE->PC2_CTRL = saved_pc2_ctrl;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ * Set analog block comparators hysteresis.

+ */

+void ACE_set_comp_hysteresis

+(

+	comparator_id_t     comp_id,

+    comp_hysteresis_t   hysteresis

+)

+{

+    uint8_t scb_id;

+    

+    ASSERT( comp_id < NB_OF_COMPARATORS );

+    ASSERT( hysteresis < NB_OF_HYSTERESIS );

+    

+    if ( (comp_id < NB_OF_COMPARATORS) && (hysteresis < NB_OF_HYSTERESIS) )

+    {

+        uint32_t odd;

+        uint32_t saved_pc2_ctrl;

+        

+        scb_id = comp_id_2_scb_lut[comp_id];

+        odd = (uint32_t)comp_id & 0x01uL;

+        

+        /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */

+        saved_pc2_ctrl = ACE->PC2_CTRL;

+        ACE->PC2_CTRL = 0u;

+    

+        if ( odd )

+        {

+            /* Temperature monitor block comparator. */

+            ACE->ACB_DATA[scb_id].b10 = (ACE->ACB_DATA[scb_id].b10 & HYSTERESIS_MASK) | (uint8_t)((uint8_t)hysteresis << HYSTERESIS_SHIFT);

+        }

+        else

+        {

+            /* Current monitor block comparator. */

+            ACE->ACB_DATA[scb_id].b9 = (ACE->ACB_DATA[scb_id].b9 & HYSTERESIS_MASK) | (uint8_t)((uint8_t)hysteresis << HYSTERESIS_SHIFT);

+        }

+        

+        /* Restore SSE PC2 operations since no ACB accesses should take place

+         * beyond this point. */

+        ACE->PC2_CTRL = saved_pc2_ctrl;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+  

+ */

+void ACE_enable_comp

+(

+	comparator_id_t comp_id

+)

+{

+    uint8_t scb_id;

+    

+    ASSERT( comp_id < NB_OF_COMPARATORS );

+    

+    if ( comp_id < NB_OF_COMPARATORS )

+    {

+        uint32_t odd;

+        uint32_t saved_pc2_ctrl;

+        

+        scb_id = comp_id_2_scb_lut[comp_id];

+        odd = (uint32_t)comp_id & 0x01uL;

+        

+        /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */

+        saved_pc2_ctrl = ACE->PC2_CTRL;

+        ACE->PC2_CTRL = 0u;

+        

+        if ( odd )

+        {

+            /* Temperature monitor block comparator. */

+            ACE->ACB_DATA[scb_id].b10 |= COMPARATOR_ENABLE_MASK;

+        }

+        else

+        {

+            /* Current monitor block comparator. */

+            ACE->ACB_DATA[scb_id].b9 |= COMPARATOR_ENABLE_MASK;

+        }

+        

+        /* Restore SSE PC2 operations since no ACB accesses should take place

+         * beyond this point. */

+        ACE->PC2_CTRL = saved_pc2_ctrl;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+void ACE_disable_comp

+(

+	comparator_id_t comp_id

+)

+{

+    uint8_t scb_id;

+    

+    ASSERT( comp_id < NB_OF_COMPARATORS );

+    

+    if ( comp_id < NB_OF_COMPARATORS )

+    {

+        uint32_t odd;

+        uint32_t saved_pc2_ctrl;

+        

+        scb_id = comp_id_2_scb_lut[comp_id];

+        odd = (uint32_t)comp_id & 0x01uL;

+        

+        /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */

+        saved_pc2_ctrl = ACE->PC2_CTRL;

+        ACE->PC2_CTRL = 0u;

+        

+        if ( odd )

+        {

+            /* Temperature monitor block comparator. */

+            ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~COMPARATOR_ENABLE_MASK;

+        }

+        else

+        {

+            /* Current monitor block comparator. */

+            ACE->ACB_DATA[scb_id].b9 &= (uint8_t)~COMPARATOR_ENABLE_MASK;

+        }

+        

+        /* Restore SSE PC2 operations since no ACB accesses should take place

+         * beyond this point. */

+        ACE->PC2_CTRL = saved_pc2_ctrl;

+    }

+}

+

+/*

+ * Bit mask of comparator 0 rise interrupt bit.

+ * Shift this value left by the value of the comparator ID to obtain the bit

+ * mask used enable/disable/clear rise interrupts from that comparator.

+ */

+#define FIRST_RISE_IRQ_MASK     0x00000800uL

+

+/*

+ * Bit mask of comparator 0 fall interrupt bit.

+ * Shift this value left by the value of the comparator ID to obtain the bit

+ * mask used enable/disable/clear fall interrupts from that comparator.

+ */

+#define FIRST_FALL_IRQ_MASK     0x00000001uL

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+void ACE_enable_comp_rise_irq

+(

+	comparator_id_t comp_id

+)

+{

+    ASSERT( comp_id < NB_OF_COMPARATORS );

+    

+    ACE->COMP_IRQ_EN |= (FIRST_RISE_IRQ_MASK << (uint32_t)comp_id);

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+void ACE_disable_comp_rise_irq

+(

+	comparator_id_t comp_id

+)

+{

+    ASSERT( comp_id < NB_OF_COMPARATORS );

+    

+    ACE->COMP_IRQ_EN &= ~(FIRST_RISE_IRQ_MASK << (uint32_t)comp_id);

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+void ACE_clear_comp_rise_irq

+(

+	comparator_id_t comp_id

+)

+{

+    ASSERT( comp_id < NB_OF_COMPARATORS );

+    

+    ACE->COMP_IRQ_CLR |= (FIRST_RISE_IRQ_MASK << (uint32_t)comp_id);

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+void ACE_enable_comp_fall_irq

+(

+	comparator_id_t comp_id

+)

+{

+    ASSERT( comp_id < NB_OF_COMPARATORS );

+    

+    ACE->COMP_IRQ_EN |= (FIRST_FALL_IRQ_MASK << (uint32_t)comp_id);

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+void ACE_disable_comp_fall_irq

+(

+	comparator_id_t comp_id

+)

+{

+    ASSERT( comp_id < NB_OF_COMPARATORS );

+    

+    ACE->COMP_IRQ_EN &= ~(FIRST_FALL_IRQ_MASK << (uint32_t)comp_id);

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+void ACE_clear_comp_fall_irq

+(

+	comparator_id_t comp_id

+)

+{

+    ASSERT( comp_id < NB_OF_COMPARATORS );

+    

+    ACE->COMP_IRQ_CLR |= (FIRST_FALL_IRQ_MASK << (uint32_t)comp_id);

+}

+

+/*-------------------------------------------------------------------------*//**

+ * Returns the raw analog quad comparator status.

+ */

+uint32_t ACE_get_comp_status( void )

+{

+    return ACE->COMP_IRQ;

+}

+

+/*==============================================================================

+ ============ Reading Samples from post processing engine (PPE) ================

+ =============================================================================*/

+extern ace_channel_desc_t g_ace_channel_desc_table[ACE_NB_OF_INPUT_CHANNELS];

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+uint32_t

+ACE_get_channel_count

+(

+    void

+)

+{

+    return (uint32_t)ACE_NB_OF_INPUT_CHANNELS;

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+ace_channel_handle_t

+ACE_get_first_channel

+(

+    void

+)

+{

+    ace_channel_handle_t channel_handle;

+    

+    channel_handle = (ace_channel_handle_t)0;

+    

+    return channel_handle;

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+ace_channel_handle_t

+ACE_get_next_channel

+(

+    ace_channel_handle_t channel_handle

+)

+{

+    ++channel_handle;

+    

+    if ( channel_handle >= NB_OF_ACE_CHANNEL_HANDLES )

+    {

+         channel_handle = (ace_channel_handle_t)0;

+    }

+    

+    return channel_handle;

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+ace_channel_handle_t

+ACE_get_channel_handle

+(

+    const uint8_t * p_sz_channel_name

+)

+{

+    uint16_t channel_idx;

+    ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE;

+    

+    for ( channel_idx = 0u;  channel_idx < (uint16_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx )

+    {

+        if ( g_ace_channel_desc_table[channel_idx].p_sz_channel_name != 0 )

+        {

+            int32_t diff;

+            diff = strncmp( (const char*)p_sz_channel_name, (const char*)g_ace_channel_desc_table[channel_idx].p_sz_channel_name, MAX_CHANNEL_NAME_LENGTH );

+            if ( 0 == diff )

+            {

+                /* channel name found. */

+                channel_handle = (ace_channel_handle_t)channel_idx;

+                break;

+            }

+        }

+    }

+    return channel_handle;

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+ace_channel_handle_t

+ACE_get_input_channel_handle

+(

+    adc_channel_id_t    channel_id

+)

+{

+    uint16_t channel_idx;

+    ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE;

+    

+    for ( channel_idx = 0u;  channel_idx < (uint16_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx )

+    {

+        if ( g_ace_channel_desc_table[channel_idx].signal_id == channel_id )

+        {

+            /* channel ID found. */

+            channel_handle = (ace_channel_handle_t)channel_idx;

+            break;

+        }

+    }

+    return channel_handle;

+}

+

+/*-------------------------------------------------------------------------*//**

+  See "mss_ace.h" for details of how to use this function.

+ */

+uint16_t

+ACE_get_ppe_sample

+(

+    ace_channel_handle_t channel_handle

+)

+{

+    uint16_t sample;

+    uint16_t ppe_offset;

+    

+    ppe_offset = g_ace_channel_desc_table[channel_handle].signal_ppe_offset;

+    sample = (uint16_t)(ACE->PPE_RAM_DATA[ppe_offset] >> 16u);

+    

+    return sample;

+}

+

+#ifdef __cplusplus

+}

+#endif

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.h
new file mode 100644
index 0000000..ec4f00e
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.h
@@ -0,0 +1,2816 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ * SmartFusion ACE driver public API.

+ *

+ * SVN $Revision: 2884 $

+ * SVN $Date: 2010-08-13 16:16:59 +0100 (Fri, 13 Aug 2010) $

+ */

+

+/*=========================================================================*//**

+  @mainpage SmartFusion Analog Compute Engine driver public API.

+

+  @section intro_sec Introduction

+  The SmartFusion™ microcontroller subsystem (MSS) includes the Analog Compute

+  Engine (ACE) which provides access to the analog capabilities of SmartFusion

+  from the Cortex™-M3 microcontroller. This driver provides a set of functions

+  for controlling the MSS ACE as part of a bare metal system where no operating

+  system is available. These drivers can be adapted for use as part of an

+  operating system, but the implementation of the adaptation layer between this

+  driver and the operating system's driver model is outside the scope of this

+  driver. The ACE includes:

+    • A Sample Sequencing Engine (SSE) controlling the  operations of up to

+      three analog to digital converters (ADC)

+    • A Post Processing Engine (PPE) processing the analog inputs samples

+      generated as a result of the SSE operations

+    • An interface for controlling Sigma Delta DACs (SDD)

+    • An interface for controlling high speed comparators

+

+  The Sample Sequencing Engine controls the sampling of the various analog

+  inputs based on a predefined sampling sequence without requiring intervention

+  from the Cortex-M3. The sampling sequence is defined using the ACE Configurator

+  provided as part of the MSS Configurator software tool.

+  Available analog inputs are:

+    • Active bipolar prescaler inputs (ABPS) allowing to measure voltages within

+      four possible ranges:

+        o -15V to +15V

+        o -10V to +10V

+        o -5V to +5V

+        o -2.5V to +2.5V

+    • Current inputs

+    • Temperature inputs

+    • Direct ADC inputs allowing to measure a voltage between zero volts and

+      the ADC’s reference voltage (VAREF)

+  Please refer to the Analog Front End section of the SmartFusion datasheet for

+  further details about analog inputs.

+

+  The Post Processing Engine can perform the following operations on the analog

+  input samples generated as a result of the SSE operations:

+    • Calibration adjustment

+    • Averaging

+    • Threshold detection

+    • DMA transfer of most recent sample result to RAM or FPGA fabric

+  The result of analog input sampling is read from the PPE rather than directly

+  from the ADC. This ensures more accurate sample results thought the factory

+  calibration adjustment performed by the PPE.

+  The PPE can be set to generate interrupts when specific threshold values are

+  reached on analog inputs through the ACE Configurator software tool. These

+  thresholds can also be dynamically adjusted through the ACE driver.

+

+  The ACE provides an interface to the Sigma Delta DACs included within the

+  Analog Front End (AFE). This interface allows control of the DAC’s output

+  value. Dynamic configuration of the DAC is also possible.

+

+  The ACE provides an interface to the high speed comparators included within

+  the Analog Front End. This interface allows dynamic configuration of the

+  comparators and controlling interrupts based on the comparators’ state.

+

+  @section theory_op Theory of Operation

+  The configuration of the ACE is set though the use of the ACE Configurator

+  included in the SmartFusion MSS Configurator software tool provided as part of

+  the Libero Integrated Design Environment tool suite. The ACE Configurator

+  offers an easy to use graphical method of selecting the configuration of the

+  following ACE characteristics:

+    • Analog input channels configuration

+    • ADC configuration

+    • Analog input channels sampling sequence

+    • Filtering applied to analog input samples

+    • Threshold flags configuration including hysteresis or state filtering properties

+    • Selection of post processing results transferred though DMA

+    • Sigma Delta DACs configuration

+    • Analog comparators configuration

+  The selected configuration hardware settings, SSE microcode and PPE microcode

+  are stored in the SmartFusion eNVM. This configuration data is used by the

+  system boot to configure the ACE after the system come out of reset and before

+  control is passed to the application. This results in the ACE being fully

+  operational by the time the application starts executing.

+  The ACE Configurator also generates a set of C files containing information

+  about the ACE’s configuration. These C files must be copied into the

+  drivers_config/mss_ace folder of you r software project for consumption by the

+  ACE driver. The ACE driver uses the content of these configuration files to

+  interact with the configured ACE hardware.

+

+  The ACE driver functions are grouped into the following categories:

+    • Initialization

+    • Reading analog input channels values and properties

+    • Post Processing Engine flags

+    • Conversion functions between sample value and real world units

+    • Sample Sequencing Engine control

+    • Sample Sequencing Engine Interrupts Control

+    • Comparators control

+    • Sigma Delta Digital to Analog Converters (SDD) control

+    • Direct analog block configuration and usage

+

+    

+  Initialization

+    The ACE driver is initialized through a call to the ACE_init() function. The

+    ACE_init() function must be called before any other ACE driver functions can

+    be called. It initializes the ACE’s internal data.

+

+    

+  Reading analog input channels values and properties

+    The ACE driver allows retrieving the most recent post processed sample value

+    for each analog input. It also allows retrieving the name of the analog input

+    channel assigned in the ACE Configurator and whether the input channel samples

+    a voltage, current or temperature.

+    Each individual analog input channel is identified using a channel handle which

+    is passed as parameter to the ACE input channel driver functions. The channel

+    handles are design specific. The list of channel handles is generated by the

+    ACE Configurator based on the names given to the input signals. The channel

+    handles can be found in the drivers_config\mss_ace\ace_handles.h file.  The

+    channel handle can be obtained from the channel name using the ACE_get_channel_handle()

+    function. It is also possible to iterate through all the channels using the

+    ACE_get_first_channel() and ACE_get_next_channel() functions.

+

+    Reading analog input samples from the post processing engine is done the following function:

+        • uint16_t ACE_get_ppe_sample( ace_channel_handle_t channel_handle )

+

+    Information about an input channel can be retrieved using the following functions:

+        • const uint8_t * ACE_get_channel_name( ace_channel_handle_t channel_handle )

+        • channel_type_t ACE_get_channel_type( ace_channel_handle_t channel_handle )

+

+        

+  Post Processing Engine flags

+    The SmartFusion ACE Post Processing Engine (PPE) provides the ability to monitor

+    the state of analog input channels and detect when certain threshold values are

+    crossed. Flags are raised by the PPE when these thresholds are crossed. Interrupts

+    can optionally be generated when flags are raised.

+    The flags are defined using the ACE Configurator software tool. The flag’s name,

+    threshold value and hysteresis settings are specified in the ACE Configurator.

+    The ACE Configurator generates microcode based on the selected configuration which

+    is executed at system run time by the PPE. The PPE microcode is loaded into the

+    ACE at chip boot time by the Actel provided system boot code. No ACE driver

+    intervention is required to load up the PPE microcode.

+    The ACE driver allows:

+        • Retrieving the current state of the post processing engine flags

+        • Assigning a handler function to individual flag assertions

+        • Assigning a handler function to flags generated based on the value of a

+          specific channel

+        • Controlling flag interrupts

+        • Dynamically modify a flag’s threshold value

+        • Dynamically modify a flag’s hysteresis

+

+    Each individual flag is identified using a flag handle which is passed as parameter

+    to the ACE driver functions controlling the flags. The flag handles are design

+    specific. They are defined in the drivers_config\mss_ace\ace_handles.h file which

+    is generated by the ACE Configurator based on the names selected for the signal

+    and flag names. A flag handle can be obtained from the driver using the name of

+    the flag entered in the ACE Configurator software when the flag was created. A

+    flag handle can also be obtained using the functions ACE_get_channel_first_flag()

+    and ACE_get_channel_next_flag() when iterating through the flags associated with

+    an analog input channel.  The functions available for retrieving flag handles are:

+        • ace_flag_handle_t ACE_get_flag_handle (const uint8_t *p_sz_full_flag_name)

+        • ace_flag_handle_t ACE_get_channel_first_flag (ace_channel_handle_t channel_handle, uint16_t *iterator)

+        • ace_flag_handle_t ACE_get_channel_next_flag (ace_channel_handle_t channel_handle, uint16_t *iterator)

+     

+    The current status of a flag can be polled using the following function:

+        • int32_t ACE_get_flag_status (ace_flag_handle_t flag_handle)

+

+    Interrupt handlers can be registered with the ACE driver to handle individual

+    flags. These interrupt handlers will be called by the ACE driver when a specific

+    flag is raised. The flag interrupt control functions are:

+        • void ACE_register_flag_isr (ace_flag_handle_t flag_handle, flag_isr_t flag_isr)

+        • void ACE_enable_flag_irq (ace_flag_handle_t flag_handle)

+        • void ACE_disable_flag_irq (ace_flag_handle_t flag_handle)

+        • void ACE_clear_flag_irq (ace_flag_handle_t flag_handle)

+

+    Interrupt handlers can be registered with the ACE driver to handle all flags

+    associated with one specific analog input channel. These interrupt handlers will

+    be called by the ACE driver when one of the flags, generated based on the state of

+    the specified analog input channel, is raised. The channel flag interrupt control

+    functions are:

+        • void ACE_register_channel_flags_isr (ace_channel_handle_t channel_handle, channel_flag_isr_t channel_flag_isr)

+        • void ACE_enable_channel_flags_irq (ace_channel_handle_t channel_handle)

+        • void ACE_disable_channel_flags_irq (ace_channel_handle_t channel_handle)

+        • void ACE_clear_channel_flags_irq (ace_channel_handle_t channel_handle)

+

+    A single global interrupt handler can be registered with the ACE driver. The global

+    flag interrupt handler function will be called by the ACE driver when any of the

+    interrupt enabled flag is raised. The handle of the flag causing the interrupt and

+    the handle of the associated analog input channel is passed as parameter to the

+    registered global flag handler.

+        • void ACE_register_global_flags_isr (global_flag_isr_t global_flag_isr)

+

+    The configuration of a flag can be dynamically modified using the following functions:

+        • void ACE_set_flag_threshold (ace_flag_handle_t flag_handle, uint16_t new_threshold)

+        • void ACE_set_flag_hysteresis (ace_flag_handle_t flag_handle, uint16_t adc_hysteresis)

+        • void ACE_set_channel_hysteresis (ace_channel_handle_t channel_handle, uint16_t adc_hysteresis)

+        • void ACE_set_flag_assertion( ace_flag_handle_t   flag_handle, uint16_t assertion_value )

+        • void ACE_set_flag_deassertion( ace_flag_handle_t   flag_handle, uint16_t assertion_value )

+

+    Information about a flag can be retrieved using the following functions once

+    the flag handle is known:

+        • const uint8_t * ACE_get_flag_name (ace_flag_handle_t flag_handle)

+        • ace_channel_handle_t ACE_get_flag_channel (ace_flag_handle_t flag_handle)

+

+        

+  Conversion to and from real world units

+    The ACE driver provides a set of conversion functions to convert sample values

+    read from the post processing engine into real world units:

+        • millivolts

+        • milliamps

+        • Degrees Kelvin

+        • Degrees Celsius

+        • Degrees Fahrenheit

+    Conversion functions are also available to convert from real world units into

+    PPE sample values. These functions are typically used for dynamically adjusting

+    flags threshold values.

+

+    

+  Sample Sequencing Engine control

+    The ACE driver provides a set of functions for dynamically controlling the

+    Sample Sequencing Engine. These functions are only required for managing multiple

+    sampling sequences. The use of these functions is not required for most applications

+    since the SSE is already configured and running by the time the application starts.

+

+    

+  Sample Sequencing Engine Interrupts Control

+    The ACE driver provides a set of functions for managing interrupts generated by

+    the Sample Sequencing Engine. These functions allow enabling, disabling and clearing

+    interrupt defined as part of the sampling sequence. These functions also allow

+    controlling interrupts generated by the ADCs.

+

+    

+  Comparators control

+    The ACE driver provides a set of functions for managing interrupts generated based

+    on the change of state of the high speed comparators. Functions are also provided

+    to dynamically modify the comparators configuration.

+

+    

+  Sigma Delta Digital to Analog Converters (SDD) control

+    The ACE driver provides functions for controlling the output value of the Sigma

+    Delta DACs (SDD). Functions are also provided for dynamically adjusting the

+    configuration of the SDDs.

+

+ *//*=========================================================================*/

+#ifndef __MSS_ACE_H_

+#define __MSS_ACE_H_

+

+#include <stdint.h>

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+#include "../../drivers_config/mss_ace/ace_handles.h"

+

+/*-------------------------------------------------------------------------*//**

+  Analog to Digital Converter channel IDs.

+  This enumeration is used to identify the ADC's analog inputs. It caters for up

+  to three ADCs/Analog Modules as can be found on the larger parts of the

+  SmartFusion family. The channel ID numbering is designed to allow easy

+  extraction of the ADC number and also the individual ADC input number by simple

+  shifting and masking. This enumeration is used as parameter to the

+  ACE_get_input_channel_handle() function retrieving the channel handle associated

+  with a specific analog input signal.

+ */

+typedef enum

+{

+    ADC0_1P5V = 0,        /*!< Analog Module 0, 1.5V/GND */

+    ABPS0 = 1,            /*!< Analog Module 0, Quad0 Active Bipolar Pre-Scaler input 1 */

+    ABPS1 = 2,            /*!< Analog Module 0, Quad0 Active Bipolar Pre-Scaler input 2 */

+    CM0 = 3,              /*!< Analog Module 0, Quad0 Current Monitor Block */

+    TM0 = 4,              /*!< Analog Module 0, Quad0 Temperature Monitor Block */

+    ABPS2 = 5,            /*!< Analog Module 0, Quad1 Active Bipolar Pre-Scaler input 1 */

+    ABPS3 = 6,            /*!< Analog Module 0, Quad1 Active Bipolar Pre-Scaler input 2 */

+    CM1 = 7,              /*!< Analog Module 0, Quad1 Current Monitor Block */

+    TM1 = 8,              /*!< Analog Module 0, Quad1 Temperature Monitor Block */

+    ADC0 = 9,             /*!< Analog Module 0 Direct Input 0 */

+    ADC1 = 10,            /*!< Analog Module 0 Direct Input 1 */

+    ADC2 = 11,            /*!< Analog Module 0 Direct Input 2 */

+    ADC3 = 12,            /*!< Analog Module 0 Direct Input 3 */

+    SDD0_IN = 15,         /*!< Analog Module 0 Sigma-Delta DAC output */

+

+    ADC1_1P5V = 16,       /*!< Analog Module 1, 1.5V/GND */

+    ABPS4 = 17,           /*!< Analog Module 1, Quad0 Active Bipolar Pre-Scaler input 1 */

+    ABPS5 = 18,           /*!< Analog Module 1, Quad0 Active Bipolar Pre-Scaler input 2 */

+    CM2 = 19,             /*!< Analog Module 1, Quad0 Current Monitor Block */

+    TM2 = 20,             /*!< Analog Module 1, Quad0 Temperature Monitor Block */

+    ABPS6 = 21,           /*!< Analog Module 1, Quad1 Active Bipolar Pre-Scaler input 1 */

+    ABPS7 = 22,           /*!< Analog Module 1, Quad1 Active Bipolar Pre-Scaler input 2 */

+    CM3 = 23,             /*!< Analog Module 1, Quad1 Current Monitor Block */

+    TM3 = 24,             /*!< Analog Module 1, Quad1 Temperature Monitor Block */

+    ADC4 = 25,            /*!< Analog Module 1 Direct Input 0 */

+    ADC5 = 26,            /*!< Analog Module 1 Direct Input 1 */

+    ADC6 = 27,            /*!< Analog Module 1 Direct Input 2 */

+    ADC7 = 28,            /*!< Analog Module 1 Direct Input 3 */

+    SDD1_IN = 31,         /*!< Analog Module 1 Sigma-Delta DAC output */

+

+    ADC2_1P5V = 32,       /*!< Analog Module 2, 1.5V/GND */

+    ABPS8 = 33,           /*!< Analog Module 2, Quad0 Active Bipolar Pre-Scaler input 1 */

+    ABPS9 = 34,           /*!< Analog Module 2, Quad0 Active Bipolar Pre-Scaler input 2 */

+    CM4 = 35,             /*!< Analog Module 2, Quad0 Current Monitor Block */

+    TM4 = 36,             /*!< Analog Module 2, Quad0 Temperature Monitor Block */

+    ABPS10 = 37,          /*!< Analog Module 2, Quad1 Active Bipolar Pre-Scaler input 1 */

+    ABPS11 = 38,          /*!< Analog Module 2, Quad1 Active Bipolar Pre-Scaler input 2 */

+    CM5 = 39,             /*!< Analog Module 2, Quad1 Current Monitor Block */

+    TM5 = 40,             /*!< Analog Module 2, Quad1 Temperature Monitor Block */

+    ADC8 = 41,            /*!< Analog Module 2 Direct Input 0 */

+    ADC9 = 42,            /*!< Analog Module 2 Direct Input 1 */

+    ADC10 = 43,           /*!< Analog Module 2 Direct Input 2 */

+    ADC11 = 44,           /*!< Analog Module 2 Direct Input 3 */

+    SDD2_IN = 47,         /*!< Analog Module 2 Sigma-Delta DAC output */

+    INVALID_CHANNEL = 255 /*!< Used to indicate errors */

+} adc_channel_id_t;

+

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_init() function initializes the SmartFusion MSS ACE driver. It

+  initializes the ACE driver’s internal data structures. The ACE_init() function

+  must be called before any other MSS ACE driver functions can be called.

+ */

+void ACE_init( void );

+

+

+/*==============================================================================

+ ============== Direct Analog Block Configuration and Usage ====================

+ =============================================================================*/

+ 

+/*=========================================================================*//**

+  @defgroup group1 Direct Analog Block Configuration and Usage

+  These functions are intended for using the SmartFusion analog block hardware

+  without relying on the Sampling Sequence Engine or Post Processing engine.

+  @{

+ *//*=========================================================================*/

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_start_adc() function initiates the sampling of the analog input

+  channel identified by the channel_id parameter. This function is provided for

+  test purposes. It must not be used while the Sample Sequencing Engine is

+  running.

+  

+  @param channel_id

+    The channel_id parameter identifies the analog input channel to sample.

+    

+  @return

+    This function does not return a value.

+ */

+void ACE_start_adc

+(

+	adc_channel_id_t channel_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_adc_result () function reads the result of the last input channel

+  sampling performed by the ADC identified as parameter.

+  

+  @param adc_id

+    The adc_id parameter identifies which of the possible three ADC to read the

+    sample result from.

+    

+  @return

+    The ACE_start_adc_sync() function returns the ADC result from the ADC

+    specified as parameter.

+ */

+uint16_t ACE_get_adc_result

+(

+    uint8_t adc_id

+);

+

+/** @} */

+

+/*==============================================================================

+ =========== Sigma Delta Digital to Analog Converters (SDD) Control ============

+ =============================================================================*/

+/*=========================================================================*//**

+  @defgroup group2 Sigma Delta Digital to Analog Converters (SDD) Control

+  The following functions are used to control the Sigma Delta DACs included

+  within the SmartFusion analog block.

+  @{

+ *//*=========================================================================*/

+

+/*-------------------------------------------------------------------------*//**

+  The sdd_id_t enumeration is used to identify the Sigma Delta DACs to the SDD

+  control functions, ACE_configure_sdd(), ACE_enable_sdd(), ACE_disable_sdd()

+  and ACE_set_sdd_value(). There is one SDD per analog module. 

+ */

+typedef enum

+{

+    SDD0_OUT = 0,    /*!< Analog Module 0 Sigma Delta DAC */

+    SDD1_OUT = 1,    /*!< Analog Module 1 Sigma Delta DAC */

+    SDD2_OUT = 2,    /*!< Analog Module 2 Sigma Delta DAC */

+    NB_OF_SDD = 3

+} sdd_id_t;

+

+/*-------------------------------------------------------------------------*//**

+  The sdd_resolution_t enumeration is used as a parameter to the

+  ACE_configure_sdd() function to specify DAC resolution of the Sigma Delta DAC. 

+ */

+typedef enum

+{

+    SDD_8_BITS = 0,

+    SDD_16_BITS = 4,

+    SDD_24_BITS = 8

+} sdd_resolution_t;

+

+/*-------------------------------------------------------------------------*//**

+  These constant definitions are used as an argument to the ACE_configure_sdd()

+  function to specify operating mode of the Sigma Delta DAC.

+ */

+#define SDD_CURRENT_MODE    1

+#define SDD_VOLTAGE_MODE    0

+#define SDD_RETURN_TO_ZERO  0

+#define SDD_NON_RTZ         2

+

+/*-------------------------------------------------------------------------*//**

+  The sdd_update_method_t enumeration is used as a parameter to the

+  ACE_configure_sdd() function to specify individual or synchronous updating of

+  the Sigma Delta DACs.

+ */

+typedef enum

+{

+    INDIVIDUAL_UPDATE = 0,

+    SYNC_UPDATE = 1

+} sdd_update_method_t;

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_configure_sdd() function is used to configure the operating mode of

+  the Sigma Delta DAC (SDD) specified as parameter. It allows selecting whether the

+  SDD will output a voltage or a current. A current between 0 and 256uA is

+  generated in current mode. A voltage between 0 and 2.56V is generated in

+  voltage mode.

+  This function also allows selecting whether Return To Zero (RTZ) mode is

+  enabled or not. Enabling Return To Zero mode improves linearity of the SDD

+  output at the detriment of accuracy. This mode should be used if linearity is

+  more important than accuracy.

+  A call to this function is not required if relying on the configuration

+  selected in the ACE configurator being loaded after reset by the system boot.

+  

+  @param sdd_id

+    The sdd_id parameter specifies which Sigma Delta DAC is configured by this

+    function. Allowed values are:

+        - SDD0_OUT

+        - SDD1_OUT

+        - SDD2_OUT

+  

+  @param resolution

+    The resolution parameter specifies the desired resolution of the Sigma Delta DAC.

+    Allowed values are:

+        - SDD_8_BITS

+        - SDD_16_BITS

+        - SDD_24_BITS

+  

+  @param mode

+    The mode parameter specifies the operating mode of the Sigma Delta DAC. It

+    specifies whether a current or voltage should be generated and whether

+    Return to Zero mode should be used. It is a logical OR of the following

+    defines:

+        - SDD_CURRENT_MODE

+        - SDD_VOLTAGE_MODE

+        - SDD_RETURN_TO_ZERO

+        - SDD_NON_RTZ

+  

+  @param sync_update

+    The sync_update parameter specifies whether the SDD output will be updated

+    individually though a call to ACE_set_sdd_value() or synchronously with one

+    or more other SDD outputs via a call to ACE_set_sdd_value_sync().

+

+  Example

+  @code

+    ACE_configure_sdd

+    (

+        SDD1_OUT,

+        SDD_24_BITS,

+        SDD_VOLTAGE_MODE | SDD_RETURN_TO_ZERO,

+        INDIVIDUAL_UPDATE

+    );

+  @endcode

+ */

+void ACE_configure_sdd

+(

+	sdd_id_t            sdd_id,

+	sdd_resolution_t    resolution,

+    uint8_t             mode,

+    sdd_update_method_t sync_update

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_enable_sdd() function is used to enable a Sigma Delta DAC. 

+  

+  @param sdd_id

+    The sdd_id parameter specifies the Sigma Delta DAC to enable.

+ */

+void ACE_enable_sdd

+(

+	sdd_id_t    sdd_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_disable_sdd() function is used to disable a Sigma Delta DAC.

+  

+  @param sdd_id

+    The sdd_id parameter specifies the Sigma Delta DAC to disable.

+ */

+void ACE_disable_sdd

+(

+	sdd_id_t    sdd_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_set_sdd_value() function is used to set the value of the output of

+  a Sigma Delta DAC. It uses the ACE's phase accumulator to generate the one bit

+  input bit stream into the SDD which will in turn define the voltage or

+  current generated at the SDD output.

+  The SDD output is proportional to the sdd_value passed to this function taking

+  the SDD resolution into account. A maximum voltage of 2.56V or a maximum

+  current of 256uA will be generated when the sdd_value is set the maximum value

+  allowed by the SDD resolution

+  

+  @param sdd_id

+    The sdd_id parameter specifies which Sigma Delta DAC is being set.

+  

+  @param sdd_value

+    The sdd_value parameter specifies the value of the Sigma Delta DAC output.

+    It is a fraction of SDD resolution. The voltage/current value generated from

+    the sdd_value paramenter can be determined using the following equation where

+    sdd_resolution is the resolution of the SDD as set through function

+    ACE_configure_sdd() and sdd_rangSDD configuration:

+        sdd_output = (sdd_value / sdd_resolution) * sdd_range

+ */

+void ACE_set_sdd_value

+(

+	sdd_id_t    sdd_id,

+	uint32_t    sdd_value

+);

+

+

+/*-------------------------------------------------------------------------*//**

+  This constant definition is used as an argument to the ACE_set_sdd_value_sync()

+  function to specify that the output value of SDD0, or SDD1, or SDD2 should not

+  be modified.

+ */

+#define SDD_NO_UPDATE   0xFFFFFFFF

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_set_sdd_value_sync() function is used to synchronize the update of

+  multiple Sigma Delta DAC outputs.

+

+  @param sdd0_value

+    The sdd0_value parameter specifies the value that will be used to set the

+    output of SDD0.

+    The define SDD_NO_UPDATE can be used to specify that the output value of

+    SDD0 should not be modified.

+

+  @param sdd1_value

+    The sdd1_value parameter specifies the value that will be used to set the

+    output of SDD1.

+    The define SDD_NO_UPDATE can be used to specify that the output value of

+    SDD1 should not be modified.

+

+  @param sdd2_value

+    The sdd2_value parameter specifies the value that will be used to set the

+    output of SDD2.

+    The define SDD_NO_UPDATE can be used to specify that the output value of

+    SDD2 should not be modified.

+

+  For example the code below will change the output value of SDD0 and SDD2 so

+  that the voltage/current generate by SDD0 and ADD2 will change at the same

+  time. This function call will not affect the output value of SDD1.

+  @code

+    uint32_t sdd0_value = 0x1234;

+    uint32_t sdd2_value = 0x5678;

+    ACE_set_sdd_value_sync( sdd0_value, SDD_NO_UPDATE, sdd2_value );

+  @endcode

+ */

+

+void ACE_set_sdd_value_sync

+(

+    uint32_t sdd0_value,

+    uint32_t sdd1_value,

+    uint32_t sdd2_value

+);

+

+/** @} */

+

+/*==============================================================================

+ ============ Reading Samples from post processing engine (PPE) ================

+ =============================================================================*/

+/*=========================================================================*//**

+  @defgroup group9 Reading Analog Input Channels Values and Properties

+  The following functions are used to access analog input channels properties

+  and sampled values.

+  @{

+ *//*=========================================================================*/

+

+/*-------------------------------------------------------------------------*//**

+  This constant returned by the ACE_get_flag_channel(), ACE_get_channel_handle()

+  and ACE_get_input_channel_handle() functions when the driver can’t find a

+  valid handle for the ADC input channel.

+ */

+#define INVALID_CHANNEL_HANDLE      NB_OF_ACE_CHANNEL_HANDLES

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_channel_handle() function returns the channel handle associated

+  with an analog input channel name. The retrieved channel handle will be

+  subsequently used as parameter to function ACE_get_ppe_sample() used to read

+  the most recent post processed sample for the analog input identified through

+  the channel/service name passed as argument to this function.

+  

+  @param p_sz_channel_name

+    The p_sz_channel_name parameter is a zero-terminated string containing the

+    name of the channel/service as entered in the ACE configurator.

+    

+  @return

+    This function returns a channel handle. This channel handle is required as

+    parameter to function ACE_get_ppe_sample().

+    It will return INVALID_CHANNEL_HANDLE if the channel/service name is not

+    recognized.

+    

+  @code

+    uint16_t adc_result;

+    ace_channel_handle_t at0;

+    at0 = ACE_get_channel_handle("VoltageMonitorAT0");

+    adc_result = ACE_get_ppe_sample( at0 );

+  @endcode

+ */

+ace_channel_handle_t

+ACE_get_channel_handle

+(

+    const uint8_t * p_sz_channel_name

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_input_channel_handle() function returns the channel handle for

+  the hardware analog input channel specified as parameter.

+  

+  @param channel_id

+    The channel_id parameter identifies a hardware analog input of the ACE.

+  

+  @return

+    This function returns a channel handle. This channel handle is required as

+    parameter to other ACE driver functions dealing with analog inputs.

+    It will return INVALID_CHANNEL_HANDLE if the channel ID passed as parameter

+    is invalid.

+ */

+ace_channel_handle_t

+ACE_get_input_channel_handle

+(

+    adc_channel_id_t    channel_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_ppe_sample() function is used to read the most recent post

+  processed sample for the analog input channel associated with the channel

+  handle passed as parameter.

+  

+  @param channel_handle

+    The channel_handle parameter identifies the analog input channel for which

+    this function will return the most recent ADC conversion result adjusted for

+    calibration and user provided coefficients as provided through the ACE

+    configurator. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+  

+  @return

+    This function returns a 16 bit value representing the adjusted value of the

+    ADC conversion result for the analog input channel identified by the channel

+    handle passed as parameter. The return value is actually a 12, 10 or 8 bits

+    number depending on the configuration of the ADC.

+    

+  @code

+    uint16_t adc_result;

+    ace_channel_handle_t at0;

+    at0 = ACE_get_channel_handle("VoltageMonitorAT0");

+    adc_result = ACE_get_ppe_sample( at0 );

+  @endcode

+ */

+uint16_t

+ACE_get_ppe_sample

+(

+    ace_channel_handle_t channel_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_channel_name() function provides the name of the channel

+  associated with the channel handle passed as parameter. The channel name is

+  the name used in the ACE configurator software tool when adding a service to

+  the ACE.

+  

+  @param channel_handle

+    The channel_handle parameter identifies the analog input channel for which

+    we want to retrieve the channel name. The available channel handle values can

+    be found in the ace_handles.h file located in the ./drivers_config/mss_ace

+    subdirectory. The channel handle value can also be retrieved through a call

+    to ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @return

+    This function returns a pointer to a zero-terminated string containing the

+    name of the channel. It returns 0 if the channel handle passed as parameter

+    is not recognized.

+ */

+const uint8_t * ACE_get_channel_name

+(

+    ace_channel_handle_t    channel_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The channel_type_t enumeration is used to identify the type of quantity

+  measured by an analog input channel. It is typically used to figure out the

+  type of conversion that must be applied to the ADC value generated from

+  sampling a channel in order to yield real world units such millivolts,

+  milliamps or degrees.

+ */

+typedef enum

+{

+    VOLTAGE,

+    CURRENT,

+    TEMPERATURE

+} channel_type_t;

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_channel_type() function returns the type of input channel of the

+  analog input channel identified by the channel handle passed as parameter.

+  This function allows determining whether the quantity measured through the ADC

+  is a voltage, current or temperature.

+  

+  @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the .\drivers_config\mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+  

+  @return

+    This function returns one of the following values to report the type of

+    quantity measure throught the channel:

+        - VOLTAGE

+        - CURRENT

+        - TEMPERATURE

+ */

+channel_type_t

+ACE_get_channel_type

+(

+    ace_channel_handle_t    channel_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_channel_count() function returns the total number of configured

+  analog input channels. It is the number of channels available for use as

+  opposed to the theorical number of physical channels supported by the device.

+  

+  @return

+    The ACE_get_channel_count() function returns the total number of input

+    channels that were configured in the ACE configurator.

+    The ACE_get_channel_count() function returns 0 if no input channels were

+    configured.

+    

+  @code

+    uint32_t inc;

+    uint32_t nb_of_channels;

+    ace_channel_handle_t current_channel;

+    

+    nb_of_channels = ACE_get_channel_count();

+    current_channel = ACE_get_first_channel();

+    

+    for (inc = 0; inc < nb_of_channels; ++inc)

+    {

+        adc_result = ACE_get_ppe_sample( current_channel );

+        display_value( current_channel, adc_result );

+        current_channel = ACE_get_next_channel( current_channel );

+    }

+  @endcode

+ */

+uint32_t

+ACE_get_channel_count

+(

+    void

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_first_channel() function returns the channel handle of one of the

+  channel controlled by the ACE. This function is used to start iterating though

+  the list of analog input channels handled by the ACE.

+  

+  @return

+    The ACE_get_first_channel() function returns the first channel handle found

+    in the ACE driver's internal channel handles list or INVALID_CHANNEL_HANDLE

+    if there are no channels defined in the ACE configuration.

+    

+  @code

+    uint32_t inc;

+    uint32_t nb_of_channels;

+    ace_channel_handle_t current_channel;

+    

+    nb_of_channels = ACE_get_channel_count();

+    current_channel = ACE_get_first_channel();

+    

+    for (inc = 0; inc < nb_of_channels; ++inc)

+    {

+        adc_result = ACE_get_ppe_sample( current_channel );

+        display_value( current_channel, adc_result );

+        current_channel = ACE_get_next_channel( current_channel );

+    }

+  @endcode

+ */

+ace_channel_handle_t

+ACE_get_first_channel

+(

+    void

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_next_channel() returns the channel handle of the channel following

+  the one passed as parameter. This function is used to iterate through the list

+  of analog input channels handled by the ACE.

+  

+  @param channel_handle

+    The channel_handle parameter identifies from which channel the driver should

+    look in its channel handle list to return the next channel handle. The

+    channel_handle parameter would typically be the channel handle returned by a

+    call to ACE_get_first_channel() or a previous call to ACE_get_next_channel().

+    Note:

+      The first call to ACE_get_next_channel() would typically use the

+      channel_handle returned by a previous call to ACE_get_first_channel(). The

+      second and subsequent calls to ACE_get_next_channel() would typically use

+      the channel_handle returned by a previous call to ACE_get_next_channel().

+  

+  @return

+    The ACE_get_next_channel() function returns the channel handle of the channel

+    following the one passed as parameter or INVALID_CHANNEL_HANDLE if the end of

+    the channels list has been reached.

+    

+  @code

+    uint32_t inc;

+    uint32_t nb_of_channels;

+    ace_channel_handle_t current_channel;

+    

+    nb_of_channels = ACE_get_channel_count();

+    current_channel = ACE_get_first_channel();

+    

+    for (inc = 0; inc < nb_of_channels; ++inc)

+    {

+        adc_result = ACE_get_ppe_sample( current_channel );

+        display_value( current_channel, adc_result );

+        current_channel = ACE_get_next_channel( current_channel );

+    }

+  @endcode

+ */

+ace_channel_handle_t

+ACE_get_next_channel

+(

+    ace_channel_handle_t channel_handle

+);

+

+ /** @} */

+

+/*==============================================================================

+ =============================== SSE Control ==================================

+ =============================================================================*/

+/*=========================================================================*//**

+  @defgroup group3 Sample Sequencing Engine Control

+  Sample Sequencing Engine control.

+  @{

+ *//*=========================================================================*/

+

+/*-------------------------------------------------------------------------*//**

+  The Sample Sequencing Engine control functions use a parameter of this type as

+  a handle to identify the Sample Sequencing Engine (SSE) sequences configured

+  using the ACE configurator. The ACE_get_sse_seq_handle() function retrieves the

+  handle of the SSE sequence identified by the sequence name passed as parameter.

+  Note: The ACE configurator generates ACE driver configuration files into the

+        .\drivers_config\mss_ace folder of the firmware project. These files

+        contain the details of the SSE sequence handles for your ACE configuration.

+        The ACE driver automatically includes these files when the

+        .\drivers_config\mss_ace folder is present in the firmware project.

+ */

+typedef uint16_t sse_sequence_handle_t;

+

+/*-------------------------------------------------------------------------*//**

+  This constant is returned by the ACE_get_sse_seq_handle() function when the

+  driver can’t find a valid handle for the Sample Sequencing Engine (SSE) sequence.

+*/

+#define INVALID_SSE_SEQ_HANDLE      0xFFFFu

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_sse_seq_handle() function retrieves the handle of the Sample

+  Sequencing Engine sequence identified by the sequence name passed as parameter.

+  The sequence handler can then be used as parameter to other SSE sequence control

+  functions to identify the sequence to control.

+  

+  @param p_sz_sequence_name

+    The p_sz_sequence_name parameter is a pointer to a zero-terminated string

+    containing the name of the sampling sequence for which we want to retrieve

+    the handle.

+    

+  @return

+    The ACE_get_sse_seq_handle() function returns the handle used to identify

+    the sequence passed as parameter with other ACE driver sampling sequence

+    control functions. It returns INVALID_SSE_SEQ_HANDLE if the sequence name

+    passed as parameter is not recognized.

+    

+  @code

+    sse_sequence_handle_t sse_seq_handle;

+    sse_seq_handle = ACE_get_sse_seq_handle("ProcedureA");

+    if ( sse_seq_handle != INVALID_SSE_SEQ_HANDLE )

+    {

+        ACE_load_sse( sse_seq_handle );

+        ACE_start_sse( sse_seq_handle );

+    }

+  @endcode

+ */

+sse_sequence_handle_t

+ACE_get_sse_seq_handle

+(

+    const uint8_t * p_sz_sequence_name

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_load_sse() function loads the ACE Sample Sequencing Engine (SSE) RAM

+  with the microcode implementing the sampling sequence identified by the SSE

+  sequence handler passed as parameter.

+  

+  @param sequence

+    The sequence parameter is the SSE sequence handler identifying the sampling

+    sequence to load into the ACE SSE. The value for this handler is retrieved

+    through a call to function ACE_get_sse_seq_handle().

+ */

+void ACE_load_sse

+(

+    sse_sequence_handle_t  sequence

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_start_sse() function causes the Sampling Sequence Engine (SSE) to start

+  executing the sequence identified by the sequence handler passed as parameter.

+  It causes the initiailization part of the sampling sequence to be executed

+  before the loop part of the sequence is started.

+  You must ensure that the sampling sequence has been loaded into the ACE's SSE

+  before calling this function.

+  

+  @param sequence

+    The sequence parameter is the SSE sequence handler identifying the sampling

+    sequence to load into the ACE SSE. The value for this handler is retrieved

+    through a call to function ACE_get_sse_seq_handle().

+ */

+void ACE_start_sse

+(

+    sse_sequence_handle_t  sequence

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_restart_sse() function restarts the loop part of the sampling sequence

+  loaded into the ACE's Sampling Sequence Engine (SSE). The sampling sequence

+  will be restarted from the beginning of the sequence but omiting the

+  intialization phase of the sequence.

+  This function would typically be called after stopping the sampling sequence

+  using the ACE_stop_see() function or with non-repeating sequences.

+  

+  @param sequence

+    The sequence parameter is the SSE sequence handler identifying the sampling

+    sequence to load into the ACE SSE. The value for this handler is retrieved

+    through a call to function ACE_get_sse_seq_handle().

+ */

+void ACE_restart_sse

+(

+    sse_sequence_handle_t  sequence

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_stop_sse() function stops execution of the Sample Sequencing Engine

+  (SSE) sequence indentified by the sequence handle passed as parameter.

+  

+  @param sequence

+    The sequence parameter is the SSE sequence handle identifying the sampling

+    sequence to load into the ACE SSE. The value for this handler is retrieved

+    through a call to function ACE_get_sse_seq_handle().

+ */

+void ACE_stop_sse

+(

+    sse_sequence_handle_t  sequence

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_resume_sse() function causes the Sampling Sequencing Engine (SSE)

+  sampling sequence identified by the sequence handle passed as parameter to

+  resume execution. This function is typically used to restart execution of

+  a sequence at the point where it was stopped through a call to ACE_stop_sse().

+  

+  @param sequence

+    The sequence parameter is the SSE sequence handler identifying the sampling

+    sequence to load into the ACE SSE. The value for this handler is retrieved

+    through a call to function ACE_get_sse_seq_handle().

+ */

+void ACE_resume_sse

+(

+    sse_sequence_handle_t  sequence

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_clear_sample_pipeline() function clears the ACE hardware of samples

+  being processed. It clear the various stages involved in the production of

+  post processed samples within the ACE hardware. It is intended for use when

+  switching between sampling sequences and using peripheral DMA. It avoids

+  receiving stale samples generated as a result of a previous sampling sequence.

+  

+  The example below shows how this function can be used to ensure that no sample

+  generated as a result of sampling sequence sequence_a will be generated once

+  sampling sequence_b is started. Please note that it is important to stop the

+  SSE using function ACE_stop_sse() before calling ACE_clear_sample_pipeline()

+  to ensure sequence_a is not restarted after the sample pipeline is cleared.

+  @code

+    ACE_stop_sse(sequence_a);

+    ACE_clear_sample_pipeline();

+    ACE_start_sse(sequence_b);

+  @endcode

+    

+  The example below shows how to ensure that the first sample read through PDMA

+  will be from the first channel in the sampling sequence.

+  @code

+    ACE_stop_sse(sequence_a);

+    ACE_clear_sample_pipeline();

+    ACE_restart_sse(sequence_a);

+    PDMA_start

+      (

+        PDMA_CHANNEL_0, 

+        PDMA_ACE_PPE_DATAOUT, 

+        (uint32_t)g_samples_buffer[g_pdma_buffer_idx], 

+        SAMPLES_BUFFER_SIZE

+      );

+  @endcode

+ */

+void ACE_clear_sample_pipeline(void);

+

+/** @} */

+/*==============================================================================

+ ======================== SSE Interrupts Control ===============================

+ =============================================================================*/

+/*=========================================================================*//**

+  @defgroup group4 Sample Sequencing Engine Interrupts Control

+  The following functions are used to control interrupts generated from the

+  ACE's Sample Sequencing Engine. These interrupts would typically be used to

+  detect when valid data is available from the ADCs controlled by the SSE or to

+  detect the complete or partial completion of the sampling sequence through the

+  insertion of SSE program counter general purpose interrupt assertion as part

+  of the sequence.

+  @{

+ *//*=========================================================================*/

+

+/*-------------------------------------------------------------------------*//**

+  The sse_irq_id_t enumeration is used to identify the Sample Sequencing Engine

+  (SSE) interrupt sources to the SSE interrupt control functions.

+ */

+typedef enum

+{

+    PC0_FLAG0 = 0,

+    PC0_FLAG1 = 1,

+    PC0_FLAG2 = 2,

+    PC0_FLAG3 = 3,

+    PC1_FLAG0 = 4,

+    PC1_FLAG1 = 5,

+    PC1_FLAG2 = 6,

+    PC1_FLAG3 = 7,

+    PC2_FLAG0 = 8,

+    PC2_FLAG1 = 9,

+    PC2_FLAG2 = 10,

+    PC2_FLAG3 = 11,

+    ADC0_DATAVALID = 12,

+    ADC1_DATAVALID = 13,

+    ADC2_DATAVALID = 14,

+    ADC0_CALIBRATION_COMPLETE = 15,

+    ADC1_CALIBRATION_COMPLETE = 16,

+    ADC2_CALIBRATION_COMPLETE = 17,

+    ADC0_CALIBRATION_START = 18,

+    ADC1_CALIBRATION_START = 19,

+    ADC2_CALIBRATION_START = 20,

+    NB_OF_SSE_FLAG_IRQS = 21

+} sse_irq_id_t;

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_enable_sse_irq() function enables the Sample Sequencing Engine (SSE)

+  interrupt source specified as parameter to generate interrupts.

+  

+  @param sse_irq_id

+    The sse_irq_id parameter identifies the SSE interrupt source controlled by

+    this function.

+ */

+void ACE_enable_sse_irq

+(

+	sse_irq_id_t sse_irq_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_disable_sse_irq() function disables the Sample Sequencing Engine

+  (SSE) interrupt source specified as parameter from generating interrupts.

+  

+  @param sse_irq_id

+    The sse_irq_id parameter identifies the SSE interrupt source controlled by

+    this function.

+ */

+void ACE_disable_sse_irq

+(

+	sse_irq_id_t sse_irq_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_clear_sse_irq() function clears the Sampling Sequencing Engine (SSE)

+  interrupt specified as parameter.

+  

+  @param sse_irq_id

+    The sse_irq_id parameter identifies the SSE interrupt source controlled by

+    this function.

+ */

+void ACE_clear_sse_irq

+(

+	sse_irq_id_t sse_irq_id

+);

+

+/** @} */

+/*==============================================================================

+ ============================ Comparators Control ==============================

+ =============================================================================*/

+/*=========================================================================*//**

+  @defgroup group5 Comparators Control

+  The following functions are used to control the analog comparators included

+  in the SmartFusion analog block.

+  The comparator configuration functions can be used to directly configure the

+  comparators. Their use is only required when the ACE is not configured using

+  the ACE configurator software tool.

+  The comparator interrupt control functions are used regardless of the way the

+  ACE was configured to enable, disable and clear interrupts generated when the

+  positive input of a comparator rises above or falls below the negative input.

+  @{

+ *//*=========================================================================*/

+

+/*-------------------------------------------------------------------------*//**

+  The comparator_id_t enumeration is used by the comparator control functions

+  to identify the analog comparators included in the SmartFusion analog block.

+ */

+typedef enum

+{

+    CMP0 = 0,                   /*!< Analog module 0, Quad 0, CMB comparator */

+    CMP1 = 1,                   /*!< Analog module 0, Quad 0, TMB comparator */

+    CMP2 = 2,                   /*!< Analog module 0, Quad 1, CMB comparator */

+    CMP3 = 3,                   /*!< Analog module 0, Quad 1, TMB comparator */

+    CMP4 = 4,                   /*!< Analog module 1, Quad 0, CMB comparator */

+    CMP5 = 5,                   /*!< Analog module 1, Quad 0, TMB comparator */

+    CMP6 = 6,                   /*!< Analog module 1, Quad 1, CMB comparator */

+    CMP7 = 7,                   /*!< Analog module 1, Quad 1, TMB comparator */

+    CMP8 = 8,                   /*!< Analog module 2, Quad 0, CMB comparator */

+    CMP9 = 9,                   /*!< Analog module 2, Quad 0, TMB comparator */

+    CMP10 = 10,                 /*!< Analog module 2, Quad 1, CMB comparator */

+    CMP11 = 11,                 /*!< Analog module 2, Quad 1, TMB comparator */

+    NB_OF_COMPARATORS = 12

+} comparator_id_t;

+

+/*-------------------------------------------------------------------------*//**

+  The comp_hysteresis_t enumeration is used by the ACE_set_comp_hysteresis()

+  function to set the hysteresis of the analog comparators included in the

+  SmartFusion analog block. This enumeration provides the allowed values of the

+  hysteresis parameter of the ACE_set_comp_hysteresis() function.

+ */

+typedef enum

+{

+    NO_HYSTERESIS = 0,

+    HYSTERESIS_10_MV = 1,

+    HYSTERESIS_30_MV = 2,

+    HYSTERESIS_100_MV = 3,

+    NB_OF_HYSTERESIS = 4

+} comp_hysteresis_t ;

+

+/*-------------------------------------------------------------------------*//**

+  The comp_reference_t enumeration is used by the ACE_set_comp_reference()

+  function to select the reference input of the odd numbered analog comparators

+  included in the SmartFusion analog block. This enumeration provides the allowed

+  values of the reference parameter of the ACE_set_comp_reference () function.

+ */

+typedef enum

+{

+    SDD0_COMP_REF = 0,

+    SDD1_COMP_REF = 1,

+    SDD2_COMP_REF = 2,

+    ADC_IN_COMP_REF = 3,

+    NB_OF_COMP_REF = 4

+} comp_reference_t;

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_set_comp_reference() function is used to select the reference input

+  of a temperature monitor block comparator. The reference input of a temperature

+  monitor can be an ADC direct input or one of the SDD's output.

+  

+  @param comp_id

+    The comp_id parameter specifies the comparator for which to select the

+    reference input. Since only temperature monitor block comparators have a 

+    selectable reference input, allowed values are:

+        - CMP1

+        - CMP3

+        - CMP5

+        - CMP7

+        - CMP9

+        - CMP11

+    

+  @param reference

+    The reference parameter specify the signal that will be used as reference

+    by the comparator. Allowed values are:

+        - SDD0_COMP_REF

+        - SDD1_COMP_REF

+        - SDD2_COMP_REF

+        - ADC_IN_COMP_REF

+ */

+void ACE_set_comp_reference

+(

+    comparator_id_t     comp_id,

+    comp_reference_t    reference

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_set_comp_hysteresis() function is used to set the hysteresis of a

+  comparator. There are four possible hystereris settings: no hysteresis,

+  +/-10mV, +/-30mV or +/-100mV.

+  

+  @param comp_id

+    The comp_id parameter specifies the comparator for which this function will

+    set the hyteresis.

+  

+  @param hysteresis

+    The hysteresis parameter specifies the hysteresis that will be applied to 

+    the comparator's input. Allowed values are:

+        - NO_HYSTERESIS

+        - HYSTERESIS_10_MV

+        - HYSTERESIS_30_MV

+        - HYSTERESIS_100_MV

+  

+ */

+void ACE_set_comp_hysteresis

+(

+	comparator_id_t     comp_id,

+    comp_hysteresis_t   hysteresis

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_enable_comp() function is used to enable the comparator specified as

+  parameter.

+  

+  @param comp_id

+    The comp_id parameter specifies which comparator will be enabled by a call

+    to this function.

+ */

+void ACE_enable_comp

+(

+	comparator_id_t comp_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_disable_comp() function is used to disable the comparator specified as

+  parameter.

+  

+  @param comp_id

+    The comp_id parameter specifies which comparator will be disabled by a call

+    to this function.

+ */

+void ACE_disable_comp

+(

+	comparator_id_t comp_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_enable_comp_rise_irq() function is used to enable interrupts to be

+  generated when the positive input of the comparator specified as parameter

+  rises above the negative input of the comparator.

+  The function prototypes for the comparator rise interrupt service routines are:

+    - void ACE_Comp0_Rise_IRQHandler( void );

+    - void ACE_Comp1_Rise_IRQHandler( void );

+    - void ACE_Comp2_Rise_IRQHandler( void );

+    - void ACE_Comp3_Rise_IRQHandler( void );

+    - void ACE_Comp4_Rise_IRQHandler( void );

+    - void ACE_Comp5_Rise_IRQHandler( void );

+    - void ACE_Comp6_Rise_IRQHandler( void );

+    - void ACE_Comp7_Rise_IRQHandler( void );

+    - void ACE_Comp8_Rise_IRQHandler( void );

+    - void ACE_Comp9_Rise_IRQHandler( void );

+    - void ACE_Comp10_Rise_IRQHandler( void );

+    - void ACE_Comp11_Rise_IRQHandler( void );

+  

+  @param comp_id

+    The comp_id parameter specifies which comparator will be enabled to generate

+    rising interrupts.

+ */

+void ACE_enable_comp_rise_irq

+(

+	comparator_id_t comp_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_disable_comp_rise_irq() function is used to disable interrupts from

+  being generated when the positive input of the comparator specified as parameter

+  rises above the negative input of the comparator.

+  

+  @param comp_id

+    The comp_id parameter specifies which comparator will be disabled from

+    generating rising interrupts.

+ */

+void ACE_disable_comp_rise_irq

+(

+	comparator_id_t comp_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_clear_comp_rise_irq() function is used to clear rise interrupts. This

+  function is typically called as part of the rise interrupt service routine.

+  

+  @param comp_id

+    The comp_id parameter specifies the comparator for which to clear the rise

+    interrupt.

+    

+  Example:

+  @code

+    void ACE_Comp1_Rise_IRQHandler( void )

+    {

+        process_rise_irq();

+        ACE_clear_comp_rise_irq( CMP1 );

+        NVIC_ClearPendingIRQ( ACE_Comp1_Rise_IRQn );

+    }

+  @endcode

+ */

+void ACE_clear_comp_rise_irq

+(

+	comparator_id_t comp_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_enable_comp_fall_irq() function is used to enable interrupts to be

+  generated when the positive input of the comparator specified as parameter

+  falls below the negative input of the comparator.

+  The function prototypes for the comparator fall interrupt service routines are:

+    - void ACE_Comp0_Fall_IRQHandler( void );

+    - void ACE_Comp1_Fall_IRQHandler( void );

+    - void ACE_Comp2_Fall_IRQHandler( void );

+    - void ACE_Comp3_Fall_IRQHandler( void );

+    - void ACE_Comp4_Fall_IRQHandler( void );

+    - void ACE_Comp5_Fall_IRQHandler( void );

+    - void ACE_Comp6_Fall_IRQHandler( void );

+    - void ACE_Comp7_Fall_IRQHandler( void );

+    - void ACE_Comp8_Fall_IRQHandler( void );

+    - void ACE_Comp9_Fall_IRQHandler( void );

+    - void ACE_Comp10_Fall_IRQHandler( void );

+    - void ACE_Comp11_Fall_IRQHandler( void );

+  

+  @param comp_id

+    The comp_id parameter specifies which comparator will be enabled to generate

+    fall interrupts.

+ */

+void ACE_enable_comp_fall_irq

+(

+	comparator_id_t comp_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_disable_comp_fall_irq() function is used to disable interrupts from

+  being generated when the positive input of the comparator specified as parameter

+  falls below the negative input of the comparator.

+  

+  @param comp_id

+    The comp_id parameter specifies which comparator will be disabled from

+    generating fall interrupts.

+ */

+void ACE_disable_comp_fall_irq

+(

+	comparator_id_t comp_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_clear_comp_fall_irq() function is used to clear fall interrupts. This

+  function is typically called as part of the fall interrupt service routine.

+  

+  @param comp_id

+    The comp_id parameter specifies the comparator for which to clear the fall

+    interrupt.

+    

+  Example:

+  @code

+    void ACE_Comp1_Fall_IRQHandler( void )

+    {

+        process_fall_irq();

+        ACE_clear_comp_fall_irq( CMP1 );

+        NVIC_ClearPendingIRQ( ACE_Comp1_Fall_IRQn );

+    }

+  @endcode

+ */

+void ACE_clear_comp_fall_irq

+(

+	comparator_id_t comp_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_comp_status() function returns the current comparator interrupt

+  status. It returns a 32 bit value indicating which comparators experienced a

+  fall and/or rise event. These status bits can be cleared using the

+  ACE_clear_comp_rise_irq() and ACE_clear_comp_fall_irq() functions.

+  

+  @return

+    The return value is a 32 bit numnber where bits 0 to 11 indicate which

+    comparator experienced a fall event and bits 21 to 23 indicate which

+    comparator experienced a rise event.

+ */

+uint32_t ACE_get_comp_status( void );

+

+/** @} */

+

+/*==============================================================================

+ ========================== Controlling Thresholds =============================

+ =============================================================================*/

+/*=========================================================================*//**

+  @defgroup group8 Controlling Flags Thresholds

+  The following functions are used to dynamically control Post Processing Engine

+  (PPE) flags threshholds.

+  @{

+ *//*=========================================================================*/

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_is_hysteresis_flag() function indicates if an hysteresis is applied

+  to the analog input sample value when determining the state of the flag

+  identified as parameter.

+  

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+    

+  @return

+    This function returns the value one if a hysteresis is applied to the channel

+    sample values as part of determining the state of the flag identified as

+    parameter. It returns zero if no hysteresis is applied.

+ */

+uint32_t ACE_is_hysteresis_flag

+(

+    ace_flag_handle_t   flag_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_is_under_flag() function indicates whether a flag is triggered when the

+  monitored analog input falls below the flag's threshold level or above the

+  flag's threshold level.

+  

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+    

+  @return

+    This function returns the value one if the flag identified as parameter

+    triggers as a result of the monitored input falling below the flag's

+    threshold value.

+    It returns zero if the flag triggers as a result of the monitored input

+    exceeding the flag's threshold value.

+ */

+uint32_t ACE_is_under_flag

+(

+    ace_flag_handle_t   flag_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_set_flag_threshold() function is used to adjust the threshold for a

+  specific post processing engine generated flag. The flag is identified through

+  the name selected in the ACE configurator software tool.

+  This function will set a new flag’s threshold value while preserving the

+  hysteresis specified at configuration time or through a call to

+  ACE_set_flag_hysteresis(). For example, requesting a 1 volt threshold for an

+  over flag configured with a 100 millivolts hysteresis will result in the flag

+  being asserted when the voltage reaches 1.1 volts and deasserted when the

+  voltage falls below 0.9 volt.

+  

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the ./drivers_config/mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+  

+  @param new_threshold

+    The new_threshold parameter specifies the new threshold level that must be

+    reached in order for the flag to be raised. The value of this parameter is

+    the sample value resulting from a post processing engine conversion of the

+    desired analog input threshold level.

+    

+  Example:

+    The function below sets the threshold of the flag specified as parameter to

+    1 volt.

+  @code

+    void set_threshold_to_1V

+    (

+        ace_flag_handle_t flag_handle

+    )

+    {

+        uint16_t new_threshold;

+        ace_channel_handle_t channel_handle;

+    

+        channel_handle = ACE_get_flag_channel(flag_handle);

+        new_threshold = ACE_convert_from_mV(channel_handle, 1000);

+        ACE_set_flag_threshold(flag_handle, new_threshold);

+    }

+  @endcode

+ */

+void ACE_set_flag_threshold

+(

+    ace_flag_handle_t   flag_handle,

+    uint16_t            new_threshold

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_set_flag_hysteresis() function modifies the hysteresis applied to the

+  analog input channel sample values used to generate the flag specified as

+  parameter.

+

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+    

+  @param adc_hysteresis

+    The adc_hysteresis parameter is the value to add and subtract to the

+    threshold value to obtain the hysteresis high and low limits triggering flag

+    assertion and deassertion. The adc_hysteresis parameter is a PPE conversion

+    result offset.

+

+  Example

+    The example below demonstrates the use of the ACE_set_flag_hysteresis()

+    function to set a 100mV hysteresis on the OVER_1V flag of the VoltageMonitor

+    input channel. VoltageMonitor and OVER_1V are names selected in the ACE

+    configurator for one of the analog inputs and one of the flags associated

+    with that input.

+    The method used to compute the adc_hysteresis value will work for all

+    input types including ABPS inputs where zero Volts is not equivalent to a 

+    PPE sample value of zero.

+    

+  @code

+    ace_channel_handle_t channel_handle;

+    ace_flag_handle_t flag_handle;

+    uint16_t adc_hysteresis;

+    uint16_t upper_limit;

+    uint16_t lower_limit;

+    

+    channel_handle = VoltageMonitor;

+    flag_handle = VoltageMonitor_OVER_1V;

+    

+    upper_limit = ACE_convert_from_mV(channel_handle, 100);

+    lower_limit = ACE_convert_from_mV(channel_handle, 0);

+    

+    if (upper_limit > lower_limit)

+    {

+        adc_hysteresis = upper_limit - lower_limit;

+    }

+    else

+    {

+        adc_hysteresis = lower_limit - upper_limit;

+    }

+    

+    ACE_set_flag_hysteresis(flag_handle, adc_hysteresis);

+  @endcode

+ */

+void

+ACE_set_flag_hysteresis

+(

+    ace_flag_handle_t   flag_handle,

+    uint16_t            adc_hysteresis

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_set_flag_assertion() function sets the PPE sample value that must be

+  reached in order for the flag specified as parameter to become asserted. It is

+  used in conjunction with the ACE_set_flag_deassertion() function as an

+  alternative to the ACE_set_flag_threshold() and ACE_set_flag_hysteresis()

+  functions to set the hysteresis window of an hysteresis flag.

+  The ACE_set_flag_assertion() and ACE_set_flag_deassertion() functions are

+  intended to be used where the threshold value is not centered within the

+  hysteresis window. They allow specifying the actual threshold values at which

+  the flag will be asserted and deasserted.

+

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+    

+  @param assertion_value

+    The assertion_value parameter is the Post Processing Engine sample value that

+    must be reached for the flag, identified through the flag_handle parameter,

+    to become asserted. The PPE sample value is always a 12 bits sample value

+    regardless of the configuration of the ADC used to sample the input channel.

+ */

+void ACE_set_flag_assertion

+(

+    ace_flag_handle_t   flag_handle,

+    uint16_t            assertion_value

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_set_flag_deassertion() function sets the PPE sample value that must be

+  reached in order for the flag specified as parameter to become deasserted. It

+  is used in conjunction with the ACE_set_flag_assertion() function as an

+  alternative to the ACE_set_flag_threshold() and ACE_set_flag_hysteresis()

+  functions to set the hysteresis window of an hysteresis flag.

+  The ACE_set_flag_assertion() and ACE_set_flag_deassertion() functions are

+  intended to be used where the threshold value is not centered within the

+  hysteresis window. They allow specifying the actual threshold values at which

+  the flag will be asserted and deasserted.

+  

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+    

+  @param assertion_value

+    The assertion_value parameter is the Post Processing Engine sample value

+    that must be reached for the flag, identified through the flag_handle

+    parameter, to become de-asserted. The PPE sample value is always a 12 bits

+    sample value regardless of the configuration of the ADC used to sample the

+    input channel.

+ */

+void ACE_set_flag_deassertion

+(

+    ace_flag_handle_t   flag_handle,

+    uint16_t            assertion_value

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_set_channel_hysteresis() function sets the hysteresis applied to

+  analog input channel sample values when generating flags. It sets the

+  hysteresis for all flags generated based on the value of the analog input

+  channel identified by the channel handle passed as first parameter.

+  

+  @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in

+    the ace_handles.h file located in the .\drivers_config\mss_ace subdirectory.

+    The channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+

+  @param adc_hysteresis

+    The adc_hysteresis parameter is the value to add and subtract to the

+    threshold value to obtain the hysteresis high and low limits triggering flag

+    assertion and deassertion. The adc_hysteresis parameter is a PPE conversion

+    result offset.

+ */

+void

+ACE_set_channel_hysteresis

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                adc_hysteresis

+);

+

+

+/** @} */

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+ 

+/*==============================================================================

+ ================================== Flags ======================================

+ =============================================================================*/

+/*=========================================================================*//**

+  @defgroup group6 Post Processing Engine Flags

+  The following functions are used to control interrupts generated by the ACE's

+  Post Processing Engine (PPE) when monitored inputs rise above or fall below

+  thresholds specified in the ACE configurator software tool.

+  @{

+ *//*=========================================================================*/

+

+ /*-------------------------------------------------------------------------*//**

+   These constant definitions are the return values of the ACE_get_flag_status()

+   function. They specify the status of the Post Processing Engine (PPE) flag.

+  */

+#define UNKNOWN_FLAG        (int32_t)(-1)

+#define FLAG_ASSERTED       (int32_t)1

+#define FLAG_NOT_ASSERTED   (int32_t)0

+

+/*-------------------------------------------------------------------------*//**

+  This constant is returned by the ACE_get_flag_handle function when the driver

+  can’t find a valid handle for the Post Processing Engine (PPE) flag.

+ */

+#define INVALID_FLAG_HANDLE     NB_OF_ACE_FLAG_HANDLES

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_flag_handle() function returns the handle of the flag identified

+  by the flag name passed as parameter. The flag handle obtained through this

+  function is then used as parameter to other flag control functions to identify

+  which flag is to be controlled by the called function.

+  

+  @param p_sz_full_flag_name

+    The p_sz_full_flag_name parameter is a pointer to a zero-terminated string

+    holding the name of the flag as specified in the ACE configurator. The full

+    name of a flag contains both the name of the monitored input channel and the

+    name of the flag generated based the level of that input separated by ":".

+    For example, the full name for the flag called "CriticalOver" raised when

+    the input channel called "MainSupply" reaches a critical level would be

+    named "MainSupply:CriticalOver".

+    

+  @return

+    The ACE_get_flag_handle() returns the flag handle associated with the flag

+    name passed as parameter. It returns INVALID_FLAG_HANDLE when the flag name

+    is invalid and not recognized by the ACE driver.

+ */

+ace_flag_handle_t

+ACE_get_flag_handle

+(

+    const uint8_t * p_sz_full_flag_name

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_flag_status() function returns the current status of the flag

+  specified as parameter. The flag is identified through the name specified in

+  the ACE configurator when the flag was created.

+  

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+    

+   @return

+    The ACE_get_flag_status() function returns one of the following values

+    depending on the current status of the flag:

+        - FLAG_ASSERTED if the flag is raised/asserted.

+        - FLAG_NOT_ASSERTED if the flag is not asserted.

+        - UNKNOWN_FLAG if the flag name is not recognized by the driver.

+*/

+int32_t

+ACE_get_flag_status

+(

+    ace_flag_handle_t   flag_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_enable_channel_flags_irq() function enables all flags generated based

+  on the value of the analog input channel passed as parameter to generate

+  interrupts. Flags used to detect that thresholds are crossed by the value

+  sampled on the analog input channel identified as parameter are enabled to

+  generate interrupts by this function. It enables flag interrupts both at the

+  ACE PEE flag and Cortex-M3 interrupt controller levels.

+  

+  @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+ */

+void ACE_enable_channel_flags_irq

+(

+    ace_channel_handle_t channel_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_disable_channel_flags_irq() function disables all flags generated

+  based on the value of the analog input channel passed as parameter to generate

+  interrupts. Flags used to detect that thresholds are crossed by the value

+  sampled on the analog input channel identified as parameter are disabled from

+  generating interrupts by this function. The interrupt is only disabled at the

+  ACE PPE flag level in order to avoid disabling other cahnnel's flag interrupts

+  which may happen to use the same ACE threshold interrupt line.

+  

+  @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+ */

+void ACE_disable_channel_flags_irq

+(

+    ace_channel_handle_t channel_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_clear_channel_flags_irq() function clears all interrupts generated by

+  flags associated with the analog input channel passed as parameter. Interrupt

+  generated by flags used to detect that thresholds are crossed by the value

+  sampled on the analog input channel identified as parameter are cleared by

+  this function. This function would typically be used before enabling the flag

+  interrupts in order to ignore past events.

+  

+  @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+ */

+void ACE_clear_channel_flags_irq

+(

+    ace_channel_handle_t channel_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_enable_flag_irq() function enables the ACE post processing engine (PPE)

+  generated flags specified as parameter to interrupt the Cortex-M3 processor.

+  It enables flag interrupts both at the ACE PPE flag and Cortex-M3 interrupt

+  controller levels.

+  

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+ */

+void ACE_enable_flag_irq

+(

+    ace_flag_handle_t flag_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_disable_flag_irq() function disables ACE post processing engine (PPE)

+  generated flags from interrupting the Cortex-M3. The interrupt is only

+  disabled at the ACE PPE flag level in order to avoid disabling other flags

+  interrupts which may happen to use the same ACE threshold interrupt line.

+  

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+ */

+void ACE_disable_flag_irq

+(

+    ace_flag_handle_t flag_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_clear_flag_irq() function clears the interrupt for the flag specified

+  as parameter. This function would typically be used before enabling the flag

+  interrupt in order to ignore past events.

+  

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+ */

+void ACE_clear_flag_irq

+(

+    ace_flag_handle_t flag_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_flag_name() function returns the name of the flag identified by

+  the flag handle passed as parameter.

+  

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+    

+  @return

+    The ACE_get_flag_name() function returns a pointer to a zero-terminated

+    string containing the name of the flag identified by the flag handle passed

+    as parameter. It returns 0 if the flag handle passed as parameter is invalid.

+ */

+const uint8_t *

+ACE_get_flag_name

+(

+    ace_flag_handle_t flag_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_flag_channel() function returns the handle of the channel

+  monitored in order to generate the flag identified by the flag handle passed

+  as parameter.

+  

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+    

+  @return

+    The ACE_get_flag_channel() function returns a channel handle identifying the

+    analog input channel monitored by the flag passed as parameter.

+ */

+ace_channel_handle_t

+ACE_get_flag_channel

+(

+    ace_flag_handle_t flag_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_channel_flag_count() function returns the total number of flags

+  associated with the input channel specified by the channel_handle parameter.

+  It indicates how many flags are generated based on the value of the specified

+  analog input channel.

+    

+  @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in

+    the ace_handles.h file located in the .\drivers_config\mss_ace subdirectory.

+    The channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @return

+    The ACE_get_channel_flag_count() function returns the total number of flags

+    that are generated based on the value of the specified analog input channel.

+    The ACE_get_channel_flag_count() function returns 0 if no input channels were

+    configured.

+  

+  Example

+  @code

+    uint32_t inc;

+    uint32_t nb_of_flags;

+    uint16_t flag_iterator;

+    ace_flag_handle_t current_flag;

+    ace_channel_handle_t channel_handle;

+    

+    nb_of_flags = ACE_get_channel_flag_count(channel_handle);

+    current_flag = ACE_get_channel_first_flag(channel_handle, &flag_iterator);

+    

+    for (inc = 0; inc < nb_of_flags; ++inc)

+    {

+        current_flag = ACE_get_channel_next_flag(channel_handle, &flag_iterator);

+        display_flag_properties(current_flag);

+    }

+  @endcode

+  */

+uint32_t

+ACE_get_channel_flag_count

+(

+    ace_channel_handle_t    channel_handle

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_channel_first_flag() function retrieves the handle of the first

+  flag associated with the analog input channel identified by the channel handle

+  passed as parameter. It also initialises the value of the iterator variable

+  pointed to by the second function parameter. The iterator can be used

+  subsequently as a parameter to the ACE_get_channel_next_flag() function to

+  iterate through all flags associated with the analog input channel.

+  

+  @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory.

+    The channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param iterator

+    The iterator parameter is a pointer to a uint16_t iterator variable. The

+    value of the iterator variable will be set by the ACE_get_channel_first_flag()

+    functions so that it can be used in subsequent calls to

+    ACE_get_channel_next_flag() to keep track of the current location in the

+    list of flags associated with the analog input channel.

+    

+  @return

+    The ACE_get_channel_first_flag() function returns a flag handle identifying

+    one of the flags generated based on the value of the analog input channel

+    identified by the channel_handle parameter. It returns INVALID_FLAG_HANDLE

+    if no flags are generated based on the analog input channel input or if the

+    channel handle is invalid.

+    

+  Example

+  @code

+    uint32_t inc;

+    uint32_t nb_of_flags;

+    uint16_t flag_iterator;

+    ace_flag_handle_t current_flag;

+    ace_channel_handle_t channel_handle;

+    

+    nb_of_flags = ACE_get_channel_flag_count(channel_handle);

+    current_flag = ACE_get_channel_first_flag(channel_handle, &flag_iterator);

+    

+    for (inc = 0; inc < nb_of_flags; ++inc)

+    {

+        current_flag = ACE_get_channel_next_flag(channel_handle, &flag_iterator);

+        display_flag_properties(current_flag);

+    }

+  @endcode

+  */

+ace_flag_handle_t

+ACE_get_channel_first_flag

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t *              iterator

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_get_channel_next_flag() function retrieves the handle of a flag

+  associated with the analog input channel identified by the channel handle

+  passed as parameter. The retrieved flag handle is the next one in the driver's

+  internal flag list based on the iterator parameter.

+  

+  @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the .\drivers_config\mss_ace subdirectory.

+    The channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param iterator

+    The iterator parameter is a pointer to a uint16_t iterator variable. The value

+    of the iterator variable will be set by the ACE_get_channel_first_flag()

+    functions so that it can be used in subsequent calls to

+    ACE_get_channel_next_flag() to keep track of the current location in the list

+    of flags associated with the analog input channel.

+    

+  Example

+  @code

+    uint32_t inc;

+    uint32_t nb_of_flags;

+    uint16_t flag_iterator;

+    ace_flag_handle_t current_flag;

+    ace_channel_handle_t channel_handle;

+    

+    nb_of_flags = ACE_get_channel_flag_count(channel_handle);

+    current_flag = ACE_get_channel_first_flag(channel_handle, &flag_iterator);

+    

+    for (inc = 0; inc < nb_of_flags; ++inc)

+    {

+        current_flag = ACE_get_channel_next_flag(channel_handle, &flag_iterator);

+        display_flag_properties(current_flag);

+    }

+  @endcode

+ */

+ace_flag_handle_t

+ACE_get_channel_next_flag

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t *              iterator

+);

+

+/*-------------------------------------------------------------------------*//**

+  This defines the function prototype that must be followed by MSS ACE Post

+  Processing Engine (PPE) flag handler functions. These functions are registered

+  with the ACE driver and associated with a particular flag through the

+  ACE_register_flag_isr() function. The ACE driver will call the flag handler

+  function when the associated flag is raised.

+  

+  Declaring and Implementing PPE Flag Handler Functions

+  PPE flag handler functions should follow the following prototype:

+    void my_flag_handler ( ace_flag_handle_t flag_handle );

+  The actual name of the PPE flag handler is unimportant. You can use any name of

+  your choice for the PPE flag handler. 

+  The flag_handle parameter passes the handle of the raised flag to the flag

+  handler function.

+ */

+typedef void (*flag_isr_t)( ace_flag_handle_t flag_handle );

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_register_flag_isr() function is used to register a handler function

+  with the ACE driver. The registered function will be called by the ACE driver

+  when the associated flag is raised by the ACE post processing engine.

+  

+  @param flag_handle

+    The flag_handle parameter identifies one of the flags generated based on the

+    value of an analog input channel. The available flag handle values can be

+    found in the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The flag handle value can also be retrieved through a call to

+    ACE_get_flag_handle() when the name of the flag is known, or by iterating

+    though all flags associated with an analog input channel using the

+    ACE_get_channel_first_flag() and ACE_get_channel_next_flag().

+  

+  @param flag_isr

+    The flag_isr parameter is a pointer to a flag handler function with the

+    following prototype: 

+        void handler_function_name(ace_flag_handle_t  flag_handle) 

+    The flag handler function is called by the ACE driver as part of the relevant

+    post processing engine flag interrupt service routine. It does not need to

+    handle flag interrupt clearing as this is done by the ACE driver.

+

+  

+  @code

+    void my_critical_handler( void );

+    

+    void system_init( void )

+    {

+        ace_flag_handle_t flag_handle;

+        

+        flag_handle = ACE_get_flag_handle( "MainSupply:CriticalLevel" );

+        ACE_register_flag_isr( flag_handle, my_critical_handler );

+        ACE_enable_flag_irq( flag_handle );

+    }

+    

+    void my_critical_handler( ace_flag_handle_t flag_handle  )

+    {

+        panic( flag_handle );

+    }

+    

+  @endcode

+ */

+void ACE_register_flag_isr

+(

+    ace_flag_handle_t   flag_handle,

+    flag_isr_t          flag_isr

+);

+

+/*-------------------------------------------------------------------------*//**

+  This defines the function prototype that must be followed by MSS ACE Post

+  Processing Engine (PPE) channel flag handler functions. These functions are

+  registered with the ACE driver and associated with a particular ADC input

+  channel through the ACE_register_channel_flags_isr() function. The ACE driver

+  will call the channel flags handler function when one of the flags for the

+  associated ADC input channel is raised.

+  

+  Declaring and Implementing PPE Channel Flag Handler Functions

+  PPE channel flag handler functions should follow the following prototype:

+    void my_channel_flag_handler ( ace_flag_handle_t flag_handle );

+    The actual name of the PPE channel flag handler is unimportant. You can use

+    any name of your choice for the PPE channel flag handler. The flag_handle

+    parameter passes the handle of the raised flag to the channel flag handler

+    function.

+ */

+typedef void (*channel_flag_isr_t)( ace_flag_handle_t flag_handle );

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_register_channel_flags_isr() function is used to register a flag

+  interrupt handler function with the ACE driver. The registered interrupt

+  handler will be called by the ACE driver when one of the flag generated based

+  on the value of the analog input channel identified by the channel handle

+  passed as parameter is asserted.

+  

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param channel_flag_isr

+    The channel_flag_isr parameter is pointer to a function taking a flag handle

+    as parameter. 

+        void handler_function_name(ace_flag_handle_t  flag_handle) 

+    The flag handler function is called by the ACE driver as part of the relevant

+    post processing engine flag interrupt service routine. It does not need to

+    handle flag interrupt clearing as this is done by the ACE driver.

+  

+  Example

+    The example below demonstrates the use of the ACE_register_channel_flags_isr()

+    function in a system where the ACE is configured to have an analog input

+    channels named "MainSupply" with one flag named "Critical" generated based

+    on the value of "MainSupply" channel. The names "MainSupply" and "Critical"

+    were user selected in the ACE configurator. 

+  @code

+    void main_supply_handler (ace_flag_handle_t flag_handle);

+    

+    void system_init(void)

+    {

+        ACE_register_channel_flag_isr(MainSupply, main_supply_handler);

+        ACE_enable_channel_flags_irq(MainSupply);

+    }

+    

+    void main_supply_handler (ace_flag_handle_t flag_handle)

+    {

+        if (MainSupply_Critical == flag_handle)

+        {

+            panic(flag_handle);

+        }

+    }

+  

+  @endcode

+*/

+void ACE_register_channel_flags_isr

+(

+    ace_channel_handle_t    channel_handle,

+    channel_flag_isr_t      channel_flag_isr

+);

+

+/*-------------------------------------------------------------------------*//**

+  This defines the function prototype that must be followed by MSS ACE Post

+  Processing Engine (PPE) global flag handler functions. These functions are

+  registered with the ACE driver through the ACE_register_global_flags_isr()

+  function. The ACE driver will call the global flags handler function when any

+  flag for any ADC input channel is raised.

+  

+  Declaring and Implementing Global Flag Handler Functions

+  PPE global flag handler functions should follow the following prototype:

+    void my_global_flag_handler( 

+        ace_flag_handle_t flag_handle, 

+        ace_channel_handle_t channel_handle 

+    );

+  The actual name of the PPE global flag handler is unimportant. You can use any

+  name of your choice for the PPE global flag handler. The flag_handle parameter

+  passes the handle of the raised flag to the global flag handler function. The

+  channel_handle parameter passes the handle of the channel for which the flag

+  was raised to the global flag handler function.

+

+ */

+typedef void (*global_flag_isr_t)( ace_flag_handle_t flag_handle, ace_channel_handle_t channel_handle );

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_register_global_flags_isr() function is used to register a global

+  flag handler function with the ACE driver. The registered global handler will

+  be called when any flag interrupt is generated.

+  

+  @param global_flag_isr

+    The global_flag_isr parameter is a pointer to a function taking a flag

+    handle and channel handle as parameter.

+ */

+void ACE_register_global_flags_isr

+(

+    global_flag_isr_t  global_flag_isr

+);

+

+/** @} */

+

+/*=========================================================================*//**

+  @defgroup group11 Conversion Functions

+  The following functions are used to convert an ADC sample value to a real

+  world unit.

+  @{

+ *//*=========================================================================*/

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_convert_adc_input_to_mV() function converts an ADC sample value into

+  the value in millivolts of the voltage seen at ADC input. It does not account

+  for prescaling taking place before the ADC hardware input.

+

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param sample_value

+    The sample_value parameter is the result of an analog to digital conversion.

+  

+  @return

+    The ACE_convert_adc_input_to_mV() returns the number of millivolts derived

+    from the ADC sample value passed as parameter.

+ */

+uint32_t ACE_convert_adc_input_to_mV

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                sample_value

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_convert_to_mV() function converts a PPE sample value into milli-Volts.

+  It handles prescaling adjusments based on ACE configuration for ABPS inputs.

+  

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param sample_value

+    The sample_value parameter is the result of an analog to digital conversion.

+  

+  @return

+    The ACE_convert_to_mV() returns the number of millivolts derived from the

+    PPE sample value passed as parameter. The returned value can be either

+    positive or negative since prescaling is accounted for in the conversion.

+ */

+int32_t ACE_convert_to_mV

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                sample_value

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_convert_to_mA() function converts a PPE sample value into milli-Amps.

+  The result of the conversion is only meaningful if the PPE sample value

+  results from the conversion of a current monitor input.

+  

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param sample_value

+    The sample_value parameter is the result of an analog to digital conversion

+    of the voltage generated by a current monitor analog block.

+  

+  @return

+    The ACE_convert_to_mA() returns the number of milliamps derived from the

+    PPE sample value passed as parameter.

+ */

+uint32_t ACE_convert_to_mA

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                sample_value

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_convert_to_Kelvin() function converts a PPE sample value into degrees

+  Kelvin. The result of the conversion is only meaningful if the PPE sample value

+  results from the conversion of a temperature monitor input.

+  

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param sample_value

+    The sample_value parameter is the result of an analog to digital conversion

+    of the voltage generated by a temperature monitor analog block.

+  

+  @return

+    The ACE_convert_to_Kelvin() returns the number of degrees Kelvin derived

+    from the PPE sample value passed as parameter.

+ */

+uint32_t ACE_convert_to_Kelvin

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                sample_value

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_convert_to_Celsius() function converts a PPE sample value into tenths

+  of degrees Celsius. The result of the conversion is only meaningful if the PPE

+  sample value results from the conversion of a temperature monitor input.

+  

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param sample_value

+    The sample_value parameter is the result of an analog to digital conversion

+    of the voltage generated by a temperature monitor analog block.

+  

+  @return

+    The ACE_convert_to_Celsius() returns the number of tenths of degrees Celsius

+    derived from the PPE sample value passed as parameter.

+ */

+int32_t ACE_convert_to_Celsius

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                sample_value

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_convert_to_Fahrenheit() function converts a PPE sample value into

+  degrees Fahrenheit. The result of the conversion is only meaningful if the PPE

+  sample value results from the conversion of a temperature monitor input.

+  

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param sample_value

+    The sample_value parameter is the result of an analog to digital conversion

+    of the voltage generated by a temperature monitor analog block.

+  

+  @return

+    The ACE_convert_to_Fahrenheit() returns the number of degrees Fahrenheit

+    derived from the PPE sample value passed as parameter.

+ */

+int32_t ACE_convert_to_Fahrenheit

+(

+    ace_channel_handle_t    channel_handle,

+    uint16_t                sample_value

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_convert_mV_to_adc_value() function converts a voltage value given in

+  milli-Volts into the ADC sample value that would result from sampling this

+  voltage value on the analog input channel specified as parameter.

+  This function is intended for use when directly controlling the ADC, not when

+  using samples read from the PPE. It does not account for prescaling taking

+  place before the ADC hardware input.

+  

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param voltage

+    The voltage parameter is the milli-Volts voltage value for which we want this

+    function to return the associated ADC sample result value.

+  

+  @return

+    The ACE_convert_mV_to_adc_value() returns the ADC sample value that would be

+    produced if the analog input channel identified by channel_handle was set to

+    the voltage value passed as second parameter.

+ */

+uint16_t ACE_convert_mV_to_adc_value

+(

+    ace_channel_handle_t    channel_handle,

+    uint32_t                voltage

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_convert_from_mV() function converts a voltage value given in

+  milli-Volts into the PPE sample value that would result from sampling this

+  voltage value on the analog input channel specified as parameter.

+  This function handles prescaling adjusments based on ACE configuration for

+  ABPS inputs.

+  

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param voltage

+    The voltage parameter is the milli-Volts voltage value for which we want this

+    function to return the associated PPE sample result value.

+  

+  @return

+    The ACE_convert_from_mV() returns the PPE sample value that would be produced

+    if the analog input channel identified by channel_handle was set to the

+    voltage value passed as second parameter.

+ */

+uint16_t ACE_convert_from_mV

+(

+    ace_channel_handle_t    channel_handle,

+    int32_t                 voltage

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_convert_from_mA() function converts a current value given in

+  milli-Amps into the PPE sample value that would result from sampling this

+  current value on the analog input channel specified as parameter.

+  The result of the conversion is only meaningful if the analog input channel

+  specified as parameter is configured as a current monitoring channel.

+  

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param current

+    The current parameter is the milli-Amps current value for which we want this

+    function to return the associated PPE sample result value.

+  

+  @return

+    The ACE_convert_from_mA() returns the PPE sample value that would be produced

+    if the analog input channel identified by channel_handle was set to the

+    current value passed as second parameter.

+ */

+uint16_t ACE_convert_from_mA

+(

+    ace_channel_handle_t    channel_handle,

+    uint32_t                current

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_convert_from_Kelvin() function converts a temperature value given in

+  degrees Kelvin into the PPE sample value that would result from sampling this

+  temperature value on the analog input channel specified as parameter.

+  The result of the conversion is only meaningful if the analog input channel

+  specified as parameter is configured as a temperature monitoring channel.

+  

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param temperature

+    The temperature parameter is the degrees Kelvin temperature value for which

+    we want this function to return the associated PPE sample result value.

+  

+  @return

+    The ACE_convert_from_Kelvin() returns the PPE sample value that would be

+    produced if the analog input channel identified by channel_handle was set to

+    the temperature value passed as second parameter.

+ */

+uint16_t ACE_convert_from_Kelvin

+(

+    ace_channel_handle_t    channel_handle,

+    uint32_t                temperature

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_convert_from_Celsius() function converts a temperature value given in

+  degrees Celsius into the PPE sample value that would result from sampling this

+  temperature value on the analog input channel specified as parameter.

+  The result of the conversion is only meaningful if the analog input channel

+  specified as parameter is configured as a temperature monitoring channel.

+  

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param temperature

+    The temperature parameter is the degrees Celsius temperature value for which

+    we want this function to return the associated PPE sample result value.

+  

+  @return

+    The ACE_convert_from_Celsius() returns the PPE sample value that would be

+    produced if the analog input channel identified by channel_handle was set to

+    the temperature value passed as second parameter.

+ */

+uint16_t ACE_convert_from_Celsius

+(

+    ace_channel_handle_t    channel_handle,

+    int32_t                 temperature

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_convert_from_Fahrenheit() function converts a temperature value given

+  in degrees Fahrenheit into the PPE sample value that would result from sampling

+  this temperature value on the analog input channel specified as parameter.

+  The result of the conversion is only meaningful if the analog input channel

+  specified as parameter is configured as a temperature monitoring channel.

+  

+   @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in the

+    ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The

+    channel handle value can also be retrieved through a call to

+    ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param temperature

+    The temperature parameter is the degrees Fahrenheit temperature value for

+    which we want this function to return the associated PPE sample result value.

+  

+  @return

+    The ACE_convert_from_Fahrenheit() returns the PPE sample value that would be

+    produced if the analog input channel identified by channel_handle was set to

+    the temperature value passed as second parameter.

+ */

+uint16_t ACE_convert_from_Fahrenheit

+(

+    ace_channel_handle_t    channel_handle,

+    int32_t                 temperature

+);

+

+/*-------------------------------------------------------------------------*//**

+  The ACE_translate_pdma_value() function translates PDMA sampling values,

+  received from the ACE via PDMA transfers, into input channel ID and PPE

+  sample value.

+  The PDMA sampling values are generated by the ACE as a result of selecting

+  "Send result to DMA" in the ACE configurator analog input configuration. The

+  PDMA sampling values can be either raw ADC values, filtered values or the

+  result of a linear transformation.

+  The PDMA sampling values are obtained by configuring the PDMA controller to

+  transfer data from the ACE into a memory buffer. The ACE_translate_pdma_value()

+  function is used to interpret the content of that memory buffer.

+  

+  Please note that the translation of PDMA data containing raw ADC values from

+  ABPS inputs will result in sample values with an unexpected polarity.

+  The returned sample value will have the opposite polarity to the actual analog

+  value seen on the ABPS input. This is due to the internal characteristics of

+  the analog front end that are normally hidden by the PPE processing of ADC raw

+  samples. The translation of raw ADC values from analog inputs other than ABPS

+  inputs will result in correct sample values.

+  

+   @param pdma_value

+    The pdma_value parameter is a 32-bit value received from the ACE through a

+    peripheral DMA transfer. 

+    

+  @param channel_id

+    The channel_id parameter is a pointer to an ADC channel ID variable. It is

+    used to return the ID of the ADC channel from which the PPE sample value

+    was generated from. This parameter can be set to zero if retrieving the

+    channel ID is not required.

+  

+  @return

+    The ACE_translate_pdma_value() returns the PPE sample value extracted from

+    the PDMA sampling value.

+  

+  Example:

+  @code

+    uint16_t ppe_value;

+    uint16_t pdma_value;

+    adc_channel_id_t channel_id;

+    ace_channel_handle_t channel_handle;

+    

+    pdma_value = get_next_pdma_ace_sample();

+    ppe_value = ACE_translate_pdma_value(pdma_value, &channel_id);

+    channel_handle = ACE_get_input_channel_handle(channel_id);

+    if (channel_handle != INVALID_CHANNEL_HANDLE)

+    {

+        display_value(channel_handle, ppe_value);

+    }

+  @endcode

+  

+ */

+uint16_t ACE_translate_pdma_value

+(

+    uint32_t            pdma_value,

+    adc_channel_id_t *  channel_id

+);

+

+/** @} */

+

+/*=========================================================================*//**

+  @defgroup group12 Dynamic Linear Transform Control Functions

+  The following functions are used to dynamically adjust the linear transform

+  applied to analog input samples by the post processing engine:

+    - ACE_get_default_m_factor()

+    - ACE_get_default_c_offset()

+    - ACE_set_linear_transform()

+  The post processing engine performs a linear transform on analog input samples

+  obtained from the sample sequencing engine. The main purpose of this linear 

+  transform is to apply part specific factory calibration to the analog samples

+  in order to achieve high accuracy. A second user specified linear transform

+  can also be optionally applied to the analog samples. This second linear

+  transform can be used to adjust for board level calibration or application

+  specific tuning. The functions described in this section apply to the user

+  defined transform. Factory calibration will not be affected by the use of the

+  ACE_set_linear_transform() function.

+  Note:

+    The post processing engine actually only performs one single linear

+    transform on analog samples. This transform takes into account factory

+    calibration and the user defined transform. The applied y = m.x + c

+    transform uses an m factor equal to m1.m2.mext and c offset equal to

+    (m2.c1.mext) + (c2.mext) where m1 and c1 are the factory calibration factor

+    and offset; m2 and c2 are the user defined transform factor and offset; and

+    mext is a factory calibration factor depending on the reference voltage

+    used by the ADC generating the sample.

+  @{

+ *//*=========================================================================*/

+

+

+/*------------------------------------------------------------------------*//**

+  The ACE_get_default_m_factor() function retrieves the default value of the m

+  factor of the user defined linear transform applied by the post processing

+  engine to analog samples. The user defined linear transform m factor default

+  value is selected in the ACE configurator tool.

+  

+  @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in

+    the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The channel handle value can also be retrieved through a call

+    to ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+  

+  @return

+    The ACE_get_default_m_factor() function returns the user transform m factor

+    default value. It is a signed 16-bit number representing a factor in the

+    range -2 to +1.99993896484375. The value of the m factor is obtained by

+    multiplying the return value’s absolute value by 2-14.

+ */

+int16_t ACE_get_default_m_factor

+(

+    ace_channel_handle_t channel_handle

+);

+

+/*------------------------------------------------------------------------*//**

+  The ACE_get_default_c_offset() function retrieves the default value of the c

+  offset of the user defined linear transform applied by the post processing

+  engine to analog samples. The user defined linear transform c offset default

+  value is selected in the ACE configurator tool.

+  

+  @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in

+    the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The channel handle value can also be retrieved through a call

+    to ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @return

+    The ACE_get_default_c_offset() function returns the user linear transform’s

+    c offset default value. It is a signed 16-bit number representing a factor

+    in the range -2 to +1.99993896484375. The value of the c offset is obtained

+    by multiplying the return value’s absolute value by 2-14.

+ */

+int16_t ACE_get_default_c_offset

+(

+    ace_channel_handle_t channel_handle

+);

+

+/*------------------------------------------------------------------------*//**

+  The ACE_set_linear_transform() function allows adjusting the user defined

+  linear transform applied to analog input samples by the post processing

+  engine. The linear transform is of the form y = m.x + b where the m factor

+  and c offset are in the range -2 to +1.99993896484375.

+   

+  @param channel_handle

+    The channel_handle parameter identifies one of the analog input channels

+    monitored by the ACE. The available channel handle values can be found in

+    the ace_handles.h file located in the .\drivers_config\mss_ace

+    subdirectory. The channel handle value can also be retrieved through a call

+    to ACE_get_channel_handle() when the name of the channel is known, or by

+    iterating though all analog input channel using the ACE_get_first_channel()

+    and ACE_get_next_channel().

+    

+  @param m2

+    The m2 parameter specifies the user defined transform’s m factor. It is a

+    signed 16-bit number representing a factor in the range -2 to

+    +1.99993896484375. The value of the m2 factor is obtained by multiplying the

+    parameter’s absolute value by 2^-14. For example, a value of 0x7000

+    represents a 1.75 factor and a value of 0xE000 represents a -0.5 factor.

+    

+  @param c2

+    The c2 parameter specifies the user defined transform’s c offset. It is a

+    signed 16-bit number representing an offset in the range -2 to

+    +1.99993896484375. The value of the c2 offset is obtained by multiplying the

+    parameter’s absolute value by 2^-14. For example, a value of 0x1000 represents

+    a 0.25 offset and a value of 0xB000 represents a -1.25 offset.

+    

+  @code

+    void reset_to_default(ace_channel_handle_t channel_handle)

+    {

+        int16_t m;

+        int16_t c;

+        

+        m = ACE_get_default_m_factor(channel_handle);

+        c = ACE_get_default_c_offset(channel_handle);

+        ACE_set_linear_transform(channel_handle, m, c);

+    }

+  @endcode

+ */

+void ACE_set_linear_transform

+(

+    ace_channel_handle_t channel_handle,

+	int16_t m2,

+	int16_t c2

+);

+

+/** @} */

+ 

+#ifdef __cplusplus

+}

+#endif

+

+#endif	/* __MSS_ACE_H_ */

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace_configurator.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace_configurator.h
new file mode 100644
index 0000000..2621f53
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace_configurator.h
@@ -0,0 +1,622 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ * SVN $Revision: 2841 $

+ * SVN $Date: 2010-07-20 18:10:00 +0100 (Tue, 20 Jul 2010) $

+ */

+

+/*=========================================================================*//**

+  @mainpage ACE Configurator data provided to ACE Driver.

+

+  @section intro_sec Introduction

+  This file contains the definition of data structures used by the ACE

+  Configurator software tool for sharing information about the ACE configuration

+  with the ACE driver. It also contains the API for accessor functions used by

+  the ACE driver to extract relevant information from these data structures.

+ *//*=========================================================================*/

+#ifndef __MSS_ACE_CONFIGURATOR_H_

+#define __MSS_ACE_CONFIGURATOR_H_

+

+#include "mss_ace.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/*-------------------------------------------------------------------------*//**

+  Post Processing Engine (PPE) flags IDs.

+ */

+typedef enum

+{

+    PPE_FLAGS0_0 = 0,

+    PPE_FLAGS0_1 = 1,

+    PPE_FLAGS0_2 = 2,

+    PPE_FLAGS0_3 = 3,

+    PPE_FLAGS0_4 = 4,

+    PPE_FLAGS0_5 = 5,

+    PPE_FLAGS0_6 = 6,

+    PPE_FLAGS0_7 = 7,

+    PPE_FLAGS0_8 = 8,

+    PPE_FLAGS0_9 = 9,

+    PPE_FLAGS0_10 = 10,

+    PPE_FLAGS0_11 = 11,

+    PPE_FLAGS0_12 = 12,

+    PPE_FLAGS0_13 = 13,

+    PPE_FLAGS0_14 = 14,

+    PPE_FLAGS0_15 = 15,

+    PPE_FLAGS0_16 = 16,

+    PPE_FLAGS0_17 = 17,

+    PPE_FLAGS0_18 = 18,

+    PPE_FLAGS0_19 = 19,

+    PPE_FLAGS0_20 = 20,

+    PPE_FLAGS0_21 = 21,

+    PPE_FLAGS0_22 = 22,

+    PPE_FLAGS0_23 = 23,

+    PPE_FLAGS0_24 = 24,

+    PPE_FLAGS0_25 = 25,

+    PPE_FLAGS0_26 = 26,

+    PPE_FLAGS0_27 = 27,

+    PPE_FLAGS0_28 = 28,

+    PPE_FLAGS0_29 = 29,

+    PPE_FLAGS0_30 = 30,

+    PPE_FLAGS0_31 = 31,

+    PPE_FLAGS1_0 = 32,

+    PPE_FLAGS1_1 = 33,

+    PPE_FLAGS1_2 = 34,

+    PPE_FLAGS1_3 = 35,

+    PPE_FLAGS1_4 = 36,

+    PPE_FLAGS1_5 = 37,

+    PPE_FLAGS1_6 = 38,

+    PPE_FLAGS1_7 = 39,

+    PPE_FLAGS1_8 = 40,

+    PPE_FLAGS1_9 = 41,

+    PPE_FLAGS1_10 = 42,

+    PPE_FLAGS1_11 = 43,

+    PPE_FLAGS1_12 = 44,

+    PPE_FLAGS1_13 = 45,

+    PPE_FLAGS1_14 = 46,

+    PPE_FLAGS1_15 = 47,

+    PPE_FLAGS1_16 = 48,

+    PPE_FLAGS1_17 = 49,

+    PPE_FLAGS1_18 = 50,

+    PPE_FLAGS1_19 = 51,

+    PPE_FLAGS1_20 = 52,

+    PPE_FLAGS1_21 = 53,

+    PPE_FLAGS1_22 = 54,

+    PPE_FLAGS1_23 = 55,

+    PPE_FLAGS1_24 = 56,

+    PPE_FLAGS1_25 = 57,

+    PPE_FLAGS1_26 = 58,

+    PPE_FLAGS1_27 = 59,

+    PPE_FLAGS1_28 = 60,

+    PPE_FLAGS1_29 = 61,

+    PPE_FLAGS1_30 = 62,

+    PPE_FLAGS1_31 = 63,

+    PPE_FLAGS2_0 = 64,

+    PPE_FLAGS2_1 = 65,

+    PPE_FLAGS2_2 = 66,

+    PPE_FLAGS2_3 = 67,

+    PPE_FLAGS2_4 = 68,

+    PPE_FLAGS2_5 = 69,

+    PPE_FLAGS2_6 = 70,

+    PPE_FLAGS2_7 = 71,

+    PPE_FLAGS2_8 = 72,

+    PPE_FLAGS2_9 = 73,

+    PPE_FLAGS2_10 = 74,

+    PPE_FLAGS2_11 = 75,

+    PPE_FLAGS2_12 = 76,

+    PPE_FLAGS2_13 = 77,

+    PPE_FLAGS2_14 = 78,

+    PPE_FLAGS2_15 = 79,

+    PPE_FLAGS2_16 = 80,

+    PPE_FLAGS2_17 = 81,

+    PPE_FLAGS2_18 = 82,

+    PPE_FLAGS2_19 = 83,

+    PPE_FLAGS2_20 = 84,

+    PPE_FLAGS2_21 = 85,

+    PPE_FLAGS2_22 = 86,

+    PPE_FLAGS2_23 = 87,

+    PPE_FLAGS2_24 = 88,

+    PPE_FLAGS2_25 = 89,

+    PPE_FLAGS2_26 = 90,

+    PPE_FLAGS2_27 = 91,

+    PPE_FLAGS2_28 = 92,

+    PPE_FLAGS2_29 = 93,

+    PPE_FLAGS2_30 = 94,

+    PPE_FLAGS2_31 = 95,

+    PPE_FLAGS3_0 = 96,

+    PPE_FLAGS3_1 = 97,

+    PPE_FLAGS3_2 = 98,

+    PPE_FLAGS3_3 = 99,

+    PPE_FLAGS3_4 = 100,

+    PPE_FLAGS3_5 = 101,

+    PPE_FLAGS3_6 = 102,

+    PPE_FLAGS3_7 = 103,

+    PPE_FLAGS3_8 = 104,

+    PPE_FLAGS3_9 = 105,

+    PPE_FLAGS3_10 = 106,

+    PPE_FLAGS3_11 = 107,

+    PPE_FLAGS3_12 = 108,

+    PPE_FLAGS3_13 = 109,

+    PPE_FLAGS3_14 = 110,

+    PPE_FLAGS3_15 = 111,

+    PPE_FLAGS3_16 = 112,

+    PPE_FLAGS3_17 = 113,

+    PPE_FLAGS3_18 = 114,

+    PPE_FLAGS3_19 = 115,

+    PPE_FLAGS3_20 = 116,

+    PPE_FLAGS3_21 = 117,

+    PPE_FLAGS3_22 = 118,

+    PPE_FLAGS3_23 = 119,

+    PPE_FLAGS3_24 = 120,

+    PPE_FLAGS3_25 = 121,

+    PPE_FLAGS3_26 = 122,

+    PPE_FLAGS3_27 = 123,

+    PPE_FLAGS3_28 = 124,

+    PPE_FLAGS3_29 = 125,

+    PPE_FLAGS3_30 = 126,

+    PPE_FLAGS3_31 = 127,

+    PPE_SFFLAGS_0 = 128,

+    PPE_SFFLAGS_1 = 129,

+    PPE_SFFLAGS_2 = 130,

+    PPE_SFFLAGS_3 = 131,

+    PPE_SFFLAGS_4 = 132,

+    PPE_SFFLAGS_5 = 133,

+    PPE_SFFLAGS_6 = 134,

+    PPE_SFFLAGS_7 = 135,

+    PPE_SFFLAGS_8 = 136,

+    PPE_SFFLAGS_9 = 137,

+    PPE_SFFLAGS_10 = 138,

+    PPE_SFFLAGS_11 = 139,

+    PPE_SFFLAGS_12 = 140,

+    PPE_SFFLAGS_13 = 141,

+    PPE_SFFLAGS_14 = 142,

+    PPE_SFFLAGS_15 = 143,

+    PPE_SFFLAGS_16 = 144,

+    PPE_SFFLAGS_17 = 145,

+    PPE_SFFLAGS_18 = 146,

+    PPE_SFFLAGS_19 = 147,

+    PPE_SFFLAGS_20 = 148,

+    PPE_SFFLAGS_21 = 149,

+    PPE_SFFLAGS_22 = 150,

+    PPE_SFFLAGS_23 = 151,

+    PPE_SFFLAGS_24 = 152,

+    PPE_SFFLAGS_25 = 153,

+    PPE_SFFLAGS_26 = 154,

+    PPE_SFFLAGS_27 = 155,

+    PPE_SFFLAGS_28 = 156,

+    PPE_SFFLAGS_29 = 157,

+    PPE_SFFLAGS_30 = 158,

+    PPE_SFFLAGS_31 = 159,

+    NB_OF_PPE_FLAGS = 160

+} ppe_flag_id_t;

+

+/*-------------------------------------------------------------------------*//**

+  Flag types.

+  The following defines are used to indicate the type of flag selected in the

+  ACE configurator.

+ */

+/**

+  A flag configured as BASIC_THRESHOLD_OVER will be asserted when the value of

+  the input channel exceeds the value of the flag threshold. The flag will be

+  de-asserted once the value of the input channel falls back under the threshold

+  value. No hysteresis or state filtering is applied to the flag.

+ */

+#define BASIC_THRESHOLD_OVER    0u

+

+/**

+  A flag configured as BASIC_THRESHOLD_UNDER will be asserted when the value of

+  the input channel falls under the value of the flag threshold. The flag will be

+  de-asserted once the value of the input channel exceeds the threshold value.

+  No hysteresis or state filtering is applied to the flag.

+ */

+#define BASIC_THRESHOLD_UNDER   1u

+

+/**

+  A flag configured as STATE_FILTERED_OVER will be asserted when n consecutive

+  samples of the analog input are seen to exceed the value of the flag threshold,

+  where n is the number selected in the "assert samples" option of the ACE

+  configuration softwaretool flag's configuration.

+  The flag will be de-asserted once m consecutive samples as seen below the flag

+  threshold value, where m is the number selected in the "deassert samples"

+  option of the flag's configuration user interface.

+ */

+#define STATE_FILTERED_OVER     2u

+

+/**

+  A flag configured as STATE_FILTERED_UNDER will be asserted when n consecutive

+  samples of the analog input are seen below the value of the flag threshold,

+  where n is the number selected in the "assert samples" option of the ACE

+  configuration softwaretool flag's configuration.

+  The flag will be de-asserted once m consecutive samples as seen to exceed the

+  flag threshold value, where m is the number selected in the "deassert samples"

+  option of the flag's configuration user interface.

+ */

+#define STATE_FILTERED_UNDER    3u

+

+/**

+  A flag configured as DUAL_HYSTERESIS_OVER will be asserted when the value

+  of the input channel exceeds the threshold value plus the hysteresis value.

+  The flag will be deasserted when the value of the input channel falls under the

+  threshold value minus the hysteresis value.

+  */

+#define DUAL_HYSTERESIS_OVER    4u

+

+/**

+  A flag configured as DUAL_HYSTERESIS_UNDER will be asserted when the value

+  of the input channel falls under the threshold value minus the hysteresis value.

+  The flag will be deasserted when the value of the input channel exceeds the

+  threshold value plus the hysteresis value.

+  */

+#define DUAL_HYSTERESIS_UNDER   5u

+

+/**

+  A flag configured as IPMI_HYSTERESIS_OVER will be asserted when the value

+  of the input channel exceeds the threshold value. The flag will be deasserted

+  when the value of the input channel falls under the threshold value minus the

+  hysteresis value.

+  */

+#define IPMI_HYSTERESIS_OVER    6u

+

+/**

+  A flag configured as IPMI_HYSTERESIS_UNDER will be asserted when the value

+  of the input channel falls under the threshold value. The flag will be

+  deasserted when the value of the input channel exceeds the threshold value

+  plus the hysteresis value.

+  */

+#define IPMI_HYSTERESIS_UNDER   7u

+

+/*-------------------------------------------------------------------------*//**

+  State filtered flag configuration.

+ */

+typedef struct __state_filtering_cfg

+{

+    /**

+      Number of consecutive samples required for flag assertion.

+     */

+    uint8_t assert_samples;

+    

+    /**

+      Number of consecutive samples required for flag deassertion.

+     */

+    uint8_t deassert_samples;

+} state_filtering_cfg_t;

+

+/*-------------------------------------------------------------------------*//**

+  Post Processing Engine generated flag descriptor.

+ */

+typedef struct

+{

+    /**

+      Pointer to a zero-terminated string identifying the flag described by this

+      structure. This unique flag name is the name selected in the ACE configurator

+      software tool when creating a flag.

+      The flag unique name contains both the name of the monitored input channel

+      and the name of the flag generated based the level of that input separated

+      by ":". For example, the unique name for the flag called "CriticalOver"

+      raised when the input channel called "MainSupply" reaches a critical level

+      would be named "MainSupply:CriticalOver".

+     */

+    const uint8_t * p_sz_flag_name;

+    

+    /**

+      The flag_id element identifies which PPE hardware flag will be asserted

+      when the flag conditions are found to be met by the Post Processing Engine.

+      This flag_id is typically used by the ACE driver to determine which ACE

+      register is used to enable, disable and clear interrupts on the associated

+      flag.

+     */

+    ppe_flag_id_t flag_id;

+    

+    /**

+      The flag_type element specifies the type of the described flag. It is

+      specified using one of the following:

+        - BASIC_THRESHOLD_OVER

+        - BASIC_THRESHOLD_UNDER

+        - STATE_FILTERED_OVER

+        - STATE_FILTERED_UNDER

+        - DUAL_HYSTERESIS_OVER

+        - DUAL_HYSTERESIS_UNDER

+        - IPMI_HYSTERESIS_OVER

+        - IPMI_HYSTERESIS_UNDER

+     */

+    uint8_t flag_type;

+    

+    /**

+      PPE RAM offset of flag threshold level.

+      This is the 32-bit word offset within the Post Processing Engine RAM where

+      the threshold associated with this flag is stored. This is used to allow

+      the ACE driver dynamically modifying the threshold beyond which a flag is

+      asserted.

+      In the case of hysteresis flags, threshold_ppe_offset indicates the

+      start location of two consecutive PPE RAM words containing the ADC value

+      of the hysteresis low limit followed by the ADC value for the high

+      hysteresis limit.

+     */

+    uint16_t threshold_ppe_offset;

+

+    /**

+      The default_threshold element specifies the value of the flag's threshold

+      selected in the ACE Configurator. It is the ADC value for which the flag

+      would be raised if hysteresis was not applied.

+     */

+    uint16_t default_threshold;

+    

+    /**

+      The flag_properties takes a different meaning depending whether the flag is

+      an hysteresis flag or a state filtered flag.

+      

+      Hysteresis flags:

+        The flag_properties element specifies the ADC value to be applied as

+        hysteresis to the threshold value that was selected in the ACE Configurator.

+        A non-zero value indicates that an hysteresis must be applied and that

+        threshold_ppe_offset refers to the first of the two ADC values defining

+        the hysteresis applied to the input signal.

+      

+      State filtered flags:

+        The flag_properties element specifies the number of consecutive samples that

+        must be over or under the threshold value for the flag state to change.

+     */

+    uint16_t flag_properties;

+    

+    /**

+      The channel_handle element specifies the monitored analog input channel.

+      It can be used as parameter to a call to function ACE_get_ppe_sample() in

+      order to read the current value of the analog input channel which caused

+      the flag described by this structure to be raised.

+     */

+    ace_channel_handle_t channel_handle;

+   

+} ppe_flag_desc_t;

+

+/*-------------------------------------------------------------------------*//**

+  The ace_procedure_desc_t structure is used as a procedure descriptor. It

+  contains all information required by the ACE driver to use and manage an ACE

+  procedure that was created using the ACE Configurator software tool.

+ */

+typedef struct

+{

+    /**

+      Pointer to a zero-terminated string identifying an ACE procedure.

+      This procedure name is the one selected when created procedures using the

+      ACE Configurator software tool.

+     */

+    const uint8_t * p_sz_proc_name;

+    

+    /**

+      Sample Sequencing Engine procedure loop start program counter value.

+     */

+    uint16_t sse_loop_pc;

+    

+    /**

+      Sample Sequencing Engine microcode offset.

+      This is the 16-bit instruction offset from which the SSE microcode for the

+      procedure must be loaded at into the ACE SSE RAM.

+      This is also the value that must be writtent into one of the ACE's SSE program

+      counter registers in order to start the procedure after having loaded its

+      microcode into SSE RAM. The actual program counter register written depends

+      on the analog module used by the procedure. It is determined by the value

+      of this structure's sse_pc_id element.

+     */

+    uint16_t sse_load_offset;

+    

+    /**

+      Sample Sequencing Engine microcode length.

+      This is the number of 16-bit SSE instructions that must be loaded into

+      SSE RAM in order to load the procedure into the ACE.

+     */

+    uint16_t sse_ucode_length;

+    

+    /**

+      Pointer to ucode.

+     */

+    const uint16_t * sse_ucode;

+    

+    /**

+      SSE program counter ID.

+      This value identifies whether the procedure is used to control analog

+      module 0, 1 or 2. It is used to know which SSE program counter should

+      be set when starting the procedure.

+     */

+    uint8_t sse_pc_id;

+} ace_procedure_desc_t;

+

+/*-------------------------------------------------------------------------*//**

+  The ace_channel_desc_t structure is used as an analog input  channel

+  descriptor. It contains the name of a channel as selected in the ACE

+  Configurator software tool and the identifier used to identify the ADC channel

+  to which the analog input signal is connected.

+ */

+typedef struct

+{

+    /**

+      Analog input signal name as selected in the ACE Configurator software tool.

+     */

+    const uint8_t * p_sz_channel_name;

+    

+    /**

+      Analog block input channel connected to the input signal.

+     */

+    adc_channel_id_t signal_id;

+    

+    /**

+      Offset into Post Processing Engine RAM where the result of post processing

+      on sample for the signal will be stored.

+     */

+    uint16_t signal_ppe_offset;

+     

+    /**

+      Number of PPE generated flags associated with the analog input channel

+      described by this structure. The nb_of_flags specifies the number of items

+      found in the p_flags_array array.

+     */

+    uint16_t nb_of_flags;

+    

+    /**

+      The p_flags_array element is a pointer to an array of indexes into the

+      g_ppe_flags_desc_table flag descriptors table. The array it points to

+      lists the flags generated base don the value of the analog input channel

+      described by this structure.

+     */

+    const uint16_t * p_flags_array;

+    

+} ace_channel_desc_t;

+

+/*-------------------------------------------------------------------------*//**

+  struct ace_config_desc_t

+  The ace_config_descr_t structure is used to provide information about the

+  configuration of the ACE and analog block. A single instance of this structure

+  is intended to be used to inform the ACE driver of the ACE configuration

+  seleted using the ACE Configurator software tool and programmed into the ACE

+  hardware at system boot time.

+ */

+typedef struct

+{

+    /*--------------------------------------------------------------------------

+     * Procedures information

+     */

+    /**

+      Procedure descriptors table location.

+      This is a pointer to an array of procedure descriptors.

+      @see nb_of_procedures

+     */

+    ace_procedure_desc_t * proc_descr_table;

+    

+    /**

+      Total number of available procedures. This indicates the number of elements

+      of the procedure descriptor array.

+      @see proc_descr_table

+     */

+    uint16_t nb_of_procedures;

+    

+    /**

+      Number of procedures loaded into the ACE hardware at system boot time.

+      @see boot_loaded_proc_idx_list

+     */

+    uint16_t nb_boot_loaded_proc;

+    /**

+      Pointer to list of procedures loaded into the ACE hardware at system boot

+      time. That list contains the indexes into the procedure descriptors array

+      of the procedures loaded into the ACE hardware.

+      @see nb_boot_loaded_proc

+     */

+    uint16_t * boot_loaded_proc_idx_list;

+    

+    /*--------------------------------------------------------------------------

+     * Analog to Digital Converter signals

+     */

+    /**

+      Total number of configured analog input signals.

+      This is the number of analog input signals that were added to the ACE

+      configuration using the ACE Configurator software tool. It is also the

+      number of elements in the signal descriptor table pointed to by this

+      structure's signals_descr_table field.

+      @see signals_descr_table

+     */

+    uint16_t nb_of_signals;

+    

+    /**

+      Signal descriptors table location.

+      This is a pointer to an array of signal descriptors describing every

+      configured analog input signals.

+      @see nb_of_signals

+     */

+    ace_channel_desc_t * signals_descr_table;

+    

+    /*--------------------------------------------------------------------------

+     * One Bit DACs

+     */

+    /**

+      One Bit DAC (OBD) names as specified in ACE configurator software tool.

+      This array is indexed on the analog block number. i.e. sz_obd_names[0]

+      contains the name used to identify the OBD contained in analog module 0.

+      A value of 0 in this array indicates that no name was assigned to the

+      associated OBD.

+     */

+    const uint8_t * sz_obd_names[3];

+    

+    /*--------------------------------------------------------------------------

+     * PPE generated flags

+     */

+    /**

+      Flag descriptors array location.

+      This is a pointer to an array of ppe_flag_desc_t structures describing the

+      properties of each of the flags generated by the Post Processing Engine.

+      The size of that array is specified by the nb_of_flags element of this

+      structure.

+     */

+    ppe_flag_desc_t * flags_descr_table;

+

+    /**

+      Number of flags used in the ACE Configurator generated configuration.

+     */

+    uint8_t nb_of_flags;

+    

+    /*--------------------------------------------------------------------------

+     * Analog comparators

+     */

+    /**

+     *

+     */

+} ace_config_desc_t;

+

+

+/*-------------------------------------------------------------------------*//**

+  The ace_adc_config_t data structure is used by the ACE configurator to inform

+  the ACE driver of an analog to digital converter's configuration.

+ */

+typedef struct

+{

+    /**

+      ADC resolution. Values can be 256, 1024 or 4096 depending whether the ADC

+      is configured for 8, 10 or 12 bits.

+     */

+    uint16_t adc_resolution;

+    

+    /**

+      VA_REF value in milli-Volts. This should be set to 2560 if internal VAREF

+      is used.

+     */

+    uint16_t va_ref;

+    

+} ace_adc_config_t;

+

+/*-------------------------------------------------------------------------*//**

+  The ppe_transforms_desc_t data structure is used by the ACE configurator to

+  inform the ACE driver of the location of the "m" factor and "c" offset used

+  by the PPE to perform a linear transform of the form y = m*x + c. This linear

+  transform is used to apply calibration to the ADC samples. It can also include

+  a user defined linear transform specified by the user using the ACE

+  configurator. The factor and offset of the user defined transform is included

+  in the default_m2 and default_c2 items. 

+ */

+typedef struct

+{

+    /**

+      Offset into Post Processing Engine RAM where the linear transform m factor

+      is stored.

+     */

+    uint16_t    m_ppe_offset;

+    

+    /**

+      Offset into Post Processing Engine RAM where the linear transform c offset

+      is stored.

+     */

+    uint16_t    c_ppe_offset;

+    

+    /**

+      Default value of the user defined linear transform m2 factor.

+     */

+    int16_t     default_m2;

+    

+    /**

+      Default value of the user defined linear transform c2 offset.

+     */

+    int16_t     default_c2;

+} ppe_transforms_desc_t;

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif  /* __MSS_ACE_CONFIGURATOR_H_ */

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mtd_data.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mtd_data.h
new file mode 100644
index 0000000..431f28f
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mtd_data.h
@@ -0,0 +1,104 @@
+/*******************************************************************************

+ * (c) Copyright 2008 Actel Corporation.  All rights reserved.

+ * 

+ *  Manufacturing Test Data data structures.

+ *  This header files specified the layout of the various data structures used

+ *  to store manaufacturing test data within eNVM.

+ *

+ * SVN $Revision: 700 $

+ * SVN $Date: 2009-03-13 13:22:03 +0000 (Fri, 13 Mar 2009) $

+ */

+#ifndef MTD_DATA_H

+#define MTD_DATA_H

+

+#include <stdint.h>

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/*

+ * Analog block specifications

+ */

+#define NB_OF_QUADS                     6

+#define NB_OF_ABPS_PER_QUAD             2

+#define TOTAL_NB_OF_ABPS                (NB_OF_QUADS * NB_OF_ABPS_PER_QUAD)

+#define NB_OF_ABPS_RANGES               4

+#define NB_OF_ANALOG_MODULES            3

+#define NB_OF_OBD_MODES                 2

+#define NB_OF_QUADS_PER_MODULE          2

+#define NB_OF_CHOPPING_OPTIONS          2

+#define NB_OF_DIRECT_INPUTS_PER_ADC     4

+

+#define NB_OF_ADC_CHANNELS      13

+

+/*------------------------------------------------------------------------------

+ * mtd_global_settings_t

+ *------------------------------------------------------------------------------

+ * This typedef specifies the layout of the data structure holding the 

+ * manufacturing test data global settings.

+ */

+typedef struct __mtd_global_settings_t

+{

+    uint16_t    crc16;

+    uint8_t     serial[6];

+    uint32_t    revision;

+    uint16_t    sram_repair[8];

+    uint16_t    varef_m;

+    uint16_t    spare;

+    uint8_t     big_dec;

+    uint8_t     reserved0;

+    uint16_t    reserved1;

+} mtd_global_settings_t;

+

+/*------------------------------------------------------------------------------

+ * mtd_abps_trim_t

+ *------------------------------------------------------------------------------

+ * The following data structure is used to store ABPS trimming information.

+ */

+typedef struct __mtd_abps_trim_t

+{

+    uint8_t dacdec;

+    uint8_t negtrim_per4_per3b_gtdec;

+} mtd_abps_trim_t;

+

+

+/*------------------------------------------------------------------------------

+ * mtd_calibration_mc_t

+ *------------------------------------------------------------------------------

+ * The following data structure is used to store M and C calibration

+ * coefficients.

+ */

+typedef struct __mtd_calibration_mc_t

+{

+    uint16_t m;

+    uint16_t c;

+} mtd_calibration_mc_t;

+

+

+/*------------------------------------------------------------------------------

+ * mtd_data_t

+ *------------------------------------------------------------------------------

+ * The following data structure is used to hold the full set of manufacturing

+ * test data.

+ */

+typedef struct __mtd_data_t

+{

+    mtd_global_settings_t   global_settings;

+    mtd_abps_trim_t         abps_trimming[NB_OF_QUADS][NB_OF_ABPS_PER_QUAD][NB_OF_ABPS_RANGES];

+    uint8_t                 odb_trimming[NB_OF_ANALOG_MODULES][NB_OF_OBD_MODES][NB_OF_CHOPPING_OPTIONS];

+    mtd_calibration_mc_t    abps_calibration[NB_OF_QUADS][NB_OF_ABPS_PER_QUAD][NB_OF_ABPS_RANGES];

+    mtd_calibration_mc_t    obd_calibration[NB_OF_ANALOG_MODULES][NB_OF_OBD_MODES][NB_OF_CHOPPING_OPTIONS];

+    mtd_calibration_mc_t    cm_calibration[NB_OF_QUADS];

+    mtd_calibration_mc_t    tm_calibration[NB_OF_QUADS];

+    mtd_calibration_mc_t    quads_direct_input_cal[NB_OF_QUADS][2];

+    mtd_calibration_mc_t    adc_direct_input_cal[NB_OF_ANALOG_MODULES][NB_OF_DIRECT_INPUTS_PER_ADC];

+    uint16_t                comparators_offsets[NB_OF_QUADS];

+    uint32_t                ccc_delays_cal;

+} mtd_data_t;

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.c
new file mode 100644
index 0000000..fc17e52
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.c
@@ -0,0 +1,103 @@
+/***************************************************************************//**

+ * @file

+ * crc32 source file.

+ * 

+ * CRC-32-IEEE 802.3 	

+ * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + 

+ * x^4 + x^2 + x + 1

+ *

+ * (c) Copyright 2007 Actel Corporation

+ *

+ * SVN $Revision: 2369 $

+ * SVN $Date: 2010-03-01 18:31:45 +0000 (Mon, 01 Mar 2010) $

+ ******************************************************************************/

+

+ #ifdef __cplusplus

+extern "C" {

+#endif 

+

+#include "crc32.h"

+

+static const uint32_t crc32_table[] = {

+   0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, 0x706af48fUL,

+   0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, 0xe0d5e91eUL, 0x97d2d988UL,

+   0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL,

+   0xf3b97148UL, 0x84be41deUL, 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL,

+   0x136c9856UL, 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,

+   0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, 0xa2677172UL,

+   0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, 0x35b5a8faUL, 0x42b2986cUL,

+   0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL,

+   0x26d930acUL, 0x51de003aUL, 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL,

+   0xcfba9599UL, 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,

+   0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, 0x01db7106UL,

+   0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, 0x9fbfe4a5UL, 0xe8b8d433UL,

+   0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL,

+   0x91646c97UL, 0xe6635c01UL, 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL,

+   0x6c0695edUL, 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,

+   0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, 0xfbd44c65UL,

+   0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, 0x4adfa541UL, 0x3dd895d7UL,

+   0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL,

+   0x44042d73UL, 0x33031de5UL, 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL,

+   0xbe0b1010UL, 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,

+   0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, 0x2eb40d81UL,

+   0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, 0x03b6e20cUL, 0x74b1d29aUL,

+   0xead54739UL, 0x9dd277afUL, 0x04db2615UL, 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL,

+   0x0d6d6a3eUL, 0x7a6a5aa8UL, 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL,

+   0xf00f9344UL, 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,

+   0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, 0x67dd4accUL,

+   0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, 0xd6d6a3e8UL, 0xa1d1937eUL,

+   0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL,

+   0xd80d2bdaUL, 0xaf0a1b4cUL, 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL,

+   0x316e8eefUL, 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,

+   0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, 0xb2bd0b28UL,

+   0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, 0x2cd99e8bUL, 0x5bdeae1dUL,

+   0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL,

+   0x72076785UL, 0x05005713UL, 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL,

+   0x92d28e9bUL, 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,

+   0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, 0x18b74777UL,

+   0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, 0x8f659effUL, 0xf862ae69UL,

+   0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL,

+   0xa7672661UL, 0xd06016f7UL, 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL,

+   0x40df0b66UL, 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,

+   0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, 0xcdd70693UL,

+   0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, 0x5d681b02UL, 0x2a6f2b94UL,

+   0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, 0x2d02ef8dUL

+};

+

+/**

+ * Calculates 32 bits CRC value of given data.

+ */

+uint32_t

+mss_mac_crc32

+(

+    uint32_t value,

+    const uint8_t *data,

+    uint32_t data_length

+)

+{

+  uint32_t a;

+  

+  for(a=0; a<data_length; a++) {

+	value = crc32_table[(value ^ data[a]) & 0xff] ^ (value >> 8);

+  }

+  

+  return value;

+}

+

+/**

+ * Calculates 32 bits CRC value of given data, using standart Ethernet CRC 

+ * function.

+ */

+uint32_t

+mss_ethernet_crc

+(

+    const uint8_t *data,

+    uint32_t data_length

+)

+{

+	return mss_mac_crc32( 0xffffffffUL, data, data_length );

+}

+

+#ifdef __cplusplus

+}

+#endif

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.h
new file mode 100644
index 0000000..ce500a6
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.h
@@ -0,0 +1,46 @@
+/***************************************************************************//**

+ * @file

+ * crc32 header file.

+ *

+ * (c) Copyright 2007 Actel Corporation

+ *

+ * SVN $Revision: 2369 $

+ * SVN $Date: 2010-03-01 18:31:45 +0000 (Mon, 01 Mar 2010) $

+ ******************************************************************************/

+ 

+#ifndef __MSS_ETHERNET_MAC_CRC32_H

+#define __MSS_ETHERNET_MAC_CRC32_H	1

+

+#include <stdint.h>

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/**

+ * Calculates 32 bits CRC value of given data.

+ */

+uint32_t

+mss_mac_crc32

+(

+    uint32_t value,

+    const uint8_t *data,

+    uint32_t data_length

+);

+

+/**

+ * Calculates 32 bits CRC value of given data, using standart Ethernet CRC 

+ * function.

+ */

+uint32_t

+mss_ethernet_crc

+(

+    const uint8_t *data,

+    uint32_t data_length

+);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif	/* __MSS_ETHERNET_MAC_CRC32_H */

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c
new file mode 100644
index 0000000..5ebea2e
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c
@@ -0,0 +1,1543 @@
+/***************************************************************************//**

+ * @file

+ * SmartFusion MSS Ethernet MAC driver implementation.

+ *

+ * (c) Copyright 2007 Actel Corporation

+ *

+ * SVN $Revision: 2369 $

+ * SVN $Date: 2010-03-01 18:31:45 +0000 (Mon, 01 Mar 2010) $

+ *

+ ******************************************************************************/

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+#include "FreeRTOS.h"

+#include "task.h"

+

+#include "crc32.h"

+

+#include "mss_ethernet_mac.h"

+#include "mss_ethernet_mac_regs.h"

+#include "mss_ethernet_mac_desc.h"

+#include "mss_ethernet_mac_conf.h"

+#include "../../CMSIS/mss_assert.h"

+

+#include "phy.h"

+

+/**************************** INTERNAL DEFINES ********************************/

+

+#define MAC_CHECK(CHECK,ERRNO)	\

+	{if(!(CHECK)){g_mss_mac.last_error=(ERRNO); configASSERT((CHECK));}}

+

+/*

+ * Flags

+ */

+#define FLAG_MAC_INIT_DONE		1u

+#define FLAG_PERFECT_FILTERING	2u

+#define FLAG_CRC_DISABLE		4u

+#define FLAG_EXCEED_LIMIT		8u

+

+/*

+ * Return types

+ */

+#define MAC_OK                    0

+#define MAC_FAIL                  (-1)

+#define MAC_WRONG_PARAMETER       (-2)

+#define MAC_TOO_BIG_PACKET        (-3)

+#define MAC_BUFFER_IS_FULL        (-4)

+#define MAC_NOT_ENOUGH_SPACE      (-5)

+#define MAC_TIME_OUT			  (-6)

+#define MAC_TOO_SMALL_PACKET      (-7)

+

+/* Allocating this many buffers will always ensure there is one free as, even

+though TX_RING_SIZE is set to two, the two Tx descriptors will only ever point

+to the same buffer. */

+#define macNUM_BUFFERS RX_RING_SIZE + TX_RING_SIZE + 1

+#define macBUFFER_SIZE 1488

+

+/***************************************************************/

+MAC_instance_t g_mss_mac __attribute__((aligned(4)));

+

+/**************************** INTERNAL DATA ***********************************/

+#define ERROR_MESSAGE_COUNT		8

+#define MAX_ERROR_MESSAGE_WIDTH 40

+static const int8_t unknown_error[] = "Unknown error";

+static const int8_t ErrorMessages[][MAX_ERROR_MESSAGE_WIDTH] = {

+	"No error occured",

+	"Method failed",

+	"Wrong parameter pased to function",

+	"Frame is too long",

+	"Not enough space in buffer",

+	"Not enough space in buffer",

+	"Timed out",

+	"Frame is too small"

+};

+

+/*

+ * Null variables

+ */

+static MAC_instance_t* 	NULL_instance;

+static uint8_t* 		NULL_buffer;

+static MSS_MAC_callback_t 	NULL_callback;

+unsigned char *uip_buf = NULL;

+

+/**************************** INTERNAL FUNCTIONS ******************************/

+

+static int32_t	MAC_test_instance( void );

+

+static int32_t	MAC_dismiss_bad_frames( void );

+static int32_t	MAC_send_setup_frame( void );

+

+static int32_t	MAC_stop_transmission( void );

+static void		MAC_start_transmission( void );

+static int32_t	MAC_stop_receiving( void );

+static void		MAC_start_receiving( void );

+

+static void		MAC_set_time_out( uint32_t time_out );

+static uint32_t	MAC_get_time_out( void );

+

+static void     MAC_memset(uint8_t *s, uint8_t c, uint32_t n);

+static void     MAC_memcpy(uint8_t *dest, const uint8_t *src, uint32_t n);

+static void     MAC_memset_All(MAC_instance_t *s, uint32_t c);

+

+static unsigned char *MAC_obtain_buffer( void );

+static void MAC_release_buffer( unsigned char *pcBufferToRelease );

+

+#if( TX_RING_SIZE != 2 )

+	#error This uIP Ethernet driver required TX_RING_SIZE to be set to 2

+#endif

+

+/* Buffers that will dynamically be allocated to/from the Tx and Rx descriptors. */

+static unsigned char ucMACBuffers[ macNUM_BUFFERS ][ macBUFFER_SIZE ] __attribute__((aligned(4)));

+

+/* Each array position indicated whether or not the buffer of the same index

+is currently allocated to a descriptor (pdFALSE) or is free for use (pdTRUE). */

+static unsigned char ucMACBufferInUse[ macNUM_BUFFERS ] = { 0 };

+

+/***************************************************************************//**

+ * Initializes the Ethernet Controller.

+ * This function will prepare the Ethernet Controller for first time use in a

+ * given hardware/software configuration. This function should be called before

+ * any other Ethernet API functions are called.

+ *

+ * Initialization of registers - config registers, enable Tx/Rx interrupts,

+ * enable Tx/Rx, initialize MAC addr, init PHY, autonegotiation, MAC address

+ * filter table (unicats/multicast)/hash init

+ */

+void

+MSS_MAC_init

+(

+	uint8_t phy_address

+)

+{

+    const uint8_t mac_address[6] = { DEFAULT_MAC_ADDRESS };

+    int32_t a;

+

+	/* To start with all buffers are free. */

+	for( a = 0; a < macNUM_BUFFERS; a++ )

+	{

+		ucMACBufferInUse[ a ] = pdFALSE;

+	}

+	

+    /* Try to reset chip */

+    MAC_BITBAND->CSR0_SWR = 1u;

+

+    do

+    {

+    	vTaskDelay( 10 );

+    } while ( 1u == MAC_BITBAND->CSR0_SWR );

+

+    /* Check reset values of some registers to constrol

+     * base address validity */

+    configASSERT( MAC->CSR0 == 0xFE000000uL );

+    configASSERT( MAC->CSR5 == 0xF0000000uL );

+    configASSERT( MAC->CSR6 == 0x32000040uL );

+

+    /* Instance setup */

+    MAC_memset_All( &g_mss_mac, 0u );

+

+    g_mss_mac.base_address = MAC_BASE;

+    g_mss_mac.phy_address = phy_address;

+

+    for( a=0; a<RX_RING_SIZE; a++ )

+    {

+        /* Give the ownership to the MAC */

+        g_mss_mac.rx_descriptors[a].descriptor_0 = RDES0_OWN;

+        g_mss_mac.rx_descriptors[a].descriptor_1 = (MSS_RX_BUFF_SIZE << RDES1_RBS1_OFFSET);

+		

+		/* Allocate a buffer to the descriptor, then mark the buffer as in use

+		(not free). */

+        g_mss_mac.rx_descriptors[a].buffer_1 = ( unsigned long ) &( ucMACBuffers[ a ][ 0 ] );

+		ucMACBufferInUse[ a ] = pdTRUE;

+    }

+    g_mss_mac.rx_descriptors[RX_RING_SIZE-1].descriptor_1 |= RDES1_RER;

+

+    for( a = 0; a < TX_RING_SIZE; a++ )

+    {

+		/* Buffers only get allocated to the Tx buffers when something is

+		actually tranmitted. */

+        g_mss_mac.tx_descriptors[a].buffer_1 = ( unsigned long ) NULL;

+    }

+    g_mss_mac.tx_descriptors[TX_RING_SIZE - 1].descriptor_1 |= TDES1_TER;

+

+    /* Configurable settings */

+    MAC_BITBAND->CSR0_DBO = DESCRIPTOR_BYTE_ORDERING_MODE;

+    MAC->CSR0 = (MAC->CSR0 & ~CSR0_PBL_MASK) | ((uint32_t)PROGRAMMABLE_BURST_LENGTH << CSR0_PBL_SHIFT);

+    MAC_BITBAND->CSR0_BLE = BUFFER_BYTE_ORDERING_MODE;

+    MAC_BITBAND->CSR0_BAR = (uint32_t)BUS_ARBITRATION_SCHEME;

+

+    /* Fixed settings */

+    /* No automatic polling */

+    MAC->CSR0 = MAC->CSR0 &~ CSR0_TAP_MASK;

+    /* No space between descriptors */

+    MAC->CSR0 = MAC->CSR0 &~ CSR0_DSL_MASK;

+    /* General-purpose timer works in continuous mode */

+    MAC_BITBAND->CSR11_CON = 1u;

+    /* Start general-purpose */

+    MAC->CSR11 =  (MAC->CSR11 & ~CSR11_TIM_MASK) | (0x0000FFFFuL << CSR11_TIM_SHIFT);

+

+    /* Disable promiscuous mode */

+    MAC_BITBAND->CSR6_PR = 0u;

+

+    /* Enable store and forward */

+    MAC_BITBAND->CSR6_SF = 1u;

+

+    /* Set descriptors */

+    MAC->CSR3 = (uint32_t)&(g_mss_mac.rx_descriptors[0].descriptor_0);

+    MAC->CSR4 = (uint32_t)&(g_mss_mac.tx_descriptors[0].descriptor_0);

+    

+	/* enable normal interrupts */

+    MAC_BITBAND->CSR7_NIE = 1u;

+

+    /* Detect PHY */

+    if( g_mss_mac.phy_address > MSS_PHY_ADDRESS_MAX )

+    {

+    	PHY_probe();

+    	configASSERT( g_mss_mac.phy_address <= MSS_PHY_ADDRESS_MAX );

+    }

+

+    /* Reset PHY */

+    PHY_reset();

+

+	/* Set flags */

+    g_mss_mac.flags = FLAG_MAC_INIT_DONE | FLAG_PERFECT_FILTERING;

+

+	/* Configure chip according to PHY status */

+    MSS_MAC_auto_setup_link();

+

+    /* Set default MAC address and reset mac filters */

+   	MAC_memcpy( g_mss_mac.mac_address, mac_address, 6u );

+   	MSS_MAC_set_mac_filters( 0u, NULL_buffer );

+   	MAC_BITBAND->CSR6_RA = 1; /* Receive all. */

+ 	MAC_BITBAND->CSR6_PR = 1; /* Promiscuous mode. */

+ 	MSS_MAC_set_mac_address((uint8_t *)mac_address);

+	

+	/* Ensure uip_buf starts by pointing somewhere. */

+	uip_buf = MAC_obtain_buffer();

+}

+

+

+/***************************************************************************//**

+ * Sets the configuration of the Ethernet Controller.

+ * After the EthernetInit function has been called, this API function can be

+ * used to configure the various features of the Ethernet Controller.

+ *

+ * @param instance      Pointer to a MAC_instance_t structure

+ * @param config        The logical OR of the following values:

+ *    - #MSS_MAC_CFG_RECEIVE_ALL

+ *    - #MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE

+ *    - #MSS_MSS_MAC_CFG_STORE_AND_FORWARD

+ *    - #MAC_CFG_THRESHOLD_CONTROL_[00,01,10,11]

+ *    - #MSS_MAC_CFG_FULL_DUPLEX_MODE

+ *    - #MSS_MAC_CFG_PASS_ALL_MULTICAST

+ *    - #MSS_MAC_CFG_PROMISCUOUS_MODE

+ *    - #MSS_MAC_CFG_PASS_BAD_FRAMES

+ * @see   MAC_get_configuration()

+ */

+void

+MSS_MAC_configure

+(

+    uint32_t configuration

+)

+{

+    int32_t ret;

+

+    configASSERT( MAC_test_instance() == MAC_OK );

+

+    ret = MAC_stop_transmission();

+    configASSERT( ret == MAC_OK );

+

+    ret = MAC_stop_receiving();

+    configASSERT( ret == MAC_OK );

+

+    MAC_BITBAND->CSR6_RA = (uint32_t)(((configuration & MSS_MAC_CFG_RECEIVE_ALL) != 0u) ? 1u : 0u );

+    MAC_BITBAND->CSR6_TTM = (((configuration & MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE) != 0u) ? 1u : 0u );

+    MAC_BITBAND->CSR6_SF = (uint32_t)(((configuration & MSS_MAC_CFG_STORE_AND_FORWARD) != 0u) ? 1u : 0u );

+    

+    switch( configuration & MSS_MAC_CFG_THRESHOLD_CONTROL_11 ) {

+    case MSS_MAC_CFG_THRESHOLD_CONTROL_00:

+        MAC->CSR6 = MAC->CSR6 & ~CSR6_TR_MASK;

+        break;

+    case MSS_MAC_CFG_THRESHOLD_CONTROL_01:

+        MAC->CSR6 = (MAC->CSR6 & ~CSR6_TR_MASK) | ((uint32_t)1 << CSR6_TR_SHIFT );

+        break;

+    case MSS_MAC_CFG_THRESHOLD_CONTROL_10:

+        MAC->CSR6 = (MAC->CSR6 & ~CSR6_TR_MASK) | ((uint32_t)2 << CSR6_TR_SHIFT );

+        break;

+    case MSS_MAC_CFG_THRESHOLD_CONTROL_11:

+        MAC->CSR6 = (MAC->CSR6 & ~CSR6_TR_MASK) | ((uint32_t)3 << CSR6_TR_SHIFT );

+        break;

+    default:

+        break;

+    }

+    MAC_BITBAND->CSR6_FD = (uint32_t)(((configuration & MSS_MAC_CFG_FULL_DUPLEX_MODE) != 0u) ? 1u : 0u );

+    MAC_BITBAND->CSR6_PM = (uint32_t)(((configuration & MSS_MAC_CFG_PASS_ALL_MULTICAST) != 0u) ? 1u : 0u );

+    MAC_BITBAND->CSR6_PR = (uint32_t)(((configuration & MSS_MAC_CFG_PROMISCUOUS_MODE) != 0u) ? 1u : 0u );

+    MAC_BITBAND->CSR6_PB = (uint32_t)(((configuration & MSS_MAC_CFG_PASS_BAD_FRAMES) != 0u) ? 1u : 0u );

+    PHY_set_link_type( (uint8_t)

+        ((((configuration & MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE) != 0u) ? MSS_MAC_LINK_STATUS_100MB : 0u ) |

+        (((configuration & MSS_MAC_CFG_FULL_DUPLEX_MODE) != 0u) ? MSS_MAC_LINK_STATUS_FDX : 0u )) );

+

+    MSS_MAC_auto_setup_link();

+}

+

+

+/***************************************************************************//**

+ * Returns the configuration of the Ethernet Controller.

+ *

+ * @param instance      Pointer to a MAC_instance_t structure

+ * @return              The logical OR of the following values:

+ *    - #MSS_MAC_CFG_RECEIVE_ALL

+ *    - #MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE

+ *    - #MSS_MAC_CFG_STORE_AND_FORWARD

+ *    - #MAC_CFG_THRESHOLD_CONTROL_[00,01,10,11]

+ *    - #MSS_MAC_CFG_FULL_DUPLEX_MODE

+ *    - #MSS_MAC_CFG_PASS_ALL_MULTICAST

+ *    - #MSS_MAC_CFG_PROMISCUOUS_MODE

+ *    - #MSS_MAC_CFG_INVERSE_FILTERING

+ *    - #MSS_MAC_CFG_PASS_BAD_FRAMES

+ *    - #MSS_MAC_CFG_HASH_ONLY_FILTERING_MODE

+ *    - #MSS_MAC_CFG_HASH_PERFECT_RECEIVE_FILTERING_MODE

+ * @see   MAC_configure()

+ */

+int32_t

+MSS_MAC_get_configuration( void )

+{

+    uint32_t configuration;

+

+    configASSERT( MAC_test_instance() == MAC_OK );

+

+    configuration = 0u;

+    if( MAC_BITBAND->CSR6_RA != 0u ) {

+        configuration |= MSS_MAC_CFG_RECEIVE_ALL;

+    }

+

+    if( MAC_BITBAND->CSR6_TTM != 0u ) {

+        configuration |= MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE;

+    }

+

+    if( MAC_BITBAND->CSR6_SF != 0u ) {

+        configuration |= MSS_MAC_CFG_STORE_AND_FORWARD;

+    }

+

+    switch( (MAC->CSR6 & CSR6_TR_MASK) >> CSR6_TR_SHIFT ) {

+    case 1: configuration |= MSS_MAC_CFG_THRESHOLD_CONTROL_01; break;

+    case 2: configuration |= MSS_MAC_CFG_THRESHOLD_CONTROL_10; break;

+    case 3: configuration |= MSS_MAC_CFG_THRESHOLD_CONTROL_11; break;

+    default: break;

+    }

+    if( MAC_BITBAND->CSR6_FD != 0u ) {

+        configuration |= MSS_MAC_CFG_FULL_DUPLEX_MODE;

+    }

+

+    if( MAC_BITBAND->CSR6_PM != 0u ) {

+        configuration |= MSS_MAC_CFG_PASS_ALL_MULTICAST;

+    }

+

+    if( MAC_BITBAND->CSR6_PR != 0u ) {

+        configuration |= MSS_MAC_CFG_PROMISCUOUS_MODE;

+    }

+

+    if( MAC_BITBAND->CSR6_IF != 0u ) {

+        configuration |= MSS_MAC_CFG_INVERSE_FILTERING;

+    }

+

+    if( MAC_BITBAND->CSR6_PB != 0u ) {

+        configuration |= MSS_MAC_CFG_PASS_BAD_FRAMES;

+    }

+

+    if( MAC_BITBAND->CSR6_HO != 0u ) {

+        configuration |= MSS_MAC_CFG_HASH_ONLY_FILTERING_MODE;

+    }

+

+    if( MAC_BITBAND->CSR6_HP != 0u ) {

+        configuration |= MSS_MAC_CFG_HASH_PERFECT_RECEIVE_FILTERING_MODE;

+    }

+    

+    return (int32_t)configuration;

+}

+

+

+/***************************************************************************//**

+  Sends a packet from the uIP stack to the Ethernet Controller.

+  The MSS_MAC_tx_packet() function is used to send a packet to the MSS Ethernet

+  MAC. This function writes uip_len bytes of the packet contained in uip_buf into

+  the transmit FIFO and then activates the transmitter for this packet. If space

+  is available in the FIFO, the function will return once pac_len bytes of the

+  packet have been placed into the FIFO and the transmitter has been started.

+  This function will not wait for the transmission to complete. 

+

+  @return

+    The function returns zero if a timeout occurs otherwise it returns size of the packet.

+    

+  @see   MAC_rx_packet()

+ */

+

+int32_t

+MSS_MAC_tx_packet

+(

+    unsigned short usLength

+)

+{

+	uint32_t desc;

+	unsigned long ulDescriptor;

+    int32_t error = MAC_OK;

+	extern unsigned char *uip_buf;

+

+    configASSERT( MAC_test_instance() == MAC_OK );

+

+    configASSERT( uip_buf != NULL_buffer );

+

+	configASSERT( usLength >= 12 );

+

+    if( (g_mss_mac.flags & FLAG_EXCEED_LIMIT) == 0u )

+    {

+		configASSERT( usLength <= MSS_MAX_PACKET_SIZE );

+	}

+

+	/* Check if second descriptor is free, if it is then the first must

+	also be free. */

+	if(((g_mss_mac.tx_descriptors[ 1 ].descriptor_0) & TDES0_OWN) == TDES0_OWN )

+	{

+		error = MAC_BUFFER_IS_FULL;

+	}

+

+	if( error == MAC_OK )

+	{

+		/* Assumed TX_RING_SIZE == 2. */

+		for( ulDescriptor = 0; ulDescriptor < TX_RING_SIZE; ulDescriptor++ )

+		{

+			g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 = 0u;

+

+			if( (g_mss_mac.flags & FLAG_CRC_DISABLE) != 0u ) {

+				g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= TDES1_AC;

+			}

+

+			/* Every buffer can hold a full frame so they are always first and last

+			   descriptor */

+			g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= TDES1_LS | TDES1_FS | TDES1_IC;

+

+			/* set data size */

+			g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= usLength;

+

+			/* reset end of ring */

+			g_mss_mac.tx_descriptors[TX_RING_SIZE-1].descriptor_1 |= TDES1_TER;

+

+			if( usLength > MSS_TX_BUFF_SIZE ) /* FLAG_EXCEED_LIMIT */

+			{

+				usLength = (uint16_t)MSS_TX_BUFF_SIZE;

+			}

+

+			/* The data buffer is assigned to the Tx descriptor. */

+			g_mss_mac.tx_descriptors[ ulDescriptor ].buffer_1 = ( unsigned long ) uip_buf;

+

+			/* update counters */

+			desc = g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_0;

+			if( (desc & TDES0_LO) != 0u ) {

+				g_mss_mac.statistics.tx_loss_of_carrier++;

+			}

+			if( (desc & TDES0_NC) != 0u ) {

+				g_mss_mac.statistics.tx_no_carrier++;

+			}

+			if( (desc & TDES0_LC) != 0u ) {

+				g_mss_mac.statistics.tx_late_collision++;

+			}

+			if( (desc & TDES0_EC) != 0u ) {

+				g_mss_mac.statistics.tx_excessive_collision++;

+			}

+			if( (desc & TDES0_UF) != 0u ) {

+				g_mss_mac.statistics.tx_underflow_error++;

+			}

+			g_mss_mac.statistics.tx_collision_count +=

+				(desc >> TDES0_CC_OFFSET) & TDES0_CC_MASK;

+

+			/* Give ownership of descriptor to the MAC */

+			g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_0 = RDES0_OWN;

+		}

+

+		/* Start transmission */

+		MAC_start_transmission();

+		g_mss_mac.tx_desc_index = 0;

+		/* transmit poll demand */

+		MAC->CSR1 = 1u;

+    }

+

+

+	

+	

+    if (error == MAC_OK)

+    {

+		/* The buffer uip_buf was pointing to is now under the control of the 

+		MAC (it is being transmitted).  Set uip_buf to point to a free buffer. */

+		uip_buf = MAC_obtain_buffer();

+        error = (int32_t)usLength;

+    }

+    else

+    {

+        error = 0;

+    }

+    return ( error );

+}

+

+

+/***************************************************************************//**

+ * Returns available packet size.

+ *

+ * @param instance      Pointer to a MAC_instance_t structure

+ * @return              size of packet, bigger than 0, if a packet is available.

+ *                      If not, returns 0.

+ * @see   MAC_rx_packet()

+ */

+int32_t

+MSS_MAC_rx_pckt_size

+(

+    void

+)

+{

+    int32_t retval;

+    configASSERT( MAC_test_instance() == MAC_OK );

+

+    MAC_dismiss_bad_frames();

+

+    if( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 &	RDES0_OWN) != 0u )

+    {

+    	/* Current descriptor is empty */

+    	retval = 0;

+    }

+    else

+    {

+        uint32_t frame_length;

+        frame_length = ( g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 >> RDES0_FL_OFFSET ) & RDES0_FL_MASK;

+        retval = (int32_t)( frame_length );

+    }

+    return retval;

+}

+

+

+/***************************************************************************//**

+ * Receives a packet from the Ethernet Controller into the uIP stack.

+ * This function reads a packet from the receive FIFO of the controller and

+ * places it into uip_buf.

+ 

+ * @return              Size of packet if packet fits in uip_buf.

+ * 					    0 if there is no received packet.

+ * @see   MAC_rx_pckt_size()

+ * @see   MAC_tx_packet()

+ */

+int32_t

+MSS_MAC_rx_packet

+(

+	void

+)

+{

+	uint16_t frame_length=0u;

+

+    configASSERT( MAC_test_instance() == MAC_OK );

+    

+    MAC_dismiss_bad_frames();

+

+    if( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 & RDES0_OWN) == 0u )

+    {

+        frame_length = ( (

+    	    g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 >>

+    	    RDES0_FL_OFFSET ) & RDES0_FL_MASK );

+

+        /* strip crc */

+        frame_length -= 4u;

+

+        if( frame_length > macBUFFER_SIZE ) {

+        	return MAC_NOT_ENOUGH_SPACE;

+        }

+       

+		/* uip_buf is about to point to the buffer that contains the received

+		data, mark the buffer that uip_buf is currently pointing to as free

+		again. */

+		MAC_release_buffer( uip_buf );

+        uip_buf = ( unsigned char * ) g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1;

+		

+		/* The buffer the Rx descriptor was pointing to is now in use by the

+		uIP stack - allocate a new buffer to the Rx descriptor. */

+		g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1 = ( unsigned long ) MAC_obtain_buffer();

+

+        MSS_MAC_prepare_rx_descriptor();

+    }

+    return ((int32_t)frame_length);

+}

+

+

+/***************************************************************************//**

+ * Receives a packet from the Ethernet Controller.

+ * This function reads a packet from the receive FIFO of the controller and

+ * sets the address of pacData to the received data. 

+ * If time_out parameter is zero the function will return

+ * immediately (after the copy operation if data is available. Otherwise the function

+ * will keep trying to read till time_out expires or data is read, if MSS_MAC_BLOCKING

+ * value is given as time_out, function will wait for the reception to complete.

+ *

+ * @param instance      Pointer to a MAC_instance_t structure

+ * @param pacData       The pointer to the packet data.

+ * @param time_out      Time out value in milli seconds for receiving.

+ * 					    if value is #MSS_MAC_BLOCKING, there will be no time out.

+ * 					    if value is #MSS_MAC_NONBLOCKING, function will return immediately

+ * 					    if there is no packet waiting.

+ * 					    Otherwise value must be greater than 0 and smaller than

+ * 					    0x01000000.

+ * @return              Size of packet if packet fits in pacData.

+ * 					    0 if there is no received packet.

+ * @see   MAC_rx_pckt_size()

+ * @see   MAC_tx_packet()

+ */

+int32_t

+MSS_MAC_rx_packet_ptrset

+(

+    uint8_t **pacData,

+    uint32_t time_out

+)

+{

+	uint16_t frame_length = 0u;

+    int8_t exit = 0;

+

+    configASSERT( MAC_test_instance() == MAC_OK );

+

+    configASSERT(  (time_out == MSS_MAC_BLOCKING) ||

+    			(time_out == MSS_MAC_NONBLOCKING) ||

+    			((time_out >= 1) && (time_out <= 0x01000000UL)) );

+

+    MAC_dismiss_bad_frames();

+

+    /* wait for a packet */

+	if( time_out != MSS_MAC_BLOCKING ) {

+		if( time_out == MSS_MAC_NONBLOCKING ) {

+    		MAC_set_time_out( 0u );

+		} else {

+    		MAC_set_time_out( time_out );

+		}

+	}

+

+    while( ((g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 &

+    	RDES0_OWN) != 0u) && (exit == 0) )

+    {

+    	if( time_out != MSS_MAC_BLOCKING )

+    	{

+    		if( MAC_get_time_out() == 0u ) {

+    			exit = 1;

+    		}

+    	}

+    }

+

+    if(exit == 0)

+    {

+        frame_length = ( (

+    	    g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 >>

+    	    RDES0_FL_OFFSET ) & RDES0_FL_MASK );

+

+        /* strip crc */

+        frame_length -= 4u;

+

+       /* Here we are setting the buffer 'pacData' address to the address

+          RX descriptor address. After this is called, the following function

+          must be called 'MAC_prepare_rx_descriptor' 

+          to prepare the current rx descriptor for receiving the next packet.

+       */       

+    	*pacData = (uint8_t *)g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1 ;         

+        

+    }

+    return ((int32_t)frame_length);

+}

+

+/***************************************************************************//**

+ * Returns the status of connection.

+ *

+ * @return              the logical OR of the following values:

+ *      #MSS_MAC_LINK_STATUS_LINK    - Link up/down

+ *      #MSS_MAC_LINK_STATUS_100MB   - Connection is 100Mb/10Mb

+ *      #MSS_MAC_LINK_STATUS_FDX     - Connection is full/half duplex

+ * @see   MAC_auto_setup_link()

+ */

+int32_t

+MSS_MAC_link_status

+(

+    void

+)

+{

+	uint32_t link;

+

+    configASSERT( MAC_test_instance() == MAC_OK );

+

+    link = PHY_link_status();

+    if( link == MSS_MAC_LINK_STATUS_LINK ) {

+    	link |= PHY_link_type();

+    }

+

+    return ((int32_t)link);

+}

+

+

+/***************************************************************************//**

+ * Setups the link between PHY and MAC and returns the status of connection.

+ *

+ * @return              the logical OR of the following values:

+ *      #MSS_MAC_LINK_STATUS_LINK    - Link up/down

+ *      #MSS_MAC_LINK_STATUS_100MB   - Connection is 100Mb/10Mb

+ *      #MSS_MAC_LINK_STATUS_FDX     - Connection is full/half duplex

+ * @see   MAC_link_status()

+ */

+int32_t

+MSS_MAC_auto_setup_link

+(

+    void

+)

+{

+	int32_t link;

+    configASSERT( MAC_test_instance() == MAC_OK );

+

+    PHY_auto_negotiate();

+

+    link = MSS_MAC_link_status();

+

+    if( (link & MSS_MAC_LINK_STATUS_LINK) != 0u ) {

+    	int32_t ret;

+	    ret = MAC_stop_transmission();

+	    MAC_CHECK( ret == MAC_OK, ret );

+

+	    ret = MAC_stop_receiving();

+	    MAC_CHECK( ret == MAC_OK, ret );

+        MAC_BITBAND->CSR6_TTM = (uint32_t)((((uint32_t)link & MSS_MAC_LINK_STATUS_100MB) != 0u) ? 1u : 0u );

+        MAC_BITBAND->CSR6_FD = (uint32_t)((((uint32_t)link & MSS_MAC_LINK_STATUS_FDX) != 0u) ? 1u : 1u );

+	    MAC_start_transmission();

+	    MAC_start_receiving();

+    }

+

+    return link;

+}

+

+

+/***************************************************************************//**

+ * Sets mac address. New address must be unicast.

+ *

+ * @param new_address   Pointer to a MAC_instance_t structure

+ * @see   MAC_get_mac_address()

+ */

+void

+MSS_MAC_set_mac_address

+(

+    const uint8_t *new_address

+)

+{

+    configASSERT( MAC_test_instance() == MAC_OK );

+    /* Check if the new address is unicast */

+    configASSERT( (new_address[0]&1) == 0 );

+

+   	MAC_memcpy( g_mss_mac.mac_address, new_address, 6u );

+

+   	if((g_mss_mac.flags & FLAG_PERFECT_FILTERING) != 0u ) {

+		int32_t a;

+	   	/* set unused filters to the new mac address */

+		for( a=14*6; a>=0; a-=6 ) {

+			if( (g_mss_mac.mac_filter_data[a] & 1u) != 0u ) {

+				/* Filters with multicast addresses are used */

+				a = -1;

+			} else {

+				MAC_memcpy( &(g_mss_mac.mac_filter_data[a]),

+					g_mss_mac.mac_address, 6u );

+			}

+		}

+   	}

+

+   	MAC_send_setup_frame();

+}

+

+

+/***************************************************************************//**

+ * Returns mac address.

+ *

+ * @param address       Pointer to receive the MAC address

+ * @see   MAC_set_mac_address()

+ */

+void

+MSS_MAC_get_mac_address

+(

+    uint8_t *address

+)

+{

+    configASSERT( MAC_test_instance() == MAC_OK );

+

+   	MAC_memcpy( address, g_mss_mac.mac_address, 6u );

+}

+

+

+/***************************************************************************//**

+ * Sets mac address filters. Addresses must be multicast.

+ *

+ * @param filter_count  number of addresses

+ * @param filters       Pointer to addresses to be filtered

+ */

+void

+MSS_MAC_set_mac_filters

+(

+	uint16_t filter_count,

+	const uint8_t *filters

+)

+{

+    configASSERT( MAC_test_instance() == MAC_OK );

+    configASSERT( (filter_count==0) || (filters != NULL_buffer) );

+    /* Check if the mac addresses is multicast */

+    {

+    	int32_t a;

+    	for( a = 0u; a < filter_count; a++ ) {

+    		configASSERT( (filters[a*6]&1) == 1 );

+    	}

+    }

+

+    if( filter_count <= 15 ){

+    	int32_t a;

+    	g_mss_mac.flags |= FLAG_PERFECT_FILTERING;

+

+    	/* copy new filters */

+    	MAC_memcpy( g_mss_mac.mac_filter_data, filters, (uint32_t)(filter_count*6));

+

+    	/* set unused filters to our mac address */

+    	for( a=filter_count; a<15; a++ ) {

+   			MAC_memcpy( &(g_mss_mac.mac_filter_data[a*6]),

+   				g_mss_mac.mac_address, 6 );

+    	}

+    } else {

+    	int32_t a,b;

+    	uint32_t hash;

+

+    	g_mss_mac.flags &= ~FLAG_PERFECT_FILTERING;

+

+    	/* reset hash table */

+    	MAC_memset( g_mss_mac.mac_filter_data, 0u, 64u );

+

+    	for( a=0, b=0; a<filter_count; a++, b+=6 ) {

+    		hash = mss_ethernet_crc( &(filters[b]), 6 ) & 0x1FF;

+    		g_mss_mac.mac_filter_data[ hash / 8 ] |= 1 << (hash & 0x7);

+    	}

+    }

+

+    MAC_send_setup_frame();

+}

+

+

+/***************************************************************************//**

+ * MAC interrupt service routine.

+ *

+ * @param instance      Pointer to a MAC_instance_t structure

+ * @see   MAC_set_callback()

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void EthernetMAC_IRQHandler( void )

+#else

+void EthernetMAC_IRQHandler( void )

+#endif

+{

+    uint32_t events;

+    uint32_t intr_status;

+

+    configASSERT( MAC_test_instance() == MAC_OK );

+

+    events = 0u;

+    intr_status = MAC->CSR5;

+

+    if( (intr_status & CSR5_NIS_MASK) != 0u ) {

+    	if( (intr_status & CSR5_TI_MASK) != 0u ) { /* Transmit */

+    		g_mss_mac.statistics.tx_interrupts++;

+    		events |= MSS_MAC_EVENT_PACKET_SEND;

+    	}

+

+    	if( (intr_status & CSR5_RI_MASK) != 0u ) { /* Receive */

+    		g_mss_mac.statistics.rx_interrupts++;

+    		events |= MSS_MAC_EVENT_PACKET_RECEIVED;

+    	}

+    }

+

+    /* Clear interrupts */

+    MAC->CSR5 = CSR5_INT_BITS;

+    

+    if( (events != 0u) && (g_mss_mac.listener != NULL_callback) ) {

+        g_mss_mac.listener( events );

+    }

+}

+

+

+/***************************************************************************//**

+ * Sets MAC event listener.

+ * Sets the given event listener function to be triggered inside MAC_isr().

+ * Assigning NULL pointer as the listener function will disable it.

+ *

+ * @param instance      Pointer to a MAC_instance_t structure

+ * @param listener      function pointer to a MAC_callback_t function

+ * @return              #MAC_OK if everything is OK

+ *                      #MAC_WRONG_PARAMETER if instance is null or hasn't been

+ * 						initialized.

+ * @see   MAC_isr()

+ */

+void

+MSS_MAC_set_callback

+(

+    MSS_MAC_callback_t listener

+)

+{

+    configASSERT( MAC_test_instance() == MAC_OK );

+

+	/* disable tx and rx interrupts */

+    MAC_BITBAND->CSR7_RIE = 0u;

+    MAC_BITBAND->CSR7_TIE = 0u;

+    

+    g_mss_mac.listener = listener;

+

+	if( listener != NULL_callback ) {

+		/* enable tx and rx interrupts */

+        MAC_BITBAND->CSR7_RIE = 1u;

+        MAC_BITBAND->CSR7_TIE = 1u;

+	}

+}

+

+

+/***************************************************************************//**

+ * Returns description of last error.

+ *

+ * @param instance      Pointer to a MAC_instance_t structure

+ * @return              A string describing the error. This string must not be

+ * 						modified by the application.

+ *                      #MAC_WRONG_PARAMETER if instance is null or hasn't been

+ *                      initialized.

+ */

+const int8_t*

+MSS_MAC_last_error

+(

+    void

+)

+{

+	int8_t error_msg_nb;

+    const int8_t* returnvalue;

+    

+    configASSERT( MAC_test_instance() == MAC_OK );

+

+	error_msg_nb = -(g_mss_mac.last_error);

+	if( error_msg_nb >= ERROR_MESSAGE_COUNT ) {

+		returnvalue = unknown_error;

+	} else {

+		returnvalue = ErrorMessages[error_msg_nb];

+	}

+	return returnvalue;

+}

+

+

+/***************************************************************************//**

+ * Returns statistics counter of stat_id identifier.

+ *

+ * @param instance      Pointer to a MAC_instance_t structure

+ * @param stat_id		Identifier of statistics counter.

+ * @return				Statistics counter of stat_id identifier.

+ * 						On error returns 0.

+ */

+uint32_t

+MSS_MAC_get_statistics

+(

+    mss_mac_statistics_id_t stat_id

+)

+{

+    uint32_t returnval = 0u;

+    configASSERT( MAC_test_instance() == MAC_OK );

+

+	switch( stat_id ) {

+	case MSS_MAC_RX_INTERRUPTS:

+		returnval = g_mss_mac.statistics.rx_interrupts;

+        break;

+	case MSS_MAC_RX_FILTERING_FAIL:

+		returnval = g_mss_mac.statistics.rx_filtering_fail;

+        break;

+	case MSS_MAC_RX_DESCRIPTOR_ERROR:

+		returnval = g_mss_mac.statistics.rx_descriptor_error;

+        break;

+	case MSS_MAC_RX_RUNT_FRAME:

+		returnval = g_mss_mac.statistics.rx_runt_frame;

+        break;

+	case MSS_MAC_RX_NOT_FIRST:

+		returnval = g_mss_mac.statistics.rx_not_first;

+        break;

+	case MSS_MAC_RX_NOT_LAST:

+		returnval = g_mss_mac.statistics.rx_not_last;

+        break;

+	case MSS_MAC_RX_FRAME_TOO_LONG:

+		returnval = g_mss_mac.statistics.rx_frame_too_long;

+        break;

+	case MSS_MAC_RX_COLLISION_SEEN:

+		returnval = g_mss_mac.statistics.rx_collision_seen;

+        break;

+	case MSS_MAC_RX_CRC_ERROR:

+		returnval = g_mss_mac.statistics.rx_crc_error;

+        break;

+	case MSS_MAC_RX_FIFO_OVERFLOW:

+		returnval = g_mss_mac.statistics.rx_fifo_overflow;

+        break;

+	case MSS_MAC_RX_MISSED_FRAME:

+		returnval = g_mss_mac.statistics.rx_missed_frame;

+        break;

+	case MSS_MAC_TX_INTERRUPTS:

+		returnval = g_mss_mac.statistics.tx_interrupts;

+        break;

+	case MSS_MAC_TX_LOSS_OF_CARRIER:

+		returnval = g_mss_mac.statistics.tx_loss_of_carrier;

+        break;

+	case MSS_MAC_TX_NO_CARRIER:

+		returnval = g_mss_mac.statistics.tx_no_carrier;

+        break;

+	case MSS_MAC_TX_LATE_COLLISION:

+		returnval = g_mss_mac.statistics.tx_late_collision;

+        break;

+	case MSS_MAC_TX_EXCESSIVE_COLLISION:

+		returnval = g_mss_mac.statistics.tx_excessive_collision;

+        break;

+	case MSS_MAC_TX_COLLISION_COUNT:

+		returnval = g_mss_mac.statistics.tx_collision_count;

+        break;

+	case MSS_MAC_TX_UNDERFLOW_ERROR:

+		returnval = g_mss_mac.statistics.tx_underflow_error;

+        break;

+    default:

+        break;

+	}

+

+	return returnval;

+}

+

+

+/**************************** INTERNAL FUNCTIONS ******************************/

+

+/***************************************************************************//**

+ * Checks if instace is valid.

+ */

+static int32_t

+MAC_test_instance

+(

+    void

+)

+{

+    uint32_t val1;

+    uint32_t val2;

+    int32_t retval = MAC_WRONG_PARAMETER;

+

+    val1 = MAC->CSR3;

+    val2 = MAC->CSR4;

+

+    if( (&g_mss_mac != NULL_instance) &&

+    	((g_mss_mac.flags & FLAG_MAC_INIT_DONE) != 0u) &&

+    	( val1 == (uint32_t)g_mss_mac.rx_descriptors) &&

+    	(val2 == (uint32_t)g_mss_mac.tx_descriptors ) )

+    {

+    	retval = MAC_OK;

+    }

+    return retval;

+}

+

+/***************************************************************************//**

+ * Prepares current rx descriptor for receiving.

+ */

+void

+MSS_MAC_prepare_rx_descriptor

+(

+    void

+)

+{

+	uint32_t desc;

+

+	/* update counters */

+	desc = g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0;

+	if( (desc & RDES0_FF) != 0u ) {

+		g_mss_mac.statistics.rx_filtering_fail++;

+	}

+	if( (desc & RDES0_DE) != 0u ) {

+		g_mss_mac.statistics.rx_descriptor_error++;

+	}

+	if( (desc & RDES0_RF) != 0u ) {

+		g_mss_mac.statistics.rx_runt_frame++;

+	}

+	if( (desc & RDES0_FS) == 0u ) {

+		g_mss_mac.statistics.rx_not_first++;

+	}

+	if( (desc & RDES0_LS) == 0u ) {

+		g_mss_mac.statistics.rx_not_last++;

+	}

+	if( (desc & RDES0_TL) != 0u ) {

+		g_mss_mac.statistics.rx_frame_too_long++;

+	}

+	if( (desc & RDES0_CS) != 0u ) {

+		g_mss_mac.statistics.rx_collision_seen++;

+	}

+	if( (desc & RDES0_CE) != 0u ) {

+		g_mss_mac.statistics.rx_crc_error++;

+	}

+    

+	desc = MAC->CSR8;

+	g_mss_mac.statistics.rx_fifo_overflow +=

+		(desc & (CSR8_OCO_MASK|CSR8_FOC_MASK)) >> CSR8_FOC_SHIFT;

+	g_mss_mac.statistics.rx_missed_frame +=

+		(desc & (CSR8_MFO_MASK|CSR8_MFC_MASK));

+

+	/* Give ownership of descriptor to the MAC */

+	g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 =

+		RDES0_OWN;

+	g_mss_mac.rx_desc_index = (g_mss_mac.rx_desc_index + 1u) % RX_RING_SIZE;

+

+	/* Start receive */

+    MAC_start_receiving();

+}

+

+

+/***************************************************************************//**

+ * Prepares a setup frame and sends it to MAC.

+ * This function is blocking.

+ * @return		#MAC_OK if everything is ok.

+ * 				#MAC_TIME_OUT if timed out before packet send.

+ */

+static int32_t

+MAC_send_setup_frame

+(

+    void

+)

+{

+	volatile MAC_descriptor_t descriptor;

+	uint8_t	frame_data[192];

+	uint8_t *data;

+	int32_t a,b,c,d;

+	int32_t ret;

+

+    /* prepare descriptor */

+	descriptor.descriptor_0 = TDES0_OWN;

+	descriptor.descriptor_1 = TDES1_SET | TDES1_TER |

+		(sizeof(frame_data) << TDES1_TBS1_OFFSET);

+

+	if( (g_mss_mac.flags & FLAG_PERFECT_FILTERING) == 0u ) {

+		descriptor.descriptor_1 |= TDES1_FT0;

+	}

+

+	descriptor.buffer_1 = (uint32_t)frame_data;

+	descriptor.buffer_2 = 0u;

+

+    /* prepare frame */

+    if( (g_mss_mac.flags & FLAG_PERFECT_FILTERING) != 0u ) {

+    	b = 0;

+    	d = 12;

+    	c = 90;

+    } else {

+    	b = 156;

+    	d = 0;

+    	c = 64;

+    }

+

+   	data = g_mss_mac.mac_address;

+   	frame_data[b] = data[0];

+   	frame_data[b+1] = data[1];

+   	frame_data[b+4] = data[2];

+   	frame_data[b+5] = data[3];

+   	frame_data[b+8] = data[4];

+   	frame_data[b+9] = data[5];

+

+   	data = g_mss_mac.mac_filter_data;

+    for( a = 0; a < c; ) {

+		frame_data[d] = data[a++];

+	   	frame_data[d+1] = data[a++];

+	   	frame_data[d+4] = data[a++];

+	   	frame_data[d+5] = data[a++];

+	   	frame_data[d+8] = data[a++];

+	   	frame_data[d+9] = data[a++];

+	   	d += 12;

+	}

+

+	/* Stop transmission */

+    ret = MAC_stop_transmission();

+    configASSERT( ret == MAC_OK );

+

+    ret = MAC_stop_receiving();

+    configASSERT( ret == MAC_OK );

+

+    /* Set descriptor */

+    MAC->CSR4 = (uint32_t)&descriptor;

+    

+	/* Start transmission */

+    MAC_start_transmission();

+

+    /* Wait until transmission over */

+    ret = MAC_OK;

+    MAC_set_time_out( (uint32_t)SETUP_FRAME_TIME_OUT );

+    

+    while( (((MAC->CSR5 & CSR5_TS_MASK) >> CSR5_TS_SHIFT) != 

+    	CSR5_TS_SUSPENDED) && (MAC_OK == ret) )

+    {

+    	/* transmit poll demand */

+    	MAC->CSR1 = 1u;

+    	if( MAC_get_time_out() == 0u ) {

+    		ret = MAC_TIME_OUT;

+    	}

+    }

+

+	MAC_CHECK( MAC_stop_transmission() == MAC_OK, MAC_FAIL );

+

+    /* Set tx descriptor */

+    MAC->CSR4 = (uint32_t)g_mss_mac.tx_descriptors;

+    

+    /* Start receiving and transmission */

+    MAC_start_receiving();

+    MAC_start_transmission();

+

+    return ret;

+}

+

+

+/***************************************************************************//**

+ * Stops transmission.

+ * Function will wait until transmit operation enters stop state.

+ *

+ * @return			#MAC_OK if everything is ok.

+ * 					#MAC_TIME_OUT if timed out.

+ */

+static int32_t

+MAC_stop_transmission

+(

+    void

+)

+{

+    int32_t retval = MAC_OK;

+    MAC_set_time_out( (uint16_t)STATE_CHANGE_TIME_OUT );

+    

+	while( (((MAC->CSR5 & CSR5_TS_MASK) >> CSR5_TS_SHIFT) !=

+		CSR5_TS_STOPPED) && (retval == MAC_OK) )

+	{

+    	MAC_BITBAND->CSR6_ST = 0u;

+    	if( MAC_get_time_out() == 0u ) {

+    		retval = MAC_TIME_OUT;

+    	}

+	}

+	return retval;

+}

+

+

+/***************************************************************************//**

+ * Starts transmission.

+ */

+static void

+MAC_start_transmission

+(

+    void

+)

+{

+    MAC_BITBAND->CSR6_ST = 1u;

+}

+

+

+/***************************************************************************//**

+ * Stops transmission.

+ * Function will wait until transmit operation enters stop state.

+ *

+ * @return			#MAC_OK if everything is ok.

+ * 					#MAC_TIME_OUT if timed out.

+ */

+static int32_t

+MAC_stop_receiving

+(

+    void

+)

+{

+    int32_t retval = MAC_OK;

+    MAC_set_time_out( (uint16_t)STATE_CHANGE_TIME_OUT );

+

+	while( (((MAC->CSR5 & CSR5_RS_MASK) >> CSR5_RS_SHIFT) != CSR5_RS_STOPPED)

+            && (retval == MAC_OK) )

+	{

+    	MAC_BITBAND->CSR6_SR = 0u;

+    	if( MAC_get_time_out() == 0u ) {

+    		retval = MAC_TIME_OUT;

+    	}

+	}

+

+	return retval;

+}

+

+

+/***************************************************************************//**

+ * Starts transmission.

+ */

+static void

+MAC_start_receiving

+(

+    void

+)

+{

+    MAC_BITBAND->CSR6_SR = 1u;

+}

+

+

+/***************************************************************************//**

+ * Dismisses bad frames.

+ *

+ * @return		dismissed frame count.

+ */

+static int32_t

+MAC_dismiss_bad_frames

+(

+    void

+)

+{

+	int32_t dc = 0;

+	int8_t cont = 1;

+    

+	if( MAC_BITBAND->CSR6_PB != 0u ) {

+		/* User wants bad frames too, don't dismiss anything */

+		cont = 0;

+	}

+

+	while( ( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 &

+            RDES0_OWN) == 0u) && (cont == 1) ) /* Host owns this descriptor */

+    {

+    	/* check error summary */

+    	if( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 &

+    		(RDES0_ES | RDES0_LS | RDES0_FS)) != (RDES0_LS | RDES0_FS) )

+    	{

+    		MSS_MAC_prepare_rx_descriptor();

+    		dc++;

+    	}

+        else

+        {

+    		cont = 0;

+    	}

+    }

+

+	return dc;

+}

+

+/***************************************************************************//**

+ * Sets time out value.

+ * #MAC_get_time_out must be called frequently to make time out value updated.

+ * Because of user may not be using ISR, we can not update time out in ISR.

+ *

+ * @time_out	time out value in milli seconds.

+ * 				Must be smaller than 0x01000000.

+ */

+static void

+MAC_set_time_out

+(

+    uint32_t time_out

+)

+{

+	g_mss_mac.time_out_value = (time_out * 122u) / 10u;

+

+	g_mss_mac.last_timer_value = (uint16_t)( MAC->CSR11 & CSR11_TIM_MASK );

+}

+

+/***************************************************************************//**

+ * Returns time out value.

+ *

+ * @return		timer out value in milli seconds.

+ */

+static uint32_t

+MAC_get_time_out

+(

+    void

+)

+{

+	uint32_t timer;

+	uint32_t time = 0u;

+    

+	timer = ( MAC->CSR11 & CSR11_TIM_MASK );

+    

+	if( timer > g_mss_mac.last_timer_value ) {

+		time = 0x0000ffffUL;

+	}

+	time += g_mss_mac.last_timer_value - timer;

+    

+	if( MAC_BITBAND->CSR6_TTM == 0u ) {

+		time *= 10u;

+	}

+	if( g_mss_mac.time_out_value <= time ){

+		g_mss_mac.time_out_value = 0u;

+	} else {

+		g_mss_mac.time_out_value -= time;

+	}

+

+	g_mss_mac.last_timer_value = (uint16_t)timer;

+

+	return ((g_mss_mac.time_out_value * 10u) / 122u);

+}

+

+/***************************************************************************//**

+ * Fills the first n bytes of the memory area pointed to by s with the constant

+ * byte c.

+ */

+static void MAC_memset(uint8_t *s, uint8_t c, uint32_t n)

+{

+    uint8_t *sb = s;

+

+    while( n > 0u ) {

+    	n--;

+        sb[n] = c;

+    }

+}

+

+/***************************************************************************//**

+ * Fills all fields of MAC_instance_t with c.

+ *

+ * @return          a pointer to the given MAC_instance_t s.

+ */

+static void MAC_memset_All(MAC_instance_t *s, uint32_t c)

+{

+    int32_t count;

+    s->base_address = (addr_t)c;

+    s->flags = (uint8_t)c;

+    s->last_error = (int8_t)c;

+    s->last_timer_value = (uint16_t)c;

+    s->listener = NULL_callback;

+   	MAC_memset( s->mac_address, (uint8_t)c, 6u );

+   	MAC_memset( s->mac_filter_data, (uint8_t)c, 90u );

+    s->phy_address = (uint8_t)c;

+//    for(count = 0; count<RX_RING_SIZE ;count++)

+//    {

+//        MAC_memset(s->rx_buffers[count], (uint8_t)c, (MSS_RX_BUFF_SIZE + 4u) );

+//    }

+    s->rx_desc_index =c;

+    for(count = 0; count<RX_RING_SIZE ;count++)

+    {

+        s->rx_descriptors[count].buffer_1 = c;

+        s->rx_descriptors[count].buffer_2 = c;

+        s->rx_descriptors[count].descriptor_0 = c;

+        s->rx_descriptors[count].descriptor_1 = c;

+    }

+    s->statistics.rx_collision_seen =c;

+    s->statistics.rx_crc_error = c;

+    s->statistics.rx_descriptor_error = c;

+    s->statistics.rx_fifo_overflow = c;

+    s->statistics.rx_filtering_fail = c;

+    s->statistics.rx_frame_too_long = c;

+    s->statistics.rx_interrupts = c;

+    s->statistics.rx_missed_frame = c;

+    s->statistics.rx_not_first = c;

+    s->statistics.rx_not_last = c;

+    s->statistics.rx_runt_frame = c;

+    s->statistics.tx_collision_count = c;

+    s->statistics.tx_excessive_collision = c;

+    s->statistics.tx_interrupts = c;

+    s->statistics.tx_late_collision = c;

+    s->statistics.tx_loss_of_carrier = c;

+    s->statistics.tx_no_carrier = c;

+    s->statistics.tx_underflow_error = c;

+    s->time_out_value = c;

+//    for(count = 0; count < TX_RING_SIZE ;count++)

+//    {

+//        MAC_memset( s->tx_buffers[count], (uint8_t)c, MSS_TX_BUFF_SIZE );

+//    }

+    s->tx_desc_index = c;

+    for(count = 0; count < TX_RING_SIZE ;count++)

+    {

+        s->tx_descriptors[count].buffer_1 = c;

+        s->tx_descriptors[count].buffer_2 = c;

+        s->tx_descriptors[count].descriptor_0 = c;

+        s->tx_descriptors[count].descriptor_1 = c;

+    }

+}

+

+/***************************************************************************//**

+ * Copies n bytes from memory area src to memory area dest.

+ * The memory areas should not overlap.

+ *

+ * @return          a pointer to the memory area dest.

+ */

+static void MAC_memcpy(uint8_t *dest, const uint8_t *src, uint32_t n)

+{

+    uint8_t *d = dest;

+

+    while( n > 0u ) {

+    	n--;

+        d[n] = src[n];

+    }

+}

+

+void MSS_MAC_TxBufferCompleted( void )

+{

+unsigned char *pxTransmittedBuffer;

+

+	/* Was it the second transmission that has completed? */

+	if( ( g_mss_mac.tx_descriptors[ 1 ].descriptor_0 & TDES0_OWN ) == 0UL )

+	{

+		pxTransmittedBuffer = ( unsigned char * ) g_mss_mac.tx_descriptors[ 1 ].buffer_1;

+

+		/* The buffer has been transmitted and is no longer in use. */

+		MAC_release_buffer( pxTransmittedBuffer );

+	}

+	else

+	{

+//		configASSERT( 0 );

+	}

+}

+

+static unsigned char *MAC_obtain_buffer( void )

+{

+long lIndex;

+unsigned char *pcReturn = NULL;

+

+	/* Find and return the address of a buffer that is not being used.  Mark

+	the buffer as now in use. */

+	for( lIndex = 0; lIndex < macNUM_BUFFERS; lIndex++ )

+	{

+		if( ucMACBufferInUse[ lIndex ] == pdFALSE )

+		{

+			pcReturn = &( ucMACBuffers[ lIndex ][ 0 ] );

+			ucMACBufferInUse[ lIndex ] = pdTRUE;

+			break;

+		}

+	}

+	

+	configASSERT( pcReturn );

+	return pcReturn;

+}

+

+void MAC_release_buffer( unsigned char *pucBufferToRelease )

+{

+long lIndex;

+

+	/* uip_buf is going to point to a different buffer - first ensure the buffer

+	it is currently pointing to is marked as being free again. */

+	for( lIndex = 0; lIndex < macNUM_BUFFERS; lIndex++ )

+	{

+		if( pucBufferToRelease == &( ucMACBuffers[ lIndex ][ 0 ] ) )

+		{

+			/* This is the buffer in use, mark it as being free. */

+			ucMACBufferInUse[ lIndex ] = pdFALSE;

+			break;

+		}

+	}

+	

+	configASSERT( lIndex < macNUM_BUFFERS );

+}

+

+

+

+#ifdef __cplusplus

+}

+#endif

+

+/******************************** END OF FILE *********************************/

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.h
new file mode 100644
index 0000000..0757105
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.h
@@ -0,0 +1,585 @@
+/***************************************************************************//**

+ * @file

+ * SmartFusion MSS Ethernet MAC header file.

+ *

+ * (c) Copyright 2007 Actel Corporation

+ *

+ * SVN $Revision: 2364 $

+ * SVN $Date: 2010-03-01 17:58:41 +0000 (Mon, 01 Mar 2010) $

+ *

+ *******************************************************************************/

+

+#ifndef __MSS_ETHERNET_MAC_H

+#define __MSS_ETHERNET_MAC_H	1

+

+#include <stdint.h>

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/******************************** DEFINES *************************************/

+

+/*******************************************************************************

+ * Configure values.

+ */

+/**

+ * Receive all.

+ * When set, all incoming frames are received, regardless of their destination address.

+ * An address check is performed, and the result of the check is written into the receive

+ * descriptor.

+ */

+#define MSS_MAC_CFG_RECEIVE_ALL                         0x00000001u

+

+/**

+ * Transmit threshold mode.

+ * 1 - Transmit FIFO threshold set for 100 Mbps mode

+ * 0 - Transmit FIFO threshold set for 10 Mbps mode

+ * This bit can be changed only when a transmit process is in a stopped state.

+ */

+#define MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE             0x00000002u

+

+/**

+ * Store and forward.

+ * When set, the transmission starts after a full packet is written into the transmit

+ * FIFO, regardless of the current FIFO threshold level.

+ * This bit can be changed only when the transmit process is in the stopped state.

+ */

+#define MSS_MAC_CFG_STORE_AND_FORWARD                   0x00000004u

+

+/**

+ * Threshold control bits.

+ * These bits, together with TTM, SF, and PS, control the threshold level for the

+ * transmit FIFO.

+ */

+#define MSS_MAC_CFG_THRESHOLD_CONTROL_00                0x00000000u

+#define MSS_MAC_CFG_THRESHOLD_CONTROL_01                0x00000008u

+#define MSS_MAC_CFG_THRESHOLD_CONTROL_10                0x00000010u

+#define MSS_MAC_CFG_THRESHOLD_CONTROL_11                0x00000018u

+

+/**

+ * Full-duplex mode.

+ * 0 - Half-duplex mode <br>

+ * 1 - Forcing full-duplex mode <br>

+ * Changing of this bit is allowed only when both the transmitter and receiver processes

+ * are in the stopped state.

+ */

+#define MSS_MAC_CFG_FULL_DUPLEX_MODE                    0x00000020u

+

+/**

+ * Pass all multicast.

+ * When set, all frames with multicast destination addresses will be received, regardless

+ * of the address check result.

+ */

+#define MSS_MAC_CFG_PASS_ALL_MULTICAST                  0x00000040u

+

+/**

+ * Promiscuous mode.

+ * When set, all frames will be received regardless of the address check result. An

+ * address check is not performed.

+ */

+#define MSS_MAC_CFG_PROMISCUOUS_MODE                    0x00000080u

+

+/**

+ * Inverse filtering (read-only).

+ * If this bit is set when working in a perfect filtering mode, the receiver performs an

+ * inverse filtering during the address check process.

+ * The 'filtering type' bits of the setup frame determine the state of this bit.

+ */

+#define MSS_MAC_CFG_INVERSE_FILTERING                   0x00000100u

+

+/**

+ * Pass bad frames.

+ * When set, Core10/100 transfers all frames into the data buffers, regardless of the

+ * receive errors. This allows the runt frames, collided fragments, and truncated frames

+ * to be received.

+ */

+#define MSS_MAC_CFG_PASS_BAD_FRAMES                     0x00000200u

+

+/**

+ * Hash-only filtering mode (read-only).

+ * When set, Core10/100 performs an imperfect filtering over both the multicast and

+ * physical addresses.

+ * The 'filtering type' bits of the setup frame determine the state of this bit.

+ */

+#define MSS_MAC_CFG_HASH_ONLY_FILTERING_MODE            0x00000400u

+

+/**

+ * Hash/perfect receive filtering mode (read-only).

+ * 0 - Perfect filtering of the incoming frames is performed according to the physical

+ * addresses specified in a setup frame. <br>

+ * 1 - Imperfect filtering over the frames with the multicast addresses is performed

+ * according to the hash table specified in a setup frame. <br>

+ * A physical address check is performed according to the CSR6.2 (HO, hash-only) bit.

+ * When both the HO and HP bits are set, an imperfect filtering is performed on all of

+ * the addresses.

+ * The 'filtering type' bits of the setup frame determine the state of this bit.

+ */

+#define MSS_MAC_CFG_HASH_PERFECT_RECEIVE_FILTERING_MODE 0x00000800u

+

+

+/*******************************************************************************

+ * Link status values.

+ */

+#define MSS_MAC_LINK_STATUS_LINK  0x0001u   /**< Link up/down */

+#define MSS_MAC_LINK_STATUS_100MB 0x0002u   /**< Connection is 100Mb/10Mb */

+#define MSS_MAC_LINK_STATUS_FDX   0x0004u   /**< Connection is full/half duplex */

+

+

+/**

+ * Size of the max packet that can be received/transmited.

+ */

+#define MSS_MAX_PACKET_SIZE  1514uL

+

+/**

+ * Size of a receive/transmit buffer.

+ * Buffer size must be enough big to hold a full frame and must be multiple of

+ * four. For rx buffer +4 bytes allocated for crc values. These bytes doesn't

+ * copied to the user buffer.

+ */

+#define MSS_TX_BUFF_SIZE  ((MSS_MAX_PACKET_SIZE + 3u) & (~(uint32_t)3))

+#define MSS_RX_BUFF_SIZE  ((MSS_MAX_PACKET_SIZE + 7u) & (~(uint32_t)3))

+

+/*******************************************************************************

+ * Time out values.

+ */

+#define MSS_MAC_NONBLOCKING		0u

+#define MSS_MAC_BLOCKING		0xFFFFFFFFUL

+

+/***************************************************************************//**

+ * MAC events.

+ */

+#define MSS_MAC_EVENT_PACKET_SEND		1u

+#define MSS_MAC_EVENT_PACKET_RECEIVED	2u

+

+/***************************************************************************//**

+ * PHY addresses.

+ */

+#define MSS_PHY_ADDRESS_MIN				0u

+#define MSS_PHY_ADDRESS_MAX				31u

+#define MSS_PHY_ADDRESS_AUTO_DETECT		255u

+

+/***************************************************************************//**

+ * Listener function type defines the function prototype that might be followed 

+ * by MAC_isr which is triggered with each receive and transmit related interrupts.

+ * Listener functions should follow the following prototype:

+ *		void MAC_Listener( uint32_t events );

+ * The parameter is used to inform the listener function about the triggering event

+ * or events. Events input to the system are:

+ *      #define MSS_MAC_EVENT_PACKET_SEND		1

+ *      #define MSS_MAC_EVENT_PACKET_RECEIVED	2

+ * Listener function should be defined by the application using this driver if 

+ * needed. This function may be assigned to the driver using MAC_set_callback

+ * routine and may be un assigned again by using the same routine with a NULL pointer

+ * as the event listener function. It is recommended to use this property for interrupt

+ * triggered systems and it is not recommended for polling mechanisms.

+ */

+typedef void (*MSS_MAC_callback_t)(uint32_t events);

+

+/***************************************************************************//**

+ * Statistics counter identifiers are used with MAC_get_statistics routine to 

+ * receive the count of the requested errors/interrupts occurrences.

+ *

+ * MSS_MAC_RX_INTERRUPTS

+ *      Used to receive the number of receive interrupts occurred.

+ *

+ * MSS_MAC_RX_FILTERING_FAIL

+ *      Used to receive the number of received frames which did not pass the

+ *      address recognition process.

+ *

+ * MSS_MAC_RX_DESCRIPTOR_ERROR

+ *      Used to receive the number of occurrences of; no receive buffer was

+ *      available when trying to store the received data.

+ *

+ * MSS_MAC_RX_RUNT_FRAME

+ *      Used to receive the number of occurrences of; the frame is damaged by a

+ *      collision or by a premature termination before the end of a collision

+ *      window.

+ *

+ * MSS_MAC_RX_NOT_FIRST

+ *      Used to receive the number of occurrences of; start of the frame is not

+ *      the first descriptor of a frame.

+ *

+ * MSS_MAC_RX_NOT_LAST

+ *      Used to receive the number of occurrences of; end of the frame is not

+ *      the first descriptor of a frame.

+ *

+ * MSS_MAC_RX_FRAME_TOO_LONG

+ *      Used to receive the number of occurrences of; a current frame is longer

+ *      than maximum size of 1,518 bytes, as specified by 802.3.

+ *

+ * MSS_MAC_RX_COLLISION_SEEN

+ *      Used to receive the number of occurrences of; a late collision was seen

+ *      (collision after 64 bytes following SFD).

+ *

+ * MSS_MAC_RX_CRC_ERROR

+ *      Used to receive the number of occurrences of; a CRC error has occurred

+ *      in the received frame.

+ *

+ * MSS_MAC_RX_FIFO_OVERFLOW

+ *      Used to receive the number of frames not accepted due to the receive

+ *      FIFO overflow.

+ *

+ * MSS_MAC_RX_MISSED_FRAME

+ *      Used to receive the number of frames not accepted due to the

+ *      unavailability of the receive descriptor.

+ *

+ * MSS_MAC_TX_INTERRUPTS

+ *      Used to receive the number of transmit interrupts occurred.

+ *

+ * MSS_MAC_TX_LOSS_OF_CARRIER

+ *      Used to receive the number of occurrences of; a loss of the carrier

+ *      during a transmission.

+ *

+ * MSS_MAC_TX_NO_CARRIER

+ *      Used to receive the number of occurrences of; the carrier was not asserted

+ *      by an external transceiver during the transmission.

+ *

+ * MSS_MAC_TX_LATE_COLLISION

+ *      Used to receive the number of occurrences of; a collision was detected

+ *      after transmitting 64 bytes.

+ *

+ * MSS_MAC_TX_EXCESSIVE_COLLISION

+ *      Used to receive the number of occurrences of; the transmission was aborted

+ *      after 16 retries.

+ *

+ * MSS_MAC_TX_COLLISION_COUNT

+ *      Used to receive the number of collisions occurred.

+ *

+ * MSS_MAC_TX_UNDERFLOW_ERROR

+ *      Used to receive the number of occurrences of; the FIFO was empty during

+ *      the frame transmission.

+ */

+typedef enum {

+	MSS_MAC_RX_INTERRUPTS,

+	MSS_MAC_RX_FILTERING_FAIL,

+	MSS_MAC_RX_DESCRIPTOR_ERROR,

+	MSS_MAC_RX_RUNT_FRAME,

+	MSS_MAC_RX_NOT_FIRST,

+	MSS_MAC_RX_NOT_LAST,

+	MSS_MAC_RX_FRAME_TOO_LONG,

+	MSS_MAC_RX_COLLISION_SEEN,

+	MSS_MAC_RX_CRC_ERROR,

+	MSS_MAC_RX_FIFO_OVERFLOW,

+	MSS_MAC_RX_MISSED_FRAME,

+	

+	MSS_MAC_TX_INTERRUPTS,

+	MSS_MAC_TX_LOSS_OF_CARRIER,

+	MSS_MAC_TX_NO_CARRIER,

+	MSS_MAC_TX_LATE_COLLISION,

+	MSS_MAC_TX_EXCESSIVE_COLLISION,

+	MSS_MAC_TX_COLLISION_COUNT,

+	MSS_MAC_TX_UNDERFLOW_ERROR

+} mss_mac_statistics_id_t; 

+

+/******************************* FUNCTIONS ************************************/

+

+/***************************************************************************//**

+ * Initializes an Ethernet MAC controller and data structures.

+ * This function will prepare the Ethernet Controller for first time use in a

+ * given hardware/software configuration. This function should be called before

+ * any other Ethernet API functions are called.

+ *

+ * Initialization of registers - config registers, enable Tx/Rx interrupts,

+ * enable Tx/Rx, initialize MAC addr, init PHY, autonegotiation, MAC address

+ * filter table (unicast/multicast)/hash init

+ *

+ */

+void

+MSS_MAC_init

+(

+    uint8_t phy_address

+);

+

+

+/***************************************************************************//**

+ * Sets the configuration of the Ethernet Controller.

+ * After the MAC_init function has been called, this API function can be

+ * used to configure the various features of the Ethernet Controller.

+ *

+ * @param configuration The logical OR of the following values:

+ *    - #MSS_MAC_CFG_RECEIVE_ALL

+ *    - #MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE

+ *    - #MSS_MAC_CFG_STORE_AND_FORWARD

+ *    - #MSS_MAC_CFG_THRESHOLD_CONTROL_[00,01,10,11]

+ *    - #MSS_MAC_CFG_FULL_DUPLEX_MODE

+ *    - #MSS_MAC_CFG_PASS_ALL_MULTICAST

+ *    - #MSS_MAC_CFG_PROMISCUOUS_MODE

+ *    - #MSS_MAC_CFG_PASS_BAD_FRAMES

+ * @see   MAC_get_configuration()

+ */

+void

+MSS_MAC_configure

+(

+    uint32_t configuration

+);

+

+

+/***************************************************************************//**

+ * Returns the configuration of the Ethernet Controller.

+ * After the MAC_init function has been called, this API function can be used to 

+ * get the configuration of the Ethernet Controller.

+ *

+ * @return              The logical OR of the following values:

+ *    - #MSS_MAC_CFG_RECEIVE_ALL

+ *    - #MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE

+ *    - #MSS_MAC_CFG_STORE_AND_FORWARD

+ *    - #MSS_MAC_CFG_THRESHOLD_CONTROL_[00,01,10,11]

+ *    - #MSS_MAC_CFG_FULL_DUPLEX_MODE

+ *    - #MSS_MAC_CFG_PASS_ALL_MULTICAST

+ *    - #MSS_MAC_CFG_PROMISCUOUS_MODE

+ *    - #MSS_MAC_CFG_INVERSE_FILTERING

+ *    - #MSS_MAC_CFG_PASS_BAD_FRAMES

+ *    - #MSS_MAC_CFG_HASH_ONLY_FILTERING_MODE

+ *    - #MSS_MAC_CFG_HASH_PERFECT_RECEIVE_FILTERING_MODE

+ * @see   MAC_configure()

+ */

+int32_t

+MSS_MAC_get_configuration

+(

+    void

+);

+

+

+/***************************************************************************//**

+  Sends a packet from the uIP stack to the Ethernet Controller.

+  The MSS_MAC_tx_packet() function is used to send a packet to the MSS Ethernet

+  MAC. This function writes uip_len bytes of the packet contained in uip_buf into

+  the transmit FIFO and then activates the transmitter for this packet. If space

+  is available in the FIFO, the function will return once pac_len bytes of the

+  packet have been placed into the FIFO and the transmitter has been started.

+  This function will not wait for the transmission to complete.

+

+  @return

+    The function returns zero if a timeout occurs otherwise it returns size of the packet.

+

+  @see   MAC_rx_packet()

+ */

+

+int32_t

+MSS_MAC_tx_packet

+(

+    unsigned short usLength

+);

+

+/***************************************************************************//**

+ * Returns available packet's size.

+ *

+ * @return              Size of packet, bigger than 0, if a packet is available,

+ *                      if not, returns 0. 

+ * @see   MAC_rx_packet()

+ */

+int32_t

+MSS_MAC_rx_pckt_size

+(

+    void

+);

+

+

+

+/***************************************************************************//**

+ * Prepares the RX descriptor for receiving packets.

+ *

+ * @return              void

+ * @see   MAC_rx_packet()

+ */

+void

+MSS_MAC_prepare_rx_descriptor

+(

+    void

+);

+

+/***************************************************************************//**

+ * Receives a packet from the Ethernet Controller into the uIP stack.

+ * This function reads a packet from the receive FIFO of the controller and

+ * places it into uip_buf.

+

+ * @return              Size of packet if packet fits in uip_buf.

+ * 					    0 if there is no received packet.

+ * @see   MAC_rx_pckt_size()

+ * @see   MAC_tx_packet()

+ */

+int32_t

+MSS_MAC_rx_packet

+(

+	void

+);

+

+

+/***************************************************************************//**

+  Receives a packet from the Ethernet Controller.

+  The MSS_MAC_rx_packet_ptrset() function is very similar to the MSS_MAC_rx_packet()

+  function, in that it receives data from the MSS Ethernet MAC. The difference

+  is that it sets pacData to point to the memory buffer where the MSS Ethernet

+  MAC copied the received packet instead of copying the received packet into a

+  buffer provided by the application. After this function is called and data is

+  used by the user application or copied to another buffer, the

+  MSS_MAC_prepare_rx_descriptor() function must be called to free up the receive

+  memory buffer used by the MSS Ethernet MAC

+ 

+  @param pacData

+   The pacData parameter is a pointer to a memory buffer pointer. The uint8_t

+   pointer pointed to by the pacData parameter will contain the address of the

+   memory buffer containing the received packet after this function returns. The

+   value of pacData is only valid if the return value is larger than zero,

+   indicating that a packet was received.

+   

+  @param time_out

+    The time_out parameter is the timeout value for the transmission in milliseconds.

+    The time_out parameter value can be one of the following values:

+        • Unsigned integer greater than 0 and less than 0x01000000

+        • MSS_MAC_BLOCKING – there will be no timeout. 

+        • MSS_MAC_NONBLOCKING – the function will return immediately if no packets

+          have been received. 

+

+  @return

+  	The function returns the size of the packet if the packet fits in pacData.

+    Returns zero if there is no received packet.

+                        

+  @see   MAC_rx_pckt_size()

+  @see   MAC_tx_packet()

+ */

+int32_t

+MSS_MAC_rx_packet_ptrset

+(

+    uint8_t **pacData,

+    uint32_t time_out

+);

+

+/***************************************************************************//**

+ * Returns the status of connection by reading it from the PHY.

+ *

+ * @return              the logical OR of the following values:

+ *      #MSS_MAC_LINK_STATUS_LINK    - Link up/down

+ *      #MSS_MAC_LINK_STATUS_100MB   - Connection is 100Mb/10Mb

+ *      #MSS_MAC_LINK_STATUS_FDX     - Connection is full/half duplex

+ * @see   MAC_auto_setup_link()

+ */

+int32_t

+MSS_MAC_link_status

+(

+    void

+);

+

+

+/***************************************************************************//**

+ * Setups the link between PHY and MAC and returns the status of connection.

+ *

+ * @return              the logical OR of the following values:

+ *      #MSS_MAC_LINK_STATUS_LINK    - Link up/down

+ *      #MSS_MAC_LINK_STATUS_100MB   - Connection is 100Mb/10Mb

+ *      #MSS_MAC_LINK_STATUS_FDX     - Connection is full/half duplex

+ * @see   MAC_link_status()

+ */

+int32_t

+MSS_MAC_auto_setup_link

+(

+    void

+);

+

+

+/***************************************************************************//**

+ * Sets mac address.

+ *

+ * @param new_address   Pointer to then new address value (6 bytes of data)

+ * @see   MAC_get_mac_address()

+ */

+void

+MSS_MAC_set_mac_address

+(

+    const uint8_t *new_address

+);

+

+

+/***************************************************************************//**

+ * Returns mac address.

+ *

+ * @param address       Pointer to the parameter to receive the MAC address.

+ * @see   MAC_set_mac_address()

+ */

+void

+MSS_MAC_get_mac_address

+(

+    uint8_t *address

+);

+

+

+/***************************************************************************//**

+ * Sets mac address filters.

+ * If less than 15 addresses are subscribed, system works on perfect filtering mode

+ * else system works in hash table mode

+ *

+ * @param filter_count  number of addresses

+ * @param filters       Pointer to addresses to be filtered

+ */

+void

+MSS_MAC_set_mac_filters

+(

+    uint16_t filter_count,

+	const uint8_t *filters

+);

+

+/***************************************************************************//**

+ * Sets MAC event listener.

+ * Sets the given event listener function to be triggered inside MAC_isr().

+ * Assigning NULL pointer as the listener function will disable it.

+ *

+ * @param listener      function pointer to a MSS_MAC_callback_t function

+ * @see   MAC_isr()

+ */

+void

+MSS_MAC_set_callback

+(

+    MSS_MAC_callback_t listener

+);

+

+

+/***************************************************************************//**

+ * Returns description of latest error happened.

+ *

+ * @return              A string describing the error. This string must not be 

+ * 						modified by the application.

+ */

+const int8_t* 

+MSS_MAC_last_error

+(

+    void

+);

+

+

+/***************************************************************************//**

+ * Returns statistics counter of stat_id identifier.

+ * 

+ * @param stat_id		Identifier of statistics counter.

+ * @return				Statistics counter of stat_id identifier.

+ * 						On error returns 0.

+ */

+uint32_t

+MSS_MAC_get_statistics

+(

+	mss_mac_statistics_id_t stat_id

+);

+

+/*

+ * Ensure uip_buf is pointing to a valid and free buffer before any transmissions

+ * initiated by the uIP stack occur.
+ */

+unsigned char *MSS_MAC_GetTxDescriptor( void );

+

+/*

+ * A buffer is no longer required by the application.  Hand it back to the

+ * control of the MAC hardware.
+ */

+void MSS_MAC_ReleaseBuffer( unsigned char *pucBuffer );

+

+/*

+ * The double Tx has completed.  Hand back the Tx buffer to the control of

+ * the MAC hardware.
+ */

+void MSS_MAC_TxBufferCompleted( void );

+#ifdef __cplusplus

+}

+#endif

+

+#endif	/* __MSS_ETHERNET_MAC_H */

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_conf.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_conf.h
new file mode 100644
index 0000000..ac144b3
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_conf.h
@@ -0,0 +1,43 @@
+/***************************************************************************//**

+ * @file

+ * SmartFusion MSS Ethenet MAC configuration header file.

+ *

+ * (c) Copyright 2007 Actel Corporation

+ *

+ * SVN $Revision: 2299 $

+ * SVN $Date: 2010-02-24 21:21:12 +0000 (Wed, 24 Feb 2010) $

+ *******************************************************************************/

+#ifndef __MSS_ETHERNET_MAC_CONF_H

+#define __MSS_ETHERNET_MAC_CONF_H	1

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/**

+ * Default MAC address

+ */

+#define DEFAULT_MAC_ADDRESS             configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5

+#define BROADCAST_MAC_ADDRESS 			0xFFu,0xFFu,0xFFu,0xFFu,0xFFu,0xFFu

+

+/**

+ * Descriptor byte ordering mode.

+ * 1 - Big-endian mode used for data descriptors <br>

+ * 0 - Little-endian mode used for data descriptors <br>

+ */

+#define DESCRIPTOR_BYTE_ORDERING_MODE   LITTLEENDIAN

+

+/**

+ * Big/little endian.

+ * Selects the byte-ordering mode used by the data buffers.

+ * 1 - Big-endian mode used for the data buffers

+ * 0 - Little-endian mode used for the data buffers

+ */

+#define BUFFER_BYTE_ORDERING_MODE       LITTLEENDIAN

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif	/* __MSS_ETHERNET_MAC_CONF_H */

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_desc.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_desc.h
new file mode 100644
index 0000000..dc697f1
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_desc.h
@@ -0,0 +1,346 @@
+/***************************************************************************//**

+ * @file

+ * SmartFusion MSS Ethernet MAC internal defines header file.

+ *

+ * (c) Copyright 2007 Actel Corporation

+ *

+ * SVN $Revision: 2299 $

+ * SVN $Date: 2010-02-24 21:21:12 +0000 (Wed, 24 Feb 2010) $

+ *******************************************************************************/

+#ifndef __MSS_ETHERNET_MAC_DESC_H

+#define __MSS_ETHERNET_MAC_DESC_H	1

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/*******************************************************************************

+ * Receive descriptor bits

+ */

+

+/***************************************************************************//**

+ * Ownership bit.

+ * 1 - Core10/100 owns the descriptor. <br>

+ * 0 - The host owns the descriptor. <br>

+ * Core10/100 will clear this bit when it completes a current frame reception or 

+ * when the data buffers associated with a given descriptor are already full.

+ */

+#define RDES0_OWN   0x80000000UL

+

+/***************************************************************************//**

+ * Filtering fail.

+ * When set, indicates that a received frame did not pass the address recognition process.

+ * This bit is valid only for the last descriptor of the frame (RDES0.8 set), when the CSR6.30 (receive all) bit

+ * is set and the frame is at least 64 bytes long.

+ */

+#define RDES0_FF    0x40000000UL

+

+/***************************************************************************//**

+ * Frame length.

+ * Indicates the length, in bytes, of the data transferred into a host memory for a given frame

+ * This bit is valid only when RDES0.8 (last descriptor) is set and RDES0.14 (descriptor error) is cleared.

+ */

+#define RDES0_FL_MASK	0x00003FFFUL

+#define RDES0_FL_OFFSET	16

+

+/***************************************************************************//**

+ * Error summary.

+ * This bit is a logical OR of the following bits:

+ * RDES0.1 - CRC error

+ * RDES0.6 - Collision seen

+ * RDES0.7 - Frame too long

+ * RDES0.11 - Runt frame

+ * RDES0.14 - Descriptor error

+ * This bit is valid only when RDES0.8 (last descriptor) is set.

+ */

+#define RDES0_ES    0x00008000UL

+

+/***************************************************************************//**

+ * Descriptor error.

+ * Set by Core10/100 when no receive buffer was available when trying to store the received data.

+ * This bit is valid only when RDES0.8 (last descriptor) is set.

+ */

+#define RDES0_DE    0x00004000UL

+

+/***************************************************************************//**

+ * Runt frame.

+ * When set, indicates that the frame is damaged by a collision or by a premature termination before the end

+ * of a collision window.

+ * This bit is valid only when RDES0.8 (last descriptor) is set.

+ */

+#define RDES0_RF    0x00000800UL

+

+/***************************************************************************//**

+ * Multicast frame.

+ * When set, indicates that the frame has a multicast address.

+ * This bit is valid only when RDES0.8 (last descriptor) is set.

+ */

+#define RDES0_MF    0x00000400UL

+

+/***************************************************************************//**

+ * First descriptor.

+ * When set, indicates that this is the first descriptor of a frame.

+ */

+#define RDES0_FS    0x00000200UL

+

+/***************************************************************************//**

+ * Last descriptor.

+ * When set, indicates that this is the last descriptor of a frame.

+ */

+#define RDES0_LS    0x00000100UL

+

+/***************************************************************************//**

+ * Frame too long.

+ * When set, indicates that a current frame is longer than maximum size of 1,518 bytes, as specified by 802.3.

+ * TL (frame too long) in the receive descriptor has been set when the received frame is longer than

+ * 1,518 bytes. This flag is valid in all receive descriptors when multiple descriptors are used for one frame.

+ */

+#define RDES0_TL    0x00000080UL

+

+/***************************************************************************//**

+ * Collision seen.

+ * When set, indicates that a late collision was seen (collision after 64 bytes following SFD).

+ * This bit is valid only when RDES0.8 (last descriptor) is set.

+ */

+#define RDES0_CS    0x00000040UL

+

+/***************************************************************************//**

+ * Frame type.

+ * When set, indicates that the frame has a length field larger than 1,500 (Ethernet-type frame). When

+ * cleared, indicates an 802.3-type frame.

+ * This bit is valid only when RDES0.8 (last descriptor) is set.

+ * Additionally, FT is invalid for runt frames shorter than 14 bytes.

+ */

+#define RDES0_FT    0x00000020UL

+

+/***************************************************************************//**

+ * Report on MII error.

+ * When set, indicates that an error has been detected by a physical layer chip connected through the MII

+ * interface.

+ * This bit is valid only when RDES0.8 (last descriptor) is set.

+ */

+#define RDES0_RE    0x00000008UL

+

+/***************************************************************************//**

+ * Dribbling bit.

+ * When set, indicates that the frame was not byte-aligned.

+ * This bit is valid only when RDES0.8 (last descriptor) is set.

+ */

+#define RDES0_DB    0x00000004UL

+

+/***************************************************************************//**

+ * CRC error.

+ * When set, indicates that a CRC error has occurred in the received frame.

+ * This bit is valid only when RDES0.8 (last descriptor) is set.

+ * Additionally, CE is not valid when the received frame is a runt frame.

+ */

+#define RDES0_CE    0x00000002UL

+

+/***************************************************************************//**

+ * This bit is reset for frames with a legal length.

+ */

+#define RDES0_ZERO  0x00000001UL

+

+/***************************************************************************//**

+ * Receive end of ring.

+ * When set, indicates that this is the last descriptor in the receive descriptor ring. Core10/100 returns to the

+ * first descriptor in the ring, as specified by CSR3 (start of receive list address).

+ */

+#define RDES1_RER   0x02000000UL

+

+/***************************************************************************//**

+ * Second address chained.

+ * When set, indicates that the second buffer's address points to the next descriptor and not to the data buffer.

+ * Note that RER takes precedence over RCH.

+ */

+#define RDES1_RCH   0x01000000UL

+

+/***************************************************************************//**

+ * Buffer 2 size.

+ * Indicates the size, in bytes, of memory space used by the second data buffer. This number must be a

+ * multiple of four. If it is 0, Core10/100 ignores the second data buffer and fetches the next data descriptor.

+ * This number is valid only when RDES1.24 (second address chained) is cleared.

+ */

+#define RDES1_RBS2_MASK		0x7FF

+#define RDES1_RBS2_OFFSET	11

+

+/***************************************************************************//**

+ * Buffer 1 size

+ * Indicates the size, in bytes, of memory space used by the first data buffer. This number must be a multiple of

+ * four. If it is 0, Core10/100 ignores the first data buffer and uses the second data buffer.

+ */

+#define RDES1_RBS1_MASK		0x7FF

+#define RDES1_RBS1_OFFSET	0

+

+

+/*******************************************************************************

+ * Transmit descriptor bits

+ */

+

+/***************************************************************************//**

+ * Ownership bit.

+ * 1 - Core10/100 owns the descriptor.

+ * 0 - The host owns the descriptor.

+ * Core10/100 will clear this bit when it completes a current frame transmission or when the data buffers

+ * associated with a given descriptor are empty.

+ */

+#define TDES0_OWN     0x80000000uL

+

+/***************************************************************************//**

+ * Error summary.

+ * This bit is a logical OR of the following bits:

+ * TDES0.1 - Underflow error

+ * TDES0.8 - Excessive collision error

+ * TDES0.9 - Late collision

+ * TDES0.10 - No carrier

+ * TDES0.11 - Loss of carrier

+ * This bit is valid only when TDES1.30 (last descriptor) is set.

+ */

+#define TDES0_ES      ((uint32_t)1 << 15)

+

+/***************************************************************************//**

+ * Loss of carrier.

+ * When set, indicates a loss of the carrier during a transmission.

+ * This bit is valid only when TDES1.30 (last descriptor) is set.

+ */

+#define TDES0_LO      ((uint32_t)1 << 11)

+

+/***************************************************************************//**

+ * No carrier.

+ * When set, indicates that the carrier was not asserted by an external transceiver during the transmission.

+ * This bit is valid only when TDES1.30 (last descriptor) is set.

+ */

+#define TDES0_NC      ((uint32_t)1 << 10)

+

+/***************************************************************************//**

+ * Late collision.

+ * When set, indicates that a collision was detected after transmitting 64 bytes.

+ * This bit is not valid when TDES0.1 (underflow error) is set.

+ * This bit is valid only when TDES1.30 (last descriptor) is set.

+ */

+#define TDES0_LC      ((uint32_t)1 << 9)

+

+/***************************************************************************//**

+ * Excessive collisions.

+ * When set, indicates that the transmission was aborted after 16 retries.

+ * This bit is valid only when TDES1.30 (last descriptor) is set.

+ */

+#define TDES0_EC      ((uint32_t)1 << 8)

+

+/***************************************************************************//**

+ * Collision count.

+ * This field indicates the number of collisions that occurred before the end of a frame transmission.

+ * This value is not valid when TDES0.8 (excessive collisions bit) is set.

+ * This bit is valid only when TDES1.30 (last descriptor) is set.

+ */

+#define TDES0_CC_MASK	0xFu

+#define TDES0_CC_OFFSET	3u

+

+/***************************************************************************//**

+ * Underflow error.

+ * When set, indicates that the FIFO was empty during the frame transmission.

+ * This bit is valid only when TDES1.30 (last descriptor) is set.

+ */

+#define TDES0_UF      ((uint32_t)1 << 1)

+

+/***************************************************************************//**

+ * Deferred.

+ * When set, indicates that the frame was deferred before transmission. Deferring occurs if the carrier is detected

+ * when the transmission is ready to start.

+ * This bit is valid only when TDES1.30 (last descriptor) is set.

+ */

+#define TDES0_DE      (1)

+

+/***************************************************************************//**

+ * Interrupt on completion.

+ * Setting this flag instructs Core10/100 to set CSR5.0 (transmit interrupt) immediately after processing a

+ * current frame.

+ * This bit is valid when TDES1.30 (last descriptor) is set or for a setup packet.

+ */

+#define TDES1_IC      ((uint32_t)1 << 31)

+

+/***************************************************************************//**

+ * Last descriptor.

+ * When set, indicates the last descriptor of the frame.

+ */

+#define TDES1_LS      ((uint32_t)1 << 30)

+

+/***************************************************************************//**

+ * First descriptor.

+ * When set, indicates the first descriptor of the frame.

+ */

+#define TDES1_FS      ((uint32_t)1 << 29)

+

+/***************************************************************************//**

+ * Filtering type.

+ * This bit, together with TDES0.22 (FT0), controls a current filtering mode.

+ * This bit is valid only for the setup frames.

+ */

+#define TDES1_FT1     ((uint32_t)1 << 28)

+

+/***************************************************************************//**

+ * Setup packet.

+ * When set, indicates that this is a setup frame descriptor.

+ */

+#define TDES1_SET     ((uint32_t)1 << 27)

+

+/***************************************************************************//**

+ * Add CRC disable.

+ * When set, Core10/100 does not append the CRC value at the end of the frame. The exception is when the

+ * frame is shorter than 64 bytes and automatic byte padding is enabled. In that case, the CRC field is added,

+ * despite the state of the AC flag.

+ */

+#define TDES1_AC      ((uint32_t)1 << 26)

+

+/***************************************************************************//**

+ * Transmit end of ring.

+ * When set, indicates the last descriptor in the descriptor ring.

+ */

+#define TDES1_TER     ((uint32_t)1 << 25)

+

+/***************************************************************************//**

+ * Second address chained.

+ * When set, indicates that the second descriptor's address points to the next descriptor and not to the data

+ * buffer.

+ * This bit is valid only when TDES1.25 (transmit end of ring) is reset.

+ */

+#define TDES1_TCH     ((uint32_t)1 << 24)

+

+/***************************************************************************//**

+ * Disabled padding.

+ * When set, automatic byte padding is disabled. Core10/100 normally appends the PAD field after the INFO

+ * field when the size of an actual frame is less than 64 bytes. After padding bytes, the CRC field is also

+ * inserted, despite the state of the AC flag. When DPD is set, no padding bytes are appended.

+ */

+#define TDES1_DPD     ((uint32_t)1 << 23)

+

+/***************************************************************************//**

+ * Filtering type.

+ * This bit, together with TDES0.28 (FT1), controls the current filtering mode.

+ * This bit is valid only when the TDES1.27 (SET) bit is set.

+ */

+#define TDES1_FT0     ((uint32_t)1 << 22)

+

+/***************************************************************************//**

+ * Buffer 2 size.

+ * Indicates the size, in bytes, of memory space used by the second data buffer. If it is zero, Core10/100 ignores

+ * the second data buffer and fetches the next data descriptor.

+ * This bit is valid only when TDES1.24 (second address chained) is cleared.

+ */

+#define TDES1_TBS2_MASK		0x7FF

+#define TDES1_TBS2_OFFSET	11u

+

+/***************************************************************************//**

+ * Buffer 1 size.

+ * Indicates the size, in bytes, of memory space used by the first data buffer. If it is 0, Core10/100 ignores the

+ * first data buffer and uses the second data buffer.

+ */

+#define TDES1_TBS1_MASK		0x7FF

+#define TDES1_TBS1_OFFSET	0u

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif	/* __MSS_ETHERNET_MAC_DESC_H */

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h
new file mode 100644
index 0000000..d54c6e9
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h
@@ -0,0 +1,1201 @@
+/***************************************************************************//**

+ * @file

+ * SmartFusion MSS Ethernet MAC registers.

+ *

+ * (c) Copyright 2007 Actel Corporation

+ *

+ * IP core registers definitions. This file contains the definitions required

+ * for accessing the IP core through the hardware abstraction layer (HAL).

+ * This file was automatically generated, using "get_header.exe" version 0.4.0,

+ * from the IP-XACT description for:

+ *

+ *

+ * SVN $Revision: 2364 $

+ * SVN $Date: 2010-03-01 17:58:41 +0000 (Mon, 01 Mar 2010) $

+ *

+ *******************************************************************************/

+#ifndef MSS_ETHERNET_MAC_REGISTERS_H_

+#define MSS_ETHERNET_MAC_REGISTERS_H_

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+#include "../../CMSIS/a2fxxxm3.h"

+#include "mss_ethernet_mac.h"

+#include "mss_ethernet_mac_user_cfg.h"

+  

+typedef uint32_t addr_t;

+

+

+/***************************************************************************//**

+ * Descriptor structure

+ */

+typedef struct {

+    volatile uint32_t   descriptor_0;

+    volatile uint32_t   descriptor_1;

+    volatile uint32_t   buffer_1;

+    volatile uint32_t   buffer_2;

+} MAC_descriptor_t;

+

+

+/***************************************************************************//**

+ * There should be one instance of this structure for each instance of

+ * the MAC in your system. MSS_MAC_init routine initializes this structure.

+ * It is used to identify the various MACs in your system and an initilized 

+ * MAC instance's structure should be passed as first parameter to MAC functions 

+ * to identify which MAC should perform the requested operation.

+ * Software using the MAC driver should only need to create one single 

+ * instance of this data structure for each MAC hardware instance in 

+ * the system. Using MAC_get_configuration routine, latest status of the driver

+ * may be read by receiving its flags field, similarly MAC_configure routine lets

+ * you modify some of these flags.

+ */

+typedef struct {

+	addr_t		base_address;           /**< Register base address of the driver*/

+    uint8_t		flags;                  /**< Configuration of the driver*/

+    int8_t		last_error;             /**< Index of last error happened inside the driver*/

+    uint8_t     mac_address[6];			/**< MAC address of the drived instance*/

+    uint8_t     mac_filter_data[90];	/**< MAC filter data, 15 addresses to be used for 

+                                            received data filtering*/

+    uint16_t	last_timer_value;		/**< Last read value of timer */

+    uint32_t	time_out_value;			/**< Time out value */

+    MSS_MAC_callback_t listener;            /**< Pointer to the call-back function to be triggered 

+                                            when a package is received*/

+

+	/* transmit related info: */

+    uint32_t    tx_desc_index;          /**< index of the transmit descriptor getting used*/

+//    uint8_t     tx_buffers[TX_RING_SIZE][MSS_TX_BUFF_SIZE];/**< array of transmit buffers*/

+    MAC_descriptor_t tx_descriptors[TX_RING_SIZE];/**< array of transmit descriptors*/

+

+	/* receive related info: */

+    uint32_t    rx_desc_index;          /**< index of the receive descriptor getting used*/

+//    uint8_t     rx_buffers[RX_RING_SIZE][MSS_RX_BUFF_SIZE+4];/**< array of receive buffers*/

+    MAC_descriptor_t rx_descriptors[RX_RING_SIZE];/**< array of receive descriptors*/

+    

+    uint8_t		phy_address;            /**< MII address of the connected PHY*/

+    

+	struct {

+		uint32_t rx_interrupts;			/**< Number of receive interrupts occurred.*/

+		uint32_t rx_filtering_fail;		/**< Number of received frames which did not pass 

+											the address recognition process.*/

+		uint32_t rx_descriptor_error;	/**< Number of occurrences of; no receive buffer was

+											available when trying to store the received data.*/

+		uint32_t rx_runt_frame;			/**< Number of occurrences of; the frame is damaged by 

+											a collision or by a premature termination before 

+											the end of a collision window.*/

+		uint32_t rx_not_first;			/**< Number of occurrences of; start of the frame is 

+											not the first descriptor of a frame.*/

+		uint32_t rx_not_last;			/**< Number of occurrences of; end of the frame is not 

+											the first descriptor of a frame.*/

+		uint32_t rx_frame_too_long;		/**< Number of occurrences of; a current frame is 

+											longer than maximum size of 1,518 bytes, as specified 

+											by 802.3.*/

+		uint32_t rx_collision_seen;		/**< Number of occurrences of; a late collision was seen 

+											(collision after 64 bytes following SFD).*/

+		uint32_t rx_crc_error;			/**< Number of occurrences of; a CRC error has occurred 

+											in the received frame.*/

+		uint32_t rx_fifo_overflow;		/**< Number of frames not accepted due to the receive 

+											FIFO overflow.*/

+		uint32_t rx_missed_frame;		/**< Number of frames not accepted due to the 

+											unavailability of the receive descriptor.*/

+		

+		uint32_t tx_interrupts;			/**< Number of transmit interrupts occurred.*/

+		uint32_t tx_loss_of_carrier;	/**< Number of occurrences of; a loss of the carrier 

+											during a transmission.*/

+		uint32_t tx_no_carrier;			/**< Number of occurrences of; the carrier was not asserted

+											by an external transceiver during the transmission.*/

+		uint32_t tx_late_collision;		/**< Number of occurrences of; a collision was detected 

+											after transmitting 64 bytes.*/

+		uint32_t tx_excessive_collision;/**< Number of occurrences of; the transmission was 

+											aborted after 16 retries.*/

+		uint32_t tx_collision_count;	/**< Number of collisions occurred.*/

+		uint32_t tx_underflow_error;	/**< Number of occurrences of; the FIFO was empty during 

+											the frame transmission.*/

+    } statistics;

+} MAC_instance_t __attribute__((packed));

+

+

+/*------------------------------------------------------------------------------

+ *

+ */

+typedef struct

+{

+    uint32_t CSR0_SWR;

+    uint32_t CSR0_BAR;

+    uint32_t CSR0_DSL[5];

+    uint32_t CSR0_BLE;

+    uint32_t CSR0_PBL[6];

+    uint32_t CSR0_RESERVED0[3];

+    uint32_t CSR0_TAP[3];

+    uint32_t CSR0_DBO;

+    uint32_t CSR0_RESERVED1[11];

+    

+    uint32_t MAC_CSR_RESERVED0[32];

+    

+    uint32_t CSR1[32];

+    

+    uint32_t MAC_CSR_RESERVED1[32];

+    

+    uint32_t CSR2[32];

+    

+    uint32_t MAC_CSR_RESERVED2[32];

+    

+    uint32_t CSR3[32];

+    

+    uint32_t MAC_CSR_RESERVED3[32];

+    

+    uint32_t CSR4[32];

+    

+    uint32_t MAC_CSR_RESERVED4[32];

+    

+    uint32_t CSR5_TI;

+    uint32_t CSR5_TPS;

+    uint32_t CSR5_TU;

+    uint32_t CSR5_RESERVED0[2];    

+    uint32_t CSR5_UNF;

+    uint32_t CSR5_RI;

+    uint32_t CSR5_RU;

+    uint32_t CSR5_RPS;

+    uint32_t CSR5_RESERVED1;

+    uint32_t CSR5_ETI;

+    uint32_t CSR5_GTE;

+    uint32_t CSR5_RESERVED2[2];

+    uint32_t CSR5_ERI;

+    uint32_t CSR5_AIS;

+    uint32_t CSR5_NIS;

+    uint32_t CSR5_RS[3];

+    uint32_t CSR5_TS[3];

+    uint32_t CSR5_RESERVED3[9];

+

+    uint32_t MAC_CSR_RESERVED5[32];

+    

+    uint32_t CSR6_HP;

+    uint32_t CSR6_SR;

+    uint32_t CSR6_HO;

+    uint32_t CSR6_PB;

+    uint32_t CSR6_IF;

+    uint32_t CSR6_RESERVED0;

+    uint32_t CSR6_PR;

+    uint32_t CSR6_PM;

+    uint32_t CSR6_RESERVED1;

+    uint32_t CSR6_FD;

+    uint32_t CSR6_RESERVED2[3];

+    uint32_t CSR6_ST;

+    uint32_t CSR6_TR[2];

+    uint32_t CSR6_RESERVED3[5];

+    uint32_t CSR6_SF;

+    uint32_t CSR6_TTM;

+    uint32_t CSR6_RESERVED4[7];

+    uint32_t CSR6_RA;

+    uint32_t CSR6_RESERVED5;

+

+    uint32_t MAC_CSR_RESERVED6[32];

+    

+    uint32_t CSR7_TIE;

+    uint32_t CSR7_TSE;

+    uint32_t CSR7_TUE;

+    uint32_t CSR7_RESERVED0[2];

+    uint32_t CSR7_UNE;

+    uint32_t CSR7_RIE;

+    uint32_t CSR7_RUE;

+    uint32_t CSR7_RSE;

+    uint32_t CSR7_RESERVED1;

+    uint32_t CSR7_ETE;

+    uint32_t CSR7_GTE;

+    uint32_t CSR7_RESERVED2[2];

+    uint32_t CSR7_ERE;

+    uint32_t CSR7_AIE;

+    uint32_t CSR7_NIE;

+    uint32_t CSR7[15];

+

+    uint32_t MAC_CSR_RESERVED7[32];

+    

+    uint32_t CSR8[32];

+

+    uint32_t MAC_CSR_RESERVED8[32];

+    

+    uint32_t CSR9_SCS;

+    uint32_t CSR9_SCLK;

+    uint32_t CSR9_SDI;

+    uint32_t CSR9_SDO;

+    uint32_t CSR9_RESERVED0[12];

+    uint32_t CSR9_MDC;

+    uint32_t CSR9_MDO;

+    uint32_t CSR9_MDEN;

+    uint32_t CSR9_MDI;

+    uint32_t CSR9_RESERVED1[12];

+

+    uint32_t MAC_CSR_RESERVED9[32];

+    

+    uint32_t CSR10[32];

+

+    uint32_t MAC_CSR_RESERVED10[32];

+    

+    uint32_t CSR11_TIM[16];

+    uint32_t CSR11_CON;

+    uint32_t CSR11_NRP[3];

+    uint32_t CSR11_RT[4];

+    uint32_t CSR11_NTP[3];

+    uint32_t CSR11_TT[4];

+    uint32_t CSR11_CS;

+} MAC_BitBand_TypeDef;

+

+#define MAC_BITBAND   ((MAC_BitBand_TypeDef *) BITBAND_ADDRESS(MAC_BASE))

+

+/*******************************************************************************

+ * CSR0 register:

+ *------------------------------------------------------------------------------

+ * CSR0 - Bus Mode Register

+ */

+#define CSR0_REG_OFFSET	0x00

+

+/*------------------------------------------------------------------------------

+ * CSR0_DBO:

+ *   DBO field of register CSR0.

+ *------------------------------------------------------------------------------

+ * Descriptor byte ordering mode

+ */

+#define CSR0_DBO_OFFSET   0x00

+#define CSR0_DBO_MASK     0x00100000UL

+#define CSR0_DBO_SHIFT    20

+

+/*

+ * Allowed values for CSR0_DBO:

+ *------------------------------------------------------------------------------

+ * LITTLEENDIAN:   Little endian mode used for data descriptors

+ * BIGENDIAN:      Big endian mode used for data descriptors

+ */

+#define LITTLEENDIAN    0u

+#define BIGENDIAN       1u

+

+/*------------------------------------------------------------------------------

+ * CSR0_TAP:

+ *   TAP field of register CSR0.

+ *------------------------------------------------------------------------------

+ * Transmit automatic polling

+ */

+#define CSR0_TAP_OFFSET   0x00

+#define CSR0_TAP_MASK     0x000E0000UL

+#define CSR0_TAP_SHIFT    17

+

+/*

+ * Allowed values for CSR0_TAP:

+ *------------------------------------------------------------------------------

+ * TAP_DISABLED:   TAP disabled

+ * TAP_819US:      TAP 819/81.9us

+ * TAP_2450US:     TAP 2450/245us

+ * TAP_5730US:     TAP 5730/573us

+ * TAP_51_2US:     TAP 51.2/5.12us

+ * TAP_102_4US:    TAP 102.4/10.24us

+ * TAP_153_6US:    TAP 156.6/15.26us

+ * TAP_358_4US:    TAP 358.4/35.84us

+ */

+#define TAP_DISABLED    0x0

+#define TAP_819US       0x1

+#define TAP_2450US      0x2

+#define TAP_5730US      0x3

+#define TAP_51_2US      0x4

+#define TAP_102_4US     0x5

+#define TAP_153_6US     0x6

+#define TAP_358_4US     0x7

+

+/*------------------------------------------------------------------------------

+ * CSR0_PBL:

+ *   PBL field of register CSR0.

+ *------------------------------------------------------------------------------

+ * Programmable burst length

+ */

+#define CSR0_PBL_OFFSET   0x00

+#define CSR0_PBL_MASK     0x00003F00uL

+#define CSR0_PBL_SHIFT    8

+

+/*------------------------------------------------------------------------------

+ * CSR0_BLE:

+ *   BLE field of register CSR0.

+ *------------------------------------------------------------------------------

+ * Big/little endian

+ */

+#define CSR0_BLE_OFFSET   0x00

+#define CSR0_BLE_MASK     0x00000080uL

+#define CSR0_BLE_SHIFT    7

+

+/*------------------------------------------------------------------------------

+ * CSR0_DSL:

+ *   DSL field of register CSR0.

+ *------------------------------------------------------------------------------

+ * Descriptor skip length

+ */

+#define CSR0_DSL_OFFSET   0x00

+#define CSR0_DSL_MASK     0x0000007CuL

+#define CSR0_DSL_SHIFT    2

+

+/*------------------------------------------------------------------------------

+ * CSR0_BAR:

+ *   BAR field of register CSR0.

+ *------------------------------------------------------------------------------

+ * Bus arbitration scheme

+ */

+#define CSR0_BAR_OFFSET   0x00

+#define CSR0_BAR_MASK     0x00000002uL

+#define CSR0_BAR_SHIFT    1

+

+/*------------------------------------------------------------------------------

+ * CSR0_SWR:

+ *   SWR field of register CSR0.

+ *------------------------------------------------------------------------------

+ * Software reset

+ */

+#define CSR0_SWR_OFFSET   0x00

+#define CSR0_SWR_MASK     0x00000001uL

+#define CSR0_SWR_SHIFT    0

+

+/*******************************************************************************

+ * CSR1 register:

+ *------------------------------------------------------------------------------

+ * CSR1 - Transmit Poll Demand Register

+ */

+#define CSR1_REG_OFFSET	0x08

+

+/*------------------------------------------------------------------------------

+ * CSR1_TPD3:

+ *   TPD3 field of register CSR1.

+ *------------------------------------------------------------------------------

+ * TPD(31..24)

+ */

+#define CSR1_TPD3_OFFSET   0x08

+#define CSR1_TPD3_MASK     0xFF000000uL

+#define CSR1_TPD3_SHIFT    24

+

+/*------------------------------------------------------------------------------

+ * CSR1_TPD2:

+ *   TPD2 field of register CSR1.

+ *------------------------------------------------------------------------------

+ * TPD(23..16)

+ */

+#define CSR1_TPD2_OFFSET   0x08

+#define CSR1_TPD2_MASK     0x00FF0000uL

+#define CSR1_TPD2_SHIFT    16

+

+/*------------------------------------------------------------------------------

+ * CSR1_TPD1:

+ *   TPD1 field of register CSR1.

+ *------------------------------------------------------------------------------

+ * TPD(15..8)

+ */

+#define CSR1_TPD1_OFFSET   0x08

+#define CSR1_TPD1_MASK     0x0000FF00uL

+#define CSR1_TPD1_SHIFT    8

+

+/*------------------------------------------------------------------------------

+ * CSR1_TPD0:

+ *   TPD0 field of register CSR1.

+ *------------------------------------------------------------------------------

+ * TPD(7..0)

+ */

+#define CSR1_TPD0_OFFSET   0x08

+#define CSR1_TPD0_MASK     0x000000FFuL

+#define CSR1_TPD0_SHIFT    0

+

+/*******************************************************************************

+ * CSR2 register:

+ *------------------------------------------------------------------------------

+ * CSR2 - Receive Poll Demand Register

+ */

+#define CSR2_REG_OFFSET	0x10

+

+/*------------------------------------------------------------------------------

+ * CSR2_RPD3:

+ *   RPD3 field of register CSR2.

+ *------------------------------------------------------------------------------

+ * RPD(31..24)

+ */

+#define CSR2_RPD3_OFFSET   0x10

+#define CSR2_RPD3_MASK     0xFF000000uL

+#define CSR2_RPD3_SHIFT    24

+

+/*------------------------------------------------------------------------------

+ * CSR2_RPD2:

+ *   RPD2 field of register CSR2.

+ *------------------------------------------------------------------------------

+ * RPD(23..16)

+ */

+#define CSR2_RPD2_OFFSET   0x10

+#define CSR2_RPD2_MASK     0x00FF0000uL

+#define CSR2_RPD2_SHIFT    16

+

+/*------------------------------------------------------------------------------

+ * CSR2_RPD1:

+ *   RPD1 field of register CSR2.

+ *------------------------------------------------------------------------------

+ * RPD(15..8)

+ */

+#define CSR2_RPD1_OFFSET   0x10

+#define CSR2_RPD1_MASK     0x0000FF00uL

+#define CSR2_RPD1_SHIFT    8

+

+/*------------------------------------------------------------------------------

+ * CSR2_RPD0:

+ *   RPD0 field of register CSR2.

+ *------------------------------------------------------------------------------

+ * RPD(7..0)

+ */

+#define CSR2_RPD0_OFFSET   0x10

+#define CSR2_RPD0_MASK     0x000000FFuL

+#define CSR2_RPD0_SHIFT    0

+

+/*******************************************************************************

+ * CSR3 register:

+ *------------------------------------------------------------------------------

+ * CSR3 - Receive Descriptor List Base Address Register

+ */

+#define CSR3_REG_OFFSET	0x18

+

+/*------------------------------------------------------------------------------

+ * CSR3_RLA3:

+ *   RLA3 field of register CSR3.

+ *------------------------------------------------------------------------------

+ * RLA(31..24)

+ */

+#define CSR3_RLA3_OFFSET   0x18

+#define CSR3_RLA3_MASK     0xFF000000uL

+#define CSR3_RLA3_SHIFT    24

+

+/*------------------------------------------------------------------------------

+ * CSR3_RLA2:

+ *   RLA2 field of register CSR3.

+ *------------------------------------------------------------------------------

+ * RLA(23..16)

+ */

+#define CSR3_RLA2_OFFSET   0x18

+#define CSR3_RLA2_MASK     0x00FF0000uL

+#define CSR3_RLA2_SHIFT    16

+

+/*------------------------------------------------------------------------------

+ * CSR3_RLA1:

+ *   RLA1 field of register CSR3.

+ *------------------------------------------------------------------------------

+ * RLA(15..8)

+ */

+#define CSR3_RLA1_OFFSET   0x18

+#define CSR3_RLA1_MASK     0x0000FF00uL

+#define CSR3_RLA1_SHIFT    8

+

+/*------------------------------------------------------------------------------

+ * CSR3_RLA0:

+ *   RLA0 field of register CSR3.

+ *------------------------------------------------------------------------------

+ * RLA(7..0)

+ */

+#define CSR3_RLA0_OFFSET   0x18

+#define CSR3_RLA0_MASK     0x000000FFuL

+#define CSR3_RLA0_SHIFT    0

+

+/*******************************************************************************

+ * CSR4 register:

+ *------------------------------------------------------------------------------

+ * CSR4 - Transmit Descriptor List Base Address Register

+ */

+#define CSR4_REG_OFFSET	0x20

+

+/*------------------------------------------------------------------------------

+ * CSR4_TLA3:

+ *   TLA3 field of register CSR4.

+ *------------------------------------------------------------------------------

+ * TLA(31..24)

+ */

+#define CSR4_TLA3_OFFSET   0x20

+#define CSR4_TLA3_MASK     0xFF000000uL

+#define CSR4_TLA3_SHIFT    24

+

+/*------------------------------------------------------------------------------

+ * CSR4_TLA2:

+ *   TLA2 field of register CSR4.

+ *------------------------------------------------------------------------------

+ * TLA(23..16)

+ */

+#define CSR4_TLA2_OFFSET   0x20

+#define CSR4_TLA2_MASK     0x00FF0000uL

+#define CSR4_TLA2_SHIFT    16

+

+/*------------------------------------------------------------------------------

+ * CSR4_TLA1:

+ *   TLA1 field of register CSR4.

+ *------------------------------------------------------------------------------

+ * TLA(15..8)

+ */

+#define CSR4_TLA1_OFFSET   0x20

+#define CSR4_TLA1_MASK     0x0000FF00uL

+#define CSR4_TLA1_SHIFT    8

+

+/*------------------------------------------------------------------------------

+ * CSR4_TLA0:

+ *   TLA0 field of register CSR4.

+ *------------------------------------------------------------------------------

+ * TLA(7..0)

+ */

+#define CSR4_TLA0_OFFSET   0x20

+#define CSR4_TLA0_MASK     0x000000FFuL

+#define CSR4_TLA0_SHIFT    0

+

+/*******************************************************************************

+ * CSR5 register:

+ *------------------------------------------------------------------------------

+ * CSR5 - Status Register

+ */

+#define CSR5_REG_OFFSET	0x28

+#define CSR5_INT_BITS	(CSR5_NIS_MASK | CSR5_AIS_MASK | CSR5_ERI_MASK | \

+	CSR5_GTE_MASK | CSR5_ETI_MASK | CSR5_RPS_MASK | CSR5_RU_MASK | \

+	CSR5_RI_MASK | CSR5_UNF_MASK | CSR5_TU_MASK | CSR5_TPS_MASK | CSR5_TI_MASK)

+

+/*------------------------------------------------------------------------------

+ * CSR5_TS:

+ *   TS field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Transmit process state

+ */

+#define CSR5_TS_OFFSET   0x28

+#define CSR5_TS_MASK     0x00700000uL

+#define CSR5_TS_SHIFT    20

+

+/** 000 - Stopped; RESET or STOP TRANSMIT command issued.             */

+#define CSR5_TS_STOPPED    0u 

+/** 001 - Running, fetching the transmit descriptor.                  */

+#define CSR5_TS_RUNNING_FD 1u 

+/** 010 - Running, waiting for end of transmission.                   */

+#define CSR5_TS_RUNNING_WT 2u 

+/** 011 - Running, transferring data buffer from host memory to FIFO. */

+#define CSR5_TS_RUNNING_TD 3u 

+/** 101 - Running, setup packet.                                      */

+#define CSR5_TS_RUNNING_SP 5u 

+/** 110 - Suspended; FIFO underflow or unavailable descriptor.        */

+#define CSR5_TS_SUSPENDED  6u 

+/** 111 - Running, closing transmit descriptor.                       */

+#define CSR5_TS_RUNNING_CD 7u 

+

+/*------------------------------------------------------------------------------

+ * CSR5_RS:

+ *   RS field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Receive process state

+ */

+#define CSR5_RS_OFFSET   0x28

+#define CSR5_RS_MASK     0x00060000uL

+#define CSR5_RS_SHIFT    17

+

+/** 000 - Stopped; RESET or STOP RECEIVE command issued.                      */

+#define CSR5_RS_STOPPED    0u                                                  

+/** 001 - Running, fetching the receive descriptor.                           */

+#define CSR5_RS_RUNNING_FD 1u                                                  

+/** 010 - Running, waiting for the end-of-receive packet before prefetch of the

+ *next descriptor. */                                                         

+#define CSR5_RS_RUNNING_WR 2u                                                  

+/** 011 - Running, waiting for the receive packet.                            */

+#define CSR5_RS_RUNNING_RB 3u                                                  

+/** 100 - Suspended, unavailable receive buffer.                              */

+#define CSR5_RS_SUSPENDED  4u                                                  

+/** 101 - Running, closing the receive descriptor.                            */

+#define CSR5_RS_RUNNING_CD 5u                                                  

+/** 111 - Running, transferring data from FIFO to host memory.                */                                                                                                                     

+#define CSR5_RS_RUNNING_TD 7u

+

+/*------------------------------------------------------------------------------

+ * CSR5_NIS:

+ *   NIS field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Normal interrupt summary

+ */

+#define CSR5_NIS_OFFSET   0x28

+#define CSR5_NIS_MASK     0x00010000uL

+#define CSR5_NIS_SHIFT    16

+

+/*------------------------------------------------------------------------------

+ * CSR5_AIS:

+ *   AIS field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Abnormal interrupt summary

+ */

+#define CSR5_AIS_OFFSET   0x28

+#define CSR5_AIS_MASK     0x00008000UL

+#define CSR5_AIS_SHIFT    15

+

+/*------------------------------------------------------------------------------

+ * CSR5_ERI:

+ *   ERI field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Early receive interrupt

+ */

+#define CSR5_ERI_OFFSET   0x28

+#define CSR5_ERI_MASK     0x00004000UL

+#define CSR5_ERI_SHIFT    14

+

+/*------------------------------------------------------------------------------

+ * CSR5_GTE:

+ *   GTE field of register CSR5.

+ *------------------------------------------------------------------------------

+ * General-purpose timer expiration

+ */

+#define CSR5_GTE_OFFSET   0x28

+#define CSR5_GTE_MASK     0x00000800UL

+#define CSR5_GTE_SHIFT    11

+

+/*------------------------------------------------------------------------------

+ * CSR5_ETI:

+ *   ETI field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Early transmit interrupt

+ */

+#define CSR5_ETI_OFFSET   0x28

+#define CSR5_ETI_MASK     0x00000400UL

+#define CSR5_ETI_SHIFT    10

+

+/*------------------------------------------------------------------------------

+ * CSR5_RPS:

+ *   RPS field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Receive process stopped

+ */

+#define CSR5_RPS_OFFSET   0x28

+#define CSR5_RPS_MASK     0x00000100UL

+#define CSR5_RPS_SHIFT    8

+

+/*------------------------------------------------------------------------------

+ * CSR5_RU:

+ *   RU field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Receive buffer unavailable

+ */

+#define CSR5_RU_OFFSET   0x28

+#define CSR5_RU_MASK     0x00000080UL

+#define CSR5_RU_SHIFT    7

+

+/*------------------------------------------------------------------------------

+ * CSR5_RI:

+ *   RI field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Receive interrupt

+ */

+#define CSR5_RI_OFFSET   0x28

+#define CSR5_RI_MASK     0x00000040UL

+#define CSR5_RI_SHIFT    6

+

+/*------------------------------------------------------------------------------

+ * CSR5_UNF:

+ *   UNF field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Transmit underflow

+ */

+#define CSR5_UNF_OFFSET   0x28

+#define CSR5_UNF_MASK     0x00000020UL

+#define CSR5_UNF_SHIFT    5

+

+/*------------------------------------------------------------------------------

+ * CSR5_TU:

+ *   TU field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Transmit buffer unavailable

+ */

+#define CSR5_TU_OFFSET   0x28

+#define CSR5_TU_MASK     0x00000004UL

+#define CSR5_TU_SHIFT    2

+

+/*------------------------------------------------------------------------------

+ * CSR5_TPS:

+ *   TPS field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Transmit process stopped

+ */

+#define CSR5_TPS_OFFSET   0x28

+#define CSR5_TPS_MASK     0x00000002UL

+#define CSR5_TPS_SHIFT    1

+

+/*------------------------------------------------------------------------------

+ * CSR5_TI:

+ *   TI field of register CSR5.

+ *------------------------------------------------------------------------------

+ * Transmit interrupt

+ */

+#define CSR5_TI_OFFSET   0x28

+#define CSR5_TI_MASK     0x00000001UL

+#define CSR5_TI_SHIFT    0

+

+/*******************************************************************************

+ * CSR6 register:

+ *------------------------------------------------------------------------------

+ * CSR6 - Operation Mode Register

+ */

+#define CSR6_REG_OFFSET	0x30

+

+/*------------------------------------------------------------------------------

+ * CSR6_RA:

+ *   RA field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Receive all

+ */

+#define CSR6_RA_OFFSET   0x30

+#define CSR6_RA_MASK     0x40000000UL

+#define CSR6_RA_SHIFT    30

+

+/*------------------------------------------------------------------------------

+ * CSR6_TTM:

+ *   TTM field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Transmit threshold mode

+ */

+#define CSR6_TTM_OFFSET   0x30

+#define CSR6_TTM_MASK     0x00400000UL

+#define CSR6_TTM_SHIFT    22

+

+/*------------------------------------------------------------------------------

+ * CSR6_SF:

+ *   SF field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Store and forward

+ */

+#define CSR6_SF_OFFSET   0x30

+#define CSR6_SF_MASK     0x00200000UL

+#define CSR6_SF_SHIFT    21

+

+/*------------------------------------------------------------------------------

+ * CSR6_TR:

+ *   TR field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Threshold control bits

+ */

+#define CSR6_TR_OFFSET   0x30

+#define CSR6_TR_MASK     0x0000C000UL

+#define CSR6_TR_SHIFT    14

+

+/*------------------------------------------------------------------------------

+ * CSR6_ST:

+ *   ST field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Start/stop transmit command

+ */

+#define CSR6_ST_OFFSET   0x30

+#define CSR6_ST_MASK     0x00002000UL

+#define CSR6_ST_SHIFT    13

+

+/*------------------------------------------------------------------------------

+ * CSR6_FD:

+ *   FD field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Full-duplex mode

+ */

+#define CSR6_FD_OFFSET   0x30

+#define CSR6_FD_MASK     0x00000200UL

+#define CSR6_FD_SHIFT    9

+

+/*------------------------------------------------------------------------------

+ * CSR6_PM:

+ *   PM field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Pass all multicast

+ */

+#define CSR6_PM_OFFSET   0x30

+#define CSR6_PM_MASK     0x00000080UL

+#define CSR6_PM_SHIFT    7

+

+/*------------------------------------------------------------------------------

+ * CSR6_PR:

+ *   PR field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Promiscuous mode

+ */

+#define CSR6_PR_OFFSET   0x30

+#define CSR6_PR_MASK     0x00000040UL

+#define CSR6_PR_SHIFT    6

+

+/*------------------------------------------------------------------------------

+ * CSR6_IF:

+ *   IF field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Inverse filtering

+ */

+#define CSR6_IF_OFFSET   0x30

+#define CSR6_IF_MASK     0x00000010UL

+#define CSR6_IF_SHIFT    4

+

+/*------------------------------------------------------------------------------

+ * CSR6_PB:

+ *   PB field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Pass bad frames

+ */

+#define CSR6_PB_OFFSET   0x30

+#define CSR6_PB_MASK     0x00000008UL

+#define CSR6_PB_SHIFT    3

+

+/*------------------------------------------------------------------------------

+ * CSR6_HO:

+ *   HO field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Hash-only filtering mode

+ */

+#define CSR6_HO_OFFSET   0x30

+#define CSR6_HO_MASK     0x00000004UL

+#define CSR6_HO_SHIFT    2

+

+/*------------------------------------------------------------------------------

+ * CSR6_SR:

+ *   SR field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Start/stop receive command

+ */

+#define CSR6_SR_OFFSET   0x30

+#define CSR6_SR_MASK     0x00000002UL

+#define CSR6_SR_SHIFT    1

+

+/*------------------------------------------------------------------------------

+ * CSR6_HP:

+ *   HP field of register CSR6.

+ *------------------------------------------------------------------------------

+ * Hash/perfect receive filtering mode

+ */

+#define CSR6_HP_OFFSET   0x30

+#define CSR6_HP_MASK     0x00000001UL

+#define CSR6_HP_SHIFT    0

+

+/*******************************************************************************

+ * CSR7 register:

+ *------------------------------------------------------------------------------

+ * CSR7 - Interrupt Enable Register

+ */

+#define CSR7_REG_OFFSET	0x38

+

+/*------------------------------------------------------------------------------

+ * CSR7_NIE:

+ *   NIE field of register CSR7.

+ *------------------------------------------------------------------------------

+ * Normal interrupt summary enable

+ */

+#define CSR7_NIE_OFFSET   0x38

+#define CSR7_NIE_MASK     0x00010000UL

+#define CSR7_NIE_SHIFT    16

+

+/*------------------------------------------------------------------------------

+ * CSR7_AIE:

+ *   AIE field of register CSR7.

+ *------------------------------------------------------------------------------

+ * Abnormal interrupt summary enable

+ */

+#define CSR7_AIE_OFFSET   0x38

+#define CSR7_AIE_MASK     0x00008000UL

+#define CSR7_AIE_SHIFT    15

+

+/*------------------------------------------------------------------------------

+ * CSR7_ERE:

+ *   ERE field of register CSR7.

+ *------------------------------------------------------------------------------

+ * Early receive interrupt enable

+ */

+#define CSR7_ERE_OFFSET   0x38

+#define CSR7_ERE_MASK     0x00004000UL

+#define CSR7_ERE_SHIFT    14

+

+/*------------------------------------------------------------------------------

+ * CSR7_GTE:

+ *   GTE field of register CSR7.

+ *------------------------------------------------------------------------------

+ * General-purpose timer overflow enable

+ */

+#define CSR7_GTE_OFFSET   0x38

+#define CSR7_GTE_MASK     0x00000800UL

+#define CSR7_GTE_SHIFT    11

+

+/*------------------------------------------------------------------------------

+ * CSR7_ETE:

+ *   ETE field of register CSR7.

+ *------------------------------------------------------------------------------

+ * Early transmit interrupt enable

+ */

+#define CSR7_ETE_OFFSET   0x38

+#define CSR7_ETE_MASK     0x00000400UL

+#define CSR7_ETE_SHIFT    10

+

+/*------------------------------------------------------------------------------

+ * CSR7_RSE:

+ *   RSE field of register CSR7.

+ *------------------------------------------------------------------------------

+ * Receive stopped enable

+ */

+#define CSR7_RSE_OFFSET   0x38

+#define CSR7_RSE_MASK     0x00000100UL

+#define CSR7_RSE_SHIFT    8

+

+/*------------------------------------------------------------------------------

+ * CSR7_RUE:

+ *   RUE field of register CSR7.

+ *------------------------------------------------------------------------------

+ * Receive buffer unavailable enable

+ */

+#define CSR7_RUE_OFFSET   0x38

+#define CSR7_RUE_MASK     0x00000080UL

+#define CSR7_RUE_SHIFT    7

+

+/*------------------------------------------------------------------------------

+ * CSR7_RIE:

+ *   RIE field of register CSR7.

+ *------------------------------------------------------------------------------

+ * Receive interrupt enable

+ */

+#define CSR7_RIE_OFFSET   0x38

+#define CSR7_RIE_MASK     0x00000040UL

+#define CSR7_RIE_SHIFT    6

+

+/*------------------------------------------------------------------------------

+ * CSR7_UNE:

+ *   UNE field of register CSR7.

+ *------------------------------------------------------------------------------

+ * Underflow interrupt enable

+ */

+#define CSR7_UNE_OFFSET   0x38

+#define CSR7_UNE_MASK     0x00000020UL

+#define CSR7_UNE_SHIFT    5

+

+/*------------------------------------------------------------------------------

+ * CSR7_TUE:

+ *   TUE field of register CSR7.

+ *------------------------------------------------------------------------------

+ * Transmit buffer unavailable enable

+ */

+#define CSR7_TUE_OFFSET   0x38

+#define CSR7_TUE_MASK     0x00000004UL

+#define CSR7_TUE_SHIFT    2

+

+/*------------------------------------------------------------------------------

+ * CSR7_TSE:

+ *   TSE field of register CSR7.

+ *------------------------------------------------------------------------------

+ * Transmit stopped enable

+ */

+#define CSR7_TSE_OFFSET   0x38

+#define CSR7_TSE_MASK     0x00000002UL

+#define CSR7_TSE_SHIFT    1

+

+/*------------------------------------------------------------------------------

+ * CSR7_TIE:

+ *   TIE field of register CSR7.

+ *------------------------------------------------------------------------------

+ * Transmit interrupt enable

+ */

+#define CSR7_TIE_OFFSET   0x38

+#define CSR7_TIE_MASK     0x00000001UL

+#define CSR7_TIE_SHIFT    0

+

+/*******************************************************************************

+ * CSR8 register:

+ *------------------------------------------------------------------------------

+ * CSR8 - Missed Frames and Overflow Counter Register

+ */

+#define CSR8_REG_OFFSET	0x40

+

+/*------------------------------------------------------------------------------

+ * CSR8_OCO:

+ *   OCO field of register CSR8.

+ *------------------------------------------------------------------------------

+ * Overflow counter overflow

+ */

+#define CSR8_OCO_OFFSET   0x40

+#define CSR8_OCO_MASK     0x10000000UL

+#define CSR8_OCO_SHIFT    28

+

+/*------------------------------------------------------------------------------

+ * CSR8_FOC:

+ *   FOC field of register CSR8.

+ *------------------------------------------------------------------------------

+ * FIFO overflow counter

+ */

+#define CSR8_FOC_OFFSET   0x40

+#define CSR8_FOC_MASK     0x0FFE0000UL

+#define CSR8_FOC_SHIFT    17

+

+/*------------------------------------------------------------------------------

+ * CSR8_MFO:

+ *   MFO field of register CSR8.

+ *------------------------------------------------------------------------------

+ * Missed frame overflow

+ */

+#define CSR8_MFO_OFFSET   0x40

+#define CSR8_MFO_MASK     0x00010000UL

+#define CSR8_MFO_SHIFT    16

+

+/*------------------------------------------------------------------------------

+ * CSR8_MFC:

+ *   MFC field of register CSR8.

+ *------------------------------------------------------------------------------

+ * Missed frame counter

+ */

+#define CSR8_MFC_OFFSET   0x40

+#define CSR8_MFC_MASK     0x0000FFFFUL

+#define CSR8_MFC_SHIFT    0

+

+/*******************************************************************************

+ * CSR9 register:

+ *------------------------------------------------------------------------------

+ * CSR9 - MII Management and Serial ROM Interface Register

+ */

+#define CSR9_REG_OFFSET	0x48

+

+/*------------------------------------------------------------------------------

+ * CSR9_MDI:

+ *   MDI field of register CSR9.

+ *------------------------------------------------------------------------------

+ * MII management data in signal

+ */

+#define CSR9_MDI_OFFSET   0x48

+#define CSR9_MDI_MASK     0x00080000UL

+#define CSR9_MDI_SHIFT    19

+

+/*------------------------------------------------------------------------------

+ * CSR9_MII:

+ *   MII field of register CSR9.

+ *------------------------------------------------------------------------------

+ * MII management operation mode

+ */

+#define CSR9_MII_OFFSET   0x48

+#define CSR9_MII_MASK     0x00040000UL

+#define CSR9_MII_SHIFT    18

+

+/*------------------------------------------------------------------------------

+ * CSR9_MDO:

+ *   MDO field of register CSR9.

+ *------------------------------------------------------------------------------

+ * MII management write data

+ */

+#define CSR9_MDO_OFFSET   0x48

+#define CSR9_MDO_MASK     0x00020000UL

+#define CSR9_MDO_SHIFT    17

+

+/*------------------------------------------------------------------------------

+ * CSR9_MDC:

+ *   MDC field of register CSR9.

+ *------------------------------------------------------------------------------

+ * MII management clock

+ */

+#define CSR9_MDC_OFFSET   0x48

+#define CSR9_MDC_MASK     0x00010000UL

+#define CSR9_MDC_SHIFT    16

+

+/*------------------------------------------------------------------------------

+ * CSR9_SDO:

+ *   SDO field of register CSR9.

+ *------------------------------------------------------------------------------

+ * Serial ROM data output

+ */

+#define CSR9_SDO_OFFSET   0x48

+#define CSR9_SDO_MASK     0x00000008UL

+#define CSR9_SDO_SHIFT    3

+

+/*------------------------------------------------------------------------------

+ * CSR9_SDI:

+ *   SDI field of register CSR9.

+ *------------------------------------------------------------------------------

+ * Serial ROM data input

+ */

+#define CSR9_SDI_OFFSET   0x48

+#define CSR9_SDI_MASK     0x00000004UL

+#define CSR9_SDI_SHIFT    2

+

+/*------------------------------------------------------------------------------

+ * CSR9_SCLK:

+ *   SCLK field of register CSR9.

+ *------------------------------------------------------------------------------

+ * Serial ROM clock

+ */

+#define CSR9_SCLK_OFFSET   0x48

+#define CSR9_SCLK_MASK     0x00000002UL

+#define CSR9_SCLK_SHIFT    1

+

+/*------------------------------------------------------------------------------

+ * CSR9_SCS:

+ *   SCS field of register CSR9.

+ *------------------------------------------------------------------------------

+ * Serial ROM chip select

+ */

+#define CSR9_SCS_OFFSET   0x48

+#define CSR9_SCS_MASK     0x00000001UL

+#define CSR9_SCS_SHIFT    0

+

+/*******************************************************************************

+ * CSR11 register:

+ *------------------------------------------------------------------------------

+ * CSR11 - General-Purpose Timer and Interrupt Mitigation Control Register

+ */

+#define CSR11_REG_OFFSET	0x58

+

+/*------------------------------------------------------------------------------

+ * CSR11_CS:

+ *   CS field of register CSR11.

+ *------------------------------------------------------------------------------

+ * Cycle size

+ */

+#define CSR11_CS_OFFSET   0x58

+#define CSR11_CS_MASK     0x80000000UL

+#define CSR11_CS_SHIFT    31

+

+/*------------------------------------------------------------------------------

+ * CSR11_TT:

+ *   TT field of register CSR11.

+ *------------------------------------------------------------------------------

+ * Transmit timer

+ */

+#define CSR11_TT_OFFSET   0x58

+#define CSR11_TT_MASK     0x78000000UL

+#define CSR11_TT_SHIFT    27

+

+/*------------------------------------------------------------------------------

+ * CSR11_NTP:

+ *   NTP field of register CSR11.

+ *------------------------------------------------------------------------------

+ * Number of transmit packets

+ */

+#define CSR11_NTP_OFFSET   0x58

+#define CSR11_NTP_MASK     0x07000000UL

+#define CSR11_NTP_SHIFT    24

+

+/*------------------------------------------------------------------------------

+ * CSR11_RT:

+ *   RT field of register CSR11.

+ *------------------------------------------------------------------------------

+ * Receive timer

+ */

+#define CSR11_RT_OFFSET   0x58

+#define CSR11_RT_MASK     0x00F00000UL

+#define CSR11_RT_SHIFT    20

+

+/*------------------------------------------------------------------------------

+ * CSR11_NRP:

+ *   NRP field of register CSR11.

+ *------------------------------------------------------------------------------

+ * Number of receive packets

+ */

+#define CSR11_NRP_OFFSET   0x58

+#define CSR11_NRP_MASK     0x000E0000UL

+#define CSR11_NRP_SHIFT    17

+

+/*------------------------------------------------------------------------------

+ * CSR11_CON:

+ *   CON field of register CSR11.

+ *------------------------------------------------------------------------------

+ * Continuous mode

+ */

+#define CSR11_CON_OFFSET   0x58

+#define CSR11_CON_MASK     0x00010000UL

+#define CSR11_CON_SHIFT    16

+

+/*------------------------------------------------------------------------------

+ * CSR11_TIM:

+ *   TIM field of register CSR11.

+ *------------------------------------------------------------------------------

+ * Timer value

+ */

+#define CSR11_TIM_OFFSET   0x58

+#define CSR11_TIM_MASK     0x0000FFFFUL

+#define CSR11_TIM_SHIFT    0

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* MSS_ETHERNET_MAC_REGISTERS_H_*/

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h
new file mode 100644
index 0000000..d4d2cc4
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h
@@ -0,0 +1,26 @@
+/*******************************************************************************

+ * (c) Copyright 2007 Actel Corporation.  All rights reserved.

+ * 

+ * Actel:Firmware:MSS_Ethernet_MAC_Driver:2.0.103 configuration.

+ *

+ */

+

+

+#ifndef ACTEL__FIRMWARE__MSS_ETHERNET_MAC_DRIVER__2_0_103_CONFIGURATION_HEADER

+#define ACTEL__FIRMWARE__MSS_ETHERNET_MAC_DRIVER__2_0_103_CONFIGURATION_HEADER

+

+

+#define CORE_VENDOR "Actel"

+#define CORE_LIBRARY "Firmware"

+#define CORE_NAME "MSS_Ethernet_MAC_Driver"

+#define CORE_VERSION "2.0.103"

+

+#define BUS_ARBITRATION_SCHEME 0

+#define PROGRAMMABLE_BURST_LENGTH 0

+#define RX_RING_SIZE 4

+#define SETUP_FRAME_TIME_OUT 10000

+#define STATE_CHANGE_TIME_OUT 10000

+#define TX_RING_SIZE 2

+

+#endif // ACTEL__FIRMWARE__MSS_ETHERNET_MAC_DRIVER__2_0_103_CONFIGURATION_HEADER

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.c
new file mode 100644
index 0000000..e0433ba
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.c
@@ -0,0 +1,390 @@
+/***************************************************************************//**

+ * PHY access methods for DP83848C.

+ * The implementation in this file is specific to the DP83848C,

+ * If a different PHY support is required the PHY specific registers must

+ * be updated.

+ * (c) Copyright 2007 Actel Corporation

+ *

+ * SVN $Revision: 2324 $

+ * SVN $Date: 2010-02-26 10:47:36 +0000 (Fri, 26 Feb 2010) $

+ *

+ ******************************************************************************/

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+

+#include "mss_ethernet_mac.h"

+#include "mss_ethernet_mac_regs.h"

+

+#include "phy.h"

+

+#include "FreeRTOS.h"

+#include "task.h"

+

+extern MAC_instance_t g_mss_mac;

+

+/***************************** MDIO FUNCTIONS *********************************/

+

+/* Defines ********************************************************************/

+#define MDIO_START				0x00004000UL

+#define MDIO_READ				0x00002000UL

+#define MDIO_WRITE				0x00001002UL

+#define MDIO_ADDR_OFFSET		7UL

+#define MDIO_ADDR_MASK			0x00000f80UL

+#define MDIO_REG_ADDR_OFFSET	2UL

+#define MDIO_REG_ADDR_MASK		0x0000007cUL

+#define PREAMBLECOUNT           32UL

+#define ONEMICROSECOND          20UL

+

+typedef enum {

+	MDIO_CMD_READ,

+	MDIO_CMD_WRITE

+}mdio_cmd_t;

+

+

+

+/***************************************************************************//**

+ * Set clock high or low.

+ */

+static void

+MDIO_management_clock

+(

+    int32_t clock

+)

+{

+	int32_t volatile a;

+    

+    MAC_BITBAND->CSR9_MDC = (uint32_t)clock;

+    

+	/* delay for 1us */

+	for( a = 0; a < ONEMICROSECOND; a++ ){}

+}

+

+

+/***************************************************************************//**

+ * Send read or write command to PHY.

+ */

+static void

+MDIO_send_cmd

+(

+    uint8_t regad,

+    mdio_cmd_t mdio_cmd

+)

+{

+    int32_t i;

+    uint16_t mask, data;

+

+    /* enable MII output */

+    MAC_BITBAND->CSR9_MDEN = 1;

+

+    /* send 32 1's preamble */

+    MAC_BITBAND->CSR9_MDO = 1;

+    for (i = 0; i < PREAMBLECOUNT; i++) {

+    	MDIO_management_clock( 0 );

+    	MDIO_management_clock( 1 );

+    }

+

+    /* calculate data bits */

+    data = MDIO_START |

+    	(( mdio_cmd == MDIO_CMD_READ ) ? MDIO_READ : MDIO_WRITE ) |

+    	((g_mss_mac.phy_address << MDIO_ADDR_OFFSET) & MDIO_ADDR_MASK) |

+    	((regad << MDIO_REG_ADDR_OFFSET) & MDIO_REG_ADDR_MASK);

+

+    /* sent out */

+    for( mask = 0x00008000L; mask>0; mask >>= 1 )

+    {

+        if ((mask == 0x2) && (mdio_cmd == MDIO_CMD_READ)) {

+    		/* enable MII input */

+            MAC_BITBAND->CSR9_MDEN = 0;

+        }

+

+    	MDIO_management_clock( 0 );

+

+        /* prepare MDO */

+        MAC_BITBAND->CSR9_MDO = (uint32_t)((mask & data) != 0 ? 1UL : 0UL);

+        

+    	MDIO_management_clock( 1 );

+    }

+}

+

+

+/***************************************************************************//**

+ * Reads a PHY register.

+ */

+static uint16_t

+MDIO_read

+(

+    uint8_t regad

+)

+{

+    uint16_t mask;

+    uint16_t data;

+

+    MDIO_send_cmd( regad, MDIO_CMD_READ);

+

+    /* read data */

+    data = 0;

+    for( mask = 0x00008000L; mask>0; mask >>= 1 )

+    {

+    	MDIO_management_clock( 0 );

+

+        /* read MDI */

+        if(MAC_BITBAND-> CSR9_MDI != 0){

+            data |= mask;

+        }

+

+    	MDIO_management_clock( 1 );

+    }

+

+    MDIO_management_clock( 0 );

+

+    return data;

+}

+

+

+/***************************************************************************//**

+ * Writes to a PHY register.

+ */

+static void

+MDIO_write

+(

+    uint8_t regad,

+    uint16_t data

+)

+{

+    uint16_t mask;

+

+    MDIO_send_cmd(regad, MDIO_CMD_WRITE);

+

+    /* write data */

+    for( mask = 0x00008000L; mask>0; mask >>= 1 )

+    {

+    	MDIO_management_clock( 0 );

+

+        /* prepare MDO */

+    	MAC_BITBAND->CSR9_MDO = (uint32_t)((mask & data) != 0 ? 1UL : 0UL);

+

+    	MDIO_management_clock( 1 );

+    }

+

+    MDIO_management_clock( 0 );

+}

+

+

+/****************************** PHY FUNCTIONS *********************************/

+

+/* Defines ********************************************************************/

+

+/* Base registers */

+#define PHYREG_MIIMCR		0x00    /**< MII Management Control Register */

+#define MIIMCR_RESET					(1<<15)

+#define MIIMCR_LOOPBACK                 (1<<14)

+#define MIIMCR_SPEED_SELECT				(1<<13)

+#define MIIMCR_ENABLE_AUTONEGOTIATION	(1<<12)

+#define MIIMCR_RESTART_AUTONEGOTIATION	(1<<9)

+#define MIIMCR_DUPLEX_MODE				(1<<8)

+#define MIIMCR_COLLISION_TEST			(1<<7)

+

+#define PHYREG_MIIMSR		0x01    /**< MII Management Status Register */

+#define MIIMSR_ANC			(1<<5)	/**< Auto-Negotiation Completed. */

+#define MIIMSR_LINK			(1<<2)	/**< Link is established. */

+

+#define PHYREG_PHYID1R		0x02    /**< PHY Identifier 1 Register */

+#define PHYREG_PHYID2R		0x03    /**< PHY Identifier 2 Register */

+

+#define PHYREG_ANAR			0x04    /**< Auto-Negotiation Advertisement Register */

+#define ANAR_100FD			(1<<8)

+#define ANAR_100HD			(1<<7)

+#define ANAR_10FD			(1<<6)

+#define ANAR_10HD			(1<<5)

+

+#define PHYREG_ANLPAR		0x05    /**< Auto-Negotiation Link Partner Ability Register */

+#define PHYREG_ANER			0x06    /**< Auto-Negotiation Expansion Register */

+#define PHYREG_NPAR			0x07    /**< Next Page Advertisement Register */

+/*			0x08-			0x0F  Reserved */

+#define PHYREG_MFR			0x10    /**< Miscellaneous Features Register */

+#define PHYREG_ICSR			0x11    /**< Interrupt Control/Status Register */

+

+#define PHYREG_DR			0x12    /**< Diagnostic Register */

+#define DR_DPLX				(1<<11)

+#define DR_DATA_RATE		(1<<10)

+

+#define PHYREG_PMLR			0x13    /**< Power Management & Loopback Register */

+/*			0x14 Reserved */

+#define PHYREG_MCR			0x15    /**< Mode Control Register */

+#define MCR_LED_SEL			(1<<9)

+/*			0x16 Reserved */

+#define PHYREG_DCR			0x17    /**< Disconnect Counter */

+#define PHYREG_RECR			0x18    /**< Receive Error Counter */

+/*                         0x19-0x1F  Reserved */

+

+/***************************************************************************//**

+ * Probe used PHY.

+ *

+ * return	PHY address. If PHY don't fount, returns 255.

+ */

+uint8_t PHY_probe( void )

+{

+	uint8_t phy;

+	uint8_t phy_found;

+	uint16_t reg;

+

+	phy_found = 0;

+	for (phy = MSS_PHY_ADDRESS_MIN; phy <= MSS_PHY_ADDRESS_MAX; phy++) {

+		g_mss_mac.phy_address = phy;

+

+        reg = MDIO_read( PHYREG_PHYID1R );

+

+        if ((reg != 0x0000ffffUL) && (reg != 0x00000000UL)) {

+        	phy_found = 1;

+        	phy = MSS_PHY_ADDRESS_MAX + 1;

+        }

+    }

+

+    if( phy_found == 0 ) {

+    	g_mss_mac.phy_address = MSS_PHY_ADDRESS_AUTO_DETECT;

+    }

+    return g_mss_mac.phy_address;

+}

+

+

+/***************************************************************************//**

+ * Resets the PHY.

+ */

+void PHY_reset( void )

+{

+	MDIO_write( PHYREG_MIIMCR, MIIMCR_RESET );

+	MDIO_write( PHYREG_MIIMCR,

+		MIIMCR_ENABLE_AUTONEGOTIATION |

+		MIIMCR_RESTART_AUTONEGOTIATION |

+		MIIMCR_COLLISION_TEST );

+}

+

+

+/***************************************************************************//**

+ * Restarts PHY auto-negotiation and wait until it's over.

+ */

+void PHY_auto_negotiate( void )

+{

+	uint16_t reg;

+

+	reg = MDIO_read( PHYREG_MIIMCR );

+	MDIO_write( PHYREG_MIIMCR,

+		(uint16_t)( MIIMCR_ENABLE_AUTONEGOTIATION |

+		MIIMCR_RESTART_AUTONEGOTIATION |

+		reg) );

+

+	for( ;; ) {

+		reg = MDIO_read( PHYREG_MIIMSR );

+		if( (reg & MIIMSR_ANC) != 0 ) {

+			break;

+		} else {

+			vTaskDelay( 200 );

+		}

+	}

+}

+

+

+/***************************************************************************//**

+ * Returns link status.

+ *

+ * @return          #MAC_LINK_STATUS_LINK if link is up.

+ */

+uint8_t PHY_link_status( void )

+{

+	uint8_t retval = 0;

+	if(( MDIO_read( PHYREG_MIIMSR ) & MIIMSR_LINK ) != 0 ){

+		retval = MSS_MAC_LINK_STATUS_LINK;

+	}

+	return retval;

+}

+

+

+/***************************************************************************//**

+ * Returns link type.

+ *

+ * @return          the logical OR of the following values:

+ *      #MAC_LINK_STATUS_100MB   - Connection is 100Mb

+ *      #MAC_LINK_STATUS_FDX     - Connection is full duplex

+ */

+uint8_t PHY_link_type( void )

+{

+	uint16_t diagnostic;

+	uint8_t type = 0;

+

+	diagnostic = MDIO_read( PHYREG_DR );

+

+    if( (diagnostic & DR_DPLX) != 0 ) {

+    	type = MSS_MAC_LINK_STATUS_FDX;

+    }

+

+    if( (diagnostic & DR_DATA_RATE) != 0 ) {

+    	type |= MSS_MAC_LINK_STATUS_100MB;

+    }

+

+    return type;

+}

+

+

+/***************************************************************************//**

+ * Sets link type.

+ */

+void

+PHY_set_link_type

+(

+    uint8_t type

+)

+{

+	uint16_t reg;

+

+	reg = MDIO_read( PHYREG_ANAR );

+	reg |= ANAR_100FD | ANAR_100HD | ANAR_10FD | ANAR_10HD;

+

+	if( (type & MSS_MAC_LINK_STATUS_100MB) == 0 ) {

+		reg &= ~(ANAR_100FD | ANAR_100HD);

+	}

+

+	if( (type & MSS_MAC_LINK_STATUS_FDX) == 0 ) {

+		reg &= ~(ANAR_100FD | ANAR_10FD);

+	}

+

+	MDIO_write( PHYREG_ANAR, reg );

+}

+

+

+/***************************************************************************//**

+ * Puts the Phy in Loopback mode

+ */

+uint16_t

+PHY_set_loopback

+(

+   uint8_t enable

+)

+{

+

+	uint16_t reg = 0;   

+	

+

+	reg = MDIO_read( PHYREG_MIIMCR );

+	// If set to one we need to set the LOCAL Phy loopback

+	if(enable == 1)

+		reg |= MIIMCR_LOOPBACK;

+	else // else we want to clear the bit..

+		reg ^= MIIMCR_LOOPBACK;

+	

+	

+	MDIO_write( PHYREG_MIIMCR,reg );

+	reg = MDIO_read( PHYREG_MIIMCR );

+	

+	return reg;

+	

+}

+

+#ifdef __cplusplus

+}

+#endif

+

+/******************************** END OF FILE *********************************/

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.h
new file mode 100644
index 0000000..e61daae
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.h
@@ -0,0 +1,78 @@
+/***************************************************************************//**

+ * PHY access methods.

+ *

+ * (c) Copyright 2007 Actel Corporation

+ *

+ * SVN $Revision: 2293 $

+ * SVN $Date: 2010-02-24 13:52:02 +0000 (Wed, 24 Feb 2010) $

+ *

+ ******************************************************************************/

+

+#ifndef __MSS_ETHERNET_MAC_PHY_H

+#define __MSS_ETHERNET_MAC_PHY_H	1

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/***************************************************************************//**

+ * Resets the PHY.

+ */

+void PHY_reset( void );

+

+

+/***************************************************************************//**

+ * Restarts PHY auto-negotiation and wait until it's over.

+ */

+void PHY_auto_negotiate( void );

+

+

+/***************************************************************************//**

+ * Probe used PHY.

+ *

+ * return	PHY address. If PHY don't fount, returns 255.

+ */

+uint8_t PHY_probe( void );

+

+

+/***************************************************************************//**

+ * Returns link status.

+ *

+ * @return          #MAC_LINK_STATUS_LINK if link is up.

+ */

+uint8_t PHY_link_status( void );

+

+

+/***************************************************************************//**

+ * Returns link type.

+ *

+ * @return          the logical OR of the following values:

+ *      #MAC_LINK_STATUS_100MB   - Connection is 100Mb

+ *      #MAC_LINK_STATUS_FDX     - Connection is full duplex

+ */

+uint8_t PHY_link_type( void );

+

+

+/***************************************************************************//**

+ * Sets link type.

+ */

+void

+PHY_set_link_type

+(

+    uint8_t type

+);

+

+/***************************************************************************//**

+ * Sets/Clears the phy loop back mode, based on the enable value

+ */

+uint16_t

+PHY_set_loopback

+(

+    uint8_t enable

+);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /*__MSS_ETHERNET_MAC_PHY_H*/

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.c
new file mode 100644
index 0000000..e3be9aa
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.c
@@ -0,0 +1,283 @@
+/*******************************************************************************

+ * (c) Copyright 2008 Actel Corporation.  All rights reserved.

+ * 

+ * SmartFusion microcontroller subsystem GPIO bare metal driver implementation.

+ *

+ * SVN $Revision: 1753 $

+ * SVN $Date: 2009-12-11 15:12:18 +0000 (Fri, 11 Dec 2009) $

+ */

+#include "mss_gpio.h"

+#include "../../CMSIS/mss_assert.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/*-------------------------------------------------------------------------*//**

+*

+*/

+#define GPIO_INT_ENABLE_MASK        (uint32_t)0x00000008UL

+#define OUTPUT_BUFFER_ENABLE_MASK   0x00000004UL

+

+#define NB_OF_GPIO  (uint32_t)32

+

+/*-------------------------------------------------------------------------*//**

+ * Lookup table of GPIO configuration registers address indexed on GPIO ID.

+ */

+static uint32_t volatile * const g_config_reg_lut[NB_OF_GPIO] =

+{

+    &(GPIO->GPIO_0_CFG),

+    &(GPIO->GPIO_1_CFG),

+    &(GPIO->GPIO_2_CFG),

+    &(GPIO->GPIO_3_CFG),

+    &(GPIO->GPIO_4_CFG),

+    &(GPIO->GPIO_5_CFG),

+    &(GPIO->GPIO_6_CFG),

+    &(GPIO->GPIO_7_CFG),

+    &(GPIO->GPIO_8_CFG),

+    &(GPIO->GPIO_9_CFG),

+    &(GPIO->GPIO_10_CFG),

+    &(GPIO->GPIO_11_CFG),

+    &(GPIO->GPIO_12_CFG),

+    &(GPIO->GPIO_13_CFG),

+    &(GPIO->GPIO_14_CFG),

+    &(GPIO->GPIO_15_CFG),

+    &(GPIO->GPIO_16_CFG),

+    &(GPIO->GPIO_17_CFG),

+    &(GPIO->GPIO_18_CFG),

+    &(GPIO->GPIO_19_CFG),

+    &(GPIO->GPIO_20_CFG),

+    &(GPIO->GPIO_21_CFG),

+    &(GPIO->GPIO_22_CFG),

+    &(GPIO->GPIO_23_CFG),

+    &(GPIO->GPIO_24_CFG),

+    &(GPIO->GPIO_25_CFG),

+    &(GPIO->GPIO_26_CFG),

+    &(GPIO->GPIO_27_CFG),

+    &(GPIO->GPIO_28_CFG),

+    &(GPIO->GPIO_29_CFG),

+    &(GPIO->GPIO_30_CFG),

+    &(GPIO->GPIO_31_CFG)

+};

+

+/*-------------------------------------------------------------------------*//**

+ * Lookup table of Cortex-M3 GPIO interrupt number indexed on GPIO ID.

+ */

+static const IRQn_Type g_gpio_irqn_lut[NB_OF_GPIO] =

+{

+    GPIO0_IRQn,

+    GPIO1_IRQn,

+    GPIO2_IRQn,

+    GPIO3_IRQn,

+    GPIO4_IRQn,

+    GPIO5_IRQn,

+    GPIO6_IRQn,

+    GPIO7_IRQn,

+    GPIO8_IRQn,

+    GPIO9_IRQn,

+    GPIO10_IRQn,

+    GPIO11_IRQn,

+    GPIO12_IRQn,

+    GPIO13_IRQn,

+    GPIO14_IRQn,

+    GPIO15_IRQn,

+    GPIO16_IRQn,

+    GPIO17_IRQn,

+    GPIO18_IRQn,

+    GPIO19_IRQn,

+    GPIO20_IRQn,

+    GPIO21_IRQn,

+    GPIO22_IRQn,

+    GPIO23_IRQn,

+    GPIO24_IRQn,

+    GPIO25_IRQn,

+    GPIO26_IRQn,

+    GPIO27_IRQn,

+    GPIO28_IRQn,

+    GPIO29_IRQn,

+    GPIO30_IRQn,

+    GPIO31_IRQn

+};

+

+/*-------------------------------------------------------------------------*//**

+ * MSS_GPIO_init

+ * See "mss_gpio.h" for details of how to use this function.

+ */

+void MSS_GPIO_init( void )

+{

+    uint32_t i;

+    

+    /* reset MSS GPIO hardware */

+    SYSREG->SOFT_RST_CR |= SYSREG_GPIO_SOFTRESET_MASK;

+    /* Clear any previously pended MSS GPIO interrupt */

+    for ( i = 0U; i < NB_OF_GPIO; ++i )

+    {

+        NVIC_ClearPendingIRQ( g_gpio_irqn_lut[i] );

+    }

+    /* Take MSS GPIO hardware out of reset. */

+    SYSREG->SOFT_RST_CR &= ~SYSREG_GPIO_SOFTRESET_MASK;

+}

+

+/*-------------------------------------------------------------------------*//**

+ * MSS_GPIO_config

+ * See "mss_gpio.h" for details of how to use this function.

+ */

+void MSS_GPIO_config

+(

+    mss_gpio_id_t port_id,

+    uint32_t config

+)

+{

+    uint32_t gpio_idx = (uint32_t)port_id;

+    

+    ASSERT( gpio_idx < NB_OF_GPIO );

+

+    if ( gpio_idx < NB_OF_GPIO )

+    {

+        *(g_config_reg_lut[gpio_idx]) = config;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ * MSS_GPIO_set_output

+ * See "mss_gpio.h" for details of how to use this function.

+ */

+void MSS_GPIO_set_output

+(

+    mss_gpio_id_t       port_id,

+    uint8_t             value

+)

+{

+    uint32_t gpio_idx = (uint32_t)port_id;

+    

+    ASSERT( gpio_idx < NB_OF_GPIO );

+    

+    if ( gpio_idx < NB_OF_GPIO )

+    {

+        GPIO_BITBAND->GPIO_OUT[gpio_idx] = (uint32_t)value;

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ * MSS_GPIO_drive_inout

+ * See "mss_gpio.h" for details of how to use this function.

+ */

+void MSS_GPIO_drive_inout

+(

+    mss_gpio_id_t port_id,

+    mss_gpio_inout_state_t inout_state

+)

+{

+    uint32_t outputs_state;

+    uint32_t config;

+    uint32_t gpio_idx = (uint32_t)port_id;

+    

+    ASSERT( gpio_idx < NB_OF_GPIO );

+    

+    if ( gpio_idx < NB_OF_GPIO )

+    {

+        switch( inout_state )

+        {

+        case MSS_GPIO_DRIVE_HIGH:

+            /* Set output high */

+            outputs_state = GPIO->GPIO_OUT;

+            outputs_state |= (uint32_t)1 << gpio_idx;

+            GPIO->GPIO_OUT = outputs_state;

+            /* Enable output buffer */

+            config = *(g_config_reg_lut[gpio_idx]);

+            config |= OUTPUT_BUFFER_ENABLE_MASK;

+            *(g_config_reg_lut[gpio_idx]) = config;

+            break;

+            

+        case MSS_GPIO_DRIVE_LOW:

+            /* Set output low */

+            outputs_state = GPIO->GPIO_OUT;

+            outputs_state &= ~((uint32_t)((uint32_t)1 << gpio_idx));

+            GPIO->GPIO_OUT = outputs_state;

+            /* Enable output buffer */

+            config = *(g_config_reg_lut[gpio_idx]);

+            config |= OUTPUT_BUFFER_ENABLE_MASK;

+            *(g_config_reg_lut[gpio_idx]) = config;

+            break;

+            

+        case MSS_GPIO_HIGH_Z:

+            /* Disable output buffer */

+            config = *(g_config_reg_lut[gpio_idx]);

+            config &= ~OUTPUT_BUFFER_ENABLE_MASK;

+            *(g_config_reg_lut[gpio_idx]) = config;

+            break;

+            

+        default:

+            ASSERT(0);

+            break;

+        }

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ * MSS_GPIO_enable_irq

+ * See "mss_gpio.h" for details of how to use this function.

+ */

+void MSS_GPIO_enable_irq

+(

+    mss_gpio_id_t port_id

+)

+{

+    uint32_t cfg_value;

+    uint32_t gpio_idx = (uint32_t)port_id;

+    

+    ASSERT( gpio_idx < NB_OF_GPIO );

+    

+    if ( gpio_idx < NB_OF_GPIO )

+    {

+        cfg_value = *(g_config_reg_lut[gpio_idx]);

+        *(g_config_reg_lut[gpio_idx]) = (cfg_value | GPIO_INT_ENABLE_MASK);

+        NVIC_EnableIRQ( g_gpio_irqn_lut[gpio_idx] );

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ * MSS_GPIO_disable_irq

+ * See "mss_gpio.h" for details of how to use this function.

+ */

+void MSS_GPIO_disable_irq

+(

+    mss_gpio_id_t port_id

+)

+{

+    uint32_t cfg_value;

+    uint32_t gpio_idx = (uint32_t)port_id;

+    

+    ASSERT( gpio_idx < NB_OF_GPIO );

+

+    if ( gpio_idx < NB_OF_GPIO )

+    {

+        cfg_value = *(g_config_reg_lut[gpio_idx]);

+        *(g_config_reg_lut[gpio_idx]) = (cfg_value & ~GPIO_INT_ENABLE_MASK);

+    }

+}

+

+/*-------------------------------------------------------------------------*//**

+ * MSS_GPIO_clear_irq

+ * See "mss_gpio.h" for details of how to use this function.

+ */

+void MSS_GPIO_clear_irq

+(

+    mss_gpio_id_t port_id

+)

+{

+    uint32_t gpio_idx = (uint32_t)port_id;

+    

+    ASSERT( gpio_idx < NB_OF_GPIO );

+    

+    if ( gpio_idx < NB_OF_GPIO )

+    {

+        GPIO->GPIO_IRQ = ((uint32_t)1) << gpio_idx;

+        NVIC_ClearPendingIRQ( g_gpio_irqn_lut[gpio_idx] );

+    }

+}

+

+#ifdef __cplusplus

+}

+#endif

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.h
new file mode 100644
index 0000000..60220f1
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.h
@@ -0,0 +1,488 @@
+/*******************************************************************************

+ * (c) Copyright 2008 Actel Corporation.  All rights reserved.

+ * 

+ *  SmartFusion Microcontroller Subsystem GPIO bare metal software driver public

+ *  API.

+ *

+ * SVN $Revision: 1751 $

+ * SVN $Date: 2009-12-11 15:05:48 +0000 (Fri, 11 Dec 2009) $

+ */

+

+/*=========================================================================*//**

+  @mainpage SmartFusion MSS GPIO Bare Metal Driver.

+

+  @section intro_sec Introduction

+  The SmartFusion Microcontroller Subsystem (MSS) includes a block of 32 general

+  purpose input/outputs (GPIO).

+  This software driver provides a set of functions for controlling the MSS GPIO

+  block as part of a bare metal system where no operating system is available.

+  This driver can be adapted for use as part of an operating system but the

+  implementation of the adaptation layer between this driver and the operating

+  system's driver model is outside the scope of this driver.

+  

+  @section hw_dependencies Hardware Flow Dependencies

+  The configuration of all features of the MSS GPIOs is covered by this driver

+  with the exception of the SmartFusion IOMUX configuration. SmartFusion allows

+  multiple non-concurrent use of some external pins through IOMUX configuration.

+  This feature allows optimizing external pin usage by assigning external pins

+  for usage by either the microcontroller subsystem or the FPGA fabric.

+  The MSS GPIO ports 0 to 15 are always connected to external pins but GPIO ports

+  16 to 31 are routed through IOMUX to the SmartFusion device external pins.

+  These IOMUX are configured using the MSS Configurator tool.

+  Make sure the MSS GPIOs 16 to 31 are enabled in the MSS Configurator tool if

+  you wish to use them

+  

+  @section theory_op Theory of Operation

+  The MSS GPIO driver uses the SmartFusion "Cortex Microcontroler Software

+  Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access MSS hardware

+  registers. You must ensure that the SmartFusion CMSIS-PAL is either included

+  in the software toolchain used to build your project or is included in your

+  project. The most up-to-date SmartFusion CMSIS-PAL files can be obtained using

+  the Actel Firmware Catalog.

+  

+  The MSS GPIO driver functions are grouped into the following categories:

+    - Initiliazation

+    - Configuration

+    - Reading and setting GPIO state

+    - Interrupt control

+  

+  The MSS GPIO driver is initialized through a call to the GPIO_init() function.

+  The GPIO_init() function must be called before any other GPIO driver functions

+  can be called.

+  

+  Each GPIO port is individually configured through a call to the

+  MSS_GPIO_config() function. Configuration includes deciding if a GPIO port

+  will be used as an input, an output or both. GPIO ports configured as inputs can be

+  further configured to generate interrupts based on the input's state.

+  Interrupts can be level or edge sensitive.

+  

+  The state of the GPIO ports can be read and set using the following functions:

+    - MSS_GPIO_get_inputs()

+    - MSS_GPIO_get_outputs()

+    - MSS_GPIO_set_outputs()

+    - MSS_GPIO_set_output()

+    - MSS_GPIO_drive_inout()

+    

+  Interrupts generated by GPIO ports configured as inputs are controlled using

+  the following functions:

+    - MSS_GPIO_enable_irq()

+    - MSS_GPIO_disable_irq()

+    - MSS_GPIO_clear_irq()

+  

+ *//*=========================================================================*/

+#ifndef MSS_GPIO_H_

+#define MSS_GPIO_H_

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+#include "../../CMSIS/a2fxxxm3.h"

+

+/*-------------------------------------------------------------------------*//**

+  The mss_gpio_id_t enumeration is used to identify GPIOs as part of the

+  parameter to functions:

+    - MSS_GPIO_config(),

+    - MSS_GPIO_drive_inout(),

+    - MSS_GPIO_enable_irq(),

+    - MSS_GPIO_disable_irq(),

+    - MSS_GPIO_clear_irq()

+ */

+typedef enum __mss_gpio_id_t

+{

+    MSS_GPIO_0 = 0,

+    MSS_GPIO_1 = 1,

+    MSS_GPIO_2 = 2,

+    MSS_GPIO_3 = 3,

+    MSS_GPIO_4 = 4,

+    MSS_GPIO_5 = 5,

+    MSS_GPIO_6 = 6,

+    MSS_GPIO_7 = 7,

+    MSS_GPIO_8 = 8,

+    MSS_GPIO_9 = 9,

+    MSS_GPIO_10 = 10,

+    MSS_GPIO_11 = 11,

+    MSS_GPIO_12 = 12,

+    MSS_GPIO_13 = 13,

+    MSS_GPIO_14 = 14,

+    MSS_GPIO_15 = 15,

+    MSS_GPIO_16 = 16,

+    MSS_GPIO_17 = 17,

+    MSS_GPIO_18 = 18,

+    MSS_GPIO_19 = 19,

+    MSS_GPIO_20 = 20,

+    MSS_GPIO_21 = 21,

+    MSS_GPIO_22 = 22,

+    MSS_GPIO_23 = 23,

+    MSS_GPIO_24 = 24,

+    MSS_GPIO_25 = 25,

+    MSS_GPIO_26 = 26,

+    MSS_GPIO_27 = 27,

+    MSS_GPIO_28 = 28,

+    MSS_GPIO_29 = 29,

+    MSS_GPIO_30 = 30,

+    MSS_GPIO_31 = 31

+} mss_gpio_id_t;

+

+/*-------------------------------------------------------------------------*//**

+  GPIO ports definitions used to identify GPIOs as part of the parameter to

+  function MSS_GPIO_set_outputs().

+  These definitions can also be used to identity GPIO through logical

+  operations on the return value of function MSS_GPIO_get_inputs().

+ */

+#define MSS_GPIO_0_MASK		    0x00000001UL

+#define MSS_GPIO_1_MASK		    0x00000002UL

+#define MSS_GPIO_2_MASK         0x00000004UL

+#define MSS_GPIO_3_MASK	        0x00000008UL

+#define MSS_GPIO_4_MASK	        0x00000010UL

+#define MSS_GPIO_5_MASK	        0x00000020UL

+#define MSS_GPIO_6_MASK	        0x00000040UL

+#define MSS_GPIO_7_MASK	        0x00000080UL

+#define MSS_GPIO_8_MASK	        0x00000100UL

+#define MSS_GPIO_9_MASK		    0x00000200UL

+#define MSS_GPIO_10_MASK		0x00000400UL

+#define MSS_GPIO_11_MASK		0x00000800UL

+#define MSS_GPIO_12_MASK		0x00001000UL

+#define MSS_GPIO_13_MASK		0x00002000UL

+#define MSS_GPIO_14_MASK		0x00004000UL

+#define MSS_GPIO_15_MASK		0x00008000UL

+#define MSS_GPIO_16_MASK		0x00010000UL

+#define MSS_GPIO_17_MASK		0x00020000UL

+#define MSS_GPIO_18_MASK		0x00040000UL

+#define MSS_GPIO_19_MASK		0x00080000UL

+#define MSS_GPIO_20_MASK		0x00100000UL

+#define MSS_GPIO_21_MASK		0x00200000UL

+#define MSS_GPIO_22_MASK		0x00400000UL

+#define MSS_GPIO_23_MASK		0x00800000UL

+#define MSS_GPIO_24_MASK		0x01000000UL

+#define MSS_GPIO_25_MASK		0x02000000UL

+#define MSS_GPIO_26_MASK		0x04000000UL

+#define MSS_GPIO_27_MASK		0x08000000UL

+#define MSS_GPIO_28_MASK		0x10000000UL

+#define MSS_GPIO_29_MASK		0x20000000UL

+#define MSS_GPIO_30_MASK		0x40000000UL

+#define MSS_GPIO_31_MASK		0x80000000UL

+

+/*-------------------------------------------------------------------------*//**

+ * GPIO modes

+ */

+#define MSS_GPIO_INPUT_MODE              0x0000000002UL

+#define MSS_GPIO_OUTPUT_MODE             0x0000000005UL

+#define MSS_GPIO_INOUT_MODE              0x0000000003UL

+

+/*-------------------------------------------------------------------------*//**

+ * Possible GPIO inputs interrupt configurations.

+ */

+#define MSS_GPIO_IRQ_LEVEL_HIGH			0x0000000000UL

+#define MSS_GPIO_IRQ_LEVEL_LOW			0x0000000020UL

+#define MSS_GPIO_IRQ_EDGE_POSITIVE		0x0000000040UL

+#define MSS_GPIO_IRQ_EDGE_NEGATIVE		0x0000000060UL

+#define MSS_GPIO_IRQ_EDGE_BOTH			0x0000000080UL

+

+/*-------------------------------------------------------------------------*//**

+ * Possible states for GPIO configured as INOUT.

+ */

+typedef enum mss_gpio_inout_state

+{

+    MSS_GPIO_DRIVE_LOW = 0,

+    MSS_GPIO_DRIVE_HIGH,

+    MSS_GPIO_HIGH_Z

+} mss_gpio_inout_state_t;

+

+/*-------------------------------------------------------------------------*//**

+  The MSS_GPIO_init() function initializes the SmartFusion MSS GPIO block. It

+  resets the MSS GPIO hardware block and it also clears any pending MSS GPIO

+  interrupts in the Cortex-M3 interrupt controller.

+  

+   @return

+    none.

+ */

+void MSS_GPIO_init( void );

+

+/*-------------------------------------------------------------------------*//**

+  The MSS_GPIO_config() function is used to configure an individual

+  GPIO port.

+ 

+  @param port_id

+    The port_id parameter identifies the GPIO port to be configured.

+    An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO

+    port is used to identify the GPIO port. For example MSS_GPIO_0 identifies

+    the first GPIO port and MSS_GPIO_31 the last one.

+    

+  @param config

+    The config parameter specifies the configuration to be applied to the GPIO

+    port identified by the port_id parameter. It is a logical OR of the required

+    I/O mode and the required interrupt mode. The interrupt mode is not relevant

+    if the GPIO is configured as an output only.

+       These I/O mode constants are allowed:

+           - MSS_GPIO_INPUT_MODE

+           - MSS_GPIO_OUTPUT_MODE

+           - MSS_GPIO_INOUT_MODE

+       These interrupt mode constants are allowed:

+           - MSS_GPIO_IRQ_LEVEL_HIGH

+           - MSS_GPIO_IRQ_LEVEL_LOW

+           - MSS_GPIO_IRQ_EDGE_POSITIVE

+           - MSS_GPIO_IRQ_EDGE_NEGATIVE

+           - MSS_GPIO_IRQ_EDGE_BOTH

+  

+   @return

+    none.

+

+  Example:

+  The following call will configure GPIO 4 as an input generating interrupts on

+  a low to high transition of the input:

+  @code

+  MSS_GPIO_config( MSS_GPIO_4, MSS_GPIO_INPUT_MODE | MSS_GPIO_IRQ_EDGE_POSITIVE );

+  @endcode

+ */

+void MSS_GPIO_config

+(

+    mss_gpio_id_t port_id,

+    uint32_t config

+);

+

+/*-------------------------------------------------------------------------*//**

+  The MSS_GPIO_set_outputs() function is used to set the state of all GPIO

+  ports configured as outputs.

+ 

+  @param value

+    The value parameter specifies the state of the GPIO ports configured as

+    outputs. It is a bit mask of the form (MSS_GPIO_n_MASK | MSS_GPIO_m_MASK) where n

+    and m are numbers identifying GPIOs.

+    For example (MSS_GPIO_0_MASK | MSS_GPIO_1_MASK | MSS_GPIO_2_MASK ) specifies

+    that the first, second and third GPIOs' must be set high and all other

+    outputs set low.

+    The driver provides 32 mask constants, MSS_GPIO_0_MASK to MSS_GPIO_31_MASK

+    inclusive, for this purpose.

+  

+  @return

+    none.

+

+  Example 1:

+    Set GPIOs outputs 0 and 8 high and all other GPIO outputs low.

+    @code

+        MSS_GPIO_set_outputs( MSS_GPIO_0_MASK | MSS_GPIO_8_MASK );

+    @endcode

+

+  Example 2:

+    Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs.

+    @code

+        uint32_t gpio_outputs;

+        gpio_outputs = MSS_GPIO_get_outputs();

+        gpio_outputs &= ~( MSS_GPIO_2_MASK | MSS_GPIO_4_MASK );

+        MSS_GPIO_set_outputs(  gpio_outputs );

+    @endcode

+

+  @see MSS_GPIO_get_outputs()

+ */

+static __INLINE void

+MSS_GPIO_set_outputs

+(

+   uint32_t value

+)

+{

+    GPIO->GPIO_OUT = value;

+}

+

+/*-------------------------------------------------------------------------*//**

+  The MSS_GPIO_set_output() function is used to set the state of a single GPIO

+  port configured as output.

+ 

+  @param port_id

+    The port_id parameter identifies the GPIO port that is to have its output set.

+    An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO

+    port is used to identify the GPIO port. For example MSS_GPIO_0 identifies the

+    first GPIO port and MSS_GPIO_31 the last one.

+  

+  @param value

+    The value parameter specifies the desired state for the GPIO output. A value

+    of 0 will set the output low and a value of 1 will set the output high.

+  

+  @return

+    none.

+ */

+void MSS_GPIO_set_output

+(

+    mss_gpio_id_t       port_id,

+    uint8_t             value

+);

+

+/*-------------------------------------------------------------------------*//**

+  The MSS_GPIO_get_inputs() function is used to read the current state of all

+  GPIO ports confgured as inputs.

+ 

+  @return

+    This function returns a 32 bit unsigned integer where each bit represents

+    the state of a GPIO input. The least significant bit represents the state of

+    GPIO input 0 and the most significant bit the state of GPIO input 31.

+

+  Example:

+    Read and assign the current state of the GPIO outputs to a variable.

+    @code

+        uint32_t gpio_inputs;

+        gpio_inputs = MSS_GPIO_get_inputs();

+    @endcode

+ */

+static __INLINE uint32_t

+MSS_GPIO_get_inputs( void )

+{

+    return GPIO->GPIO_IN;

+}

+

+/*-------------------------------------------------------------------------*//**

+  The MSS_GPIO_get_outputs() function is used to read the current state of all

+  GPIO ports confgured as outputs.

+ 

+  @return

+     This function returns a 32 bit unsigned integer where each bit represents

+     the state of a GPIO output. The least significant bit represents the state

+     of GPIO output 0 and the most significant bit the state of GPIO output 31.

+

+  Example:

+    Read and assign the current state of the GPIO outputs to a variable.

+    @code

+        uint32_t gpio_outputs;

+        gpio_outputs = MSS_GPIO_get_outputs();

+    @endcode

+ */

+static __INLINE uint32_t

+MSS_GPIO_get_outputs( void )

+{

+    return GPIO->GPIO_OUT;

+}

+

+/*-------------------------------------------------------------------------*//**

+  The MSS_GPIO_drive_inout() function is used to set the output state of a single

+  GPIO port configured as an INOUT. An INOUT GPIO can be in one of three states:

+    - high

+    - low

+    - high impedance

+  An INOUT output would typically be used where several devices can drive the

+  state of a shared signal line. The high and low states are equivalent to the

+  high and low states of a GPIO configured as output. The high impedance state

+  is used to prevent the GPIO from driving its output state onto the signal line,

+  while at the same time allowing the input state of the GPIO to be read

+ 

+  @param port_id

+    The port_id parameter identifies the GPIO port for which you want to change

+    the output state.

+    An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO

+    port is used to identify the GPIO port. For example MSS_GPIO_0 identifies

+    the first GPIO port and MSS_GPIO_31 the last one.

+    

+  @param inout_state

+    The inout_state parameter specifies the state of the GPIO port identified by

+    the port_id parameter. Allowed values of type mss_gpio_inout_state_t are:

+                           - MSS_GPIO_DRIVE_HIGH

+                           - MSS_GPIO_DRIVE_LOW

+                           - MSS_GPIO_HIGH_Z (high impedance)

+

+  @return

+    none.

+

+  Example:

+    The call to MSS_GPIO_drive_inout() below will set the GPIO 7 output to the

+    high impedance state.

+    @code

+    MSS_GPIO_drive_inout( MSS_GPIO_7, MSS_GPIO_HIGH_Z );

+    @endcode

+ */

+void MSS_GPIO_drive_inout

+(

+    mss_gpio_id_t           port_id,

+    mss_gpio_inout_state_t  inout_state

+);

+

+/*-------------------------------------------------------------------------*//**

+  The MSS_GPIO_enable_irq() function is used to enable interrupt generation

+  for the specified GPIO input. Interrupts are generated based on the state of

+  the GPIO input and the interrupt mode configured for it by MSS_GPIO_config().

+ 

+  @param port_id

+    The port_id parameter identifies the GPIO port for which you want to enable

+    interrupt generation.

+    An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO

+    port is used to identify the GPIO port. For example MSS_GPIO_0 identifies the

+    first GPIO port and MSS_GPIO_31 the last one.

+    

+  @return

+    none.

+

+  Example:

+    The call to MSS_GPIO_enable_irq() below will allow GPIO 8 to generate

+    interrupts.

+    @code

+    MSS_GPIO_enable_irq( MSS_GPIO_8 );

+    @endcode

+ */

+void MSS_GPIO_enable_irq

+(

+    mss_gpio_id_t port_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The MSS_GPIO_disable_irq() function is used to disable interrupt generation

+  for the specified GPIO input.

+ 

+  @param port_id

+    The port_id parameter identifies the GPIO port for which you want to disable

+    interrupt generation.

+    An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO

+    port is used to identify the GPIO port. For example MSS_GPIO_0 identifies the

+    first GPIO port and MSS_GPIO_31 the last one.

+ 

+  @return

+    none.

+

+  Example:

+    The call to MSS_GPIO_disable_irq() below will prevent GPIO 8 from generating

+    interrupts.

+    @code

+    MSS_GPIO_disable_irq( MSS_GPIO_8 );

+    @endcode

+ */

+void MSS_GPIO_disable_irq

+(

+    mss_gpio_id_t port_id

+);

+

+/*-------------------------------------------------------------------------*//**

+  The MSS_GPIO_clear_irq() function is used to clear a pending interrupt from

+  the specified GPIO input.

+  Note: The MSS_GPIO_clear_irq() function must be called as part of any GPIO

+  interrupt service routine (ISR) in order to prevent the same interrupt event

+  retriggering a call to the GPIO ISR. The function also clears the interrupt

+  in the Cortex-M3 interrupt controller through a call to NVIC_ClearPendingIRQ().

+ 

+  @param port_id

+    The port_id parameter identifies the GPIO input for which you want to clear the

+    interrupt.

+    An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO

+    port is used to identify the GPIO port. For example MSS_GPIO_0 identifies the

+    first GPIO port and MSS_GPIO_31 the last one.

+    

+  @return

+    none.

+

+  Example:

+    The example below demonstrates the use of the MSS_GPIO_clear_irq() function

+    as part of the GPIO 9 interrupt service routine.  

+    @code

+    void GPIO9_IRQHandler( void )

+    {

+        do_interrupt_processing();

+        

+        MSS_GPIO_clear_irq( MSS_GPIO_9 );

+    }

+    @endcode

+ */

+void MSS_GPIO_clear_irq

+(

+    mss_gpio_id_t port_id

+);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* MSS_GPIO_H_ */

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.c
new file mode 100644
index 0000000..b49dca4
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.c
@@ -0,0 +1,413 @@
+/*******************************************************************************

+ * (c) Copyright 2008 Actel Corporation.  All rights reserved.

+ * 

+ * SmartFusion microcontroller subsystem Peripheral DMA bare metal software

+ * driver implementation.

+ *

+ * SVN $Revision: 2110 $

+ * SVN $Date: 2010-02-05 15:24:19 +0000 (Fri, 05 Feb 2010) $

+ */

+#include "mss_pdma.h"

+#include "../../CMSIS/mss_assert.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void DMA_IRQHandler( void );

+#else

+void DMA_IRQHandler( void );

+#endif

+

+/***************************************************************************//**

+  Offset of the posted writes WRITE_ADJ bits in a PDMA channel's configuration

+  register.

+ */

+#define CHANNEL_N_POSTED_WRITE_ADJUST_SHIFT   14

+

+/*-------------------------------------------------------------------------*//**

+ * Look-up table use to derice a channel's control register value from the

+ * requested source/destination. This table is incexed on the pdma_src_dest_t

+ * enumeration.

+ */

+#define CHANNEL_N_CTRL_PDMA_MASK        (uint32_t)0x00000001

+#define CHANNEL_N_PERIPH_SELECT_SHIFT   (uint32_t)23

+#define CHANNEL_N_DIRECTION_MASK        (uint32_t)0x00000002

+

+const uint32_t src_dest_to_ctrl_reg_lut[] =

+{

+    CHANNEL_N_CTRL_PDMA_MASK,                                                                               /* PDMA_FROM_UART_0 */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)1 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK,  /* PDMA_TO_UART_0 */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)2 << CHANNEL_N_PERIPH_SELECT_SHIFT),                             /* PDMA_FROM_UART_1 */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)3 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK,  /* PDMA_TO_UART_1 */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)4 << CHANNEL_N_PERIPH_SELECT_SHIFT),                             /* PDMA_FROM_SPI_0 */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)5 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK,  /* PDMA_TO_SPI_0 */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)6 << CHANNEL_N_PERIPH_SELECT_SHIFT),                             /* PDMA_FROM_SPI_1 */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)7 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK,  /* PDMA_TO_SPI_1 */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)8 << CHANNEL_N_PERIPH_SELECT_SHIFT),                             /* PDMA_FROM_FPGA_1 */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)8 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK,  /* PDMA_TO_FPGA_1 */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)9 << CHANNEL_N_PERIPH_SELECT_SHIFT),                             /* PDMA_FROM_FPGA_0 */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)9 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK,  /* PDMA_TO_FPGA_0 */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)10 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_ACE */

+    CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)11 << CHANNEL_N_PERIPH_SELECT_SHIFT)                             /* PDMA_FROM_ACE */

+};

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#define PDMA_MASTER_ENABLE  (uint32_t)0x04

+#define PDMA_SOFT_RESET     (uint32_t)0x20

+

+/*-------------------------------------------------------------------------*//**

+ *

+ */

+#define NB_OF_PDMA_CHANNELS     8

+

+#define NEXT_CHANNEL_A      0U

+#define NEXT_CHANNEL_B      1U

+

+#define CHANNEL_STOPPED     0U

+#define CHANNEL_STARTED     1U

+

+static uint8_t g_pdma_next_channel[NB_OF_PDMA_CHANNELS];

+static uint8_t g_pdma_started_a[NB_OF_PDMA_CHANNELS];

+static uint8_t g_pdma_started_b[NB_OF_PDMA_CHANNELS];

+static pdma_channel_isr_t g_pdma_isr_table[NB_OF_PDMA_CHANNELS];

+static const uint16_t g_pdma_status_mask[NB_OF_PDMA_CHANNELS] =

+{

+    (uint16_t)0x0003, /* PDMA_CHANNEL_0 */

+    (uint16_t)0x000C, /* PDMA_CHANNEL_1 */

+    (uint16_t)0x0030, /* PDMA_CHANNEL_2 */

+    (uint16_t)0x00C0, /* PDMA_CHANNEL_3 */

+    (uint16_t)0x0300, /* PDMA_CHANNEL_4 */

+    (uint16_t)0x0C00, /* PDMA_CHANNEL_5 */

+    (uint16_t)0x3000, /* PDMA_CHANNEL_6 */

+    (uint16_t)0xC000, /* PDMA_CHANNEL_7 */

+};

+

+

+

+/***************************************************************************//**

+ * See mss_pdma.h for description of this function.

+ */

+void PDMA_init( void )

+{

+    int32_t i;

+    

+    /* Enable PDMA master access to comms matrix. */

+    SYSREG->AHB_MATRIX_CR |= PDMA_MASTER_ENABLE;

+    

+    /* Reset PDMA block. */

+    SYSREG->SOFT_RST_CR |= PDMA_SOFT_RESET;

+    

+    /* Clear any previously pended MSS PDMA interrupt */

+    NVIC_ClearPendingIRQ( DMA_IRQn );

+        

+    /* Take PDMA controller out of reset*/

+    SYSREG->SOFT_RST_CR &= ~PDMA_SOFT_RESET;

+    

+    /* Initialize channels state information. */

+    for ( i = 0; i < NB_OF_PDMA_CHANNELS; ++i )

+    {

+        g_pdma_next_channel[i] = NEXT_CHANNEL_A;

+        g_pdma_started_a[i] = CHANNEL_STOPPED;

+        g_pdma_started_b[i] = CHANNEL_STOPPED;

+        g_pdma_isr_table[i] = 0;

+    }

+}

+

+/***************************************************************************//**

+ * See mss_pdma.h for description of this function.

+ */

+#define CHANNEL_RESET_MASK  (uint32_t)0x00000020

+

+void PDMA_configure

+(

+    pdma_channel_id_t channel_id,

+    pdma_src_dest_t src_dest,

+    uint32_t channel_cfg,

+    uint8_t write_adjust

+)

+{

+    /* Reset the channel. */

+    PDMA->CHANNEL[channel_id].CRTL |= CHANNEL_RESET_MASK;

+    PDMA->CHANNEL[channel_id].CRTL &= ~CHANNEL_RESET_MASK;

+

+    /* Configure PDMA channel's data source and destination. */

+    if ( src_dest != PDMA_MEM_TO_MEM )

+    {

+        PDMA->CHANNEL[channel_id].CRTL |= src_dest_to_ctrl_reg_lut[src_dest];

+    }

+    

+    /* Configure PDMA channel trnasfer size, priority, source and destination address increment. */

+    PDMA->CHANNEL[channel_id].CRTL |= channel_cfg;

+

+    /* Posted write adjust. */

+    PDMA->CHANNEL[channel_id].CRTL |= ((uint32_t)write_adjust << CHANNEL_N_POSTED_WRITE_ADJUST_SHIFT);

+}

+

+/***************************************************************************//**

+ * See mss_pdma.h for description of this function.

+ */

+#define PAUSE_MASK  (uint32_t)0x00000010

+

+#define BUFFER_B_SELECT_MASK    (uint32_t)0x00000004

+

+#define CLEAR_PORT_A_DONE_MASK      (uint32_t)0x00000080

+#define CLEAR_PORT_B_DONE_MASK      (uint32_t)0x00000100

+

+#define PORT_A_COMPLETE_MASK        (uint32_t)0x00000001

+#define PORT_B_COMPLETE_MASK        (uint32_t)0x00000002

+

+void PDMA_start

+(

+    pdma_channel_id_t channel_id,

+    uint32_t src_addr,

+    uint32_t dest_addr,

+    uint16_t transfer_count

+)

+{

+    /* Pause transfer. */

+    PDMA->CHANNEL[channel_id].CRTL |= PAUSE_MASK;

+    

+    /* Clear complete transfers. */

+    if ( PDMA->CHANNEL[channel_id].STATUS & PORT_A_COMPLETE_MASK )

+    {

+        PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_A_DONE_MASK;

+        g_pdma_started_a[channel_id] = CHANNEL_STOPPED;

+    }

+    if ( PDMA->CHANNEL[channel_id].STATUS & PORT_B_COMPLETE_MASK )

+    {

+        PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_B_DONE_MASK;

+        g_pdma_started_b[channel_id] = CHANNEL_STOPPED;

+    }

+    

+    /* Load source, destination and transfer count. */

+    if ( PDMA->CHANNEL[channel_id].STATUS & BUFFER_B_SELECT_MASK )

+    {

+        g_pdma_next_channel[channel_id] = NEXT_CHANNEL_A;

+        g_pdma_started_b[channel_id] = CHANNEL_STARTED;

+        

+        PDMA->CHANNEL[channel_id].BUFFER_B_SRC_ADDR = src_addr;

+        PDMA->CHANNEL[channel_id].BUFFER_B_DEST_ADDR = dest_addr;

+        PDMA->CHANNEL[channel_id].BUFFER_B_TRANSFER_COUNT = transfer_count;

+    }

+    else

+    {

+        g_pdma_next_channel[channel_id] = NEXT_CHANNEL_B;

+        g_pdma_started_a[channel_id] = CHANNEL_STARTED;

+        

+        PDMA->CHANNEL[channel_id].BUFFER_A_SRC_ADDR = src_addr;

+        PDMA->CHANNEL[channel_id].BUFFER_A_DEST_ADDR = dest_addr;

+        PDMA->CHANNEL[channel_id].BUFFER_A_TRANSFER_COUNT = transfer_count;

+    }

+    

+    /* Start transfer */

+    PDMA->CHANNEL[channel_id].CRTL &= ~PAUSE_MASK;

+}

+

+/***************************************************************************//**

+ * See mss_pdma.h for description of this function.

+ */

+void PDMA_load_next_buffer

+(

+    pdma_channel_id_t channel_id,

+    uint32_t src_addr,

+    uint32_t dest_addr,

+    uint16_t transfer_count

+)

+{

+    if ( NEXT_CHANNEL_A == g_pdma_next_channel[channel_id] )

+    {

+        /* Wait for channel A current transfer completion. */

+        if ( CHANNEL_STARTED == g_pdma_started_a[channel_id] )

+        {

+            uint32_t completed;

+            uint32_t channel_mask;

+            channel_mask = (uint32_t)1 << ((uint32_t)channel_id * 2U);

+            do {

+                completed = PDMA->BUFFER_STATUS & channel_mask;

+            } while( !completed );

+            PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_A_DONE_MASK;

+        }

+        /* Load source, destination and transfer count. */

+        PDMA->CHANNEL[channel_id].BUFFER_A_SRC_ADDR = src_addr;

+        PDMA->CHANNEL[channel_id].BUFFER_A_DEST_ADDR = dest_addr;

+        PDMA->CHANNEL[channel_id].BUFFER_A_TRANSFER_COUNT = transfer_count;

+        

+        /* Update channel state information. */

+        g_pdma_next_channel[channel_id] = NEXT_CHANNEL_B;

+        g_pdma_started_a[channel_id] = CHANNEL_STARTED;

+    }

+    else

+    {

+        /* Wait for channel B current transfer completion. */

+        if ( CHANNEL_STARTED == g_pdma_started_b[channel_id] )

+        {

+            uint32_t completed;

+            uint32_t channel_mask;

+            channel_mask = (uint32_t)1 << (((uint32_t)channel_id * 2U) + 1U);

+            do {

+                completed = PDMA->BUFFER_STATUS & channel_mask;

+            } while( !completed );

+            PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_B_DONE_MASK;

+        }            

+        /* Load source, destination and transfer count. */

+        PDMA->CHANNEL[channel_id].BUFFER_B_SRC_ADDR = src_addr;

+        PDMA->CHANNEL[channel_id].BUFFER_B_DEST_ADDR = dest_addr;

+        PDMA->CHANNEL[channel_id].BUFFER_B_TRANSFER_COUNT = transfer_count;

+        

+        /* Update channel state information. */

+        g_pdma_next_channel[channel_id] = NEXT_CHANNEL_A;

+        g_pdma_started_b[channel_id] = CHANNEL_STARTED;

+    }

+}

+

+/***************************************************************************//**

+ * See mss_pdma.h for description of this function.

+ */

+uint32_t PDMA_status

+(

+    pdma_channel_id_t  channel_id

+)

+{

+    uint32_t status;

+    

+    status = PDMA->CHANNEL[channel_id].STATUS & (PORT_A_COMPLETE_MASK | PORT_B_COMPLETE_MASK);

+    

+    return status;

+}

+

+/***************************************************************************//**

+ *

+ */

+#define CHANNEL_0_STATUS_BITS_MASK     (uint16_t)0x0003

+#define CHANNEL_1_STATUS_BITS_MASK     (uint16_t)0x000C

+#define CHANNEL_2_STATUS_BITS_MASK     (uint16_t)0x0030

+#define CHANNEL_3_STATUS_BITS_MASK     (uint16_t)0x00C0

+#define CHANNEL_4_STATUS_BITS_MASK     (uint16_t)0x0300

+#define CHANNEL_5_STATUS_BITS_MASK     (uint16_t)0x0C00

+#define CHANNEL_6_STATUS_BITS_MASK     (uint16_t)0x3000

+#define CHANNEL_7_STATUS_BITS_MASK     (uint16_t)0xC000

+

+static pdma_channel_id_t get_channel_id_from_status

+(

+    uint16_t status

+)

+{

+    pdma_channel_id_t channel_id = PDMA_CHANNEL_0;

+    

+    if ( status & CHANNEL_0_STATUS_BITS_MASK )

+    {

+        channel_id = PDMA_CHANNEL_0;

+    }

+    else if ( status & CHANNEL_1_STATUS_BITS_MASK )

+    {

+        channel_id = PDMA_CHANNEL_1;

+    }

+    else if ( status & CHANNEL_2_STATUS_BITS_MASK )

+    {

+        channel_id = PDMA_CHANNEL_2;

+    }

+    else if ( status & CHANNEL_3_STATUS_BITS_MASK )

+    {

+        channel_id = PDMA_CHANNEL_3;

+    }

+    else if ( status & CHANNEL_4_STATUS_BITS_MASK )

+    {

+        channel_id = PDMA_CHANNEL_4;

+    }

+    else if ( status & CHANNEL_5_STATUS_BITS_MASK )

+    {

+        channel_id = PDMA_CHANNEL_5;

+    }

+    else if ( status & CHANNEL_6_STATUS_BITS_MASK )

+    {

+        channel_id = PDMA_CHANNEL_6;

+    }

+    else if ( status & CHANNEL_7_STATUS_BITS_MASK )

+    {

+        channel_id = PDMA_CHANNEL_7;

+    }

+    else

+    {

+        ASSERT(0);

+    }

+    return channel_id;

+}

+

+/***************************************************************************//**

+ *

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void DMA_IRQHandler( void )

+#else

+void DMA_IRQHandler( void )

+#endif

+{

+    uint16_t status;

+    pdma_channel_id_t channel_id;

+    

+    status = (uint16_t)PDMA->BUFFER_STATUS;

+    

+    do {

+        channel_id = get_channel_id_from_status( status );

+        status &= (uint16_t)~g_pdma_status_mask[channel_id];

+        if ( 0 != g_pdma_isr_table[channel_id])

+        {

+            g_pdma_isr_table[channel_id]();

+        }

+    } while ( 0U != status );

+      

+    NVIC_ClearPendingIRQ( DMA_IRQn );

+}

+

+/***************************************************************************//**

+ * See mss_pdma.h for description of this function.

+ */

+void PDMA_set_irq_handler

+(

+    pdma_channel_id_t channel_id,

+    pdma_channel_isr_t handler

+)

+{

+    /* Save address of handler function in PDMA driver ISR lookup table. */

+    g_pdma_isr_table[channel_id] = handler;

+    

+    /* Enable PDMA channel's interrupt. */

+    PDMA->CHANNEL[channel_id].CRTL |= PDMA_IRQ_ENABLE_MASK;

+    

+    /* Enable PDMA interrupt in Cortex-M3 NVIC. */

+    NVIC_EnableIRQ( DMA_IRQn );

+}

+

+/***************************************************************************//**

+ * See mss_pdma.h for description of this function.

+ */

+void PDMA_enable_irq( pdma_channel_id_t channel_id )

+{

+    PDMA->CHANNEL[channel_id].CRTL |= PDMA_IRQ_ENABLE_MASK;

+    NVIC_EnableIRQ( DMA_IRQn );

+}

+

+/***************************************************************************//**

+ * See mss_pdma.h for description of this function.

+ */

+void PDMA_clear_irq

+(

+    pdma_channel_id_t channel_id

+)

+{

+    /* Clear interrupt in PDMA controller. */

+    PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_A_DONE_MASK;

+    PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_B_DONE_MASK;

+    

+    /* Clear interrupt in Cortex-M3 NVIC. */

+    NVIC_ClearPendingIRQ( DMA_IRQn );

+}

+

+#ifdef __cplusplus

+}

+#endif

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.h
new file mode 100644
index 0000000..6f79226
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.h
@@ -0,0 +1,703 @@
+/*******************************************************************************

+ * (c) Copyright 2008 Actel Corporation.  All rights reserved.

+ * 

+ * SmartFusion microcontroller subsystem Peripheral DMA bare metal software

+ * driver public API.

+ *

+ * SVN $Revision: 2110 $

+ * SVN $Date: 2010-02-05 15:24:19 +0000 (Fri, 05 Feb 2010) $

+ */

+/*=========================================================================*//**

+  @mainpage SmartFusion MSS GPIO Bare Metal Driver.

+

+  @section intro_sec Introduction

+  The SmartFusion Microcontroller Subsystem (MSS) includes an 8 channel

+  Peripheral DMA (PDMA) controller.

+  This software driver provides a set of functions for controlling the MSS PDMA

+  controller as part of a bare metal system where no operating system is available.

+  This driver can be adapted for use as part of an operating system but the

+  implementation of the adaptation layer between this driver and the operating

+  system's driver model is outside the scope of this driver.

+  

+  @section theory_op Theory of Operation

+  The MSS PDMA driver uses the SmartFusion "Cortex Microcontroler Software

+  Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access MSS hardware

+  registers. You must ensure that the SmartFusion CMSIS-PAL is either included

+  in the software toolchain used to build your project or is included in your

+  project. The most up-to-date SmartFusion CMSIS-PAL files can be obtained using

+  the Actel Firmware Catalog.

+  

+  The MSS PDMA driver functions are grouped into the following categories:

+    - Initialization

+    - Configuration

+    - DMA transfer control

+    - Interrupt control

+  

+  The MSS PDMA driver is initialized through a call to the PDMA_init() function.

+  The PDMA_init() function must be called before any other PDMA driver functions

+  can be called.

+  

+  Each PDMA channel is individually configured through a call to the PDMA_configure()

+  function. Configuration includes:

+    - channel priority

+    - transfer size

+    - source and/or destination address increment

+    - source or destination of the DMA transfer

+  PDMA channels can be divided into high and low priority channels. High priority

+  channels are given more opportunities to perform transfers than low priority

+  channels when there are continuous high priority channels requests. The ratio

+  of high priority to low priority PDMA transfers is configurable through the

+  PDMA_set_priority() function.

+  PDMA channels can be configured to perform byte (8 bits), half-word (16 bits)

+  or word (32 bits) transfers.

+  The source and destination address of a PDMA channel’s transfers can be

+  independently configured to increment by 0, 1, 2 or 4 bytes. For example, the

+  content of a byte buffer located in RAM can be transferred into a peripheral’s

+  transmit register by configuring the source address increment to one byte and

+  no increment of the destination address.

+  The source or destination of a PDMA channel’s transfers can be configured to

+  be one of the MSS peripherals. This allows the PDMA controller to use some

+  hardware flow control signaling with the peripheral to avoid overrunning the

+  peripheral’s data buffer when the peripheral is the destination of the DMA

+  transfer, or attempting to read data from the peripheral while it is not ready

+  when the peripheral is the source of the transfer.

+  A PDMA channel can also be configured to transfer data between two memory

+  mapped locations (memory to memory). No hardware flow control is used by the

+  PDMA controller for data transfer in this configuration.

+  

+  A DMA transfer can be initiated by a call to the PDMA_start() function after a

+  PDMA channel has been configured. Once started, further data can be pushed

+  through the PDMA channel by calling the PDMA_load_next_buffer() function. The

+  PDMA_load_next_buffer() function can be called every time a call to the

+  PDMA_status() function indicates that the PDMA channel used for the transfer

+  has a free buffer or it can be called as a result of a PDMA interrupt.

+  

+  A DMA transfer can be paused and resumed through calls to functions PDMA_pause()

+  and PDMA_resume().

+  

+  Your application can manage DMA transfers using interrupts through the use of

+  the following functions:

+    - PDMA_set_irq_handler()

+    - PDMA_enable_irq()

+    - PDMA_clear_irq()

+    - PDMA_disable_irq()

+  The PDMA_set_irq_handler() function is used to register PDMA channel interrupt

+  handler functions with the driver. You must create and register an interrupt

+  handler function for each interrupt driven PDMA channel used by the application.

+  Use the PDMA_enable_irq() function to enable interrupts for the PDMA channels. 

+  Every time a PDMA channel completes the transfer of a buffer it causes a PDMA

+  interrupt to occur and the PDMA driver will call the interrupt handler

+  registered by the application for that PDMA channel.

+  

+ *//*=========================================================================*/

+#ifndef __MSS_PERIPHERAL_DMA_H_

+#define __MSS_PERIPHERAL_DMA_H_

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+#include "../../CMSIS/a2fxxxm3.h"

+

+/***************************************************************************//**

+  The pdma_channel_id_t enumeration is used to identify peripheral DMA channels.

+  It is used as function parameter to specify the PDMA channel used.

+ */

+typedef enum __pdma_channel_id

+{

+    PDMA_CHANNEL_0 = 0,

+    PDMA_CHANNEL_1,

+    PDMA_CHANNEL_2,

+    PDMA_CHANNEL_3,

+    PDMA_CHANNEL_4,

+    PDMA_CHANNEL_5,

+    PDMA_CHANNEL_6,

+    PDMA_CHANNEL_7

+} pdma_channel_id_t;

+

+/***************************************************************************//**

+  The pdma_src_dest_t enumeration is used to specify the source or destination

+  of transfers on a PDMA channel. It specifies which hardware peripheral will be

+  the source or destination of DMA transfers. This allows the PDMA controller

+  to use hardware flow control signals to avoid overrunning a

+  destination peripheral with data it is not ready to receive, or attempting to

+  transfer data from a peripheral while it has no data ready to transfer.

+  The pdma_src_dest_t enumeration can also be used to specify that a PDMA channel

+  is configured to transfer data between two memory mapped locations

+  (memory to memory). No hardware data flow control is used by the PDMA

+  controller in this configuration.

+  This enumeration is used as parameter to function PDMA_configure().

+ */

+typedef enum __pdma_src_dest

+{

+    PDMA_FROM_UART_0 = 0,

+    PDMA_TO_UART_0,

+    PDMA_FROM_UART_1,

+    PDMA_TO_UART_1,

+    PDMA_FROM_SPI_0,

+    PDMA_TO_SPI_0,

+    PDMA_FROM_SPI_1,

+    PDMA_TO_SPI_1,

+    PDMA_FROM_FPGA_1,

+    PDMA_TO_FPGA_1,

+    PDMA_FROM_FPGA_0,

+    PDMA_TO_FPGA_0,

+    PDMA_TO_ACE,

+    PDMA_FROM_ACE,

+    PDMA_MEM_TO_MEM

+} pdma_src_dest_t;

+

+/***************************************************************************//**

+  The pdma_priority_ratio_t enumeration is used to configure the ratio of high

+  priority to low priority PDMA channels.  This ratio specifies how many DMA

+  transfer opportunities will be given to high priority channels before a DMA

+  transfer opportunity is given to a low priority channel when there are

+  continuous requests from high priority channels. This enumeration is used as

+  parameter to function PDMA_set_priority_ratio().

+ */

+typedef enum __pdma_priority_ratio_t

+{

+    PDMA_ROUND_ROBIN = 0,

+    PDMA_RATIO_HIGH_LOW_1_TO_1 = 1,

+    PDMA_RATIO_HIGH_LOW_3_TO_1 = 3,

+    PDMA_RATIO_HIGH_LOW_7_TO_1 = 7,

+    PDMA_RATIO_HIGH_LOW_15_TO_1 = 15,

+    PDMA_RATIO_HIGH_LOW_31_TO_1 = 31,

+    PDMA_RATIO_HIGH_LOW_63_TO_1 = 63,

+    PDMA_RATIO_HIGH_LOW_127_TO_1 = 127,

+    PDMA_RATIO_HIGH_LOW_255_TO_1 = 255

+} pdma_priority_ratio_t;

+

+

+/***************************************************************************//**

+  The pdma_channel_isr_t type is a pointer to a PDMA channel interrupt handler

+  function. It specifies the function prototype of functions that can be

+  registered as PDMA channel interrupt handlers. It is used as parameter to

+  function PDMA_set_irq_handler().

+ */

+typedef void (*pdma_channel_isr_t)( void );

+/***************************************************************************//**

+  These constants are used to build the channel_cfg parameter of the

+  PDMA_configure() function. They specify whether a channel is a high or low

+  priority channel.

+ */

+#define PDMA_LOW_PRIORITY    0x0000

+#define PDMA_HIGH_PRIORITY   0x0200

+

+/***************************************************************************//**

+  These constants are used to build the channel_cfg parameter of the

+  PDMA_configure() function. They specify the data width of the transfers

+  performed by a PDMA channel.

+ */

+#define PDMA_BYTE_TRANSFER       0x0000     /* Byte transfers (8 bits) */

+#define PDMA_HALFWORD_TRANSFER   0x0004     /* Half-word transfers (16 bits) */

+#define PDMA_WORD_TRANSFER       0x0008     /* Word transfers (32 bits) */

+

+/***************************************************************************//**

+  These constants are used to build the channel_cfg parameter of the

+  PDMA_configure() function. They specify the PDMA channel’s source and

+  destination address increment.

+ */

+#define PDMA_NO_INC  0

+#define PDMA_INC_SRC_ONE_BYTE    0x0400

+#define PDMA_INC_SRC_TWO_BYTES   0x0800

+#define PDMA_INC_SRC_FOUR_BYTES  0x0C00

+#define PDMA_INC_DEST_ONE_BYTE   0x1000

+#define PDMA_INC_DEST_TWO_BYTES  0x2000

+#define PDMA_INC_DEST_FOUR_BYTES 0x3000

+

+/***************************************************************************//**

+ * Mask for various control register bits.

+ */

+#define PDMA_IRQ_ENABLE_MASK    (uint32_t)0x00000040

+#define PDMA_PAUSE_MASK         (uint32_t)0x00000010

+

+/***************************************************************************//**

+  These constants are used to specify the src_addr parameter to the PDMA_start()

+  and PDMA_load_next_buffer() functions. They specify the receive register

+  address of peripherals that can be the source of a DMA transfer. 

+  When a PDMA channel is configured for DMA transfers from a peripheral to memory,

+  the constant specifying that peripheral’s receive register address must be used

+  as the src_addr parameter.

+ */

+#define PDMA_SPI0_RX_REGISTER       0x40001010uL

+#define PDMA_SPI1_RX_REGISTER       0x40011010uL

+#define PDMA_UART0_RX_REGISTER      0x40000000uL

+#define PDMA_UART1_RX_REGISTER      0x40010000uL

+#define PDMA_ACE_PPE_DATAOUT        0x40021308uL

+

+/***************************************************************************//**

+  These constants are used to specify the dest_addr parameter to the PDMA_start()

+  and PDMA_load_next_buffer() functions. They specify the transmit register

+  address of peripherals that can be the destination of a DMA transfer. 

+  When a PDMA channel is configured for DMA transfers from memory to a peripheral,

+  the constant specifying that peripheral’s transmit register address must be used

+  as the dest_addr parameter.

+ */

+#define PDMA_SPI0_TX_REGISTER       0x40001014uL

+#define PDMA_SPI1_TX_REGISTER       0x40011014uL

+#define PDMA_UART0_TX_REGISTER      0x40000000uL

+#define PDMA_UART1_TX_REGISTER      0x40010000uL

+#define PDMA_ACE_SSE_DATAIN         0x40020700uL

+

+/***************************************************************************//**

+  The PDMA_DEFAULT_WRITE_ADJ constant provides a suitable default value for the

+  PDMA_configure() function write_adjust parameter.

+ */

+#define PDMA_DEFAULT_WRITE_ADJ      10u

+

+/***************************************************************************//**

+  The PDMA_init() function initializes the peripheral DMA hardware and driver

+  internal data. It resets the PDMA and it also clears any pending PDMA

+  interrupts in the Cortex-M3 interrupt controller. When the function exits, it

+  takes the PDMA block out of reset.

+ */

+void PDMA_init( void );

+

+/***************************************************************************//**

+  The PDMA_configure() function configures a PDMA channel.

+  It specifies:

+   - The peripheral which will be the source or destination of the DMA transfer.

+   - Whether the DMA channel will be a high or low priority channel

+   - The source and destination address increment that will take place after

+     each transfer.

+ 

+  @param channel_id

+    The channel_id parameter identifies the PDMA channel used by the function.

+ 

+  @param src_dest

+    The src_dest parameter specifies the source or destination of the DMA

+    transfers that will be performed. It can be one of the following:

+        - PDMA_FROM_UART_0

+        - PDMA_TO_UART_0

+        - PDMA_FROM_UART_1

+        - PDMA_TO_UART_1

+        - PDMA_FROM_SPI_0

+        - PDMA_TO_SPI_0

+        - PDMA_FROM_SPI_1

+        - PDMA_TO_SPI_1

+        - PDMA_FROM_FPGA_1

+        - PDMA_TO_FPGA_1

+        - PDMA_FROM_FPGA_0

+        - PDMA_TO_FPGA_0

+        - PDMA_TO_ACE

+        - PDMA_FROM_ACE

+        - PDMA_MEM_TO_MEM

+ 

+  @param channel_cfg

+    The channel_cfg parameter specifies the configuration of the PDMA channel.

+    The configuration includes:

+        - channel priority

+        - transfer size

+        - source and/or destination address increment

+    The channel_cfg parameter value is a logical OR of:

+        One of the following to specify the channel priority:

+           - PDMA_LOW_PRIORITY

+           - PDMA_HIGH_PRIORITY

+        One of the following to specify the transfer size:

+           - PDMA_BYTE_TRANSFER

+           - PDMA_HALFWORD_TRANSFER

+           - PDMA_WORD_TRANSFER

+        One or two of the following to specify the source and/or destination address

+        increment:

+           - PDMA_NO_INC

+           - PDMA_INC_SRC_ONE_BYTE

+           - PDMA_INC_SRC_TWO_BYTES

+           - PDMA_INC_SRC_FOUR_BYTES

+           - PDMA_INC_DEST_ONE_BYTE

+           - PDMA_INC_DEST_TWO_BYTES

+           - PDMA_INC_DEST_FOUR_BYTES

+  

+  @param write_adjust

+    The write_adjust parameter specifies the number of Cortex-M3 clock cycles

+    the PDMA controller will wait before attempting another transfer cycle. This

+    delay is necessary when peripherals are used as destination of a DMA transfer

+    to ensure the DMA controller interprets the state of the peripheral’s ready

+    signal only after data has actually been written to the peripheral. This delay

+    accounts for posted writes (dump and run) for write accesses to peripherals. 

+    The effect of posted writes is that if the PDMA performs a write operation to

+    a peripheral, the data is not actually written into the peripheral until

+    sometime after the PDMA controller thinks it is written.

+    A suitable value for write_adjust depends on the target of the DMA transfer.

+    Guidelines for choosing this value are as follows:

+        • The PDMA_DEFAULT_WRITE_ADJ constant provides a suitable default value

+          for the write_adjust parameter when the PDMA channel is configured for

+          transfers with MSS peripherals.

+        • The PDMA_DEFAULT_WRITE_ADJ constant can also be used for DMA transfers

+          with FPGA fabric implemented peripherals making use of the DMAREADY0 or

+          DMAREADY1fabric interface signal to indicate that the peripheral is

+          ready for another DMA transfer.

+        • The write_adjust parameter can be set to zero to achieve maximum transfer

+          speed for genuine memory to memory transfers. 

+        • The internal latency of FPGA implemented peripherals will decide the

+          write_adjust value for fabric peripherals that do not use the DMAREADY0

+          or DMAREADY1 fabric interface signals. You need to check the fabric

+          peripheral documentation for the value to use.

+    

+  Example:

+  @code

+   PDMA_configure

+   (

+       PDMA_CHANNEL_0,

+       PDMA_TO_SPI_1,

+       PDMA_LOW_PRIORITY | PDMA_BYTE_TRANSFER | PDMA_INC_SRC_ONE_BYTE,

+       PDMA_DEFAULT_WRITE_ADJ

+   );

+  @endcode

+ */

+void PDMA_configure

+(

+    pdma_channel_id_t channel_id,

+    pdma_src_dest_t src_dest,

+    uint32_t channel_cfg,

+    uint8_t write_adjust

+);

+

+

+/***************************************************************************//**

+  The PDMA_set_priority_ratio() function sets the ratio of high priority to low

+  priority DMA access opportunities. This ratio is used by the PDMA controller

+  arbiter to decide which PDMA channel will be given the opportunity to perform

+  a transfer when multiple PDMA channels are requesting to transfer data at the

+  same time. The priority ratio specifies how many DMA transfer opportunities

+  will be given to high priority channels before a DMA transfer opportunity is

+  given to a low priority channel when there are continuous requests from high

+  priority channels.

+ 

+  @param priority_ratio

+    The priority_ratio parameter specifies the ratio of DMA access opportunities

+    given to high priority channels versus low priority channels.

+    Allowed values for this parameter are:

+       - PDMA_ROUND_ROBIN

+       - PDMA_RATIO_HIGH_LOW_1_TO_1

+       - PDMA_RATIO_HIGH_LOW_3_TO_1

+       - PDMA_RATIO_HIGH_LOW_7_TO_1

+       - PDMA_RATIO_HIGH_LOW_15_TO_1

+       - PDMA_RATIO_HIGH_LOW_31_TO_1

+       - PDMA_RATIO_HIGH_LOW_63_TO_1

+       - PDMA_RATIO_HIGH_LOW_127_TO_1

+       - PDMA_RATIO_HIGH_LOW_255_TO_1

+ 

+  Example:

+  @code

+   PDMA_set_priority_ratio( PDMA_ROUND_ROBIN );

+  @endcode

+ */

+static __INLINE void PDMA_set_priority_ratio

+(

+    pdma_priority_ratio_t priority_ratio

+)

+{

+    PDMA->RATIO_HIGH_LOW = (uint32_t)priority_ratio;

+}

+

+/***************************************************************************//**

+  The PDMA_start() function  initiates a DMA transfer. It specifies the source

+  and destination address of the transfer as well as the number of transfers

+  that must take place. The source and destination addresses can be the address

+  of peripheral registers.

+ 

+  @param channel_id

+    The channel_id parameter identifies the PDMA channel used by the function.

+ 

+  @param src_addr

+    The src_addr parameter specifies the address location of the data to be

+    transferred. You must ensure that this source address is consistent with the

+    DMA source configured for the selected channel using the PDMA_configure()

+    function.

+    For DMA transfers from MSS peripheral to memory, the following src_addr

+    parameter values are allowed:

+        • PDMA_SPI0_RX_REGISTER

+        • PDMA_SPI1_RX_REGISTER

+        • PDMA_UART0_RX_REGISTER

+        • PDMA_UART1_RX_REGISTER

+        • PDMA_ACE_PPE_DATAOUT

+    For DMA transfers from FPGA fabric peripheral to memory, the following

+    src_addr parameter values are allowed:

+        • An address in the FPGA fabric address space (0x40050000-0x400FFFFF)

+    For DMA transfers from memory to MSS peripheral, or from memory to FPGA

+    fabric peripheral, or from memory to memory, the following src_addr

+    parameter values are allowed:

+        • Any memory mapped address.

+

+  @param dest_addr

+    The dest_addr parameter specifies the destination address of the PDMA

+    transfer. You must ensure that this matches with the DMA destination

+    configured for the selected channel.

+    For DMA transfers from memory to MSS peripheral, the following dest_addr parameter values are allowed:

+        • PDMA_SPI0_TX_REGISTER

+        • PDMA_SPI1_TX_REGISTER

+        • PDMA_UART0_TX_REGISTER

+        • PDMA_UART1_TX_REGISTER

+        • PDMA_ACE_SSE_DATAIN

+    For DMA transfers from memory to FPGA fabric peripheral, the following

+    dest_addr parameter values are allowed:

+        • An address in the FPGA fabric address space (0x40050000-0x400FFFFF)

+    For DMA transfers from MSS peripheral to memory, or from FPGA fabric

+    peripheral to memory, or from memory to memory, the following dest_addr

+    parameter values are allowed:

+        • Any memory mapped address.

+

+  @param transfer_count

+    The transfer_count parameter specifies the number of transfers to be

+    performed. It is the number of bytes to transfer if the PDMA channel is

+    configured for byte transfer, the number of half-words to transfer if the

+    PDMA channel is configured for half-word transfer, or the number of words

+    to transfer if the PDMA channel is configured for word transfer.

+ 

+  Example:

+  @code

+    PDMA_start

+      (

+          PDMA_CHANNEL_3,

+          PDMA_SPI1_RX_REGISTER,

+          (uint32_t)slave_rx_buffer,

+          sizeof(slave_rx_buffer)

+      ); 

+  @endcode

+ */

+void PDMA_start

+(

+    pdma_channel_id_t channel_id,

+    uint32_t src_addr,

+    uint32_t dest_addr,

+    uint16_t transfer_count

+);

+

+/***************************************************************************//**

+  The PDMA_load_next_buffer() function sets the next buffer to be transferred.

+  This function is called after a transfer has been initiated using the

+  PDMA_start() function. Its purpose is to keep feeding a PDMA channel with data

+  buffers.

+ 

+  @param channel_id

+    The channel_id parameter identifies the PDMA channel used by the function.

+ 

+  @param src_addr

+    The src_addr parameter specifies the address location of the data to be

+    transferred. You must ensure that this source address is consistent with the

+    DMA source configured for the selected channel using the PDMA_configure()

+    function.

+    For DMA transfers from MSS peripheral to memory, the following src_addr parameter values are allowed:

+        • PDMA_SPI0_RX_REGISTER

+        • PDMA_SPI1_RX_REGISTER

+        • PDMA_UART0_RX_REGISTER

+        • PDMA_UART1_RX_REGISTER

+        • PDMA_ACE_PPE_DATAOUT

+    For DMA transfers from FPGA fabric peripheral to memory, the following src_addr parameter values are allowed:

+        • An address in the FPGA fabric address space (0x40050000-0x400FFFFF)

+    For DMA transfers from memory to MSS peripheral, or from memory to FPGA fabric peripheral, or from memory to memory, the following src_addr parameter values are allowed:

+        • Any memory mapped address.

+

+  @param dest_addr

+    The dest_addr parameter specifies the destination address of the PDMA

+    transfer. You must ensure that this matches with the DMA destination

+    configured for the selected channel.

+    For DMA transfers from memory to MSS peripheral, the following dest_addr parameter values are allowed:

+        • PDMA_SPI0_TX_REGISTER

+        • PDMA_SPI1_TX_REGISTER

+        • PDMA_UART0_TX_REGISTER

+        • PDMA_UART1_TX_REGISTER

+        • PDMA_ACE_SSE_DATAIN

+    For DMA transfers from memory to FPGA fabric peripheral, the following dest_addr parameter values are allowed:

+        • An address in the FPGA fabric address space (0x40050000-0x400FFFFF)

+    For DMA transfers from MSS peripheral to memory, or from FPGA fabric peripheral to memory, or from memory to memory, the following dest_addr parameter values are allowed:

+        • Any memory mapped address.

+ 

+  @param transfer_count

+    The transfer_count parameter specifies the number of transfers to be

+    performed. It is the number of bytes to transfer if the PDMA channel is

+    configured for byte transfer, the number of half-words to transfer if the

+    PDMA channel is configured for half-word transfer or the number of words to

+    transfer if the PDMA channel is configured for word transfer.

+    

+  Example:

+  @code

+  void write_cmd_data

+  (

+      mss_spi_instance_t * this_spi,

+      const uint8_t * cmd_buffer,

+      uint16_t cmd_byte_size,

+      uint8_t * data_buffer,

+      uint16_t data_byte_size

+  )

+  {

+      uint32_t transfer_size;

+      

+      transfer_size = cmd_byte_size + data_byte_size;

+  

+      MSS_SPI_disable( this_spi );

+      MSS_SPI_set_transfer_byte_count( this_spi, transfer_size );

+  

+      PDMA_start

+          (

+              PDMA_CHANNEL_0,

+              (uint32_t)cmd_buffer,

+              PDMA_SPI1_TX_REGISTER,

+              cmd_byte_size

+          );

+      

+      PDMA_load_next_buffer

+          (

+              PDMA_CHANNEL_0,

+              (uint32_t)data_buffer,

+              PDMA_SPI1_TX_REGISTER,

+              data_byte_size

+          );

+      

+      MSS_SPI_enable( this_spi );

+      

+      while ( !MSS_SPI_tx_done(this_spi) )

+      {

+          ;

+      }

+  }

+  @endcode

+ */

+void PDMA_load_next_buffer

+(

+    pdma_channel_id_t channel_id,

+    uint32_t src_addr,

+    uint32_t dest_addr,

+    uint16_t transfer_count

+);

+

+/***************************************************************************//**

+  The PDMA_status() function returns the status of a DMA channel.

+  The returned value indicates if transfers have been completed using buffer A

+  or buffer B of the PDMA hardware block.

+ 

+  @param channel_id

+    The channel_id parameter identifies the PDMA channel used by the function.

+ 

+  @return

+    bit 0 of the return value indicates if buffer A has been trasnfered. It is

+    set to 1 if the transfer has completed.

+    bit 1 of the return value indicates if buffer B has been transfered. It is

+    set to 1 if the transfer has completed.

+ */

+uint32_t PDMA_status

+(

+    pdma_channel_id_t  channel_id

+);

+

+/***************************************************************************//**

+  The PDMA_pause() function temporarily pauses a PDMA transfer taking place on

+  the specified PDMA channel. The transfer can later be resumed by using the

+  PDMA_resume() function.

+ 

+  @param channel_id

+    The channel_id parameter identifies the PDMA channel used by the function.

+ */

+static __INLINE void PDMA_pause( pdma_channel_id_t channel_id )

+{

+    PDMA->CHANNEL[channel_id].CRTL |= PDMA_PAUSE_MASK;

+}

+

+/***************************************************************************//**

+  The PDMA_resume() function resumes a transfer previously paused using the

+  PDMA_pause() function.

+ 

+  @param channel_id    The channel_id parameter identifies the PDMA channel

+                       used by the function.

+ */

+static __INLINE void PDMA_resume( pdma_channel_id_t channel_id )

+{

+    PDMA->CHANNEL[channel_id].CRTL &= ~PDMA_PAUSE_MASK;

+}

+

+/***************************************************************************//**

+  The PDMA_enable_irq() enables the PDMA hardware to generate an interrupt when

+  a DMA transfer completes on the specified PDMA channel. This function also

+  enables the PDMA interrupt in the Cortex-M3 interrupt controller.

+ 

+  @param channel_id

+    The channel_id parameter identifies the PDMA channel used by the function.

+ */

+void PDMA_enable_irq( pdma_channel_id_t channel_id );

+

+/***************************************************************************//**

+  The PDMA_disable_irq() disables interrupts for a specific PDMA channel.

+ 

+  @param channel_id

+    The channel_id parameter identifies the PDMA channel used by the function.

+ */

+static __INLINE void PDMA_disable_irq( pdma_channel_id_t channel_id )

+{

+    PDMA->CHANNEL[channel_id].CRTL &= ~PDMA_IRQ_ENABLE_MASK;

+}

+

+/***************************************************************************//**

+  The PDMA_set_irq_handler() function registers a handler function for

+  interrupts generated on the completion of a transfer on a specific PDMA

+  channel. This function also enables the PDMA interrupt both in the PDMA

+  controller and in the Cortex-M3 interrupt controller.

+ 

+  @param channel_id

+    The channel_id parameter identifies the PDMA channel used by the function.

+    

+  @param handler

+    The handler parameter is a pointer to the function that will be called when

+    a transfer completes on the PDMA channel identified by channel_id and the

+    interrupt is enabled for that channel.

+    

+  Example:

+  @code

+  void slave_dma_irq_handler( void )

+  {

+      if ( g_spi1_rx_buffer[2] == 0x99 )

+      {

+          PDMA_load_next_buffer

+          (

+              PDMA_CHANNEL_0,

+              (uint32_t)g_spi1_tx_buffer_b,

+              PDMA_SPI1_TX_REGISTER,

+              sizeof(g_spi1_tx_buffer_b)

+          );      

+      }

+      PDMA_disable_irq( PDMA_CHANNEL_3 );

+  }

+  

+  void setup_dma( void )

+  {

+      PDMA_init();

+      PDMA_configure

+      (

+           PDMA_CHANNEL_0, 

+           PDMA_TO_SPI_1, 

+           PDMA_LOW_PRIORITY | PDMA_BYTE_TRANSFER | PDMA_INC_SRC_ONE_BYTE

+      );

+      PDMA_configure

+      ( 

+           PDMA_CHANNEL_3,

+           PDMA_FROM_SPI_1,

+           PDMA_HIGH_PRIORITY | PDMA_BYTE_TRANSFER | PDMA_INC_DEST_ONE_BYTE

+      );

+      PDMA_set_irq_handler( PDMA_CHANNEL_3, slave_dma_irq_handler );

+      PDMA_start( PDMA_CHANNEL_3, PDMA_SPI1_RX_REGISTER, (uint32_t)g_spi1_rx_buffer, 3 ); 

+  }

+  @endcode

+ */

+void PDMA_set_irq_handler

+(

+    pdma_channel_id_t channel_id,

+    pdma_channel_isr_t handler

+);

+

+/***************************************************************************//**

+  The PDMA_clear_irq() function clears interrupts for a specific PDMA channel.

+  This function also clears the PDMA interrupt in the Cortex-M3 NVIC.

+ 

+  @param channel_id

+    The channel_id parameter identifies the PDMA channel used by the function.

+ */

+void PDMA_clear_irq

+(

+    pdma_channel_id_t channel_id

+);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif  /* __MSS_PERIPHERAL_DMA_H_ */

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.c
new file mode 100644
index 0000000..e599230
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.c
@@ -0,0 +1,610 @@
+/*******************************************************************************

+ * (c) Copyright 2008 Actel Corporation.  All rights reserved.

+ * 

+ * SmartFusion microcontroller subsystem SPI bare metal software driver

+ * implementation.

+ *

+ * SVN $Revision: 2176 $

+ * SVN $Date: 2010-02-15 21:04:22 +0000 (Mon, 15 Feb 2010) $

+ */

+#include "mss_spi.h"

+#include "../../CMSIS/mss_assert.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/***************************************************************************//**

+  MSS SPI can operate as master or slave.

+ */

+#define MSS_SPI_MODE_SLAVE      (uint32_t)0

+#define MSS_SPI_MODE_MASTER     (uint32_t)1

+

+/***************************************************************************//**

+ * Mask of transfer protocol and SPO, SPH bits within control register.

+ */

+#define PROTOCOL_MODE_MASK  (uint32_t)0x030000C0

+

+/***************************************************************************//**

+ * Mask of theframe count bits within the SPI control register.

+ */

+#define TXRXDFCOUNT_MASK    (uint32_t)0x00FFFF00

+#define TXRXDFCOUNT_SHIFT   (uint32_t)8

+

+/***************************************************************************//**

+ * SPI hardware FIFO depth.

+ */

+#define RX_FIFO_SIZE    4u

+

+/***************************************************************************//**

+  Marker used to detect that the configuration has not been selected for a

+  specific slave when operating as a master.

+ */

+#define NOT_CONFIGURED  0xFFFFFFFF

+

+/***************************************************************************//**

+ * SPI instance data structures for SPI0 and SPI1. A pointer to these data

+ * structures must be used as first parameter to any of the SPI driver functions

+ * to identify the SPI hardware block that will perform the requested operation.

+ */

+mss_spi_instance_t g_mss_spi0;

+mss_spi_instance_t g_mss_spi1;

+

+/***************************************************************************//**

+  SPI0 interrupt service routine

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void SPI0_IRQHandler( void );

+#else

+void SPI0_IRQHandler( void );

+#endif

+

+/***************************************************************************//**

+  SPI1 interrupt service routine

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void SPI1_IRQHandler( void );

+#else

+void SPI1_IRQHandler( void );

+#endif

+

+/***************************************************************************//**

+ * MSS_SPI_init()

+ * See "mss_spi.h" for details of how to use this function.

+ */

+void MSS_SPI_init

+(

+	mss_spi_instance_t * this_spi

+)

+{

+    uint16_t i;

+    

+    ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) );

+    

+    if (this_spi == &g_mss_spi0)

+    {

+        this_spi->hw_reg = SPI0;

+        this_spi->hw_reg_bit = SPI0_BITBAND;

+        this_spi->irqn = SPI0_IRQn;

+

+        /* reset SPI0 */

+        SYSREG->SOFT_RST_CR |= SYSREG_SPI0_SOFTRESET_MASK;

+        /* Clear any previously pended SPI0 interrupt */

+        NVIC_ClearPendingIRQ( SPI0_IRQn );

+        /* Take SPI0 out of reset. */

+        SYSREG->SOFT_RST_CR &= ~SYSREG_SPI0_SOFTRESET_MASK;

+    }

+    else

+    {

+        this_spi->hw_reg = SPI1;

+        this_spi->hw_reg_bit = SPI1_BITBAND;

+        this_spi->irqn = SPI1_IRQn;

+        

+        /* reset SPI1 */

+        SYSREG->SOFT_RST_CR |= SYSREG_SPI1_SOFTRESET_MASK;

+        /* Clear any previously pended SPI1 interrupt */

+        NVIC_ClearPendingIRQ( SPI1_IRQn );

+        /* Take SPI1 out of reset. */

+        SYSREG->SOFT_RST_CR &= ~SYSREG_SPI1_SOFTRESET_MASK;

+    }

+    

+    this_spi->frame_rx_handler = 0U;

+    this_spi->slave_tx_frame = 0U;

+    

+    this_spi->block_rx_handler = 0U;

+    

+    this_spi->slave_tx_buffer = 0U;

+    this_spi->slave_tx_size = 0U;

+    this_spi->slave_tx_idx = 0U;

+    

+    for ( i = 0u; i < (uint16_t)MSS_SPI_MAX_NB_OF_SLAVES; ++i )

+    {

+        this_spi->slaves_cfg[i].ctrl_reg = NOT_CONFIGURED;

+    }

+}

+

+/***************************************************************************//**

+ * MSS_SPI_configure_slave_mode()

+ * See "mss_spi.h" for details of how to use this function.

+ */

+void MSS_SPI_configure_slave_mode

+(

+	mss_spi_instance_t * this_spi,

+    mss_spi_protocol_mode_t protocol_mode,

+    mss_spi_pclk_div_t clk_rate,

+    uint8_t frame_bit_length

+)

+{

+    ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) );

+    ASSERT( frame_bit_length <= 32 );

+    

+	/* Set the mode. */

+    this_spi->hw_reg_bit->CTRL_MASTER = MSS_SPI_MODE_SLAVE;

+

+    /* Set the clock rate. */

+    this_spi->hw_reg_bit->CTRL_ENABLE = 0U;

+    this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~PROTOCOL_MODE_MASK) | (uint32_t)protocol_mode;

+    this_spi->hw_reg->CLK_GEN = (uint32_t)clk_rate;

+    

+    /* Set default frame size to byte size and number of data frames to 1. */

+    this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~TXRXDFCOUNT_MASK) | ((uint32_t)1 << TXRXDFCOUNT_SHIFT);

+    this_spi->hw_reg->TXRXDF_SIZE = frame_bit_length;

+    this_spi->hw_reg_bit->CTRL_ENABLE = 1U;

+}

+

+/***************************************************************************//**

+ * MSS_SPI_configure_master_mode()

+ * See "mss_spi.h" for details of how to use this function.

+ */

+void MSS_SPI_configure_master_mode

+(

+	mss_spi_instance_t *    this_spi,

+	mss_spi_slave_t         slave,

+    mss_spi_protocol_mode_t protocol_mode,

+    mss_spi_pclk_div_t      clk_rate,

+    uint8_t                 frame_bit_length

+)

+{

+    ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) );

+    ASSERT( slave < MSS_SPI_MAX_NB_OF_SLAVES );

+    ASSERT( frame_bit_length <= 32 );

+    

+	/* Set the mode. */

+    this_spi->hw_reg_bit->CTRL_ENABLE = 0U;

+    this_spi->hw_reg_bit->CTRL_MASTER = MSS_SPI_MODE_MASTER;

+    this_spi->hw_reg_bit->CTRL_ENABLE = 1U;

+

+    /*

+     * Keep track of the required register configuration for this slave. These

+     * values will be used by the MSS_SPI_set_slave_select() function to configure

+     * the master to match the slave being selected.

+     */

+    if ( slave < MSS_SPI_MAX_NB_OF_SLAVES )     

+    {

+        this_spi->slaves_cfg[slave].ctrl_reg = 0x00000002uL | (uint32_t)protocol_mode | ((uint32_t)1 << TXRXDFCOUNT_SHIFT);

+        this_spi->slaves_cfg[slave].txrxdf_size_reg = frame_bit_length;

+        this_spi->slaves_cfg[slave].clk_gen = (uint8_t)clk_rate;

+    }

+}

+

+/***************************************************************************//**

+ * MSS_SPI_set_slave_select()

+ * See "mss_spi.h" for details of how to use this function.

+ */

+void MSS_SPI_set_slave_select

+(

+	mss_spi_instance_t * this_spi,

+	mss_spi_slave_t slave

+)

+{

+    ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) );

+    

+    /* This function is only intended to be used with an SPI master. */

+    ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_MASTER );

+    ASSERT( this_spi->slaves_cfg[slave].ctrl_reg != NOT_CONFIGURED );

+

+    /* Set the clock rate. */

+    this_spi->hw_reg_bit->CTRL_ENABLE = 0U;

+    this_spi->hw_reg->CONTROL = this_spi->slaves_cfg[slave].ctrl_reg;

+    this_spi->hw_reg->CLK_GEN = this_spi->slaves_cfg[slave].clk_gen;

+    this_spi->hw_reg->TXRXDF_SIZE = this_spi->slaves_cfg[slave].txrxdf_size_reg;

+    this_spi->hw_reg_bit->CTRL_ENABLE = 1U;

+    

+    /* Set slave select */

+    this_spi->hw_reg->SLAVE_SELECT |= ((uint32_t)1 << (uint32_t)slave);

+}

+

+/***************************************************************************//**

+ * MSS_SPI_clear_slave_select()

+ * See "mss_spi.h" for details of how to use this function.

+ */

+void MSS_SPI_clear_slave_select

+(

+	mss_spi_instance_t * this_spi,

+	mss_spi_slave_t slave

+)

+{

+    ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) );

+    

+    /* This function is only intended to be used with an SPI master. */

+    ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_MASTER );

+

+    this_spi->hw_reg->SLAVE_SELECT &= ~((uint32_t)1 << (uint32_t)slave);

+}

+

+/***************************************************************************//**

+ * MSS_SPI_transfer_frame()

+ * See "mss_spi.h" for details of how to use this function.

+ */

+uint32_t MSS_SPI_transfer_frame

+(

+    mss_spi_instance_t * this_spi,

+    uint32_t tx_bits

+)

+{

+    volatile uint32_t dummy;

+    

+    ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) );

+    

+    /* This function is only intended to be used with an SPI master. */

+    ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_MASTER );

+    

+    /* Flush Rx FIFO. */

+    while ( this_spi->hw_reg_bit->STATUS_RX_RDY == 1U )

+    {

+        dummy = this_spi->hw_reg->RX_DATA;

+        dummy = dummy;  /* Prevent Lint warning. */

+    }

+    

+    /* Send frame. */

+    this_spi->hw_reg->TX_DATA = tx_bits;

+    

+    /* Wait for frame Tx to complete. */

+    while ( this_spi->hw_reg_bit->STATUS_TX_DONE == 0U )

+    {

+        ;

+    }

+    

+    /* Read received frame. */

+    /* Wait for Rx complete. */

+    while ( this_spi->hw_reg_bit->STATUS_RX_RDY == 0U )

+    {

+        ;

+    }

+    /* Return Rx data. */

+    return( this_spi->hw_reg->RX_DATA );

+}

+

+

+/***************************************************************************//**

+ * MSS_SPI_transfer_block()

+ * See "mss_spi.h" for details of how to use this function.

+ */

+void MSS_SPI_transfer_block

+(

+    mss_spi_instance_t * this_spi,

+    const uint8_t * cmd_buffer,

+    uint16_t cmd_byte_size,

+    uint8_t * rd_buffer,

+    uint16_t rd_byte_size

+)

+{

+    uint16_t transfer_idx = 0U;

+    uint16_t tx_idx;

+    uint16_t rx_idx;

+    uint32_t frame_count;

+    volatile uint32_t rx_raw;

+    uint16_t transit = 0U;

+    

+    uint16_t transfer_size;     /* Total number of bytes transfered. */

+    

+    ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) );

+    

+    /* This function is only intended to be used with an SPI master. */

+    ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_MASTER );

+    

+    /* Compute number of bytes to transfer. */

+    transfer_size = cmd_byte_size + rd_byte_size;

+    

+    /* Adjust to 1 byte transfer to cater for DMA transfers. */

+    if ( transfer_size == 0U )

+    {

+        frame_count = 1U;

+    }

+    else

+    {

+        frame_count = transfer_size;

+    }

+    

+    /* Set frame size to 8 bits and the frame count to the tansfer size. */

+    this_spi->hw_reg_bit->CTRL_ENABLE = 0U;

+    this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~TXRXDFCOUNT_MASK) | ( (frame_count << TXRXDFCOUNT_SHIFT) & TXRXDFCOUNT_MASK);

+    this_spi->hw_reg->TXRXDF_SIZE = 8U;

+    this_spi->hw_reg_bit->CTRL_ENABLE = 1U;

+

+    /* Flush the receive FIFO. */

+    while ( !this_spi->hw_reg_bit->STATUS_RX_FIFO_EMPTY )

+    {

+        rx_raw = this_spi->hw_reg->RX_DATA;

+    }

+    

+    tx_idx = 0u;

+    rx_idx = 0u;

+    if ( tx_idx < cmd_byte_size )

+    {

+        this_spi->hw_reg->TX_DATA = cmd_buffer[tx_idx];

+        ++tx_idx;

+        ++transit;

+    }

+    else

+    {

+        if ( tx_idx < transfer_size )

+        {

+            this_spi->hw_reg->TX_DATA = 0x00U;

+            ++tx_idx;

+            ++transit;

+        }

+    }

+    /* Perform the remainder of the transfer by sending a byte every time a byte

+     * has been received. This should ensure that no Rx overflow can happen in

+     * case of an interrupt occurs during this function. */

+    while ( transfer_idx < transfer_size )

+    {

+        if ( !this_spi->hw_reg_bit->STATUS_RX_FIFO_EMPTY )

+        {

+            /* Process received byte. */

+            rx_raw = this_spi->hw_reg->RX_DATA;

+            if ( transfer_idx >= cmd_byte_size )

+            {

+                if ( rx_idx < rd_byte_size )

+                {

+                    rd_buffer[rx_idx] = (uint8_t)rx_raw;   

+                }

+                ++rx_idx;

+            }

+            ++transfer_idx;

+            --transit;

+        }

+

+        if ( !this_spi->hw_reg_bit->STATUS_TX_FIFO_FULL )

+        {

+            if (transit < RX_FIFO_SIZE)

+            {

+                /* Send another byte. */

+                if ( tx_idx < cmd_byte_size )

+                {

+                    this_spi->hw_reg->TX_DATA = cmd_buffer[tx_idx];

+                    ++tx_idx;

+                    ++transit;

+                }

+                else

+                {

+                    if ( tx_idx < transfer_size )

+                    {

+                        this_spi->hw_reg->TX_DATA = 0x00U;

+                        ++tx_idx;

+                        ++transit;

+                    }

+                }

+            }

+        }

+    }

+}

+

+/***************************************************************************//**

+ * MSS_SPI_set_frame_rx_handler()

+ * See "mss_spi.h" for details of how to use this function.

+ */

+void MSS_SPI_set_frame_rx_handler

+(

+    mss_spi_instance_t * this_spi,

+    mss_spi_frame_rx_handler_t rx_handler

+)

+{

+    ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) );

+    

+    /* This function is only intended to be used with an SPI slave. */

+    ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_SLAVE );

+    

+    /* Disable block Rx handler as they are mutually exclusive. */

+    this_spi->block_rx_handler = 0U;

+    

+    /* Keep a copy of the pointer to the rx hnadler function. */

+    this_spi->frame_rx_handler = rx_handler;

+    

+    /* Enable Rx interrupt. */

+    this_spi->hw_reg_bit->CTRL_RX_INT_EN = 1U;

+    NVIC_EnableIRQ( this_spi->irqn );

+}

+

+/***************************************************************************//**

+ * MSS_SPI_set_slave_tx_frame()

+ * See "mss_spi.h" for details of how to use this function.

+ */

+void MSS_SPI_set_slave_tx_frame

+(

+    mss_spi_instance_t * this_spi,

+    uint32_t frame_value

+)

+{

+    ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) );

+

+    /* This function is only intended to be used with an SPI slave. */

+    ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_SLAVE );

+    

+    /* Disable slave block tx buffer as it is mutually exclusive with frame

+     * level handling. */    

+    this_spi->slave_tx_buffer = 0U;

+    this_spi->slave_tx_size = 0U;

+    this_spi->slave_tx_idx = 0U;

+    

+    /* Keep a copy of the slave tx frame value. */

+    this_spi->slave_tx_frame = frame_value;

+    

+    /* Load frame into Tx data register. */

+    this_spi->hw_reg->TX_DATA = this_spi->slave_tx_frame;

+    

+    /* Enable Tx Done interrupt in order to reload the slave Tx frame after each

+     * time it has been sent. */

+    this_spi->hw_reg_bit->CTRL_TX_INT_EN = 1U;

+    NVIC_EnableIRQ( this_spi->irqn );

+}

+

+/***************************************************************************//**

+ * MSS_SPI_set_slave_block_buffers()

+ * See "mss_spi.h" for details of how to use this function.

+ */

+void MSS_SPI_set_slave_block_buffers

+(

+    mss_spi_instance_t * this_spi,

+    const uint8_t * tx_buffer,

+    uint32_t tx_buff_size,

+    uint8_t * rx_buffer,

+    uint32_t rx_buff_size,

+    mss_spi_block_rx_handler_t block_rx_handler

+)

+{

+    uint32_t frame_count;

+    

+    ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) );

+    

+    /* This function is only intended to be used with an SPI slave. */

+    ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_SLAVE );

+    

+    /* Disable Rx frame handler as it is mutually exclusive with block rx handler. */

+    this_spi->frame_rx_handler = 0U;

+    

+    /* Keep a copy of the pointer to the block rx handler function. */

+    this_spi->block_rx_handler = block_rx_handler;

+    

+    this_spi->slave_rx_buffer = rx_buffer;

+    this_spi->slave_rx_size = rx_buff_size;

+    this_spi->slave_rx_idx = 0U;

+    

+    /**/

+    this_spi->slave_tx_buffer = tx_buffer;

+    this_spi->slave_tx_size = tx_buff_size;

+    this_spi->slave_tx_idx = 0U;

+

+    frame_count = rx_buff_size;

+    

+    /**/

+    this_spi->hw_reg_bit->CTRL_ENABLE = 0U;

+    this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~TXRXDFCOUNT_MASK) | (frame_count << TXRXDFCOUNT_SHIFT);

+    this_spi->hw_reg->TXRXDF_SIZE = 8U;

+    this_spi->hw_reg_bit->CTRL_ENABLE = 1U;

+    

+    /* Load the transmit FIFO. */

+    while ( !(this_spi->hw_reg_bit->STATUS_TX_FIFO_FULL) && ( this_spi->slave_tx_idx < this_spi->slave_tx_size ) )

+    {

+        this_spi->hw_reg->TX_DATA = this_spi->slave_tx_buffer[this_spi->slave_tx_idx];

+        ++this_spi->slave_tx_idx;

+    }

+    

+    /* Enable Rx interrupt. */

+    this_spi->hw_reg_bit->CTRL_RX_INT_EN = 1U;

+    NVIC_EnableIRQ( this_spi->irqn );

+}

+

+/***************************************************************************//**

+ * SPI interrupt service routine.

+ */

+static void mss_spi_isr

+(

+    mss_spi_instance_t * this_spi

+)

+{

+    uint32_t rx_frame;

+    

+    ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) );

+    

+    if ( this_spi->hw_reg_bit->MIS_RX_RDY )

+    {

+        while( !this_spi->hw_reg_bit->STATUS_RX_FIFO_EMPTY )

+        {

+            rx_frame = this_spi->hw_reg->RX_DATA;

+            if ( this_spi->frame_rx_handler != 0U )

+            {

+                /* Single frame handling mode. */

+                this_spi->frame_rx_handler( rx_frame );

+            }

+            else 

+            {

+                if ( this_spi->block_rx_handler != 0U )

+                {

+                    /* Block handling mode. */

+                    if ( this_spi->slave_rx_idx < this_spi->slave_rx_size )

+                    {

+                        this_spi->slave_rx_buffer[this_spi->slave_rx_idx] = (uint8_t)rx_frame;

+                        ++this_spi->slave_rx_idx;

+                        if ( this_spi->slave_rx_idx == this_spi->slave_rx_size )

+                        {

+                            (*this_spi->block_rx_handler)( this_spi->slave_rx_buffer, this_spi->slave_rx_size );

+                        }

+                    }

+                }

+            }

+            

+            /* Feed transmit FIFO. */

+            if ( !(this_spi->hw_reg_bit->STATUS_TX_FIFO_FULL) && ( this_spi->slave_tx_idx < this_spi->slave_tx_size ) )

+            {

+                this_spi->hw_reg->TX_DATA = this_spi->slave_tx_buffer[this_spi->slave_tx_idx];

+                ++this_spi->slave_tx_idx;

+            }

+        }

+        this_spi->hw_reg_bit->INT_CLEAR_RX_RDY = 1U;

+    }

+    

+    if ( this_spi->hw_reg_bit->MIS_TX_DONE )

+    {

+        if ( this_spi->slave_tx_buffer != 0U )

+        {

+            this_spi->hw_reg->TX_DATA = this_spi->slave_tx_buffer[this_spi->slave_tx_idx];

+            ++this_spi->slave_tx_idx;

+            if ( this_spi->slave_tx_idx >= this_spi->slave_tx_size )

+            {

+                this_spi->slave_tx_idx = 0U;

+            }

+        }

+        else

+        {

+            /* Reload slave tx frame into Tx data register. */

+            this_spi->hw_reg->TX_DATA = this_spi->slave_tx_frame;

+        }

+    }

+}

+

+/***************************************************************************//**

+ * SPIO interrupt service routine.

+ * Please note that the name of this ISR is defined as part of the SmartFusion

+ * CMSIS startup code.

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void SPI0_IRQHandler( void )

+#else

+void SPI0_IRQHandler( void )

+#endif

+{

+    mss_spi_isr( &g_mss_spi0 );

+    NVIC_ClearPendingIRQ( SPI0_IRQn );

+}

+

+/***************************************************************************//**

+ * SPI1 interrupt service routine.

+ * Please note that the name of this ISR is defined as part of the SmartFusion

+ * CMSIS startup code.

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void SPI1_IRQHandler( void )

+#else

+void SPI1_IRQHandler( void )

+#endif

+{

+    mss_spi_isr( &g_mss_spi1 );

+    NVIC_ClearPendingIRQ( SPI1_IRQn );

+}

+

+#ifdef __cplusplus

+}

+#endif

+

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.h
new file mode 100644
index 0000000..2b3617b
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.h
@@ -0,0 +1,1296 @@
+/***************************************************************************//**

+ * (c) Copyright 2008 Actel Corporation.  All rights reserved.

+ * 

+ * SmartFusion microcontroller subsystem SPI bare metal software driver public API.

+ *

+ * The microcontroller subsystem SPI driver provides functions for implementing

+ * SPI master or SPI slave operations. These operations can be one of two

+ * classes: SPI frame operation or block transfer operations.

+ * Frame operations allow transferring SPI frames from 4 to 32 bits long. Block

+ * operations allow transferring blocks of data organized as 8 bit bytes. 

+ *

+ * SVN $Revision: 2189 $

+ * SVN $Date: 2010-02-16 22:02:32 +0000 (Tue, 16 Feb 2010) $

+ */

+/*=========================================================================*//**

+  @mainpage SmartFusion MSS SPI Bare Metal Driver.

+

+  @section intro_sec Introduction

+  The SmartFusion™ microcontroller subsystem (MSS) includes two serial

+  peripheral interface SPI peripherals for serial communication. This driver

+  provides a set of functions for controlling the MSS SPIs as part of a bare

+  metal system where no operating system is available. These drivers can be

+  adapted for use as part of an operating system, but the implementation of the

+  adaptation layer between this driver and the operating system's driver model

+  is outside the scope of this driver.

+  

+  @section hw_dependencies Hardware Flow Dependencies

+  The configuration of all features of the MSS SPIs is covered by this driver

+  with the exception of the SmartFusion IOMUX configuration. SmartFusion allows

+  multiple non-concurrent uses of some external pins through IOMUX configuration.

+  This feature allows optimization of external pin usage by assigning external

+  pins for use by either the microcontroller subsystem or the FPGA fabric. The

+  MSS SPIs serial signals are routed through IOMUXes to the SmartFusion device

+  external pins. These IOMUXes are automatically configured correctly by the MSS

+  configurator tool in the hardware flow when the MSS SPIs are enabled in that

+  tool. You must ensure that the MSS SPIs are enabled by the MSS configurator

+  tool in the hardware flow; otherwise the serial inputs and outputs will not be

+  connected to the chip's external pins. For more information on IOMUX, refer to

+  the IOMUX section of the SmartFusion Datasheet.

+  The base address, register addresses and interrupt number assignment for the

+  MSS SPI blocks are defined as constants in the SmartFusion CMSIS-PAL. You must

+  ensure that the SmartFusion CMSIS-PAL is either included in the software tool

+  chain used to build your project or is included in your project.

+  

+  @section theory_op Theory of Operation

+  The MSS SPI driver functions are grouped into the following categories:

+    • Initialization

+    • Configuration for either master or slave operations

+    • SPI master frame transfer control

+    • SPI master block transfer control

+    • SPI slave frame transfer control

+    • SPI slave block transfer control

+    • DMA block transfer

+  Frame transfers allow the MSS SPI to write or read up to 32 bits of data in a

+  SPI transaction. For example, a frame transfer of 12 bits might be used to

+  read the result of an ADC conversion from a SPI analog to digital converter.

+  Block transfers allow the MSS SPI to write or read a number of bytes in a SPI

+  transaction. Block transfer transactions allow data transfers in multiples of

+  8 bits (8, 16, 24, 32, 40…). Block transfers are typically used with byte

+  oriented devices like SPI FLASH devices.

+

+  Initialization 

+    The MSS SPI driver is initialized through a call to the MSS_SPI_init()

+    function. The MSS_SPI_init() function takes only one parameter, a pointer

+    to one of two global data structures used by the driver to store state

+    information for each MSS SPI. A pointer to these data structures is also

+    used as first parameter to any of the driver functions to identify which MSS

+    SPI will be used by the called function. The names of these two data

+    structures are g_mss_spi0 and g_mss_spi1. Therefore any call to an MSS SPI

+    driver function should be of the form MSS_SPI_function_name( &g_mss_spi0, ... )

+    or MSS_SPI_function_name( &g_mss_spi1, ... ).

+    The MSS_SPI_init() function resets the specified MSS SPI hardware block and

+    clears any pending interrupts from that MSS SPI in the Cortex-M3 NVIC.

+    The MSS_SPI_init() function must be called before any other MSS SPI driver

+    functions can be called.

+

+  Configuration

+    A MSS SPI block can operate either as a master or slave SPI device. There

+    are two distinct functions for configuring a MSS SPI block for master or

+    slave operations.

+

+    Master configuration

+    The MSS_SPI_configure_master_mode() function configures the specified MSS

+    SPI block for operations as a SPI master. It must be called once for each

+    remote SPI slave device the MSS SPI block will communicate with. It is used

+    to provide the following information about each SPI slave’s communication

+    characteristics:

+        • The SPI protocol mode

+        • The SPI clock speed

+        • The frame bit length

+    This information is held by the driver and will be used to alter the

+    configuration of the MSS SPI block each time a slave is selected through a

+    call to MSS_SPI_set_slave_select(). The SPI protocol mode defines the

+    initial state of the clock signal at the start of a transaction and which

+    clock edge will be used to sample the data signal, or it defines whether the

+    SPI block will operate in TI synchronous serial mode or in NSC MICROWIRE mode.

+

+    Slave configuration

+    The MSS_SPI_configure_slave_mode() function configures the specified MSS SPI

+    block for operations as a SPI slave. It configures the following SPI

+    communication characteristics:

+        • The SPI protocol mode 

+        • The SPI clock speed

+        • The frame bit length

+    The SPI protocol mode defines the initial state of the clock signal at the

+    start of a transaction and which clock edge will be used to sample the data

+    signal, or it defines whether the SPI block will operate in TI synchronous

+    serial mode or in NSC MICROWIRE mode.

+

+  SPI master frame transfer control

+    The following functions are used as part of SPI master frame transfers:

+        • MSS_SPI_set_slave_select()

+        • MSS_SPI_transfer_frame()

+        • MSS_SPI_clear_slave_select()

+    The master must first select the target slave through a call to

+    MSS_SPI_set_slave_select(). This causes the relevant slave select line to

+    become asserted while data is clocked out onto the SPI data line.

+    A call to is then made to function MSS_SPI_transfer_frame() specifying and

+    the value of the data frame to be sent.

+    The function MSS_SPI_clear_slave_select() can be used after the transfer is

+    complete to prevent this slave select line from being asserted during

+    subsequent SPI transactions. A call to this function is only required if the

+    master is communicating with multiple slave devices.

+

+  SPI master block transfer control

+    The following functions are used as part of SPI master block transfers:

+        • MSS_SPI_set_slave_select()

+        • MSS_SPI_clear_slave_select()

+        • MSS_SPI_transfer_block()

+    The master must first select the target slave through a call to

+    MSS_SPI_set_slave_select(). This causes the relevant slave select line to

+    become asserted while data is clocked out onto the SPI data line.

+    Alternatively a GPIO can be used to control the state of the target slave

+    device’s chip select signal.

+    A call to is then made to function MSS_SPI_transfer_block (). The

+    parameters of this function specify:

+        • the number of bytes to be transmitted

+        • a pointer to the buffer containing the data to be transmitted

+        • the number of bytes to be received

+        • a pointer to the buffer where received data will be stored

+    The number of bytes to be transmitted can be set to zero to indicate that

+    the transfer is purely a block read transfer. The number of bytes to be

+    received can be set to zero to specify that the transfer is purely a block

+    write transfer.

+    The function MSS_SPI_clear_slave_select() can be used after the transfer is

+    complete to prevent this slave select line from being asserted during

+    subsequent SPI transactions. A call to this function is only required if the

+    master is communicating with multiple slave devices.

+ 

+  SPI slave frame transfer control

+    The following functions are used as part of SPI slave frame transfers:

+        • MSS_SPI_set_slave_tx_frame()

+        • MSS_SPI_set_frame_rx_handler()

+    The MSS_SPI_set_slave_tx_frame() function specifies the frame data that will

+    be returned to the SPI master. The frame data specified through this

+    function is the value that will be read over the SPI bus by the remote SPI

+    master when it initiates a transaction. A call to MSS_SPI_set_slave_tx_frame()

+    is only required if the MSS SPI slave is the target of SPI  read transactions,

+    i.e. if data is meant to be read from the SmartFusion device over SPI.

+    The MSS_SPI_set_frame_rx_handler() function specifies the receive handler

+    function that will called when a frame of data has been received by the MSS

+    SPI when it is configured as a slave. The receive handler function specified

+    through this call will process the frame data written, over the SPI bus, to

+    the MSS SPI slave by the remote SPI master. The receive handler function must

+    be implemented as part of the application. It is only required if the MSS SPI

+    slave is the target of SPI frame write transactions.

+

+  SPI slave block transfer control

+    The following functions are used as part of SPI slave block transfers:

+        • MSS_SPI_set_slave_block_buffers()

+    The MSS_SPI_set_slave_block_buffers() function is used to configure a MSS SPI

+    slave for block transfer operations. It specifies:

+        • The buffer containing the data that will be returned to the remote SPI master

+        • The buffer where data received from the remote SPI master will be stored

+        • The handler function that will be called after the receive buffer is filled

+

+  DMA block transfer control

+    The following functions are used as part of MSS SPI DMA transfers:

+        • MSS_SPI_disable()

+        • MSS_SPI_set_transfer_byte_count()

+        • MSS_SPI_enable()

+        • MSS_SPI_tx_done()

+    The MSS SPI must first be disabled through a call to function MSS_SPI_disable().

+    The number of bytes to be transferred is then set through a call to function

+    MSS_SPI_set_transfer_byte_count(). The DMA transfer is then initiated by a call

+    to the MSS_PDMA_start() function provided by the MSS PDMA driver. The actual

+    DMA transfer will only start once the MSS SPI block has been re-enabled through

+    a call to  MSS_SPI_enable(). The completion of the DMA driven SPI transfer can

+    be detected through a call to MSS_SPI_tx_done(). The direction of the SPI

+    transfer, write or read, depends on the DMA channel configuration. A SPI write

+    transfer occurs when the DMA channel is configured to write data to the MSS SPI

+    block. A SPI read transfer occurs when the DMA channel is configured to read data

+    from the MSS SPI block.

+

+ *//*=========================================================================*/

+#ifndef MSS_SPI_H_

+#define MSS_SPI_H_

+

+#include "../../CMSIS/a2fxxxm3.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/***************************************************************************//**

+  This defines the function prototype that must be followed by MSS SPI slave

+  frame receive handler functions. These functions are registered with the MSS

+  SPI driver through the MSS_SPI_set_frame_rx_handler () function.

+  

+  Declaring and Implementing Slave Frame Receive Handler Functions:

+    Slave frame receive handler functions should follow the following prototype:

+        void slave_frame_receive_handler ( uint32_t rx_frame );

+    The actual name of the receive handler is unimportant. You can use any name

+    of your choice for the receive frame handler. The rx_frame parameter will

+    contain the value of the received frame.

+ */

+typedef void (*mss_spi_frame_rx_handler_t)( uint32_t rx_frame );

+

+/***************************************************************************//**

+  This defines the function prototype that must be followed by MSS SPI slave

+  block receive handler functions. These functions are registered with the MSS

+  SPI driver through the MSS_SPI_set_slave_block_buffers() function.

+  

+  Declaring and Implementing Slave Block Receive Handler Functions

+    Slave block receive handler functions should follow the following prototype:

+        void mss_spi_block_rx_handler ( uint8_t * rx_buff, uint16_t rx_size );

+    The actual name of the receive handler is unimportant. You can use any name

+    of your choice for the receive frame handler. The rx_buff parameter will

+    contain a pointer to the start of the received block. The rx_size parameter

+    will contain the number of bytes of the received block.

+

+ */

+typedef void (*mss_spi_block_rx_handler_t)( uint8_t * rx_buff, uint32_t rx_size );

+

+/***************************************************************************//**

+  This enumeration is used to define the settings for the SPI protocol mode

+  bits, CPHA and CPOL. It is used as a parameter to the MSS_SPI_configure_master_mode()

+  and MSS_SPI_configure_slave_mode() functions.

+  

+  - MSS_SPI_MODE0:

+        Clock starts low, data read on clock's rising edge, data changes on

+        falling edge.

+        

+  - MSS_SPI_MODE1:

+        Clock starts low, data read on clock's falling edge, data changes on

+        rising edge.

+        

+  - MSS_SPI_MODE2:

+        Clock starts high, data read on clock's falling edge, data changes on

+        rising edge.

+        

+  - MSS_SPI_MODE3:

+        Clock starts high, data read on clock's rising edge, data changes on

+        falling edge.

+        

+  - MSS_TI_MODE:  

+        TI syncronous serial mode. Slave select is pulsed at start of transfer.

+        

+  - MSS_NSC_MODE:

+        NSC Microwire mode.

+ */

+typedef enum __mss_spi_protocol_mode_t

+{

+    MSS_SPI_MODE0    = 0x00000000,

+    MSS_SPI_TI_MODE  = 0x00000004,

+    MSS_SPI_NSC_MODE = 0x00000008,

+    MSS_SPI_MODE2    = 0x01000000,

+    MSS_SPI_MODE1    = 0x02000000,

+    MSS_SPI_MODE3    = 0x03000000

+} mss_spi_protocol_mode_t;

+

+/***************************************************************************//**

+ This enumeration specifies the divider to be applied to the the APB bus clock

+ in order to generate the SPI clock. It is used as parameter to the

+ MSS_SPI_configure_master_mode() and MSS_SPI_configure_slave_mode()functions.

+ */

+ typedef enum __mss_spi_pclk_div_t

+ {

+	MSS_SPI_PCLK_DIV_2		= 0,

+	MSS_SPI_PCLK_DIV_4		= 1,

+	MSS_SPI_PCLK_DIV_8		= 2,

+	MSS_SPI_PCLK_DIV_16		= 3,

+	MSS_SPI_PCLK_DIV_32		= 4,

+	MSS_SPI_PCLK_DIV_64		= 5,

+	MSS_SPI_PCLK_DIV_128	= 6,

+	MSS_SPI_PCLK_DIV_256	= 7

+} mss_spi_pclk_div_t;

+

+/***************************************************************************//**

+ This enumeration is used to select a specific SPI slave device (0 to 7). It is

+ used as a parameter to the MSS_SPI_configure_master_mode(),

+ MSS_SPI_set_slave_select() and MSS_SPI_clear_slave_select () functions.

+ */

+ typedef enum __mss_spi_slave_t

+ {

+	MSS_SPI_SLAVE_0		= 0,

+	MSS_SPI_SLAVE_1		= 1,

+	MSS_SPI_SLAVE_2		= 2,

+	MSS_SPI_SLAVE_3		= 3,

+	MSS_SPI_SLAVE_4		= 4,

+	MSS_SPI_SLAVE_5		= 5,

+	MSS_SPI_SLAVE_6		= 6,

+	MSS_SPI_SLAVE_7		= 7,

+    MSS_SPI_MAX_NB_OF_SLAVES = 8

+} mss_spi_slave_t;

+

+/***************************************************************************//**

+  This constant defines a frame size of 8 bits when configuring an MSS SPI to

+  perform block transfer data transactions.

+  It must be used as the value for the frame_bit_length parameter of function

+  MSS_SPI_configure_master_mode() when performing block transfers between the

+  MSS SPI master and the target SPI slave.

+  It must also be used as the value for the frame_bit_length parameter of

+  function MSS_SPI_configure_slave_mode() when performing block transfers

+  between the MSS SPI slave and the remote SPI master.

+ */

+#define MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE   8

+

+/***************************************************************************//**

+  The mss_spi_slave_cfg_t holds the MSS SPI configuration that must be used to

+  communicate with a specific SPI slave.

+ */

+typedef struct __mss_spi_slave_cfg_t

+{

+    uint32_t ctrl_reg;

+    uint8_t txrxdf_size_reg;

+    uint8_t clk_gen;

+} mss_spi_slave_cfg_t;

+

+/***************************************************************************//**

+  There is one instance of this structure for each of the microcontroller

+  subsystem's SPIs. Instances of this structure are used to identify a specific

+  SPI. A pointer to an instance of the mss_spi_instance_t structure is passed as

+  the first parameter to MSS SPI driver functions to identify which SPI should

+  perform the requested operation.

+ */

+typedef struct __mss_spi_instance_t

+{

+    /* CMSIS related defines identifying the SPI hardware. */

+    SPI_TypeDef *          hw_reg;     /*!< Pointer to SPI registers. */

+    SPI_BitBand_TypeDef *  hw_reg_bit; /*!< Pointer to SPI registers bit band area. */

+    IRQn_Type               irqn;       /*!< SPI's Cortex-M3 NVIC interrupt number. */

+    

+	/* Internal transmit state: */

+	const uint8_t * slave_tx_buffer;    /*!< Pointer to slave transmit buffer. */

+	uint32_t slave_tx_size;             /*!< Size of slave transmit buffer. */

+	uint32_t slave_tx_idx;              /*!< Current index into slave transmit buffer. */

+	

+	/* Internal receive state: */

+	uint8_t * slave_rx_buffer;          /*!< Pointer to buffer where data received by a slave will be stored. */

+	uint32_t slave_rx_size;             /*!< Slave receive buffer size. */

+	uint32_t slave_rx_idx;              /*!< Current index into slave receive buffer. */

+    

+    /* Configuration for each target slave. */

+    mss_spi_slave_cfg_t slaves_cfg[MSS_SPI_MAX_NB_OF_SLAVES];

+    

+    /** Slave received frame handler: */

+    mss_spi_frame_rx_handler_t frame_rx_handler;    /*!< Pointer to function that will be called when a frame is received when the SPI block is configured as slave. */

+    

+    uint32_t slave_tx_frame;                /*!< Value of the data frame that will be transmited when the SPI block is configured as slave. */

+    

+    /* Slave block rx handler: */

+    mss_spi_block_rx_handler_t block_rx_handler;    /*!< Pointer to the function that will be called when a data block has been received. */

+

+} mss_spi_instance_t;

+

+/***************************************************************************//**

+  This instance of mss_spi_instance_t holds all data related to the operations

+  performed by MSS SPI 0. A pointer to g_mss_spi0 is passed as the first

+  parameter to MSS SPI driver functions to indicate that MSS SPI 0 should

+  perform the requested operation.

+ */

+extern mss_spi_instance_t g_mss_spi0;

+

+/***************************************************************************//**

+  This instance of mss_spi_instance_t holds all data related to the operations

+  performed by MSS SPI 1. A pointer to g_mss_spi1 is passed as the first

+  parameter to MSS SPI driver functions to indicate that MSS SPI 1 should

+  perform the requested operation.

+ */

+extern mss_spi_instance_t g_mss_spi1;

+

+/***************************************************************************//**

+  The MSS_SPI_init() function initializes and hardware and data structures of

+  one of the SmartFusion MSS SPIs. The MSS_SPI_init() function must be called

+  before any other MSS SPI driver functions can be called.

+  

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+    

+  Example:

+  @code

+  MSS_SPI_init( &g_mss_spi0 );

+  @endcode

+ */

+void MSS_SPI_init

+(

+	mss_spi_instance_t * this_spi

+);

+

+/***************************************************************************//**

+  The MSS_SPI_configure_slave_mode() function configure a MSS SPI block for

+  operations as a slave SPI device. It configures the SPI hardware with the

+  selected SPI protocol mode and clock speed.

+    

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+    

+  @param protocol_mode

+    Serial peripheral interface operating mode. Allowed values are:

+        - MSS_SPI_MODE0

+        - MSS_SPI_MODE1

+        - MSS_SPI_MODE2

+        - MSS_SPI_MODE3

+        - MSS_TI_MODE

+        - MSS_NSC_MODE

+ 

+  @param clk_rate

+    Divider value used to generate serial interface clock signal from PCLK.

+    Allowed values are:

+        - MSS_SPI_PCLK_DIV_2

+        - MSS_SPI_PCLK_DIV_4

+        - MSS_SPI_PCLK_DIV_8

+        - MSS_SPI_PCLK_DIV_16

+        - MSS_SPI_PCLK_DIV_32

+        - MSS_SPI_PCLK_DIV_64

+        - MSS_SPI_PCLK_DIV_128

+        - MSS_SPI_PCLK_DIV_256

+       

+  @param frame_bit_length

+    Number of bits making up the frame. The maximum frame length is 32 bits. You

+    must use the MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE constant as the value for

+    frame_bit_length when configuring the MSS SPI master for block transfer

+    transactions with the target SPI slave.

+  

+  Example:

+  @code

+  MSS_SPI_init( &g_mss_spi0 );

+  MSS_SPI_configure_slave_mode

+    (

+        &g_mss_spi0,

+        MSS_SPI_MODE2,

+        MSS_SPI_PCLK_DIV_64,

+        MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE

+    );

+  @endcode

+  

+ */ 

+void MSS_SPI_configure_slave_mode

+(

+	mss_spi_instance_t * this_spi,

+    mss_spi_protocol_mode_t protocol_mode,

+    mss_spi_pclk_div_t clk_rate,

+    uint8_t frame_bit_length

+);

+

+/***************************************************************************//**

+  The MSS_SPI_configure_master_mode() function configures the protocol mode,

+  serial clock speed and frame size for a specific target SPI slave device. It

+  is used when the MSS SPI hardware block is used as a SPI master. This function

+  must be called once for each target SPI slave the SPI master is going to

+  communicate with. The SPI master hardware will be configured with the

+  configuration specified by this function during calls to

+  MSS_SPI_set_slave_select().

+  

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+    

+    

+  @param slave

+    The slave parameter is used to identify a target SPI slave. The driver will

+    hold the MSS SPI master configuration required to communicate with this

+    slave, as specified by the other function parameters. Allowed values are:

+        • MSS_SPI_SLAVE_0

+        • MSS_SPI_SLAVE_1

+        • MSS_SPI_SLAVE_2

+        • MSS_SPI_SLAVE_3

+        • MSS_SPI_SLAVE_4

+        • MSS_SPI_SLAVE_5

+        • MSS_SPI_SLAVE_6

+        • MSS_SPI_SLAVE_7

+    

+  @param protocol_mode

+    Serial peripheral interface operating mode. Allowed values are:

+        • MSS_SPI_MODE0

+        • MSS_SPI_MODE1

+        • MSS_SPI_MODE2

+        • MSS_SPI_MODE3

+        • MSS_SPI_TI_MODE

+        • MSS_SPI_NSC_MODE

+ 

+  @param clk_rate

+    Divider value used to generate serial interface clock signal from PCLK.

+    Allowed values are:

+        • MSS_SPI_PCLK_DIV_2

+        • MSS_SPI_PCLK_DIV_4

+        • MSS_SPI_PCLK_DIV_8

+        • MSS_SPI_PCLK_DIV_16

+        • MSS_SPI_PCLK_DIV_32

+        • MSS_SPI_PCLK_DIV_64

+        • MSS_SPI_PCLK_DIV_128

+        • MSS_SPI_PCLK_DIV_256

+        

+  @param frame_bit_length

+    Number of bits making up the frame. The maximum frame length is 32 bits. You

+    must use the MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE constant as the value for

+    frame_bit_length when configuring the MSS SPI master for block transfer

+    transactions with the target SPI slave.

+    

+  Example:

+  @code

+  MSS_SPI_init( &g_mss_spi0 );

+

+  MSS_SPI_configure_master_mode

+    (

+        &g_mss_spi0,

+        MSS_SPI_SLAVE_0,

+        MSS_SPI_MODE2,

+        MSS_SPI_PCLK_DIV_64,

+        12

+     );

+

+  MSS_SPI_configure_master_mode

+    (

+        &g_mss_spi0,

+        MSS_SPI_SLAVE_1,

+        MSS_SPI_TI_MODE,

+        MSS_SPI_PCLK_DIV_128,

+        MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE

+     );

+  @endcode

+ */ 

+void MSS_SPI_configure_master_mode

+(

+	mss_spi_instance_t *    this_spi,

+	mss_spi_slave_t         slave,

+    mss_spi_protocol_mode_t protocol_mode,

+    mss_spi_pclk_div_t      clk_rate,

+    uint8_t                 frame_bit_length

+);

+

+/*==============================================================================

+ * Master functions

+ *============================================================================*/

+

+/***************************************************************************//**

+  The MSS_SPI_slave_select() function is used by a MSS SPI master to select a

+  specific slave. This function causes the relevant slave select signal to be

+  asserted.

+ 

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+    

+ 

+  @param slave

+    The slave parameter is one of mss_spi_slave_t enumerated constants

+    identifying a slave.

+  

+  Example:

+  @code

+  const uint8_t frame_size = 25;

+  const uint32_t master_tx_frame = 0x0100A0E1;

+

+  MSS_SPI_init( &g_mss_spi0 );

+  MSS_SPI_configure_master_mode

+    (

+        &g_mss_spi0,

+        MSS_SPI_SLAVE_0,

+        MSS_SPI_MODE1,

+        MSS_SPI_PCLK_DIV_256,

+        frame_size

+     );

+

+  MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 );

+  MSS_SPI_transfer_frame( &g_mss_spi0, master_tx_frame );

+  MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 );

+  @endcode

+ */

+void MSS_SPI_set_slave_select

+(

+	mss_spi_instance_t * this_spi,

+	mss_spi_slave_t slave

+);

+

+/***************************************************************************//**

+  The MSS_SPI_clear_slave_select() function is used by a MSS SPI Master to

+  deselect a specific slave. This function causes the relevant slave select

+  signal to be de-asserted.

+ 

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+    

+ 

+  @param slave

+    The slave parameter is one of mss_spi_slave_t enumerated constants

+    identifying a slave.

+  

+  Example:

+  @code

+  const uint8_t frame_size = 25;

+  const uint32_t master_tx_frame = 0x0100A0E1;

+

+  MSS_SPI_init( &g_mss_spi0 );

+  MSS_SPI_configure_master_mode

+    (

+        &g_mss_spi0,

+        MSS_SPI_SLAVE_0,

+        MSS_SPI_MODE1,

+        MSS_SPI_PCLK_DIV_256,

+        frame_size

+     );

+  MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 );

+  MSS_SPI_transfer_frame( &g_mss_spi0, master_tx_frame );

+  MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 );

+  @endcode

+ */

+void MSS_SPI_clear_slave_select

+(

+	mss_spi_instance_t * this_spi,

+	mss_spi_slave_t slave

+);

+

+/***************************************************************************//**

+  The MSS_SPI_disable() function is used to temporarily disable a MSS SPI

+  hardware block. This function is typically used in conjunction with the

+  SPI_set_transfer_byte_count() function to setup a DMA controlled SPI transmit

+  transaction as the SPI_set_transfer_byte_count() function must only be used

+  when the MSS SPI hardware is disabled.

+ 

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+  

+  Example:

+  @code

+  uint32_t transfer_size;

+  uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };

+  

+  transfer_size = sizeof(tx_buffer);

+  

+  MSS_SPI_disable( &g_mss_spi0 );

+  MSS_SPI_set_transfer_byte_count( &g_mss_spi0, transfer_size );

+  PDMA_start

+    (

+        PDMA_CHANNEL_0,

+        (uint32_t)tx_buffer,

+        PDMA_SPI1_TX_REGISTER,

+        transfer_size

+    );

+  MSS_SPI_enable( &g_mss_spi0 );

+  

+  while ( !MSS_SPI_tx_done( &g_mss_spi0 ) )

+  {

+      ;

+  }

+  @endcode

+ */

+static __INLINE void MSS_SPI_disable

+(

+    mss_spi_instance_t * this_spi

+)

+{

+    this_spi->hw_reg_bit->CTRL_ENABLE = 0;

+}

+

+/***************************************************************************//**

+  The MSS_SPI_enable() function is used to re-enable a MSS SPI hardware block

+  after it was disabled using the SPI_disable() function.

+ 

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+    

+  Example:

+  @code

+  uint32_t transfer_size;

+  uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };

+  

+  transfer_size = sizeof(tx_buffer);

+  

+  MSS_SPI_disable( &g_mss_spi0 );

+  MSS_SPI_set_transfer_byte_count( &g_mss_spi0, transfer_size );

+  PDMA_start

+    (

+        PDMA_CHANNEL_0,

+        (uint32_t)tx_buffer,

+        PDMA_SPI1_TX_REGISTER,

+        transfer_size

+    );

+  MSS_SPI_enable( &g_mss_spi0 );

+  

+  while ( !MSS_SPI_tx_done( &g_mss_spi0 ) )

+  {

+      ;

+  }

+  @endcode

+ */

+static __INLINE void MSS_SPI_enable

+(

+    mss_spi_instance_t * this_spi

+)

+{

+    this_spi->hw_reg_bit->CTRL_ENABLE = 1;

+}

+

+/***************************************************************************//**

+  The MSS_SPI_set_transfer_byte_count() function is used as part of setting up

+  a SPI transfer using DMA. It specifies the number of bytes that must be

+  transferred before MSS_SPI_tx_done() indicates that the transfer is complete.

+ 

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+    

+ 

+  @param byte_count

+    The byte_count parameter specifies the number of bytes that must be

+    transferred by the SPI hardware block considering that a transaction has

+    been completed.

+  

+  Example:

+  @code

+  uint32_t transfer_size;

+  uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };

+  

+  transfer_size = sizeof(tx_buffer);

+  

+  MSS_SPI_disable( &g_mss_spi0 );

+  

+  MSS_SPI_set_transfer_byte_count( &g_mss_spi0, transfer_size );

+  

+  PDMA_start( PDMA_CHANNEL_0, (uint32_t)tx_buffer, 0x40011014, transfer_size );

+  

+  MSS_SPI_enable( &g_mss_spi0 );

+  

+  while ( !MSS_SPI_tx_done( &g_mss_spi0) )

+  {

+      ;

+  }

+  @endcode

+ */

+static __INLINE void MSS_SPI_set_transfer_byte_count

+(

+    mss_spi_instance_t * this_spi,

+    uint16_t byte_count

+)

+{

+    const uint32_t TXRXDFCOUNT_SHIFT = 8U;

+    const uint32_t TXRXDFCOUNT_MASK = 0x00FFFF00U;

+    

+    this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~TXRXDFCOUNT_MASK) | ( (byte_count << TXRXDFCOUNT_SHIFT) & TXRXDFCOUNT_MASK);

+    this_spi->hw_reg->TXRXDF_SIZE = 8U;

+}

+

+/***************************************************************************//**

+  The MSS_SPI_tx_done() function is used to find out if a DMA controlled transfer

+  has completed.

+ 

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+  

+  Example:

+  @code

+      uint32_t transfer_size;

+      uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };

+      

+      transfer_size = sizeof(tx_buffer);

+      

+      MSS_SPI_disable( &g_mss_spi0 );

+      

+      MSS_SPI_set_transfer_byte_count( &g_mss_spi0, transfer_size );

+      

+      PDMA_start

+        (

+            PDMA_CHANNEL_0,

+            (uint32_t)tx_buffer,

+            PDMA_SPI1_TX_REGISTER,

+            transfer_size

+        );

+      

+      MSS_SPI_enable( &g_mss_spi0 );

+      

+      while ( !MSS_SPI_tx_done(&g_mss_spi0) )

+      {

+          ;

+      }

+  @endcode

+ */

+static __INLINE uint32_t MSS_SPI_tx_done

+(

+    mss_spi_instance_t * this_spi

+)

+{

+    return this_spi->hw_reg_bit->STATUS_TX_DONE;

+}

+

+/***************************************************************************//**

+  The MSS_SPI_transfer_frame() function is used by a MSS SPI master to transmit

+  and receive a frame up to 32 bits long. This function is typically used for

+  transactions with a SPI slave where the number of transmit and receive bits is

+  not divisible by 8.

+ 

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+    

+ 

+  @param tx_bits

+    The tx_bits parameter is a 32 bits word containing the value that will be

+    transmitted.

+    Note:   The bit length of the value to be transmitted to the slave must be

+            specified as the frame_bit_length parameter in a previous call to

+            the MSS_SPI_configure_master() function.

+

+  @return

+    This function returns a 32 bits word containing the value that is received

+    from the slave.

+ 

+  Example:

+  @code

+      const uint8_t frame_size = 25;

+      const uint32_t master_tx_frame = 0x0100A0E1;

+      uint32_t master_rx;

+      

+      MSS_SPI_init( &g_mss_spi0 );

+      MSS_SPI_configure_master_mode

+        (

+            &g_mss_spi0,

+            MSS_SPI_SLAVE_0,

+            MSS_SPI_MODE1,

+            MSS_SPI_PCLK_DIV_256,

+            frame_size

+         );

+     

+      MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 );

+      master_rx = MSS_SPI_transfer_frame( &g_mss_spi0, master_tx_frame );

+      MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 );

+  @endcode

+ */

+uint32_t MSS_SPI_transfer_frame

+(

+    mss_spi_instance_t * this_spi,

+    uint32_t tx_bits

+);

+

+/***************************************************************************//**

+  The MSS_SPI_transfer_block() function is used by MSS SPI masters to transmit

+  and receive blocks of data organized as a specified number of bytes. It can be

+  used for:

+    • Writing a data block to a slave

+    • Reading a data block from a slave

+    • Sending a command to a slave followed by reading the outcome of the

+      command in a single SPI transaction. This function can be used alongside

+      Peripheral DMA functions to perform the actual moving to and from the SPI

+      hardware block using Peripheral DMA.

+ 

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+    

+ 

+  @param cmd_buffer

+    The cmd_buffer parameter is a pointer to the buffer containing the data that

+    will be sent by the master from the beginning of the transfer. This pointer

+    can be null (0) if the master does not need to send a command before reading

+    data or if the command part of the transfer is written to the SPI hardware

+    block using DMA.

+ 

+  @param cmd_byte_size

+    The cmd_byte_size parameter specifies the number of bytes contained in

+    cmd_buffer that will be sent. A value of 0 indicates that no data needs to

+    be sent to the slave. A non-zero value while the cmd_buffer pointer is 0 is

+    used to indicate that the command data will be written to the SPI hardware

+    block using DMA.

+ 

+  @param rd_buffer

+    The rd_buffer parameter is a pointer to the buffer where the data received

+    from the slave after the command has been sent will be stored.

+ 

+  @param rd_byte_size

+    The rd_byte_size parameter specifies the number of bytes to be received from

+    the slave and stored in the rd_buffer. A value of 0 indicates that no data

+    is to be read from the slave. A non-zero value while the rd_buffer pointer

+    is null (0) is used to specify the receive size when using DMA to read from

+    the slave. 

+    Note:   All bytes received from the slave, including the bytes received

+            while the command is sent, will be read through DMA.

+  

+  Polled write transfer example:

+  @code

+      uint8_t master_tx_buffer[MASTER_TX_BUFFER] = 

+      {

+          0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A

+      };

+      MSS_SPI_init( &g_mss_spi0 );

+      MSS_SPI_configure_master_mode

+        (

+            &g_mss_spi0,

+            MSS_SPI_SLAVE_0,

+            MSS_SPI_MODE1,

+            MSS_SPI_PCLK_DIV_256,

+            MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE

+         );

+     

+      MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 );

+      MSS_SPI_transfer_block

+        (

+            &g_mss_spi0,

+            master_tx_buffer,

+            sizeof(master_tx_buffer),

+            0,

+            0

+        );

+      MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 );

+  @endcode

+ 

+  DMA transfer example:

+  In this example the transmit and receive buffers are not specified as part of

+  the call to MSS_SPI_transfer_block(). MSS_SPI_transfer_block() will only

+  prepare the MSS SPI hardware for a transfer. The MSS SPI transmit hardware

+  FIFO is filled using one DMA channel and a second DMA channel is used to read

+  the content of the MSS SPI receive hardware FIFO. The transmit and receive

+  buffers are specified by two separate calls to PDMA_start() to initiate DMA

+  transfers on the channel used for transmit data and the channel used for

+  receive data. 

+  @code

+      uint8_t master_tx_buffer[MASTER_RX_BUFFER] =

+      {

+          0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA

+      };

+      uint8_t slave_rx_buffer[MASTER_RX_BUFFER] = 

+      {

+          0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A

+      };

+      MSS_SPI_init( &g_mss_spi0 );

+

+      MSS_SPI_configure_master_mode

+          (

+            &g_mss_spi0,

+            MSS_SPI_SLAVE_0,

+            MSS_SPI_MODE1,

+            MSS_SPI_PCLK_DIV_256,

+            MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE

+         );

+      MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 );

+      MSS_SPI_transfer_block( &g_mss_spi0, 0, 0, 0, 0 );

+      PDMA_start

+        (

+            PDMA_CHANNEL_1,

+            PDMA_SPI0_RX_REGISTER,

+            (uint32_t)master_rx_buffer,

+            sizeof(master_rx_buffer)

+        ); 

+      PDMA_start

+        (

+            PDMA_CHANNEL_2,

+            (uint32_t)master_tx_buffer,

+            PDMA_SPI0_TX_REGISTER,

+            sizeof(master_tx_buffer)

+        ); 

+      while( PDMA_status(PDMA_CHANNEL_1) == 0 )

+      {

+          ;

+      }

+      MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 );

+  @endcode

+ */

+void MSS_SPI_transfer_block

+(

+    mss_spi_instance_t * this_spi,

+    const uint8_t * cmd_buffer,

+    uint16_t cmd_byte_size,

+    uint8_t * rd_buffer,

+    uint16_t rd_byte_size

+);

+

+/*==============================================================================

+ * Slave functions

+ *============================================================================*/

+

+/***************************************************************************//**

+  The MSS_SPI_set_frame_rx_handler() function is used by MSS SPI slaves to

+  specify the receive handler function that will be called by the MSS SPI driver

+  interrupt handler when a a frame of data is received by the MSS SPI slave.

+  

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+    

+ 

+  @param rx_handler

+    The rx_handler parameter is a pointer to the frame receive handler that must

+    be called when a frame is received by the MSS SPI slave.

+ 

+  Example:

+  @code

+      uint32_t g_slave_rx_frame = 0;

+

+      void slave_frame_handler( uint32_t rx_frame )

+      {

+          g_slave_rx_frame = rx_frame;

+      }

+

+      int setup_slave( void )

+      {

+          const uint16_t frame_size = 25;

+          MSS_SPI_init( &g_mss_spi1 );

+          MSS_SPI_configure_slave_mode

+            (

+                &g_mss_spi0,

+                MSS_SPI_MODE2,

+                MSS_SPI_PCLK_DIV_64,

+                frame_size

+            );

+          MSS_SPI_set_frame_rx_handler( &g_mss_spi1, slave_frame_handler );

+      }

+  @endcode

+ */

+void MSS_SPI_set_frame_rx_handler

+(

+    mss_spi_instance_t * this_spi,

+    mss_spi_frame_rx_handler_t rx_handler

+);

+

+/***************************************************************************//**

+  The MSS_SPI_set_slave_tx_frame() function is used by MSS SPI slaves to specify

+  the frame that will be transmitted when a transaction is initiated by the SPI

+  master.

+  

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+    

+ 

+  @param frame_value

+    The frame_value parameter contains the value of the frame to be sent to the

+    master.

+    Note:   The bit length of the value to be transmitted to the master must be

+            specified as the frame_bit_length parameter in a previous call to

+            the MSS_SPI_configure_slave() function.

+

+  Example:

+  @code

+      const uint16_t frame_size = 25;

+      const uint32_t slave_tx_frame = 0x0110F761;

+      uint32_t master_rx;

+

+      MSS_SPI_init( &g_mss_spi1 );

+      MSS_SPI_configure_slave_mode

+        (

+            &g_mss_spi0,

+            MSS_SPI_MODE2,

+            MSS_SPI_PCLK_DIV_64,

+            frame_size

+        );

+      MSS_SPI_set_slave_tx_frame( &g_mss_spi1, slave_tx_frame );

+  @endcode

+ */

+void MSS_SPI_set_slave_tx_frame

+(

+    mss_spi_instance_t * this_spi,

+    uint32_t frame_value

+);

+

+/***************************************************************************//**

+  The MSS_SPI_set_slave_block_buffers() function is used to configure an MSS

+  SPI slave for block transfer operations. It specifies one or more of the

+  following:

+    • The data that will be transmitted when accessed by a master.

+    • The buffer where data received from a master will be stored.

+    • The handler function that must be called after the receive buffer has been

+      filled.

+    • The number of bytes that must be received from the master before the receive

+      handler function is called.

+  These parameters allow the following use cases:

+    • Slave performing an action after receiving a block of data from a master

+      containing a command. The action will be performed by the receive handling

+      based on the content of the receive data buffer.

+    • Slave returning a block of data to the master. The type of information is

+      always the same but the actual values change over time. For example,

+      returning the voltage of a predefined set of analog inputs.

+    • Slave returning data based on a command contained in the first part of the

+      SPI transaction. For example, reading the voltage of the analog input

+      specified by the first data byte by the master. This is achieved by setting

+      the rx_buff_size parameter to the number of received bytes making up the

+      command.

+  

+  @param this_spi

+    The this_spi parameter is a pointer to an mss_spi_instance_t structure

+    identifying the MSS SPI hardware block to be initialized. There are two such

+    data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and

+    MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0

+    or g_mss_spi1 global data structure defined within the SPI driver.

+    

+ 

+  @param tx_buffer

+    The tx_buffer parameter is a pointer to a buffer containing the data that

+    will be sent to the master. This parameter can be set to 0 if the MSS SPI

+    slave is not intended to be the target of SPI read transactions or if DMA

+    is used to transfer SPI read data into the MSS SPI slave.

+ 

+  @param tx_buff_size

+    The tx_buff_size parameter specifies the number of bytes contained in the

+    tx_buffer. This parameter can be set to 0 if the MSS SPI slave is not

+    intended to be the target of SPI read transactions or if DMA is used to

+    transfer SPI read data into the MSS SPI slave.

+ 

+  @param rx_buffer

+    The rx_buffer parameter is a pointer to the buffer where data received from

+    the master will be stored. This parameter can be set to 0 if the MSS SPI

+    slave is not intended to be the target of SPI write or write-read

+    transactions. It can also set to 0 if the MSS SPI slave uses DMA to handle

+    data written to it.

+ 

+  @param rx_buff_size

+    The rx_buff_size parameter specifies the size of the receive buffer. It is

+    also the number of bytes that must be received before the receive handler

+    is called, if a receive handler is specified using the block_rx_handler

+    parameter. This parameter can be set to 0 if the MSS SPI slave is not

+    intended to be the target of SPI write or write-read transactions. It can

+    also set to 0 if the MSS SPI slave uses DMA to handle data written to it.

+ 

+  @param block_rx_handler

+    The block_rx_handler parameter is a pointer to a function that will be

+    called when the receive buffer has been filled. This parameter can be set

+    to 0 if the MSS SPI slave is not intended to be the target of SPI write or

+    write-read transactions. It can also set to 0 if the MSS SPI slave uses DMA

+    to handle data written to it.

+ 

+  Slave performing operation based on master command:

+  In this example the SPI slave is configured to receive 10 bytes of data or

+  command from the SPI slave and process the data received from the master.

+  @code

+     uint32_t nb_of_rx_handler_calls = 0;

+     

+     void spi1_block_rx_handler_b

+     (

+         uint8_t * rx_buff,

+         uint16_t rx_size

+     )

+     {

+         ++nb_of_rx_handler_calls;

+     }

+     

+     void setup_slave( void )

+     {

+         uint8_t slave_rx_buffer[10] = 

+         {

+             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

+         };

+         

+         MSS_SPI_init( &g_mss_spi1 );

+         MSS_SPI_configure_slave_mode

+            ( 

+                &g_mss_spi0,

+                MSS_SPI_MODE2,

+                MSS_SPI_PCLK_DIV_64,

+                MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE

+            );

+         

+         MSS_SPI_set_slave_block_buffers

+             (

+                 &g_mss_spi1,

+                 0,

+                 0,

+                 slave_rx_buffer,

+                 sizeof(master_tx_buffer),

+                 spi1_block_rx_handler_b

+             );

+     }

+  @endcode

+  

+  Slave responding to command example:

+  In this example the slave will return data based on a command sent by the

+  master. The first part of the transaction is handled using polled mode where

+  each byte returned to the master is written as part of the interrupt service

+  routine. The second part of the transaction, where the slave returns data

+  based on the command value, is sent using a DMA transfer initiated by the

+  receive handler. 

+  @code

+     static uint8_t g_spi1_tx_buffer_b[SLAVE_TX_BUFFER_SIZE] =

+     {

+         5, 6, 7, 8, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5

+     };

+     

+     void spi1_block_rx_handler

+     (

+         uint8_t * rx_buff,

+         uint16_t rx_size

+     )

+     {

+         if ( rx_buff[2] == 0x99 )

+         {

+             PDMA_start

+             (

+                 PDMA_CHANNEL_0,

+                 (uint32_t)g_spi1_tx_buffer_b,

+                 0x40011014,

+                 sizeof(g_spi1_tx_buffer_b)

+             );      

+         }

+     }

+     

+     void setup_slave( void )

+     {

+         uint8_t slave_preamble[8] = { 9, 10, 11, 12, 13, 14, 16, 16 };

+

+         MSS_SPI_init( &g_mss_spi1 );

+         MSS_SPI_configure_slave_mode

+            (

+                &g_mss_spi0,

+                MSS_SPI_MODE2,

+                MSS_SPI_PCLK_DIV_64,

+                MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE

+        );

+         

+         PDMA_init();

+         PDMA_configure

+              (

+                  PDMA_CHANNEL_0, 

+                  TO_SPI_1,

+                  LOW_PRIORITY | BYTE_TRANSFER | INC_SRC_ONE_BYTE

+              );

+     

+         MSS_SPI_set_slave_block_buffers

+             (

+                 &g_mss_spi1,

+                 slave_preamble,

+                 4,

+                 g_spi1_rx_buffer,

+                 sizeof(g_spi1_rx_buffer),

+                 spi1_block_rx_handler

+             );

+     }

+  @endcode

+ */

+void MSS_SPI_set_slave_block_buffers

+(

+    mss_spi_instance_t * this_spi,

+    const uint8_t * tx_buffer,

+    uint32_t tx_buff_size,

+    uint8_t * rx_buffer,

+    uint32_t rx_buff_size,

+    mss_spi_block_rx_handler_t block_rx_handler

+);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* MSS_SPI_H_*/

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.c
new file mode 100644
index 0000000..7dbb6c0
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.c
@@ -0,0 +1,458 @@
+/*******************************************************************************

+ * (c) Copyright 2007 Actel Corporation.  All rights reserved.

+ *

+ * SmartFusion Microcontroller Subsystem UART bare metal software driver

+ * implementation.

+ *

+ * SVN $Revision: 1898 $

+ * SVN $Date: 2009-12-21 17:27:57 +0000 (Mon, 21 Dec 2009) $

+ */

+#include "mss_uart.h"

+#include "../../CMSIS/mss_assert.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/*******************************************************************************

+ * defines

+ */

+#define TX_READY	    0x01U

+#define TX_COMPLETE		0U

+

+#define TX_FIFO_SIZE	16U

+

+#define FCR_TRIG_LEVEL_MASK     0xC0U

+

+#define IIRF_MASK   0x0FU

+

+/*******************************************************************************

+ * Possible values for Interrupt Identification Register Field.

+ */

+#define IIRF_MODEM_STATUS   0x00U    

+#define IIRF_THRE           0x02U

+#define IIRF_RX_DATA        0x04U

+#define IIRF_RX_LINE_STATUS 0x06U

+#define IIRF_DATA_TIMEOUT   0x0CU

+

+/*******************************************************************************

+ * Cortex-M3 interrupt handler functions implemented as part of the MSS UART

+ * driver.

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void UART0_IRQHandler( void );

+#else

+void UART0_IRQHandler( void );

+#endif

+

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void UART1_IRQHandler( void );

+#else

+void UART1_IRQHandler( void );

+#endif

+

+/*******************************************************************************

+ * Local functions.

+ */

+static void MSS_UART_isr( mss_uart_instance_t * this_uart );

+

+/*******************************************************************************

+ *

+ */

+mss_uart_instance_t g_mss_uart0;

+mss_uart_instance_t g_mss_uart1;

+

+/***************************************************************************//**

+ * UART_init.

+ * Initialises the UART with default configuration.

+ */

+void 

+MSS_UART_init

+(

+	mss_uart_instance_t* this_uart, 

+    uint32_t baud_rate,

+    uint8_t line_config

+)

+{

+    uint16_t baud_value;

+    uint32_t pclk_freq;

+

+    /* The driver expects g_mss_uart0 and g_mss_uart1 to be the only 

+     * mss_uart_instance_t instances used to identfy UART0 and UART1. */

+    ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) );

+    

+    /* Force the value of the CMSIS global variables holding the various system

+     * clock frequencies to be updated. */

+    SystemCoreClockUpdate();

+    

+    if ( this_uart == &g_mss_uart0 )

+    {

+        this_uart->hw_reg = UART0;

+        this_uart->hw_reg_bit = UART0_BITBAND;

+        this_uart->irqn = UART0_IRQn;

+

+        pclk_freq = g_FrequencyPCLK0;

+        

+        /* reset UART0 */

+        SYSREG->SOFT_RST_CR |= SYSREG_UART0_SOFTRESET_MASK;

+        /* Clear any previously pended UART0 interrupt */

+        NVIC_ClearPendingIRQ( UART0_IRQn );

+        /* Take UART0 out of reset. */

+        SYSREG->SOFT_RST_CR &= ~SYSREG_UART0_SOFTRESET_MASK;

+    }

+    else

+    {

+        this_uart->hw_reg = UART1;

+        this_uart->hw_reg_bit = UART1_BITBAND;

+        this_uart->irqn = UART1_IRQn;

+

+        pclk_freq = g_FrequencyPCLK1;

+        

+        /* Reset UART1 */

+        SYSREG->SOFT_RST_CR |= SYSREG_UART1_SOFTRESET_MASK;

+        /* Clear any previously pended UART1 interrupt */

+        NVIC_ClearPendingIRQ( UART1_IRQn );

+        /* Take UART1 out of reset. */

+        SYSREG->SOFT_RST_CR &= ~SYSREG_UART1_SOFTRESET_MASK;

+    }

+    

+    /* disable interrupts */

+    this_uart->hw_reg->IER = 0U;

+

+    /*

+     * Compute baud value based on requested baud rate and PCLK frequency.

+     * The baud value is computed using the following equation:

+     *      baud_value = PCLK_Frequency / (baud_rate * 16)

+     * The baud value is rounded up or down depending on what would be the remainder

+     * of the divide by 16 operation.

+     */

+    baud_value = (uint16_t)(pclk_freq / baud_rate);

+    if ( baud_value & 0x00000008U )

+    {

+        /* remainder above 0.5 */

+        baud_value = (baud_value >> 4U) + 1U;

+    }

+    else

+    {

+        /* remainder below 0.5 */

+        baud_value = (baud_value >> 4U);

+    }

+

+    /* set divisor latch */

+    this_uart->hw_reg_bit->LCR_DLAB = (uint32_t)1;

+

+    /* msb of baud value */

+    this_uart->hw_reg->DMR = (uint8_t)(baud_value >> 8);

+    /* lsb of baud value */

+    this_uart->hw_reg->DLR = (uint8_t)baud_value;

+

+    /* reset divisor latch */

+    this_uart->hw_reg_bit->LCR_DLAB = (uint32_t)0;

+

+    /* set the line control register (bit length, stop bits, parity) */

+    this_uart->hw_reg->LCR = line_config;

+    

+    /* FIFO configuration */

+    this_uart->hw_reg->FCR = (uint8_t)MSS_UART_FIFO_SINGLE_BYTE;

+    

+    /* disable loopback */

+    this_uart->hw_reg_bit->MCR_LOOP = (uint32_t)0;

+

+    /* Instance setup */

+    this_uart->tx_buff_size = TX_COMPLETE;

+    this_uart->tx_buffer = (const uint8_t *)0;

+    this_uart->tx_idx = 0U;

+    

+    this_uart->rx_handler = (mss_uart_rx_handler_t)0;

+}

+

+/***************************************************************************//**

+ * See mss_uart.h for details of how to use this function.

+ */

+void 

+MSS_UART_polled_tx

+( 

+	mss_uart_instance_t * this_uart, 

+	const uint8_t * pbuff,

+	uint32_t tx_size

+)

+{

+	uint32_t char_idx;

+	uint32_t status;

+

+    ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) );

+    

+    for ( char_idx = 0U; char_idx < tx_size; char_idx++ )

+    {

+        /* Wait for UART to become ready to transmit. */

+        do {

+            status = this_uart->hw_reg_bit->LSR_THRE;

+        } while ( (status & TX_READY) == 0U );

+        /* Send next character in the buffer. */

+        this_uart->hw_reg->THR = pbuff[char_idx];

+    }

+}

+

+/***************************************************************************//**

+ * See mss_uart.h for details of how to use this function.

+ */

+void 

+MSS_UART_polled_tx_string

+( 

+	mss_uart_instance_t * this_uart, 

+	const uint8_t * p_sz_string

+)

+{

+	uint32_t char_idx;

+	uint32_t status;

+

+    ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) );

+    

+    char_idx = 0U;

+    

+    while ( p_sz_string[char_idx] != 0U )

+    {

+        /* Wait for UART to become ready to transmit. */

+        do {

+            status = this_uart->hw_reg_bit->LSR_THRE;

+        } while ( (status & TX_READY) == 0U);

+        /* Send next character in the buffer. */

+        this_uart->hw_reg->THR = p_sz_string[char_idx];

+        ++char_idx;

+    }

+}

+

+/***************************************************************************//**

+ * See mss_uart.h for details of how to use this function.

+ */

+void 

+MSS_UART_irq_tx

+( 

+	mss_uart_instance_t * this_uart, 

+	const uint8_t * pbuff,

+	uint32_t tx_size

+)

+{

+    ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) );

+    

+    if ( tx_size > 0U )

+    {

+        /*Initialise the transmit info for the UART instance with the arguments.*/

+        this_uart->tx_buffer = pbuff;

+        this_uart->tx_buff_size = tx_size;

+        this_uart->tx_idx = (uint16_t)0;

+                

+        /* enables TX interrupt */

+        this_uart->hw_reg_bit->IER_ETBEI = (uint32_t)1;

+        

+        /* Enable UART instance interrupt in Cortex-M3 NVIC. */

+        NVIC_EnableIRQ( this_uart->irqn );

+    }

+}

+

+/***************************************************************************//**

+ * See mss_uart.h for details of how to use this function.

+ */

+int8_t 

+MSS_UART_tx_complete

+( 

+	mss_uart_instance_t * this_uart 

+)

+{

+    int8_t ret_value = 0;

+    uint32_t transmit_empty = this_uart->hw_reg_bit->LSR_TEMT;

+    

+    ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) );

+

+    if ( ( TX_COMPLETE == this_uart->tx_buff_size ) && transmit_empty )

+    {

+        ret_value = 1;

+    }

+    

+    return ret_value;

+}

+

+

+/***************************************************************************//**

+ * See mss_uart.h for details of how to use this function.

+ */

+size_t

+MSS_UART_get_rx

+(

+    mss_uart_instance_t * this_uart,

+    uint8_t * rx_buff,

+    size_t buff_size

+)

+{

+    size_t rx_size = 0U;

+    

+    ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) );

+

+    while (( this_uart->hw_reg_bit->LSR_DR != 0U) && ( rx_size < buff_size ) )

+    {

+        rx_buff[rx_size] = this_uart->hw_reg->RBR;

+        ++rx_size;

+    }

+               

+    return rx_size;

+}

+

+/***************************************************************************//**

+ * Interrupt service routine triggered by the Transmitter Holding Register

+ * Empty (THRE) interrupt or Received Data Available (RDA). 

+ * On THRE irq this routine will transmit the data from the transmit buffer. 

+ * When all bytes are transmitted, this routine disables the THRE interrupt

+ * and resets the transmit counter.

+ * On RDA irq this routine will call the user's receive handler routine previously

+ * registered with the UART driver through a call to UART_set_rx_handler().

+ */

+static void 

+MSS_UART_isr

+( 

+	mss_uart_instance_t * this_uart 

+)

+{

+	uint8_t iirf;

+    uint32_t tx_empty;

+	

+    ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) );

+

+    iirf = this_uart->hw_reg->IIR & IIRF_MASK;

+   

+    switch ( iirf )

+    {

+    case IIRF_MODEM_STATUS:

+        break;

+        

+    case IIRF_THRE: /* Transmitter Holding Register Empty */

+        tx_empty = this_uart->hw_reg_bit->LSR_TEMT;

+        

+        if ( tx_empty )

+        {

+            uint32_t i;

+            uint32_t fill_size = TX_FIFO_SIZE;

+            uint32_t tx_remain = this_uart->tx_buff_size - this_uart->tx_idx;

+            if ( tx_remain < TX_FIFO_SIZE )

+            {

+                fill_size = tx_remain;

+            }

+            /* Fill up FIFO */

+            for ( i = 0U; i < fill_size; ++i )

+            {

+                this_uart->hw_reg->THR = this_uart->tx_buffer[this_uart->tx_idx];

+                ++this_uart->tx_idx;

+            }

+        }

+        else

+        {

+            this_uart->hw_reg->THR = this_uart->tx_buffer[this_uart->tx_idx];

+            ++this_uart->tx_idx;

+        }

+        

+        if ( this_uart->tx_idx == this_uart->tx_buff_size )

+        {

+            this_uart->tx_buff_size = TX_COMPLETE;

+            /* disables TX interrupt */

+            this_uart->hw_reg_bit->IER_ETBEI = 0U;

+        }

+        break;

+        

+    case IIRF_RX_DATA:          /* Received Data Available */

+    case IIRF_DATA_TIMEOUT:

+        if (this_uart->rx_handler != 0)

+        {

+            (*(this_uart->rx_handler))();

+        }

+        break;

+        

+    case IIRF_RX_LINE_STATUS:

+        break;

+        

+    default:

+        /* Disable other interrupts */

+        this_uart->hw_reg_bit->IER_ELSI = 0U;

+        this_uart->hw_reg_bit->IER_EDSSI = 0U;

+        break;

+    }

+}

+

+/***************************************************************************//**

+ * See mss_uart.h for details of how to use this function.

+ */

+void

+MSS_UART_set_rx_handler

+(

+	mss_uart_instance_t *       this_uart,

+    mss_uart_rx_handler_t       handler,

+    mss_uart_rx_trig_level_t    trigger_level

+)

+{

+    ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) );

+    

+    this_uart->rx_handler = handler;

+    

+    /* Set the receive interrupt trigger level. */

+    this_uart->hw_reg->FCR = (this_uart->hw_reg->FCR & (uint8_t)(~((uint8_t)FCR_TRIG_LEVEL_MASK))) | (uint8_t)trigger_level;

+    

+    /* Enable receive interrupt. */

+    this_uart->hw_reg_bit->IER_ERBFI = 1U;

+    

+    /* Enable UART instance interrupt in Cortex-M3 NVIC. */

+    NVIC_EnableIRQ( this_uart->irqn );

+}

+

+/***************************************************************************//**

+ * See mss_uart.h for details of how to use this function.

+ */

+void

+MSS_UART_set_loopback

+(

+	mss_uart_instance_t *   this_uart,

+	mss_uart_loopback_t     loopback

+)

+{

+    ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) );

+    

+    if ( loopback == MSS_UART_LOOPBACK_OFF )

+    {

+        this_uart->hw_reg_bit->MCR_LOOP = 0U;

+    }

+    else

+    {

+        this_uart->hw_reg_bit->MCR_LOOP = 1U;

+    }

+}

+

+/***************************************************************************//**

+ * UART0 interrupt service routine.

+ * UART0_IRQHandler is included within the Cortex-M3 vector table as part of the

+ * Fusion 2 CMSIS.

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void UART0_IRQHandler( void )

+#else

+void UART0_IRQHandler( void )

+#endif

+{

+    MSS_UART_isr( &g_mss_uart0 );

+    NVIC_ClearPendingIRQ( UART0_IRQn );

+}

+

+/***************************************************************************//**

+ * UART1 interrupt service routine.

+ * UART2_IRQHandler is included within the Cortex-M3 vector table as part of the

+ * Fusion 2 CMSIS.

+ */

+#if defined(__GNUC__)

+__attribute__((__interrupt__)) void UART1_IRQHandler( void )

+#else

+void UART1_IRQHandler( void )

+#endif

+{

+    MSS_UART_isr( &g_mss_uart1 );

+    NVIC_ClearPendingIRQ( UART1_IRQn );

+}

+

+#ifdef __cplusplus

+}

+#endif

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.h
new file mode 100644
index 0000000..3897a3c
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.h
@@ -0,0 +1,626 @@
+/*******************************************************************************

+ * (c) Copyright 2007 Actel Corporation.  All rights reserved.

+ *

+ * SmartFusion Microcontroller Subsystem UART bare metal software driver public API.

+ *

+ * SVN $Revision: 1942 $

+ * SVN $Date: 2009-12-22 17:48:07 +0000 (Tue, 22 Dec 2009) $

+ */

+/*=========================================================================*//**

+  @mainpage SmartFusion MSS UART Bare Metal Driver.

+

+  @section intro_sec Introduction

+  The SmartFusion MicroController Subsystem (MSS) includes two UART peripherals

+  for serial communications.

+  This driver provides a set of functions for controlling the MSS UARTs as part

+  of a bare metal system where no operating system is available. These drivers

+  can be adapted for use as part of an operating system but the implementation

+  of the adaptation layer between this driver and the operating system's driver

+  model is outside the scope of this driver.

+  

+  @section hw_dependencies Hardware Flow Dependencies

+  The configuration of all features of the MSS UARTs is covered by this driver

+  with the exception of the SmartFusion IOMUX configuration. SmartFusion allows

+  multiple non-concurrent uses of some external pins through IOMUX configuration.

+  This feature allows optimization of external pin usage by assigning external

+  pins for use by either the microcontroller subsystem or the FPGA fabric. The

+  MSS UARTs serial signals are routed through IOMUXes to the SmartFusion device

+  external pins. These IOMUXes are configured automatically by the MSS

+  configurator tool in the hardware flow correctly when the MSS UARTs are enabled

+  in that tool. You must ensure that the MSS UARTs are enabled by the MSS

+  configurator tool in the hardware flow; otherwise the serial inputs and outputs

+  will not be connected to the chip's external pins. For more information on

+  IOMUX, refer to the IOMUX section of the SmartFusion Datasheet.

+  The base address, register addresses and interrupt number assignment for the MSS

+  UART blocks are defined as constants in the SmartFusion CMSIS-PAL You must ensure

+  that the SmartFusion CMSIS-PAL is either included in the software tool chain used

+  to build your project or is included in your project.

+

+  

+  @section theory_op Theory of Operation

+  The MSS UART driver uses the SmartFusion "Cortex Microcontroler Software

+  Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access hadware

+  registers. You must ensure that the SmartFusion CMSIS-PAL is either included

+  in the software toolchain used to build your project or is included in your

+  project. The most up to date SmartFusion CMSIS-PAL files can be obtained using

+  the Actel Firmware Catalog.

+  

+  The MSS UART driver functions are logically grouped into three groups:

+    - Initialization functions

+    - Polled transmit and receive functions

+    - Interrupt driven transmit and receive functions

+  

+  The MSS UART driver is initialized through a call to the UART_init() function.

+  This function takes the UART's configuration as parameters. The UART_init()

+  function must be called before any other UART driver functions can be called.

+  The first parameter of the UART_init() function is a pointer to one of two

+  global data structures used to store state information for each UART driver.

+  A pointer to these data structures is also used as first parameter to any of

+  the driver functions to identify which UART will be used by the called

+  function. The name of these two data structures are g_mss_uart0 and

+  g_mss_uart1. Therefore any call to a MSS UART function should be of the form

+  UART_function_name( &g_mss_uart0, ... ) or UART_function_name( &g_mss_uart1, ... ).

+  The two SmartFusion MSS UARTs can also be configured to loop back to each

+  other using the MSS_set_loopback() function for debugging purposes.

+  

+  Polled operations where the processor constantly poll the UART registers state

+  in order to control data transmit or data receive is performed using functions:

+    - MSS_UART_polled_tx()

+    - MSS_UART_get_rx()

+  

+  Interrupt driven operations where the processor sets up transmit or receive

+  then returns to performing some other operation until an interrupts occurs

+  indicating that its attention is required is performed using functions:

+    - MSS_UART_irq_tx()

+    - MSS_UART_tx_complete()

+    - MSS_UART_set_rx_handler()

+    - MSS_UART_get_rx()

+  Interrupt driven transmit is initiated by a call to MSS_UART_irq_tx() specifying

+  the block of data to transmit. The processor can then perform some other

+  operation and later inquire whether transmit has completed by calling the

+  MSS_UART_tx_complete() function.

+  Interrupt driven receive is performed by first registering a receive handler

+  function that will be called by the driver whenever receive data is available.

+  This receive handler function in turns calls the MSS_UART_get_rx() function to

+  actually read the received data.

+  

+ *//*=========================================================================*/

+#ifndef __MSS_UART_H_

+#define __MSS_UART_H_ 1

+

+#include "../../CMSIS/a2fxxxm3.h"

+#include <stddef.h>

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+/***************************************************************************//**

+  Baud rates.

+  The following definitions are used to specify standard baud rates as a

+  parameter to the MSS_UART_init() function.

+ */

+#define MSS_UART_110_BAUD       110

+#define MSS_UART_300_BAUD       300

+#define MSS_UART_1200_BAUD      1200

+#define MSS_UART_2400_BAUD      2400

+#define MSS_UART_4800_BAUD      4800

+#define MSS_UART_9600_BAUD      9600

+#define MSS_UART_19200_BAUD     19200

+#define MSS_UART_38400_BAUD     38400

+#define MSS_UART_57600_BAUD     57600

+#define MSS_UART_115200_BAUD    115200

+#define MSS_UART_230400_BAUD    230400

+#define MSS_UART_460800_BAUD    460800

+#define MSS_UART_921600_BAUD    921600

+

+/***************************************************************************//**

+  Data bits length values.

+ 

+  The following defines are used to build the value of the MSS_UART_init()

+  function line_config parameter.

+ */

+#define MSS_UART_DATA_5_BITS     0x00

+#define MSS_UART_DATA_6_BITS     0x01

+#define MSS_UART_DATA_7_BITS     0x02

+#define MSS_UART_DATA_8_BITS     0x03

+

+/***************************************************************************//**

+  Parity values

+  The following defines are used to build the value of the MSS_UART_init()

+  function line_config parameter.

+ */

+#define MSS_UART_NO_PARITY           0x00

+#define MSS_UART_ODD_PARITY          0x08

+#define MSS_UART_EVEN_PARITY         0x18

+#define MSS_UART_STICK_PARITY_0      0x38

+#define MSS_UART_STICK_PARITY_1      0x28

+

+/***************************************************************************//**

+  Stop bit values

+  The following defines are used to build the value of the MSS_UART_init()

+  function line_config parameter.

+ */

+#define MSS_UART_ONE_STOP_BIT        0x00

+#define MSS_UART_ONEHALF_STOP_BIT    0x04

+#define MSS_UART_TWO_STOP_BITS       0x04

+

+/***************************************************************************//**

+  FIFO trigger sizes

+  This enumeration specifies the number of bytes that must be received before a

+  receive interrupt is generated. This enumeration provides the allowed values for

+  the MSS_UART_set_rx_handler() function trigger_level parameter.

+ */

+typedef enum __mss_uart_rx_trig_level_t {

+    MSS_UART_FIFO_SINGLE_BYTE    = 0x00,

+    MSS_UART_FIFO_FOUR_BYTES     = 0x40,

+    MSS_UART_FIFO_EIGHT_BYTES    = 0x80,

+    MSS_UART_FIFO_FOURTEEN_BYTES = 0xC0

+} mss_uart_rx_trig_level_t;

+

+/***************************************************************************//**

+  Loopback.

+  This enumeration is used as parameter to function MSS_UART_set_loopback(). It

+  specifies the loopback configuration of the UARTs. Using MSS_UART_LOOPBACK_ON

+  as parameter to function MSS_UART_set_loopback() will set up the UART to locally

+  loopback its Tx and Rx lines.

+ */

+typedef enum __mss_uart_loopback_t {

+    MSS_UART_LOOPBACK_OFF   = 0,

+    MSS_UART_LOOPBACK_ON    = 1

+} mss_uart_loopback_t;

+

+/***************************************************************************//**

+  Receive handler prototype.

+  This typedef specifies the prototype of functions that can be registered with

+  this driver as receive handler functions.

+ */

+typedef void (*mss_uart_rx_handler_t)(void);

+

+/***************************************************************************//**

+  mss_uart_instance_t.

+ 

+  There is one instance of this structure for each instance of the Microcontroller

+  Subsystem's UARTs. Instances of this structure are used to identify a specific

+  UART. A pointer to an instance of the mss_uart_instance_t structure is passed

+  as the first parameter to MSS UART driver functions to identify which UART

+  should perform the requested operation.

+ */

+typedef struct {

+    /* CMSIS related defines identifying the UART hardware. */

+    UART_TypeDef *          hw_reg;     /*!< Pointer to UART registers. */

+    UART_BitBand_TypeDef *  hw_reg_bit; /*!< Pointer to UART registers bit band area. */

+    IRQn_Type               irqn;       /*!< UART's Cortex-M3 NVIC interrupt number. */

+    

+	/* transmit related info (used with interrupt driven trnasmit): */

+	const uint8_t * tx_buffer;          /*!< Pointer to transmit buffer. */

+	uint32_t        tx_buff_size;       /*!< Transmit buffer size. */

+	uint32_t        tx_idx;             /*!< Index within trnamit buffer of next byte to transmit.*/

+	

+    /* receive interrupt handler:*/

+    mss_uart_rx_handler_t rx_handler;   /*!< Pointer to user registered received handler. */

+} mss_uart_instance_t;

+

+/***************************************************************************//**

+  This instance of mss_uart_instance_t holds all data related to the operations

+  performed by UART0. A pointer to g_mss_uart0 is passed as the first parameter

+  to MSS UART driver functions to indicate that UART0 should perform the requested

+  operation.

+ */

+extern mss_uart_instance_t g_mss_uart0;

+

+/***************************************************************************//**

+  This instance of mss_uart_instance_t holds all data related to the operations

+  performed by UART1. A pointer to g_mss_uart1 is passed as the first parameter

+  to MSS UART driver functions to indicate that UART1 should perform the requested

+  operation.

+ */

+extern mss_uart_instance_t g_mss_uart1;

+

+/***************************************************************************//**

+  The MSS_UART_init() function initializes and configures one of the SmartFusion

+  MSS UARTs with the configuration passed as a parameter. The configuration

+  parameters are the baud_rate which is used to generate the baud value and the

+  line_config which is used to specify the line configuration (bit length, stop

+  bits and parity).

+ 

+  Example:

+  @code

+  #include "mss_uart.h"

+ 

+  int main(void)

+  {

+      MSS_UART_init

+        (

+            &g_mss_uart0,

+            MSS_UART_57600_BAUD,

+            MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT

+        );

+      return(0);

+  }

+  @endcode

+ 

+  @param this_uart

+    The this_uart parameter is a pointer to an mss_uart_instance_t structure

+    identifying the MSS UART hardware block to be initialized. There are two

+    such data structures, g_mss_uart0 and g_mss_uart1, associated with MSS UART0

+    and MSS UART1 respectively. This parameter must point to either the

+    g_mss_uart0 or g_mss_uart1 global data structure defined within the UART

+    driver.

+    

+ 

+  @param baud_rate

+    The baud_rate parameter specifies the baud rate. It can be specified for

+    common baud rates' using the following defines:

+        - MSS_UART_110_BAUD

+        - MSS_UART_300_BAUD

+        - MSS_UART_1200_BAUD

+        - MSS_UART_2400_BAUD

+        - MSS_UART_4800_BAUD

+        - MSS_UART_9600_BAUD

+        - MSS_UART_19200_BAUD

+        - MSS_UART_38400_BAUD

+        - MSS_UART_57600_BAUD

+        - MSS_UART_115200_BAUD

+        - MSS_UART_230400_BAUD

+        - MSS_UART_460800_BAUD

+        - MSS_UART_921600_BAUD 

+    Alternatively, any non standard baud rate can be specified by simply passing

+    the actual required baud rate as value for this parameter.

+ 

+  @param line_config

+    The line_config parameter is the line configuration specifying the bit length,

+    number of stop bits and parity settings. This is a logical OR of one of the

+    following to specify the transmit/receive data bit length: 

+       - MSS_UART_DATA_5_BITS

+       - MSS_UART_DATA_6_BITS,

+       - MSS_UART_DATA_7_BITS

+       - MSS_UART_DATA_8_BITS

+    with one of the following to specify the parity setting:

+       - MSS_UART_NO_PARITY

+       - MSS_UART_EVEN_PARITY

+       - MSS_UART_ODD_PARITY

+       - MSS_UART_STICK_PARITY_0

+       - MSS_UART_STICK_PARITY_1

+    with one of the following to specify the number of stop bits:

+       - MSS_UART_ONE_STOP_BIT

+       - MSS_UART_ONEHALF_STOP_BIT

+       - MSS_UART_TWO_STOP_BITS

+ 

+  @return

+    This function does not return a value.

+ */

+void

+MSS_UART_init

+(

+	mss_uart_instance_t* this_uart,

+    uint32_t baud_rate,

+    uint8_t line_config

+);

+

+/***************************************************************************//**

+  The function MSS_UART_polled_tx() is used to transmit data. It transfers the

+  contents of the transmitter data buffer, passed as a function parameter, into

+  the UART's hardware transmitter FIFO. It returns when the full content of the

+  transmit data buffer has been transferred to the UART's transmit FIFO. 

+ 

+  @param this_uart

+    The this_uart parameter is a pointer to an mss_uart_instance_t structure

+    identifying the MSS UART hardware block that will perform the requested

+    function. There are two such data structures, g_mss_uart0 and g_mss_uart1,

+    associated with MSS UART0 and MSS UART1. This parameter must point to either

+    the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART

+    driver.

+ 

+  @param pbuff

+    The pbuff parameter is a pointer to a buffer containing the data to be

+    transmitted.

+ 

+  @param tx_size

+    The tx_size parameter specifies the size, in bytes, of the data to be

+    transmitted.

+ 

+  @return				This function does not return a value.

+ */

+void 

+MSS_UART_polled_tx

+( 

+	mss_uart_instance_t * this_uart, 

+	const uint8_t * pbuff,

+	uint32_t tx_size

+);

+

+/***************************************************************************//**

+  The function MSS_UART_polled_tx_string() is used to transmit a zero-terminated

+  string. It transfers the text found starting at the address pointed to by

+  p_sz_string into the UART's hardware transmitter FIFO. It returns when the

+  complete string has been transferred to the UART's transmit FIFO. 

+ 

+  @param this_uart

+    The this_uart parameter is a pointer to an mss_uart_instance_t structure

+    identifying the MSS UART hardware block that will perform the requested

+    function. There are two such data structures, g_mss_uart0 and g_mss_uart1,

+    associated with MSS UART0 and MSS UART1. This parameter must point to either

+    the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART

+    driver.

+ 

+  @param p_sz_string

+    The p_sz_string parameter is a pointer to a buffer containing the

+    zero-terminated string to be transmitted.

+ 

+  @return				This function does not return a value.

+ */

+void 

+MSS_UART_polled_tx_string

+( 

+	mss_uart_instance_t * this_uart, 

+	const uint8_t * p_sz_string

+);

+

+

+/***************************************************************************//**

+  The function MSS_UART_irq_tx() is used to initiate interrupt driven transmit. It

+  returns immediately after making a note of the transmit buffer location and

+  enabling transmit interrupts both at the UART and Cortex-M3 NVIC level.

+  This function takes a pointer to a memory buffer containing the data to

+  transmit as parameter. The memory buffer specified through this pointer

+  should remain allocated and contain the data to transmit until the transmit

+  completion has been detected through calls to function MSS_UART_tx_complete().

+  NOTE: The MSS_UART_irq_tx() function also enables the Transmitter Holding

+  Register Empty (THRE) interrupt and the UART instance interrupt in the

+  Cortex-M3 NVIC as part of its implementation.

+  

+  Example:

+  @code

+  #include "mss_uart.h"

+ 

+  int main(void)

+  {

+      uint8_t tx_buff[10] = "abcdefghi";

+      MSS_UART_init( &g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );

+      MSS_UART_irq_tx( &g_mss_uart0, tx_buff, sizeof(tx_buff));

+      while ( 0 == MSS_UART_tx_complete( &g_mss_uart0 ) )

+      {

+          ;

+      }

+      return(0);

+  }

+  @endcode

+ 

+  @param this_uart

+    The this_uart parameter is a pointer to an mss_uart_instance_t structure

+    identifying the MSS UART hardware block that will perform the requested

+    function. There are two such data structures, g_mss_uart0 and g_mss_uart1,

+    associated with MSS UART0 and MSS UART1. This parameter must point to either

+    the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART

+    driver.

+ 

+  @param pbuff

+    The pbuff parameter is a pointer to a buffer containing the data to be

+    transmitted.

+ 

+  @param tx_size

+    The tx_size parameter specifies the size, in bytes, of the data to be

+    transmitted.

+ 

+  @return

+    This function does not return a value.

+ */

+void 

+MSS_UART_irq_tx

+( 

+	mss_uart_instance_t * this_uart, 

+	const uint8_t * pbuff,

+	uint32_t tx_size

+);

+

+/***************************************************************************//**

+  The MSS_UART_tx_complete() function is used to find out if interrupt driven

+  transmit previously initiated through a call to MSS_UART_irq_tx() is complete.

+  This is typically used to find out when it is safe to reuse or release the

+  memory buffer holding transmit data.

+ 

+  @param this_uart

+    The this_uart parameter is a pointer to an mss_uart_instance_t structure

+    identifying the MSS UART hardware block that will perform the requested

+    function. There are two such data structures, g_mss_uart0 and g_mss_uart1,

+    associated with MSS UART0 and MSS UART1. This parameter must point to either

+    the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART

+    driver.

+ 

+  @return

+    This function return a non-zero value if transmit has completed, otherwise

+    it returns zero.

+ 

+  Example:

+    See the MSS_UART_irq_tx() function for an example that uses the

+    MSS_UART_tx_complete() function.

+ */

+int8_t

+MSS_UART_tx_complete

+(

+   mss_uart_instance_t * this_uart

+);

+

+/***************************************************************************//**

+  The MSS_UART_get_rx() function is used to read the content of a UART's receive

+  FIFO. It can be used in polled mode where it is called at regular interval

+  to find out if any data has been received or in interrupt driven mode where

+  it is called as part of a receive handler called by the driver as a result of

+  data being received. This function is non-blocking and will return 0

+  immediately if no data has been received.

+  NOTE: In interrupt driven mode you should call the MSS_UART_get_rx() function

+  as part of the receive handler function that you register with the MSS UART

+  driver through a call to MSS_UART_set_rx_handler().

+ 

+  @param this_uart

+    The this_uart parameter is a pointer to an mss_uart_instance_t structure

+    identifying the MSS UART hardware block that will perform the requested

+    function. There are two such data structures, g_mss_uart0 and g_mss_uart1,

+    associated with MSS UART0 and MSS UART1. This parameter must point to either

+    the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART

+    driver.

+ 

+  @param rx_buff

+    The rx_buff parameter is a pointer to a buffer where the received data will

+    be copied.

+ 

+  @param buff_size

+    The buff_size parameter specifies the size of the receive buffer in bytes.

+ 

+  @return

+    This function return the number of bytes that were copied into the rx_buff

+    buffer. It returns 0 if no data has been received.

+ 

+  Polled mode example:

+  @code

+   int main( void )

+   {

+      	uint8_t rx_buff[RX_BUFF_SIZE];

+      	uint32_t rx_idx  = 0;

+  

+      	MSS_UART_init( &g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );

+  

+      	while( 1 )

+      	{

+           rx_size = MSS_UART_get_rx( &g_mss_uart0, rx_buff, sizeof(rx_buff) );

+           if (rx_size > 0)

+           {

+               process_rx_data( rx_buff, rx_size );

+           }

+           task_a();

+           task_b();

+       }

+       return 0;

+   }

+  @endcode

+ 

+  Interrupt driven example:

+  @code

+   int main( void )

+   {

+      	MSS_UART_init( &g_mss_uart1, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );

+       MSS_UART_set_rx_handler( &g_mss_uart1, uart1_rx_handler, MSS_UART_FIFO_SINGLE_BYTE );

+  

+      	while( 1 )

+      	{

+           task_a();

+           task_b();

+       }

+       return 0;

+   }

+ 

+   void uart1_rx_handler( void )

+   {

+      	uint8_t rx_buff[RX_BUFF_SIZE];

+       uint32_t rx_idx  = 0;

+       rx_size = MSS_UART_get_rx( &g_mss_uart1, rx_buff, sizeof(rx_buff) );

+       process_rx_data( rx_buff, rx_size );

+   }

+  @endcode

+ */

+size_t

+MSS_UART_get_rx

+(

+   mss_uart_instance_t * this_uart,

+   uint8_t * rx_buff,

+   size_t buff_size

+);

+

+/***************************************************************************//**

+  The MSS_UART_set_rx_handler() function is used to register a receive handler

+  function which will be called by the driver when a UART Received Data Available

+  (RDA) interrupt occurs. You must create and register the handler function to

+  suit your application. The MSS_UART_set_rx_handler() function also enables the UART

+  Received Data Available interrupt and the UART instance interrupt in the

+  Cortex-M3 NVIC as part of its implementation.

+ 

+  @param this_uart

+    The this_uart parameter is a pointer to an mss_uart_instance_t structure

+    identifying the MSS UART hardware block that will perform the requested

+    function. There are two such data structures, g_mss_uart0 and g_mss_uart1,

+    associated with MSS UART0 and MSS UART1. This parameter must point to either

+    the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART

+    driver.

+ 

+  @param handler

+    The handler parameter is a pointer to a receive handler function provided

+    by your application which will be called as a result of a UART Received

+    Data Available interrupt.

+ 

+  @param trigger_level

+    The trigger_level parameter is the receive FIFO trigger level. This specifies

+    the number of bytes that must be received before the UART triggers a Received

+    Data Available interrupt. 

+                       

+  @return

+    This function does not return a value.

+    

+  Example:

+  @code

+  #include "mss_uart.h"

+ 

+  #define RX_BUFF_SIZE    64

+ 

+  uint8_t g_rx_buff[RX_BUFF_SIZE];

+ 

+  void uart0_rx_handler( void )

+  {

+      MSS_UART_get_rx( &g_mss_uart, &g_rx_buff[g_rx_idx], sizeof(g_rx_buff) );

+  }

+ 

+  int main(void)

+  {

+      MSS_UART_init( &g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );

+      MSS_UART_set_rx_handler( &g_mss_uart0, uart0_rx_handler, MSS_UART_FIFO_SINGLE_BYTE );

+ 

+      while ( 1 )

+      {

+          ;

+      }

+      return(0);

+  }

+  @endcode

+ */

+void

+MSS_UART_set_rx_handler

+(

+	mss_uart_instance_t *       this_uart,

+    mss_uart_rx_handler_t       handler,

+    mss_uart_rx_trig_level_t    trigger_level

+);

+

+/***************************************************************************//**

+  The MSS_UART_set_loopback() function is used to locally loopback the Tx and Rx

+  lines of a UART.

+  This is not to be confused with the loopback of UART0 to UART1 which can be

+  achieved through the microcontroller subsystem's system registers

+ 

+  @param this_uart

+    The this_uart parameter is a pointer to an mss_uart_instance_t structure

+    identifying the MSS UART hardware block that will perform the requested

+    function. There are two such data structures, g_mss_uart0 and g_mss_uart1,

+    associated with MSS UART0 and MSS UART1. This parameter must point to either

+    the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART

+    driver.

+ 

+  @param loopback

+    The loopback parameter indicates whether or not the UART's transmit and receive lines

+    should be looped back. Allowed values are:

+       - MSS_UART_LOOPBACK_ON

+       - MSS_UART_LOOPBACK_OFF

+  @return

+    This function does not return a value.

+ */

+void

+MSS_UART_set_loopback

+(

+	mss_uart_instance_t *   this_uart,

+	mss_uart_loopback_t     loopback

+);

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* __MSS_UART_H_ */

diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_watchdog/mss_watchdog.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_watchdog/mss_watchdog.h
new file mode 100644
index 0000000..337a91b
--- /dev/null
+++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_watchdog/mss_watchdog.h
@@ -0,0 +1,427 @@
+/*******************************************************************************

+ * (c) Copyright 2009 Actel Corporation.  All rights reserved.

+ * 

+ * SmartFusion Microcontroller Subsystem (MSS) Watchdog bare metal software

+ * driver.

+ *

+ * SVN $Revision: 1888 $

+ * SVN $Date: 2009-12-18 10:58:42 +0000 (Fri, 18 Dec 2009) $

+ */

+/*=========================================================================*//**

+  @section intro_sec Introduction

+  The SmartFusion microcontroller subsystem (MSS) includes a watchdog timer used

+  to detect system lockups.

+  This driver provides a set of functions for controlling the MSS watchdog as

+  part of a bare metal system where no operating system is available. These

+  drivers can be adapted for use as part of an operating system but the

+  implementation of the adaptation layer between this driver and the operating

+  system's driver model is outside the scope of this driver.

+    

+  @section hw_dependencies Hardware Flow Dependencies

+  The configuration of all features of the MSS watchdog is covered by this

+  driver. There are no dependencies on the hardware flow for configuring the

+  SmartFusion MSS watchdog timer.

+    

+  @section theory_op Theory of Operation

+  The watchdog driver uses the SmartFusion "Cortex Microcontroler Software

+  Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access hadware

+  registers. You must ensure that the SmartFusion CMSIS-PAL is either included

+  in the software toolchain used to build your project or is included in your

+  project. The most up-to-date SmartFusion CMSIS-PAL files can be obtained using

+  the Actel Firmware Catalog.

+  

+  The watchdog driver functions are grouped into the following categories:

+    - Initialization and cnfiguration

+    - Reading the watchdog timer current value and status

+    - Refreshing the watchdog timer value

+    - Time-out and wake-up interrupts control

+  

+  The watchdog driver is initialized and configured through a call to the

+  MSS_WD_init() function. The parameters passed to MSS_WD_init() function

+  specify the watchdog timer configuration. The configuration parameters include

+  the value that will be reloaded into the watchdog timer down counter every

+  time the watchdog is refreshed. Also included as part of the configuration

+  parameters is the optional allowed refresh window. The allowed refresh window

+  specifies the maximum allowed current value of the watchdog timer at the time

+  of the watchdog is relaoded. Attempting to reload the watchdog timer when its

+  value is larger than the allowed refresh window will cause a reset or

+  interrupt depending on the watchdog configuration. The allowed refresh window

+  can be disabled by specifying an allowed refesh window equal or higher than

+  the watchdog reload value.

+  The MSS_WD_init() function must be called before any other watchdog driver

+  functions can be called with the exception of the MSS_WD_disable() function.

+  

+  The watchdog timer can be disabled using the MSS_WD_disable() function. Once

+  disabled, the watchdog timer can only be reenabled by a power-on reset.

+  

+  The watchdog timer current value can be read using the MSS_WD_current_value()

+  function. The watchdog status can be read using the MSS_WD_status() function.

+  These functions are typically required when using the watchdog configured with

+  an allowed refresh window to check if a watchdog reload is currently allowed.

+  

+  The watchdog timer value is reloaded using the MSS_WD_reload() function. The

+  value reloaded into the watchdog timer down counter is the value specified as

+  parameter to the MSS_WD_init() function.

+  

+  The watchdog timer can generate interrupts instead of resetting the system

+  when its down-counter timer expires. These time-out interrupts are controlled

+  using the following functions:

+    - MSS_WD_enable_timeout_irq

+    - MSS_WD_disable_timeout_irq

+    - MSS_WD_clear_timeout_irq

+  

+  The watchdog timer is external to the Cortex-M3 processor core and operates

+  even when the Cortex-M3 is in sleep mode. A wakeup interrupt can be generated

+  by the watchdog timer to wakeup the Cortext-M3 when the watchdog timer value

+  reaches the allowed refresh window while the Cortex-M3 is in sleep mode. The

+  watchdog driver provides the following functions to control wakeup interrupts:

+    - MSS_WD_enable_wakeup_irq

+    - MSS_WD_disable_wakeup_irq

+    - MSS_WD_clear_wakeup_irq

+    

+ *//*=========================================================================*/

+

+#ifndef MSS_WATCHDOG_H_

+#define MSS_WATCHDOG_H_

+

+#ifdef __cplusplus

+extern "C" {

+#endif 

+

+#include "../../CMSIS/a2fxxxm3.h"

+

+/***************************************************************************//**

+ * The MSS_WDOG_RESET_ON_TIMEOUT_MODE macro is one of the possible values for the

+ * mode parameter of the WD_init() function. It is used to specify that a reset

+ * should occur when the watchdog down counter times out.

+ */

+#define MSS_WDOG_RESET_ON_TIMEOUT_MODE       (uint32_t)0x00000000U

+

+/***************************************************************************//**

+ * The MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE macro is one of the possible values for

+ * the  mode parameter of function the WD_init() function. It is used to specify

+ * that a time out interrupt should occur when the watchdog down counter expires.

+ */

+#define MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE   (uint32_t)0x00000004U

+

+/***************************************************************************//**

+ * The MSS_WDOG_NO_WINDOW macro can be used as the value for the reload_window

+ * parameter of the WD_init() function. It is used to specify that no forbidden

+ * window will exist for the reload of the watchdog down counter.

+ */

+#define MSS_WDOG_NO_WINDOW    (uint32_t)0xFFFFFFFFU

+

+/***************************************************************************//**

+ * The MSS_WDOG_CTRL_MODE_BIT_MASK macro is a bit mask specifying the bit used to

+ * set the watchdog's operating mode within the wathcdog's WDOGCONTROL register.

+ */

+#define MSS_WDOG_CTRL_MODE_BIT_MASK           (uint32_t)0x00000004U

+

+/***************************************************************************//**

+ * The MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK macro is a bit mask specifying the bit

+ * used to enable the time out interrupt within the watchdog's WDOGCONTROL

+ * register.

+ */

+#define MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK  (uint32_t)0x00000001U

+

+/***************************************************************************//**

+  The MSS_WDOG_WAKEUP_IRQ_ENABLE_BIT_MASK macro is a bit mask specifying the bit

+  used to enable the wake up interrupt within the watchdog's WDOGCONTROL

+  register.

+ */

+#define MSS_WDOG_WAKEUP_IRQ_ENABLE_BIT_MASK   (uint32_t)0x00000002U

+

+/***************************************************************************//**

+  The MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK macro is a bit mask specifying the bit

+  used to clear the time out interrupt within the watchdog's WDOGRIS register.

+ */

+#define MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK   (uint32_t)0x00000001U

+

+/***************************************************************************//**

+  The MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK macro is a bit mask specifying the bit

+  used to clear the wake up interrupt within the watchdog's WDOGRIS register.

+ */

+#define MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK    (uint32_t)0x00000002U

+

+/***************************************************************************//**

+  The MSS_WDOG_REFRESH_KEY macro holds the magic value which will cause a reload

+  of the watchdog's down counter when written to the watchdog's WDOGREFRESH

+  register.

+ */

+#define MSS_WDOG_REFRESH_KEY    (uint32_t)0xAC15DE42U

+

+/***************************************************************************//**

+  The MSS_WDOG_DISABLE_KEY macro holds the magic value which will disable the

+  watchdog if written to the watchdog's WDOGENABLE register.

+ */

+#define MSS_WDOG_DISABLE_KEY    (uint32_t)0x4C6E55FAU

+

+/***************************************************************************//**

+  The MSS_WD_init() function initializes and configures the watchdog timer.

+ 

+  @param load_value

+    The load_value parameter specifies the value that will be loaded into the

+    watchdog's down counter when the reload command is issued through a call to

+    MSS_WD_reload().

+                   

+  @param reload_window

+    The reload_window parameter specifies the time window during which a reload

+    of the watchdog counter is allowed. A reload of the watchdog counter should

+    only be performed when the watchdog counter value is below the value of the

+    reload_window. Reloading the watchdog down counter value before it has

+    reached the reload_window will result in an interrupt or reset depending on

+    the watchdog's mode.

+    The reload window can be disabled by using WDOG_NO_WINDOW for this parameter.

+ 

+  @param mode

+    The mode parameter specifies the watchdog's operating mode. It can be either

+    MSS_WDOG_RESET_ON_TIMEOUT_MODE or MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE.

+    MSS_WDOG_RESET_ON_TIMEOUT_MODE: a reset will occur if the watchdog timer

+    expires.

+    MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE: an NMI interrupt will occur if the

+    watchdog timer expires.

+ 

+  @return

+    This function does not return a value.

+ */

+static __INLINE void MSS_WD_init

+(

+    uint32_t load_value,

+    uint32_t reload_window,

+    uint32_t mode

+)

+{

+    /* Disable interrupts. */

+    WATCHDOG->WDOGCONTROL &= ~(MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK | MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK);

+    

+    /* Clear any existing interrupts. */

+    WATCHDOG->WDOGRIS = MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK | MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK;

+    

+    /* Configure watchdog with new configuration passed as parameter. */

+    WATCHDOG->WDOGMVRP = MSS_WDOG_NO_WINDOW;

+    WATCHDOG->WDOGLOAD = load_value;

+    WATCHDOG->WDOGCONTROL = (WATCHDOG->WDOGCONTROL & ~MSS_WDOG_CTRL_MODE_BIT_MASK) | (mode & MSS_WDOG_CTRL_MODE_BIT_MASK);

+    

+    /* Reload watchdog with new load value. */

+    WATCHDOG->WDOGREFRESH = MSS_WDOG_REFRESH_KEY;

+    

+    /* Set allowed window. */

+    WATCHDOG->WDOGMVRP = reload_window;

+}

+

+/***************************************************************************//**

+  The MSS_WD_reload() function causes the watchdog to reload its down counter timer

+  with the load value configured through the call to WD_init(). This function 

+  must be called regularly to avoid a system reset.

+ 

+  @return

+    This function does not return a value.

+ */

+static __INLINE void MSS_WD_reload( void )

+{

+    WATCHDOG->WDOGREFRESH = MSS_WDOG_REFRESH_KEY;

+}

+

+/***************************************************************************//**

+  The MSS_WD_disable() function disables the watchdog.

+  Please note that the watchdog can only be reenabled as a result of a power-on

+  reset.

+ 

+  @return

+    This function does not return a value.

+ */

+static __INLINE void MSS_WD_disable( void )

+{

+    WATCHDOG->WDOGENABLE = MSS_WDOG_DISABLE_KEY;

+}

+

+/***************************************************************************//**

+  The MSS_WD_current_value() function returns the current value of the watchdog's

+  down counter.

+ 

+  @return

+    This function returns the current value of the watchdog down counter.

+ */

+static __INLINE uint32_t MSS_WD_current_value( void )

+{

+    return WATCHDOG->WDOGVALUE;

+}

+

+/***************************************************************************//**

+  The MSS_WD_status() function returns the status of the watchdog.

+ 

+  @return 

+    The MSS_WD_status() function returns the status of the watchdog. A value of

+    0 indicates that watchdog counter has reached the forbidden window and that

+    a reload should not be done. A value of 1 indicates that the watchdog counter

+    is within the permitted window and that a reload is allowed.

+ */

+static __INLINE uint32_t MSS_WD_status( void )

+{

+    return WATCHDOG->WDOGSTATUS;

+}

+

+/***************************************************************************//**

+  The MSS_WD_enable_timeout_irq() function enables the watchdog’s time out

+  interrupt which is connected to the Cortex-M3 NMI interrupt.

+  The NMI_Handler() function will be called when a watchdog time out occurs. You

+  must provide the implementation of the NMI_Handler() function to suit your

+  application.

+ 

+  @return

+    This function does not return a value.

+ 

+  Example:

+  @code

+  #include "mss_watchdog.h"

+  int main( void )

+  {

+      MSS_WD_init( 0x10000000, MSS_WDOG_NO_WINDOW, MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE );

+      MSS_WD_enable_timeout_irq();

+      for (;;)

+      {

+          main_task();

+      }

+  }

+ 

+  void NMI_Handler( void )

+  {

+      process_timeout();

+      MSS_WD_clear_timeout_irq();

+  }

+  @endcode

+ */

+static __INLINE void MSS_WD_enable_timeout_irq( void )

+{

+    WATCHDOG->WDOGCONTROL |= MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK;

+}

+

+/***************************************************************************//**

+  The WD_disable_timeout_irq() function disables the generation of the NMI

+  interrupt when the watchdog times out.

+ 

+  @return

+    This function does not return a value.

+ */

+static __INLINE void MSS_WD_disable_timeout_irq( void )

+{

+    WATCHDOG->WDOGCONTROL &= ~MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK;

+}

+

+/***************************************************************************//**

+  The MSS_WD_enable_wakeup_irq() function enables the SmartFusion wakeup

+  interrupt. The WdogWakeup_IRQHandler() function will be called when a wake up

+  interrupt occurs. You must provide the implementation of the WdogWakeup_IRQHandler()

+  function to suit your application.

+ 

+  @return

+    This function does not return a value.

+ 

+  Example:

+  @code

+  #include "mss_watchdog.h"

+  int main( void )

+  {

+      MSS_WD_init( 0x10000000, MSS_WDOG_NO_WINDOW, MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE );

+      MSS_WD_enable_wakeup_irq();

+      for (;;)

+      {

+          main_task();

+          cortex_sleep();

+      }

+  }

+ 

+  void WdogWakeup_IRQHandler( void )

+  {

+      process_wakeup();

+      MSS_WD_clear_wakeup_irq();

+  }

+  @endcode

+ */

+static __INLINE void MSS_WD_enable_wakeup_irq( void )

+{

+    WATCHDOG->WDOGCONTROL |= MSS_WDOG_WAKEUP_IRQ_ENABLE_BIT_MASK;

+    NVIC_EnableIRQ( WdogWakeup_IRQn );

+}

+

+/***************************************************************************//**

+  The MSS_WD_disable_wakeup_irq() function disables the SmartFusion wakeup

+  interrupt. 

+ 

+  @return

+    This function does not return a value.

+ */

+static __INLINE void MSS_WD_disable_wakeup_irq( void )

+{

+    WATCHDOG->WDOGCONTROL &= ~MSS_WDOG_WAKEUP_IRQ_ENABLE_BIT_MASK;

+}

+

+/***************************************************************************//**

+  The MSS_WD_clear_timeout_irq() function clears the watchdog’s time out

+  interrupt which is connected to the Cortex-M3 NMI interrupt.

+  Calling MSS_WD_clear_timeout_irq() results in clearing the Cortex-M3 NMI interrupt.

+  Note: The MSS_WD_clear_timeout_irq() function must be called as part of the

+  timeout interrupt service routine (ISR) in order to prevent the same interrupt

+  event retriggering a call to the wakeup ISR.

+ 

+  @return

+    The example below demonstrates the use of the MSS_WD_clear_timeout_irq()

+    function as part of the NMI interrupt service routine.

+

+    Example:

+  @code

+  void NMI_Handler( void )

+  {

+      process_timeout();

+      MSS_WD_clear_timeout_irq();

+  }

+  @endcode

+ */

+static __INLINE void MSS_WD_clear_timeout_irq( void )

+{

+    WATCHDOG->WDOGRIS = MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK;

+    /*

+     * Perform a second write to ensure that the first write completed before 

+     * returning from this function. This is to account for posted writes across

+     * the AHB matrix. The second write ensures that the first write has

+     * completed and that the interrupt line has been de-asserted by the time

+     * the function returns. Omitting the second write may result in a delay

+     * in the de-assertion of the interrupt line going to the Cortex-M3 and a

+     * retriggering of the interrupt.

+     */

+    WATCHDOG->WDOGRIS = MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK;

+}

+

+/***************************************************************************//**

+  The MSS_WD_clear_wakeup_irq() function clears the wakeup interrupt.

+  Note: The MSS_WD_clear_wakeup_irq() function must be called as part of the

+  wakeup interrupt service routine (ISR) in order to prevent the same interrupt

+  event retriggering a call to the wakeup ISR. This function also clears the

+  interrupt in the Cortex-M3 interrupt controller through a call to

+  NVIC_ClearPendingIRQ().

+ 

+  @return

+    This function does not return a value.

+

+    Example:

+    The example below demonstrates the use of the MSS_WD_clear_wakeup_irq() function

+    as part of the wakeup interrupt service routine.  

+    @code

+    void WdogWakeup_IRQHandler( void )

+    {

+        do_interrupt_processing();

+        

+        MSS_WD_clear_wakeup_irq();

+    }

+    @endcode

+*/

+static __INLINE void MSS_WD_clear_wakeup_irq( void )

+{

+    WATCHDOG->WDOGRIS = MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK;

+    NVIC_ClearPendingIRQ( WdogWakeup_IRQn );

+}

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* MSS_WATCHDOG_H_ */