diff --git a/Demo/CORTEX_A2F200_SoftConsole/.cproject b/Demo/CORTEX_A2F200_SoftConsole/.cproject
new file mode 100644
index 000000000..91b100ac3
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/.cproject
@@ -0,0 +1,316 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Demo/CORTEX_A2F200_SoftConsole/.project b/Demo/CORTEX_A2F200_SoftConsole/.project
new file mode 100644
index 000000000..f957d73b8
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/.project
@@ -0,0 +1,80 @@
+
+
+ RTOSDemo
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.autoBuildTarget
+ all
+
+
+ org.eclipse.cdt.make.core.buildArguments
+
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/RTOSDemo/Debug}
+
+
+ org.eclipse.cdt.make.core.cleanBuildTarget
+ clean
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.fullBuildTarget
+ all
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/Demo/CORTEX_A2F200_SoftConsole/.settings/org.eclipse.ltk.core.refactoring.prefs b/Demo/CORTEX_A2F200_SoftConsole/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 000000000..c1e59b5eb
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,3 @@
+#Sun Apr 03 18:36:27 BST 2011
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/Demo/CORTEX_A2F200_SoftConsole/CreateProjectDirectoryStructure.bat b/Demo/CORTEX_A2F200_SoftConsole/CreateProjectDirectoryStructure.bat
new file mode 100644
index 000000000..3d6dbb391
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/CreateProjectDirectoryStructure.bat
@@ -0,0 +1,36 @@
+REM This file should be executed from the command line prior to the first
+REM build. It will be necessary to refresh the Eclipse project once the
+REM .bat file has been executed (normally just press F5 to refresh).
+
+REM Copies all the required files from their location within the standard
+REM FreeRTOS directory structure to under the Eclipse project directory.
+REM This permits the Eclipse project to be used in 'managed' mode and without
+REM having to setup any linked resources.
+
+REM Have the files already been copied?
+IF EXIST FreeRTOS_Source Goto END
+
+ REM Create the required directory structure.
+ MD FreeRTOS_Source
+ MD FreeRTOS_Source\include
+ MD FreeRTOS_Source\portable\GCC
+ MD FreeRTOS_Source\portable\GCC\ARM_CM3
+ MD FreeRTOS_Source\portable\MemMang
+
+ REM Copy the core kernel files.
+ copy ..\..\Source\tasks.c FreeRTOS_Source
+ copy ..\..\Source\queue.c FreeRTOS_Source
+ copy ..\..\Source\list.c FreeRTOS_Source
+ copy ..\..\Source\timers.c FreeRTOS_Source
+
+ REM Copy the common header files
+
+ copy ..\..\Source\include\*.* FreeRTOS_Source\include
+
+ REM Copy the portable layer files
+ copy ..\..\Source\portable\GCC\ARM_CM3\*.* FreeRTOS_Source\portable\GCC\ARM_CM3
+
+ REM Copy the basic memory allocation files
+ copy ..\..\Source\portable\MemMang\heap_1.c FreeRTOS_Source\portable\MemMang
+
+: END
diff --git a/Demo/CORTEX_A2F200_SoftConsole/FreeRTOSConfig.h b/Demo/CORTEX_A2F200_SoftConsole/FreeRTOSConfig.h
new file mode 100644
index 000000000..b2c9697e6
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/FreeRTOSConfig.h
@@ -0,0 +1,142 @@
+/*
+ FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
+
+ ***************************************************************************
+ * *
+ * If you are: *
+ * *
+ * + New to FreeRTOS, *
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *
+ * + Looking for basic training, *
+ * + Wanting to improve your FreeRTOS skills and productivity *
+ * *
+ * then take a look at the FreeRTOS books - available as PDF or paperback *
+ * *
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
+ * http://www.FreeRTOS.org/Documentation *
+ * *
+ * A pdf reference manual is also available. Both are usually delivered *
+ * to your inbox within 20 minutes to two hours when purchased between 8am *
+ * and 8pm GMT (although please allow up to 24 hours in case of *
+ * exceptional circumstances). Thank you for your support! *
+ * *
+ ***************************************************************************
+
+ This file is part of the FreeRTOS distribution.
+
+ FreeRTOS is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License (version 2) as published by the
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+ ***NOTE*** The exception to the GPL is included to allow you to distribute
+ a combined work that includes FreeRTOS without being obliged to provide the
+ source code for proprietary components outside of the FreeRTOS kernel.
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details. You should have received a copy of the GNU General Public
+ License and the FreeRTOS license exception along with FreeRTOS; if not it
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained
+ by writing to Richard Barry, contact details for whom are available on the
+ FreeRTOS WEB site.
+
+ 1 tab == 4 spaces!
+
+ http://www.FreeRTOS.org - Documentation, latest information, license and
+ contact details.
+
+ http://www.SafeRTOS.com - A version that is certified for use in safety
+ critical systems.
+
+ http://www.OpenRTOS.com - Commercial support, development, porting,
+ licensing and training services.
+*/
+
+
+/* The following #error directive is to remind users that a batch file must be
+ * executed prior to this project being built. The batch file *cannot* be
+ * executed from within CCS4! Once it has been executed, re-open or refresh
+ * the CCS4 project and remove the #error line below.
+ */
+//#error Ensure CreateProjectDirectoryStructure.bat has been executed before building. See comment immediately above.
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+#define configUSE_PREEMPTION 1
+#define configUSE_IDLE_HOOK 1
+#define configUSE_TICK_HOOK 0
+#define configCPU_CLOCK_HZ ( 75000000UL )
+#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
+#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 7 * 1024 ) )
+#define configMAX_TASK_NAME_LEN ( 10 )
+#define configUSE_TRACE_FACILITY 0
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_MUTEXES 1
+#define configQUEUE_REGISTRY_SIZE 0
+#define configGENERATE_RUN_TIME_STATS 0
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configUSE_RECURSIVE_MUTEXES 0
+#define configUSE_MALLOC_FAILED_HOOK 1
+#define configUSE_APPLICATION_TASK_TAG 0
+#define configUSE_COUNTING_SEMAPHORES 0
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
+
+/* Software timer definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY ( 3 )
+#define configTIMER_QUEUE_LENGTH 5
+#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )
+
+/* Set the following definitions to 1 to include the API function, or zero
+to exclude the API function. */
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskCleanUpResources 1
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+
+/* Use the system definition, if there is one */
+#ifdef __NVIC_PRIO_BITS
+ #define configPRIO_BITS __NVIC_PRIO_BITS
+#else
+ #define configPRIO_BITS 4 /* 15 priority levels */
+#endif
+
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
+
+/* The lowest priority. */
+#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+/* Priority 5, or 160 as only the top three bits are implemented. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
+
+#define vPortSVCHandler SVC_Handler
+#define xPortPendSVHandler PendSV_Handler
+#define vPortSVCHandler SVC_Handler
+#define xPortSysTickHandler SysTick_Handler
+
+#endif /* FREERTOS_CONFIG_H */
+
diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/a2fxxxm3.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/a2fxxxm3.h
new file mode 100644
index 000000000..ab389e05d
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/CMSIS/core_cm3.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/core_cm3.c
new file mode 100644
index 000000000..56fddc52b
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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
+
+/* 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_SoftConsole/MicroSemi_Code/CMSIS/core_cm3.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/core_cm3.h
new file mode 100644
index 000000000..e0565d7d4
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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 '' (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 /* Include standard types */
+
+#if defined (__ICCARM__)
+ #include /* 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_SoftConsole/MicroSemi_Code/CMSIS/mss_assert.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/mss_assert.h
new file mode 100644
index 000000000..4725d2132
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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
+
+#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_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-envm.ld b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-envm.ld
new file mode 100644
index 000000000..1d33683f3
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-esram.ld b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-esram.ld
new file mode 100644
index 000000000..85e416044
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/debug-in-external-ram.ld b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/debug-in-external-ram.ld
new file mode 100644
index 000000000..b2d614d31
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/newlib_stubs.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/newlib_stubs.c
new file mode 100644
index 000000000..3b42429f1
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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
+#include
+#include
+#include
+#include
+#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_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/production-execute-in-place.ld b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/production-execute-in-place.ld
new file mode 100644
index 000000000..cfaddb615
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/production-relocate-executable.ld b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/production-relocate-executable.ld
new file mode 100644
index 000000000..21e613c92
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/startup_a2fxxxm3.s b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/startup_gcc/startup_a2fxxxm3.s
new file mode 100644
index 000000000..e9e87adca
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/CMSIS/system_a2fxxxm3.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/system_a2fxxxm3.c
new file mode 100644
index 000000000..1b3798f3e
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/CMSIS/system_a2fxxxm3.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/CMSIS/system_a2fxxxm3.h
new file mode 100644
index 000000000..6ae0ad5b7
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mac/nettype.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mac/nettype.h
new file mode 100644
index 000000000..d27ce14fe
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mac/nettype.h
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * (c) Copyright 2009 SLS Corporation,All Rights Reserved.
+ *
+ * tcpip.h:header file for TCP/IP implementation.
+ * Version Author Comment
+ * 1.0.0 SLS corp. First release
+ */
+/***************************************************************************//**
+ * This header file contains the definition and datastructures for the TCP/IP
+ * stack implementation.
+ */
+#ifndef _NETTYPE_H_
+#define _NETTYPE_H_
+
+#define BUF_LEN 1500
+
+/* IP header length in terms of 16-bit words */
+#define IP_HDR_LEN 10
+#define IP_HDR_CSUM_OFFSET 5
+#define TCP_HDR_CSUM_OFFSET 8
+
+#define ETH_ADDR_LEN 6
+#define IP_ADDR_LEN 4
+#define ETH_TYPE_LEN 2
+#define ARP_HW_TYPE_LEN 2
+#define ARP_PROTO_TYPE_LEN 2
+#define ARP_OPCODE_LEN 2
+
+#define ETH_TYPE_0 0x08 /* both IP and ARP have 08 as the first byte */
+#define ETH_TYPE_ARP_1 0x06 /* 0806 is ARP */
+#define ETH_TYPE_IP_1 0x00 /* 0800 is IP */
+
+#define ARP_HW_TYPE_0 0x00 /* 0001 for ethernet */
+#define ARP_HW_TYPE_1 0x01 /* 0001 for ethernet */
+
+#define ARP_PROTO_TYPE_0 0x08 /* 0800 is IP */
+#define ARP_PROTO_TYPE_1 0x00
+
+#define ARP_OPCODE_0 0x00 /* same for req and reply */
+#define ARP_OPCODE_REQ_1 0x01 /* 0001 is Request */
+#define ARP_OPCODE_REPLY_1 0x02 /* 0002 is Reply */
+
+extern unsigned char my_IP_address[IP_ADDR_LEN];
+
+typedef struct ether_hdr {
+ unsigned char da[ETH_ADDR_LEN]; /* destination MAC address */
+ unsigned char sa[ETH_ADDR_LEN]; /* source MAC address */
+ unsigned char type_code[ETH_TYPE_LEN]; /* type code */
+} ether_hdr_t;
+
+typedef struct arp_pkt {
+ unsigned char hw_type[ARP_HW_TYPE_LEN]; /* Hardware Type */
+ unsigned char proto_type[ARP_PROTO_TYPE_LEN]; /* Protocol Type */
+ unsigned char hw_addr_len; /* Hardware Address Length */
+ unsigned char proto_addr_len; /* Protocol Address Length */
+ unsigned char opcode[ARP_OPCODE_LEN]; /* Opcode */
+ unsigned char mac_sa[ETH_ADDR_LEN]; /* sender MAC address */
+ unsigned char ip_sa[IP_ADDR_LEN]; /* sender IP address */
+ unsigned char mac_ta[ETH_ADDR_LEN]; /* target MAC address */
+ unsigned char ip_ta[IP_ADDR_LEN]; /* target IP address */
+} arp_pkt_t;
+
+#define ICMP_PROTO 0x01
+#define TCP_PROTO 0x06
+#define UDP_PROTO 0x11
+
+#define IP_CSUM_LEN 2
+#define IP_ID_LEN 2
+#define IP_TLEN_LEN 2
+#define IP_FRAG_OFF_LEN 2
+
+typedef struct ip_hdr {
+ unsigned char ver_hlen; /* version - 4 bits; IP hdr len - 4 bits */
+ unsigned char tos; /* Type of service */
+ unsigned char tlen[IP_TLEN_LEN]; /* Size of datagram (header + data) */
+ unsigned char id[IP_ID_LEN]; /* together with sa, uniequly identifies pkt */
+ unsigned char frag_off[IP_FRAG_OFF_LEN]; /* flags - 3 bits; fragment offset - 13 bits */
+ unsigned char ttl; /* time to live */
+ unsigned char proto; /* protocol */
+ unsigned char csum[IP_CSUM_LEN]; /* header checksum */
+ unsigned char sa[IP_ADDR_LEN]; /* IP source address */
+ unsigned char da[IP_ADDR_LEN]; /* IP dest address */
+} ip_hdr_t;
+
+
+#define ICMP_TYPE_ECHO_REQUEST 8
+#define ICMP_TYPE_ECHO_REPLY 0
+
+typedef struct icmp_hdr {
+ unsigned char type;
+ unsigned char icode;
+ unsigned char csum[IP_CSUM_LEN];
+} icmp_hdr_t;
+
+#define TCP_PORT_LEN 2
+#define TCP_SEQ_LEN 4
+#define TCP_WSIZE_LEN 2
+#define TCP_UPTR_LEN 2
+#define TCP_CSUM_LEN 2
+#define TCP_PLEN_LEN 2
+
+typedef struct tcp_hdr {
+ unsigned char sp[TCP_PORT_LEN]; /* Source port */
+ unsigned char dp[TCP_PORT_LEN]; /* Destination port */
+ unsigned char seqnum[TCP_SEQ_LEN]; /* Sequence number */
+ unsigned char acknum[TCP_SEQ_LEN]; /* Acknowledgement number */
+ unsigned char data_off; /* Data Offset - 4 upper bits are valid */
+ unsigned char urg_ack_psh_rst_syn_fin; /* 6 lower bits are valid */
+ unsigned char wsize[TCP_WSIZE_LEN]; /* Window */
+ unsigned char csum[TCP_CSUM_LEN]; /* Chekcsum */
+ unsigned char uptr[TCP_UPTR_LEN]; /* Urgent pointer */
+} tcp_hdr_t;
+
+#define UDP_LEN_LEN 2
+#define UDP_CSUM_LEN 2
+
+typedef struct udp_hdr {
+ unsigned char sp[TCP_PORT_LEN]; /* Source port */
+ unsigned char dp[TCP_PORT_LEN]; /* Destination port */
+ unsigned char len[UDP_LEN_LEN]; /* length of packet */
+ unsigned char csum[UDP_CSUM_LEN]; /* checksum */
+} udp_hdr_t;
+
+#define BOOTP_OPTCODE_DHCP_SUBNET 1 /* Subnet mask */
+#define BOOTP_OPTCODE_DHCP_ROUTER 3 /* Router*/
+#define BOOTP_OPTCODE_DHCP_DOMAIN 6 /* Domain */
+#define BOOTP_OPTCODE_DHCP_LEASE 51 /* Lease time*/
+#define BOOTP_OPTCODE_DHCP_TYPE 53 /* 53, 1, DHCP_TYPE_* */
+#define BOOTP_OPTCODE_DHCP_SID 54 /* 54, 4, a.b.c.d, Server ID */
+#define BOOTP_OPTCODE_DHCP_RENEW 58 /* Renewal time */
+#define BOOTP_OPTCODE_DHCP_REBIND 59 /* Rebinding time */
+
+#define BOOTP_OPTCODE_END 255 /* last in options */
+
+#define DHCP_TYPE_DISCOVER 1
+#define DHCP_TYPE_OFFER 2
+#define DHCP_TYPE_REQUEST 3
+#define DHCP_TYPE_DECLINE 4
+#define DHCP_TYPE_ACK 5
+#define DHCP_TYPE_NAK 6
+#define DHCP_TYPE_RELEASE 7
+
+
+#define BOOTP_OP_REQUEST 1
+#define BOOTP_OP_REPLY 2
+#define BOOTP_HWTYPE_ETH 1
+#define BOOTP_XID_LEN 4
+#define BOOTP_SEC_LEN 2
+#define BOOTP_CHLEN 16
+#define BOOTP_SN_LEN 64
+#define BOOTP_FL_LEN 128
+#define BOOTP_VEN_LEN 64
+
+#define BOOTP_CLIENT_PORT 68
+#define BOOTP_SERVER_PORT 67
+
+typedef struct bootp_pkt {
+ unsigned char op; /* packet op code */
+ unsigned char hwtype; /* hardware type */
+ unsigned char hlen; /* hardware address length */
+ unsigned char hops; /* client sets to zero */
+ unsigned char xid[BOOTP_XID_LEN]; /* transaction ID, random */
+ unsigned char secs[BOOTP_SEC_LEN]; /* seconds since boot */
+ unsigned char flags[2]; /* flags */
+ unsigned char ciaddr[IP_ADDR_LEN]; /* client IP ADDR */
+ unsigned char yiaddr[IP_ADDR_LEN]; /* Your IP Addr */
+ unsigned char siaddr[IP_ADDR_LEN]; /* Server IP ADDR */
+ unsigned char giaddr[IP_ADDR_LEN]; /* Gateway IP ADDR */
+ unsigned char chaddr[BOOTP_CHLEN]; /* Client Hardware Addr */
+ unsigned char sname[BOOTP_SN_LEN]; /* Server Name */
+ unsigned char file[BOOTP_FL_LEN]; /* File Path */
+ unsigned char vend[BOOTP_VEN_LEN]; /* Vendor Data */
+} bootp_pkt_t;
+
+typedef struct tcp_pseudo_hdr {
+ unsigned char sa[IP_ADDR_LEN];
+ unsigned char da[IP_ADDR_LEN];
+ unsigned char zero;
+ unsigned char proto;
+ unsigned char plen[TCP_PLEN_LEN];
+} tcp_pseudo_hdr_t;
+
+typedef enum tcp_state_e {
+ TCP_STATE_LISTEN = 0,
+ TCP_STATE_SYN_RECVD,
+ TCP_STATE_ESTABLISHED,
+ TCP_STATE_LAST_ACK,
+ TCP_STATE_MY_LAST,
+ TCP_STATE_CLOSED
+} tcp_state_t;
+
+typedef struct tcp_control_block {
+ unsigned char local_port[TCP_PORT_LEN];
+ unsigned char remote_port[TCP_PORT_LEN];
+ unsigned char remote_addr[IP_ADDR_LEN];
+ tcp_state_t state;
+ unsigned int local_seq;
+ unsigned int remote_seq;
+ unsigned char remote_mac[ETH_ADDR_LEN]; /* this really doesn't belong here */
+//:
+ const uint8_t * tx_block_addr;
+ unsigned short int tx_block_size;
+ unsigned short int tx_block_idx;
+ uint8_t * tcp_packet;
+} tcp_control_block_t;
+
+
+typedef enum tcp_cntrol_flags_e {
+ TCP_CNTRL_FIN = 0x01,
+ TCP_CNTRL_SYN = 0x02,
+ TCP_CNTRL_RST = 0x04,
+ TCP_CNTRL_PSH = 0x08,
+ TCP_CNTRL_ACK = 0x10,
+ TCP_CNTRL_URG = 0x20
+} tcp_control_flags_t;
+
+
+typedef struct arp_entry {
+ unsigned char mac[ETH_ADDR_LEN]; /* MAC address */
+ unsigned char ip[IP_ADDR_LEN]; /* IP address */
+ unsigned char used; /* Is this entry used? */
+} arp_entry_t;
+
+typedef arp_pkt_t *arp_pkt_xp;
+typedef ether_hdr_t *eth_hdr_xp;
+typedef ip_hdr_t *ip_hdr_xp;
+typedef icmp_hdr_t *icmp_hdr_xp;
+typedef udp_hdr_t *udp_hdr_xp;
+typedef tcp_hdr_t *tcp_hdr_xp;
+typedef tcp_pseudo_hdr_t *tcp_pseudo_hdr_xp;
+typedef bootp_pkt_t *bootp_pkt_xp;
+
+#endif /* _NETTYPE_H_ */
diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mac/tcpip.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mac/tcpip.c
new file mode 100644
index 000000000..c2d03d8b2
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mac/tcpip.c
@@ -0,0 +1,748 @@
+/*******************************************************************************
+ * (c) Copyright 2009 Actel Corporation,All Rights Reserved.
+ *
+ * tcpip.c:TCP/IP implementation for webserver.
+ */
+#include "../port_config/cpu_types.h"
+#include "nettype.h"
+#include "../mss_ethernet_mac/mss_ethernet_mac.h"
+#include "../mss_ethernet_mac/mss_ethernet_mac_regs.h"
+#include "tcpip.h"
+#include
+#include
+#include
+#define OK 0
+#define ERR 1
+#define MAC_BASE_ADDRESS 0x40003000
+
+
+extern char ethAddr[6];
+
+unsigned char my_ip[IP_ADDR_LEN]={192,168,0,14};
+unsigned char my_mac[ETH_ADDR_LEN]={0xAA,0xBB,0xCC,0x11,0x22,0x33};
+unsigned char tcp_packet[1532];
+unsigned char ip_known;
+unsigned char dhcp_ip_found;
+unsigned short int ip_id;
+unsigned char selected_mode = 0;
+unsigned char selectedwaveform = 0;
+unsigned char rtc_count[5]={0,0,0,0,0};
+unsigned char rtc_match_count[5]={0,5,0,0,0};
+unsigned char get_count[5];
+unsigned int num_pkt_tx = 0,num_pkt_rx = 0;
+#define TCP_START_SEQ 0x10203040
+static const unsigned char g_client_ip[IP_ADDR_LEN] = { 192, 168, 1, 10 };
+unsigned char oled_string[20];
+tcp_control_block_t tcb;
+MAC_instance_t g_mac;
+
+
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char send_arp_reply(unsigned char *buf)
+{
+ /* Modify the packet in place */
+
+ arp_pkt_xp arp_pkt = (arp_pkt_xp )(buf + sizeof(ether_hdr_t));
+ eth_hdr_xp eth_hdr = (eth_hdr_xp ) buf;
+
+ memcpy(eth_hdr->da, eth_hdr->sa, ETH_ADDR_LEN);
+ memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);
+ arp_pkt->opcode[1] = ARP_OPCODE_REPLY_1;
+ memcpy(arp_pkt->mac_ta, arp_pkt->mac_sa, ETH_ADDR_LEN);
+ memcpy(arp_pkt->ip_ta, arp_pkt->ip_sa, IP_ADDR_LEN);
+ memcpy(arp_pkt->mac_sa, my_mac, ETH_ADDR_LEN);
+ memcpy(arp_pkt->ip_sa, my_ip, IP_ADDR_LEN);
+ num_pkt_tx++;
+ MSS_MAC_tx_packet(buf,42, MSS_MAC_BLOCKING);
+ return OK;
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+void send_gratuitous_arp(unsigned char *buf)
+{
+ arp_pkt_xp arp_pkt = (arp_pkt_xp )(buf + sizeof(ether_hdr_t));
+ eth_hdr_xp eth_hdr = (eth_hdr_xp ) buf;
+ memset(eth_hdr->da, 0xFF, ETH_ADDR_LEN); /* broadcast */
+ memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);
+ eth_hdr->type_code[0] = ETH_TYPE_0;
+ eth_hdr->type_code[1] = ETH_TYPE_ARP_1;
+ arp_pkt->hw_type[0] = ARP_HW_TYPE_0;
+ arp_pkt->hw_type[1] = ARP_HW_TYPE_1;
+ arp_pkt->proto_type[0] = ETH_TYPE_0;
+ arp_pkt->proto_type[1] = ETH_TYPE_IP_1;
+ arp_pkt->hw_addr_len = ETH_ADDR_LEN;
+ arp_pkt->proto_addr_len = IP_ADDR_LEN;
+ arp_pkt->opcode[0] = ARP_OPCODE_0;
+ arp_pkt->opcode[1] = ARP_OPCODE_REQ_1;
+ memcpy(arp_pkt->mac_sa, my_mac, ETH_ADDR_LEN);
+ memcpy(arp_pkt->ip_sa, my_ip, IP_ADDR_LEN);
+ memset(arp_pkt->mac_ta, 0x00, ETH_ADDR_LEN);
+ memcpy(arp_pkt->ip_ta, my_ip, IP_ADDR_LEN);
+ //mac_tx_send(buf,42,0);
+ num_pkt_tx++;
+ MSS_MAC_tx_packet(buf,42, MSS_MAC_BLOCKING);
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ *
+ */
+unsigned short int get_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos)
+{
+ unsigned int sum; /* our accumulated sum */
+ unsigned short int delta; /* the next 16-bit quantity to add */
+ unsigned short int i;
+ unsigned short int ilen;
+ sum = (unsigned int) 0;
+ ilen=(len&1)?len-1:len;
+ for (i = 0; i < ilen; i += 2) {
+ if (i == pos) continue;
+ delta = (unsigned short int)buf[i+1] + (unsigned short int)((unsigned short int)buf[i] << 8);
+ sum += delta;
+ if (sum & (unsigned int) 0x10000) { /* if there's a carry... */
+ sum &= 0xffff; /* get rid of the carry bit */
+ sum++; /* and move it down here */
+ }
+ }
+ if ( len & 1) {
+ delta = (unsigned short int)((unsigned short int)buf[i] << 8);
+ sum += delta;
+ if (sum & (unsigned int) 0x10000) { /* if there's a carry... */
+ sum &= 0xffff; /* get rid of the carry bit */
+ sum++; /* and move it down here */
+ }
+ }
+ sum = ~sum;
+ return sum;
+
+} //end calc_checksum
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char fix_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos)
+{
+ unsigned short int sum = get_checksum(buf,len,pos);
+ buf[pos] = (unsigned char)(sum >> 8);
+ buf[pos+1] = (unsigned char)sum;
+ return OK;
+}
+
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char check_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos, char type)
+{
+ unsigned short int sum = get_checksum(buf,len,pos);
+
+ if ((buf[pos] != (unsigned char)(sum >> 8)) ||
+ (buf[pos+1] != (unsigned char) sum)) {
+
+ type = 0; /* get around compiler warning */
+ return ERR;
+ } else {
+ return OK;
+ }
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char send_icmp_echo_reply(unsigned char *buf)
+{
+ eth_hdr_xp eth_hdr = (eth_hdr_xp ) buf;
+ ip_hdr_xp ip_hdr = (ip_hdr_xp ) (buf + sizeof (ether_hdr_t));
+ icmp_hdr_xp icmp_hdr = (icmp_hdr_xp )
+ (buf + sizeof (ether_hdr_t) + sizeof(ip_hdr_t));
+ unsigned short int elen = ((unsigned short int)ip_hdr->tlen[0] << 8) + (unsigned short int)ip_hdr->tlen[1] - sizeof(ip_hdr_t);
+ memcpy(eth_hdr->da, eth_hdr->sa, ETH_ADDR_LEN);
+ memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);
+ memcpy(ip_hdr->da, ip_hdr->sa, IP_ADDR_LEN);
+ memcpy(ip_hdr->sa, my_ip, IP_ADDR_LEN);
+ ip_hdr->ttl--;
+ fix_checksum((unsigned char *)ip_hdr, (unsigned short int) 20, (unsigned short int) 10);
+ icmp_hdr->type = ICMP_TYPE_ECHO_REPLY;
+ if (elen & 1) {
+ ((unsigned char *)icmp_hdr)[elen] = 0;
+ }
+ fix_checksum((unsigned char *)icmp_hdr, (unsigned short int) elen, (unsigned short int) 2);
+ num_pkt_tx++;
+ MSS_MAC_tx_packet(buf,elen + sizeof(ether_hdr_t) + sizeof(ip_hdr_t), MSS_MAC_BLOCKING);
+ return OK;
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+void dtoa_reverse(unsigned short int n, unsigned char *buf)
+{
+ buf--;
+ if (n == 0) {
+ *buf = '0';
+ return;
+ }
+ while (n > 0) {
+ *buf-- = (n % 10) + '0';
+ n = n / 10;
+ }
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+void send_bootp_packet (unsigned char *buf)
+{
+ /* output packet */
+ eth_hdr_xp eth_hdr = (eth_hdr_xp ) tcp_packet;
+ ip_hdr_xp ip_hdr = (ip_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t));
+ udp_hdr_xp udp_hdr = (udp_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));
+ bootp_pkt_xp bootp_pkt = (bootp_pkt_xp )((unsigned char *)udp_hdr + sizeof(udp_hdr_t));
+ unsigned char *opts = bootp_pkt->vend;
+ /* input packet */
+ // eth_hdr_xp ieth_hdr = (eth_hdr_xp ) buf;
+ // ip_hdr_xp iip_hdr = (ip_hdr_xp ) (buf + sizeof(ether_hdr_t));
+ udp_hdr_xp iudp_hdr = (udp_hdr_xp ) (buf + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));
+ bootp_pkt_xp ibootp_pkt = (bootp_pkt_xp )((unsigned char *)iudp_hdr + sizeof(udp_hdr_t));
+ unsigned short int plen;
+ /* Set up Bootp */
+ memset(bootp_pkt, 0, sizeof(bootp_pkt_t));
+ bootp_pkt->op = BOOTP_OP_REQUEST;
+ bootp_pkt->hwtype = BOOTP_HWTYPE_ETH;
+ bootp_pkt->hlen = ETH_ADDR_LEN;
+ bootp_pkt->secs[1] = 0x64;
+ memcpy(bootp_pkt->chaddr, my_mac, ETH_ADDR_LEN);
+ bootp_pkt->flags[0] = 0x80; /* ask for a broadcast */
+ if (buf) {
+ if (memcmp(my_mac, ibootp_pkt->chaddr, ETH_ADDR_LEN)) /* not for me ignore */
+ return;
+ memcpy(my_ip, ibootp_pkt->yiaddr, IP_ADDR_LEN);
+ ip_known = 1;
+ dhcp_ip_found = 1;
+ memcpy(bootp_pkt->ciaddr, ibootp_pkt->yiaddr, IP_ADDR_LEN);
+ memcpy(bootp_pkt->xid, ibootp_pkt->xid, BOOTP_XID_LEN);
+ } else {
+ bootp_pkt->xid[0] = 0x90;
+ }
+ *opts++ = 99; /* magic number */
+ *opts++ = 130;
+ *opts++ = 83;
+ *opts++ = 99;
+ *opts++ = BOOTP_OPTCODE_DHCP_TYPE;
+ *opts++ = 1;
+ if (buf) {
+ *opts++ = DHCP_TYPE_REQUEST;
+ *opts++ = BOOTP_OPTCODE_DHCP_SID;
+ *opts++ = 4;
+ *opts++ = ibootp_pkt->siaddr[0];
+ *opts++ = ibootp_pkt->siaddr[1];
+ *opts++ = ibootp_pkt->siaddr[2];
+ *opts++ = ibootp_pkt->siaddr[3];
+ } else {
+ *opts++ = DHCP_TYPE_DISCOVER;
+ }
+ *opts++ = BOOTP_OPTCODE_END;
+
+ /* Set up Udp */
+ memset(udp_hdr, 0, sizeof(udp_hdr_t));
+ udp_hdr->sp[1] = BOOTP_CLIENT_PORT;
+ udp_hdr->dp[1] = BOOTP_SERVER_PORT;
+ plen = sizeof(udp_hdr_t) + sizeof(bootp_pkt_t);
+ udp_hdr->len[0] = plen >> 8;
+ udp_hdr->len[1] = (unsigned char) plen;
+ /* leave csum 0 */
+
+ /* Set up IP */
+ memset(ip_hdr, 0, sizeof(ip_hdr_t));
+ ip_hdr->ver_hlen = 0x45; /* IPv4 with 20 byte header */
+ plen += sizeof(ip_hdr_t);
+ ip_hdr->tlen[0] = plen >> 8;
+ ip_hdr->tlen[1] = (unsigned char) plen;
+ ip_hdr->id[0] = ip_id >> 8;
+ ip_hdr->id[1] = (unsigned char) ip_id;
+ ip_id++;
+ ip_hdr->ttl = 32; /* max 32 hops */
+ ip_hdr->proto = UDP_PROTO;
+ memset(ip_hdr->da, 0xFF, IP_ADDR_LEN);
+ fix_checksum((unsigned char *)ip_hdr, sizeof(ip_hdr_t), 10);
+ /* Set up Ethernet */
+ eth_hdr->type_code[0] = ETH_TYPE_0;
+ eth_hdr->type_code[1] = ETH_TYPE_IP_1;
+ memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);
+ memset(eth_hdr->da, 0xFF, ETH_ADDR_LEN); /* broadcast */
+ num_pkt_tx++;
+ MSS_MAC_tx_packet(tcp_packet,plen + sizeof(ether_hdr_t), MSS_MAC_BLOCKING);
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+void send_dhcp_server_packet (unsigned char *buf)
+{
+ unsigned char * tcp_packet = tcp_packet;
+ /* output packet */
+ eth_hdr_xp eth_hdr = (eth_hdr_xp ) tcp_packet;
+ ip_hdr_xp ip_hdr = (ip_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t));
+ udp_hdr_xp udp_hdr = (udp_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));
+ bootp_pkt_xp bootp_pkt = (bootp_pkt_xp )((unsigned char *)udp_hdr + sizeof(udp_hdr_t));
+ unsigned char *opts = bootp_pkt->vend;
+
+ /* input packet */
+ eth_hdr_xp ieth_hdr = (eth_hdr_xp ) buf;
+ // ip_hdr_xp iip_hdr = (ip_hdr_xp ) (buf + sizeof(ether_hdr_t));
+ udp_hdr_xp iudp_hdr = (udp_hdr_xp ) (buf + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));
+ bootp_pkt_xp ibootp_pkt = (bootp_pkt_xp )((unsigned char *)iudp_hdr + sizeof(udp_hdr_t));
+ unsigned char *iopts = ibootp_pkt->vend;
+
+ unsigned short int plen;
+
+ /* Set up Bootp */
+ memset(bootp_pkt, 0, sizeof(bootp_pkt_t));
+ bootp_pkt->op = BOOTP_OP_REPLY;
+ bootp_pkt->hwtype = BOOTP_HWTYPE_ETH;
+ bootp_pkt->hlen = ETH_ADDR_LEN;
+ bootp_pkt->secs[1] = 0x64;
+ memcpy(bootp_pkt->chaddr, ieth_hdr->sa, ETH_ADDR_LEN);
+ bootp_pkt->flags[0] = 0x00;
+ if (buf) {
+ memcpy(bootp_pkt->ciaddr, ibootp_pkt->yiaddr, IP_ADDR_LEN);
+ memcpy(bootp_pkt->yiaddr, g_client_ip, IP_ADDR_LEN);
+ memcpy(bootp_pkt->xid, ibootp_pkt->xid, BOOTP_XID_LEN);
+ } else {
+ bootp_pkt->xid[0] = 0x90;
+ }
+ *opts++ = 99; /* magic number */
+ *opts++ = 130;
+ *opts++ = 83;
+ *opts++ = 99;
+ *opts++ = BOOTP_OPTCODE_DHCP_TYPE;
+ *opts++ = 1;
+ if (iopts[6] == DHCP_TYPE_DISCOVER)
+ {
+ *opts++ = DHCP_TYPE_OFFER;
+ }
+ else
+ {
+ *opts++ = DHCP_TYPE_ACK;
+ }
+ /* Server ID */
+ *opts++ = BOOTP_OPTCODE_DHCP_SID;
+ *opts++ = 4;
+ *opts++ = my_ip[0];
+ *opts++ = my_ip[1];
+ *opts++ = my_ip[2];
+ *opts++ = my_ip[3];
+ /* Lease time (1 our) */
+ *opts++ = BOOTP_OPTCODE_DHCP_LEASE;
+ *opts++ = 4;
+ *opts++ = 0x00;
+ *opts++ = 0x00;
+ *opts++ = 0x0E;
+ *opts++ = 0x10;
+ /* Renewal time */
+ *opts++ = BOOTP_OPTCODE_DHCP_RENEW;
+ *opts++ = 4;
+ *opts++ = 0x00;
+ *opts++ = 0x00;
+ *opts++ = 0x07;
+ *opts++ = 0x08;
+ /* Rebinding time */
+ *opts++ = BOOTP_OPTCODE_DHCP_REBIND;
+ *opts++ = 4;
+ *opts++ = 0x00;
+ *opts++ = 0x00;
+ *opts++ = 0x0C;
+ *opts++ = 0x4E;
+ /* Subnet mask */
+ *opts++ = BOOTP_OPTCODE_DHCP_SUBNET;
+ *opts++ = 4;
+ *opts++ = 0xFF;
+ *opts++ = 0xFF;
+ *opts++ = 0xFF;
+ *opts++ = 0x00;
+ /* Router */
+ *opts++ = BOOTP_OPTCODE_DHCP_ROUTER;
+ *opts++ = 4;
+ *opts++ = my_ip[0];
+ *opts++ = my_ip[1];
+ *opts++ = my_ip[2];
+ *opts++ = my_ip[3];
+ /* Domain */
+ *opts++ = BOOTP_OPTCODE_DHCP_DOMAIN;
+ *opts++ = 4;
+ *opts++ = my_ip[0];
+ *opts++ = my_ip[1];
+ *opts++ = my_ip[2];
+ *opts++ = my_ip[3];
+
+ *opts++ = BOOTP_OPTCODE_END;
+
+ /* Set up Udp */
+ memset(udp_hdr, 0, sizeof(udp_hdr_t));
+ udp_hdr->sp[1] = BOOTP_SERVER_PORT;
+ udp_hdr->dp[1] = BOOTP_CLIENT_PORT;
+ plen = sizeof(udp_hdr_t) + sizeof(bootp_pkt_t);
+ udp_hdr->len[0] = plen >> 8;
+ udp_hdr->len[1] = (unsigned char) plen;
+ /* leave csum 0 */
+
+ /* Set up IP */
+ memset(ip_hdr, 0, sizeof(ip_hdr_t));
+ ip_hdr->ver_hlen = 0x45; /* IPv4 with 20 byte header */
+ plen += sizeof(ip_hdr_t);
+ ip_hdr->tlen[0] = plen >> 8;
+ ip_hdr->tlen[1] = (unsigned char) plen;
+ ip_hdr->id[0] = ip_id >> 8;
+ ip_hdr->id[1] = (unsigned char) ip_id;
+ ip_id++;
+ ip_hdr->ttl = 255;
+ ip_hdr->proto = UDP_PROTO;
+ memcpy(ip_hdr->sa, my_ip, IP_ADDR_LEN);
+ memset(ip_hdr->da, 0xFF, IP_ADDR_LEN);
+ fix_checksum((unsigned char *)ip_hdr, sizeof(ip_hdr_t), 10);
+
+ /* Set up Ethernet */
+ eth_hdr->type_code[0] = ETH_TYPE_0;
+ eth_hdr->type_code[1] = ETH_TYPE_IP_1;
+ memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);
+ memset(eth_hdr->da, 0xFF, ETH_ADDR_LEN); /* broadcast */
+ num_pkt_tx++;
+ MSS_MAC_tx_packet(tcp_packet,plen + sizeof(ether_hdr_t), MSS_MAC_BLOCKING);
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char process_udp_packet (unsigned char *buf)
+{
+
+ udp_hdr_xp udp_hdr = (udp_hdr_xp ) (buf + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));
+
+ if (udp_hdr->dp[1] != BOOTP_CLIENT_PORT) {
+ send_dhcp_server_packet( buf );
+ return OK;
+ }
+ if (ip_known) {
+ return ERR;
+ }
+ /* some more error checking here? */
+ send_bootp_packet(buf);
+ return OK;
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+
+void send_tcp_packet (unsigned char control_bits,unsigned short int buflen)
+{
+
+ eth_hdr_xp eth_hdr = (eth_hdr_xp ) tcp_packet;
+ ip_hdr_xp ip_hdr = (ip_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t));
+ tcp_hdr_xp tcp_hdr = (tcp_hdr_xp )
+ (tcp_packet + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));
+ tcp_pseudo_hdr_xp tcp_pseudo_hdr = (tcp_pseudo_hdr_xp )
+ (((unsigned char *)tcp_hdr) - sizeof(tcp_pseudo_hdr_t));
+ unsigned char *tcp_data = tcp_packet + sizeof(ether_hdr_t) + sizeof(ip_hdr_t) + sizeof (tcp_hdr_t);
+ unsigned char *seqp = (unsigned char *)(&tcb.local_seq);
+ unsigned short int plen;
+ memset(tcp_hdr, 0, sizeof(tcp_hdr_t));
+ memcpy(tcp_hdr->sp, tcb.local_port, TCP_PORT_LEN);
+ memcpy(tcp_hdr->dp, tcb.remote_port, TCP_PORT_LEN);
+ tcp_hdr->seqnum[0] = seqp[3];
+ tcp_hdr->seqnum[1] = seqp[2];
+ tcp_hdr->seqnum[2] = seqp[1];
+ tcp_hdr->seqnum[3] = seqp[0];
+ tcb.local_seq++;
+ if (buflen) {
+ tcb.local_seq += buflen - 1;
+ }
+ if (control_bits & TCP_CNTRL_ACK) {
+ seqp = (unsigned char *)(&tcb.remote_seq);
+ tcp_hdr->acknum[3] = seqp[0];
+ tcp_hdr->acknum[2] = seqp[1];
+ tcp_hdr->acknum[1] = seqp[2];
+ tcp_hdr->acknum[0] = seqp[3];
+ }
+ tcp_hdr->data_off = 0x50; /* always 5 32 bit words for us */
+ tcp_hdr->urg_ack_psh_rst_syn_fin = control_bits;
+ tcp_hdr->wsize[0] = 0x08; /* this is 0x0800, which is 2K */
+ if (buflen & 1) {
+ tcp_data[buflen] = 0;
+ }
+ /* memset(tcp_pseudo_hdr, 0, sizeof(tcp_pseudo_hdr_t)); */
+ memcpy(tcp_pseudo_hdr->sa, my_ip, IP_ADDR_LEN);
+ memcpy(tcp_pseudo_hdr->da, tcb.remote_addr, IP_ADDR_LEN);
+ tcp_pseudo_hdr->zero = 0;
+ tcp_pseudo_hdr->proto = TCP_PROTO;
+ plen = buflen + sizeof(tcp_hdr_t);
+ tcp_pseudo_hdr->plen[0] = plen >> 8;
+ tcp_pseudo_hdr->plen[1] = (unsigned char)plen;
+ fix_checksum((unsigned char *)tcp_pseudo_hdr,
+ (unsigned short int)(plen + sizeof(tcp_pseudo_hdr_t)), (unsigned short int)28);
+
+ memset(ip_hdr, 0, sizeof(ip_hdr_t));
+
+ ip_hdr->ver_hlen = 0x45; /* IPv4 with 20 byte header */
+ plen += sizeof(ip_hdr_t); /* add the size of the IP Header */
+ ip_hdr->tlen[0] = plen >> 8;
+ ip_hdr->tlen[1] = (unsigned char) plen;
+ ip_hdr->id[0] = ip_id >> 8;
+ ip_hdr->id[1] = (unsigned char) ip_id;
+ ip_id++;
+ ip_hdr->ttl = 32; /* max 32 hops */
+ ip_hdr->proto = TCP_PROTO;
+ memcpy(ip_hdr->sa, my_ip, IP_ADDR_LEN);
+ memcpy(ip_hdr->da, tcb.remote_addr, IP_ADDR_LEN);
+ fix_checksum((unsigned char *)ip_hdr, sizeof(ip_hdr_t), 10);
+ /* Fix the Ethernet Header */
+ eth_hdr->type_code[0] = ETH_TYPE_0;
+ eth_hdr->type_code[1] = ETH_TYPE_IP_1;
+ memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);
+ memcpy(eth_hdr->da, tcb.remote_mac, ETH_ADDR_LEN); /* should be table lookup */
+ num_pkt_tx++;
+ MSS_MAC_tx_packet(tcp_packet,plen + sizeof(ether_hdr_t), MSS_MAC_BLOCKING);
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char tcp_init(void)
+{
+ memset(&tcb,0,sizeof(tcp_control_block_t));
+ tcb.state = TCP_STATE_LISTEN;
+ ip_id = 0;
+ ip_known = 0;
+ return OK;
+}
+
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char hex_digits_to_byte(unsigned char u, unsigned char l)
+{
+ if (u > '9')
+ u = u - 'A' + 10;
+ else
+ u = u - '0';
+ if (l > '9')
+ l = l - 'A' + 10;
+ else
+ l = l - '0';
+ return (u << 4) + l;
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char process_icmp_packet(unsigned char *buf)
+{
+ ip_hdr_xp ip_hdr = (ip_hdr_xp ) (buf + sizeof (ether_hdr_t));
+ icmp_hdr_xp icmp_hdr = (icmp_hdr_xp )
+ (buf + sizeof (ether_hdr_t) + sizeof(ip_hdr_t));
+ unsigned short int elen = ((unsigned short int)ip_hdr->tlen[0] << 8) + (unsigned short int)ip_hdr->tlen[1] - sizeof(ip_hdr_t);
+ if (check_checksum((unsigned char *)icmp_hdr, (unsigned short int) elen, (unsigned short int) 2, 'M') != OK)
+ return ERR;
+ if (icmp_hdr->type != ICMP_TYPE_ECHO_REQUEST) {
+ return ERR;
+ }
+ return send_icmp_echo_reply(buf);
+}
+
+ /* See tcpip.h for more information.
+ */
+
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char process_tcp_packet(unsigned char *buf)
+{
+ eth_hdr_xp eth_hdr = (eth_hdr_xp )buf;
+ ip_hdr_xp ip_hdr = (ip_hdr_xp ) (buf + sizeof (ether_hdr_t));
+ tcp_hdr_xp tcp_hdr = (tcp_hdr_xp )
+ (buf + sizeof (ether_hdr_t) + sizeof(ip_hdr_t));
+ unsigned short int elen = ((unsigned short int)ip_hdr->tlen[0] << 8) + (unsigned short int)ip_hdr->tlen[1] - sizeof(ip_hdr_t);
+ unsigned char state;
+ if ( !memcmp(tcb.remote_addr, ip_hdr->sa, IP_ADDR_LEN) && /* same source IP */
+ !memcmp(tcb.remote_port, tcp_hdr->sp, TCP_PORT_LEN) && /* same source port */
+ !memcmp(tcb.local_port, tcp_hdr->dp, TCP_PORT_LEN)) { /* same dest port */
+ state = tcb.state;
+ } else { /* copy it over, a new IP wants in */
+ memcpy(tcb.remote_addr, ip_hdr->sa, IP_ADDR_LEN);
+ memcpy(tcb.remote_port, tcp_hdr->sp, TCP_PORT_LEN);
+ memcpy(tcb.local_port, tcp_hdr->dp, TCP_PORT_LEN);
+ memcpy(tcb.remote_mac, eth_hdr->sa, ETH_ADDR_LEN);
+ state = TCP_STATE_LISTEN;
+ }
+ switch (state) {
+ case TCP_STATE_LISTEN:
+ if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_SYN) {
+ /* recd SYN : new connection; send SYN+ACK */
+
+ tcb.local_seq = TCP_START_SEQ;
+ tcb.remote_seq = 0;
+ tcb.remote_seq = (tcb.remote_seq | tcp_hdr->seqnum[0]);
+ tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[1]);
+ tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[2]);
+ tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[3]);
+ tcb.remote_seq++;
+ send_tcp_packet( TCP_CNTRL_SYN | TCP_CNTRL_ACK, 0);
+ tcb.state = TCP_STATE_SYN_RECVD;
+ }
+ break;
+ case TCP_STATE_SYN_RECVD:
+ if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_ACK) {
+ /* recd ack; send nothing */
+ tcb.state = TCP_STATE_ESTABLISHED;
+ }
+ else {
+ tcb.state = TCP_STATE_LISTEN;
+ }
+ break;
+ case TCP_STATE_ESTABLISHED:
+ if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_FIN) {
+ /* recd fin; send ack */
+ /* skip CLOSE_WAIT state; send fin along with ack */
+ tcb.remote_seq = 0;
+ tcb.remote_seq = (tcb.remote_seq | tcp_hdr->seqnum[0]);
+ tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[1]);
+ tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[2]);
+ tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[3]);
+ tcb.remote_seq++;
+ send_tcp_packet(TCP_CNTRL_ACK | TCP_CNTRL_FIN, 0);
+ tcb.state = TCP_STATE_LAST_ACK;
+ /* Default scroll message on OLED */
+ }
+ else if (tcp_hdr->dp[0] != 0 || \
+ tcp_hdr->dp[1] != 80) { /* HTTP Port */
+ break;
+ }
+ else if (elen > sizeof(tcp_hdr_t)) { /* dont respond to empty packets*/
+ tcb.remote_seq = 0;
+ tcb.remote_seq = (tcb.remote_seq | tcp_hdr->seqnum[0]);
+ tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[1]);
+ tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[2]);
+ tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[3]);
+ tcb.remote_seq += (unsigned long) (elen - sizeof(tcp_hdr_t));
+ //send_http_response(((unsigned char *)(tcp_hdr)) + sizeof (tcp_hdr_t));
+ tcb.state = TCP_STATE_MY_LAST;
+ }
+ break;
+ case TCP_STATE_MY_LAST:
+ if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_FIN) {
+ /* sent fin, got fin, ack the fin */
+ tcb.remote_seq = 0;
+ tcb.remote_seq = (tcb.remote_seq | tcp_hdr->seqnum[0]);
+ tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[1]);
+ tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[2]);
+ tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[3]);
+ tcb.remote_seq++;
+ send_tcp_packet(TCP_CNTRL_ACK, 0);
+ tcb.state = TCP_STATE_CLOSED;
+ }
+ break;
+ case TCP_STATE_LAST_ACK:
+
+ if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_ACK) {
+ /* recd ack; send nothing */
+ tcb.state = TCP_STATE_CLOSED;
+ }
+ /* no break here... go on to CLOSED directly */
+ case TCP_STATE_CLOSED:
+ memset (&tcb, 0, sizeof (tcp_control_block_t));
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char process_ip_packet(unsigned char *buf)
+{
+ ip_hdr_xp ip_hdr = (ip_hdr_xp ) (buf + sizeof (ether_hdr_t));
+ /* Is the incoming pkt for me?
+ (either explicity addressed to me or a broadcast address) */
+ if (memcmp(my_ip, ip_hdr->da, IP_ADDR_LEN)) /* not my IP */ {
+ if (ip_known) {
+ return ERR;
+ }
+ if (ip_hdr->da[0] != 0xFF || ip_hdr->da[1] != 0xFF ||
+ ip_hdr->da[2] != 0xFF || ip_hdr->da[3] != 0xFF) {
+ return ERR;
+ }
+ }
+ if (check_checksum((unsigned char *)ip_hdr, (unsigned short int) 20, (unsigned short int) 10, 'I') != OK)
+ return ERR;
+ switch (ip_hdr->proto)
+ {
+ case TCP_PROTO:
+ return process_tcp_packet(buf);
+ case ICMP_PROTO:
+ return process_icmp_packet(buf);
+ case UDP_PROTO:
+ return process_udp_packet(buf);
+ default: {
+ return ERR;
+ }
+ }
+ return ERR;
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char process_arp_packet(unsigned char *buf)
+{
+ arp_pkt_xp arp_pkt = (arp_pkt_xp )(buf + sizeof(ether_hdr_t));
+ if (arp_pkt->opcode[1] != ARP_OPCODE_REQ_1) {
+ if (arp_pkt->opcode[1] == ARP_OPCODE_REPLY_1)
+ {
+ if (!memcmp(my_ip, arp_pkt->ip_sa, IP_ADDR_LEN))
+ {
+ //printf("IP conflict with MAC");
+ //printf("%02x:%02x:%02x:%02x:%02x:%02x",arp_pkt->mac_sa[0],arp_pkt->mac_sa[1],arp_pkt->mac_sa[2],arp_pkt->mac_sa[3],arp_pkt->mac_sa[4],arp_pkt->mac_sa[5]);
+ }
+ }
+ return ERR;
+ }
+ if (memcmp(my_ip, arp_pkt->ip_ta, IP_ADDR_LEN)) {
+ return ERR;
+ }
+ return send_arp_reply(buf);
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char process_packet( unsigned char * buf )
+{
+ eth_hdr_xp eth_hdr;
+ unsigned char typ;
+ eth_hdr = (eth_hdr_xp ) buf;
+ typ = eth_hdr->type_code[0];
+ if (typ != ETH_TYPE_0)
+ {
+ return ERR;
+ }
+ typ = eth_hdr->type_code[1];
+ if (typ == ETH_TYPE_ARP_1)
+ {
+ return process_arp_packet(buf);
+ }
+ else if (typ == ETH_TYPE_IP_1) {
+ return process_ip_packet(buf);
+ }
+ else
+ {
+ return ERR;
+ }
+ return ERR;
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+unsigned char *xstrcpy(unsigned char *d, const unsigned char *s)
+{
+ unsigned char c;
+
+ while ((c = *s++))
+ (*d++ = c) ;
+ return d;
+}
+/***************************************************************************//**
+ * See tcpip.h for more information.
+ */
+// updated html page with fusion board link on page:
+
diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mac/tcpip.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mac/tcpip.h
new file mode 100644
index 000000000..9b7d06fea
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mac/tcpip.h
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * (c) Copyright 2009 SLS Corporation,All Rights Reserved.
+ *
+ * tcpip.h:header file of TCP/IP implementation.
+ *
+ * Version Author Comment
+ * 1.0.0 SLS corp. First release,16 Jan 2009
+ */
+#ifndef TCPIP_H_
+#define TCPIP_H_
+
+#define FLASH_CONTEXT_INDICATOR 0x20000000
+#define FLASH_SELFWAKEUP_INDICATOR 0x20000001
+#define FLASH_CONTEXT_LOCATION 0x20000002
+
+/***************************************************************************//**
+ * Replies to ARP requests.
+ *
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ *
+ */
+unsigned char send_arp_reply(unsigned char *buf);
+/***************************************************************************//**
+ * Sends gratuitous arp brodcast message to the LAN.
+ *
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ *
+ */
+void send_gratuitous_arp(unsigned char *buf);
+/***************************************************************************//**
+ * Calculates the checksum for Ethernet data in the header.
+ *
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ * @param len Number of bytes.
+ * @param pos position for the check sum.
+ *
+ * @return value of the checksum
+ */
+unsigned short int get_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos);
+/***************************************************************************//**
+ * Calls internally to get_checksum and fixes the value of the checksum to
+ * position.
+ *
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ * @param len Number of bytes.
+ * @param pos position for the check sum.
+ *
+ * @return OK
+ */
+unsigned char fix_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos);
+/***************************************************************************//**
+ * Checks the calculated checksum for the errors.
+ *
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ * @param len Number of bytes.
+ * @param pos position for the check sum.
+ *
+ * @return OK If there is no error
+ * ERR If there is error in the data
+ */
+unsigned char check_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos, char type);
+/***************************************************************************//**
+ * Sends the reply to ICMP request like PING.
+ *
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ */
+unsigned char send_icmp_echo_reply(unsigned char *buf);
+/***************************************************************************//**
+ * Converts the input integer to the ascii char and fills in the buffer.
+ *
+ * @param buf To filled in by the ascii value.
+ * @param n integer number
+ */
+void dtoa_reverse(unsigned short int n, unsigned char *buf);
+/***************************************************************************//**
+ * Sends DHCP request to the server available in LAN.
+ *
+ * @param buf Pointer to the recieved data in case of DHCP reply.Zero for request.
+ */
+void send_bootp_packet (unsigned char *buf);
+/***************************************************************************//**
+ * Processes the UDP datagram.
+ *
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ */
+unsigned char process_udp_packet (unsigned char *buf);
+/***************************************************************************//**
+ * Sends TCP packet to the network.
+ *
+ * @param buf Pointer to the transmitt buffer to Ethernet MAC.
+ */
+void send_tcp_packet (unsigned char control_bits,unsigned short int buflen);
+/***************************************************************************//**
+ * Initialize TCP for the software TCP/IP stack.
+ *
+ * @return OK
+ */
+unsigned char tcp_init(void);
+/***************************************************************************//**
+ * Converts two hex decimal ascii digits into a sigle integer digit.
+ *
+ * @param u ascii hex digit
+ * l ascii hex digit
+ * @returm converted integer byte
+ *
+ */
+unsigned char hex_digits_to_byte(unsigned char u, unsigned char l);
+/***************************************************************************//**
+ * Processes ICMP packets
+ *
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ *
+ * @return ERR if there is an error in the data
+ * or calls further necessary functions.
+ */
+unsigned char process_icmp_packet(unsigned char *buf);
+/***************************************************************************//**
+ * Sends logo of ACTEL on the network over HTTP protocol.
+ * @return OK
+ */
+unsigned char http_send_logo ();
+/***************************************************************************//**
+ * Sends appropriate answer to the different HTTP requests.
+ *
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ * @return OK
+ */
+unsigned char send_http_response(unsigned char *buf);
+/***************************************************************************//**
+ * Process incoming TCP requests and handles the TCP state machine.
+ *
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ * @return OK
+ */
+unsigned char process_tcp_packet(unsigned char *buf);
+/***************************************************************************//**
+ * Process incoming IP datagrams and handles the TCP state machine.
+ *
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ * @return OK
+ */
+unsigned char process_ip_packet(unsigned char *buf);
+/***************************************************************************//**
+ * Processes the ARP packets.
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ * @return OK
+ */
+unsigned char process_arp_packet(unsigned char *buf);
+/***************************************************************************//**
+ * Processes incoming packets and identifies its type.
+ *
+ * @param buf Pointer to the recieved buffer from Ethernet MAC.
+ * @return call the function for further process
+ * ERR if any error
+ */
+unsigned char process_packet( unsigned char * buf );
+/***************************************************************************//**
+ * copies source string to destination address.
+ *
+ * @param d Pointer to the destination
+ * @param s Pointer to the source
+ * @return The last location after copy
+ *
+ */
+unsigned char *xstrcpy(unsigned char *d, const unsigned char *s);
+/***************************************************************************//**
+ * Sends the home page of the demonstration webserver.
+ *
+ */
+void http_send_packet();
+/***************************************************************************//**
+ * Sends the packet for waveform mode.
+ *
+ */
+void http_send_packet_waveform();
+/***************************************************************************//**
+ * Sends the packet for multimeter mode.
+ *
+ */
+void http_send_packet_multimeter();
+/***************************************************************************//**
+ * Sends the packet for DAC mode.
+ *
+ */
+void http_send_packet_DAC();
+/***************************************************************************//**
+ * Sends the packet for sleeping stopwatch.
+ *
+ */
+void http_send_packet_SLEEPING_STOPWATCH();
+/***************************************************************************//**
+ * Sends the packet for text terminal.
+ *
+ */
+void http_send_packet_textterminal();
+/***************************************************************************//**
+ * Sends the packet for VIT auxiliary mode.
+ *
+ */
+void http_send_packet_VIT();
+/***************************************************************************//**
+ * Sends the packet for Real Time Data Display.
+ *
+ */
+void http_send_packet_RTDD();
+/***************************************************************************//**
+ * Sends the packet for Stock Ticker.
+ *
+ */
+void http_send_packet_Stockticker();
+/***************************************************************************//**
+ * Sends the packet for Gadgets mode.
+ *
+ */
+void http_send_packet_weatherblog();
+/***************************************************************************//**
+ * Sends the packet for Selfwakeup.
+ *
+ */
+void http_send_packet_SELFWAKEUP();
+/***************************************************************************//**
+ * Same as above mentioned functions but following functions are applicable
+ * to Internet Explorer.
+ *
+ */
+void http_send_packet_IE();
+void http_send_packet_SELFWAKEUP_IE();
+void http_send_packet_VIT_IE();
+void http_send_packet_waveform_IE();
+void http_send_packet_SLEEPING_STOPWATCH_IE();
+void http_send_packet_DAC_IE();
+void http_send_packet_multimeter_IE();
+void http_send_packet_RTDD_IE();
+#endif /*TCPIP_H_*/
diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_convert.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_convert.c
new file mode 100644
index 000000000..dbe1205ba
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_flags.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_flags.c
new file mode 100644
index 000000000..926a80dc2
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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
+
+#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_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_sse.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_sse.c
new file mode 100644
index 000000000..eefb06b18
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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
+
+#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_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_transform.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_transform.c
new file mode 100644
index 000000000..0a44a6aae
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_ace/envm_layout.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/envm_layout.h
new file mode 100644
index 000000000..0081310d7
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace.c
new file mode 100644
index 000000000..cd717f036
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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
+
+#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_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace.h
new file mode 100644
index 000000000..ec4f00ed7
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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
+
+#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_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace_configurator.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace_configurator.h
new file mode 100644
index 000000000..2621f5375
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_ace/mtd_data.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/mtd_data.h
new file mode 100644
index 000000000..431f28f78
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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
+
+#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_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.c
new file mode 100644
index 000000000..fc17e5298
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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> 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_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.h
new file mode 100644
index 000000000..ce500a6f2
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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
+
+#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_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c
new file mode 100644
index 000000000..daebab325
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c
@@ -0,0 +1,1527 @@
+/***************************************************************************//**
+ * @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 "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); ASSERT((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)
+
+/***************************************************************/
+MAC_instance_t g_mss_mac;
+
+/**************************** 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;
+
+/**************************** 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);
+
+/***************************************************************************//**
+ * 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;
+
+ /* Try to reset chip */
+ MAC_BITBAND->CSR0_SWR = 1u;
+
+ while ( 1u == MAC_BITBAND->CSR0_SWR )
+ {
+ ;
+ }
+
+ /* Check reset values of some registers to constrol
+ * base address validity */
+ ASSERT( MAC->CSR0 == 0xFE000000uL );
+ ASSERT( MAC->CSR5 == 0xF0000000uL );
+ ASSERT( 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; aCSR0_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();
+ ASSERT( 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 );
+
+
+ /* Start receiving and transmission */
+ MAC_start_receiving();
+ MAC_start_transmission();
+}
+
+
+/***************************************************************************//**
+ * 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;
+
+ ASSERT( MAC_test_instance() == MAC_OK );
+
+ ret = MAC_stop_transmission();
+ ASSERT( ret == MAC_OK );
+
+ ret = MAC_stop_receiving();
+ ASSERT( 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 )) );
+
+ MAC_start_transmission();
+ MAC_start_receiving();
+
+ 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;
+
+ ASSERT( 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 to the Ethernet Controller.
+ The MSS_MAC_tx_packet() function is used to send a packet to the MSS Ethernet
+ MAC. This function writes pacLen bytes of the packet contained in pacData into
+ the transmit FIFO and then activates the transmitter for this packet. If space
+ is available in the FIFO, the function will return once pacLen 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. If space is not
+ available in FIFO, the function will keep trying until time_out expires. The
+ function will wait for the transmission to complete when the time_out parameter
+ is set to MSS_MAC_BLOCKING.
+
+ @param pacData
+ The pacData parameter is a pointer to the packet data to be transmitted.
+
+ @param pacLen
+ The pacLen parameter is the number of bytes in the packet to be transmitted.
+
+ @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 the MSS Ethernet
+ MAC does not have any available transmit descriptor. This would happen when
+ several packets are already queued into the MSS Ethernet MAC transmit descriptor FIFO.
+
+ @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
+(
+ const uint8_t *pacData,
+ uint16_t pacLen,
+ uint32_t time_out
+)
+{
+ uint32_t desc;
+ int32_t error = MAC_OK;
+
+ ASSERT( MAC_test_instance() == MAC_OK );
+
+ ASSERT( pacData != NULL_buffer );
+
+ ASSERT( pacLen >= 12 );
+
+ if( (g_mss_mac.flags & FLAG_EXCEED_LIMIT) == 0u )
+ {
+ ASSERT( pacLen <= MSS_MAX_PACKET_SIZE );
+ }
+
+ ASSERT( (time_out == MSS_MAC_BLOCKING) ||
+ (time_out == MSS_MAC_NONBLOCKING) ||
+ ((time_out >= 1) && (time_out <= 0x01000000uL)) );
+
+ if( time_out == MSS_MAC_NONBLOCKING )
+ {
+ /* Check if current descriptor is free */
+ if(((g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0) & TDES0_OWN) == TDES0_OWN )
+ {
+ error = MAC_BUFFER_IS_FULL;
+ }
+ }
+ else
+ {
+ /* Wait until descriptor is free */
+ if( time_out != MSS_MAC_BLOCKING ) {
+ MAC_set_time_out( time_out );
+ }
+
+ while( (((g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0) & TDES0_OWN) == TDES0_OWN )
+ && (error == MAC_OK) )
+ {
+ /* transmit poll demand */
+ MAC->CSR1 = 1u;
+
+ if(time_out != MSS_MAC_BLOCKING){
+ if(MAC_get_time_out() == 0u) {
+ error = MAC_TIME_OUT;
+ }
+ }
+ }
+ }
+
+ if( error == MAC_OK ) {
+
+ g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 = 0u;
+
+ if( (g_mss_mac.flags & FLAG_CRC_DISABLE) != 0u ) {
+ g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_AC;
+ }
+
+ /* Every buffer can hold a full frame so they are always first and last
+ descriptor */
+ g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_LS | TDES1_FS;
+
+ /* set data size */
+ g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= pacLen;
+
+ /* reset end of ring */
+ g_mss_mac.tx_descriptors[TX_RING_SIZE-1].descriptor_1 |= TDES1_TER;
+
+ /* copy data into buffer */
+ if( pacLen > MSS_TX_BUFF_SIZE ) /* FLAG_EXCEED_LIMIT */
+ {
+ pacLen = (uint16_t)MSS_TX_BUFF_SIZE;
+ }
+ MAC_memcpy(
+ (uint8_t*)
+ g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].buffer_1,
+ pacData, (uint32_t)pacLen );
+
+ /* update counters */
+ desc = g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].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[ g_mss_mac.tx_desc_index ].descriptor_0 = RDES0_OWN;
+
+ g_mss_mac.tx_desc_index = (g_mss_mac.tx_desc_index + 1u) % (uint32_t)TX_RING_SIZE;
+
+ /* Start transmission */
+ MAC_start_transmission();
+
+ /* transmit poll demand */
+ MAC->CSR1 = 1u;
+ }
+
+ if (error == MAC_OK)
+ {
+ error = (int32_t)pacLen;
+ }
+ 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;
+ ASSERT( 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.
+ * This function reads a packet from the receive FIFO of the controller and
+ * places it into pacData. 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 pacLen The pacLen parameter is the size in bytes of the pacData
+ * buffer where the received data will be copied.
+ * @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
+(
+ uint8_t *pacData,
+ uint16_t pacLen,
+ uint32_t time_out
+)
+{
+ uint16_t frame_length=0u;
+ int8_t exit=0;
+
+ ASSERT( MAC_test_instance() == MAC_OK );
+
+ ASSERT( pacData != NULL_buffer );
+
+ ASSERT( (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;
+
+ if( frame_length > pacLen ) {
+ return MAC_NOT_ENOUGH_SPACE;
+ }
+
+ MAC_memcpy( pacData,
+ (uint8_t*)
+ g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1,
+ (uint32_t)frame_length );
+
+ 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;
+
+ ASSERT( MAC_test_instance() == MAC_OK );
+
+ ASSERT( (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;
+
+ ASSERT( 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;
+ ASSERT( 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
+)
+{
+ ASSERT( MAC_test_instance() == MAC_OK );
+ /* Check if the new address is unicast */
+ ASSERT( (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
+)
+{
+ ASSERT( 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
+)
+{
+ ASSERT( MAC_test_instance() == MAC_OK );
+ ASSERT( (filter_count==0) || (filters != NULL_buffer) );
+ /* Check if the mac addresses is multicast */
+ {
+ int32_t a;
+ for( a = 0u; a < filter_count; a++ ) {
+ ASSERT( (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; aCSR5;
+
+ 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
+)
+{
+ ASSERT( 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;
+
+ ASSERT( 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;
+ ASSERT( 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();
+ ASSERT( ret == MAC_OK );
+
+ ret = MAC_stop_receiving();
+ ASSERT( 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; countrx_buffers[count], (uint8_t)c, (MSS_RX_BUFF_SIZE + 4u) );
+ }
+ s->rx_desc_index =c;
+ for(count = 0; countrx_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];
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/******************************** END OF FILE *********************************/
+
diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.h
new file mode 100644
index 000000000..3b84dccf6
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.h
@@ -0,0 +1,595 @@
+/***************************************************************************//**
+ * @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
+
+#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
+ * 1 - Forcing full-duplex mode
+ * 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.
+ * 1 - Imperfect filtering over the frames with the multicast addresses is performed
+ * according to the hash table specified in a setup frame.
+ * 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 to the Ethernet Controller.
+ * This function writes pacLen bytes of the packet contained in pacData into the
+ * transmit FIFO of the controller and then activates the transmitter for this
+ * packet. If space is available in FIFO, the function will return once lBufLen
+ * bytes of the packet have been placed into the FIFO and the transmitter has been
+ * started. The function will not wait for the transmission to complete. If space
+ * is not available in FIFO, the function will keep trying till time_out expires,
+ * if MSS_MAC_BLOCKING value is given as time_out, function will wait for the
+ * transmission to complete.
+ *
+ * @param pacData the pointer to the packet data to be transmitted.
+ * @param pacLen number of bytes in the packet to be transmitted.
+ * @param time_out Time out value for transmision.
+ * If value is #MSS_MAC_BLOCKING, there will be no time out.
+ * If value is #MSS_MAC_NONBLOCKING, function will return immediately
+ * on buffer full case.
+ * Otherwise value must be greater than 0 and smaller than
+ * 0x01000000.
+ * @return Returns 0 if time out occurs otherwise returns size
+ * of the packet.
+ * @see MAC_rx_packet()
+ */
+int32_t
+MSS_MAC_tx_packet
+(
+ const uint8_t *pacData,
+ uint16_t pacLen,
+ uint32_t time_out
+);
+
+
+/***************************************************************************//**
+ * 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.
+ * This function reads a packet from the receive FIFO of the controller and
+ * places it into pacData. 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 pacData The pointer to the buffer where received packet data will
+ * be copied. Memory for the buffer should be allocated prior
+ * to calling this function.
+ * @param pacLen Size of the buffer, which the received data will be copied in,
+ * given in number of bytes.
+ * @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
+(
+ uint8_t *pacData,
+ uint16_t pacLen,
+ uint32_t time_out
+);
+
+
+/***************************************************************************//**
+ 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
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_ETHERNET_MAC_H */
+
diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_conf.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_conf.h
new file mode 100644
index 000000000..a841e7293
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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 0xC0u,0xB1u,0x3Cu,0x88u,0x88u,0x88u
+#define BROADCAST_MAC_ADDRESS 0xFFu,0xFFu,0xFFu,0xFFu,0xFFu,0xFFu
+
+/**
+ * Descriptor byte ordering mode.
+ * 1 - Big-endian mode used for data descriptors
+ * 0 - Little-endian mode used for data descriptors
+ */
+#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_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_desc.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_desc.h
new file mode 100644
index 000000000..dc697f11a
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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.
+ * 0 - The host owns the descriptor.
+ * 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_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h
new file mode 100644
index 000000000..7f03e0adb
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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;
+
+
+/*------------------------------------------------------------------------------
+ *
+ */
+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_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h
new file mode 100644
index 000000000..d4d2cc4df
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/phy.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/phy.c
new file mode 100644
index 000000000..dd1ca43b5
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/phy.c
@@ -0,0 +1,387 @@
+/***************************************************************************//**
+ * 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"
+
+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 )
+{
+ int32_t a;
+ uint16_t reg;
+ int32_t exit = 1;
+
+ reg = MDIO_read( PHYREG_MIIMCR );
+ MDIO_write( PHYREG_MIIMCR,
+ (uint16_t)( MIIMCR_ENABLE_AUTONEGOTIATION |
+ MIIMCR_RESTART_AUTONEGOTIATION |
+ reg) );
+
+ for(a=0; (a<1000) && (exit); a++) {
+ reg = MDIO_read( PHYREG_MIIMSR );
+ if( (reg & MIIMSR_ANC) != 0 ) {
+ exit = 0;
+ }
+ }
+}
+
+
+/***************************************************************************//**
+ * 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_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/phy.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/phy.h
new file mode 100644
index 000000000..e61daaed2
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_gpio/mss_gpio.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_gpio/mss_gpio.c
new file mode 100644
index 000000000..e3be9aaa0
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_gpio/mss_gpio.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_gpio/mss_gpio.h
new file mode 100644
index 000000000..60220f128
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_pdma/mss_pdma.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_pdma/mss_pdma.c
new file mode 100644
index 000000000..b49dca4ea
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_pdma/mss_pdma.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_pdma/mss_pdma.h
new file mode 100644
index 000000000..6f79226c3
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_spi/mss_spi.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_spi/mss_spi.c
new file mode 100644
index 000000000..e5992301f
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_spi/mss_spi.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_spi/mss_spi.h
new file mode 100644
index 000000000..2b3617bc4
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_uart/mss_uart.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_uart/mss_uart.c
new file mode 100644
index 000000000..7dbb6c010
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_SoftConsole/MicroSemi_Code/drivers/mss_uart/mss_uart.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_uart/mss_uart.h
new file mode 100644
index 000000000..3897a3c37
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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
+
+#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_SoftConsole/MicroSemi_Code/drivers/mss_watchdog/mss_watchdog.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_watchdog/mss_watchdog.h
new file mode 100644
index 000000000..337a91bb1
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/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_ */
diff --git a/Demo/CORTEX_A2F200_SoftConsole/main-blinky.c b/Demo/CORTEX_A2F200_SoftConsole/main-blinky.c
new file mode 100644
index 000000000..1af00f2be
--- /dev/null
+++ b/Demo/CORTEX_A2F200_SoftConsole/main-blinky.c
@@ -0,0 +1,367 @@
+/*
+ FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
+
+ ***************************************************************************
+ * *
+ * If you are: *
+ * *
+ * + New to FreeRTOS, *
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *
+ * + Looking for basic training, *
+ * + Wanting to improve your FreeRTOS skills and productivity *
+ * *
+ * then take a look at the FreeRTOS books - available as PDF or paperback *
+ * *
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
+ * http://www.FreeRTOS.org/Documentation *
+ * *
+ * A pdf reference manual is also available. Both are usually delivered *
+ * to your inbox within 20 minutes to two hours when purchased between 8am *
+ * and 8pm GMT (although please allow up to 24 hours in case of *
+ * exceptional circumstances). Thank you for your support! *
+ * *
+ ***************************************************************************
+
+ This file is part of the FreeRTOS distribution.
+
+ FreeRTOS is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License (version 2) as published by the
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+ ***NOTE*** The exception to the GPL is included to allow you to distribute
+ a combined work that includes FreeRTOS without being obliged to provide the
+ source code for proprietary components outside of the FreeRTOS kernel.
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details. You should have received a copy of the GNU General Public
+ License and the FreeRTOS license exception along with FreeRTOS; if not it
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained
+ by writing to Richard Barry, contact details for whom are available on the
+ FreeRTOS WEB site.
+
+ 1 tab == 4 spaces!
+
+ http://www.FreeRTOS.org - Documentation, latest information, license and
+ contact details.
+
+ http://www.SafeRTOS.com - A version that is certified for use in safety
+ critical systems.
+
+ http://www.OpenRTOS.com - Commercial support, development, porting,
+ licensing and training services.
+*/
+
+/*
+This simple demo project runs on the STM32 Discovery board, which is
+populated with an STM32F100RB Cortex-M3 microcontroller. The discovery board
+makes an ideal low cost evaluation platform, but the 8K of RAM provided on the
+STM32F100RB does not allow the simple application to demonstrate all of all the
+FreeRTOS kernel features. Therefore, this simple demo only actively
+demonstrates task, queue, timer and interrupt functionality. In addition, the
+demo is configured to include malloc failure, idle and stack overflow hook
+functions.
+
+The idle hook function:
+The idle hook function queries the amount of FreeRTOS heap space that is
+remaining (see vApplicationIdleHook() defined in this file). The demo
+application is configured use 7K or the available 8K of RAM as the FreeRTOS heap.
+Memory is only allocated from this heap during initialisation, and this demo
+only actually uses 1.6K bytes of the configured 7K available - leaving 5.4K
+bytes of heap space unallocated.
+
+The main() Function:
+main() creates one software timer, one queue, and two tasks. It then starts the
+scheduler.
+
+The Queue Send Task:
+The queue send task is implemented by the prvQueueSendTask() function in this
+file. prvQueueSendTask() sits in a loop that causes it to repeatedly block for
+200 milliseconds, before sending the value 100 to the queue that was created
+within main(). Once the value is sent, the task loops back around to block for
+another 200 milliseconds.
+
+The Queue Receive Task:
+The queue receive task is implemented by the prvQueueReceiveTask() function
+in this file. prvQueueReceiveTask() sits in a loop that causes repeatedly
+attempt to read data from the queue that was created within main(). When data
+is received, the task checks the value of the data, and if the value equals
+the expected 100, toggles the green LED. The 'block time' parameter passed to
+the queue receive function specifies that the task should be held in the Blocked
+state indefinitely to wait for data to be available on the queue. The queue
+receive task will only leave the Blocked state when the queue send task writes
+to the queue. As the queue send task writes to the queue every 200
+milliseconds, the queue receive task leaves the Blocked state every 200
+milliseconds, and therefore toggles the green LED every 200 milliseconds.
+
+The LED Software Timer and the Button Interrupt:
+The user button B1 is configured to generate an interrupt each time it is
+pressed. The interrupt service routine switches the red LED on, and resets the
+LED software timer. The LED timer has a 5000 millisecond (5 second) period, and
+uses a callback function that is defined to just turn the red LED off.
+Therefore, pressing the user button will turn the red LED on, and the LED will
+remain on until a full five seconds pass without the button being pressed.
+*/
+
+/* Kernel includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "timers.h"
+
+/* Microsemi drivers/libraries. */
+#include "mss_gpio.h"
+#include "mss_watchdog.h"
+
+
+/* Priorities at which the tasks are created. */
+#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
+#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
+
+/* The rate at which data is sent to the queue, specified in milliseconds, and
+converted to ticks using the portTICK_RATE_MS constant. */
+#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_RATE_MS )
+
+/* The number of items the queue can hold. This is 1 as the receive task
+will remove items as they are added, meaning the send task should always find
+the queue empty. */
+#define mainQUEUE_LENGTH ( 1 )
+
+#define mainTASK_CONTROLLED_LED 0x01UL
+#define mainTIMER_CONTROLLED_LED 0x02UL
+/*-----------------------------------------------------------*/
+
+/*
+ * Setup the NVIC, LED outputs, and button inputs.
+ */
+static void prvSetupHardware( void );
+
+/*
+ * The tasks as described in the comments at the top of this file.
+ */
+static void prvQueueReceiveTask( void *pvParameters );
+static void prvQueueSendTask( void *pvParameters );
+
+/*
+ * The LED timer callback function. This does nothing but switch the red LED
+ * off.
+ */
+static void vLEDTimerCallback( xTimerHandle xTimer );
+
+/*-----------------------------------------------------------*/
+
+/* The queue used by both tasks. */
+static xQueueHandle xQueue = NULL;
+
+/* The LED software timer. This uses vLEDTimerCallback() as its callback
+function. */
+static xTimerHandle xLEDTimer = NULL;
+
+volatile unsigned long ulGPIOState = 0UL;
+
+/*-----------------------------------------------------------*/
+
+int main(void)
+{
+ /* Configure the NVIC, LED outputs and button inputs. */
+ prvSetupHardware();
+
+ /* Create the queue. */
+ xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
+
+ if( xQueue != NULL )
+ {
+ /* Start the two tasks as described in the comments at the top of this
+ file. */
+ xTaskCreate( prvQueueReceiveTask, ( signed char * ) "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
+ xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
+
+ /* Create the software timer that is responsible for turning off the LED
+ if the button is not pushed within 5000ms, as described at the top of
+ this file. */
+ xLEDTimer = xTimerCreate( ( const signed char * ) "LEDTimer", /* A text name, purely to help debugging. */
+ ( 5000 / portTICK_RATE_MS ), /* The timer period, in this case 5000ms (5s). */
+ pdFALSE, /* This is a one shot timer, so xAutoReload is set to pdFALSE. */
+ ( void * ) 0, /* The ID is not used, so can be set to anything. */
+ vLEDTimerCallback /* The callback function that switches the LED off. */
+ );
+
+ /* Start the tasks and timer running. */
+ vTaskStartScheduler();
+ }
+
+ /* If all is well, the scheduler will now be running, and the following line
+ will never be reached. If the following line does execute, then there was
+ insufficient FreeRTOS heap memory available for the idle and/or timer tasks
+ to be created. See the memory management section on the FreeRTOS web site
+ for more details. */
+ for( ;; );
+}
+/*-----------------------------------------------------------*/
+
+static void vLEDTimerCallback( xTimerHandle xTimer )
+{
+ /* The timer has expired - so no button pushes have occurred in the last
+ five seconds - turn the LED off. NOTE - accessing the LED port should use
+ a critical section because it is accessed from multiple tasks, and the
+ button interrupt - in this trivial case, for simplicity, the critical
+ section is omitted. */
+ ulGPIOState |= mainTIMER_CONTROLLED_LED;
+ MSS_GPIO_set_outputs( ulGPIOState );
+}
+/*-----------------------------------------------------------*/
+
+/* The ISR executed when the user button is pushed. */
+void GPIO8_IRQHandler( void )
+{
+portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
+
+ /* The button was pushed, so ensure the LED is on before resetting the
+ LED timer. The LED timer will turn the LED off if the button is not
+ pushed within 5000ms. */
+ ulGPIOState &= ~mainTIMER_CONTROLLED_LED;
+ MSS_GPIO_set_outputs( ulGPIOState );
+
+ /* This interrupt safe FreeRTOS function can be called from this interrupt
+ because the interrupt priority is below the
+ configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
+ xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken );
+
+ /* Clear the interrupt before leaving. */
+ MSS_GPIO_clear_irq( MSS_GPIO_8 );
+
+ /* If calling xTimerResetFromISR() caused a task (in this case the timer
+ service/daemon task) to unblock, and the unblocked task has a priority
+ higher than or equal to the task that was interrupted, then
+ xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
+ portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
+ portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
+}
+/*-----------------------------------------------------------*/
+
+static void prvQueueSendTask( void *pvParameters )
+{
+portTickType xNextWakeTime;
+const unsigned long ulValueToSend = 100UL;
+
+ /* Initialise xNextWakeTime - this only needs to be done once. */
+ xNextWakeTime = xTaskGetTickCount();
+
+ for( ;; )
+ {
+ /* Place this task in the blocked state until it is time to run again.
+ The block time is specified in ticks, the constant used converts ticks
+ to ms. While in the Blocked state this task will not consume any CPU
+ time. */
+ vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
+
+ /* Send to the queue - causing the queue receive task to unblock and
+ toggle an LED. 0 is used as the block time so the sending operation
+ will not block - it shouldn't need to block as the queue should always
+ be empty at this point in the code. */
+ xQueueSend( xQueue, &ulValueToSend, 0 );
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvQueueReceiveTask( void *pvParameters )
+{
+unsigned long ulReceivedValue;
+
+ for( ;; )
+ {
+ /* Wait until something arrives in the queue - this task will block
+ indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
+ FreeRTOSConfig.h. */
+ xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
+
+ /* To get here something must have been received from the queue, but
+ is it the expected value? If it is, toggle the green LED. */
+ if( ulReceivedValue == 100UL )
+ {
+ /* NOTE - accessing the LED port should use a critical section
+ because it is accessed from multiple tasks, and the button interrupt
+ - in this trivial case, for simplicity, the critical section is
+ omitted. */
+ if( ( ulGPIOState & mainTASK_CONTROLLED_LED ) != 0 )
+ {
+ ulGPIOState &= ~mainTASK_CONTROLLED_LED;
+ }
+ else
+ {
+ ulGPIOState |= mainTASK_CONTROLLED_LED;
+ }
+ MSS_GPIO_set_outputs( ulGPIOState );
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvSetupHardware( void )
+{
+ /* Disable the Watch Dog Timer */
+ MSS_WD_disable( );
+
+ /* Initialise the GPIO */
+ MSS_GPIO_init();
+
+ /* Set up GPIO for the LEDs. */
+ MSS_GPIO_config( MSS_GPIO_0 , MSS_GPIO_OUTPUT_MODE );
+ MSS_GPIO_config( MSS_GPIO_1 , MSS_GPIO_OUTPUT_MODE );
+ MSS_GPIO_config( MSS_GPIO_2 , MSS_GPIO_OUTPUT_MODE );
+ MSS_GPIO_config( MSS_GPIO_3 , MSS_GPIO_OUTPUT_MODE );
+ MSS_GPIO_config( MSS_GPIO_4 , MSS_GPIO_OUTPUT_MODE );
+ MSS_GPIO_config( MSS_GPIO_5 , MSS_GPIO_OUTPUT_MODE );
+ MSS_GPIO_config( MSS_GPIO_6 , MSS_GPIO_OUTPUT_MODE );
+ MSS_GPIO_config( MSS_GPIO_7 , MSS_GPIO_OUTPUT_MODE );
+
+ /* All LEDs start off. */
+ ulGPIOState = 0xffffffffUL;
+ MSS_GPIO_set_outputs( ulGPIOState );
+
+ /* Setup the GPIO and the NVIC for the switch used in this simple demo. */
+ NVIC_EnableIRQ( GPIO8_IRQn );
+ MSS_GPIO_config( MSS_GPIO_8, MSS_GPIO_INPUT_MODE | MSS_GPIO_IRQ_EDGE_NEGATIVE );
+ MSS_GPIO_enable_irq( MSS_GPIO_8 );
+}
+/*-----------------------------------------------------------*/
+
+void vApplicationMallocFailedHook( void )
+{
+ /* Called if a call to pvPortMalloc() fails because there is insufficient
+ free memory available in the FreeRTOS heap. pvPortMalloc() is called
+ internally by FreeRTOS API functions that create tasks, queues, software
+ timers, and semaphores. The size of the FreeRTOS heap is set by the
+ configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
+ for( ;; );
+}
+/*-----------------------------------------------------------*/
+
+void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
+{
+ ( void ) pcTaskName;
+ ( void ) pxTask;
+
+ /* Run time stack overflow checking is performed if
+ configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
+ function is called if a stack overflow is detected. */
+ for( ;; );
+}
+/*-----------------------------------------------------------*/
+
+void vApplicationIdleHook( void )
+{
+volatile size_t xFreeStackSpace;
+
+ /* This function is called on each cycle of the idle task. In this case it
+ does nothing useful, other than report the amout of FreeRTOS heap that
+ remains unallocated. */
+ xFreeStackSpace = xPortGetFreeHeapSize();
+
+ if( xFreeStackSpace > 100 )
+ {
+ /* By now, the kernel has allocated everything it is going to, so
+ if there is a lot of heap remaining unallocated then
+ the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
+ reduced accordingly. */
+ }
+}